From 42ce3cc5d1a8380a2a7ba51dc86628f38ef53a1d Mon Sep 17 00:00:00 2001 From: jagadam97 Date: Sat, 19 Jul 2025 19:45:01 +0530 Subject: [PATCH] fix : return error rather than log.fatal using checkErr --- cmd/cmds_add.go | 8 +- cmd/cmds_ls.go | 9 +- cmd/cmds_rm.go | 16 +++- cmd/config.go | 193 +++++++++++++++++++++++++++---------------- cmd/config_cat.go | 15 ++-- cmd/config_export.go | 16 +++- cmd/config_import.go | 63 ++++++++++---- cmd/config_init.go | 152 ++++++++++++++++++++++++++++------ cmd/config_set.go | 87 ++++++++++++------- cmd/docs.go | 36 +++++--- cmd/hash.go | 7 +- cmd/root.go | 45 +++++++--- cmd/rule_rm.go | 19 +++-- cmd/rules.go | 44 ++++++---- cmd/rules_add.go | 21 +++-- cmd/rules_ls.go | 3 +- cmd/upgrade.go | 19 +++-- cmd/users.go | 57 +++++++------ cmd/users_add.go | 36 ++++++-- cmd/users_export.go | 8 +- cmd/users_find.go | 4 +- cmd/users_import.go | 60 +++++++++----- cmd/users_rm.go | 4 +- cmd/users_update.go | 36 ++++++-- cmd/utils.go | 38 ++++++--- 25 files changed, 699 insertions(+), 297 deletions(-) diff --git a/cmd/cmds_add.go b/cmd/cmds_add.go index 12a2b201..a4d17061 100644 --- a/cmd/cmds_add.go +++ b/cmd/cmds_add.go @@ -17,11 +17,15 @@ var cmdsAddCmd = &cobra.Command{ Args: cobra.MinimumNArgs(2), RunE: python(func(_ *cobra.Command, args []string, d *pythonData) error { s, err := d.store.Settings.Get() - checkErr(err) + if err != nil { + return err + } command := strings.Join(args[1:], " ") s.Commands[args[0]] = append(s.Commands[args[0]], command) err = d.store.Settings.Save(s) - checkErr(err) + if err != nil { + return err + } printEvents(s.Commands) return nil }, pythonConfig{}), diff --git a/cmd/cmds_ls.go b/cmd/cmds_ls.go index 409a1bc0..4f70d650 100644 --- a/cmd/cmds_ls.go +++ b/cmd/cmds_ls.go @@ -16,8 +16,13 @@ var cmdsLsCmd = &cobra.Command{ Args: cobra.NoArgs, RunE: python(func(cmd *cobra.Command, _ []string, d *pythonData) error { s, err := d.store.Settings.Get() - checkErr(err) - evt := mustGetString(cmd.Flags(), "event") + if err != nil { + return err + } + evt, err := mustGetString(cmd.Flags(), "event") + if err != nil { + return err + } if evt == "" { printEvents(s.Commands) diff --git a/cmd/cmds_rm.go b/cmd/cmds_rm.go index 83972ee3..34089388 100644 --- a/cmd/cmds_rm.go +++ b/cmd/cmds_rm.go @@ -37,20 +37,28 @@ including 'index_end'.`, }, RunE: python(func(_ *cobra.Command, args []string, d *pythonData) error { s, err := d.store.Settings.Get() - checkErr(err) + if err != nil { + return err + } evt := args[0] i, err := strconv.Atoi(args[1]) - checkErr(err) + if err != nil { + return err + } f := i if len(args) == 3 { f, err = strconv.Atoi(args[2]) - checkErr(err) + if err != nil { + return err + } } s.Commands[evt] = append(s.Commands[evt][:i], s.Commands[evt][f+1:]...) err = d.store.Settings.Save(s) - checkErr(err) + if err != nil { + return err + } printEvents(s.Commands) return nil }, pythonConfig{}), diff --git a/cmd/config.go b/cmd/config.go index 3ee8dab8..7bd58442 100644 --- a/cmd/config.go +++ b/cmd/config.go @@ -51,9 +51,12 @@ func addConfigFlags(flags *pflag.FlagSet) { flags.Bool("branding.disableUsedPercentage", false, "disable used disk percentage graph") } -//nolint:gocyclo -func getAuthentication(flags *pflag.FlagSet, defaults ...interface{}) (settings.AuthMethod, auth.Auther) { - method := settings.AuthMethod(mustGetString(flags, "auth.method")) +func getAuthMethod(flags *pflag.FlagSet, defaults ...interface{}) (settings.AuthMethod, map[string]interface{}, error) { + methodStr, err := mustGetString(flags, "auth.method") + if err != nil { + return "", nil, err + } + method := settings.AuthMethod(methodStr) var defaultAuther map[string]interface{} if len(defaults) > 0 { @@ -64,83 +67,124 @@ func getAuthentication(flags *pflag.FlagSet, defaults ...interface{}) (settings. method = def.AuthMethod case auth.Auther: ms, err := json.Marshal(def) - checkErr(err) + if err != nil { + return "", nil, err + } err = json.Unmarshal(ms, &defaultAuther) - checkErr(err) + if err != nil { + return "", nil, err + } } } } } - var auther auth.Auther - if method == auth.MethodProxyAuth { - header := mustGetString(flags, "auth.header") - - if header == "" { - header = defaultAuther["header"].(string) - } - - if header == "" { - checkErr(nerrors.New("you must set the flag 'auth.header' for method 'proxy'")) - } - - auther = &auth.ProxyAuth{Header: header} - } - - if method == auth.MethodNoAuth { - auther = &auth.NoAuth{} - } - - if method == auth.MethodJSONAuth { - jsonAuth := &auth.JSONAuth{} - host := mustGetString(flags, "recaptcha.host") - key := mustGetString(flags, "recaptcha.key") - secret := mustGetString(flags, "recaptcha.secret") - - if key == "" { - if kmap, ok := defaultAuther["recaptcha"].(map[string]interface{}); ok { - key = kmap["key"].(string) - } - } - - if secret == "" { - if smap, ok := defaultAuther["recaptcha"].(map[string]interface{}); ok { - secret = smap["secret"].(string) - } - } - - if key != "" && secret != "" { - jsonAuth.ReCaptcha = &auth.ReCaptcha{ - Host: host, - Key: key, - Secret: secret, - } - } - auther = jsonAuth - } - - if method == auth.MethodHookAuth { - command := mustGetString(flags, "auth.command") - - if command == "" { - command = defaultAuther["command"].(string) - } - - if command == "" { - checkErr(nerrors.New("you must set the flag 'auth.command' for method 'hook'")) - } - - auther = &auth.HookAuth{Command: command} - } - - if auther == nil { - panic(errors.ErrInvalidAuthMethod) - } - - return method, auther + return method, defaultAuther, nil } -func printSettings(ser *settings.Server, set *settings.Settings, auther auth.Auther) { +func getProxyAuth(flags *pflag.FlagSet, defaultAuther map[string]interface{}) (auth.Auther, error) { + header, err := mustGetString(flags, "auth.header") + if err != nil { + return nil, err + } + + if header == "" { + header = defaultAuther["header"].(string) + } + + if header == "" { + return nil, nerrors.New("you must set the flag 'auth.header' for method 'proxy'") + } + + return &auth.ProxyAuth{Header: header}, nil +} + +func getNoAuth() auth.Auther { + return &auth.NoAuth{} +} + +func getJSONAuth(flags *pflag.FlagSet, defaultAuther map[string]interface{}) (auth.Auther, error) { + jsonAuth := &auth.JSONAuth{} + host, err := mustGetString(flags, "recaptcha.host") + if err != nil { + return nil, err + } + key, err := mustGetString(flags, "recaptcha.key") + if err != nil { + return nil, err + } + secret, err := mustGetString(flags, "recaptcha.secret") + if err != nil { + return nil, err + } + + if key == "" { + if kmap, ok := defaultAuther["recaptcha"].(map[string]interface{}); ok { + key = kmap["key"].(string) + } + } + + if secret == "" { + if smap, ok := defaultAuther["recaptcha"].(map[string]interface{}); ok { + secret = smap["secret"].(string) + } + } + + if key != "" && secret != "" { + jsonAuth.ReCaptcha = &auth.ReCaptcha{ + Host: host, + Key: key, + Secret: secret, + } + } + return jsonAuth, nil +} + +func getHookAuth(flags *pflag.FlagSet, defaultAuther map[string]interface{}) (auth.Auther, error) { + command, err := mustGetString(flags, "auth.command") + if err != nil { + return nil, err + } + + if command == "" { + command = defaultAuther["command"].(string) + } + + if command == "" { + return nil, nerrors.New("you must set the flag 'auth.command' for method 'hook'") + } + + return &auth.HookAuth{Command: command}, nil +} + +func getAuthentication(flags *pflag.FlagSet, defaults ...interface{}) (settings.AuthMethod, auth.Auther, error) { + method, defaultAuther, err := getAuthMethod(flags, defaults...) + if err != nil { + return "", nil, err + } + + var auther auth.Auther + switch method { + case auth.MethodProxyAuth: + auther, err = getProxyAuth(flags, defaultAuther) + case auth.MethodNoAuth: + auther = getNoAuth() + case auth.MethodJSONAuth: + auther, err = getJSONAuth(flags, defaultAuther) + case auth.MethodHookAuth: + auther, err = getHookAuth(flags, defaultAuther) + default: + return "", nil, errors.ErrInvalidAuthMethod + } + + if err != nil { + return "", nil, err + } + + return method, auther, nil +} + +func printSettings(ser *settings.Server, set *settings.Settings, auther auth.Auther) error { w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0) fmt.Fprintf(w, "Sign up:\t%t\n", set.Signup) @@ -186,6 +230,9 @@ func printSettings(ser *settings.Server, set *settings.Settings, auther auth.Aut w.Flush() b, err := json.MarshalIndent(auther, "", " ") - checkErr(err) + if err != nil { + return err + } fmt.Printf("\nAuther configuration (raw):\n\n%s\n\n", string(b)) + return nil } diff --git a/cmd/config_cat.go b/cmd/config_cat.go index 507dfc6e..39b1f664 100644 --- a/cmd/config_cat.go +++ b/cmd/config_cat.go @@ -15,12 +15,17 @@ var configCatCmd = &cobra.Command{ Args: cobra.NoArgs, RunE: python(func(_ *cobra.Command, _ []string, d *pythonData) error { set, err := d.store.Settings.Get() - checkErr(err) + if err != nil { + return err + } ser, err := d.store.Settings.GetServer() - checkErr(err) + if err != nil { + return err + } auther, err := d.store.Auth.Get(set.AuthMethod) - checkErr(err) - printSettings(ser, set, auther) - return nil + if err != nil { + return err + } + return printSettings(ser, set, auther) }, pythonConfig{}), } diff --git a/cmd/config_export.go b/cmd/config_export.go index aafb1f17..9877fb63 100644 --- a/cmd/config_export.go +++ b/cmd/config_export.go @@ -17,13 +17,19 @@ and imported again with 'config import' command.`, Args: jsonYamlArg, RunE: python(func(_ *cobra.Command, args []string, d *pythonData) error { settings, err := d.store.Settings.Get() - checkErr(err) + if err != nil { + return err + } server, err := d.store.Settings.GetServer() - checkErr(err) + if err != nil { + return err + } auther, err := d.store.Auth.Get(settings.AuthMethod) - checkErr(err) + if err != nil { + return err + } data := &settingsFile{ Settings: settings, @@ -32,7 +38,9 @@ and imported again with 'config import' command.`, } err = marshal(args[0], data) - checkErr(err) + if err != nil { + return err + } return nil }, pythonConfig{}), } diff --git a/cmd/config_import.go b/cmd/config_import.go index baef7c29..7763517d 100644 --- a/cmd/config_import.go +++ b/cmd/config_import.go @@ -36,24 +36,33 @@ The path must be for a json or yaml file.`, Args: jsonYamlArg, RunE: python(func(_ *cobra.Command, args []string, d *pythonData) error { var key []byte + var err error if d.hadDB { - settings, err := d.store.Settings.Get() - checkErr(err) + settings, settingErr := d.store.Settings.Get() + if settingErr != nil { + return settingErr + } key = settings.Key } else { key = generateKey() } file := settingsFile{} - err := unmarshal(args[0], &file) - checkErr(err) + err = unmarshal(args[0], &file) + if err != nil { + return err + } file.Settings.Key = key err = d.store.Settings.Save(file.Settings) - checkErr(err) + if err != nil { + return err + } err = d.store.Settings.SaveServer(file.Server) - checkErr(err) + if err != nil { + return err + } var rawAuther interface{} if filepath.Ext(args[0]) != ".json" { @@ -63,33 +72,51 @@ The path must be for a json or yaml file.`, } var auther auth.Auther + var autherErr error switch file.Settings.AuthMethod { case auth.MethodJSONAuth: - auther = getAuther(auth.JSONAuth{}, rawAuther).(*auth.JSONAuth) + var a interface{} + a, autherErr = getAuther(auth.JSONAuth{}, rawAuther) + auther = a.(*auth.JSONAuth) case auth.MethodNoAuth: - auther = getAuther(auth.NoAuth{}, rawAuther).(*auth.NoAuth) + var a interface{} + a, autherErr = getAuther(auth.NoAuth{}, rawAuther) + auther = a.(*auth.NoAuth) case auth.MethodProxyAuth: - auther = getAuther(auth.ProxyAuth{}, rawAuther).(*auth.ProxyAuth) + var a interface{} + a, autherErr = getAuther(auth.ProxyAuth{}, rawAuther) + auther = a.(*auth.ProxyAuth) case auth.MethodHookAuth: - auther = getAuther(&auth.HookAuth{}, rawAuther).(*auth.HookAuth) + var a interface{} + a, autherErr = getAuther(&auth.HookAuth{}, rawAuther) + auther = a.(*auth.HookAuth) default: - checkErr(errors.New("invalid auth method")) + return errors.New("invalid auth method") + } + + if autherErr != nil { + return autherErr } err = d.store.Auth.Save(auther) - checkErr(err) + if err != nil { + return err + } - printSettings(file.Server, file.Settings, auther) - return nil + return printSettings(file.Server, file.Settings, auther) }, pythonConfig{allowNoDB: true}), } -func getAuther(sample auth.Auther, data interface{}) interface{} { +func getAuther(sample auth.Auther, data interface{}) (interface{}, error) { authType := reflect.TypeOf(sample) auther := reflect.New(authType).Interface() bytes, err := json.Marshal(data) - checkErr(err) + if err != nil { + return nil, err + } err = json.Unmarshal(bytes, &auther) - checkErr(err) - return auther + if err != nil { + return nil, err + } + return auther, nil } diff --git a/cmd/config_init.go b/cmd/config_init.go index c57008ef..115dc2ee 100644 --- a/cmd/config_init.go +++ b/cmd/config_init.go @@ -25,50 +25,148 @@ override the options.`, RunE: python(func(cmd *cobra.Command, _ []string, d *pythonData) error { defaults := settings.UserDefaults{} flags := cmd.Flags() - getUserDefaults(flags, &defaults, true) - authMethod, auther := getAuthentication(flags) + err := getUserDefaults(flags, &defaults, true) + if err != nil { + return err + } + authMethod, auther, err := getAuthentication(flags) + if err != nil { + return err + } + + key := generateKey() + + signup, err := mustGetBool(flags, "signup") + if err != nil { + return err + } + + createUserDir, err := mustGetBool(flags, "create-user-dir") + if err != nil { + return err + } + + minLength, err := mustGetUint(flags, "minimum-password-length") + if err != nil { + return err + } + + shell, err := mustGetString(flags, "shell") + if err != nil { + return err + } + + brandingName, err := mustGetString(flags, "branding.name") + if err != nil { + return err + } + + brandingDisableExternal, err := mustGetBool(flags, "branding.disableExternal") + if err != nil { + return err + } + + brandingDisableUsedPercentage, err := mustGetBool(flags, "branding.disableUsedPercentage") + if err != nil { + return err + } + + brandingTheme, err := mustGetString(flags, "branding.theme") + if err != nil { + return err + } + + brandingFiles, err := mustGetString(flags, "branding.files") + if err != nil { + return err + } s := &settings.Settings{ - Key: generateKey(), - Signup: mustGetBool(flags, "signup"), - CreateUserDir: mustGetBool(flags, "create-user-dir"), - MinimumPasswordLength: mustGetUint(flags, "minimum-password-length"), - Shell: convertCmdStrToCmdArray(mustGetString(flags, "shell")), + Key: key, + Signup: signup, + CreateUserDir: createUserDir, + MinimumPasswordLength: minLength, + Shell: convertCmdStrToCmdArray(shell), AuthMethod: authMethod, Defaults: defaults, Branding: settings.Branding{ - Name: mustGetString(flags, "branding.name"), - DisableExternal: mustGetBool(flags, "branding.disableExternal"), - DisableUsedPercentage: mustGetBool(flags, "branding.disableUsedPercentage"), - Theme: mustGetString(flags, "branding.theme"), - Files: mustGetString(flags, "branding.files"), + Name: brandingName, + DisableExternal: brandingDisableExternal, + DisableUsedPercentage: brandingDisableUsedPercentage, + Theme: brandingTheme, + Files: brandingFiles, }, } - ser := &settings.Server{ - Address: mustGetString(flags, "address"), - Socket: mustGetString(flags, "socket"), - Root: mustGetString(flags, "root"), - BaseURL: mustGetString(flags, "baseurl"), - TLSKey: mustGetString(flags, "key"), - TLSCert: mustGetString(flags, "cert"), - Port: mustGetString(flags, "port"), - Log: mustGetString(flags, "log"), + address, err := mustGetString(flags, "address") + if err != nil { + return err } - err := d.store.Settings.Save(s) - checkErr(err) + socket, err := mustGetString(flags, "socket") + if err != nil { + return err + } + + root, err := mustGetString(flags, "root") + if err != nil { + return err + } + + baseURL, err := mustGetString(flags, "baseurl") + if err != nil { + return err + } + + tlsKey, err := mustGetString(flags, "key") + if err != nil { + return err + } + + cert, err := mustGetString(flags, "cert") + if err != nil { + return err + } + + port, err := mustGetString(flags, "port") + if err != nil { + return err + } + + log, err := mustGetString(flags, "log") + if err != nil { + return err + } + + ser := &settings.Server{ + Address: address, + Socket: socket, + Root: root, + BaseURL: baseURL, + TLSKey: tlsKey, + TLSCert: cert, + Port: port, + Log: log, + } + + err = d.store.Settings.Save(s) + if err != nil { + return err + } err = d.store.Settings.SaveServer(ser) - checkErr(err) + if err != nil { + return err + } err = d.store.Auth.Save(auther) - checkErr(err) + if err != nil { + return err + } fmt.Printf(` Congratulations! You've set up your database to use with File Browser. Now add your first user via 'filebrowser users add' and then you just need to call the main command to boot up the server. `) - printSettings(ser, s, auther) - return nil + return printSettings(ser, s, auther) }, pythonConfig{noDB: true}), } diff --git a/cmd/config_set.go b/cmd/config_set.go index d7256d9f..2f6fd77c 100644 --- a/cmd/config_set.go +++ b/cmd/config_set.go @@ -19,71 +19,102 @@ you want to change. Other options will remain unchanged.`, RunE: python(func(cmd *cobra.Command, _ []string, d *pythonData) error { flags := cmd.Flags() set, err := d.store.Settings.Get() - checkErr(err) + if err != nil { + return err + } ser, err := d.store.Settings.GetServer() - checkErr(err) + if err != nil { + return err + } hasAuth := false + var visitErr error flags.Visit(func(flag *pflag.Flag) { + if visitErr != nil { + return + } + var configSetErr error switch flag.Name { case "baseurl": - ser.BaseURL = mustGetString(flags, flag.Name) + ser.BaseURL, configSetErr = mustGetString(flags, flag.Name) case "root": - ser.Root = mustGetString(flags, flag.Name) + ser.Root, configSetErr = mustGetString(flags, flag.Name) case "socket": - ser.Socket = mustGetString(flags, flag.Name) + ser.Socket, configSetErr = mustGetString(flags, flag.Name) case "cert": - ser.TLSCert = mustGetString(flags, flag.Name) + ser.TLSCert, configSetErr = mustGetString(flags, flag.Name) case "key": - ser.TLSKey = mustGetString(flags, flag.Name) + ser.TLSKey, configSetErr = mustGetString(flags, flag.Name) case "address": - ser.Address = mustGetString(flags, flag.Name) + ser.Address, configSetErr = mustGetString(flags, flag.Name) case "port": - ser.Port = mustGetString(flags, flag.Name) + ser.Port, configSetErr = mustGetString(flags, flag.Name) case "log": - ser.Log = mustGetString(flags, flag.Name) + ser.Log, configSetErr = mustGetString(flags, flag.Name) case "signup": - set.Signup = mustGetBool(flags, flag.Name) + set.Signup, configSetErr = mustGetBool(flags, flag.Name) case "auth.method": hasAuth = true case "shell": - set.Shell = convertCmdStrToCmdArray(mustGetString(flags, flag.Name)) + var shell string + shell, configSetErr = mustGetString(flags, flag.Name) + set.Shell = convertCmdStrToCmdArray(shell) case "create-user-dir": - set.CreateUserDir = mustGetBool(flags, flag.Name) + set.CreateUserDir, configSetErr = mustGetBool(flags, flag.Name) case "minimum-password-length": - set.MinimumPasswordLength = mustGetUint(flags, flag.Name) + set.MinimumPasswordLength, configSetErr = mustGetUint(flags, flag.Name) case "branding.name": - set.Branding.Name = mustGetString(flags, flag.Name) + set.Branding.Name, configSetErr = mustGetString(flags, flag.Name) case "branding.color": - set.Branding.Color = mustGetString(flags, flag.Name) + set.Branding.Color, configSetErr = mustGetString(flags, flag.Name) case "branding.theme": - set.Branding.Theme = mustGetString(flags, flag.Name) + set.Branding.Theme, configSetErr = mustGetString(flags, flag.Name) case "branding.disableExternal": - set.Branding.DisableExternal = mustGetBool(flags, flag.Name) + set.Branding.DisableExternal, configSetErr = mustGetBool(flags, flag.Name) case "branding.disableUsedPercentage": - set.Branding.DisableUsedPercentage = mustGetBool(flags, flag.Name) + set.Branding.DisableUsedPercentage, configSetErr = mustGetBool(flags, flag.Name) case "branding.files": - set.Branding.Files = mustGetString(flags, flag.Name) + set.Branding.Files, configSetErr = mustGetString(flags, flag.Name) + } + if configSetErr != nil { + visitErr = configSetErr } }) - getUserDefaults(flags, &set.Defaults, false) + if visitErr != nil { + return visitErr + } + + err = getUserDefaults(flags, &set.Defaults, false) + if err != nil { + return err + } // read the defaults auther, err := d.store.Auth.Get(set.AuthMethod) - checkErr(err) + if err != nil { + return err + } // check if there are new flags for existing auth method - set.AuthMethod, auther = getAuthentication(flags, hasAuth, set, auther) + set.AuthMethod, auther, err = getAuthentication(flags, hasAuth, set, auther) + if err != nil { + return err + } err = d.store.Auth.Save(auther) - checkErr(err) + if err != nil { + return err + } err = d.store.Settings.Save(set) - checkErr(err) + if err != nil { + return err + } err = d.store.Settings.SaveServer(ser) - checkErr(err) - printSettings(ser, set, auther) - return nil + if err != nil { + return err + } + return printSettings(ser, set, auther) }, pythonConfig{}), } diff --git a/cmd/docs.go b/cmd/docs.go index 88d39d18..941b0acd 100644 --- a/cmd/docs.go +++ b/cmd/docs.go @@ -39,12 +39,18 @@ var docsCmd = &cobra.Command{ Use: "docs", Hidden: true, Args: cobra.NoArgs, - Run: func(cmd *cobra.Command, _ []string) { - dir := mustGetString(cmd.Flags(), "path") - generateDocs(rootCmd, dir) + RunE: func(cmd *cobra.Command, _ []string) error { + dir, err := mustGetString(cmd.Flags(), "path") + if err != nil { + return err + } + err = generateDocs(rootCmd, dir) + if err != nil { + return err + } names := []string{} - err := filepath.Walk(dir, func(_ string, info os.FileInfo, err error) error { + walkErr := filepath.Walk(dir, func(_ string, info os.FileInfo, err error) error { if err != nil || info.IsDir() { return err } @@ -57,29 +63,37 @@ var docsCmd = &cobra.Command{ return nil }) - checkErr(err) + if walkErr != nil { + return walkErr + } printToc(names) + return nil }, } -func generateDocs(cmd *cobra.Command, dir string) { +func generateDocs(cmd *cobra.Command, dir string) error { for _, c := range cmd.Commands() { if !c.IsAvailableCommand() || c.IsAdditionalHelpTopicCommand() { continue } - generateDocs(c, dir) + err := generateDocs(c, dir) + if err != nil { + return err + } } basename := strings.Replace(cmd.CommandPath(), " ", "-", -1) + ".md" filename := filepath.Join(dir, basename) f, err := os.Create(filename) - checkErr(err) + if err != nil { + return err + } defer f.Close() - generateMarkdown(cmd, f) + return generateMarkdown(cmd, f) } -func generateMarkdown(cmd *cobra.Command, w io.Writer) { +func generateMarkdown(cmd *cobra.Command, w io.Writer) error { cmd.InitDefaultHelpCmd() cmd.InitDefaultHelpFlag() @@ -108,7 +122,7 @@ func generateMarkdown(cmd *cobra.Command, w io.Writer) { printOptions(buf, cmd) _, err := buf.WriteTo(w) - checkErr(err) + return err } func generateFlagsTable(fs *pflag.FlagSet, buf io.StringWriter) { diff --git a/cmd/hash.go b/cmd/hash.go index 7d16df5e..3e7d8cdc 100644 --- a/cmd/hash.go +++ b/cmd/hash.go @@ -17,9 +17,12 @@ var hashCmd = &cobra.Command{ Short: "Hashes a password", Long: `Hashes a password using bcrypt algorithm.`, Args: cobra.ExactArgs(1), - Run: func(_ *cobra.Command, args []string) { + RunE: func(_ *cobra.Command, args []string) error { pwd, err := users.HashPwd(args[0]) - checkErr(err) + if err != nil { + return err + } fmt.Println(pwd) + return nil }, } diff --git a/cmd/root.go b/cmd/root.go index 96faf893..4e7b1213 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -4,6 +4,7 @@ import ( "context" "crypto/tls" "errors" + "fmt" "io" "io/fs" "log" @@ -123,18 +124,22 @@ user created with the credentials from options "username" and "password".`, // build img service workersCount, err := cmd.Flags().GetInt("img-processors") - checkErr(err) + if err != nil { + return err + } if workersCount < 1 { - log.Fatal("Image resize workers count could not be < 1") + return errors.New("image resize workers count could not be < 1") } imgSvc := img.New(workersCount) var fileCache diskcache.Interface = diskcache.NewNoOp() cacheDir, err := cmd.Flags().GetString("cache-dir") - checkErr(err) + if err != nil { + return err + } if cacheDir != "" { if err := os.MkdirAll(cacheDir, 0700); err != nil { //nolint:govet - log.Fatalf("can't make directory %s: %s", cacheDir, err) + return fmt.Errorf("can't make directory %s: %w", cacheDir, err) } fileCache = diskcache.New(afero.NewOsFs(), cacheDir) } @@ -143,7 +148,9 @@ user created with the credentials from options "username" and "password".`, setupLog(server.Log) root, err := filepath.Abs(server.Root) - checkErr(err) + if err != nil { + return err + } server.Root = root adr := server.Address + ":" + server.Port @@ -153,22 +160,34 @@ user created with the credentials from options "username" and "password".`, switch { case server.Socket != "": listener, err = net.Listen("unix", server.Socket) - checkErr(err) + if err != nil { + return err + } socketPerm, err := cmd.Flags().GetUint32("socket-perm") //nolint:govet - checkErr(err) + if err != nil { + return err + } err = os.Chmod(server.Socket, os.FileMode(socketPerm)) - checkErr(err) + if err != nil { + return err + } case server.TLSKey != "" && server.TLSCert != "": cer, err := tls.LoadX509KeyPair(server.TLSCert, server.TLSKey) //nolint:govet - checkErr(err) + if err != nil { + return err + } listener, err = tls.Listen("tcp", adr, &tls.Config{ MinVersion: tls.VersionTLS12, Certificates: []tls.Certificate{cer}}, ) - checkErr(err) + if err != nil { + return err + } default: listener, err = net.Listen("tcp", adr) - checkErr(err) + if err != nil { + return err + } } assetsFs, err := fs.Sub(frontend.Assets(), "dist") @@ -177,7 +196,9 @@ user created with the credentials from options "username" and "password".`, } handler, err := fbhttp.NewHandler(imgSvc, fileCache, d.store, server, assetsFs) - checkErr(err) + if err != nil { + return err + } defer listener.Close() diff --git a/cmd/rule_rm.go b/cmd/rule_rm.go index 74175e4a..1437fc2f 100644 --- a/cmd/rule_rm.go +++ b/cmd/rule_rm.go @@ -42,26 +42,33 @@ including 'index_end'.`, }, RunE: python(func(cmd *cobra.Command, args []string, d *pythonData) error { i, err := strconv.Atoi(args[0]) - checkErr(err) + if err != nil { + return err + } f := i if len(args) == 2 { f, err = strconv.Atoi(args[1]) - checkErr(err) + if err != nil { + return err + } } user := func(u *users.User) { u.Rules = append(u.Rules[:i], u.Rules[f+1:]...) err := d.store.Users.Save(u) - checkErr(err) + if err != nil { + checkErr(err) + } } global := func(s *settings.Settings) { s.Rules = append(s.Rules[:i], s.Rules[f+1:]...) err := d.store.Settings.Save(s) - checkErr(err) + if err != nil { + checkErr(err) + } } - runRules(d.store, cmd, user, global) - return nil + return runRules(d.store, cmd, user, global) }, pythonConfig{}), } diff --git a/cmd/rules.go b/cmd/rules.go index 3bf91dd1..ec6afd5d 100644 --- a/cmd/rules.go +++ b/cmd/rules.go @@ -29,41 +29,55 @@ rules.`, Args: cobra.NoArgs, } -func runRules(st *storage.Storage, cmd *cobra.Command, usersFn func(*users.User), globalFn func(*settings.Settings)) { - id := getUserIdentifier(cmd.Flags()) +func runRules(st *storage.Storage, cmd *cobra.Command, usersFn func(*users.User), globalFn func(*settings.Settings)) error { + id, err := getUserIdentifier(cmd.Flags()) + if err != nil { + return err + } if id != nil { - user, err := st.Users.Get("", id) - checkErr(err) + user, usrErr := st.Users.Get("", id) + if usrErr != nil { + return usrErr + } if usersFn != nil { usersFn(user) } printRules(user.Rules, id) - return + return nil } s, err := st.Settings.Get() - checkErr(err) + if err != nil { + return err + } if globalFn != nil { globalFn(s) } printRules(s.Rules, id) + return nil } -func getUserIdentifier(flags *pflag.FlagSet) interface{} { - id := mustGetUint(flags, "id") - username := mustGetString(flags, "username") - - if id != 0 { - return id - } else if username != "" { - return username +func getUserIdentifier(flags *pflag.FlagSet) (interface{}, error) { + id, err := mustGetUint(flags, "id") + if err != nil { + return nil, err + } + username, err := mustGetString(flags, "username") + if err != nil { + return nil, err } - return nil + if id != 0 { + return id, nil + } else if username != "" { + return username, nil + } + + return nil, nil } func printRules(rulez []rules.Rule, id interface{}) { diff --git a/cmd/rules_add.go b/cmd/rules_add.go index 5005ad66..3ec30feb 100644 --- a/cmd/rules_add.go +++ b/cmd/rules_add.go @@ -22,8 +22,14 @@ var rulesAddCmd = &cobra.Command{ Long: `Add a global rule or user rule.`, Args: cobra.ExactArgs(1), RunE: python(func(cmd *cobra.Command, args []string, d *pythonData) error { - allow := mustGetBool(cmd.Flags(), "allow") - regex := mustGetBool(cmd.Flags(), "regex") + allow, err := mustGetBool(cmd.Flags(), "allow") + if err != nil { + return err + } + regex, err := mustGetBool(cmd.Flags(), "regex") + if err != nil { + return err + } exp := args[0] if regex { @@ -44,16 +50,19 @@ var rulesAddCmd = &cobra.Command{ user := func(u *users.User) { u.Rules = append(u.Rules, rule) err := d.store.Users.Save(u) - checkErr(err) + if err != nil { + checkErr(err) + } } global := func(s *settings.Settings) { s.Rules = append(s.Rules, rule) err := d.store.Settings.Save(s) - checkErr(err) + if err != nil { + checkErr(err) + } } - runRules(d.store, cmd, user, global) - return nil + return runRules(d.store, cmd, user, global) }, pythonConfig{}), } diff --git a/cmd/rules_ls.go b/cmd/rules_ls.go index fa017dc2..67a279dc 100644 --- a/cmd/rules_ls.go +++ b/cmd/rules_ls.go @@ -14,7 +14,6 @@ var rulesLsCommand = &cobra.Command{ Long: `List global rules or user specific rules.`, Args: cobra.NoArgs, RunE: python(func(cmd *cobra.Command, _ []string, d *pythonData) error { - runRules(d.store, cmd, nil, nil) - return nil + return runRules(d.store, cmd, nil, nil) }, pythonConfig{}), } diff --git a/cmd/upgrade.go b/cmd/upgrade.go index f6966e2e..3976e9d9 100644 --- a/cmd/upgrade.go +++ b/cmd/upgrade.go @@ -21,11 +21,20 @@ var upgradeCmd = &cobra.Command{ import share links because they are incompatible with this version.`, Args: cobra.NoArgs, - Run: func(cmd *cobra.Command, _ []string) { + RunE: func(cmd *cobra.Command, _ []string) error { flags := cmd.Flags() - oldDB := mustGetString(flags, "old.database") - oldConf := mustGetString(flags, "old.config") - err := importer.Import(oldDB, oldConf, getStringParam(flags, "database")) - checkErr(err) + oldDB, err := mustGetString(flags, "old.database") + if err != nil { + return err + } + oldConf, err := mustGetString(flags, "old.config") + if err != nil { + return err + } + db, err := mustGetString(flags, "database") + if err != nil { + return err + } + return importer.Import(oldDB, oldConf, db) }, } diff --git a/cmd/users.go b/cmd/users.go index d3f97da6..f5bc29b5 100644 --- a/cmd/users.go +++ b/cmd/users.go @@ -79,50 +79,60 @@ func addUserFlags(flags *pflag.FlagSet) { flags.Bool("singleClick", false, "use single clicks only") } -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) + "\"")) +func getViewMode(flags *pflag.FlagSet) (users.ViewMode, error) { + viewModeStr, err := mustGetString(flags, "viewMode") + if err != nil { + return "", err } - return viewMode + 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 } //nolint:gocyclo -func getUserDefaults(flags *pflag.FlagSet, defaults *settings.UserDefaults, all bool) { +func getUserDefaults(flags *pflag.FlagSet, defaults *settings.UserDefaults, all bool) error { + var visitErr error visit := func(flag *pflag.Flag) { + if visitErr != nil { + return + } + var err error switch flag.Name { case "scope": - defaults.Scope = mustGetString(flags, flag.Name) + defaults.Scope, err = mustGetString(flags, flag.Name) case "locale": - defaults.Locale = mustGetString(flags, flag.Name) + defaults.Locale, err = mustGetString(flags, flag.Name) case "viewMode": - defaults.ViewMode = getViewMode(flags) + defaults.ViewMode, err = getViewMode(flags) case "singleClick": - defaults.SingleClick = mustGetBool(flags, flag.Name) + defaults.SingleClick, err = mustGetBool(flags, flag.Name) case "perm.admin": - defaults.Perm.Admin = mustGetBool(flags, flag.Name) + defaults.Perm.Admin, err = mustGetBool(flags, flag.Name) case "perm.execute": - defaults.Perm.Execute = mustGetBool(flags, flag.Name) + defaults.Perm.Execute, err = mustGetBool(flags, flag.Name) case "perm.create": - defaults.Perm.Create = mustGetBool(flags, flag.Name) + defaults.Perm.Create, err = mustGetBool(flags, flag.Name) case "perm.rename": - defaults.Perm.Rename = mustGetBool(flags, flag.Name) + defaults.Perm.Rename, err = mustGetBool(flags, flag.Name) case "perm.modify": - defaults.Perm.Modify = mustGetBool(flags, flag.Name) + defaults.Perm.Modify, err = mustGetBool(flags, flag.Name) case "perm.delete": - defaults.Perm.Delete = mustGetBool(flags, flag.Name) + defaults.Perm.Delete, err = mustGetBool(flags, flag.Name) case "perm.share": - defaults.Perm.Share = mustGetBool(flags, flag.Name) + defaults.Perm.Share, err = mustGetBool(flags, flag.Name) case "perm.download": - defaults.Perm.Download = mustGetBool(flags, flag.Name) + defaults.Perm.Download, err = mustGetBool(flags, flag.Name) case "commands": - commands, err := flags.GetStringSlice(flag.Name) - checkErr(err) - defaults.Commands = commands + defaults.Commands, err = flags.GetStringSlice(flag.Name) case "sorting.by": - defaults.Sorting.By = mustGetString(flags, flag.Name) + defaults.Sorting.By, err = mustGetString(flags, flag.Name) case "sorting.asc": - defaults.Sorting.Asc = mustGetBool(flags, flag.Name) + defaults.Sorting.Asc, err = mustGetBool(flags, flag.Name) + } + if err != nil { + visitErr = err } } @@ -131,4 +141,5 @@ func getUserDefaults(flags *pflag.FlagSet, defaults *settings.UserDefaults, all } else { flags.Visit(visit) } + return visitErr } diff --git a/cmd/users_add.go b/cmd/users_add.go index 66a61088..1358d7e1 100644 --- a/cmd/users_add.go +++ b/cmd/users_add.go @@ -18,34 +18,54 @@ var usersAddCmd = &cobra.Command{ Args: cobra.ExactArgs(2), RunE: python(func(cmd *cobra.Command, args []string, d *pythonData) error { s, err := d.store.Settings.Get() - checkErr(err) - getUserDefaults(cmd.Flags(), &s.Defaults, false) + if err != nil { + return err + } + err = getUserDefaults(cmd.Flags(), &s.Defaults, false) + if err != nil { + return err + } password, err := users.ValidateAndHashPwd(args[1], s.MinimumPasswordLength) - checkErr(err) + if err != nil { + return err + } + + lockPassword, err := mustGetBool(cmd.Flags(), "lockPassword") + if err != nil { + return err + } user := &users.User{ Username: args[0], Password: password, - LockPassword: mustGetBool(cmd.Flags(), "lockPassword"), + LockPassword: lockPassword, } s.Defaults.Apply(user) servSettings, err := d.store.Settings.GetServer() - checkErr(err) + if err != nil { + return err + } // since getUserDefaults() polluted s.Defaults.Scope // which makes the Scope not the one saved in the db // we need the right s.Defaults.Scope here s2, err := d.store.Settings.Get() - checkErr(err) + if err != nil { + return err + } userHome, err := s2.MakeUserDir(user.Username, user.Scope, servSettings.Root) - checkErr(err) + if err != nil { + return err + } user.Scope = userHome err = d.store.Users.Save(user) - checkErr(err) + if err != nil { + return err + } printUsers([]*users.User{user}) return nil }, pythonConfig{}), diff --git a/cmd/users_export.go b/cmd/users_export.go index 65462727..d6009a37 100644 --- a/cmd/users_export.go +++ b/cmd/users_export.go @@ -16,10 +16,14 @@ path to the file where you want to write the users.`, Args: jsonYamlArg, RunE: python(func(_ *cobra.Command, args []string, d *pythonData) error { list, err := d.store.Users.Gets("") - checkErr(err) + if err != nil { + return err + } err = marshal(args[0], list) - checkErr(err) + if err != nil { + return err + } return nil }, pythonConfig{}), } diff --git a/cmd/users_find.go b/cmd/users_find.go index 9bdad2a1..0dea071a 100644 --- a/cmd/users_find.go +++ b/cmd/users_find.go @@ -46,7 +46,9 @@ var findUsers = python(func(_ *cobra.Command, args []string, d *pythonData) erro list, err = d.store.Users.Gets("") } - checkErr(err) + if err != nil { + return err + } printUsers(list) return nil }, pythonConfig{}) diff --git a/cmd/users_import.go b/cmd/users_import.go index 8a40c0bd..d7b32454 100644 --- a/cmd/users_import.go +++ b/cmd/users_import.go @@ -27,32 +27,52 @@ list or set it to 0.`, Args: jsonYamlArg, RunE: python(func(cmd *cobra.Command, args []string, d *pythonData) error { fd, err := os.Open(args[0]) - checkErr(err) + if err != nil { + return err + } defer fd.Close() list := []*users.User{} err = unmarshal(args[0], &list) - checkErr(err) + if err != nil { + return err + } for _, user := range list { err = user.Clean("") - checkErr(err) - } - - 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) + if err != nil { + return err } } - overwrite := mustGetBool(cmd.Flags(), "overwrite") + replace, err := mustGetBool(cmd.Flags(), "replace") + if err != nil { + return err + } + + if replace { + oldUsers, userImportErr := d.store.Users.Gets("") + if userImportErr != nil { + return userImportErr + } + + err = marshal("users.backup.json", list) + if err != nil { + return err + } + + for _, user := range oldUsers { + err = d.store.Users.Delete(user.ID) + if err != nil { + return err + } + } + } + + overwrite, err := mustGetBool(cmd.Flags(), "overwrite") + if err != nil { + return err + } for _, user := range list { onDB, err := d.store.Users.Get("", user.ID) @@ -60,7 +80,7 @@ list or set it to 0.`, // User exists in DB. if err == nil { if !overwrite { - checkErr(errors.New("user " + strconv.Itoa(int(user.ID)) + " is already registered")) + return errors.New("user " + strconv.Itoa(int(user.ID)) + " is already registered") } // If the usernames mismatch, check if there is another one in the DB @@ -68,7 +88,7 @@ list or set it to 0.`, // operation if user.Username != onDB.Username { if conflictuous, err := d.store.Users.Get("", user.Username); err == nil { //nolint:govet - checkErr(usernameConflictError(user.Username, conflictuous.ID, user.ID)) + return usernameConflictError(user.Username, conflictuous.ID, user.ID) } } } else { @@ -78,7 +98,9 @@ list or set it to 0.`, } err = d.store.Users.Save(user) - checkErr(err) + if err != nil { + return err + } } return nil }, pythonConfig{}), diff --git a/cmd/users_rm.go b/cmd/users_rm.go index fa5a216c..55b973f4 100644 --- a/cmd/users_rm.go +++ b/cmd/users_rm.go @@ -25,7 +25,9 @@ var usersRmCmd = &cobra.Command{ err = d.store.Users.Delete(id) } - checkErr(err) + if err != nil { + return err + } fmt.Println("user deleted successfully") return nil }, pythonConfig{}), diff --git a/cmd/users_update.go b/cmd/users_update.go index 3ed440ff..ad3ab877 100644 --- a/cmd/users_update.go +++ b/cmd/users_update.go @@ -24,11 +24,19 @@ options you want to change.`, RunE: python(func(cmd *cobra.Command, args []string, d *pythonData) error { username, id := parseUsernameOrID(args[0]) flags := cmd.Flags() - password := mustGetString(flags, "password") - newUsername := mustGetString(flags, "username") + password, err := mustGetString(flags, "password") + if err != nil { + return err + } + newUsername, err := mustGetString(flags, "username") + if err != nil { + return err + } s, err := d.store.Settings.Get() - checkErr(err) + if err != nil { + return err + } var ( user *users.User @@ -40,7 +48,9 @@ options you want to change.`, user, err = d.store.Users.Get("", username) } - checkErr(err) + if err != nil { + return err + } defaults := settings.UserDefaults{ Scope: user.Scope, @@ -51,7 +61,10 @@ options you want to change.`, Sorting: user.Sorting, Commands: user.Commands, } - getUserDefaults(flags, &defaults, false) + err = getUserDefaults(flags, &defaults, false) + if err != nil { + return err + } user.Scope = defaults.Scope user.Locale = defaults.Locale user.ViewMode = defaults.ViewMode @@ -59,7 +72,10 @@ options you want to change.`, user.Perm = defaults.Perm user.Commands = defaults.Commands user.Sorting = defaults.Sorting - user.LockPassword = mustGetBool(flags, "lockPassword") + user.LockPassword, err = mustGetBool(flags, "lockPassword") + if err != nil { + return err + } if newUsername != "" { user.Username = newUsername @@ -67,11 +83,15 @@ options you want to change.`, if password != "" { user.Password, err = users.ValidateAndHashPwd(password, s.MinimumPasswordLength) - checkErr(err) + if err != nil { + return err + } } err = d.store.Users.Update(user) - checkErr(err) + if err != nil { + return err + } printUsers([]*users.User{user}) return nil }, pythonConfig{}), diff --git a/cmd/utils.go b/cmd/utils.go index e1e3c32c..2aa48a9b 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -26,22 +26,26 @@ func checkErr(err error) { } } -func mustGetString(flags *pflag.FlagSet, flag string) string { +func returnErr(err error) error { + if err != nil { + return err + } + return nil +} + +func mustGetString(flags *pflag.FlagSet, flag string) (string, error) { s, err := flags.GetString(flag) - checkErr(err) - return s + return s, returnErr(err) } -func mustGetBool(flags *pflag.FlagSet, flag string) bool { +func mustGetBool(flags *pflag.FlagSet, flag string) (bool, error) { b, err := flags.GetBool(flag) - checkErr(err) - return b + return b, returnErr(err) } -func mustGetUint(flags *pflag.FlagSet, flag string) uint { +func mustGetUint(flags *pflag.FlagSet, flag string) (uint, error) { b, err := flags.GetUint(flag) - checkErr(err) - return b + return b, returnErr(err) } func generateKey() []byte { @@ -108,17 +112,23 @@ func python(fn pythonFunc, cfg pythonConfig) cobraFunc { log.Println("Using database: " + absPath) data.hadDB = exists db, err := storm.Open(path, storm.BoltOptions(files.PermFile, nil)) - checkErr(err) + if err != nil { + return err + } defer db.Close() data.store, err = bolt.NewStorage(db) - checkErr(err) + if err != nil { + return err + } return fn(cmd, args, data) } } func marshal(filename string, data interface{}) error { fd, err := os.Create(filename) - checkErr(err) + if err != nil { + return err + } defer fd.Close() switch ext := filepath.Ext(filename); ext { @@ -136,7 +146,9 @@ func marshal(filename string, data interface{}) error { func unmarshal(filename string, data interface{}) error { fd, err := os.Open(filename) - checkErr(err) + if err != nil { + return err + } defer fd.Close() switch ext := filepath.Ext(filename); ext {