refactor: mostly keep existent behavioru

This commit is contained in:
Henrique Dias 2025-11-16 20:45:34 +01:00
parent a05e562fbf
commit 3cde0c007b
22 changed files with 393 additions and 233 deletions

View File

@ -4,7 +4,6 @@ import (
"strings" "strings"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper"
) )
func init() { func init() {
@ -16,7 +15,7 @@ var cmdsAddCmd = &cobra.Command{
Short: "Add a command to run on a specific event", Short: "Add a command to run on a specific event",
Long: `Add a command to run on a specific event.`, Long: `Add a command to run on a specific event.`,
Args: cobra.MinimumNArgs(2), Args: cobra.MinimumNArgs(2),
RunE: python(func(_ *cobra.Command, args []string, v *viper.Viper, d *pythonData) error { RunE: python(func(_ *cobra.Command, args []string, d *pythonData) error {
s, err := d.store.Settings.Get() s, err := d.store.Settings.Get()
if err != nil { if err != nil {
return err return err

View File

@ -2,7 +2,6 @@ package cmd
import ( import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper"
) )
func init() { func init() {
@ -15,12 +14,17 @@ var cmdsLsCmd = &cobra.Command{
Short: "List all commands for each event", Short: "List all commands for each event",
Long: `List all commands for each event.`, Long: `List all commands for each event.`,
Args: cobra.NoArgs, Args: cobra.NoArgs,
RunE: python(func(cmd *cobra.Command, _ []string, v *viper.Viper, d *pythonData) error { RunE: python(func(cmd *cobra.Command, _ []string, d *pythonData) error {
s, err := d.store.Settings.Get() s, err := d.store.Settings.Get()
if err != nil { if err != nil {
return err return err
} }
evt := v.GetString("event")
evt, err := cmd.Flags().GetString("event")
if err != nil {
return err
}
if evt == "" { if evt == "" {
printEvents(s.Commands) printEvents(s.Commands)
} else { } else {
@ -29,6 +33,7 @@ var cmdsLsCmd = &cobra.Command{
show["after_"+evt] = s.Commands["after_"+evt] show["after_"+evt] = s.Commands["after_"+evt]
printEvents(show) printEvents(show)
} }
return nil return nil
}, pythonConfig{}), }, pythonConfig{}),
} }

View File

@ -4,7 +4,6 @@ import (
"strconv" "strconv"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper"
) )
func init() { func init() {
@ -36,7 +35,7 @@ including 'index_end'.`,
return nil return nil
}, },
RunE: python(func(_ *cobra.Command, args []string, v *viper.Viper, d *pythonData) error { RunE: python(func(_ *cobra.Command, args []string, d *pythonData) error {
s, err := d.store.Settings.Get() s, err := d.store.Settings.Get()
if err != nil { if err != nil {
return err return err

View File

@ -10,7 +10,6 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/pflag" "github.com/spf13/pflag"
"github.com/spf13/viper"
"github.com/filebrowser/filebrowser/v2/auth" "github.com/filebrowser/filebrowser/v2/auth"
"github.com/filebrowser/filebrowser/v2/errors" "github.com/filebrowser/filebrowser/v2/errors"
@ -62,8 +61,11 @@ func addConfigFlags(flags *pflag.FlagSet) {
flags.Uint16("tus.retryCount", settings.DefaultTusRetryCount, "the tus retry count") flags.Uint16("tus.retryCount", settings.DefaultTusRetryCount, "the tus retry count")
} }
func getAuthMethod(v *viper.Viper, defaults ...interface{}) (settings.AuthMethod, map[string]interface{}, error) { func getAuthMethod(flags *pflag.FlagSet, defaults ...interface{}) (settings.AuthMethod, map[string]interface{}, error) {
methodStr := v.GetString("auth.method") methodStr, err := flags.GetString("auth.method")
if err != nil {
return "", nil, err
}
method := settings.AuthMethod(methodStr) method := settings.AuthMethod(methodStr)
var defaultAuther map[string]interface{} var defaultAuther map[string]interface{}
@ -90,8 +92,12 @@ func getAuthMethod(v *viper.Viper, defaults ...interface{}) (settings.AuthMethod
return method, defaultAuther, nil return method, defaultAuther, nil
} }
func getProxyAuth(v *viper.Viper, defaultAuther map[string]interface{}) (auth.Auther, error) { func getProxyAuth(flags *pflag.FlagSet, defaultAuther map[string]interface{}) (auth.Auther, error) {
header := v.GetString("auth.header") header, err := flags.GetString("auth.header")
if err != nil {
return nil, err
}
if header == "" { if header == "" {
header = defaultAuther["header"].(string) header = defaultAuther["header"].(string)
} }
@ -107,11 +113,22 @@ func getNoAuth() auth.Auther {
return &auth.NoAuth{} return &auth.NoAuth{}
} }
func getJSONAuth(v *viper.Viper, defaultAuther map[string]interface{}) (auth.Auther, error) { func getJSONAuth(flags *pflag.FlagSet, defaultAuther map[string]interface{}) (auth.Auther, error) {
jsonAuth := &auth.JSONAuth{} jsonAuth := &auth.JSONAuth{}
host := v.GetString("recaptcha.host") host, err := flags.GetString("recaptcha.host")
key := v.GetString("recaptcha.key") if err != nil {
secret := v.GetString("recaptcha.secret") return nil, err
}
key, err := flags.GetString("recaptcha.key")
if err != nil {
return nil, err
}
secret, err := flags.GetString("recaptcha.secret")
if err != nil {
return nil, err
}
if key == "" { if key == "" {
if kmap, ok := defaultAuther["recaptcha"].(map[string]interface{}); ok { if kmap, ok := defaultAuther["recaptcha"].(map[string]interface{}); ok {
@ -135,8 +152,11 @@ func getJSONAuth(v *viper.Viper, defaultAuther map[string]interface{}) (auth.Aut
return jsonAuth, nil return jsonAuth, nil
} }
func getHookAuth(v *viper.Viper, defaultAuther map[string]interface{}) (auth.Auther, error) { func getHookAuth(flags *pflag.FlagSet, defaultAuther map[string]interface{}) (auth.Auther, error) {
command := v.GetString("auth.command") command, err := flags.GetString("auth.command")
if err != nil {
return nil, err
}
if command == "" { if command == "" {
command = defaultAuther["command"].(string) command = defaultAuther["command"].(string)
} }
@ -148,8 +168,8 @@ func getHookAuth(v *viper.Viper, defaultAuther map[string]interface{}) (auth.Aut
return &auth.HookAuth{Command: command}, nil return &auth.HookAuth{Command: command}, nil
} }
func getAuthentication(v *viper.Viper, defaults ...interface{}) (settings.AuthMethod, auth.Auther, error) { func getAuthentication(flags *pflag.FlagSet, defaults ...interface{}) (settings.AuthMethod, auth.Auther, error) {
method, defaultAuther, err := getAuthMethod(v, defaults...) method, defaultAuther, err := getAuthMethod(flags, defaults...)
if err != nil { if err != nil {
return "", nil, err return "", nil, err
} }
@ -157,13 +177,13 @@ func getAuthentication(v *viper.Viper, defaults ...interface{}) (settings.AuthMe
var auther auth.Auther var auther auth.Auther
switch method { switch method {
case auth.MethodProxyAuth: case auth.MethodProxyAuth:
auther, err = getProxyAuth(v, defaultAuther) auther, err = getProxyAuth(flags, defaultAuther)
case auth.MethodNoAuth: case auth.MethodNoAuth:
auther = getNoAuth() auther = getNoAuth()
case auth.MethodJSONAuth: case auth.MethodJSONAuth:
auther, err = getJSONAuth(v, defaultAuther) auther, err = getJSONAuth(flags, defaultAuther)
case auth.MethodHookAuth: case auth.MethodHookAuth:
auther, err = getHookAuth(v, defaultAuther) auther, err = getHookAuth(flags, defaultAuther)
default: default:
return "", nil, errors.ErrInvalidAuthMethod return "", nil, errors.ErrInvalidAuthMethod
} }

View File

@ -2,7 +2,6 @@ package cmd
import ( import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper"
) )
func init() { func init() {
@ -14,7 +13,7 @@ var configCatCmd = &cobra.Command{
Short: "Prints the configuration", Short: "Prints the configuration",
Long: `Prints the configuration.`, Long: `Prints the configuration.`,
Args: cobra.NoArgs, Args: cobra.NoArgs,
RunE: python(func(_ *cobra.Command, _ []string, v *viper.Viper, d *pythonData) error { RunE: python(func(_ *cobra.Command, _ []string, d *pythonData) error {
set, err := d.store.Settings.Get() set, err := d.store.Settings.Get()
if err != nil { if err != nil {
return err return err

View File

@ -2,7 +2,6 @@ package cmd
import ( import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper"
) )
func init() { func init() {
@ -16,7 +15,7 @@ var configExportCmd = &cobra.Command{
json or yaml file. This exported configuration can be changed, json or yaml file. This exported configuration can be changed,
and imported again with 'config import' command.`, and imported again with 'config import' command.`,
Args: jsonYamlArg, Args: jsonYamlArg,
RunE: python(func(_ *cobra.Command, args []string, v *viper.Viper, d *pythonData) error { RunE: python(func(_ *cobra.Command, args []string, d *pythonData) error {
settings, err := d.store.Settings.Get() settings, err := d.store.Settings.Get()
if err != nil { if err != nil {
return err return err

View File

@ -7,7 +7,6 @@ import (
"reflect" "reflect"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/filebrowser/filebrowser/v2/auth" "github.com/filebrowser/filebrowser/v2/auth"
"github.com/filebrowser/filebrowser/v2/settings" "github.com/filebrowser/filebrowser/v2/settings"
@ -35,7 +34,7 @@ database.
The path must be for a json or yaml file.`, The path must be for a json or yaml file.`,
Args: jsonYamlArg, Args: jsonYamlArg,
RunE: python(func(_ *cobra.Command, args []string, v *viper.Viper, d *pythonData) error { RunE: python(func(_ *cobra.Command, args []string, d *pythonData) error {
var key []byte var key []byte
var err error var err error
if d.hadDB { if d.hadDB {

View File

@ -4,8 +4,8 @@ import (
"fmt" "fmt"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/filebrowser/filebrowser/v2/auth"
"github.com/filebrowser/filebrowser/v2/settings" "github.com/filebrowser/filebrowser/v2/settings"
) )
@ -23,68 +23,148 @@ this options can be changed in the future with the command
to the defaults when creating new users and you don't to the defaults when creating new users and you don't
override the options.`, override the options.`,
Args: cobra.NoArgs, Args: cobra.NoArgs,
RunE: python(func(cmd *cobra.Command, _ []string, v *viper.Viper, d *pythonData) error { RunE: python(func(cmd *cobra.Command, _ []string, d *pythonData) error {
defaults := settings.UserDefaults{} flags := cmd.Flags()
err := getUserDefaults(v, &defaults, true)
if err != nil {
return err
}
authMethod, auther, err := getAuthentication(v)
if err != nil {
return err
}
// General Settings
s := &settings.Settings{ s := &settings.Settings{
Key: generateKey(), Key: generateKey(),
Signup: v.GetBool("signup"),
HideLoginButton: v.GetBool("hideLoginButton"),
CreateUserDir: v.GetBool("createUserDir"),
MinimumPasswordLength: v.GetUint("minimumPasswordLength"),
Shell: convertCmdStrToCmdArray(v.GetString("shell")),
AuthMethod: authMethod,
Defaults: defaults,
Branding: settings.Branding{
Name: v.GetString("branding.name"),
DisableExternal: v.GetBool("branding.disableExternal"),
DisableUsedPercentage: v.GetBool("branding.disableUsedPercentage"),
Theme: v.GetString("branding.theme"),
Files: v.GetString("branding.files"),
},
Tus: settings.Tus{
ChunkSize: v.GetUint64("tus.chunkSize"),
RetryCount: v.GetUint16("tus.retryCount"),
},
} }
s.FileMode, err = parseFileMode(v.GetString("fileMode")) err := getUserDefaults(flags, &s.Defaults, true)
if err != nil { if err != nil {
return err return err
} }
s.DirMode, err = parseFileMode(v.GetString("dirMode")) s.Signup, err = flags.GetBool("signup")
if err != nil { if err != nil {
return err return err
} }
ser := &settings.Server{ s.HideLoginButton, err = flags.GetBool("hideLoginButton")
Address: v.GetString("address"), if err != nil {
Socket: v.GetString("socket"), return err
Root: v.GetString("root"), }
BaseURL: v.GetString("baseurl"),
TLSKey: v.GetString("key"), s.CreateUserDir, err = flags.GetBool("createUserDir")
TLSCert: v.GetString("cert"), if err != nil {
Port: v.GetString("port"), return err
Log: v.GetString("log"), }
s.MinimumPasswordLength, err = flags.GetUint("minimumPasswordLength")
if err != nil {
return err
}
shell, err := flags.GetString("shell")
if err != nil {
return err
}
s.Shell = convertCmdStrToCmdArray(shell)
s.FileMode, err = getAndParseFileMode(flags, "fileMode")
if err != nil {
return err
}
s.DirMode, err = getAndParseFileMode(flags, "dirMode")
if err != nil {
return err
}
s.Branding.Name, err = flags.GetString("branding.name")
if err != nil {
return err
}
s.Branding.DisableExternal, err = flags.GetBool("branding.disableExternal")
if err != nil {
return err
}
s.Branding.DisableUsedPercentage, err = flags.GetBool("branding.disableUsedPercentage")
if err != nil {
return err
}
s.Branding.Theme, err = flags.GetString("branding.themes")
if err != nil {
return err
}
s.Branding.Files, err = flags.GetString("branding.files")
if err != nil {
return err
}
s.Tus.ChunkSize, err = flags.GetUint64("tus.chunkSize")
if err != nil {
return err
}
s.Tus.RetryCount, err = flags.GetUint16("tus.retryCount")
if err != nil {
return err
}
var auther auth.Auther
s.AuthMethod, auther, err = getAuthentication(flags)
if err != nil {
return err
}
// Server Settings
ser := &settings.Server{}
ser.Address, err = flags.GetString("address")
if err != nil {
return err
}
ser.Socket, err = flags.GetString("socket")
if err != nil {
return err
}
ser.Root, err = flags.GetString("root")
if err != nil {
return err
}
ser.BaseURL, err = flags.GetString("baseURL")
if err != nil {
return err
}
ser.TLSKey, err = flags.GetString("key")
if err != nil {
return err
}
ser.TLSCert, err = flags.GetString("cert")
if err != nil {
return err
}
ser.Port, err = flags.GetString("port")
if err != nil {
return err
}
ser.Log, err = flags.GetString("log")
if err != nil {
return err
} }
err = d.store.Settings.Save(s) err = d.store.Settings.Save(s)
if err != nil { if err != nil {
return err return err
} }
err = d.store.Settings.SaveServer(ser) err = d.store.Settings.SaveServer(ser)
if err != nil { if err != nil {
return err return err
} }
err = d.store.Auth.Save(auther) err = d.store.Auth.Save(auther)
if err != nil { if err != nil {
return err return err

View File

@ -2,7 +2,7 @@ package cmd
import ( import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper" "github.com/spf13/pflag"
) )
func init() { func init() {
@ -16,7 +16,9 @@ var configSetCmd = &cobra.Command{
Long: `Updates the configuration. Set the flags for the options Long: `Updates the configuration. Set the flags for the options
you want to change. Other options will remain unchanged.`, you want to change. Other options will remain unchanged.`,
Args: cobra.NoArgs, Args: cobra.NoArgs,
RunE: python(func(cmd *cobra.Command, _ []string, v *viper.Viper, d *pythonData) error { RunE: python(func(cmd *cobra.Command, _ []string, d *pythonData) error {
flags := cmd.Flags()
set, err := d.store.Settings.Get() set, err := d.store.Settings.Get()
if err != nil { if err != nil {
return err return err
@ -29,70 +31,73 @@ you want to change. Other options will remain unchanged.`,
hasAuth := false hasAuth := false
for _, key := range v.AllKeys() { flags.Visit(func(flag *pflag.Flag) {
if !v.IsSet(key) { if err != nil {
continue return
} }
switch key { switch flag.Name {
case "baseurl": case "baseURL":
ser.BaseURL = v.GetString(key) ser.BaseURL, err = flags.GetString(flag.Name)
case "root": case "root":
ser.Root = v.GetString(key) ser.Root, err = flags.GetString(flag.Name)
case "socket": case "socket":
ser.Socket = v.GetString(key) ser.Socket, err = flags.GetString(flag.Name)
case "cert": case "cert":
ser.TLSCert = v.GetString(key) ser.TLSCert, err = flags.GetString(flag.Name)
case "key": case "key":
ser.TLSKey = v.GetString(key) ser.TLSKey, err = flags.GetString(flag.Name)
case "address": case "address":
ser.Address = v.GetString(key) ser.Address, err = flags.GetString(flag.Name)
case "port": case "port":
ser.Port = v.GetString(key) ser.Port, err = flags.GetString(flag.Name)
case "log": case "log":
ser.Log = v.GetString(key) ser.Log, err = flags.GetString(flag.Name)
case "hideloginbutton": case "hideLoginButton":
set.HideLoginButton = v.GetBool(key) set.HideLoginButton, err = flags.GetBool(flag.Name)
case "signup": case "signup":
set.Signup = v.GetBool(key) set.Signup, err = flags.GetBool(flag.Name)
case "auth.method": case "auth.method":
hasAuth = true hasAuth = true
case "shell": case "shell":
var shell string var shell string
shell = v.GetString(key) shell, err = flags.GetString(flag.Name)
if err != nil {
return
}
set.Shell = convertCmdStrToCmdArray(shell) set.Shell = convertCmdStrToCmdArray(shell)
case "createuserdir": case "createUserDir":
set.CreateUserDir = v.GetBool(key) set.CreateUserDir, err = flags.GetBool(flag.Name)
case "minimumpasswordlength": case "minimumPasswordLength":
set.MinimumPasswordLength = v.GetUint(key) set.MinimumPasswordLength, err = flags.GetUint(flag.Name)
case "branding.name": case "branding.name":
set.Branding.Name = v.GetString(key) set.Branding.Name, err = flags.GetString(flag.Name)
case "branding.color": case "branding.color":
set.Branding.Color = v.GetString(key) set.Branding.Color, err = flags.GetString(flag.Name)
case "branding.theme": case "branding.theme":
set.Branding.Theme = v.GetString(key) set.Branding.Theme, err = flags.GetString(flag.Name)
case "branding.disableexternal": case "branding.disableExternal":
set.Branding.DisableExternal = v.GetBool(key) set.Branding.DisableExternal, err = flags.GetBool(flag.Name)
case "branding.disableusedpercentage": case "branding.disableUsedPercentage":
set.Branding.DisableUsedPercentage = v.GetBool(key) set.Branding.DisableUsedPercentage, err = flags.GetBool(flag.Name)
case "branding.files": case "branding.files":
set.Branding.Files = v.GetString(key) set.Branding.Files, err = flags.GetString(flag.Name)
case "filemode": case "fileMode":
set.FileMode, err = parseFileMode(v.GetString(key)) set.FileMode, err = getAndParseFileMode(flags, flag.Name)
case "dirmode": case "dirMode":
set.DirMode, err = parseFileMode(v.GetString(key)) set.DirMode, err = getAndParseFileMode(flags, flag.Name)
case "tus.chunksize": case "tus.chunkSize":
set.Tus.ChunkSize = v.GetUint64(key) set.Tus.ChunkSize, err = flags.GetUint64(flag.Name)
case "tus.retrycount": case "tus.retryCount":
set.Tus.RetryCount = v.GetUint16(key) set.Tus.RetryCount, err = flags.GetUint16(flag.Name)
} }
})
if err != nil { if err != nil {
return err return err
} }
}
err = getUserDefaults(v, &set.Defaults, false) err = getUserDefaults(cmd.Flags(), &set.Defaults, false)
if err != nil { if err != nil {
return err return err
} }
@ -104,7 +109,7 @@ you want to change. Other options will remain unchanged.`,
} }
// check if there are new flags for existing auth method // check if there are new flags for existing auth method
set.AuthMethod, auther, err = getAuthentication(v, hasAuth, set, auther) set.AuthMethod, auther, err = getAuthentication(flags, hasAuth, set, auther)
if err != nil { if err != nil {
return err return err
} }

View File

@ -134,23 +134,23 @@ The precedence of the configuration values are as follows:
Also, if the database path doesn't exist, File Browser will enter into Also, if the database path doesn't exist, File Browser will enter into
the quick setup mode and a new database will be bootstrapped and a new the quick setup mode and a new database will be bootstrapped and a new
user created with the credentials from options "username" and "password".`, user created with the credentials from options "username" and "password".`,
RunE: python(func(cmd *cobra.Command, _ []string, v *viper.Viper, d *pythonData) error { RunE: python(func(cmd *cobra.Command, _ []string, d *pythonData) error {
if !d.hadDB { if !d.hadDB {
err := quickSetup(v, *d) err := quickSetup(d.viper, *d)
if err != nil { if err != nil {
return err return err
} }
} }
// build img service // build img service
workersCount := v.GetInt("imageProcessors") imgWorkersCount := d.viper.GetInt("imageProcessors")
if workersCount < 1 { if imgWorkersCount < 1 {
return errors.New("image resize workers count could not be < 1") return errors.New("image resize workers count could not be < 1")
} }
imgSvc := img.New(workersCount) imageService := img.New(imgWorkersCount)
var fileCache diskcache.Interface = diskcache.NewNoOp() var fileCache diskcache.Interface = diskcache.NewNoOp()
cacheDir := v.GetString("cacheDir") cacheDir := d.viper.GetString("cacheDir")
if cacheDir != "" { if cacheDir != "" {
if err := os.MkdirAll(cacheDir, 0700); err != nil { if err := os.MkdirAll(cacheDir, 0700); err != nil {
return fmt.Errorf("can't make directory %s: %w", cacheDir, err) return fmt.Errorf("can't make directory %s: %w", cacheDir, err)
@ -158,7 +158,7 @@ user created with the credentials from options "username" and "password".`,
fileCache = diskcache.New(afero.NewOsFs(), cacheDir) fileCache = diskcache.New(afero.NewOsFs(), cacheDir)
} }
server, err := getRunParams(v, d.store) server, err := getServerSettings(d.viper, d.store)
if err != nil { if err != nil {
return err return err
} }
@ -180,7 +180,7 @@ user created with the credentials from options "username" and "password".`,
if err != nil { if err != nil {
return err return err
} }
socketPerm := v.GetUint32("socketPerm") socketPerm := d.viper.GetUint32("socketPerm")
err = os.Chmod(server.Socket, os.FileMode(socketPerm)) err = os.Chmod(server.Socket, os.FileMode(socketPerm))
if err != nil { if err != nil {
return err return err
@ -209,7 +209,7 @@ user created with the credentials from options "username" and "password".`,
panic(err) panic(err)
} }
handler, err := fbhttp.NewHandler(imgSvc, fileCache, d.store, server, assetsFs) handler, err := fbhttp.NewHandler(imageService, fileCache, d.store, server, assetsFs)
if err != nil { if err != nil {
return err return err
} }
@ -253,52 +253,56 @@ user created with the credentials from options "username" and "password".`,
}, pythonConfig{allowNoDB: true}), }, pythonConfig{allowNoDB: true}),
} }
func getRunParams(v *viper.Viper, st *storage.Storage) (*settings.Server, error) { func getServerSettings(v *viper.Viper, st *storage.Storage) (*settings.Server, error) {
server, err := st.Settings.GetServer() server, err := st.Settings.GetServer()
if err != nil { if err != nil {
return nil, err return nil, err
} }
if val, set := getStringParamB(v, "root"); set { if val, set := vGetStringIsSet(v, "root"); set {
server.Root = val server.Root = val
} }
if val, set := getStringParamB(v, "baseurl"); set { if val, set := vGetStringIsSet(v, "baseURL"); set {
server.BaseURL = val server.BaseURL = val
} }
if val, set := getStringParamB(v, "log"); set { if val, set := vGetStringIsSet(v, "log"); set {
server.Log = val server.Log = val
} }
isSocketSet := false isSocketSet := false
isAddrSet := false isAddrSet := false
if val, set := getStringParamB(v, "address"); set { if val, set := vGetStringIsSet(v, "address"); set {
server.Address = val server.Address = val
isAddrSet = isAddrSet || set isAddrSet = isAddrSet || set
} }
if val, set := getStringParamB(v, "port"); set { if val, set := vGetStringIsSet(v, "port"); set {
server.Port = val server.Port = val
isAddrSet = isAddrSet || set isAddrSet = isAddrSet || set
} }
if val, set := getStringParamB(v, "key"); set { if val, set := vGetStringIsSet(v, "key"); set {
server.TLSKey = val server.TLSKey = val
isAddrSet = isAddrSet || set isAddrSet = isAddrSet || set
} }
if val, set := getStringParamB(v, "cert"); set { if val, set := vGetStringIsSet(v, "cert"); set {
server.TLSCert = val server.TLSCert = val
isAddrSet = isAddrSet || set isAddrSet = isAddrSet || set
} }
if val, set := getStringParamB(v, "socket"); set { if val, set := vGetStringIsSet(v, "socket"); set {
server.Socket = val server.Socket = val
isSocketSet = isSocketSet || set isSocketSet = isSocketSet || set
} }
if val, set := vGetStringIsSet(v, "tokenExpirationTime"); set {
server.TokenExpirationTime = val
}
if isAddrSet && isSocketSet { if isAddrSet && isSocketSet {
return nil, errors.New("--socket flag cannot be used with --address, --port, --key nor --cert") return nil, errors.New("--socket flag cannot be used with --address, --port, --key nor --cert")
} }
@ -308,17 +312,10 @@ func getRunParams(v *viper.Viper, st *storage.Storage) (*settings.Server, error)
server.Socket = "" server.Socket = ""
} }
disableThumbnails := v.GetBool("disableThumbnails") server.EnableThumbnails = !v.GetBool("disableThumbnails")
server.EnableThumbnails = !disableThumbnails server.ResizePreview = !v.GetBool("disablePreviewResize")
server.TypeDetectionByHeader = !v.GetBool("disableTypeDetectionByHeader")
disablePreviewResize := v.GetBool("disablePreviewResize") server.EnableExec = !v.GetBool("disableExec")
server.ResizePreview = !disablePreviewResize
disableTypeDetectionByHeader := v.GetBool("disableTypeDetectionByHeader")
server.TypeDetectionByHeader = !disableTypeDetectionByHeader
disableExec := v.GetBool("disableExec")
server.EnableExec = !disableExec
if server.EnableExec { if server.EnableExec {
log.Println("WARNING: Command Runner feature enabled!") log.Println("WARNING: Command Runner feature enabled!")
@ -327,14 +324,10 @@ func getRunParams(v *viper.Viper, st *storage.Storage) (*settings.Server, error)
log.Println("WARNING: read https://github.com/filebrowser/filebrowser/issues/5199") log.Println("WARNING: read https://github.com/filebrowser/filebrowser/issues/5199")
} }
if val, set := getStringParamB(v, "tokenExpirationTime"); set {
server.TokenExpirationTime = val
}
return server, nil return server, nil
} }
func getStringParamB(v *viper.Viper, key string) (string, bool) { func vGetStringIsSet(v *viper.Viper, key string) (string, bool) {
return v.GetString(key), v.IsSet(key) return v.GetString(key), v.IsSet(key)
} }
@ -394,7 +387,7 @@ func quickSetup(v *viper.Viper, d pythonData) error {
} }
var err error var err error
if _, noauth := getStringParamB(v, "noauth"); noauth { if _, noauth := vGetStringIsSet(v, "noauth"); noauth {
set.AuthMethod = auth.MethodNoAuth set.AuthMethod = auth.MethodNoAuth
err = d.store.Auth.Save(&auth.NoAuth{}) err = d.store.Auth.Save(&auth.NoAuth{})
} else { } else {

View File

@ -4,7 +4,6 @@ import (
"strconv" "strconv"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/filebrowser/filebrowser/v2/settings" "github.com/filebrowser/filebrowser/v2/settings"
"github.com/filebrowser/filebrowser/v2/users" "github.com/filebrowser/filebrowser/v2/users"
@ -41,7 +40,7 @@ including 'index_end'.`,
return nil return nil
}, },
RunE: python(func(cmd *cobra.Command, args []string, v *viper.Viper, d *pythonData) error { RunE: python(func(cmd *cobra.Command, args []string, d *pythonData) error {
i, err := strconv.Atoi(args[0]) i, err := strconv.Atoi(args[0])
if err != nil { if err != nil {
return err return err
@ -64,6 +63,6 @@ including 'index_end'.`,
return d.store.Settings.Save(s) return d.store.Settings.Save(s)
} }
return runRules(d.store, cmd, v, user, global) return runRules(d.store, cmd, user, global)
}, pythonConfig{}), }, pythonConfig{}),
} }

View File

@ -4,7 +4,7 @@ import (
"fmt" "fmt"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper" "github.com/spf13/pflag"
"github.com/filebrowser/filebrowser/v2/rules" "github.com/filebrowser/filebrowser/v2/rules"
"github.com/filebrowser/filebrowser/v2/settings" "github.com/filebrowser/filebrowser/v2/settings"
@ -29,8 +29,8 @@ rules.`,
Args: cobra.NoArgs, Args: cobra.NoArgs,
} }
func runRules(st *storage.Storage, cmd *cobra.Command, v *viper.Viper, usersFn func(*users.User) error, globalFn func(*settings.Settings) error) error { func runRules(st *storage.Storage, cmd *cobra.Command, usersFn func(*users.User) error, globalFn func(*settings.Settings) error) error {
id, err := getUserIdentifier(v) id, err := getUserIdentifier(cmd.Flags())
if err != nil { if err != nil {
return err return err
} }
@ -68,9 +68,16 @@ func runRules(st *storage.Storage, cmd *cobra.Command, v *viper.Viper, usersFn f
return nil return nil
} }
func getUserIdentifier(v *viper.Viper) (interface{}, error) { func getUserIdentifier(flags *pflag.FlagSet) (interface{}, error) {
id := v.GetUint("id") id, err := flags.GetUint("id")
username := v.GetString("username") if err != nil {
return nil, err
}
username, err := flags.GetString("username")
if err != nil {
return nil, err
}
if id != 0 { if id != 0 {
return id, nil return id, nil

View File

@ -4,7 +4,6 @@ import (
"regexp" "regexp"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/filebrowser/filebrowser/v2/rules" "github.com/filebrowser/filebrowser/v2/rules"
"github.com/filebrowser/filebrowser/v2/settings" "github.com/filebrowser/filebrowser/v2/settings"
@ -22,9 +21,19 @@ var rulesAddCmd = &cobra.Command{
Short: "Add a global rule or user rule", Short: "Add a global rule or user rule",
Long: `Add a global rule or user rule.`, Long: `Add a global rule or user rule.`,
Args: cobra.ExactArgs(1), Args: cobra.ExactArgs(1),
RunE: python(func(cmd *cobra.Command, args []string, v *viper.Viper, d *pythonData) error { RunE: python(func(cmd *cobra.Command, args []string, d *pythonData) error {
allow := v.GetBool("allow") flags := cmd.Flags()
regex := v.GetBool("regex")
allow, err := flags.GetBool("allow")
if err != nil {
return err
}
regex, err := flags.GetBool("regex")
if err != nil {
return err
}
exp := args[0] exp := args[0]
if regex { if regex {
@ -52,6 +61,6 @@ var rulesAddCmd = &cobra.Command{
return d.store.Settings.Save(s) return d.store.Settings.Save(s)
} }
return runRules(d.store, cmd, v, user, global) return runRules(d.store, cmd, user, global)
}, pythonConfig{}), }, pythonConfig{}),
} }

View File

@ -2,7 +2,6 @@ package cmd
import ( import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper"
) )
func init() { func init() {
@ -14,7 +13,7 @@ var rulesLsCommand = &cobra.Command{
Short: "List global rules or user specific rules", Short: "List global rules or user specific rules",
Long: `List global rules or user specific rules.`, Long: `List global rules or user specific rules.`,
Args: cobra.NoArgs, Args: cobra.NoArgs,
RunE: python(func(cmd *cobra.Command, _ []string, v *viper.Viper, d *pythonData) error { RunE: python(func(cmd *cobra.Command, _ []string, d *pythonData) error {
return runRules(d.store, cmd, v, nil, nil) return runRules(d.store, cmd, nil, nil)
}, pythonConfig{}), }, pythonConfig{}),
} }

View File

@ -9,7 +9,6 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/pflag" "github.com/spf13/pflag"
"github.com/spf13/viper"
"github.com/filebrowser/filebrowser/v2/settings" "github.com/filebrowser/filebrowser/v2/settings"
"github.com/filebrowser/filebrowser/v2/users" "github.com/filebrowser/filebrowser/v2/users"
@ -83,64 +82,72 @@ func addUserFlags(flags *pflag.FlagSet) {
flags.String("aceEditorTheme", "", "ace editor's syntax highlighting theme for users") flags.String("aceEditorTheme", "", "ace editor's syntax highlighting theme for users")
} }
func getAndParseViewMode(v *viper.Viper) (users.ViewMode, error) { func getAndParseViewMode(flags *pflag.FlagSet) (users.ViewMode, error) {
viewModeStr := v.GetString("viewMode") viewModeStr, err := flags.GetString("viewMode")
if err != nil {
return "", err
}
viewMode := users.ViewMode(viewModeStr) viewMode := users.ViewMode(viewModeStr)
if viewMode != users.ListViewMode && viewMode != users.MosaicViewMode { if viewMode != users.ListViewMode && viewMode != users.MosaicViewMode {
return "", errors.New("view mode must be \"" + string(users.ListViewMode) + "\" or \"" + string(users.MosaicViewMode) + "\"") return "", errors.New("view mode must be \"" + string(users.ListViewMode) + "\" or \"" + string(users.MosaicViewMode) + "\"")
} }
return viewMode, nil return viewMode, nil
} }
func getUserDefaults(v *viper.Viper, defaults *settings.UserDefaults, all bool) error { func getUserDefaults(flags *pflag.FlagSet, defaults *settings.UserDefaults, all bool) error {
keys := v.AllKeys() errs := []error{}
for _, key := range keys {
if !all && !v.IsSet(key) {
continue
}
visit := func(flag *pflag.Flag) {
var err error var err error
switch key { switch flag.Name {
case "scope": case "scope":
defaults.Scope = v.GetString(key) defaults.Scope, err = flags.GetString(flag.Name)
case "locale": case "locale":
defaults.Locale = v.GetString(key) defaults.Locale, err = flags.GetString(flag.Name)
case "viewmode": case "viewMode":
defaults.ViewMode, err = getAndParseViewMode(v) defaults.ViewMode, err = getAndParseViewMode(flags)
case "singleclick": case "singleClick":
defaults.SingleClick = v.GetBool(key) defaults.SingleClick, err = flags.GetBool(flag.Name)
case "aceeditortheme": case "aceEditorTheme":
defaults.AceEditorTheme = v.GetString(key) defaults.AceEditorTheme, err = flags.GetString(flag.Name)
case "perm.admin": case "perm.admin":
defaults.Perm.Admin = v.GetBool(key) defaults.Perm.Admin, err = flags.GetBool(flag.Name)
case "perm.execute": case "perm.execute":
defaults.Perm.Execute = v.GetBool(key) defaults.Perm.Execute, err = flags.GetBool(flag.Name)
case "perm.create": case "perm.create":
defaults.Perm.Create = v.GetBool(key) defaults.Perm.Create, err = flags.GetBool(flag.Name)
case "perm.rename": case "perm.rename":
defaults.Perm.Rename = v.GetBool(key) defaults.Perm.Rename, err = flags.GetBool(flag.Name)
case "perm.modify": case "perm.modify":
defaults.Perm.Modify = v.GetBool(key) defaults.Perm.Modify, err = flags.GetBool(flag.Name)
case "perm.delete": case "perm.delete":
defaults.Perm.Delete = v.GetBool(key) defaults.Perm.Delete, err = flags.GetBool(flag.Name)
case "perm.share": case "perm.share":
defaults.Perm.Share = v.GetBool(key) defaults.Perm.Share, err = flags.GetBool(flag.Name)
case "perm.download": case "perm.download":
defaults.Perm.Download = v.GetBool(key) defaults.Perm.Download, err = flags.GetBool(flag.Name)
case "commands": case "commands":
defaults.Commands = v.GetStringSlice(key) defaults.Commands, err = flags.GetStringSlice(flag.Name)
case "sorting.by": case "sorting.by":
defaults.Sorting.By = v.GetString(key) defaults.Sorting.By, err = flags.GetString(flag.Name)
case "sorting.asc": case "sorting.asc":
defaults.Sorting.Asc = v.GetBool(key) defaults.Sorting.Asc, err = flags.GetBool(flag.Name)
case "hidedotfiles": case "hideDotfiles":
defaults.HideDotfiles = v.GetBool(key) defaults.HideDotfiles, err = flags.GetBool(flag.Name)
} }
if err != nil { if err != nil {
return err errs = append(errs, err)
} }
} }
return nil if all {
flags.VisitAll(visit)
} else {
flags.Visit(visit)
}
return errors.Join(errs...)
} }

View File

@ -2,7 +2,6 @@ package cmd
import ( import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/filebrowser/filebrowser/v2/users" "github.com/filebrowser/filebrowser/v2/users"
) )
@ -17,12 +16,13 @@ var usersAddCmd = &cobra.Command{
Short: "Create a new user", Short: "Create a new user",
Long: `Create a new user and add it to the database.`, Long: `Create a new user and add it to the database.`,
Args: cobra.ExactArgs(2), Args: cobra.ExactArgs(2),
RunE: python(func(cmd *cobra.Command, args []string, v *viper.Viper, d *pythonData) error { RunE: python(func(cmd *cobra.Command, args []string, d *pythonData) error {
flags := cmd.Flags()
s, err := d.store.Settings.Get() s, err := d.store.Settings.Get()
if err != nil { if err != nil {
return err return err
} }
err = getUserDefaults(v, &s.Defaults, false) err = getUserDefaults(flags, &s.Defaults, false)
if err != nil { if err != nil {
return err return err
} }
@ -35,9 +35,21 @@ var usersAddCmd = &cobra.Command{
user := &users.User{ user := &users.User{
Username: args[0], Username: args[0],
Password: password, Password: password,
LockPassword: v.GetBool("lockPassword"), }
DateFormat: v.GetBool("dateFormat"),
HideDotfiles: v.GetBool("hideDotfiles"), user.LockPassword, err = flags.GetBool("lockPassword")
if err != nil {
return err
}
user.DateFormat, err = flags.GetBool("dateFormat")
if err != nil {
return err
}
user.HideDotfiles, err = flags.GetBool("hideDotfiles")
if err != nil {
return err
} }
s.Defaults.Apply(user) s.Defaults.Apply(user)

View File

@ -2,7 +2,6 @@ package cmd
import ( import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper"
) )
func init() { func init() {
@ -15,7 +14,7 @@ var usersExportCmd = &cobra.Command{
Long: `Export all users to a json or yaml file. Please indicate the Long: `Export all users to a json or yaml file. Please indicate the
path to the file where you want to write the users.`, path to the file where you want to write the users.`,
Args: jsonYamlArg, Args: jsonYamlArg,
RunE: python(func(_ *cobra.Command, args []string, v *viper.Viper, d *pythonData) error { RunE: python(func(_ *cobra.Command, args []string, d *pythonData) error {
list, err := d.store.Users.Gets("") list, err := d.store.Users.Gets("")
if err != nil { if err != nil {
return err return err

View File

@ -2,7 +2,6 @@ package cmd
import ( import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/filebrowser/filebrowser/v2/users" "github.com/filebrowser/filebrowser/v2/users"
) )
@ -27,7 +26,7 @@ var usersLsCmd = &cobra.Command{
RunE: findUsers, RunE: findUsers,
} }
var findUsers = python(func(_ *cobra.Command, args []string, v *viper.Viper, d *pythonData) error { var findUsers = python(func(_ *cobra.Command, args []string, d *pythonData) error {
var ( var (
list []*users.User list []*users.User
user *users.User user *users.User

View File

@ -7,7 +7,6 @@ import (
"strconv" "strconv"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/filebrowser/filebrowser/v2/users" "github.com/filebrowser/filebrowser/v2/users"
) )
@ -26,7 +25,8 @@ file. You can use this command to import new users to your
installation. For that, just don't place their ID on the files installation. For that, just don't place their ID on the files
list or set it to 0.`, list or set it to 0.`,
Args: jsonYamlArg, Args: jsonYamlArg,
RunE: python(func(cmd *cobra.Command, args []string, v *viper.Viper, d *pythonData) error { RunE: python(func(cmd *cobra.Command, args []string, d *pythonData) error {
flags := cmd.Flags()
fd, err := os.Open(args[0]) fd, err := os.Open(args[0])
if err != nil { if err != nil {
return err return err
@ -46,7 +46,12 @@ list or set it to 0.`,
} }
} }
if v.GetBool("replace") { replace, err := flags.GetBool("replace")
if err != nil {
return err
}
if replace {
oldUsers, userImportErr := d.store.Users.Gets("") oldUsers, userImportErr := d.store.Users.Gets("")
if userImportErr != nil { if userImportErr != nil {
return userImportErr return userImportErr
@ -65,7 +70,10 @@ list or set it to 0.`,
} }
} }
overwrite := v.GetBool("overwrite") overwrite, err := flags.GetBool("overwrite")
if err != nil {
return err
}
for _, user := range list { for _, user := range list {
onDB, err := d.store.Users.Get("", user.ID) onDB, err := d.store.Users.Get("", user.ID)

View File

@ -4,7 +4,6 @@ import (
"fmt" "fmt"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper"
) )
func init() { func init() {
@ -16,7 +15,7 @@ var usersRmCmd = &cobra.Command{
Short: "Delete a user by username or id", Short: "Delete a user by username or id",
Long: `Delete a user by username or id`, Long: `Delete a user by username or id`,
Args: cobra.ExactArgs(1), Args: cobra.ExactArgs(1),
RunE: python(func(_ *cobra.Command, args []string, v *viper.Viper, d *pythonData) error { RunE: python(func(_ *cobra.Command, args []string, d *pythonData) error {
username, id := parseUsernameOrID(args[0]) username, id := parseUsernameOrID(args[0])
var err error var err error

View File

@ -2,7 +2,6 @@ package cmd
import ( import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/filebrowser/filebrowser/v2/settings" "github.com/filebrowser/filebrowser/v2/settings"
"github.com/filebrowser/filebrowser/v2/users" "github.com/filebrowser/filebrowser/v2/users"
@ -22,10 +21,18 @@ var usersUpdateCmd = &cobra.Command{
Long: `Updates an existing user. Set the flags for the Long: `Updates an existing user. Set the flags for the
options you want to change.`, options you want to change.`,
Args: cobra.ExactArgs(1), Args: cobra.ExactArgs(1),
RunE: python(func(cmd *cobra.Command, args []string, v *viper.Viper, d *pythonData) error { RunE: python(func(cmd *cobra.Command, args []string, d *pythonData) error {
flags := cmd.Flags()
username, id := parseUsernameOrID(args[0]) username, id := parseUsernameOrID(args[0])
password := v.GetString("password") password, err := flags.GetString("password")
newUsername := v.GetString("username") if err != nil {
return err
}
newUsername, err := flags.GetString("username")
if err != nil {
return err
}
s, err := d.store.Settings.Get() s, err := d.store.Settings.Get()
if err != nil { if err != nil {
@ -35,13 +42,11 @@ options you want to change.`,
var ( var (
user *users.User user *users.User
) )
if id != 0 { if id != 0 {
user, err = d.store.Users.Get("", id) user, err = d.store.Users.Get("", id)
} else { } else {
user, err = d.store.Users.Get("", username) user, err = d.store.Users.Get("", username)
} }
if err != nil { if err != nil {
return err return err
} }
@ -55,10 +60,12 @@ options you want to change.`,
Sorting: user.Sorting, Sorting: user.Sorting,
Commands: user.Commands, Commands: user.Commands,
} }
err = getUserDefaults(v, &defaults, false)
err = getUserDefaults(flags, &defaults, false)
if err != nil { if err != nil {
return err return err
} }
user.Scope = defaults.Scope user.Scope = defaults.Scope
user.Locale = defaults.Locale user.Locale = defaults.Locale
user.ViewMode = defaults.ViewMode user.ViewMode = defaults.ViewMode
@ -66,9 +73,20 @@ options you want to change.`,
user.Perm = defaults.Perm user.Perm = defaults.Perm
user.Commands = defaults.Commands user.Commands = defaults.Commands
user.Sorting = defaults.Sorting user.Sorting = defaults.Sorting
user.LockPassword = v.GetBool("lockPassword") user.LockPassword, err = flags.GetBool("lockPassword")
user.DateFormat = v.GetBool("dateFormat") if err != nil {
user.HideDotfiles = v.GetBool("hideDotfiles") return err
}
user.DateFormat, err = flags.GetBool("dateFormat")
if err != nil {
return err
}
user.HideDotfiles, err = flags.GetBool("hideDotfiles")
if err != nil {
return err
}
if newUsername != "" { if newUsername != "" {
user.Username = newUsername user.Username = newUsername

View File

@ -26,8 +26,13 @@ import (
const databasePermissions = 0640 const databasePermissions = 0640
func parseFileMode(value string) (fs.FileMode, error) { func getAndParseFileMode(flags *pflag.FlagSet, name string) (fs.FileMode, error) {
b, err := strconv.ParseUint(value, 0, 32) mode, err := flags.GetString(name)
if err != nil {
return 0, err
}
b, err := strconv.ParseUint(mode, 0, 32)
if err != nil { if err != nil {
return 0, err return 0, err
} }
@ -127,7 +132,7 @@ func initViper(cmd *cobra.Command) (*viper.Viper, error) {
} }
type cobraFunc func(cmd *cobra.Command, args []string) error type cobraFunc func(cmd *cobra.Command, args []string) error
type pythonFunc func(cmd *cobra.Command, args []string, v *viper.Viper, data *pythonData) error type pythonFunc func(cmd *cobra.Command, args []string, data *pythonData) error
type pythonConfig struct { type pythonConfig struct {
noDB bool noDB bool
@ -136,6 +141,7 @@ type pythonConfig struct {
type pythonData struct { type pythonData struct {
hadDB bool hadDB bool
viper *viper.Viper
store *storage.Storage store *storage.Storage
} }
@ -146,7 +152,7 @@ func python(fn pythonFunc, cfg pythonConfig) cobraFunc {
return err return err
} }
data := &pythonData{hadDB: true} data := &pythonData{hadDB: true, viper: v}
path := v.GetString("database") path := v.GetString("database")
absPath, err := filepath.Abs(path) absPath, err := filepath.Abs(path)
@ -179,7 +185,7 @@ func python(fn pythonFunc, cfg pythonConfig) cobraFunc {
return err return err
} }
return fn(cmd, args, v, data) return fn(cmd, args, data)
} }
} }