From 545a831c664dafee8414d99da007b7c7ad8cd593 Mon Sep 17 00:00:00 2001 From: Graham Steffaniak <42989099+gtsteffaniak@users.noreply.github.com> Date: Sat, 1 Feb 2025 08:10:46 -0500 Subject: [PATCH] simple bugfixes beta/v0.5.1 (#344) --- CHANGELOG.md | 11 +++++++ backend/cmd/root.go | 59 ++++++++++++++++++++++++----------- backend/files/sync.go | 6 +++- backend/http/auth.go | 2 +- backend/http/middleware.go | 2 +- backend/http/static.go | 2 +- backend/logger/write.go | 8 ++--- backend/settings/config.go | 7 +++-- backend/settings/structs.go | 11 +++++-- backend/storage/bolt/users.go | 13 ++++++-- backend/storage/storage.go | 5 +++ 11 files changed, 91 insertions(+), 35 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d60ad5ed..f2eca41b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,17 @@ All notable changes to this project will be documented in this file. For commit guidelines, please refer to [Standard Version](https://github.com/conventional-changelog/standard-version). +## v0.5.1-beta + + > Note: I changed the [config](https://github.com/gtsteffaniak/filebrowser/wiki/Configuration#example-auth-config) for password auth again... It was a mistake just to make it a boolean, so now you can provide options, going forward this allows for more. + + **New Features**: + - password length requirement config via `auth.methods.password.minLength` as a number of characters required. + + **Bugfixes**: + - NoAuth error message "resource not found" + - CLI user configuration works and simplified see examples in the [Wiki](https://github.com/gtsteffaniak/filebrowser/wiki/CLI) + ## v0.5.0-beta > Note: This Beta release includes a configuration change: `auth.method` is now deprecated. This is done to allow multiple login methods at once. Auth methods are specified via `auth.methods` instead. see [example on the wiki](https://github.com/gtsteffaniak/filebrowser/wiki/Configuration#example-auth-config). diff --git a/backend/cmd/root.go b/backend/cmd/root.go index 40152ede..5c648c18 100644 --- a/backend/cmd/root.go +++ b/backend/cmd/root.go @@ -87,38 +87,60 @@ func StartFilebrowser() { if len(os.Args) > 1 { switch os.Args[1] { case "set": - err := setCmd.Parse(os.Args) + err := setCmd.Parse(os.Args[2:]) if err != nil { setCmd.PrintDefaults() os.Exit(1) } userInfo := strings.Split(user, ",") if len(userInfo) < 2 { - fmt.Println("not enough info to create user: \"set -u username,password\"") + fmt.Printf("not enough info to create user: \"set -u username,password\", only provided %v\n", userInfo) setCmd.PrintDefaults() os.Exit(1) } username := userInfo[0] password := userInfo[1] - getStore(dbConfig) - // Create the user logic - if asAdmin { - logger.Info(fmt.Sprintf("Creating user as admin: %s\n", username)) - } else { - logger.Info(fmt.Sprintf("Creating non-admin user: %s\n", username)) + store, ok := getStore(dbConfig) + if !ok { + logger.Fatal("could not load db info") } - newUser := users.User{ - Username: username, - Password: password, - } - if scope != "" { - newUser.Scope = scope - } - err = storage.CreateUser(newUser, asAdmin) + user, err := store.Users.Get("", username) if err != nil { - logger.Fatal(fmt.Sprintf("could not create user: %v", err)) + newUser := users.User{ + Username: username, + Password: password, + } + if scope != "" { + newUser.Scope = scope + } else { + newUser.Scope = settings.Config.UserDefaults.Scope + } + // Create the user logic + if asAdmin { + logger.Info(fmt.Sprintf("Creating user as admin: %s\n", username)) + } else { + logger.Info(fmt.Sprintf("Creating non-admin user: %s\n", username)) + } + err = storage.CreateUser(newUser, asAdmin) + if err != nil { + logger.Error(fmt.Sprintf("could not create user: %v", err)) + } + return } + user.Password = password + if scope != "" { + user.Scope = scope + } + if asAdmin { + user.Perm.Admin = true + } + err = store.Users.Save(user) + if err != nil { + logger.Error(fmt.Sprintf("could not update user: %v", err)) + } + fmt.Printf("successfully updated user: %s\n", username) return + case "version": fmt.Printf(`FileBrowser Quantum - A modern web-based file manager Version : %v @@ -128,7 +150,6 @@ Release Info : https://github.com/gtsteffaniak/filebrowser/releases/tag/%v return } } - store, dbExists := getStore(configPath) database := fmt.Sprintf("Using existing database : %v", settings.Config.Server.Database) if !dbExists { @@ -140,7 +161,7 @@ Release Info : https://github.com/gtsteffaniak/filebrowser/releases/tag/%v } authMethods := []string{} - if settings.Config.Auth.Methods.PasswordAuth { + if settings.Config.Auth.Methods.PasswordAuth.Enabled { authMethods = append(authMethods, "Password") } if settings.Config.Auth.Methods.ProxyAuth.Enabled { diff --git a/backend/files/sync.go b/backend/files/sync.go index ab75d6c8..b3d93887 100644 --- a/backend/files/sync.go +++ b/backend/files/sync.go @@ -2,6 +2,8 @@ package files import ( "path/filepath" + + "github.com/gtsteffaniak/filebrowser/backend/settings" ) // UpdateFileMetadata updates the FileInfo for the specified directory in the index. @@ -69,7 +71,9 @@ func GetIndex(name string) *Index { defer indexesMutex.Unlock() index, ok := indexes[name] if !ok { - return nil + return &Index{ + Source: settings.Source{Name: "default", Path: "."}, + } } return index } diff --git a/backend/http/auth.go b/backend/http/auth.go index 79ce2977..d9ce2608 100644 --- a/backend/http/auth.go +++ b/backend/http/auth.go @@ -75,7 +75,7 @@ func extractToken(r *http.Request) (string, error) { } func loginHandler(w http.ResponseWriter, r *http.Request) { - if !config.Auth.Methods.PasswordAuth { + if !config.Auth.Methods.PasswordAuth.Enabled { http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden) return } diff --git a/backend/http/middleware.go b/backend/http/middleware.go index e01afefa..00a98e74 100644 --- a/backend/http/middleware.go +++ b/backend/http/middleware.go @@ -97,7 +97,7 @@ func withUserHelper(fn handleFunc) handleFunc { if config.Auth.Methods.NoAuth { var err error // Retrieve the user from the store and store it in the context - data.user, err = store.Users.Get(files.RootPaths["default"], 1) + data.user, err = store.Users.Get(files.RootPaths["default"], uint(1)) if err != nil { logger.Error(fmt.Sprintf("no auth: %v", err)) return http.StatusInternalServerError, err diff --git a/backend/http/static.go b/backend/http/static.go index 4a04eb31..9e7a7f3a 100644 --- a/backend/http/static.go +++ b/backend/http/static.go @@ -80,7 +80,7 @@ func handleWithStaticData(w http.ResponseWriter, r *http.Request, file, contentT } } - if config.Auth.Methods.PasswordAuth { + if config.Auth.Methods.PasswordAuth.Enabled { raw, err := store.Auth.Get("password") //nolint:govet if err != nil { http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) diff --git a/backend/logger/write.go b/backend/logger/write.go index 25f74f85..b7fca24a 100644 --- a/backend/logger/write.go +++ b/backend/logger/write.go @@ -110,7 +110,7 @@ func Debug(msg string) { if len(loggers) > 0 { Log(levels.DEBUG, msg, true, false, GRAY) } else { - log.Println("[DEBUG]: " + msg) + log.Println("[DEBUG] ", msg) } } @@ -126,7 +126,7 @@ func Warning(msg string) { if len(loggers) > 0 { Log(levels.WARNING, msg, true, false, YELLOW) } else { - log.Println("[WARN ]: " + msg) + log.Println("[WARN ] ", msg) } } @@ -134,7 +134,7 @@ func Error(msg string) { if len(loggers) > 0 { Log(levels.ERROR, msg, true, false, RED) } else { - log.Println("[ERROR] : ", msg) + log.Println("[ERROR] ", msg) } } @@ -142,5 +142,5 @@ func Fatal(msg string) { if len(loggers) > 0 { Log(levels.FATAL, msg, true, false, RED) } - log.Fatal("[FATAL] : ", msg) + log.Fatal("[FATAL] ", msg) } diff --git a/backend/settings/config.go b/backend/settings/config.go index 20e122ab..c9426559 100644 --- a/backend/settings/config.go +++ b/backend/settings/config.go @@ -144,8 +144,11 @@ func setDefaults() Settings { CreateUser: false, Header: "", }, - NoAuth: false, - PasswordAuth: true, + NoAuth: false, + PasswordAuth: PasswordAuthConfig{ + Enabled: true, + MinLength: 5, + }, }, }, Frontend: Frontend{ diff --git a/backend/settings/structs.go b/backend/settings/structs.go index ad9718b8..dd985558 100644 --- a/backend/settings/structs.go +++ b/backend/settings/structs.go @@ -38,9 +38,14 @@ type Auth struct { } type LoginMethods struct { - ProxyAuth ProxyAuthConfig `json:"proxy"` - NoAuth bool `json:"noauth"` - PasswordAuth bool `json:"password"` + ProxyAuth ProxyAuthConfig `json:"proxy"` + NoAuth bool `json:"noauth"` + PasswordAuth PasswordAuthConfig `json:"password"` +} + +type PasswordAuthConfig struct { + Enabled bool `json:"enabled"` + MinLength int `json:"minLength"` } type ProxyAuthConfig struct { diff --git a/backend/storage/bolt/users.go b/backend/storage/bolt/users.go index a7281917..3b628479 100644 --- a/backend/storage/bolt/users.go +++ b/backend/storage/bolt/users.go @@ -7,6 +7,7 @@ import ( "github.com/asdine/storm/v3" "github.com/gtsteffaniak/filebrowser/backend/errors" + "github.com/gtsteffaniak/filebrowser/backend/settings" "github.com/gtsteffaniak/filebrowser/backend/users" "github.com/gtsteffaniak/filebrowser/backend/utils" ) @@ -19,18 +20,21 @@ func (st usersBackend) GetBy(i interface{}) (user *users.User, err error) { user = &users.User{} var arg string - switch val := i.(type) { + var val interface{} + switch i := i.(type) { case uint: + val = i arg = "ID" case int: - i = uint(val) + val = uint(i) case string: arg = "Username" + val = i default: return nil, errors.ErrInvalidDataType } - err = st.db.One(arg, i, user) + err = st.db.One(arg, val, user) if err != nil { if err == storm.ErrNotFound { @@ -82,6 +86,9 @@ func (st usersBackend) Update(user *users.User, fields ...string) error { } func (st usersBackend) Save(user *users.User) error { + if len(user.Password) < settings.Config.Auth.Methods.PasswordAuth.MinLength { + return fmt.Errorf("password must be at least %d characters long", settings.Config.Auth.Methods.PasswordAuth.MinLength) + } pass, err := users.HashPwd(user.Password) if err != nil { return err diff --git a/backend/storage/storage.go b/backend/storage/storage.go index 43c66a8a..5c4833cd 100644 --- a/backend/storage/storage.go +++ b/backend/storage/storage.go @@ -115,7 +115,12 @@ func CreateUser(userInfo users.User, asAdmin bool) error { } newUser.Scope = userHome logger.Debug(fmt.Sprintf("user: %s, home dir: [%s].", newUser.Username, userHome)) + + // todo: fix this, requries index path to be set idx := files.GetIndex("default") + if idx == nil { + idx = files.GetIndex("default") + } _, _, err = idx.GetRealPath(newUser.Scope) if err != nil { logger.Error(fmt.Sprintf("user path is not valid: %v", newUser.Scope))