diff --git a/cmd/cmd.go b/cmd/cmd.go new file mode 100644 index 00000000..10863f40 --- /dev/null +++ b/cmd/cmd.go @@ -0,0 +1,14 @@ +package cmd + +import ( + "fmt" + "os" +) + +// Execute executes the commands. +func Execute() { + if err := rootCmd.Execute(); err != nil { + fmt.Println(err) + os.Exit(1) + } +} diff --git a/cmd/cmds_add.go b/cmd/cmds_add.go index 9df9b47b..3957180f 100644 --- a/cmd/cmds_add.go +++ b/cmd/cmds_add.go @@ -1,7 +1,6 @@ package cmd import ( - "github.com/filebrowser/filebrowser/bolt" "github.com/spf13/cobra" ) @@ -21,15 +20,15 @@ var cmdsAddCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { db := getDB() defer db.Close() - st := bolt.ConfigStore{DB: db} - r, err := st.GetRunner() + st := getStore(db) + r, err := st.Config.GetRunner() checkErr(err) evt := mustGetString(cmd, "event") command := mustGetString(cmd, "command") r.Commands[evt] = append(r.Commands[evt], command) - err = st.SaveRunner(r) + err = st.Config.SaveRunner(r) checkErr(err) printEvents(r.Commands) }, diff --git a/cmd/cmds_ls.go b/cmd/cmds_ls.go index 41a698f6..30f07580 100644 --- a/cmd/cmds_ls.go +++ b/cmd/cmds_ls.go @@ -1,7 +1,6 @@ package cmd import ( - "github.com/filebrowser/filebrowser/bolt" "github.com/spf13/cobra" ) @@ -18,8 +17,8 @@ var cmdsLsCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { db := getDB() defer db.Close() - st := bolt.ConfigStore{DB: db} - r, err := st.GetRunner() + st := getStore(db) + r, err := st.Config.GetRunner() checkErr(err) evt := mustGetString(cmd, "event") diff --git a/cmd/cmds_rm.go b/cmd/cmds_rm.go index 155b1178..c4226591 100644 --- a/cmd/cmds_rm.go +++ b/cmd/cmds_rm.go @@ -1,7 +1,6 @@ package cmd import ( - "github.com/filebrowser/filebrowser/bolt" "github.com/spf13/cobra" ) @@ -21,8 +20,8 @@ var cmdsRmCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { db := getDB() defer db.Close() - st := bolt.ConfigStore{DB: db} - r, err := st.GetRunner() + st := getStore(db) + r, err := st.Config.GetRunner() checkErr(err) evt := mustGetString(cmd, "event") @@ -30,7 +29,7 @@ var cmdsRmCmd = &cobra.Command{ checkErr(err) r.Commands[evt] = append(r.Commands[evt][:i], r.Commands[evt][i+1:]...) - err = st.SaveRunner(r) + err = st.Config.SaveRunner(r) checkErr(err) printEvents(r.Commands) }, diff --git a/cmd/config_cat.go b/cmd/config_cat.go index e2d1a853..4c8dba3e 100644 --- a/cmd/config_cat.go +++ b/cmd/config_cat.go @@ -1,7 +1,6 @@ package cmd import ( - "github.com/filebrowser/filebrowser/bolt" "github.com/spf13/cobra" ) @@ -17,10 +16,10 @@ var configCatCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { db := getDB() defer db.Close() - st := bolt.ConfigStore{DB: db} - s, err := st.GetSettings() + st := getStore(db) + s, err := st.Config.GetSettings() checkErr(err) - auther, err := st.GetAuther(s.AuthMethod) + auther, err := st.Config.GetAuther(s.AuthMethod) checkErr(err) printSettings(s, auther) }, diff --git a/cmd/config_init.go b/cmd/config_init.go index 120128fc..4d8751f5 100644 --- a/cmd/config_init.go +++ b/cmd/config_init.go @@ -5,6 +5,7 @@ import ( "fmt" "os" + "github.com/asdine/storm" "github.com/filebrowser/filebrowser/bolt" "github.com/filebrowser/filebrowser/types" "github.com/spf13/cobra" @@ -26,50 +27,49 @@ 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, - Run: initDatabase, -} + Run: func(cmd *cobra.Command, args []string) { + if _, err := os.Stat(databasePath); err == nil { + panic(errors.New(databasePath + " already exists")) + } -func initDatabase(cmd *cobra.Command, args []string) { - if _, err := os.Stat(databasePath); err == nil { - panic(errors.New(databasePath + " already exists")) - } + defaults := types.UserDefaults{} + getUserDefaults(cmd, &defaults, true) + authMethod, auther := getAuthentication(cmd) - defaults := types.UserDefaults{} - getUserDefaults(cmd, &defaults, true) - authMethod, auther := getAuthentication(cmd) + settings := &types.Settings{ + Key: generateRandomBytes(64), // 256 bits + BaseURL: mustGetString(cmd, "baseURL"), + Signup: mustGetBool(cmd, "signup"), + Defaults: defaults, + AuthMethod: authMethod, + Branding: types.Branding{ + Name: mustGetString(cmd, "branding.name"), + DisableExternal: mustGetBool(cmd, "branding.disableExternal"), + Files: mustGetString(cmd, "branding.files"), + }, + } - settings := &types.Settings{ - Key: generateRandomBytes(64), // 256 bits - BaseURL: mustGetString(cmd, "baseURL"), - Signup: mustGetBool(cmd, "signup"), - Defaults: defaults, - AuthMethod: authMethod, - } + db, err := bolt.Open(databasePath) + checkErr(err) + defer db.Close() - runner := &types.Runner{ - Commands: map[string][]string{}, - } + saveConfig(db, settings, &types.Runner{}, auther) - for _, event := range types.DefaultEvents { - runner.Commands[event] = []string{} - } - - db, err := bolt.Open(databasePath) - checkErr(err) - defer db.Close() - - st := bolt.ConfigStore{DB: db} - err = st.SaveSettings(settings) - checkErr(err) - err = st.SaveRunner(runner) - checkErr(err) - err = st.SaveAuther(auther) - checkErr(err) - - fmt.Printf(` + fmt.Printf(` 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(settings, auther) + printSettings(settings, auther) + }, +} + +func saveConfig(db *storm.DB, s *types.Settings, r *types.Runner, a types.Auther) { + st := getStore(db) + err := st.Config.SaveSettings(s) + checkErr(err) + err = st.Config.SaveRunner(r) + checkErr(err) + err = st.Config.SaveAuther(a) + checkErr(err) } diff --git a/cmd/config_set.go b/cmd/config_set.go index 099fd56b..d74af6be 100644 --- a/cmd/config_set.go +++ b/cmd/config_set.go @@ -1,7 +1,6 @@ package cmd import ( - "github.com/filebrowser/filebrowser/bolt" "github.com/filebrowser/filebrowser/types" "github.com/spf13/cobra" "github.com/spf13/pflag" @@ -22,8 +21,8 @@ you want to change.`, db := getDB() defer db.Close() - st := bolt.ConfigStore{DB: db} - s, err := st.GetSettings() + st := getStore(db) + s, err := st.Config.GetSettings() checkErr(err) auth := false @@ -49,14 +48,14 @@ you want to change.`, var auther types.Auther if auth { s.AuthMethod, auther = getAuthentication(cmd) - err = st.SaveAuther(auther) + err = st.Config.SaveAuther(auther) checkErr(err) } else { - auther, err = st.GetAuther(s.AuthMethod) + auther, err = st.Config.GetAuther(s.AuthMethod) checkErr(err) } - err = st.SaveSettings(s) + err = st.Config.SaveSettings(s) checkErr(err) printSettings(s, auther) }, diff --git a/cmd/root.go b/cmd/root.go index 3ba9036f..cdbfd53b 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -2,7 +2,7 @@ package cmd import ( "crypto/tls" - "fmt" + "errors" "io/ioutil" "log" "net" @@ -10,9 +10,11 @@ import ( "os" "strconv" + "github.com/filebrowser/filebrowser/auth" "github.com/filebrowser/filebrowser/bolt" - fhttp "github.com/filebrowser/filebrowser/http" "github.com/filebrowser/filebrowser/types" + + fhttp "github.com/filebrowser/filebrowser/http" "github.com/spf13/cobra" lumberjack "gopkg.in/natefinch/lumberjack.v2" ) @@ -29,7 +31,7 @@ func init() { rootCmd.Flags().IntP("port", "p", 0, "port to listen on") rootCmd.Flags().StringP("cert", "c", "", "tls certificate") rootCmd.Flags().StringP("key", "k", "", "tls key") - rootCmd.AddCommand(versionCmd) + rootCmd.Flags().StringP("scope", "s", "", "scope for users") } var rootCmd = &cobra.Command{ @@ -45,34 +47,18 @@ See 'filebrowser help config init' for more information. This command is used to start up the server. By default it starts listening on loalhost on a random port. Use the flags to change it.`, Run: func(cmd *cobra.Command, args []string) { - switch l := mustGetString(cmd, "log"); l { - case "stdout": - log.SetOutput(os.Stdout) - case "stderr": - log.SetOutput(os.Stderr) - case "": - log.SetOutput(ioutil.Discard) - default: - log.SetOutput(&lumberjack.Logger{ - Filename: l, - MaxSize: 100, - MaxAge: 14, - MaxBackups: 10, - }) + setupLogger(cmd) + + if _, err := os.Stat(databasePath); os.IsNotExist(err) { + quickSetup(cmd) } var err error db := getDB() defer db.Close() - usersStore := &types.UsersVerify{Store: bolt.UsersStore{DB: db}} - env := &fhttp.Env{ - Store: &types.Store{ - Users: usersStore, - Config: bolt.ConfigStore{DB: db, Users: usersStore}, - Share: bolt.ShareStore{DB: db}, - }, + Store: getStore(db), } env.Settings, err = env.Store.Config.GetSettings() @@ -82,45 +68,101 @@ listening on loalhost on a random port. Use the flags to change it.`, env.Runner, err = env.Store.Config.GetRunner() checkErr(err) - addr := mustGetString(cmd, "address") - port, err := cmd.Flags().GetInt("port") - checkErr(err) - - cert := mustGetString(cmd, "cert") - key := mustGetString(cmd, "key") - - var listener net.Listener - - if cert != "" && key != "" { - cer, err := tls.LoadX509KeyPair(cert, key) - checkErr(err) - config := &tls.Config{Certificates: []tls.Certificate{cer}} - listener, err = tls.Listen("tcp", addr+":"+strconv.Itoa(port), config) - checkErr(err) - } else { - listener, err = net.Listen("tcp", addr+":"+strconv.Itoa(port)) - checkErr(err) - } - - log.Println("Listening on", listener.Addr().String()) - if err := http.Serve(listener, fhttp.Handler(env)); err != nil { - log.Fatal(err) - } + startServer(cmd, env) }, } -var versionCmd = &cobra.Command{ - Use: "version", - Short: "Print the version number", - Run: func(cmd *cobra.Command, args []string) { - fmt.Println("File Browser Version " + types.Version) - }, -} - -// Execute executes the commands. -func Execute() { - if err := rootCmd.Execute(); err != nil { - fmt.Println(err) - os.Exit(1) +func setupLogger(cmd *cobra.Command) { + switch l := mustGetString(cmd, "log"); l { + case "stdout": + log.SetOutput(os.Stdout) + case "stderr": + log.SetOutput(os.Stderr) + case "": + log.SetOutput(ioutil.Discard) + default: + log.SetOutput(&lumberjack.Logger{ + Filename: l, + MaxSize: 100, + MaxAge: 14, + MaxBackups: 10, + }) + } +} + +func quickSetup(cmd *cobra.Command) { + scope := mustGetString(cmd, "scope") + if scope == "" { + panic(errors.New("scope flag must be set for quick setup")) + } + + settings := &types.Settings{ + Key: generateRandomBytes(64), + BaseURL: "", + Signup: false, + AuthMethod: auth.MethodJSONAuth, + Defaults: types.UserDefaults{ + Scope: scope, + Locale: "en", + Perm: types.Permissions{ + Admin: false, + Execute: true, + Create: true, + Rename: true, + Modify: true, + Delete: true, + Share: true, + Download: true, + }, + }, + } + + password, err := types.HashPwd("admin") + checkErr(err) + + user := &types.User{ + Username: "admin", + Password: password, + LockPassword: false, + } + + user.ApplyDefaults(settings.Defaults) + user.Perm.Admin = true + + db, err := bolt.Open(databasePath) + checkErr(err) + defer db.Close() + + saveConfig(db, settings, &types.Runner{}, &auth.JSONAuth{}) + + st := getStore(db) + err = st.Users.Save(user) + checkErr(err) +} + +func startServer(cmd *cobra.Command, env *fhttp.Env) { + addr := mustGetString(cmd, "address") + port, err := cmd.Flags().GetInt("port") + checkErr(err) + + cert := mustGetString(cmd, "cert") + key := mustGetString(cmd, "key") + + var listener net.Listener + + if cert != "" && key != "" { + cer, err := tls.LoadX509KeyPair(cert, key) + checkErr(err) + config := &tls.Config{Certificates: []tls.Certificate{cer}} + listener, err = tls.Listen("tcp", addr+":"+strconv.Itoa(port), config) + checkErr(err) + } else { + listener, err = net.Listen("tcp", addr+":"+strconv.Itoa(port)) + checkErr(err) + } + + log.Println("Listening on", listener.Addr().String()) + if err := http.Serve(listener, fhttp.Handler(env)); err != nil { + log.Fatal(err) } } diff --git a/cmd/users_find.go b/cmd/users_find.go index 43a65a25..599da296 100644 --- a/cmd/users_find.go +++ b/cmd/users_find.go @@ -1,7 +1,6 @@ package cmd import ( - storage "github.com/filebrowser/filebrowser/bolt" "github.com/filebrowser/filebrowser/types" "github.com/spf13/cobra" ) @@ -31,7 +30,7 @@ var usersLsCmd = &cobra.Command{ var findUsers = func(cmd *cobra.Command, args []string) { db := getDB() defer db.Close() - st := storage.UsersStore{DB: db} + st := getStore(db) username, _ := cmd.Flags().GetString("username") id, _ := cmd.Flags().GetUint("id") @@ -41,11 +40,11 @@ var findUsers = func(cmd *cobra.Command, args []string) { var user *types.User if username != "" { - user, err = st.GetByUsername(username) + user, err = st.Users.GetByUsername(username) } else if id != 0 { - user, err = st.Get(id) + user, err = st.Users.Get(id) } else { - users, err = st.Gets() + users, err = st.Users.Gets() } checkErr(err) diff --git a/cmd/users_new.go b/cmd/users_new.go index f27b1346..1d9f946d 100644 --- a/cmd/users_new.go +++ b/cmd/users_new.go @@ -1,7 +1,6 @@ package cmd import ( - storage "github.com/filebrowser/filebrowser/bolt" "github.com/filebrowser/filebrowser/types" "github.com/spf13/cobra" ) @@ -24,10 +23,9 @@ var usersNewCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { db := getDB() defer db.Close() - ust := storage.UsersStore{DB: db} - cst := storage.ConfigStore{DB: db} + st := getStore(db) - settings, err := cst.GetSettings() + settings, err := st.Config.GetSettings() checkErr(err) getUserDefaults(cmd, &settings.Defaults, false) @@ -39,14 +37,11 @@ var usersNewCmd = &cobra.Command{ Username: mustGetString(cmd, "username"), Password: password, LockPassword: mustGetBool(cmd, "lockPassword"), - Scope: settings.Defaults.Scope, - Locale: settings.Defaults.Locale, - ViewMode: settings.Defaults.ViewMode, - Perm: settings.Defaults.Perm, - Sorting: settings.Defaults.Sorting, } - err = ust.Save(user) + user.ApplyDefaults(settings.Defaults) + + err = st.Users.Save(user) checkErr(err) printUsers([]*types.User{user}) }, diff --git a/cmd/users_rm.go b/cmd/users_rm.go index dd81c051..17296b39 100644 --- a/cmd/users_rm.go +++ b/cmd/users_rm.go @@ -3,7 +3,6 @@ package cmd import ( "fmt" - storage "github.com/filebrowser/filebrowser/bolt" "github.com/spf13/cobra" ) @@ -21,7 +20,7 @@ var usersRmCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { db := getDB() defer db.Close() - st := storage.UsersStore{DB: db} + st := getStore(db) username, _ := cmd.Flags().GetString("username") id, _ := cmd.Flags().GetUint("id") @@ -29,9 +28,9 @@ var usersRmCmd = &cobra.Command{ var err error if username != "" { - err = st.DeleteByUsername(username) + err = st.Users.DeleteByUsername(username) } else { - err = st.Delete(id) + err = st.Users.Delete(id) } checkErr(err) diff --git a/cmd/users_update.go b/cmd/users_update.go index 448dbb74..f9576fbb 100644 --- a/cmd/users_update.go +++ b/cmd/users_update.go @@ -1,7 +1,6 @@ package cmd import ( - storage "github.com/filebrowser/filebrowser/bolt" "github.com/filebrowser/filebrowser/types" "github.com/spf13/cobra" ) @@ -24,7 +23,7 @@ options you want to change.`, Run: func(cmd *cobra.Command, args []string) { db := getDB() defer db.Close() - st := storage.UsersStore{DB: db} + st := getStore(db) id, _ := cmd.Flags().GetUint("id") username := mustGetString(cmd, "username") @@ -34,9 +33,9 @@ options you want to change.`, var err error if id != 0 { - user, err = st.Get(id) + user, err = st.Users.Get(id) } else { - user, err = st.GetByUsername(username) + user, err = st.Users.GetByUsername(username) } checkErr(err) @@ -67,7 +66,7 @@ options you want to change.`, checkErr(err) } - err = st.Update(user) + err = st.Users.Update(user) checkErr(err) printUsers([]*types.User{user}) }, diff --git a/cmd/utils.go b/cmd/utils.go index 72533a07..f1da22ac 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -7,6 +7,7 @@ import ( "github.com/asdine/storm" "github.com/filebrowser/filebrowser/bolt" + "github.com/filebrowser/filebrowser/types" "github.com/spf13/cobra" ) @@ -38,6 +39,27 @@ func getDB() *storm.DB { return db } +func getStore(db *storm.DB) *types.Store { + usersStore := &types.UsersVerify{ + Store: bolt.UsersStore{ + DB: db, + }, + } + + configSore := &types.ConfigVerify{ + Store: bolt.ConfigStore{ + DB: db, + Users: usersStore, + }, + } + + return &types.Store{ + Users: usersStore, + Config: configSore, + Share: bolt.ShareStore{DB: db}, + } +} + func generateRandomBytes(n int) []byte { b := make([]byte, n) _, err := rand.Read(b) diff --git a/cmd/version.go b/cmd/version.go new file mode 100644 index 00000000..98f8fa1e --- /dev/null +++ b/cmd/version.go @@ -0,0 +1,20 @@ +package cmd + +import ( + "fmt" + + "github.com/filebrowser/filebrowser/types" + "github.com/spf13/cobra" +) + +func init() { + rootCmd.AddCommand(versionCmd) +} + +var versionCmd = &cobra.Command{ + Use: "version", + Short: "Print the version number", + Run: func(cmd *cobra.Command, args []string) { + fmt.Println("File Browser Version " + types.Version) + }, +} diff --git a/http/auth.go b/http/auth.go index 9bbe8463..fd51e1d1 100644 --- a/http/auth.go +++ b/http/auth.go @@ -53,13 +53,10 @@ func (e *Env) signupHandler(w http.ResponseWriter, r *http.Request) { user := &types.User{ Username: info.Username, - Locale: e.Settings.Defaults.Locale, - Perm: e.Settings.Defaults.Perm, - ViewMode: e.Settings.Defaults.ViewMode, - Commands: e.Settings.Defaults.Commands, - Scope: e.Settings.Defaults.Scope, } + user.ApplyDefaults(e.Settings.Defaults) + pwd, err := types.HashPwd(info.Password) if err != nil { httpErr(w, r, http.StatusInternalServerError, err) diff --git a/http/static.go b/http/static.go index 2693baf0..2e98ec7c 100644 --- a/http/static.go +++ b/http/static.go @@ -15,14 +15,12 @@ import ( ) func (e *Env) getStaticData() map[string]interface{} { - baseURL := strings.TrimSuffix(e.Settings.BaseURL, "/") - staticURL := strings.TrimPrefix(baseURL+"/static", "/") + staticURL := strings.TrimPrefix(e.Settings.BaseURL+"/static", "/") - // TODO: baseurl must always not have the trailing slash data := map[string]interface{}{ "Name": e.Settings.Branding.Name, "DisableExternal": e.Settings.Branding.DisableExternal, - "BaseURL": baseURL, + "BaseURL": e.Settings.BaseURL, "Version": types.Version, "StaticURL": staticURL, "Signup": e.Settings.Signup, diff --git a/types/errors.go b/types/errors.go index 7f30e733..030cb061 100644 --- a/types/errors.go +++ b/types/errors.go @@ -17,4 +17,5 @@ var ( ErrPathIsRel = errors.New("path is relative") ErrNoPermission = errors.New("permission denied") ErrInvalidAuthMethod = errors.New("invalid auth method") + ErrEmptyKey = errors.New("empty key") ) diff --git a/types/runner.go b/types/runner.go index d3d0417e..afdef5c9 100644 --- a/types/runner.go +++ b/types/runner.go @@ -10,19 +10,12 @@ import ( "github.com/mholt/caddy" ) -// DefaultEvents are the default events that can trigger commands. -// See Settings.Commands. -var DefaultEvents = []string{ - "before_save", - "after_save", - "before_copy", - "after_copy", - "before_rename", - "after_rename", - "before_upload", - "after_upload", - "before_delete", - "after_delete", +var defaultEvents = []string{ + "save", + "copy", + "rename", + "upload", + "delete", } // Runner runs certain commands. diff --git a/types/storage.go b/types/storage.go index dd596869..411918f7 100644 --- a/types/storage.go +++ b/types/storage.go @@ -3,22 +3,10 @@ package types // Store is used to persist data. type Store struct { Users *UsersVerify - Config ConfigStore + Config *ConfigVerify Share ShareStore } -// ConfigStore is used to manage configurations relativey to a data storage. -type ConfigStore interface { - Get(name string, to interface{}) error - Save(name string, from interface{}) error - GetSettings() (*Settings, error) - SaveSettings(*Settings) error - SaveRunner(*Runner) error - GetRunner() (*Runner, error) - GetAuther(AuthMethod) (Auther, error) - SaveAuther(Auther) error -} - // ShareStore is the interface to manage share links. type ShareStore interface { Get(hash string) (*ShareLink, error) diff --git a/types/storage_config.go b/types/storage_config.go new file mode 100644 index 00000000..a33e4f95 --- /dev/null +++ b/types/storage_config.go @@ -0,0 +1,84 @@ +package types + +import "strings" + +// ConfigStore is used to manage configurations relativey to a data storage. +type ConfigStore interface { + GetSettings() (*Settings, error) + SaveSettings(*Settings) error + SaveRunner(*Runner) error + GetRunner() (*Runner, error) + GetAuther(AuthMethod) (Auther, error) + SaveAuther(Auther) error +} + +// ConfigVerify wraps a ConfigStore and makes the verifications needed. +type ConfigVerify struct { + Store ConfigStore +} + +// GetSettings wraps a ConfigStore.GetSettings +func (v ConfigVerify) GetSettings() (*Settings, error) { + return v.Store.GetSettings() +} + +// SaveSettings wraps a ConfigStore.SaveSettings +func (v ConfigVerify) SaveSettings(s *Settings) error { + s.BaseURL = strings.TrimSuffix(s.BaseURL, "/") + + if len(s.Key) == 0 { + return ErrEmptyKey + } + + if s.Defaults.Locale == "" { + s.Defaults.Locale = "en" + } + + if s.Defaults.Commands == nil { + s.Defaults.Commands = []string{} + } + + if s.Defaults.ViewMode == "" { + s.Defaults.ViewMode = MosaicViewMode + } + + if s.Rules == nil { + s.Rules = []Rule{} + } + + return v.Store.SaveSettings(s) +} + +// GetRunner wraps a ConfigStore.GetRunner +func (v ConfigVerify) GetRunner() (*Runner, error) { + return v.Store.GetRunner() +} + +// SaveRunner wraps a ConfigStore.SaveRunner +func (v ConfigVerify) SaveRunner(r *Runner) error { + if r.Commands == nil { + r.Commands = map[string][]string{} + } + + for _, event := range defaultEvents { + if _, ok := r.Commands["before_"+event]; !ok { + r.Commands["before_"+event] = []string{} + } + + if _, ok := r.Commands["after_"+event]; !ok { + r.Commands["after_"+event] = []string{} + } + } + + return v.Store.SaveRunner(r) +} + +// GetAuther wraps a ConfigStore.GetAuther +func (v ConfigVerify) GetAuther(t AuthMethod) (Auther, error) { + return v.Store.GetAuther(t) +} + +// SaveAuther wraps a ConfigStore.SaveAuther +func (v ConfigVerify) SaveAuther(a Auther) error { + return v.Store.SaveAuther(a) +} diff --git a/types/user.go b/types/user.go index f54030d5..14e6f25d 100644 --- a/types/user.go +++ b/types/user.go @@ -99,10 +99,20 @@ func (u *User) clean(fields ...string) error { } // IsAllowed checks if an user is allowed to go to a certain path. -func (u User) IsAllowed(url string) bool { +func (u *User) IsAllowed(url string) bool { return isAllowed(url, u.Rules) } +// ApplyDefaults applies defaults to a user. +func (u *User) ApplyDefaults(defaults UserDefaults) { + u.Scope = defaults.Scope + u.Locale = defaults.Locale + u.ViewMode = defaults.ViewMode + u.Perm = defaults.Perm + u.Sorting = defaults.Sorting + u.Commands = defaults.Commands +} + // HashPwd hashes a password. func HashPwd(password string) (string, error) { bytes, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)