diff --git a/cmd/root.go b/cmd/root.go index f0089fbe..2fb42ff2 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -14,7 +14,7 @@ import ( "github.com/filebrowser/filebrowser/auth" "github.com/filebrowser/filebrowser/lib" - fhttp "github.com/filebrowser/filebrowser/http" + fbhttp "github.com/filebrowser/filebrowser/http" "github.com/spf13/cobra" lumberjack "gopkg.in/natefinch/lumberjack.v2" ) @@ -57,10 +57,10 @@ listening on loalhost on a random port. Use the flags to change it.`, db := getDB() defer db.Close() fb := getFileBrowser(db) - env := &fhttp.Env{FileBrowser: fb} - env.Auther, err = env.GetAuther(env.GetSettings().AuthMethod) + + handler, err := fbhttp.NewHandler(fb) checkErr(err) - startServer(cmd, env) + startServer(cmd, handler) }, } @@ -134,7 +134,7 @@ func quickSetup(cmd *cobra.Command) { checkErr(err) } -func startServer(cmd *cobra.Command, env *fhttp.Env) { +func startServer(cmd *cobra.Command, handler http.Handler) { addr := mustGetString(cmd, "address") port, err := cmd.Flags().GetInt("port") checkErr(err) @@ -156,7 +156,7 @@ func startServer(cmd *cobra.Command, env *fhttp.Env) { } log.Println("Listening on", listener.Addr().String()) - if err := http.Serve(listener, fhttp.Handler(env)); err != nil { + if err := http.Serve(listener, handler); err != nil { log.Fatal(err) } } diff --git a/http/auth.go b/http/auth.go index aa7737b4..a866ccf9 100644 --- a/http/auth.go +++ b/http/auth.go @@ -13,7 +13,7 @@ import ( ) -func (e *Env) loginHandler(w http.ResponseWriter, r *http.Request) { +func (e *env) loginHandler(w http.ResponseWriter, r *http.Request) { user, err := e.Auther.Auth(r) if err == lib.ErrNoPermission { httpErr(w, r, http.StatusForbidden, nil) @@ -29,7 +29,7 @@ type signupBody struct { Password string `json:"password"` } -func (e *Env) signupHandler(w http.ResponseWriter, r *http.Request) { +func (e *env) signupHandler(w http.ResponseWriter, r *http.Request) { e.RLockSettings() defer e.RUnlockSettings() @@ -117,7 +117,7 @@ func (e extractor) ExtractToken(r *http.Request) (string, error) { return auth, nil } -func (e *Env) auth(next http.HandlerFunc) http.HandlerFunc { +func (e *env) auth(next http.HandlerFunc) http.HandlerFunc { keyFunc := func(token *jwt.Token) (interface{}, error) { return e.GetSettings().Key, nil } @@ -145,7 +145,7 @@ func (e *Env) auth(next http.HandlerFunc) http.HandlerFunc { } } -func (e *Env) renew(w http.ResponseWriter, r *http.Request) { +func (e *env) renew(w http.ResponseWriter, r *http.Request) { user, ok := e.getUser(w, r) if !ok { return @@ -154,7 +154,7 @@ func (e *Env) renew(w http.ResponseWriter, r *http.Request) { e.printToken(w, r, user) } -func (e *Env) printToken(w http.ResponseWriter, r *http.Request, user *lib.User) { +func (e *env) printToken(w http.ResponseWriter, r *http.Request, user *lib.User) { claims := &authToken{ User: userInfo{ ID: user.ID, diff --git a/http/http.go b/http/http.go index 3237767f..bed3014e 100644 --- a/http/http.go +++ b/http/http.go @@ -23,14 +23,24 @@ type modifyRequest struct { Which []string `json:"which"` // Answer to: which fields? } -// Env contains the required info for FB to run. -type Env struct { +type env struct { *lib.FileBrowser Auther lib.Auther } -// Handler ... -func Handler(e *Env) http.Handler { +// NewHandler builds an HTTP handler on the top of a File Browser instance. +func NewHandler(fb *lib.FileBrowser) (http.Handler, error) { + authMethod := fb.GetSettings().AuthMethod + auther, err := fb.GetAuther(authMethod) + if err != nil { + return nil, err + } + + e := &env{ + FileBrowser: fb, + Auther: auther, + } + r := mux.NewRouter() index, static := e.getStaticHandlers() @@ -67,7 +77,7 @@ func Handler(e *Env) http.Handler { api.PathPrefix("/command").HandlerFunc(e.auth(e.commandsHandler)) api.PathPrefix("/search").HandlerFunc(e.auth(e.searchHandler)) - return r + return r, nil } func httpErr(w http.ResponseWriter, r *http.Request, status int, err error) { @@ -99,7 +109,7 @@ func renderJSON(w http.ResponseWriter, r *http.Request, data interface{}) { } } -func (e *Env) getUser(w http.ResponseWriter, r *http.Request) (*lib.User, bool) { +func (e *env) getUser(w http.ResponseWriter, r *http.Request) (*lib.User, bool) { id := r.Context().Value(keyUserID).(uint) user, err := e.GetUser(id) if err == lib.ErrNotExist { @@ -115,7 +125,7 @@ func (e *Env) getUser(w http.ResponseWriter, r *http.Request) (*lib.User, bool) return user, true } -func (e *Env) getAdminUser(w http.ResponseWriter, r *http.Request) (*lib.User, bool) { +func (e *env) getAdminUser(w http.ResponseWriter, r *http.Request) (*lib.User, bool) { user, ok := e.getUser(w, r) if !ok { return nil, false diff --git a/http/raw.go b/http/raw.go index a1eb1abf..ac128f84 100644 --- a/http/raw.go +++ b/http/raw.go @@ -56,7 +56,7 @@ func parseQueryAlgorithm(r *http.Request) (string, archiver.Writer, error) { } } -func (e *Env) rawHandler(w http.ResponseWriter, r *http.Request) { +func (e *env) rawHandler(w http.ResponseWriter, r *http.Request) { path, user, ok := e.getResourceData(w, r, apiRawPrefix) if !ok { return diff --git a/http/resource.go b/http/resource.go index 3160bd2a..778924c7 100644 --- a/http/resource.go +++ b/http/resource.go @@ -30,7 +30,7 @@ func httpFsErr(err error) int { } } -func (e *Env) getResourceData(w http.ResponseWriter, r *http.Request, prefix string) (string, *lib.User, bool) { +func (e *env) getResourceData(w http.ResponseWriter, r *http.Request, prefix string) (string, *lib.User, bool) { user, ok := e.getUser(w, r) if !ok { return "", nil, ok @@ -45,7 +45,7 @@ func (e *Env) getResourceData(w http.ResponseWriter, r *http.Request, prefix str return path, user, true } -func (e *Env) resourceGetHandler(w http.ResponseWriter, r *http.Request) { +func (e *env) resourceGetHandler(w http.ResponseWriter, r *http.Request) { path, user, ok := e.getResourceData(w, r, apiResourcePrefix) if !ok { return @@ -86,7 +86,7 @@ func (e *Env) resourceGetHandler(w http.ResponseWriter, r *http.Request) { renderJSON(w, r, file) } -func (e *Env) resourceDeleteHandler(w http.ResponseWriter, r *http.Request) { +func (e *env) resourceDeleteHandler(w http.ResponseWriter, r *http.Request) { path, user, ok := e.getResourceData(w, r, apiResourcePrefix) if !ok { return @@ -109,7 +109,7 @@ func (e *Env) resourceDeleteHandler(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) } -func (e *Env) resourcePostPutHandler(w http.ResponseWriter, r *http.Request) { +func (e *env) resourcePostPutHandler(w http.ResponseWriter, r *http.Request) { path, user, ok := e.getResourceData(w, r, apiResourcePrefix) if !ok { return @@ -179,7 +179,7 @@ func (e *Env) resourcePostPutHandler(w http.ResponseWriter, r *http.Request) { httpErr(w, r, http.StatusOK, nil) } -func (e *Env) resourcePatchHandler(w http.ResponseWriter, r *http.Request) { +func (e *env) resourcePatchHandler(w http.ResponseWriter, r *http.Request) { src, user, ok := e.getResourceData(w, r, apiResourcePrefix) if !ok { return diff --git a/http/settings.go b/http/settings.go index 36039cf9..063b01bb 100644 --- a/http/settings.go +++ b/http/settings.go @@ -17,7 +17,7 @@ type settingsData struct { Commands map[string][]string `json:"commands"` } -func (e *Env) settingsGetHandler(w http.ResponseWriter, r *http.Request) { +func (e *env) settingsGetHandler(w http.ResponseWriter, r *http.Request) { _, ok := e.getAdminUser(w, r) if !ok { return @@ -38,7 +38,7 @@ func (e *Env) settingsGetHandler(w http.ResponseWriter, r *http.Request) { renderJSON(w, r, data) } -func (e *Env) settingsPutHandler(w http.ResponseWriter, r *http.Request) { +func (e *env) settingsPutHandler(w http.ResponseWriter, r *http.Request) { _, ok := e.getAdminUser(w, r) if !ok { return diff --git a/http/share.go b/http/share.go index efc0bee1..5c2bdf30 100644 --- a/http/share.go +++ b/http/share.go @@ -13,7 +13,7 @@ import ( const apiSharePrefix = "/api/share" -func (e *Env) getShareData(w http.ResponseWriter, r *http.Request, prefix string) (string, bool) { +func (e *env) getShareData(w http.ResponseWriter, r *http.Request, prefix string) (string, bool) { relPath, user, ok := e.getResourceData(w, r, apiSharePrefix) if !ok { return "", false @@ -27,7 +27,7 @@ func (e *Env) getShareData(w http.ResponseWriter, r *http.Request, prefix string return user.FullPath(relPath), ok } -func (e *Env) shareGetHandler(w http.ResponseWriter, r *http.Request) { +func (e *env) shareGetHandler(w http.ResponseWriter, r *http.Request) { path, ok := e.getShareData(w, r, apiSharePrefix) if !ok { return @@ -54,7 +54,7 @@ func (e *Env) shareGetHandler(w http.ResponseWriter, r *http.Request) { renderJSON(w, r, s) } -func (e *Env) shareDeleteHandler(w http.ResponseWriter, r *http.Request) { +func (e *env) shareDeleteHandler(w http.ResponseWriter, r *http.Request) { user, ok := e.getUser(w, r) if !ok { return @@ -79,7 +79,7 @@ func (e *Env) shareDeleteHandler(w http.ResponseWriter, r *http.Request) { } } -func (e *Env) sharePostHandler(w http.ResponseWriter, r *http.Request) { +func (e *env) sharePostHandler(w http.ResponseWriter, r *http.Request) { path, ok := e.getShareData(w, r, apiSharePrefix) if !ok { return diff --git a/http/static.go b/http/static.go index d7a08596..cf7f7478 100644 --- a/http/static.go +++ b/http/static.go @@ -14,7 +14,7 @@ import ( "github.com/filebrowser/filebrowser/lib" ) -func (e *Env) getStaticData() map[string]interface{} { +func (e *env) getStaticData() map[string]interface{} { e.RLockSettings() defer e.RUnlockSettings() @@ -63,7 +63,7 @@ func (e *Env) getStaticData() map[string]interface{} { return data } -func (e *Env) getStaticHandlers() (http.Handler, http.Handler) { +func (e *env) getStaticHandlers() (http.Handler, http.Handler) { box := rice.MustFindBox("../frontend/dist") handler := http.FileServer(box.HTTPBox()) diff --git a/http/users.go b/http/users.go index 559dfe93..0cb2731b 100644 --- a/http/users.go +++ b/http/users.go @@ -46,7 +46,7 @@ func getUser(w http.ResponseWriter, r *http.Request) (*modifyUserRequest, bool) return req, true } -func (e *Env) usersGetHandler(w http.ResponseWriter, r *http.Request) { +func (e *env) usersGetHandler(w http.ResponseWriter, r *http.Request) { user, ok := e.getUser(w, r) if !ok { return @@ -74,7 +74,7 @@ func (e *Env) usersGetHandler(w http.ResponseWriter, r *http.Request) { renderJSON(w, r, users) } -func (e *Env) userSelfOrAdmin(w http.ResponseWriter, r *http.Request) (*lib.User, uint, bool) { +func (e *env) userSelfOrAdmin(w http.ResponseWriter, r *http.Request) (*lib.User, uint, bool) { user, ok := e.getUser(w, r) if !ok { return nil, 0, false @@ -94,7 +94,7 @@ func (e *Env) userSelfOrAdmin(w http.ResponseWriter, r *http.Request) (*lib.User return user, id, true } -func (e *Env) userGetHandler(w http.ResponseWriter, r *http.Request) { +func (e *env) userGetHandler(w http.ResponseWriter, r *http.Request) { _, id, ok := e.userSelfOrAdmin(w, r) if !ok { return @@ -115,7 +115,7 @@ func (e *Env) userGetHandler(w http.ResponseWriter, r *http.Request) { renderJSON(w, r, u) } -func (e *Env) userDeleteHandler(w http.ResponseWriter, r *http.Request) { +func (e *env) userDeleteHandler(w http.ResponseWriter, r *http.Request) { _, id, ok := e.userSelfOrAdmin(w, r) if !ok { return @@ -132,7 +132,7 @@ func (e *Env) userDeleteHandler(w http.ResponseWriter, r *http.Request) { } } -func (e *Env) userPostHandler(w http.ResponseWriter, r *http.Request) { +func (e *env) userPostHandler(w http.ResponseWriter, r *http.Request) { _, ok := e.getAdminUser(w,r) if !ok { return @@ -170,7 +170,7 @@ func (e *Env) userPostHandler(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusCreated) } -func (e *Env) userPutHandler(w http.ResponseWriter, r *http.Request) { +func (e *env) userPutHandler(w http.ResponseWriter, r *http.Request) { sessionUser, modifiedID, ok := e.userSelfOrAdmin(w, r) if !ok { return diff --git a/http/websockets.go b/http/websockets.go index cfd2fd4b..7eef4780 100644 --- a/http/websockets.go +++ b/http/websockets.go @@ -23,7 +23,7 @@ var ( cmdNotAllowed = []byte("Command not allowed.") ) -func (e *Env) commandsHandler(w http.ResponseWriter, r *http.Request) { +func (e *env) commandsHandler(w http.ResponseWriter, r *http.Request) { user, ok := e.getUser(w, r) if !ok { return @@ -102,7 +102,7 @@ func (e *Env) commandsHandler(w http.ResponseWriter, r *http.Request) { } } -func (e *Env) searchHandler(w http.ResponseWriter, r *http.Request) { +func (e *env) searchHandler(w http.ResponseWriter, r *http.Request) { user, ok := e.getUser(w, r) if !ok { return