diff --git a/cmd/cmds_add.go b/cmd/cmds_add.go index 19b44f67..eebbe00c 100644 --- a/cmd/cmds_add.go +++ b/cmd/cmds_add.go @@ -20,14 +20,15 @@ var cmdsAddCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { db := getDB() defer db.Close() - st := getFileBrowser(db) - s := st.GetSettings() + st := getStorage(db) + s, err := st.Settings.Get() + checkErr(err) evt := mustGetString(cmd, "event") command := mustGetString(cmd, "command") s.Commands[evt] = append(s.Commands[evt], command) - err := st.SaveSettings(s) + err = st.Settings.Save(s) checkErr(err) printEvents(s.Commands) }, diff --git a/cmd/cmds_ls.go b/cmd/cmds_ls.go index e46a1aa8..e8a03ae1 100644 --- a/cmd/cmds_ls.go +++ b/cmd/cmds_ls.go @@ -17,8 +17,9 @@ var cmdsLsCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { db := getDB() defer db.Close() - st := getFileBrowser(db) - s := st.GetSettings() + st := getStorage(db) + s, err := st.Settings.Get() + checkErr(err) evt := mustGetString(cmd, "event") if evt == "" { diff --git a/cmd/cmds_rm.go b/cmd/cmds_rm.go index efe1f6d4..2c19727f 100644 --- a/cmd/cmds_rm.go +++ b/cmd/cmds_rm.go @@ -20,15 +20,16 @@ var cmdsRmCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { db := getDB() defer db.Close() - st := getFileBrowser(db) - s := st.GetSettings() + st := getStorage(db) + s, err := st.Settings.Get() + checkErr(err) evt := mustGetString(cmd, "event") i, err := cmd.Flags().GetUint("index") checkErr(err) s.Commands[evt] = append(s.Commands[evt][:i], s.Commands[evt][i+1:]...) - err = st.SaveSettings(s) + err = st.Settings.Save(s) checkErr(err) printEvents(s.Commands) }, diff --git a/cmd/config.go b/cmd/config.go index bb40a026..d21c95d3 100644 --- a/cmd/config.go +++ b/cmd/config.go @@ -2,14 +2,15 @@ package cmd import ( "encoding/json" - "errors" + nerrors "errors" "fmt" "os" "strings" "text/tabwriter" "github.com/filebrowser/filebrowser/auth" - + "github.com/filebrowser/filebrowser/settings" + "github.com/filebrowser/filebrowser/errors" "github.com/spf13/cobra" ) @@ -46,14 +47,14 @@ func addConfigFlags(cmd *cobra.Command) { cmd.Flags().Bool("branding.disableExternal", false, "disable external links such as GitHub links") } -func getAuthentication(cmd *cobra.Command) (lib.AuthMethod, lib.Auther) { - method := lib.AuthMethod(mustGetString(cmd, "auth.method")) +func getAuthentication(cmd *cobra.Command) (settings.AuthMethod, auth.Auther) { + method := settings.AuthMethod(mustGetString(cmd, "auth.method")) - var auther lib.Auther + var auther auth.Auther if method == auth.MethodProxyAuth { header := mustGetString(cmd, "auth.header") if header == "" { - panic(errors.New("you must set the flag 'auth.header' for method 'proxy'")) + panic(nerrors.New("you must set the flag 'auth.header' for method 'proxy'")) } auther = &auth.ProxyAuth{Header: header} } @@ -81,13 +82,13 @@ func getAuthentication(cmd *cobra.Command) (lib.AuthMethod, lib.Auther) { } if auther == nil { - panic(lib.ErrInvalidAuthMethod) + panic(errors.ErrInvalidAuthMethod) } return method, auther } -func printSettings(s *lib.Settings, auther lib.Auther) { +func printSettings(s *settings.Settings, auther auth.Auther) { w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0) fmt.Fprintf(w, "\nBase URL:\t%s\n", s.BaseURL) diff --git a/cmd/config_cat.go b/cmd/config_cat.go index 1c59fc34..f58d4444 100644 --- a/cmd/config_cat.go +++ b/cmd/config_cat.go @@ -16,9 +16,10 @@ var configCatCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { db := getDB() defer db.Close() - st := getFileBrowser(db) - s := st.GetSettings() - auther, err := st.GetAuther(s.AuthMethod) + st := getStorage(db) + s, err := st.Settings.Get() + checkErr(err) + auther, err := st.Auth.Get(s.AuthMethod) checkErr(err) printSettings(s, auther) }, diff --git a/cmd/config_init.go b/cmd/config_init.go index df829914..9eb3a8b9 100644 --- a/cmd/config_init.go +++ b/cmd/config_init.go @@ -7,7 +7,7 @@ import ( "strings" "github.com/asdine/storm" - + "github.com/filebrowser/filebrowser/settings" "github.com/spf13/cobra" ) @@ -32,30 +32,31 @@ override the options.`, panic(errors.New(databasePath + " already exists")) } - defaults := lib.UserDefaults{} + defaults := settings.UserDefaults{} getUserDefaults(cmd, &defaults, true) authMethod, auther := getAuthentication(cmd) db, err := storm.Open(databasePath) checkErr(err) defer db.Close() - st := getFileBrowser(db) - settings := st.GetSettings() + st := getStorage(db) + s, err := st.Settings.Get() + checkErr(err) - settings.BaseURL = mustGetString(cmd, "baseURL") - settings.Signup = mustGetBool(cmd, "signup") - settings.Shell = strings.Split(strings.TrimSpace(mustGetString(cmd, "shell")), " ") - settings.Defaults = defaults - settings.AuthMethod = authMethod - settings.Branding = lib.Branding{ + s.BaseURL = mustGetString(cmd, "baseURL") + s.Signup = mustGetBool(cmd, "signup") + s.Shell = strings.Split(strings.TrimSpace(mustGetString(cmd, "shell")), " ") + s.Defaults = defaults + s.AuthMethod = authMethod + s.Branding = settings.Branding{ Name: mustGetString(cmd, "branding.name"), DisableExternal: mustGetBool(cmd, "branding.disableExternal"), Files: mustGetString(cmd, "branding.files"), } - err = st.SaveSettings(settings) + err = st.Settings.Save(s) checkErr(err) - err = st.SaveAuther(auther) + err = st.Auth.Save(auther) checkErr(err) fmt.Printf(` @@ -63,6 +64,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(settings, auther) + printSettings(s, auther) }, } diff --git a/cmd/config_set.go b/cmd/config_set.go index db622993..96c80578 100644 --- a/cmd/config_set.go +++ b/cmd/config_set.go @@ -3,7 +3,7 @@ package cmd import ( "strings" - + "github.com/filebrowser/filebrowser/auth" "github.com/spf13/cobra" "github.com/spf13/pflag" ) @@ -23,10 +23,11 @@ you want to change.`, db := getDB() defer db.Close() - st := getFileBrowser(db) - s := st.GetSettings() + st := getStorage(db) + s, err := st.Settings.Get() + checkErr(err) - auth := false + hasAuth := false cmd.Flags().Visit(func(flag *pflag.Flag) { switch flag.Name { case "baseURL": @@ -34,7 +35,7 @@ you want to change.`, case "signup": s.Signup = mustGetBool(cmd, "signup") case "auth.method": - auth = true + hasAuth = true case "shell": s.Shell = strings.Split(strings.TrimSpace(mustGetString(cmd, "shell")), " ") case "branding.name": @@ -48,18 +49,17 @@ you want to change.`, getUserDefaults(cmd, &s.Defaults, false) - var auther lib.Auther - var err error - if auth { + var auther auth.Auther + if hasAuth { s.AuthMethod, auther = getAuthentication(cmd) - err = st.SaveAuther(auther) + err = st.Auth.Save(auther) checkErr(err) } else { - auther, err = st.GetAuther(s.AuthMethod) + auther, err = st.Auth.Get(s.AuthMethod) checkErr(err) } - err = st.SaveSettings(s) + err = st.Settings.Save(s) checkErr(err) printSettings(s, auther) }, diff --git a/cmd/root.go b/cmd/root.go index 4338eefe..827929b7 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -1,6 +1,7 @@ package cmd import ( + "crypto/rand" "crypto/tls" "errors" "io/ioutil" @@ -12,7 +13,8 @@ import ( "github.com/asdine/storm" "github.com/filebrowser/filebrowser/auth" - + "github.com/filebrowser/filebrowser/settings" + "github.com/filebrowser/filebrowser/users" fbhttp "github.com/filebrowser/filebrowser/http" "github.com/spf13/cobra" @@ -56,9 +58,10 @@ listening on loalhost on a random port. Use the flags to change it.`, var err error db := getDB() defer db.Close() - fb := getFileBrowser(db) - handler, err := fbhttp.NewHandler(fb) + st := getStorage(db) + + handler, err := fbhttp.NewHandler(st) checkErr(err) startServer(cmd, handler) }, @@ -91,46 +94,48 @@ func quickSetup(cmd *cobra.Command) { db, err := storm.Open(databasePath) checkErr(err) defer db.Close() - fb := getFileBrowser(db) - settings := fb.GetSettings() - settings.BaseURL = "" - settings.Signup = false - settings.AuthMethod = auth.MethodJSONAuth - settings.Defaults = lib.UserDefaults{ - Scope: scope, - Locale: "en", - Perm: lib.Permissions{ - Admin: false, - Execute: true, - Create: true, - Rename: true, - Modify: true, - Delete: true, - Share: true, - Download: true, + set := &settings.Settings{ + BaseURL: "", + Signup: false, + AuthMethod: auth.MethodJSONAuth, + Defaults: settings.UserDefaults{ + Scope: scope, + Locale: "en", + Perm: users.Permissions{ + Admin: false, + Execute: true, + Create: true, + Rename: true, + Modify: true, + Delete: true, + Share: true, + Download: true, + }, }, } - err = fb.SaveSettings(settings) - checkErr(err) - - err = fb.SaveAuther(&auth.JSONAuth{}) - checkErr(err) - - password, err := lib.HashPwd("admin") + st := getStorage(db) + + err = st.Settings.Save(set) checkErr(err) - user := &lib.User{ + err = st.Auth.Save(&auth.JSONAuth{}) + checkErr(err) + + password, err := users.HashPwd("admin") + checkErr(err) + + user := &users.User{ Username: "admin", Password: password, LockPassword: false, } - fb.ApplyDefaults(user) + set.Defaults.Apply(user) user.Perm.Admin = true - err = fb.SaveUser(user) + err = st.Users.Save(user) checkErr(err) } @@ -160,3 +165,11 @@ func startServer(cmd *cobra.Command, handler http.Handler) { log.Fatal(err) } } + +func generateRandomBytes(n int) []byte { + b := make([]byte, n) + _, err := rand.Read(b) + checkErr(err) + // Note that err == nil only if we read len(b) bytes. + return b +} diff --git a/cmd/users.go b/cmd/users.go index 3a86d5e6..f4700301 100644 --- a/cmd/users.go +++ b/cmd/users.go @@ -6,7 +6,8 @@ import ( "os" "text/tabwriter" - + "github.com/filebrowser/filebrowser/settings" + "github.com/filebrowser/filebrowser/users" "github.com/spf13/cobra" "github.com/spf13/pflag" ) @@ -26,7 +27,7 @@ var usersCmd = &cobra.Command{ }, } -func printUsers(users []*lib.User) { +func printUsers(users []*users.User) { w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0) fmt.Fprintln(w, "ID\tUsername\tScope\tLocale\tV. Mode\tAdmin\tExecute\tCreate\tRename\tModify\tDelete\tShare\tDownload\tPwd Lock") @@ -78,18 +79,18 @@ func addUserFlags(cmd *cobra.Command) { cmd.Flags().StringSlice("commands", nil, "a list of the commands a user can execute") cmd.Flags().String("scope", "", "scope for users") cmd.Flags().String("locale", "en", "locale for users") - cmd.Flags().String("viewMode", string(lib.ListViewMode), "view mode for users") + cmd.Flags().String("viewMode", string(users.ListViewMode), "view mode for users") } -func getViewMode(cmd *cobra.Command) lib.ViewMode { - viewMode := lib.ViewMode(mustGetString(cmd, "viewMode")) - if viewMode != lib.ListViewMode && viewMode != lib.MosaicViewMode { - checkErr(errors.New("view mode must be \"" + string(lib.ListViewMode) + "\" or \"" + string(lib.MosaicViewMode) + "\"")) +func getViewMode(cmd *cobra.Command) users.ViewMode { + viewMode := users.ViewMode(mustGetString(cmd, "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 *lib.UserDefaults, all bool) { +func getUserDefaults(cmd *cobra.Command, defaults *settings.UserDefaults, all bool) { visit := func(flag *pflag.Flag) { switch flag.Name { case "scope": diff --git a/cmd/users_find.go b/cmd/users_find.go index 376d8e03..02713881 100644 --- a/cmd/users_find.go +++ b/cmd/users_find.go @@ -1,7 +1,7 @@ package cmd import ( - + "github.com/filebrowser/filebrowser/users" "github.com/spf13/cobra" ) @@ -30,28 +30,28 @@ var usersLsCmd = &cobra.Command{ var findUsers = func(cmd *cobra.Command, args []string) { db := getDB() defer db.Close() - st := getFileBrowser(db) + st := getStorage(db) username, _ := cmd.Flags().GetString("username") id, _ := cmd.Flags().GetUint("id") var err error - var users []*lib.User - var user *lib.User + var list []*users.User + var user *users.User if username != "" { - user, err = st.GetUser(username) + user, err = st.Users.Get(username) } else if id != 0 { - user, err = st.GetUser(id) + user, err = st.Users.Get(id) } else { - users, err = st.GetUsers() + list, err = st.Users.Gets() } checkErr(err) if user != nil { - users = []*lib.User{user} + list = []*users.User{user} } - printUsers(users) + printUsers(list) } diff --git a/cmd/users_new.go b/cmd/users_new.go index e6084bb7..467df194 100644 --- a/cmd/users_new.go +++ b/cmd/users_new.go @@ -1,7 +1,7 @@ package cmd import ( - + "github.com/filebrowser/filebrowser/users" "github.com/spf13/cobra" ) @@ -23,24 +23,25 @@ var usersNewCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { db := getDB() defer db.Close() - st := getFileBrowser(db) + st := getStorage(db) - settings := st.GetSettings() - getUserDefaults(cmd, &settings.Defaults, false) + s, err := st.Settings.Get() + checkErr(err) + getUserDefaults(cmd, &s.Defaults, false) password, _ := cmd.Flags().GetString("password") - password, err := lib.HashPwd(password) + password, err = users.HashPwd(password) checkErr(err) - user := &lib.User{ + user := &users.User{ Username: mustGetString(cmd, "username"), Password: password, LockPassword: mustGetBool(cmd, "lockPassword"), } - st.ApplyDefaults(user) - err = st.SaveUser(user) + s.Defaults.Apply(user) + err = st.Users.Save(user) checkErr(err) - printUsers([]*lib.User{user}) + printUsers([]*users.User{user}) }, } diff --git a/cmd/users_rm.go b/cmd/users_rm.go index 346c3223..5f1b5eb6 100644 --- a/cmd/users_rm.go +++ b/cmd/users_rm.go @@ -20,7 +20,7 @@ var usersRmCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { db := getDB() defer db.Close() - st := getFileBrowser(db) + st := getStorage(db) username, _ := cmd.Flags().GetString("username") id, _ := cmd.Flags().GetUint("id") @@ -28,9 +28,9 @@ var usersRmCmd = &cobra.Command{ var err error if username != "" { - err = st.DeleteUser(username) + err = st.Users.Delete(username) } else { - err = st.DeleteUser(id) + err = st.Users.Delete(id) } checkErr(err) diff --git a/cmd/users_update.go b/cmd/users_update.go index 2a988d65..996dffad 100644 --- a/cmd/users_update.go +++ b/cmd/users_update.go @@ -1,7 +1,8 @@ package cmd import ( - + "github.com/filebrowser/filebrowser/settings" + "github.com/filebrowser/filebrowser/users" "github.com/spf13/cobra" ) @@ -23,24 +24,24 @@ options you want to change.`, Run: func(cmd *cobra.Command, args []string) { db := getDB() defer db.Close() - st := getFileBrowser(db) + st := getStorage(db) id, _ := cmd.Flags().GetUint("id") username := mustGetString(cmd, "username") password := mustGetString(cmd, "password") - var user *lib.User + var user *users.User var err error if id != 0 { - user, err = st.GetUser(id) + user, err = st.Users.Get(id) } else { - user, err = st.GetUser(username) + user, err = st.Users.Get(username) } checkErr(err) - defaults := lib.UserDefaults{ + defaults := settings.UserDefaults{ Scope: user.Scope, Locale: user.Locale, ViewMode: user.ViewMode, @@ -62,12 +63,12 @@ options you want to change.`, } if password != "" { - user.Password, err = lib.HashPwd(password) + user.Password, err = users.HashPwd(password) checkErr(err) } - err = st.UpdateUser(user) + err = st.Users.Update(user) checkErr(err) - printUsers([]*lib.User{user}) + printUsers([]*users.User{user}) }, } diff --git a/cmd/utils.go b/cmd/utils.go index 213d68c0..c7506bcd 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -5,8 +5,8 @@ import ( "os" "github.com/asdine/storm" - "github.com/filebrowser/filebrowser/bolt" - + "github.com/filebrowser/filebrowser/storage" + "github.com/filebrowser/filebrowser/storage/bolt" "github.com/spf13/cobra" ) @@ -38,8 +38,6 @@ func getDB() *storm.DB { return db } -func getFileBrowser(db *storm.DB) *lib.FileBrowser { - fb, err := lib.NewFileBrowser(&bolt.Backend{DB: db}) - checkErr(err) - return fb +func getStorage(db *storm.DB) *storage.Storage { + return bolt.NewStorage(db) } diff --git a/cmd/version.go b/cmd/version.go index fce074ec..c60ef7e9 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -3,7 +3,7 @@ package cmd import ( "fmt" - + "github.com/filebrowser/filebrowser/version" "github.com/spf13/cobra" ) @@ -15,6 +15,6 @@ var versionCmd = &cobra.Command{ Use: "version", Short: "Print the version number", Run: func(cmd *cobra.Command, args []string) { - fmt.Println("File Browser Version " + lib.Version) + fmt.Println("File Browser Version " + version.Version) }, } diff --git a/errors/errors.go b/errors/errors.go index e989faf2..e2c7cb1a 100644 --- a/errors/errors.go +++ b/errors/errors.go @@ -3,14 +3,15 @@ package errors import "errors" var ( - ErrEmptyKey = errors.New("empty key") - ErrExist = errors.New("the resource already exists") - ErrNotExist = errors.New("the resource does not exist") - ErrEmptyPassword = errors.New("password is empty") - ErrEmptyUsername = errors.New("username is empty") - ErrEmptyRequest = errors.New("empty request") - ErrScopeIsRelative = errors.New("scope is a relative path") - ErrInvalidDataType = errors.New("invalid data type") - ErrIsDirectory = errors.New("file is directory") - ErrInvalidOption = errors.New("invalid option") + ErrEmptyKey = errors.New("empty key") + ErrExist = errors.New("the resource already exists") + ErrNotExist = errors.New("the resource does not exist") + ErrEmptyPassword = errors.New("password is empty") + ErrEmptyUsername = errors.New("username is empty") + ErrEmptyRequest = errors.New("empty request") + ErrScopeIsRelative = errors.New("scope is a relative path") + ErrInvalidDataType = errors.New("invalid data type") + ErrIsDirectory = errors.New("file is directory") + ErrInvalidOption = errors.New("invalid option") + ErrInvalidAuthMethod = errors.New("invalid auth method") ) diff --git a/http/http.go b/http/http.go index 9b4c3cc4..96c85ae0 100644 --- a/http/http.go +++ b/http/http.go @@ -15,10 +15,10 @@ type modifyRequest struct { func NewHandler(storage *storage.Storage) (http.Handler, error) { r := mux.NewRouter() - /* index, static := e.getStaticHandlers() + index, static := getStaticHandlers(storage) r.PathPrefix("/static").Handler(static) - r.NotFoundHandler = index */ + r.NotFoundHandler = index api := r.PathPrefix("/api").Subrouter() @@ -26,12 +26,12 @@ func NewHandler(storage *storage.Storage) (http.Handler, error) { api.Handle("/signup", handle(signupHandler, "", storage)) api.Handle("/renew", handle(renewHandler, "", storage)) - /* users := api.PathPrefix("/users").Subrouter() - users.HandleFunc("", e.auth(e.usersGetHandler)).Methods("GET") - users.HandleFunc("", e.auth(e.userPostHandler)).Methods("POST") - users.HandleFunc("/{id:[0-9]+}", e.auth(e.userPutHandler)).Methods("PUT") - users.HandleFunc("/{id:[0-9]+}", e.auth(e.userGetHandler)).Methods("GET") - users.HandleFunc("/{id:[0-9]+}", e.auth(e.userDeleteHandler)).Methods("DELETE") */ + users := api.PathPrefix("/users").Subrouter() + users.Handle("", handle(usersGetHandler, "", storage)).Methods("GET") + users.Handle("", handle(userPostHandler, "", storage)).Methods("POST") + users.Handle("/{id:[0-9]+}", handle(userPutHandler, "", storage)).Methods("PUT") + users.Handle("/{id:[0-9]+}", handle(userGetHandler, "", storage)).Methods("GET") + users.Handle("/{id:[0-9]+}", handle(userDeleteHandler, "", storage)).Methods("DELETE") api.PathPrefix("/resources").Handler(handle(resourceGetHandler, "/api/resources", storage)).Methods("GET") api.PathPrefix("/resources").Handler(handle(resourceDeleteHandler, "/api/resources", storage)).Methods("DELETE") @@ -46,8 +46,8 @@ func NewHandler(storage *storage.Storage) (http.Handler, error) { api.Handle("/settings", handle(settingsGetHandler, "", storage)).Methods("GET") api.Handle("/settings", handle(settingsPutHandler, "", storage)).Methods("PUT") - /* api.PathPrefix("/raw").HandlerFunc(e.auth(e.rawHandler)).Methods("GET") - api.PathPrefix("/command").HandlerFunc(e.auth(e.commandsHandler)) + api.PathPrefix("/raw").Handler(handle(rawHandler, "/api/raw", storage)).Methods("GET") + /* api.PathPrefix("/command").HandlerFunc(e.auth(e.commandsHandler)) api.PathPrefix("/search").HandlerFunc(e.auth(e.searchHandler)) */ return r, nil diff --git a/http/raw.go b/http/raw.go index 369231e0..76bbb7f3 100644 --- a/http/raw.go +++ b/http/raw.go @@ -1,7 +1,17 @@ package http -/* -const apiRawPrefix = "/api/raw" +import ( + "errors" + "net/http" + "net/url" + "path/filepath" + "strings" + + "github.com/filebrowser/filebrowser/files" + "github.com/filebrowser/filebrowser/users" + "github.com/hacdias/fileutils" + "github.com/mholt/archiver" +) func parseQueryFiles(r *http.Request, f *files.FileInfo, u *users.User) ([]string, error) { files := []string{} @@ -45,38 +55,77 @@ func parseQueryAlgorithm(r *http.Request) (string, archiver.Writer, error) { } } -func (e *env) rawHandler(w http.ResponseWriter, r *http.Request) { - path, user, ok := e.getResourceData(w, r, apiRawPrefix) - if !ok { - return +var rawHandler = withUser(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) { + if !d.user.Perm.Download { + return http.StatusAccepted, nil } - if !user.Perm.Download { - httpErr(w, r, http.StatusForbidden, nil) - return - } - - file, err := files.NewFileInfo(user.Fs, path, user.Perm.Modify) + file, err := files.NewFileInfo(d.user.Fs, r.URL.Path, d.user.Perm.Modify, d) if err != nil { - httpErr(w, r, httpFsErr(err), err) - return + return errToStatus(err), err } if !file.IsDir { - fileHandler(w, r, file, user) - return + return rawFileHandler(w, r, file) } - filenames, err := parseQueryFiles(r, file, user) + return rawDirHandler(w, r, d, file) +}) + +func addFile(ar archiver.Writer, d *data, path string) error { + if !d.Check(path) { + return nil + } + + info, err := d.user.Fs.Stat(path) if err != nil { - httpErr(w, r, http.StatusInternalServerError, err) - return + return err + } + + // open the file + file, err := d.user.Fs.Open(path) + if err != nil { + return err + } + defer file.Close() + + err = ar.Write(archiver.File{ + FileInfo: archiver.FileInfo{ + FileInfo: info, + CustomName: path, + }, + ReadCloser: file, + }) + if err != nil { + return err + } + + if info.IsDir() { + names, err := file.Readdirnames(0) + if err != nil { + return err + } + + for _, name := range names { + err = addFile(ar, d, filepath.Join(path, name)) + if err != nil { + return err + } + } + } + + return nil +} + +func rawDirHandler(w http.ResponseWriter, r *http.Request, d *data, file *files.FileInfo) (int, error) { + filenames, err := parseQueryFiles(r, file, d.user) + if err != nil { + return http.StatusInternalServerError, err } extension, ar, err := parseQueryAlgorithm(r) if err != nil { - httpErr(w, r, http.StatusInternalServerError, err) - return + return http.StatusInternalServerError, err } name := file.Name @@ -88,53 +137,24 @@ func (e *env) rawHandler(w http.ResponseWriter, r *http.Request) { err = ar.Create(w) if err != nil { - httpErr(w, r, http.StatusInternalServerError, err) - return + return http.StatusInternalServerError, err } defer ar.Close() for _, fname := range filenames { - info, err := user.Fs.Stat(fname) + err = addFile(ar, d, fname) if err != nil { - httpErr(w, r, http.StatusInternalServerError, err) - return - } - - // get file's name for the inside of the archive - internalName, err := archiver.NameInArchive(info, fname, fname) - if err != nil { - httpErr(w, r, http.StatusInternalServerError, err) - return - } - - // open the file - file, err := user.Fs.Open(fname) - if err != nil { - httpErr(w, r, http.StatusInternalServerError, err) - return - } - - // write it to the archive - err = ar.Write(archiver.File{ - FileInfo: archiver.FileInfo{ - FileInfo: info, - CustomName: internalName, - }, - ReadCloser: file, - }) - file.Close() - if err != nil { - httpErr(w, r, http.StatusInternalServerError, err) - return + return http.StatusInternalServerError, err } } + + return 0, nil } -func fileHandler(w http.ResponseWriter, r *http.Request, file *files.File, user *users.User) { - fd, err := user.Fs.Open(file.Path) +func rawFileHandler(w http.ResponseWriter, r *http.Request, file *files.FileInfo) (int, error) { + fd, err := file.Fs.Open(file.Path) if err != nil { - httpErr(w, r, http.StatusInternalServerError, err) - return + return http.StatusInternalServerError, err } defer fd.Close() @@ -146,4 +166,5 @@ func fileHandler(w http.ResponseWriter, r *http.Request, file *files.File, user } http.ServeContent(w, r, file.Name, file.ModTime, fd) -} */ + return 0, nil +} diff --git a/http/resource.go b/http/resource.go index a5c2e020..9ebfffc3 100644 --- a/http/resource.go +++ b/http/resource.go @@ -15,8 +15,6 @@ import ( "github.com/filebrowser/filebrowser/fileutils" ) -// TODO: trim path - var resourceGetHandler = withUser(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) { file, err := files.NewFileInfo(d.user.Fs, r.URL.Path, d.user.Perm.Modify, d) if err != nil { diff --git a/http/static.go b/http/static.go index 17d1d9bb..06a41b6d 100644 --- a/http/static.go +++ b/http/static.go @@ -1,40 +1,39 @@ package http -/* import ( "encoding/json" + "text/template" "log" + "net/http" "os" "path/filepath" "strings" + "github.com/GeertJohan/go.rice" "github.com/filebrowser/filebrowser/auth" "github.com/filebrowser/filebrowser/storage" "github.com/filebrowser/filebrowser/version" ) -func getStaticData(storage *storage.Storage) (map[string]interface{}, error) { - settings, err := storage.Settings.Get() - if err != nil { - return nil, err - } +func handleWithStaticData(w http.ResponseWriter, r *http.Request, d *data, box *rice.Box, file, contentType string) (int, error) { + w.Header().Set("Content-Type", contentType) - staticURL := strings.TrimPrefix(settings.BaseURL+"/static", "/") + staticURL := strings.TrimPrefix(d.settings.BaseURL+"/static", "/") data := map[string]interface{}{ - "Name": settings.Branding.Name, - "DisableExternal": settings.Branding.DisableExternal, - "BaseURL": settings.BaseURL, + "Name": d.settings.Branding.Name, + "DisableExternal": d.settings.Branding.DisableExternal, + "BaseURL": d.settings.BaseURL, "Version": version.Version, "StaticURL": staticURL, - "Signup": settings.Signup, - "NoAuth": settings.AuthMethod == auth.MethodNoAuth, + "Signup": d.settings.Signup, + "NoAuth": d.settings.AuthMethod == auth.MethodNoAuth, "CSS": false, "ReCaptcha": false, } - if settings.Branding.Files != "" { - path := filepath.Join(settings.Branding.Files, "custom.css") + if d.settings.Branding.Files != "" { + path := filepath.Join(d.settings.Branding.Files, "custom.css") _, err := os.Stat(path) if err != nil && !os.IsNotExist(err) { @@ -46,10 +45,10 @@ func getStaticData(storage *storage.Storage) (map[string]interface{}, error) { } } - if settings.AuthMethod == auth.MethodJSONAuth { - raw, err := storage.Auth.Get() + if d.settings.AuthMethod == auth.MethodJSONAuth { + raw, err := d.store.Auth.Get(d.settings.AuthMethod) if err != nil { - return nil, err + return http.StatusInternalServerError, err } auther := raw.(*auth.JSONAuth) @@ -61,68 +60,62 @@ func getStaticData(storage *storage.Storage) (map[string]interface{}, error) { } } - b, _ := json.MarshalIndent(data, "", " ") + b, err := json.MarshalIndent(data, "", " ") + if err != nil { + return http.StatusInternalServerError, err + } + data["Json"] = string(b) - return data, nil + + index := template.Must(template.New("index").Delims("[{[", "]}]").Parse(box.MustString(file))) + err = index.Execute(w, data) + if err != nil { + return http.StatusInternalServerError, err + } + + return 0, nil } -func getStaticHandlers(storage *storage.Storage) (http.Handler, http.Handler, error) { +func getStaticHandlers(storage *storage.Storage) (http.Handler, http.Handler) { box := rice.MustFindBox("../frontend/dist") handler := http.FileServer(box.HTTPBox()) - handleWithData := func(w http.ResponseWriter, r *http.Request, file string, contentType string) { - w.Header().Set("Content-Type", contentType) - index := template.Must(template.New("index").Delims("[{[", "]}]").Parse(box.MustString(file))) - data, err := getStaticData(storage) - if err != nil { - - } - - err := index.Execute(w, e.getStaticData()) - - if err != nil { - httpErr(w, r, http.StatusInternalServerError, err) - } - } - - index := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + index := handle(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) { if r.Method != http.MethodGet { - httpErr(w, r, http.StatusNotFound, nil) - return + return http.StatusNotFound, nil } w.Header().Set("x-frame-options", "SAMEORIGIN") w.Header().Set("x-xss-protection", "1; mode=block") - handleWithData(w, r, "index.html", "text/html; charset=utf-8") - }) + return handleWithStaticData(w, r, d, box, "index.html", "text/html; charset=utf-8") + }, "", storage) - static := http.StripPrefix("/static/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - e.RLockSettings() - defer e.RUnlockSettings() + static := handle(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) { + if r.Method != http.MethodGet { + return http.StatusNotFound, nil + } - if e.GetSettings().Branding.Files != "" { + if d.settings.Branding.Files != "" { if strings.HasPrefix(r.URL.Path, "img/") { - path := filepath.Join(e.GetSettings().Branding.Files, r.URL.Path) + path := filepath.Join(d.settings.Branding.Files, r.URL.Path) if _, err := os.Stat(path); err == nil { http.ServeFile(w, r, path) - return + return 0, nil } - } else if r.URL.Path == "custom.css" && e.GetSettings().Branding.Files != "" { - http.ServeFile(w, r, filepath.Join(e.GetSettings().Branding.Files, "custom.css")) - return + } else if r.URL.Path == "custom.css" && d.settings.Branding.Files != "" { + http.ServeFile(w, r, filepath.Join(d.settings.Branding.Files, "custom.css")) + return 0, nil } } if !strings.HasSuffix(r.URL.Path, ".js") { handler.ServeHTTP(w, r) - return + return 0, nil } - handleWithData(w, r, r.URL.Path, "application/javascript; charset=utf-8") - })) + return handleWithStaticData(w, r, d, box, r.URL.Path, "application/javascript; charset=utf-8") + }, "/static/", storage) return index, static } - -*/ diff --git a/http/users.go b/http/users.go index 2ce571ed..dc38490d 100644 --- a/http/users.go +++ b/http/users.go @@ -5,6 +5,7 @@ import ( "net/http" "sort" "strconv" + "strings" "github.com/filebrowser/filebrowser/errors" "github.com/filebrowser/filebrowser/users" @@ -64,15 +65,15 @@ var usersGetHandler = withAdmin(func(w http.ResponseWriter, r *http.Request, d * if err != nil { return http.StatusInternalServerError, err } - + for _, u := range users { u.Password = "" } - + sort.Slice(users, func(i, j int) bool { return users[i].ID < users[j].ID }) - + return renderJSON(w, r, users) }) @@ -81,7 +82,7 @@ var userGetHandler = withSelfOrAdmin(func(w http.ResponseWriter, r *http.Request if err == errors.ErrNotExist { return http.StatusNotFound, err } - + if err != nil { return http.StatusInternalServerError, err } @@ -95,85 +96,63 @@ var userDeleteHandler = withSelfOrAdmin(func(w http.ResponseWriter, r *http.Requ if err == errors.ErrNotExist { return http.StatusNotFound, err } - + return http.StatusOK, nil }) -/* - -func (e *env) userPostHandler(w http.ResponseWriter, r *http.Request) { - _, ok := e.getAdminUser(w, r) - if !ok { - return - } - - req, ok := getUser(w, r) - if !ok { - return +var userPostHandler = withAdmin(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) { + req, err := getUser(w, r) + if err != nil { + return http.StatusBadRequest, err } if len(req.Which) != 0 { - httpErr(w, r, http.StatusBadRequest, nil) - return + return http.StatusBadRequest, nil } if req.Data.Password == "" { - httpErr(w, r, http.StatusBadRequest, lib.ErrEmptyPassword) - return + return http.StatusBadRequest, errors.ErrEmptyPassword } - var err error - req.Data.Password, err = lib.HashPwd(req.Data.Password) + req.Data.Password, err = users.HashPwd(req.Data.Password) if err != nil { - httpErr(w, r, http.StatusInternalServerError, err) - return + return http.StatusInternalServerError, err } - err = e.SaveUser(req.Data) + err = d.store.Users.Save(req.Data) if err != nil { - httpErr(w, r, http.StatusInternalServerError, err) - return + return http.StatusInternalServerError, err } w.Header().Set("Location", "/settings/users/"+strconv.FormatUint(uint64(req.Data.ID), 10)) - w.WriteHeader(http.StatusCreated) -} + return http.StatusCreated, nil +}) -func (e *env) userPutHandler(w http.ResponseWriter, r *http.Request) { - sessionUser, modifiedID, ok := e.userSelfOrAdmin(w, r) - if !ok { - return +var userPutHandler = withSelfOrAdmin(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) { + req, err := getUser(w, r) + if err != nil { + return http.StatusBadRequest, err } - req, ok := getUser(w, r) - if !ok { - return + if req.Data.ID != d.raw.(uint) { + return http.StatusBadRequest, nil } - if req.Data.ID != modifiedID { - httpErr(w, r, http.StatusBadRequest, nil) - return - } - - var err error - if len(req.Which) == 1 && req.Which[0] == "all" { - if !sessionUser.Perm.Admin { - httpErr(w, r, http.StatusForbidden, nil) - return + if !d.user.Perm.Admin { + return http.StatusForbidden, err } if req.Data.Password != "" { - req.Data.Password, err = lib.HashPwd(req.Data.Password) + req.Data.Password, err = users.HashPwd(req.Data.Password) } else { var suser *users.User - suser, err = e.GetUser(modifiedID) + suser, err = d.store.Users.Get(d.raw.(uint)) req.Data.Password = suser.Password } if err != nil { - httpErr(w, r, http.StatusInternalServerError, err) - return + return http.StatusInternalServerError, err } req.Which = []string{} @@ -181,28 +160,27 @@ func (e *env) userPutHandler(w http.ResponseWriter, r *http.Request) { for k, v := range req.Which { if v == "password" { - if !sessionUser.Perm.Admin && sessionUser.LockPassword { - httpErr(w, r, http.StatusForbidden, nil) - return + if !d.user.Perm.Admin && d.user.LockPassword { + return http.StatusForbidden, nil } - req.Data.Password, err = lib.HashPwd(req.Data.Password) + req.Data.Password, err = users.HashPwd(req.Data.Password) if err != nil { - httpErr(w, r, http.StatusInternalServerError, err) - return + return http.StatusInternalServerError, err } } - if !sessionUser.Perm.Admin && (v == "scope" || v == "perm" || v == "username") { - httpErr(w, r, http.StatusForbidden, nil) - return + if !d.user.Perm.Admin && (v == "scope" || v == "perm" || v == "username") { + return http.StatusForbidden, nil } req.Which[k] = strings.Title(v) } - err = e.UpdateUser(req.Data, req.Which...) + err = d.store.Users.Update(req.Data, req.Which...) if err != nil { - httpErr(w, r, http.StatusInternalServerError, err) + return http.StatusInternalServerError, err } -} */ + + return http.StatusOK, nil +}) diff --git a/storage/bolt/auth.go b/storage/bolt/auth.go new file mode 100644 index 00000000..280d06f7 --- /dev/null +++ b/storage/bolt/auth.go @@ -0,0 +1,33 @@ +package bolt + +import ( + "github.com/asdine/storm" + "github.com/filebrowser/filebrowser/auth" + "github.com/filebrowser/filebrowser/errors" + "github.com/filebrowser/filebrowser/settings" +) + +type authBackend struct { + db *storm.DB +} + +func (s authBackend) Get(t settings.AuthMethod) (auth.Auther, error) { + var auther auth.Auther + + switch t { + case auth.MethodJSONAuth: + auther = &auth.JSONAuth{} + case auth.MethodProxyAuth: + auther = &auth.ProxyAuth{} + case auth.MethodNoAuth: + auther = &auth.NoAuth{} + default: + return nil, errors.ErrInvalidAuthMethod + } + + return auther, get(s.db, "auther", auther) +} + +func (s authBackend) Save(a auth.Auther) error { + return save(s.db, "auther", a) +} diff --git a/storage/bolt/bolt.go b/storage/bolt/bolt.go index 824de7f9..f6366d7e 100644 --- a/storage/bolt/bolt.go +++ b/storage/bolt/bolt.go @@ -1,9 +1,25 @@ package bolt -import "github.com/asdine/storm" +import ( + "github.com/filebrowser/filebrowser/settings" + "github.com/asdine/storm" + "github.com/filebrowser/filebrowser/auth" + "github.com/filebrowser/filebrowser/share" + "github.com/filebrowser/filebrowser/storage" + "github.com/filebrowser/filebrowser/users" +) -// Backend implements storage.Backend -// using Bolt DB. -type Backend struct { - DB *storm.DB +// NewStorage creates a storage.Storage based on Bolt DB. +func NewStorage(db *storm.DB) *storage.Storage { + users := users.NewStorage(usersBackend{db: db}) + share := share.NewStorage(shareBackend{db: db}) + settings := settings.NewStorage(settingsBackend{ db: db}) + auth := auth.NewStorage(authBackend{db: db}, users) + + return &storage.Storage{ + Auth: auth, + Users: users, + Share: share, + Settings: settings, + } } diff --git a/storage/bolt/config.go b/storage/bolt/config.go index ed2cfa1d..37b81cab 100644 --- a/storage/bolt/config.go +++ b/storage/bolt/config.go @@ -2,49 +2,18 @@ package bolt import ( "github.com/asdine/storm" - "github.com/filebrowser/filebrowser/auth" - + "github.com/filebrowser/filebrowser/settings" ) -func (b Backend) get(name string, to interface{}) error { - err := b.DB.Get("config", name, to) - if err == storm.ErrNotFound { - return lib.ErrNotExist - } - - return err +type settingsBackend struct { + db *storm.DB } -func (b Backend) save(name string, from interface{}) error { - return b.DB.Set("config", name, from) -} - -func (b Backend) GetSettings() (*settings.Settings, error) { +func (s settingsBackend) Get() (*settings.Settings, error) { settings := &settings.Settings{} - return settings, b.get("settings", settings) + return settings, get(s.db, "settings", settings) } -func (b Backend) SaveSettings(s *settings.Settings) error { - return b.save("settings", s) -} - -func (b Backend) GetAuther(t lib.AuthMethod) (lib.Auther, error) { - var auther lib.Auther - - switch t { - case auth.MethodJSONAuth: - auther = &auth.JSONAuth{} - case auth.MethodProxyAuth: - auther = &auth.ProxyAuth{} - case auth.MethodNoAuth: - auther = &auth.NoAuth{} - default: - return nil, lib.ErrInvalidAuthMethod - } - - return auther, b.get("auther", auther) -} - -func (b Backend) SaveAuther(a lib.Auther) error { - return b.save("auther", a) +func (s settingsBackend) Save(settings *settings.Settings) error { + return save(s.db, "settings", settings) } diff --git a/storage/bolt/share.go b/storage/bolt/share.go index 374a60c0..70cf7e22 100644 --- a/storage/bolt/share.go +++ b/storage/bolt/share.go @@ -3,43 +3,48 @@ package bolt import ( "github.com/asdine/storm" "github.com/asdine/storm/q" - + "github.com/filebrowser/filebrowser/errors" + "github.com/filebrowser/filebrowser/share" ) -func (s Backend) GetLinkByHash(hash string) (*lib.ShareLink, error) { - var v lib.ShareLink - err := s.DB.One("Hash", hash, &v) +type shareBackend struct { + db *storm.DB +} + +func (s shareBackend) GetByHash(hash string) (*share.Link, error) { + var v share.Link + err := s.db.One("Hash", hash, &v) if err == storm.ErrNotFound { - return nil, lib.ErrNotExist + return nil, errors.ErrNotExist } return &v, err } -func (s Backend) GetLinkPermanent(path string) (*lib.ShareLink, error) { - var v lib.ShareLink - err := s.DB.Select(q.Eq("Path", path), q.Eq("Expires", false)).First(&v) +func (s shareBackend) GetPermanent(path string) (*share.Link, error) { + var v share.Link + err := s.db.Select(q.Eq("Path", path), q.Eq("Expires", false)).First(&v) if err == storm.ErrNotFound { - return nil, lib.ErrNotExist + return nil, errors.ErrNotExist } return &v, err } -func (s Backend) GetLinksByPath(hash string) ([]*lib.ShareLink, error) { - var v []*lib.ShareLink - err := s.DB.Find("Path", hash, &v) +func (s shareBackend) Gets(hash string) ([]*share.Link, error) { + var v []*share.Link + err := s.db.Find("Path", hash, &v) if err == storm.ErrNotFound { - return v, lib.ErrNotExist + return v, errors.ErrNotExist } return v, err } -func (s Backend) SaveLink(l *lib.ShareLink) error { - return s.DB.Save(l) +func (s shareBackend) Save(l *share.Link) error { + return s.db.Save(l) } -func (s Backend) DeleteLink(hash string) error { - return s.DB.DeleteStruct(&lib.ShareLink{Hash: hash}) +func (s shareBackend) Delete(hash string) error { + return s.db.DeleteStruct(&share.Link{Hash: hash}) } diff --git a/storage/bolt/users.go b/storage/bolt/users.go index b599a132..cced8c89 100644 --- a/storage/bolt/users.go +++ b/storage/bolt/users.go @@ -4,14 +4,19 @@ import ( "reflect" "github.com/asdine/storm" - + "github.com/filebrowser/filebrowser/errors" + "github.com/filebrowser/filebrowser/users" ) -func (st Backend) GetUserByID(id uint) (*lib.User, error) { - user := &lib.User{} - err := st.DB.One("ID", id, user) +type usersBackend struct { + db *storm.DB +} + +func (st usersBackend) GetByID(id uint) (*users.User, error) { + user := &users.User{} + err := st.db.One("ID", id, user) if err == storm.ErrNotFound { - return nil, lib.ErrNotExist + return nil, errors.ErrNotExist } if err != nil { @@ -21,11 +26,11 @@ func (st Backend) GetUserByID(id uint) (*lib.User, error) { return user, nil } -func (st Backend) GetUserByUsername(username string) (*lib.User, error) { - user := &lib.User{} - err := st.DB.One("Username", username, user) +func (st usersBackend) GetByUsername(username string) (*users.User, error) { + user := &users.User{} + err := st.db.One("Username", username, user) if err == storm.ErrNotFound { - return nil, lib.ErrNotExist + return nil, errors.ErrNotExist } if err != nil { @@ -35,11 +40,11 @@ func (st Backend) GetUserByUsername(username string) (*lib.User, error) { return user, nil } -func (st Backend) GetUsers() ([]*lib.User, error) { - users := []*lib.User{} - err := st.DB.All(&users) +func (st usersBackend) Gets() ([]*users.User, error) { + users := []*users.User{} + err := st.db.All(&users) if err == storm.ErrNotFound { - return nil, lib.ErrNotExist + return nil, errors.ErrNotExist } if err != nil { @@ -49,14 +54,14 @@ func (st Backend) GetUsers() ([]*lib.User, error) { return users, err } -func (st Backend) UpdateUser(user *lib.User, fields ...string) error { +func (st usersBackend) Update(user *users.User, fields ...string) error { if len(fields) == 0 { - return st.SaveUser(user) + return st.Save(user) } for _, field := range fields { val := reflect.ValueOf(user).Elem().FieldByName(field).Interface() - if err := st.DB.UpdateField(user, field, val); err != nil { + if err := st.db.UpdateField(user, field, val); err != nil { return err } } @@ -64,23 +69,23 @@ func (st Backend) UpdateUser(user *lib.User, fields ...string) error { return nil } -func (st Backend) SaveUser(user *lib.User) error { - err := st.DB.Save(user) +func (st usersBackend) Save(user *users.User) error { + err := st.db.Save(user) if err == storm.ErrAlreadyExists { - return lib.ErrExist + return errors.ErrExist } return err } -func (st Backend) DeleteUserByID(id uint) error { - return st.DB.DeleteStruct(&lib.User{ID: id}) +func (st usersBackend) DeleteByID(id uint) error { + return st.db.DeleteStruct(&users.User{ID: id}) } -func (st Backend) DeleteUserByUsername(username string) error { - user, err := st.GetUserByUsername(username) +func (st usersBackend) DeleteByUsername(username string) error { + user, err := st.GetByUsername(username) if err != nil { return err } - return st.DB.DeleteStruct(user) + return st.db.DeleteStruct(user) } diff --git a/storage/bolt/utils.go b/storage/bolt/utils.go new file mode 100644 index 00000000..bf68c45c --- /dev/null +++ b/storage/bolt/utils.go @@ -0,0 +1,19 @@ +package bolt + +import ( + "github.com/asdine/storm" + "github.com/filebrowser/filebrowser/errors" +) + +func get(db *storm.DB, name string, to interface{}) error { + err := db.Get("config", name, to) + if err == storm.ErrNotFound { + return errors.ErrNotExist + } + + return err +} + +func save(db *storm.DB, name string, from interface{}) error { + return db.Set("config", name, from) +} diff --git a/storage/utils.go b/storage/utils.go deleted file mode 100644 index 8f27b354..00000000 --- a/storage/utils.go +++ /dev/null @@ -1,10 +0,0 @@ -package storage - -import "crypto/rand" - -func generateRandomBytes(n int) ([]byte, error) { - b := make([]byte, n) - _, err := rand.Read(b) - // Note that err == nil only if we read len(b) bytes. - return b, err -}