diff --git a/auth/json.go b/auth/json.go index 8f5f193e..8ad9fa47 100644 --- a/auth/json.go +++ b/auth/json.go @@ -22,7 +22,7 @@ type jsonCred struct { // JSONAuth is a json implementaion of an Auther. type JSONAuth struct { - ReCaptcha *ReCaptcha + ReCaptcha *ReCaptcha `json:"recaptcha" yaml:"recaptcha"` } // Auth authenticates the user via a json in content body. diff --git a/auth/proxy.go b/auth/proxy.go index 09a16c02..176b69c5 100644 --- a/auth/proxy.go +++ b/auth/proxy.go @@ -14,7 +14,7 @@ const MethodProxyAuth settings.AuthMethod = "proxy" // ProxyAuth is a proxy implementation of an auther. type ProxyAuth struct { - Header string + Header string `json:"header"` } // Auth authenticates the user via an HTTP header. diff --git a/cmd/config_export.go b/cmd/config_export.go index 6471b9e0..f85d89b6 100644 --- a/cmd/config_export.go +++ b/cmd/config_export.go @@ -1,9 +1,6 @@ package cmd import ( - "encoding/json" - "os" - "github.com/spf13/cobra" ) @@ -14,7 +11,7 @@ func init() { var configExportCmd = &cobra.Command{ Use: "export ", Short: "Export the configuration to a file.", - Args: cobra.ExactArgs(1), + Args: jsonYamlArg, Run: python(func(cmd *cobra.Command, args []string, d pythonData) { settings, err := d.store.Settings.Get() checkErr(err) @@ -22,15 +19,12 @@ var configExportCmd = &cobra.Command{ auther, err := d.store.Auth.Get(settings.AuthMethod) checkErr(err) - fd, err := os.Create(args[0]) - checkErr(err) - defer fd.Close() - - encoder := json.NewEncoder(fd) - encoder.SetIndent("", " ") - encoder.Encode(&settingsFile{ + data := &settingsFile{ Settings: settings, Auther: auther, - }) + } + + err = marshal(args[0], data) + checkErr(err) }, pythonConfig{}), } diff --git a/cmd/config_import.go b/cmd/config_import.go index 51217f75..c8b8ec0f 100644 --- a/cmd/config_import.go +++ b/cmd/config_import.go @@ -3,7 +3,6 @@ package cmd import ( "encoding/json" "errors" - "os" "reflect" "github.com/filebrowser/filebrowser/v2/auth" @@ -27,7 +26,7 @@ configuration. Can be used with or without unexisting databases. If used with a nonexisting database, a key will be generated automatically. Otherwise the key will be kept the same as in the database.`, - Args: cobra.ExactArgs(1), + Args: jsonYamlArg, Run: python(func(cmd *cobra.Command, args []string, d pythonData) { var key []byte if d.hadDB { @@ -38,27 +37,24 @@ database.`, key = generateRandomBytes(64) } - fd, err := os.Open(args[0]) - checkErr(err) - defer fd.Close() - file := settingsFile{} - err = json.NewDecoder(fd).Decode(&file) + err := unmarshal(args[0], &file) checkErr(err) file.Settings.Key = key - err = d.store.Settings.Save(file.Settings) checkErr(err) + autherInterf := cleanUpInterfaceMap(file.Auther.(map[interface{}]interface{})) + var auther auth.Auther switch file.Settings.AuthMethod { case auth.MethodJSONAuth: - auther = getAuther(auth.JSONAuth{}, file.Auther).(*auth.JSONAuth) + auther = getAuther(auth.JSONAuth{}, autherInterf).(*auth.JSONAuth) case auth.MethodNoAuth: - auther = getAuther(auth.NoAuth{}, file.Auther).(*auth.NoAuth) + auther = getAuther(auth.NoAuth{}, autherInterf).(*auth.NoAuth) case auth.MethodProxyAuth: - auther = getAuther(auth.ProxyAuth{}, file.Auther).(*auth.ProxyAuth) + auther = getAuther(auth.ProxyAuth{}, autherInterf).(*auth.ProxyAuth) default: checkErr(errors.New("invalid auth method")) } diff --git a/cmd/users_export.go b/cmd/users_export.go index 764ec44b..711cd420 100644 --- a/cmd/users_export.go +++ b/cmd/users_export.go @@ -1,9 +1,6 @@ package cmd import ( - "encoding/json" - "os" - "github.com/spf13/cobra" ) @@ -14,17 +11,12 @@ func init() { var usersExportCmd = &cobra.Command{ Use: "export ", Short: "Export all users.", - Args: cobra.ExactArgs(1), + Args: jsonYamlArg, Run: python(func(cmd *cobra.Command, args []string, d pythonData) { list, err := d.store.Users.Gets("") checkErr(err) - fd, err := os.Create(args[0]) + err = marshal(args[0], list) checkErr(err) - defer fd.Close() - - encoder := json.NewEncoder(fd) - encoder.SetIndent("", " ") - encoder.Encode(list) }, pythonConfig{}), } diff --git a/cmd/users_import.go b/cmd/users_import.go index 1cdf1203..a9af4d0f 100644 --- a/cmd/users_import.go +++ b/cmd/users_import.go @@ -1,7 +1,6 @@ package cmd import ( - "encoding/json" "errors" "os" "strconv" @@ -18,14 +17,14 @@ func init() { var usersImportCmd = &cobra.Command{ Use: "import ", Short: "Import users from a file.", - Args: cobra.ExactArgs(1), + Args: jsonYamlArg, Run: python(func(cmd *cobra.Command, args []string, d pythonData) { fd, err := os.Open(args[0]) checkErr(err) defer fd.Close() list := []*users.User{} - err = json.NewDecoder(fd).Decode(&list) + err = unmarshal(args[0], &list) checkErr(err) for _, user := range list { diff --git a/cmd/utils.go b/cmd/utils.go index b1c4c25e..d1e24dc2 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -2,9 +2,12 @@ package cmd import ( "crypto/rand" + "encoding/json" + "errors" "fmt" "log" "os" + "path/filepath" "github.com/asdine/storm" "github.com/filebrowser/filebrowser/v2/storage" @@ -12,6 +15,7 @@ import ( "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) { @@ -110,3 +114,76 @@ func python(fn pythonFunc, cfg pythonConfig) cobraFunc { fn(cmd, args, data) } } + +func marshal(filename string, data interface{}) error { + fd, err := os.Create(filename) + checkErr(err) + defer fd.Close() + + switch ext := filepath.Ext(filename); ext { + case ".json": + encoder := json.NewEncoder(fd) + encoder.SetIndent("", " ") + return encoder.Encode(data) + case ".yml", ".yaml": + encoder := yaml.NewEncoder(fd) + return encoder.Encode(data) + default: + return errors.New("invalid format: " + ext) + } +} + +func unmarshal(filename string, data interface{}) error { + fd, err := os.Open(filename) + checkErr(err) + defer fd.Close() + + switch ext := filepath.Ext(filename); ext { + case ".json": + return json.NewDecoder(fd).Decode(data) + case ".yml", ".yaml": + return yaml.NewDecoder(fd).Decode(data) + default: + return errors.New("invalid format: " + ext) + } +} + +func jsonYamlArg(cmd *cobra.Command, args []string) error { + if err := cobra.ExactArgs(1)(cmd, args); err != nil { + return err + } + + switch ext := filepath.Ext(args[0]); ext { + case ".json", ".yml", ".yaml": + return nil + default: + return errors.New("invalid format: " + ext) + } +} + +func cleanUpInterfaceMap(in map[interface{}]interface{}) map[string]interface{} { + result := make(map[string]interface{}) + for k, v := range in { + result[fmt.Sprintf("%v", k)] = cleanUpMapValue(v) + } + return result +} + +func cleanUpInterfaceArray(in []interface{}) []interface{} { + result := make([]interface{}, len(in)) + for i, v := range in { + result[i] = cleanUpMapValue(v) + } + return result +} + +func cleanUpMapValue(v interface{}) interface{} { + switch v := v.(type) { + case []interface{}: + return cleanUpInterfaceArray(v) + case map[interface{}]interface{}: + return cleanUpInterfaceMap(v) + default: + return v + } +} diff --git a/users/users.go b/users/users.go index 387a4eaa..4fdbef6c 100644 --- a/users/users.go +++ b/users/users.go @@ -31,7 +31,7 @@ type User struct { Perm Permissions `json:"perm"` Commands []string `json:"commands"` Sorting files.Sorting `json:"sorting"` - Fs afero.Fs `json:"-"` + Fs afero.Fs `json:"-" yaml:"-"` Rules []rules.Rule `json:"rules"` }