From 01a70564195c12d44b829cfc3f79dbfaa3df1851 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Thu, 3 Jan 2019 15:01:52 +0000 Subject: [PATCH] feat: some updates needed License: MIT Signed-off-by: Henrique Dias --- frontend | 2 +- http/share.go | 3 +- http/websockets.go | 3 +- types/fs.go | 85 +++++++++++++++++++++++++++++++++++++++++++++- types/runner.go | 5 ++- types/user.go | 7 +++- 6 files changed, 95 insertions(+), 10 deletions(-) diff --git a/frontend b/frontend index b18139b2..56b609be 160000 --- a/frontend +++ b/frontend @@ -1 +1 @@ -Subproject commit b18139b2786ffd236294eed812d21197009ca1aa +Subproject commit 56b609be4f496dfa11f1237490cb167e1c774fb0 diff --git a/http/share.go b/http/share.go index 48201861..5df58dad 100644 --- a/http/share.go +++ b/http/share.go @@ -9,7 +9,6 @@ import ( "time" "github.com/filebrowser/filebrowser/types" - "github.com/spf13/afero" ) const apiSharePrefix = "/api/share" @@ -25,7 +24,7 @@ func (e *Env) getShareData(w http.ResponseWriter, r *http.Request, prefix string return "", false } - return afero.FullBaseFsPath(user.Fs.(*afero.BasePathFs), relPath), ok + return user.FullPath(relPath), ok } func (e *Env) shareGetHandler(w http.ResponseWriter, r *http.Request) { diff --git a/http/websockets.go b/http/websockets.go index 2a3f85ed..fbe2552a 100644 --- a/http/websockets.go +++ b/http/websockets.go @@ -10,7 +10,6 @@ import ( "strings" "github.com/filebrowser/filebrowser/search" - "github.com/spf13/afero" "github.com/gorilla/websocket" ) @@ -75,7 +74,7 @@ func (e *Env) commandsHandler(w http.ResponseWriter, r *http.Request) { } path := strings.TrimPrefix(r.URL.Path, "/api/command") - dir := afero.FullBaseFsPath(user.Fs.(*afero.BasePathFs), path) + dir := user.FullPath(path) cmd := exec.Command(command[0], command[1:]...) cmd.Dir = dir diff --git a/types/fs.go b/types/fs.go index 165bfbe8..accb4c48 100644 --- a/types/fs.go +++ b/types/fs.go @@ -2,6 +2,7 @@ package types import ( "os" + "path" "syscall" "time" @@ -14,6 +15,12 @@ type userFs struct { settings *Settings } +type userFile struct { + f afero.File + path string + fs *userFs +} + func (u *userFs) isAllowed(name string) bool { if !isAllowed(name, u.user.Rules) { return false @@ -22,6 +29,10 @@ func (u *userFs) isAllowed(name string) bool { return isAllowed(name, u.settings.Rules) } +func (u *userFs) FullPath(path string) string { + return afero.FullBaseFsPath(u.source.(*afero.BasePathFs), path) +} + func (u *userFs) Chtimes(name string, a, m time.Time) error { if !u.isAllowed(name) { return syscall.ENOENT @@ -99,7 +110,8 @@ func (u *userFs) Open(name string) (afero.File, error) { return nil, syscall.ENOENT } - return u.source.Open(name) + f, err := u.source.Open(name) + return &userFile{fs: u, path: name, f: f}, err } func (u *userFs) Mkdir(name string, perm os.FileMode) error { @@ -137,3 +149,74 @@ func (u *userFs) Create(name string) (afero.File, error) { return u.source.Create(name) } + +func (f *userFile) Close() error { + return f.f.Close() +} + +func (f *userFile) Read(s []byte) (int, error) { + return f.f.Read(s) +} + +func (f *userFile) ReadAt(s []byte, o int64) (int, error) { + return f.f.ReadAt(s, o) +} + +func (f *userFile) Seek(o int64, w int) (int64, error) { + return f.f.Seek(o, w) +} + +func (f *userFile) Write(s []byte) (int, error) { + return f.f.Write(s) +} + +func (f *userFile) WriteAt(s []byte, o int64) (int, error) { + return f.f.WriteAt(s, o) +} + +func (f *userFile) Name() string { + return f.f.Name() +} + +func (f *userFile) Readdir(c int) (fi []os.FileInfo, err error) { + var rfi []os.FileInfo + rfi, err = f.f.Readdir(c) + if err != nil { + return nil, err + } + for _, i := range rfi { + if f.fs.isAllowed(path.Join(f.path, i.Name())) { + fi = append(fi, i) + } + } + return fi, nil +} + +func (f *userFile) Readdirnames(c int) (n []string, err error) { + fi, err := f.Readdir(c) + if err != nil { + return nil, err + } + for _, s := range fi { + if f.fs.isAllowed(s.Name()) { + n = append(n, s.Name()) + } + } + return n, nil +} + +func (f *userFile) Stat() (os.FileInfo, error) { + return f.f.Stat() +} + +func (f *userFile) Sync() error { + return f.f.Sync() +} + +func (f *userFile) Truncate(s int64) error { + return f.f.Truncate(s) +} + +func (f *userFile) WriteString(s string) (int, error) { + return f.f.WriteString(s) +} diff --git a/types/runner.go b/types/runner.go index 84fabcab..478da61d 100644 --- a/types/runner.go +++ b/types/runner.go @@ -8,7 +8,6 @@ import ( "strings" "github.com/mholt/caddy" - "github.com/spf13/afero" ) var defaultEvents = []string{ @@ -21,8 +20,8 @@ var defaultEvents = []string{ // Run runs the hooks for the before and after event. func (s *Settings) Run(fn func() error, evt, path, dst string, user *User) error { - path = afero.FullBaseFsPath(user.Fs.(*afero.BasePathFs), path) - dst = afero.FullBaseFsPath(user.Fs.(*afero.BasePathFs), dst) + path = user.FullPath(path) + dst = user.FullPath(dst) if val, ok := s.Commands["before_"+evt]; ok { for _, command := range val { diff --git a/types/user.go b/types/user.go index 3c9864aa..7c11297d 100644 --- a/types/user.go +++ b/types/user.go @@ -22,7 +22,7 @@ type Permissions struct { Execute bool `json:"execute"` Create bool `json:"create"` Rename bool `json:"rename"` - Modify bool `json:"edit"` + Modify bool `json:"modify"` Delete bool `json:"delete"` Share bool `json:"share"` Download bool `json:"download"` @@ -103,6 +103,11 @@ func (u *User) clean(settings *Settings, fields ...string) error { return nil } +// FullPath gets the full path for a user's relative path. +func (u *User) FullPath(path string) string { + return u.Fs.(*userFs).FullPath(path) +} + // CanExecute checks if an user can execute a specific command. func (u *User) CanExecute(command string) bool { if !u.Perm.Execute {