From 72069207c6bb0664c7b270096f6916cce76ebeb1 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 8 Jan 2019 14:07:55 +0000 Subject: [PATCH] fix: use server options from DB too (#616) License: MIT Signed-off-by: Henrique Dias --- .filebrowser.docker.json | 8 +++ Dockerfile | 3 +- cmd/cmds_ls.go | 2 +- cmd/config.go | 63 +++++++++-------- cmd/config_cat.go | 8 ++- cmd/config_export.go | 4 ++ cmd/config_import.go | 21 ++++-- cmd/config_init.go | 29 +++++--- cmd/config_set.go | 44 ++++++++---- cmd/docs.go | 2 +- cmd/root.go | 143 ++++++++++++++++++++++++++------------- cmd/rules.go | 9 +-- cmd/rules_add.go | 4 +- cmd/upgrade.go | 9 ++- cmd/users.go | 38 +++++------ cmd/users_add.go | 4 +- cmd/users_import.go | 10 +-- cmd/users_update.go | 9 +-- cmd/utils.go | 39 ++--------- 19 files changed, 270 insertions(+), 179 deletions(-) create mode 100644 .filebrowser.docker.json diff --git a/.filebrowser.docker.json b/.filebrowser.docker.json new file mode 100644 index 00000000..8e7472df --- /dev/null +++ b/.filebrowser.docker.json @@ -0,0 +1,8 @@ +{ + "port": 80, + "baseURL": "", + "address": "", + "log": "stdout", + "database": "/database.db", + "root": "/srv" +} diff --git a/Dockerfile b/Dockerfile index cb0e8865..5409c2d3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,6 +6,7 @@ VOLUME /tmp VOLUME /srv EXPOSE 80 +COPY .filebrowser.docker.json /.filebrowser.json COPY filebrowser /filebrowser -ENTRYPOINT [ "/filebrowser"] +ENTRYPOINT [ "/filebrowser" ] diff --git a/cmd/cmds_ls.go b/cmd/cmds_ls.go index f688ede6..71f36382 100644 --- a/cmd/cmds_ls.go +++ b/cmd/cmds_ls.go @@ -17,7 +17,7 @@ var cmdsLsCmd = &cobra.Command{ Run: python(func(cmd *cobra.Command, args []string, d pythonData) { s, err := d.store.Settings.Get() checkErr(err) - evt := mustGetString(cmd, "event") + evt := mustGetString(cmd.Flags(), "event") if evt == "" { printEvents(s.Commands) diff --git a/cmd/config.go b/cmd/config.go index 2034e0aa..db97cf10 100644 --- a/cmd/config.go +++ b/cmd/config.go @@ -27,6 +27,7 @@ var configCmd = &cobra.Command{ } func addConfigFlags(flags *pflag.FlagSet) { + addServerFlags(flags) addUserFlags(flags) flags.BoolP("signup", "s", false, "allow users to signup") flags.String("shell", "", "shell command to which other commands should be appended") @@ -43,12 +44,12 @@ func addConfigFlags(flags *pflag.FlagSet) { flags.Bool("branding.disableExternal", false, "disable external links such as GitHub links") } -func getAuthentication(cmd *cobra.Command) (settings.AuthMethod, auth.Auther) { - method := settings.AuthMethod(mustGetString(cmd, "auth.method")) +func getAuthentication(flags *pflag.FlagSet) (settings.AuthMethod, auth.Auther) { + method := settings.AuthMethod(mustGetString(flags, "auth.method")) var auther auth.Auther if method == auth.MethodProxyAuth { - header := mustGetString(cmd, "auth.header") + header := mustGetString(flags, "auth.header") if header == "" { panic(nerrors.New("you must set the flag 'auth.header' for method 'proxy'")) } @@ -62,9 +63,9 @@ func getAuthentication(cmd *cobra.Command) (settings.AuthMethod, auth.Auther) { if method == auth.MethodJSONAuth { jsonAuth := &auth.JSONAuth{} - host := mustGetString(cmd, "recaptcha.host") - key := mustGetString(cmd, "recaptcha.key") - secret := mustGetString(cmd, "recaptcha.secret") + host := mustGetString(flags, "recaptcha.host") + key := mustGetString(flags, "recaptcha.key") + secret := mustGetString(flags, "recaptcha.secret") if key != "" && secret != "" { jsonAuth.ReCaptcha = &auth.ReCaptcha{ @@ -84,33 +85,41 @@ func getAuthentication(cmd *cobra.Command) (settings.AuthMethod, auth.Auther) { return method, auther } -func printSettings(s *settings.Settings, auther auth.Auther) { +func printSettings(ser *settings.Server, set *settings.Settings, auther auth.Auther) { w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0) - fmt.Fprintf(w, "Sign up:\t%t\n", s.Signup) - fmt.Fprintf(w, "Auth method:\t%s\n", s.AuthMethod) - fmt.Fprintf(w, "Shell:\t%s\t\n", strings.Join(s.Shell, " ")) + fmt.Fprintf(w, "Sign up:\t%t\n", set.Signup) + fmt.Fprintf(w, "Auth method:\t%s\n", set.AuthMethod) + fmt.Fprintf(w, "Shell:\t%s\t\n", strings.Join(set.Shell, " ")) fmt.Fprintln(w, "\nBranding:") - fmt.Fprintf(w, "\tName:\t%s\n", s.Branding.Name) - fmt.Fprintf(w, "\tFiles override:\t%s\n", s.Branding.Files) - fmt.Fprintf(w, "\tDisable external links:\t%t\n", s.Branding.DisableExternal) + fmt.Fprintf(w, "\tName:\t%s\n", set.Branding.Name) + fmt.Fprintf(w, "\tFiles override:\t%s\n", set.Branding.Files) + fmt.Fprintf(w, "\tDisable external links:\t%t\n", set.Branding.DisableExternal) + fmt.Fprintln(w, "\nServer:") + fmt.Fprintf(w, "\tLog:\t%s\n", ser.Log) + fmt.Fprintf(w, "\tPort:\t%s\n", ser.Port) + fmt.Fprintf(w, "\tBase URL:\t%s\n", ser.BaseURL) + fmt.Fprintf(w, "\tRoot:\t%s\n", ser.Root) + fmt.Fprintf(w, "\tAddress:\t%s\n", ser.Address) + fmt.Fprintf(w, "\tTLS Cert:\t%s\n", ser.TLSCert) + fmt.Fprintf(w, "\tTLS Key:\t%s\n", ser.TLSKey) fmt.Fprintln(w, "\nDefaults:") - fmt.Fprintf(w, "\tScope:\t%s\n", s.Defaults.Scope) - fmt.Fprintf(w, "\tLocale:\t%s\n", s.Defaults.Locale) - fmt.Fprintf(w, "\tView mode:\t%s\n", s.Defaults.ViewMode) - fmt.Fprintf(w, "\tCommands:\t%s\n", strings.Join(s.Defaults.Commands, " ")) + fmt.Fprintf(w, "\tScope:\t%s\n", set.Defaults.Scope) + fmt.Fprintf(w, "\tLocale:\t%s\n", set.Defaults.Locale) + fmt.Fprintf(w, "\tView mode:\t%s\n", set.Defaults.ViewMode) + fmt.Fprintf(w, "\tCommands:\t%s\n", strings.Join(set.Defaults.Commands, " ")) fmt.Fprintf(w, "\tSorting:\n") - fmt.Fprintf(w, "\t\tBy:\t%s\n", s.Defaults.Sorting.By) - fmt.Fprintf(w, "\t\tAsc:\t%t\n", s.Defaults.Sorting.Asc) + fmt.Fprintf(w, "\t\tBy:\t%s\n", set.Defaults.Sorting.By) + fmt.Fprintf(w, "\t\tAsc:\t%t\n", set.Defaults.Sorting.Asc) fmt.Fprintf(w, "\tPermissions:\n") - fmt.Fprintf(w, "\t\tAdmin:\t%t\n", s.Defaults.Perm.Admin) - fmt.Fprintf(w, "\t\tExecute:\t%t\n", s.Defaults.Perm.Execute) - fmt.Fprintf(w, "\t\tCreate:\t%t\n", s.Defaults.Perm.Create) - fmt.Fprintf(w, "\t\tRename:\t%t\n", s.Defaults.Perm.Rename) - fmt.Fprintf(w, "\t\tModify:\t%t\n", s.Defaults.Perm.Modify) - fmt.Fprintf(w, "\t\tDelete:\t%t\n", s.Defaults.Perm.Delete) - fmt.Fprintf(w, "\t\tShare:\t%t\n", s.Defaults.Perm.Share) - fmt.Fprintf(w, "\t\tDownload:\t%t\n", s.Defaults.Perm.Download) + fmt.Fprintf(w, "\t\tAdmin:\t%t\n", set.Defaults.Perm.Admin) + fmt.Fprintf(w, "\t\tExecute:\t%t\n", set.Defaults.Perm.Execute) + fmt.Fprintf(w, "\t\tCreate:\t%t\n", set.Defaults.Perm.Create) + fmt.Fprintf(w, "\t\tRename:\t%t\n", set.Defaults.Perm.Rename) + fmt.Fprintf(w, "\t\tModify:\t%t\n", set.Defaults.Perm.Modify) + fmt.Fprintf(w, "\t\tDelete:\t%t\n", set.Defaults.Perm.Delete) + fmt.Fprintf(w, "\t\tShare:\t%t\n", set.Defaults.Perm.Share) + fmt.Fprintf(w, "\t\tDownload:\t%t\n", set.Defaults.Perm.Download) w.Flush() b, err := json.MarshalIndent(auther, "", " ") diff --git a/cmd/config_cat.go b/cmd/config_cat.go index fcc45583..eca56dd1 100644 --- a/cmd/config_cat.go +++ b/cmd/config_cat.go @@ -14,10 +14,12 @@ var configCatCmd = &cobra.Command{ Long: `Prints the configuration.`, Args: cobra.NoArgs, Run: python(func(cmd *cobra.Command, args []string, d pythonData) { - s, err := d.store.Settings.Get() + set, err := d.store.Settings.Get() checkErr(err) - auther, err := d.store.Auth.Get(s.AuthMethod) + ser, err := d.store.Settings.GetServer() checkErr(err) - printSettings(s, auther) + auther, err := d.store.Auth.Get(set.AuthMethod) + checkErr(err) + printSettings(ser, set, auther) }, pythonConfig{}), } diff --git a/cmd/config_export.go b/cmd/config_export.go index f85d89b6..80574b29 100644 --- a/cmd/config_export.go +++ b/cmd/config_export.go @@ -16,12 +16,16 @@ var configExportCmd = &cobra.Command{ settings, err := d.store.Settings.Get() checkErr(err) + server, err := d.store.Settings.GetServer() + checkErr(err) + auther, err := d.store.Auth.Get(settings.AuthMethod) checkErr(err) data := &settingsFile{ Settings: settings, Auther: auther, + Server: server, } err = marshal(args[0], data) diff --git a/cmd/config_import.go b/cmd/config_import.go index c8b8ec0f..3463c2f8 100644 --- a/cmd/config_import.go +++ b/cmd/config_import.go @@ -3,6 +3,7 @@ package cmd import ( "encoding/json" "errors" + "path/filepath" "reflect" "github.com/filebrowser/filebrowser/v2/auth" @@ -16,6 +17,7 @@ func init() { type settingsFile struct { Settings *settings.Settings `json:"settings"` + Server *settings.Server `json:"server"` Auther interface{} `json:"auther"` } @@ -45,23 +47,32 @@ database.`, err = d.store.Settings.Save(file.Settings) checkErr(err) - autherInterf := cleanUpInterfaceMap(file.Auther.(map[interface{}]interface{})) + err = d.store.Settings.SaveServer(file.Server) + checkErr(err) + + var rawAuther interface{} + if filepath.Ext(args[0]) != ".json" { + rawAuther = cleanUpInterfaceMap(file.Auther.(map[interface{}]interface{})) + } else { + rawAuther = file.Auther + } var auther auth.Auther switch file.Settings.AuthMethod { case auth.MethodJSONAuth: - auther = getAuther(auth.JSONAuth{}, autherInterf).(*auth.JSONAuth) + auther = getAuther(auth.JSONAuth{}, rawAuther).(*auth.JSONAuth) case auth.MethodNoAuth: - auther = getAuther(auth.NoAuth{}, autherInterf).(*auth.NoAuth) + auther = getAuther(auth.NoAuth{}, rawAuther).(*auth.NoAuth) case auth.MethodProxyAuth: - auther = getAuther(auth.ProxyAuth{}, autherInterf).(*auth.ProxyAuth) + auther = getAuther(auth.ProxyAuth{}, rawAuther).(*auth.ProxyAuth) default: checkErr(errors.New("invalid auth method")) } err = d.store.Auth.Save(auther) checkErr(err) - printSettings(file.Settings, auther) + + printSettings(file.Server, file.Settings, auther) }, pythonConfig{allowNoDB: true}), } diff --git a/cmd/config_init.go b/cmd/config_init.go index 37a698a9..86098376 100644 --- a/cmd/config_init.go +++ b/cmd/config_init.go @@ -24,24 +24,37 @@ override the options.`, Args: cobra.NoArgs, Run: python(func(cmd *cobra.Command, args []string, d pythonData) { defaults := settings.UserDefaults{} - getUserDefaults(cmd, &defaults, true) - authMethod, auther := getAuthentication(cmd) + flags := cmd.Flags() + getUserDefaults(flags, &defaults, true) + authMethod, auther := getAuthentication(flags) s := &settings.Settings{ Key: generateRandomBytes(64), // 256 bit - Signup: mustGetBool(cmd, "signup"), - Shell: strings.Split(strings.TrimSpace(mustGetString(cmd, "shell")), " "), + Signup: mustGetBool(flags, "signup"), + Shell: strings.Split(strings.TrimSpace(mustGetString(flags, "shell")), " "), AuthMethod: authMethod, Defaults: defaults, Branding: settings.Branding{ - Name: mustGetString(cmd, "branding.name"), - DisableExternal: mustGetBool(cmd, "branding.disableExternal"), - Files: mustGetString(cmd, "branding.files"), + Name: mustGetString(flags, "branding.name"), + DisableExternal: mustGetBool(flags, "branding.disableExternal"), + Files: mustGetString(flags, "branding.files"), }, } + ser := &settings.Server{ + Address: mustGetString(flags, "address"), + Root: mustGetString(flags, "root"), + BaseURL: mustGetString(flags, "baseurl"), + TLSKey: mustGetString(flags, "key"), + TLSCert: mustGetString(flags, "cert"), + Port: mustGetString(flags, "port"), + Log: mustGetString(flags, "log"), + } + err := d.store.Settings.Save(s) checkErr(err) + err = d.store.Settings.SaveServer(ser) + checkErr(err) err = d.store.Auth.Save(auther) checkErr(err) @@ -50,6 +63,6 @@ Congratulations! You've set up your database to use with File Browser. Now add your first user via 'filebrowser users new' and then you just need to call the main command to boot up the server. `) - printSettings(s, auther) + printSettings(ser, s, auther) }, pythonConfig{noDB: true}), } diff --git a/cmd/config_set.go b/cmd/config_set.go index b1e6388f..7ccf7e43 100644 --- a/cmd/config_set.go +++ b/cmd/config_set.go @@ -20,41 +20,61 @@ var configSetCmd = &cobra.Command{ you want to change.`, Args: cobra.NoArgs, Run: python(func(cmd *cobra.Command, args []string, d pythonData) { - s, err := d.store.Settings.Get() + flags := cmd.Flags() + set, err := d.store.Settings.Get() + checkErr(err) + + ser, err := d.store.Settings.GetServer() checkErr(err) hasAuth := false - cmd.Flags().Visit(func(flag *pflag.Flag) { + flags.Visit(func(flag *pflag.Flag) { switch flag.Name { + case "baseurl": + ser.BaseURL = mustGetString(flags, flag.Name) + case "root": + ser.Root = mustGetString(flags, flag.Name) + case "cert": + ser.TLSCert = mustGetString(flags, flag.Name) + case "key": + ser.TLSKey = mustGetString(flags, flag.Name) + case "address": + ser.Address = mustGetString(flags, flag.Name) + case "port": + ser.Port = mustGetString(flags, flag.Name) + case "log": + ser.Log = mustGetString(flags, flag.Name) case "signup": - s.Signup = mustGetBool(cmd, flag.Name) + set.Signup = mustGetBool(flags, flag.Name) case "auth.method": hasAuth = true case "shell": - s.Shell = strings.Split(strings.TrimSpace(mustGetString(cmd, flag.Name)), " ") + set.Shell = strings.Split(strings.TrimSpace(mustGetString(flags, flag.Name)), " ") case "branding.name": - s.Branding.Name = mustGetString(cmd, flag.Name) + set.Branding.Name = mustGetString(flags, flag.Name) case "branding.disableExternal": - s.Branding.DisableExternal = mustGetBool(cmd, flag.Name) + set.Branding.DisableExternal = mustGetBool(flags, flag.Name) case "branding.files": - s.Branding.Files = mustGetString(cmd, flag.Name) + set.Branding.Files = mustGetString(flags, flag.Name) } }) - getUserDefaults(cmd, &s.Defaults, false) + getUserDefaults(flags, &set.Defaults, false) var auther auth.Auther if hasAuth { - s.AuthMethod, auther = getAuthentication(cmd) + set.AuthMethod, auther = getAuthentication(flags) err = d.store.Auth.Save(auther) checkErr(err) } else { - auther, err = d.store.Auth.Get(s.AuthMethod) + auther, err = d.store.Auth.Get(set.AuthMethod) checkErr(err) } - err = d.store.Settings.Save(s) + err = d.store.Settings.Save(set) checkErr(err) - printSettings(s, auther) + err = d.store.Settings.SaveServer(ser) + checkErr(err) + printSettings(ser, set, auther) }, pythonConfig{}), } diff --git a/cmd/docs.go b/cmd/docs.go index 0a86f5ab..49f5f3f7 100644 --- a/cmd/docs.go +++ b/cmd/docs.go @@ -40,7 +40,7 @@ var docsCmd = &cobra.Command{ Hidden: true, Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { - dir := mustGetString(cmd, "path") + dir := mustGetString(cmd.Flags(), "path") generateDocs(rootCmd, dir) names := []string{} diff --git a/cmd/root.go b/cmd/root.go index ef9f14ff..25ce85b3 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -18,6 +18,7 @@ import ( "github.com/filebrowser/filebrowser/v2/users" "github.com/mitchellh/go-homedir" "github.com/spf13/cobra" + "github.com/spf13/pflag" v "github.com/spf13/viper" lumberjack "gopkg.in/natefinch/lumberjack.v2" ) @@ -28,29 +29,61 @@ var ( func init() { cobra.OnInitialize(initConfig) + flags := rootCmd.Flags() + persistent := rootCmd.PersistentFlags() - f := rootCmd.Flags() - pf := rootCmd.PersistentFlags() + persistent.StringVarP(&cfgFile, "config", "c", "", "config file path") + persistent.StringP("database", "d", "./filebrowser.db", "database path") + flags.String("username", "admin", "username for the first user when using quick config") + flags.String("password", "", "hashed password for the first user when using quick config (default \"admin\")") - pf.StringVarP(&cfgFile, "config", "c", "", "config file path") - vaddP(pf, "database", "d", "./filebrowser.db", "path to the database") - vaddP(f, "address", "a", "127.0.0.1", "address to listen on") - vaddP(f, "log", "l", "stdout", "log output") - vaddP(f, "port", "p", "8080", "port to listen on") - vaddP(f, "cert", "t", "", "tls certificate") - vaddP(f, "key", "k", "", "tls key") - vaddP(f, "root", "r", ".", "root to prepend to relative paths") - vaddP(f, "baseurl", "b", "", "base url") - vadd(f, "username", "admin", "username for the first user when using quick config") - vadd(f, "password", "", "hashed password for the first user when using quick config (default \"admin\")") + addServerFlags(flags) +} - if err := v.BindPFlags(f); err != nil { - panic(err) +func addServerFlags(flags *pflag.FlagSet) { + flags.StringP("address", "a", "127.0.0.1", "address to listen on") + flags.StringP("log", "l", "stdout", "log output") + flags.StringP("port", "p", "8080", "port to listen on") + flags.StringP("cert", "t", "", "tls certificate") + flags.StringP("key", "k", "", "tls key") + flags.StringP("root", "r", ".", "root to prepend to relative paths") + flags.StringP("baseurl", "b", "", "base url") +} + +// NOTE: we could simply bind the flags to viper and use IsSet. +// Although there is a bug on Viper that always returns true on IsSet +// if a flag is binded. Our alternative way is to manually check +// the flag and then the value from env/config/gotten by viper. +// https://github.com/spf13/viper/pull/331 +func getStringViperFlag(flags *pflag.FlagSet, key string) (string, bool) { + value := "" + set := false + + // If set on Flags, use it. + flags.Visit(func(flag *pflag.Flag) { + if flag.Name == key { + set = true + value, _ = flags.GetString(key) + } + }) + + if set { + return value, set } - if err := v.BindPFlags(pf); err != nil { - panic(err) + // If set through viper (env, config), return it. + if v.IsSet(key) { + return v.GetString(key), true } + + // Otherwise use default value on flags. + value, _ = flags.GetString(key) + return value, false +} + +func mustGetStringViperFlag(flags *pflag.FlagSet, key string) string { + val, _ := getStringViperFlag(flags, key) + return val } var rootCmd = &cobra.Command{ @@ -92,10 +125,10 @@ the quick setup mode and a new database will be bootstraped and a new user created with the credentials from options "username" and "password".`, Run: python(func(cmd *cobra.Command, args []string, d pythonData) { if !d.hadDB { - quickSetup(d) + quickSetup(cmd.Flags(), d) } - server := getServer(d.store) + server := getServerWithViper(cmd.Flags(), d.store) setupLog(server.Log) handler, err := fbhttp.NewHandler(d.store, server) @@ -121,27 +154,40 @@ user created with the credentials from options "username" and "password".`, }, pythonConfig{allowNoDB: true}), } -// TODO: get server settings and only replace -// them if set on Viper. Although viper.IsSet -// is bugged and if binded to a pflag, it will -// always return true. -// Also, when doing that, add this options to -// config init, config import, printConfig -// and config set since the DB values will actually -// be used. For now, despite being stored in the DB, -// they won't be used. -func getServer(st *storage.Storage) *settings.Server { - root := v.GetString("root") - root, err := filepath.Abs(root) +func getServerWithViper(flags *pflag.FlagSet, st *storage.Storage) *settings.Server { + server, err := st.Settings.GetServer() checkErr(err) - server := &settings.Server{} - server.BaseURL = v.GetString("baseurl") - server.Root = root - server.Address = v.GetString("address") - server.Port = v.GetString("port") - server.TLSKey = v.GetString("key") - server.TLSCert = v.GetString("cert") - server.Log = v.GetString("log") + + if val, set := getStringViperFlag(flags, "root"); set { + root, err := filepath.Abs(val) + checkErr(err) + server.Root = root + } + + if val, set := getStringViperFlag(flags, "baseurl"); set { + server.BaseURL = val + } + + if val, set := getStringViperFlag(flags, "address"); set { + server.Address = val + } + + if val, set := getStringViperFlag(flags, "port"); set { + server.Port = val + } + + if val, set := getStringViperFlag(flags, "log"); set { + server.Log = val + } + + if val, set := getStringViperFlag(flags, "key"); set { + server.TLSKey = val + } + + if val, set := getStringViperFlag(flags, "cert"); set { + server.TLSCert = val + } + return server } @@ -164,7 +210,7 @@ func setupLog(logMethod string) { } -func quickSetup(d pythonData) { +func quickSetup(flags *pflag.FlagSet, d pythonData) { set := &settings.Settings{ Key: generateRandomBytes(64), // 256 bit Signup: false, @@ -186,12 +232,13 @@ func quickSetup(d pythonData) { } ser := &settings.Server{ - BaseURL: v.GetString("baseurl"), - Log: v.GetString("log"), - TLSKey: v.GetString("key"), - TLSCert: v.GetString("cert"), - Address: v.GetString("address"), - Root: v.GetString("root"), + BaseURL: mustGetStringViperFlag(flags, "baseurl"), + Port: mustGetStringViperFlag(flags, "port"), + Log: mustGetStringViperFlag(flags, "log"), + TLSKey: mustGetStringViperFlag(flags, "key"), + TLSCert: mustGetStringViperFlag(flags, "cert"), + Address: mustGetStringViperFlag(flags, "address"), + Root: mustGetStringViperFlag(flags, "root"), } err := d.store.Settings.Save(set) @@ -203,8 +250,8 @@ func quickSetup(d pythonData) { err = d.store.Auth.Save(&auth.JSONAuth{}) checkErr(err) - username := v.GetString("username") - password := v.GetString("password") + username := mustGetStringViperFlag(flags, "username") + password := mustGetStringViperFlag(flags, "password") if password == "" { password, err = users.HashPwd("admin") diff --git a/cmd/rules.go b/cmd/rules.go index c3490a5d..0d0f030e 100644 --- a/cmd/rules.go +++ b/cmd/rules.go @@ -8,6 +8,7 @@ import ( "github.com/filebrowser/filebrowser/v2/storage" "github.com/filebrowser/filebrowser/v2/users" "github.com/spf13/cobra" + "github.com/spf13/pflag" ) func init() { @@ -28,7 +29,7 @@ rules.`, } func runRules(st *storage.Storage, cmd *cobra.Command, users func(*users.User), global func(*settings.Settings)) { - id := getUserIdentifier(cmd) + id := getUserIdentifier(cmd.Flags()) if id != nil { user, err := st.Users.Get("", id) checkErr(err) @@ -51,9 +52,9 @@ func runRules(st *storage.Storage, cmd *cobra.Command, users func(*users.User), printRules(settings.Rules, id) } -func getUserIdentifier(cmd *cobra.Command) interface{} { - id := mustGetUint(cmd, "id") - username := mustGetString(cmd, "username") +func getUserIdentifier(flags *pflag.FlagSet) interface{} { + id := mustGetUint(flags, "id") + username := mustGetString(flags, "username") if id != 0 { return id diff --git a/cmd/rules_add.go b/cmd/rules_add.go index e3cfb7a3..bfed8f15 100644 --- a/cmd/rules_add.go +++ b/cmd/rules_add.go @@ -21,8 +21,8 @@ var rulesAddCmd = &cobra.Command{ Long: `Add a global rule or user rule.`, Args: cobra.ExactArgs(1), Run: python(func(cmd *cobra.Command, args []string, d pythonData) { - allow := mustGetBool(cmd, "allow") - regex := mustGetBool(cmd, "regex") + allow := mustGetBool(cmd.Flags(), "allow") + regex := mustGetBool(cmd.Flags(), "regex") exp := args[0] if regex { diff --git a/cmd/upgrade.go b/cmd/upgrade.go index c0e06567..bdc40a5d 100644 --- a/cmd/upgrade.go +++ b/cmd/upgrade.go @@ -3,7 +3,6 @@ package cmd import ( "github.com/filebrowser/filebrowser/v2/storage/bolt/importer" "github.com/spf13/cobra" - v "github.com/spf13/viper" ) func init() { @@ -22,10 +21,10 @@ import share links because they are incompatible with this version.`, Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { - oldDB := mustGetString(cmd, "old.database") - oldConf := mustGetString(cmd, "old.config") - - err := importer.Import(oldDB, oldConf, v.GetString("database")) + flags := cmd.Flags() + oldDB := mustGetString(flags, "old.database") + oldConf := mustGetString(flags, "old.config") + err := importer.Import(oldDB, oldConf, mustGetStringViperFlag(flags, "database")) checkErr(err) }, } diff --git a/cmd/users.go b/cmd/users.go index 9946c3b0..74c1c185 100644 --- a/cmd/users.go +++ b/cmd/users.go @@ -76,53 +76,53 @@ func addUserFlags(flags *pflag.FlagSet) { flags.String("viewMode", string(users.ListViewMode), "view mode for users") } -func getViewMode(cmd *cobra.Command) users.ViewMode { - viewMode := users.ViewMode(mustGetString(cmd, "viewMode")) +func getViewMode(flags *pflag.FlagSet) users.ViewMode { + viewMode := users.ViewMode(mustGetString(flags, "viewMode")) if viewMode != users.ListViewMode && viewMode != users.MosaicViewMode { checkErr(errors.New("view mode must be \"" + string(users.ListViewMode) + "\" or \"" + string(users.MosaicViewMode) + "\"")) } return viewMode } -func getUserDefaults(cmd *cobra.Command, defaults *settings.UserDefaults, all bool) { +func getUserDefaults(flags *pflag.FlagSet, defaults *settings.UserDefaults, all bool) { visit := func(flag *pflag.Flag) { switch flag.Name { case "scope": - defaults.Scope = mustGetString(cmd, flag.Name) + defaults.Scope = mustGetString(flags, flag.Name) case "locale": - defaults.Locale = mustGetString(cmd, flag.Name) + defaults.Locale = mustGetString(flags, flag.Name) case "viewMode": - defaults.ViewMode = getViewMode(cmd) + defaults.ViewMode = getViewMode(flags) case "perm.admin": - defaults.Perm.Admin = mustGetBool(cmd, flag.Name) + defaults.Perm.Admin = mustGetBool(flags, flag.Name) case "perm.execute": - defaults.Perm.Execute = mustGetBool(cmd, flag.Name) + defaults.Perm.Execute = mustGetBool(flags, flag.Name) case "perm.create": - defaults.Perm.Create = mustGetBool(cmd, flag.Name) + defaults.Perm.Create = mustGetBool(flags, flag.Name) case "perm.rename": - defaults.Perm.Rename = mustGetBool(cmd, flag.Name) + defaults.Perm.Rename = mustGetBool(flags, flag.Name) case "perm.modify": - defaults.Perm.Modify = mustGetBool(cmd, flag.Name) + defaults.Perm.Modify = mustGetBool(flags, flag.Name) case "perm.delete": - defaults.Perm.Delete = mustGetBool(cmd, flag.Name) + defaults.Perm.Delete = mustGetBool(flags, flag.Name) case "perm.share": - defaults.Perm.Share = mustGetBool(cmd, flag.Name) + defaults.Perm.Share = mustGetBool(flags, flag.Name) case "perm.download": - defaults.Perm.Download = mustGetBool(cmd, flag.Name) + defaults.Perm.Download = mustGetBool(flags, flag.Name) case "commands": - commands, err := cmd.Flags().GetStringSlice(flag.Name) + commands, err := flags.GetStringSlice(flag.Name) checkErr(err) defaults.Commands = commands case "sorting.by": - defaults.Sorting.By = mustGetString(cmd, flag.Name) + defaults.Sorting.By = mustGetString(flags, flag.Name) case "sorting.asc": - defaults.Sorting.Asc = mustGetBool(cmd, flag.Name) + defaults.Sorting.Asc = mustGetBool(flags, flag.Name) } } if all { - cmd.Flags().VisitAll(visit) + flags.VisitAll(visit) } else { - cmd.Flags().Visit(visit) + flags.Visit(visit) } } diff --git a/cmd/users_add.go b/cmd/users_add.go index 295dbb5c..f0ce0776 100644 --- a/cmd/users_add.go +++ b/cmd/users_add.go @@ -18,7 +18,7 @@ var usersAddCmd = &cobra.Command{ Run: python(func(cmd *cobra.Command, args []string, d pythonData) { s, err := d.store.Settings.Get() checkErr(err) - getUserDefaults(cmd, &s.Defaults, false) + getUserDefaults(cmd.Flags(), &s.Defaults, false) password, err := users.HashPwd(args[1]) checkErr(err) @@ -26,7 +26,7 @@ var usersAddCmd = &cobra.Command{ user := &users.User{ Username: args[0], Password: password, - LockPassword: mustGetBool(cmd, "lockPassword"), + LockPassword: mustGetBool(cmd.Flags(), "lockPassword"), } s.Defaults.Apply(user) diff --git a/cmd/users_import.go b/cmd/users_import.go index ad0dc9e7..67f32f75 100644 --- a/cmd/users_import.go +++ b/cmd/users_import.go @@ -33,20 +33,20 @@ var usersImportCmd = &cobra.Command{ checkErr(err) } - if mustGetBool(cmd, "replace") { + if mustGetBool(cmd.Flags(), "replace") { oldUsers, err := d.store.Users.Gets("") checkErr(err) - + err = marshal("users.backup.json", list) checkErr(err) - + for _, user := range oldUsers { err = d.store.Users.Delete(user.ID) checkErr(err) } } - - overwrite := mustGetBool(cmd, "overwrite") + + overwrite := mustGetBool(cmd.Flags(), "overwrite") for _, user := range list { onDB, err := d.store.Users.Get("", user.ID) diff --git a/cmd/users_update.go b/cmd/users_update.go index e468f5a5..65b281af 100644 --- a/cmd/users_update.go +++ b/cmd/users_update.go @@ -22,8 +22,9 @@ options you want to change.`, Args: cobra.ExactArgs(1), Run: python(func(cmd *cobra.Command, args []string, d pythonData) { username, id := parseUsernameOrID(args[0]) - password := mustGetString(cmd, "password") - newUsername := mustGetString(cmd, "username") + flags := cmd.Flags() + password := mustGetString(flags, "password") + newUsername := mustGetString(flags, "username") var err error var user *users.User @@ -44,14 +45,14 @@ options you want to change.`, Sorting: user.Sorting, Commands: user.Commands, } - getUserDefaults(cmd, &defaults, false) + getUserDefaults(flags, &defaults, false) user.Scope = defaults.Scope user.Locale = defaults.Locale user.ViewMode = defaults.ViewMode user.Perm = defaults.Perm user.Commands = defaults.Commands user.Sorting = defaults.Sorting - user.LockPassword = mustGetBool(cmd, "lockPassword") + user.LockPassword = mustGetBool(flags, "lockPassword") if newUsername != "" { user.Username = newUsername diff --git a/cmd/utils.go b/cmd/utils.go index 9921a578..2478c046 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -14,34 +14,9 @@ import ( "github.com/filebrowser/filebrowser/v2/storage/bolt" "github.com/spf13/cobra" "github.com/spf13/pflag" - v "github.com/spf13/viper" yaml "gopkg.in/yaml.v2" ) -func vaddP(f *pflag.FlagSet, k, p string, i interface{}, u string) { - switch y := i.(type) { - case bool: - f.BoolP(k, p, y, u) - case int: - f.IntP(k, p, y, u) - case string: - f.StringP(k, p, y, u) - } - v.SetDefault(k, i) -} - -func vadd(f *pflag.FlagSet, k string, i interface{}, u string) { - switch y := i.(type) { - case bool: - f.Bool(k, y, u) - case int: - f.Int(k, y, u) - case string: - f.String(k, y, u) - } - v.SetDefault(k, i) -} - func checkErr(err error) { if err != nil { fmt.Println(err) @@ -49,20 +24,20 @@ func checkErr(err error) { } } -func mustGetString(cmd *cobra.Command, flag string) string { - s, err := cmd.Flags().GetString(flag) +func mustGetString(flags *pflag.FlagSet, flag string) string { + s, err := flags.GetString(flag) checkErr(err) return s } -func mustGetBool(cmd *cobra.Command, flag string) bool { - b, err := cmd.Flags().GetBool(flag) +func mustGetBool(flags *pflag.FlagSet, flag string) bool { + b, err := flags.GetBool(flag) checkErr(err) return b } -func mustGetUint(cmd *cobra.Command, flag string) uint { - b, err := cmd.Flags().GetUint(flag) +func mustGetUint(flags *pflag.FlagSet, flag string) uint { + b, err := flags.GetUint(flag) checkErr(err) return b } @@ -92,7 +67,7 @@ func python(fn pythonFunc, cfg pythonConfig) cobraFunc { return func(cmd *cobra.Command, args []string) { data := pythonData{hadDB: true} - path := v.GetString("database") + path := mustGetStringViperFlag(cmd.Flags(), "database") _, err := os.Stat(path) if os.IsNotExist(err) {