simple bugfixes beta/v0.5.1 (#344)

This commit is contained in:
Graham Steffaniak 2025-02-01 08:10:46 -05:00 committed by GitHub
parent e269fc8c0a
commit 545a831c66
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 91 additions and 35 deletions

View File

@ -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). 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 ## 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). > 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).

View File

@ -87,38 +87,60 @@ func StartFilebrowser() {
if len(os.Args) > 1 { if len(os.Args) > 1 {
switch os.Args[1] { switch os.Args[1] {
case "set": case "set":
err := setCmd.Parse(os.Args) err := setCmd.Parse(os.Args[2:])
if err != nil { if err != nil {
setCmd.PrintDefaults() setCmd.PrintDefaults()
os.Exit(1) os.Exit(1)
} }
userInfo := strings.Split(user, ",") userInfo := strings.Split(user, ",")
if len(userInfo) < 2 { 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() setCmd.PrintDefaults()
os.Exit(1) os.Exit(1)
} }
username := userInfo[0] username := userInfo[0]
password := userInfo[1] password := userInfo[1]
getStore(dbConfig) store, ok := getStore(dbConfig)
// Create the user logic if !ok {
if asAdmin { logger.Fatal("could not load db info")
logger.Info(fmt.Sprintf("Creating user as admin: %s\n", username))
} else {
logger.Info(fmt.Sprintf("Creating non-admin user: %s\n", username))
} }
user, err := store.Users.Get("", username)
if err != nil {
newUser := users.User{ newUser := users.User{
Username: username, Username: username,
Password: password, Password: password,
} }
if scope != "" { if scope != "" {
newUser.Scope = 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) err = storage.CreateUser(newUser, asAdmin)
if err != nil { if err != nil {
logger.Fatal(fmt.Sprintf("could not create user: %v", err)) logger.Error(fmt.Sprintf("could not create user: %v", err))
} }
return 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": case "version":
fmt.Printf(`FileBrowser Quantum - A modern web-based file manager fmt.Printf(`FileBrowser Quantum - A modern web-based file manager
Version : %v Version : %v
@ -128,7 +150,6 @@ Release Info : https://github.com/gtsteffaniak/filebrowser/releases/tag/%v
return return
} }
} }
store, dbExists := getStore(configPath) store, dbExists := getStore(configPath)
database := fmt.Sprintf("Using existing database : %v", settings.Config.Server.Database) database := fmt.Sprintf("Using existing database : %v", settings.Config.Server.Database)
if !dbExists { if !dbExists {
@ -140,7 +161,7 @@ Release Info : https://github.com/gtsteffaniak/filebrowser/releases/tag/%v
} }
authMethods := []string{} authMethods := []string{}
if settings.Config.Auth.Methods.PasswordAuth { if settings.Config.Auth.Methods.PasswordAuth.Enabled {
authMethods = append(authMethods, "Password") authMethods = append(authMethods, "Password")
} }
if settings.Config.Auth.Methods.ProxyAuth.Enabled { if settings.Config.Auth.Methods.ProxyAuth.Enabled {

View File

@ -2,6 +2,8 @@ package files
import ( import (
"path/filepath" "path/filepath"
"github.com/gtsteffaniak/filebrowser/backend/settings"
) )
// UpdateFileMetadata updates the FileInfo for the specified directory in the index. // UpdateFileMetadata updates the FileInfo for the specified directory in the index.
@ -69,7 +71,9 @@ func GetIndex(name string) *Index {
defer indexesMutex.Unlock() defer indexesMutex.Unlock()
index, ok := indexes[name] index, ok := indexes[name]
if !ok { if !ok {
return nil return &Index{
Source: settings.Source{Name: "default", Path: "."},
}
} }
return index return index
} }

View File

@ -75,7 +75,7 @@ func extractToken(r *http.Request) (string, error) {
} }
func loginHandler(w http.ResponseWriter, r *http.Request) { 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) http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
return return
} }

View File

@ -97,7 +97,7 @@ func withUserHelper(fn handleFunc) handleFunc {
if config.Auth.Methods.NoAuth { if config.Auth.Methods.NoAuth {
var err error var err error
// Retrieve the user from the store and store it in the context // 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 { if err != nil {
logger.Error(fmt.Sprintf("no auth: %v", err)) logger.Error(fmt.Sprintf("no auth: %v", err))
return http.StatusInternalServerError, err return http.StatusInternalServerError, err

View File

@ -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 raw, err := store.Auth.Get("password") //nolint:govet
if err != nil { if err != nil {
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)

View File

@ -110,7 +110,7 @@ func Debug(msg string) {
if len(loggers) > 0 { if len(loggers) > 0 {
Log(levels.DEBUG, msg, true, false, GRAY) Log(levels.DEBUG, msg, true, false, GRAY)
} else { } else {
log.Println("[DEBUG]: " + msg) log.Println("[DEBUG] ", msg)
} }
} }
@ -126,7 +126,7 @@ func Warning(msg string) {
if len(loggers) > 0 { if len(loggers) > 0 {
Log(levels.WARNING, msg, true, false, YELLOW) Log(levels.WARNING, msg, true, false, YELLOW)
} else { } else {
log.Println("[WARN ]: " + msg) log.Println("[WARN ] ", msg)
} }
} }
@ -134,7 +134,7 @@ func Error(msg string) {
if len(loggers) > 0 { if len(loggers) > 0 {
Log(levels.ERROR, msg, true, false, RED) Log(levels.ERROR, msg, true, false, RED)
} else { } else {
log.Println("[ERROR] : ", msg) log.Println("[ERROR] ", msg)
} }
} }
@ -142,5 +142,5 @@ func Fatal(msg string) {
if len(loggers) > 0 { if len(loggers) > 0 {
Log(levels.FATAL, msg, true, false, RED) Log(levels.FATAL, msg, true, false, RED)
} }
log.Fatal("[FATAL] : ", msg) log.Fatal("[FATAL] ", msg)
} }

View File

@ -145,7 +145,10 @@ func setDefaults() Settings {
Header: "", Header: "",
}, },
NoAuth: false, NoAuth: false,
PasswordAuth: true, PasswordAuth: PasswordAuthConfig{
Enabled: true,
MinLength: 5,
},
}, },
}, },
Frontend: Frontend{ Frontend: Frontend{

View File

@ -40,7 +40,12 @@ type Auth struct {
type LoginMethods struct { type LoginMethods struct {
ProxyAuth ProxyAuthConfig `json:"proxy"` ProxyAuth ProxyAuthConfig `json:"proxy"`
NoAuth bool `json:"noauth"` NoAuth bool `json:"noauth"`
PasswordAuth bool `json:"password"` PasswordAuth PasswordAuthConfig `json:"password"`
}
type PasswordAuthConfig struct {
Enabled bool `json:"enabled"`
MinLength int `json:"minLength"`
} }
type ProxyAuthConfig struct { type ProxyAuthConfig struct {

View File

@ -7,6 +7,7 @@ import (
"github.com/asdine/storm/v3" "github.com/asdine/storm/v3"
"github.com/gtsteffaniak/filebrowser/backend/errors" "github.com/gtsteffaniak/filebrowser/backend/errors"
"github.com/gtsteffaniak/filebrowser/backend/settings"
"github.com/gtsteffaniak/filebrowser/backend/users" "github.com/gtsteffaniak/filebrowser/backend/users"
"github.com/gtsteffaniak/filebrowser/backend/utils" "github.com/gtsteffaniak/filebrowser/backend/utils"
) )
@ -19,18 +20,21 @@ func (st usersBackend) GetBy(i interface{}) (user *users.User, err error) {
user = &users.User{} user = &users.User{}
var arg string var arg string
switch val := i.(type) { var val interface{}
switch i := i.(type) {
case uint: case uint:
val = i
arg = "ID" arg = "ID"
case int: case int:
i = uint(val) val = uint(i)
case string: case string:
arg = "Username" arg = "Username"
val = i
default: default:
return nil, errors.ErrInvalidDataType return nil, errors.ErrInvalidDataType
} }
err = st.db.One(arg, i, user) err = st.db.One(arg, val, user)
if err != nil { if err != nil {
if err == storm.ErrNotFound { 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 { 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) pass, err := users.HashPwd(user.Password)
if err != nil { if err != nil {
return err return err

View File

@ -115,7 +115,12 @@ func CreateUser(userInfo users.User, asAdmin bool) error {
} }
newUser.Scope = userHome newUser.Scope = userHome
logger.Debug(fmt.Sprintf("user: %s, home dir: [%s].", newUser.Username, 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") idx := files.GetIndex("default")
if idx == nil {
idx = files.GetIndex("default")
}
_, _, err = idx.GetRealPath(newUser.Scope) _, _, err = idx.GetRealPath(newUser.Scope)
if err != nil { if err != nil {
logger.Error(fmt.Sprintf("user path is not valid: %v", newUser.Scope)) logger.Error(fmt.Sprintf("user path is not valid: %v", newUser.Scope))