diff --git a/cmd/cmds_add.go b/cmd/cmds_add.go index 5f34630f..a4d17061 100644 --- a/cmd/cmds_add.go +++ b/cmd/cmds_add.go @@ -4,7 +4,6 @@ import ( "strings" "github.com/spf13/cobra" - "github.com/spf13/viper" ) func init() { @@ -16,7 +15,7 @@ var cmdsAddCmd = &cobra.Command{ Short: "Add a command to run on a specific event", Long: `Add a command to run on a specific event.`, 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() if err != nil { return err diff --git a/cmd/cmds_ls.go b/cmd/cmds_ls.go index 15a8f0e7..ad700eb7 100644 --- a/cmd/cmds_ls.go +++ b/cmd/cmds_ls.go @@ -2,7 +2,6 @@ package cmd import ( "github.com/spf13/cobra" - "github.com/spf13/viper" ) func init() { @@ -15,12 +14,17 @@ var cmdsLsCmd = &cobra.Command{ Short: "List all commands for each event", Long: `List all commands for each event.`, 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() if err != nil { return err } - evt := v.GetString("event") + + evt, err := cmd.Flags().GetString("event") + if err != nil { + return err + } + if evt == "" { printEvents(s.Commands) } else { @@ -29,6 +33,7 @@ var cmdsLsCmd = &cobra.Command{ show["after_"+evt] = s.Commands["after_"+evt] printEvents(show) } + return nil }, pythonConfig{}), } diff --git a/cmd/cmds_rm.go b/cmd/cmds_rm.go index 8cfa5a29..34089388 100644 --- a/cmd/cmds_rm.go +++ b/cmd/cmds_rm.go @@ -4,7 +4,6 @@ import ( "strconv" "github.com/spf13/cobra" - "github.com/spf13/viper" ) func init() { @@ -36,7 +35,7 @@ including 'index_end'.`, 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() if err != nil { return err diff --git a/cmd/config.go b/cmd/config.go index 090e5177..4a2f8d14 100644 --- a/cmd/config.go +++ b/cmd/config.go @@ -10,7 +10,6 @@ import ( "github.com/spf13/cobra" "github.com/spf13/pflag" - "github.com/spf13/viper" "github.com/filebrowser/filebrowser/v2/auth" "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") } -func getAuthMethod(v *viper.Viper, defaults ...interface{}) (settings.AuthMethod, map[string]interface{}, error) { - methodStr := v.GetString("auth.method") +func getAuthMethod(flags *pflag.FlagSet, defaults ...interface{}) (settings.AuthMethod, map[string]interface{}, error) { + methodStr, err := flags.GetString("auth.method") + if err != nil { + return "", nil, err + } method := settings.AuthMethod(methodStr) var defaultAuther map[string]interface{} @@ -90,8 +92,12 @@ func getAuthMethod(v *viper.Viper, defaults ...interface{}) (settings.AuthMethod return method, defaultAuther, nil } -func getProxyAuth(v *viper.Viper, defaultAuther map[string]interface{}) (auth.Auther, error) { - header := v.GetString("auth.header") +func getProxyAuth(flags *pflag.FlagSet, defaultAuther map[string]interface{}) (auth.Auther, error) { + header, err := flags.GetString("auth.header") + if err != nil { + return nil, err + } + if header == "" { header = defaultAuther["header"].(string) } @@ -107,11 +113,22 @@ func getNoAuth() auth.Auther { 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{} - host := v.GetString("recaptcha.host") - key := v.GetString("recaptcha.key") - secret := v.GetString("recaptcha.secret") + host, err := flags.GetString("recaptcha.host") + if err != nil { + 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 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 } -func getHookAuth(v *viper.Viper, defaultAuther map[string]interface{}) (auth.Auther, error) { - command := v.GetString("auth.command") +func getHookAuth(flags *pflag.FlagSet, defaultAuther map[string]interface{}) (auth.Auther, error) { + command, err := flags.GetString("auth.command") + if err != nil { + return nil, err + } if command == "" { 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 } -func getAuthentication(v *viper.Viper, defaults ...interface{}) (settings.AuthMethod, auth.Auther, error) { - method, defaultAuther, err := getAuthMethod(v, defaults...) +func getAuthentication(flags *pflag.FlagSet, defaults ...interface{}) (settings.AuthMethod, auth.Auther, error) { + method, defaultAuther, err := getAuthMethod(flags, defaults...) if err != nil { return "", nil, err } @@ -157,13 +177,13 @@ func getAuthentication(v *viper.Viper, defaults ...interface{}) (settings.AuthMe var auther auth.Auther switch method { case auth.MethodProxyAuth: - auther, err = getProxyAuth(v, defaultAuther) + auther, err = getProxyAuth(flags, defaultAuther) case auth.MethodNoAuth: auther = getNoAuth() case auth.MethodJSONAuth: - auther, err = getJSONAuth(v, defaultAuther) + auther, err = getJSONAuth(flags, defaultAuther) case auth.MethodHookAuth: - auther, err = getHookAuth(v, defaultAuther) + auther, err = getHookAuth(flags, defaultAuther) default: return "", nil, errors.ErrInvalidAuthMethod } diff --git a/cmd/config_cat.go b/cmd/config_cat.go index 094a3ccd..39b1f664 100644 --- a/cmd/config_cat.go +++ b/cmd/config_cat.go @@ -2,7 +2,6 @@ package cmd import ( "github.com/spf13/cobra" - "github.com/spf13/viper" ) func init() { @@ -14,7 +13,7 @@ var configCatCmd = &cobra.Command{ Short: "Prints the configuration", Long: `Prints the configuration.`, 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() if err != nil { return err diff --git a/cmd/config_export.go b/cmd/config_export.go index a33d6aad..9877fb63 100644 --- a/cmd/config_export.go +++ b/cmd/config_export.go @@ -2,7 +2,6 @@ package cmd import ( "github.com/spf13/cobra" - "github.com/spf13/viper" ) func init() { @@ -16,7 +15,7 @@ var configExportCmd = &cobra.Command{ json or yaml file. This exported configuration can be changed, and imported again with 'config import' command.`, 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() if err != nil { return err diff --git a/cmd/config_import.go b/cmd/config_import.go index 35023863..7763517d 100644 --- a/cmd/config_import.go +++ b/cmd/config_import.go @@ -7,7 +7,6 @@ import ( "reflect" "github.com/spf13/cobra" - "github.com/spf13/viper" "github.com/filebrowser/filebrowser/v2/auth" "github.com/filebrowser/filebrowser/v2/settings" @@ -35,7 +34,7 @@ database. The path must be for a json or yaml file.`, 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 err error if d.hadDB { diff --git a/cmd/config_init.go b/cmd/config_init.go index 71b628f4..ad079d19 100644 --- a/cmd/config_init.go +++ b/cmd/config_init.go @@ -4,8 +4,8 @@ import ( "fmt" "github.com/spf13/cobra" - "github.com/spf13/viper" + "github.com/filebrowser/filebrowser/v2/auth" "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 override the options.`, Args: cobra.NoArgs, - RunE: python(func(cmd *cobra.Command, _ []string, v *viper.Viper, d *pythonData) error { - defaults := settings.UserDefaults{} - err := getUserDefaults(v, &defaults, true) - if err != nil { - return err - } - authMethod, auther, err := getAuthentication(v) - if err != nil { - return err - } + RunE: python(func(cmd *cobra.Command, _ []string, d *pythonData) error { + flags := cmd.Flags() + // General Settings s := &settings.Settings{ - 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"), - }, + Key: generateKey(), } - s.FileMode, err = parseFileMode(v.GetString("fileMode")) + err := getUserDefaults(flags, &s.Defaults, true) if err != nil { return err } - s.DirMode, err = parseFileMode(v.GetString("dirMode")) + s.Signup, err = flags.GetBool("signup") if err != nil { return err } - ser := &settings.Server{ - Address: v.GetString("address"), - Socket: v.GetString("socket"), - Root: v.GetString("root"), - BaseURL: v.GetString("baseurl"), - TLSKey: v.GetString("key"), - TLSCert: v.GetString("cert"), - Port: v.GetString("port"), - Log: v.GetString("log"), + s.HideLoginButton, err = flags.GetBool("hideLoginButton") + if err != nil { + return err + } + + s.CreateUserDir, err = flags.GetBool("createUserDir") + if err != nil { + return err + } + + 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) if err != nil { return err } + err = d.store.Settings.SaveServer(ser) if err != nil { return err } + err = d.store.Auth.Save(auther) if err != nil { return err diff --git a/cmd/config_set.go b/cmd/config_set.go index 7d303ab9..1b903f34 100644 --- a/cmd/config_set.go +++ b/cmd/config_set.go @@ -2,7 +2,7 @@ package cmd import ( "github.com/spf13/cobra" - "github.com/spf13/viper" + "github.com/spf13/pflag" ) func init() { @@ -16,7 +16,9 @@ var configSetCmd = &cobra.Command{ Long: `Updates the configuration. Set the flags for the options you want to change. Other options will remain unchanged.`, 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() if err != nil { return err @@ -29,70 +31,73 @@ you want to change. Other options will remain unchanged.`, hasAuth := false - for _, key := range v.AllKeys() { - if !v.IsSet(key) { - continue + flags.Visit(func(flag *pflag.Flag) { + if err != nil { + return } - switch key { - case "baseurl": - ser.BaseURL = v.GetString(key) + switch flag.Name { + case "baseURL": + ser.BaseURL, err = flags.GetString(flag.Name) case "root": - ser.Root = v.GetString(key) + ser.Root, err = flags.GetString(flag.Name) case "socket": - ser.Socket = v.GetString(key) + ser.Socket, err = flags.GetString(flag.Name) case "cert": - ser.TLSCert = v.GetString(key) + ser.TLSCert, err = flags.GetString(flag.Name) case "key": - ser.TLSKey = v.GetString(key) + ser.TLSKey, err = flags.GetString(flag.Name) case "address": - ser.Address = v.GetString(key) + ser.Address, err = flags.GetString(flag.Name) case "port": - ser.Port = v.GetString(key) + ser.Port, err = flags.GetString(flag.Name) case "log": - ser.Log = v.GetString(key) - case "hideloginbutton": - set.HideLoginButton = v.GetBool(key) + ser.Log, err = flags.GetString(flag.Name) + case "hideLoginButton": + set.HideLoginButton, err = flags.GetBool(flag.Name) case "signup": - set.Signup = v.GetBool(key) + set.Signup, err = flags.GetBool(flag.Name) case "auth.method": hasAuth = true case "shell": var shell string - shell = v.GetString(key) + shell, err = flags.GetString(flag.Name) + if err != nil { + return + } set.Shell = convertCmdStrToCmdArray(shell) - case "createuserdir": - set.CreateUserDir = v.GetBool(key) - case "minimumpasswordlength": - set.MinimumPasswordLength = v.GetUint(key) + case "createUserDir": + set.CreateUserDir, err = flags.GetBool(flag.Name) + case "minimumPasswordLength": + set.MinimumPasswordLength, err = flags.GetUint(flag.Name) case "branding.name": - set.Branding.Name = v.GetString(key) + set.Branding.Name, err = flags.GetString(flag.Name) case "branding.color": - set.Branding.Color = v.GetString(key) + set.Branding.Color, err = flags.GetString(flag.Name) case "branding.theme": - set.Branding.Theme = v.GetString(key) - case "branding.disableexternal": - set.Branding.DisableExternal = v.GetBool(key) - case "branding.disableusedpercentage": - set.Branding.DisableUsedPercentage = v.GetBool(key) + set.Branding.Theme, err = flags.GetString(flag.Name) + case "branding.disableExternal": + set.Branding.DisableExternal, err = flags.GetBool(flag.Name) + case "branding.disableUsedPercentage": + set.Branding.DisableUsedPercentage, err = flags.GetBool(flag.Name) case "branding.files": - set.Branding.Files = v.GetString(key) - case "filemode": - set.FileMode, err = parseFileMode(v.GetString(key)) - case "dirmode": - set.DirMode, err = parseFileMode(v.GetString(key)) - case "tus.chunksize": - set.Tus.ChunkSize = v.GetUint64(key) - case "tus.retrycount": - set.Tus.RetryCount = v.GetUint16(key) + set.Branding.Files, err = flags.GetString(flag.Name) + case "fileMode": + set.FileMode, err = getAndParseFileMode(flags, flag.Name) + case "dirMode": + set.DirMode, err = getAndParseFileMode(flags, flag.Name) + case "tus.chunkSize": + set.Tus.ChunkSize, err = flags.GetUint64(flag.Name) + case "tus.retryCount": + set.Tus.RetryCount, err = flags.GetUint16(flag.Name) } - if err != nil { - return err - } + }) + if err != nil { + return err } - err = getUserDefaults(v, &set.Defaults, false) + err = getUserDefaults(cmd.Flags(), &set.Defaults, false) if err != nil { 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 - set.AuthMethod, auther, err = getAuthentication(v, hasAuth, set, auther) + set.AuthMethod, auther, err = getAuthentication(flags, hasAuth, set, auther) if err != nil { return err } diff --git a/cmd/root.go b/cmd/root.go index 86a23903..6576afb9 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -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 the quick setup mode and a new database will be bootstrapped and a new 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 { - err := quickSetup(v, *d) + err := quickSetup(d.viper, *d) if err != nil { return err } } // build img service - workersCount := v.GetInt("imageProcessors") - if workersCount < 1 { + imgWorkersCount := d.viper.GetInt("imageProcessors") + if imgWorkersCount < 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() - cacheDir := v.GetString("cacheDir") + cacheDir := d.viper.GetString("cacheDir") if cacheDir != "" { if err := os.MkdirAll(cacheDir, 0700); err != nil { 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) } - server, err := getRunParams(v, d.store) + server, err := getServerSettings(d.viper, d.store) if err != nil { return err } @@ -180,7 +180,7 @@ user created with the credentials from options "username" and "password".`, if err != nil { return err } - socketPerm := v.GetUint32("socketPerm") + socketPerm := d.viper.GetUint32("socketPerm") err = os.Chmod(server.Socket, os.FileMode(socketPerm)) if err != nil { return err @@ -209,7 +209,7 @@ user created with the credentials from options "username" and "password".`, 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 { return err } @@ -253,52 +253,56 @@ user created with the credentials from options "username" and "password".`, }, 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() if err != nil { return nil, err } - if val, set := getStringParamB(v, "root"); set { + if val, set := vGetStringIsSet(v, "root"); set { server.Root = val } - if val, set := getStringParamB(v, "baseurl"); set { + if val, set := vGetStringIsSet(v, "baseURL"); set { server.BaseURL = val } - if val, set := getStringParamB(v, "log"); set { + if val, set := vGetStringIsSet(v, "log"); set { server.Log = val } isSocketSet := false isAddrSet := false - if val, set := getStringParamB(v, "address"); set { + if val, set := vGetStringIsSet(v, "address"); set { server.Address = val isAddrSet = isAddrSet || set } - if val, set := getStringParamB(v, "port"); set { + if val, set := vGetStringIsSet(v, "port"); set { server.Port = val isAddrSet = isAddrSet || set } - if val, set := getStringParamB(v, "key"); set { + if val, set := vGetStringIsSet(v, "key"); set { server.TLSKey = val isAddrSet = isAddrSet || set } - if val, set := getStringParamB(v, "cert"); set { + if val, set := vGetStringIsSet(v, "cert"); set { server.TLSCert = val isAddrSet = isAddrSet || set } - if val, set := getStringParamB(v, "socket"); set { + if val, set := vGetStringIsSet(v, "socket"); set { server.Socket = val isSocketSet = isSocketSet || set } + if val, set := vGetStringIsSet(v, "tokenExpirationTime"); set { + server.TokenExpirationTime = val + } + if isAddrSet && isSocketSet { 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 = "" } - disableThumbnails := v.GetBool("disableThumbnails") - server.EnableThumbnails = !disableThumbnails - - disablePreviewResize := v.GetBool("disablePreviewResize") - server.ResizePreview = !disablePreviewResize - - disableTypeDetectionByHeader := v.GetBool("disableTypeDetectionByHeader") - server.TypeDetectionByHeader = !disableTypeDetectionByHeader - - disableExec := v.GetBool("disableExec") - server.EnableExec = !disableExec + server.EnableThumbnails = !v.GetBool("disableThumbnails") + server.ResizePreview = !v.GetBool("disablePreviewResize") + server.TypeDetectionByHeader = !v.GetBool("disableTypeDetectionByHeader") + server.EnableExec = !v.GetBool("disableExec") if server.EnableExec { 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") } - if val, set := getStringParamB(v, "tokenExpirationTime"); set { - server.TokenExpirationTime = val - } - 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) } @@ -394,7 +387,7 @@ func quickSetup(v *viper.Viper, d pythonData) error { } var err error - if _, noauth := getStringParamB(v, "noauth"); noauth { + if _, noauth := vGetStringIsSet(v, "noauth"); noauth { set.AuthMethod = auth.MethodNoAuth err = d.store.Auth.Save(&auth.NoAuth{}) } else { diff --git a/cmd/rule_rm.go b/cmd/rule_rm.go index 3be13622..26e801ae 100644 --- a/cmd/rule_rm.go +++ b/cmd/rule_rm.go @@ -4,7 +4,6 @@ import ( "strconv" "github.com/spf13/cobra" - "github.com/spf13/viper" "github.com/filebrowser/filebrowser/v2/settings" "github.com/filebrowser/filebrowser/v2/users" @@ -41,7 +40,7 @@ including 'index_end'.`, 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]) if err != nil { return err @@ -64,6 +63,6 @@ including 'index_end'.`, return d.store.Settings.Save(s) } - return runRules(d.store, cmd, v, user, global) + return runRules(d.store, cmd, user, global) }, pythonConfig{}), } diff --git a/cmd/rules.go b/cmd/rules.go index d045cc0f..bdb1d1cf 100644 --- a/cmd/rules.go +++ b/cmd/rules.go @@ -4,7 +4,7 @@ import ( "fmt" "github.com/spf13/cobra" - "github.com/spf13/viper" + "github.com/spf13/pflag" "github.com/filebrowser/filebrowser/v2/rules" "github.com/filebrowser/filebrowser/v2/settings" @@ -29,8 +29,8 @@ rules.`, 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 { - id, err := getUserIdentifier(v) +func runRules(st *storage.Storage, cmd *cobra.Command, usersFn func(*users.User) error, globalFn func(*settings.Settings) error) error { + id, err := getUserIdentifier(cmd.Flags()) if err != nil { return err } @@ -68,9 +68,16 @@ func runRules(st *storage.Storage, cmd *cobra.Command, v *viper.Viper, usersFn f return nil } -func getUserIdentifier(v *viper.Viper) (interface{}, error) { - id := v.GetUint("id") - username := v.GetString("username") +func getUserIdentifier(flags *pflag.FlagSet) (interface{}, error) { + id, err := flags.GetUint("id") + if err != nil { + return nil, err + } + + username, err := flags.GetString("username") + if err != nil { + return nil, err + } if id != 0 { return id, nil diff --git a/cmd/rules_add.go b/cmd/rules_add.go index de6c70fb..d58a6987 100644 --- a/cmd/rules_add.go +++ b/cmd/rules_add.go @@ -4,7 +4,6 @@ import ( "regexp" "github.com/spf13/cobra" - "github.com/spf13/viper" "github.com/filebrowser/filebrowser/v2/rules" "github.com/filebrowser/filebrowser/v2/settings" @@ -22,9 +21,19 @@ var rulesAddCmd = &cobra.Command{ Short: "Add a global rule or user rule", Long: `Add a global rule or user rule.`, Args: cobra.ExactArgs(1), - RunE: python(func(cmd *cobra.Command, args []string, v *viper.Viper, d *pythonData) error { - allow := v.GetBool("allow") - regex := v.GetBool("regex") + RunE: python(func(cmd *cobra.Command, args []string, d *pythonData) error { + flags := cmd.Flags() + + allow, err := flags.GetBool("allow") + if err != nil { + return err + } + + regex, err := flags.GetBool("regex") + if err != nil { + return err + } + exp := args[0] if regex { @@ -52,6 +61,6 @@ var rulesAddCmd = &cobra.Command{ return d.store.Settings.Save(s) } - return runRules(d.store, cmd, v, user, global) + return runRules(d.store, cmd, user, global) }, pythonConfig{}), } diff --git a/cmd/rules_ls.go b/cmd/rules_ls.go index 728faae8..67a279dc 100644 --- a/cmd/rules_ls.go +++ b/cmd/rules_ls.go @@ -2,7 +2,6 @@ package cmd import ( "github.com/spf13/cobra" - "github.com/spf13/viper" ) func init() { @@ -14,7 +13,7 @@ var rulesLsCommand = &cobra.Command{ Short: "List global rules or user specific rules", Long: `List global rules or user specific rules.`, Args: cobra.NoArgs, - RunE: python(func(cmd *cobra.Command, _ []string, v *viper.Viper, d *pythonData) error { - return runRules(d.store, cmd, v, nil, nil) + RunE: python(func(cmd *cobra.Command, _ []string, d *pythonData) error { + return runRules(d.store, cmd, nil, nil) }, pythonConfig{}), } diff --git a/cmd/users.go b/cmd/users.go index 59726ca4..86434a42 100644 --- a/cmd/users.go +++ b/cmd/users.go @@ -9,7 +9,6 @@ import ( "github.com/spf13/cobra" "github.com/spf13/pflag" - "github.com/spf13/viper" "github.com/filebrowser/filebrowser/v2/settings" "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") } -func getAndParseViewMode(v *viper.Viper) (users.ViewMode, error) { - viewModeStr := v.GetString("viewMode") +func getAndParseViewMode(flags *pflag.FlagSet) (users.ViewMode, error) { + viewModeStr, err := flags.GetString("viewMode") + if err != nil { + return "", err + } + viewMode := users.ViewMode(viewModeStr) if viewMode != users.ListViewMode && viewMode != users.MosaicViewMode { return "", errors.New("view mode must be \"" + string(users.ListViewMode) + "\" or \"" + string(users.MosaicViewMode) + "\"") } + return viewMode, nil } -func getUserDefaults(v *viper.Viper, defaults *settings.UserDefaults, all bool) error { - keys := v.AllKeys() - - for _, key := range keys { - if !all && !v.IsSet(key) { - continue - } +func getUserDefaults(flags *pflag.FlagSet, defaults *settings.UserDefaults, all bool) error { + errs := []error{} + visit := func(flag *pflag.Flag) { var err error - switch key { + switch flag.Name { case "scope": - defaults.Scope = v.GetString(key) + defaults.Scope, err = flags.GetString(flag.Name) case "locale": - defaults.Locale = v.GetString(key) - case "viewmode": - defaults.ViewMode, err = getAndParseViewMode(v) - case "singleclick": - defaults.SingleClick = v.GetBool(key) - case "aceeditortheme": - defaults.AceEditorTheme = v.GetString(key) + defaults.Locale, err = flags.GetString(flag.Name) + case "viewMode": + defaults.ViewMode, err = getAndParseViewMode(flags) + case "singleClick": + defaults.SingleClick, err = flags.GetBool(flag.Name) + case "aceEditorTheme": + defaults.AceEditorTheme, err = flags.GetString(flag.Name) case "perm.admin": - defaults.Perm.Admin = v.GetBool(key) + defaults.Perm.Admin, err = flags.GetBool(flag.Name) case "perm.execute": - defaults.Perm.Execute = v.GetBool(key) + defaults.Perm.Execute, err = flags.GetBool(flag.Name) case "perm.create": - defaults.Perm.Create = v.GetBool(key) + defaults.Perm.Create, err = flags.GetBool(flag.Name) case "perm.rename": - defaults.Perm.Rename = v.GetBool(key) + defaults.Perm.Rename, err = flags.GetBool(flag.Name) case "perm.modify": - defaults.Perm.Modify = v.GetBool(key) + defaults.Perm.Modify, err = flags.GetBool(flag.Name) case "perm.delete": - defaults.Perm.Delete = v.GetBool(key) + defaults.Perm.Delete, err = flags.GetBool(flag.Name) case "perm.share": - defaults.Perm.Share = v.GetBool(key) + defaults.Perm.Share, err = flags.GetBool(flag.Name) case "perm.download": - defaults.Perm.Download = v.GetBool(key) + defaults.Perm.Download, err = flags.GetBool(flag.Name) case "commands": - defaults.Commands = v.GetStringSlice(key) + defaults.Commands, err = flags.GetStringSlice(flag.Name) case "sorting.by": - defaults.Sorting.By = v.GetString(key) + defaults.Sorting.By, err = flags.GetString(flag.Name) case "sorting.asc": - defaults.Sorting.Asc = v.GetBool(key) - case "hidedotfiles": - defaults.HideDotfiles = v.GetBool(key) + defaults.Sorting.Asc, err = flags.GetBool(flag.Name) + case "hideDotfiles": + defaults.HideDotfiles, err = flags.GetBool(flag.Name) } + if err != nil { - return err + errs = append(errs, err) } } - return nil + if all { + flags.VisitAll(visit) + } else { + flags.Visit(visit) + } + + return errors.Join(errs...) } diff --git a/cmd/users_add.go b/cmd/users_add.go index 98230496..bfc70069 100644 --- a/cmd/users_add.go +++ b/cmd/users_add.go @@ -2,7 +2,6 @@ package cmd import ( "github.com/spf13/cobra" - "github.com/spf13/viper" "github.com/filebrowser/filebrowser/v2/users" ) @@ -17,12 +16,13 @@ var usersAddCmd = &cobra.Command{ Short: "Create a new user", Long: `Create a new user and add it to the database.`, 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() if err != nil { return err } - err = getUserDefaults(v, &s.Defaults, false) + err = getUserDefaults(flags, &s.Defaults, false) if err != nil { return err } @@ -33,11 +33,23 @@ var usersAddCmd = &cobra.Command{ } user := &users.User{ - Username: args[0], - Password: password, - LockPassword: v.GetBool("lockPassword"), - DateFormat: v.GetBool("dateFormat"), - HideDotfiles: v.GetBool("hideDotfiles"), + Username: args[0], + Password: password, + } + + 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) diff --git a/cmd/users_export.go b/cmd/users_export.go index cdc15a8b..d6009a37 100644 --- a/cmd/users_export.go +++ b/cmd/users_export.go @@ -2,7 +2,6 @@ package cmd import ( "github.com/spf13/cobra" - "github.com/spf13/viper" ) func init() { @@ -15,7 +14,7 @@ var usersExportCmd = &cobra.Command{ Long: `Export all users to a json or yaml file. Please indicate the path to the file where you want to write the users.`, 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("") if err != nil { return err diff --git a/cmd/users_find.go b/cmd/users_find.go index 73aad57d..0dea071a 100644 --- a/cmd/users_find.go +++ b/cmd/users_find.go @@ -2,7 +2,6 @@ package cmd import ( "github.com/spf13/cobra" - "github.com/spf13/viper" "github.com/filebrowser/filebrowser/v2/users" ) @@ -27,7 +26,7 @@ var usersLsCmd = &cobra.Command{ 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 ( list []*users.User user *users.User diff --git a/cmd/users_import.go b/cmd/users_import.go index 7f15d8f6..d08889df 100644 --- a/cmd/users_import.go +++ b/cmd/users_import.go @@ -7,7 +7,6 @@ import ( "strconv" "github.com/spf13/cobra" - "github.com/spf13/viper" "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 list or set it to 0.`, 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]) if err != nil { 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("") if userImportErr != nil { 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 { onDB, err := d.store.Users.Get("", user.ID) diff --git a/cmd/users_rm.go b/cmd/users_rm.go index d4ebdbe9..55b973f4 100644 --- a/cmd/users_rm.go +++ b/cmd/users_rm.go @@ -4,7 +4,6 @@ import ( "fmt" "github.com/spf13/cobra" - "github.com/spf13/viper" ) func init() { @@ -16,7 +15,7 @@ var usersRmCmd = &cobra.Command{ Short: "Delete a user by username or id", Long: `Delete a user by username or id`, 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]) var err error diff --git a/cmd/users_update.go b/cmd/users_update.go index 6758c114..59854a81 100644 --- a/cmd/users_update.go +++ b/cmd/users_update.go @@ -2,7 +2,6 @@ package cmd import ( "github.com/spf13/cobra" - "github.com/spf13/viper" "github.com/filebrowser/filebrowser/v2/settings" "github.com/filebrowser/filebrowser/v2/users" @@ -22,10 +21,18 @@ var usersUpdateCmd = &cobra.Command{ Long: `Updates an existing user. Set the flags for the options you want to change.`, 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]) - password := v.GetString("password") - newUsername := v.GetString("username") + password, err := flags.GetString("password") + if err != nil { + return err + } + + newUsername, err := flags.GetString("username") + if err != nil { + return err + } s, err := d.store.Settings.Get() if err != nil { @@ -35,13 +42,11 @@ options you want to change.`, var ( user *users.User ) - if id != 0 { user, err = d.store.Users.Get("", id) } else { user, err = d.store.Users.Get("", username) } - if err != nil { return err } @@ -55,10 +60,12 @@ options you want to change.`, Sorting: user.Sorting, Commands: user.Commands, } - err = getUserDefaults(v, &defaults, false) + + err = getUserDefaults(flags, &defaults, false) if err != nil { return err } + user.Scope = defaults.Scope user.Locale = defaults.Locale user.ViewMode = defaults.ViewMode @@ -66,9 +73,20 @@ options you want to change.`, user.Perm = defaults.Perm user.Commands = defaults.Commands user.Sorting = defaults.Sorting - user.LockPassword = v.GetBool("lockPassword") - user.DateFormat = v.GetBool("dateFormat") - user.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 + } if newUsername != "" { user.Username = newUsername diff --git a/cmd/utils.go b/cmd/utils.go index c6e7700a..e486c9d5 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -26,8 +26,13 @@ import ( const databasePermissions = 0640 -func parseFileMode(value string) (fs.FileMode, error) { - b, err := strconv.ParseUint(value, 0, 32) +func getAndParseFileMode(flags *pflag.FlagSet, name string) (fs.FileMode, error) { + mode, err := flags.GetString(name) + if err != nil { + return 0, err + } + + b, err := strconv.ParseUint(mode, 0, 32) if err != nil { 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 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 { noDB bool @@ -136,6 +141,7 @@ type pythonConfig struct { type pythonData struct { hadDB bool + viper *viper.Viper store *storage.Storage } @@ -146,7 +152,7 @@ func python(fn pythonFunc, cfg pythonConfig) cobraFunc { return err } - data := &pythonData{hadDB: true} + data := &pythonData{hadDB: true, viper: v} path := v.GetString("database") absPath, err := filepath.Abs(path) @@ -179,7 +185,7 @@ func python(fn pythonFunc, cfg pythonConfig) cobraFunc { return err } - return fn(cmd, args, v, data) + return fn(cmd, args, data) } }