cleanup and bug fixing

License: MIT
Signed-off-by: Henrique Dias <hacdias@gmail.com>
This commit is contained in:
Henrique Dias 2019-01-04 21:46:53 +00:00
parent 9f58170575
commit ff99e72093
28 changed files with 458 additions and 410 deletions

View File

@ -20,14 +20,15 @@ var cmdsAddCmd = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
db := getDB() db := getDB()
defer db.Close() defer db.Close()
st := getFileBrowser(db) st := getStorage(db)
s := st.GetSettings() s, err := st.Settings.Get()
checkErr(err)
evt := mustGetString(cmd, "event") evt := mustGetString(cmd, "event")
command := mustGetString(cmd, "command") command := mustGetString(cmd, "command")
s.Commands[evt] = append(s.Commands[evt], command) s.Commands[evt] = append(s.Commands[evt], command)
err := st.SaveSettings(s) err = st.Settings.Save(s)
checkErr(err) checkErr(err)
printEvents(s.Commands) printEvents(s.Commands)
}, },

View File

@ -17,8 +17,9 @@ var cmdsLsCmd = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
db := getDB() db := getDB()
defer db.Close() defer db.Close()
st := getFileBrowser(db) st := getStorage(db)
s := st.GetSettings() s, err := st.Settings.Get()
checkErr(err)
evt := mustGetString(cmd, "event") evt := mustGetString(cmd, "event")
if evt == "" { if evt == "" {

View File

@ -20,15 +20,16 @@ var cmdsRmCmd = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
db := getDB() db := getDB()
defer db.Close() defer db.Close()
st := getFileBrowser(db) st := getStorage(db)
s := st.GetSettings() s, err := st.Settings.Get()
checkErr(err)
evt := mustGetString(cmd, "event") evt := mustGetString(cmd, "event")
i, err := cmd.Flags().GetUint("index") i, err := cmd.Flags().GetUint("index")
checkErr(err) checkErr(err)
s.Commands[evt] = append(s.Commands[evt][:i], s.Commands[evt][i+1:]...) s.Commands[evt] = append(s.Commands[evt][:i], s.Commands[evt][i+1:]...)
err = st.SaveSettings(s) err = st.Settings.Save(s)
checkErr(err) checkErr(err)
printEvents(s.Commands) printEvents(s.Commands)
}, },

View File

@ -2,14 +2,15 @@ package cmd
import ( import (
"encoding/json" "encoding/json"
"errors" nerrors "errors"
"fmt" "fmt"
"os" "os"
"strings" "strings"
"text/tabwriter" "text/tabwriter"
"github.com/filebrowser/filebrowser/auth" "github.com/filebrowser/filebrowser/auth"
"github.com/filebrowser/filebrowser/settings"
"github.com/filebrowser/filebrowser/errors"
"github.com/spf13/cobra" "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") cmd.Flags().Bool("branding.disableExternal", false, "disable external links such as GitHub links")
} }
func getAuthentication(cmd *cobra.Command) (lib.AuthMethod, lib.Auther) { func getAuthentication(cmd *cobra.Command) (settings.AuthMethod, auth.Auther) {
method := lib.AuthMethod(mustGetString(cmd, "auth.method")) method := settings.AuthMethod(mustGetString(cmd, "auth.method"))
var auther lib.Auther var auther auth.Auther
if method == auth.MethodProxyAuth { if method == auth.MethodProxyAuth {
header := mustGetString(cmd, "auth.header") header := mustGetString(cmd, "auth.header")
if 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} auther = &auth.ProxyAuth{Header: header}
} }
@ -81,13 +82,13 @@ func getAuthentication(cmd *cobra.Command) (lib.AuthMethod, lib.Auther) {
} }
if auther == nil { if auther == nil {
panic(lib.ErrInvalidAuthMethod) panic(errors.ErrInvalidAuthMethod)
} }
return method, auther 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) w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
fmt.Fprintf(w, "\nBase URL:\t%s\n", s.BaseURL) fmt.Fprintf(w, "\nBase URL:\t%s\n", s.BaseURL)

View File

@ -16,9 +16,10 @@ var configCatCmd = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
db := getDB() db := getDB()
defer db.Close() defer db.Close()
st := getFileBrowser(db) st := getStorage(db)
s := st.GetSettings() s, err := st.Settings.Get()
auther, err := st.GetAuther(s.AuthMethod) checkErr(err)
auther, err := st.Auth.Get(s.AuthMethod)
checkErr(err) checkErr(err)
printSettings(s, auther) printSettings(s, auther)
}, },

View File

@ -7,7 +7,7 @@ import (
"strings" "strings"
"github.com/asdine/storm" "github.com/asdine/storm"
"github.com/filebrowser/filebrowser/settings"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -32,30 +32,31 @@ override the options.`,
panic(errors.New(databasePath + " already exists")) panic(errors.New(databasePath + " already exists"))
} }
defaults := lib.UserDefaults{} defaults := settings.UserDefaults{}
getUserDefaults(cmd, &defaults, true) getUserDefaults(cmd, &defaults, true)
authMethod, auther := getAuthentication(cmd) authMethod, auther := getAuthentication(cmd)
db, err := storm.Open(databasePath) db, err := storm.Open(databasePath)
checkErr(err) checkErr(err)
defer db.Close() defer db.Close()
st := getFileBrowser(db) st := getStorage(db)
settings := st.GetSettings() s, err := st.Settings.Get()
checkErr(err)
settings.BaseURL = mustGetString(cmd, "baseURL") s.BaseURL = mustGetString(cmd, "baseURL")
settings.Signup = mustGetBool(cmd, "signup") s.Signup = mustGetBool(cmd, "signup")
settings.Shell = strings.Split(strings.TrimSpace(mustGetString(cmd, "shell")), " ") s.Shell = strings.Split(strings.TrimSpace(mustGetString(cmd, "shell")), " ")
settings.Defaults = defaults s.Defaults = defaults
settings.AuthMethod = authMethod s.AuthMethod = authMethod
settings.Branding = lib.Branding{ s.Branding = settings.Branding{
Name: mustGetString(cmd, "branding.name"), Name: mustGetString(cmd, "branding.name"),
DisableExternal: mustGetBool(cmd, "branding.disableExternal"), DisableExternal: mustGetBool(cmd, "branding.disableExternal"),
Files: mustGetString(cmd, "branding.files"), Files: mustGetString(cmd, "branding.files"),
} }
err = st.SaveSettings(settings) err = st.Settings.Save(s)
checkErr(err) checkErr(err)
err = st.SaveAuther(auther) err = st.Auth.Save(auther)
checkErr(err) checkErr(err)
fmt.Printf(` 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 Now add your first user via 'filebrowser users new' and then you just
need to call the main command to boot up the server. need to call the main command to boot up the server.
`) `)
printSettings(settings, auther) printSettings(s, auther)
}, },
} }

View File

@ -3,7 +3,7 @@ package cmd
import ( import (
"strings" "strings"
"github.com/filebrowser/filebrowser/auth"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/pflag" "github.com/spf13/pflag"
) )
@ -23,10 +23,11 @@ you want to change.`,
db := getDB() db := getDB()
defer db.Close() defer db.Close()
st := getFileBrowser(db) st := getStorage(db)
s := st.GetSettings() s, err := st.Settings.Get()
checkErr(err)
auth := false hasAuth := false
cmd.Flags().Visit(func(flag *pflag.Flag) { cmd.Flags().Visit(func(flag *pflag.Flag) {
switch flag.Name { switch flag.Name {
case "baseURL": case "baseURL":
@ -34,7 +35,7 @@ you want to change.`,
case "signup": case "signup":
s.Signup = mustGetBool(cmd, "signup") s.Signup = mustGetBool(cmd, "signup")
case "auth.method": case "auth.method":
auth = true hasAuth = true
case "shell": case "shell":
s.Shell = strings.Split(strings.TrimSpace(mustGetString(cmd, "shell")), " ") s.Shell = strings.Split(strings.TrimSpace(mustGetString(cmd, "shell")), " ")
case "branding.name": case "branding.name":
@ -48,18 +49,17 @@ you want to change.`,
getUserDefaults(cmd, &s.Defaults, false) getUserDefaults(cmd, &s.Defaults, false)
var auther lib.Auther var auther auth.Auther
var err error if hasAuth {
if auth {
s.AuthMethod, auther = getAuthentication(cmd) s.AuthMethod, auther = getAuthentication(cmd)
err = st.SaveAuther(auther) err = st.Auth.Save(auther)
checkErr(err) checkErr(err)
} else { } else {
auther, err = st.GetAuther(s.AuthMethod) auther, err = st.Auth.Get(s.AuthMethod)
checkErr(err) checkErr(err)
} }
err = st.SaveSettings(s) err = st.Settings.Save(s)
checkErr(err) checkErr(err)
printSettings(s, auther) printSettings(s, auther)
}, },

View File

@ -1,6 +1,7 @@
package cmd package cmd
import ( import (
"crypto/rand"
"crypto/tls" "crypto/tls"
"errors" "errors"
"io/ioutil" "io/ioutil"
@ -12,7 +13,8 @@ import (
"github.com/asdine/storm" "github.com/asdine/storm"
"github.com/filebrowser/filebrowser/auth" "github.com/filebrowser/filebrowser/auth"
"github.com/filebrowser/filebrowser/settings"
"github.com/filebrowser/filebrowser/users"
fbhttp "github.com/filebrowser/filebrowser/http" fbhttp "github.com/filebrowser/filebrowser/http"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -56,9 +58,10 @@ listening on loalhost on a random port. Use the flags to change it.`,
var err error var err error
db := getDB() db := getDB()
defer db.Close() defer db.Close()
fb := getFileBrowser(db)
handler, err := fbhttp.NewHandler(fb) st := getStorage(db)
handler, err := fbhttp.NewHandler(st)
checkErr(err) checkErr(err)
startServer(cmd, handler) startServer(cmd, handler)
}, },
@ -91,46 +94,48 @@ func quickSetup(cmd *cobra.Command) {
db, err := storm.Open(databasePath) db, err := storm.Open(databasePath)
checkErr(err) checkErr(err)
defer db.Close() defer db.Close()
fb := getFileBrowser(db)
settings := fb.GetSettings() set := &settings.Settings{
settings.BaseURL = "" BaseURL: "",
settings.Signup = false Signup: false,
settings.AuthMethod = auth.MethodJSONAuth AuthMethod: auth.MethodJSONAuth,
settings.Defaults = lib.UserDefaults{ Defaults: settings.UserDefaults{
Scope: scope, Scope: scope,
Locale: "en", Locale: "en",
Perm: lib.Permissions{ Perm: users.Permissions{
Admin: false, Admin: false,
Execute: true, Execute: true,
Create: true, Create: true,
Rename: true, Rename: true,
Modify: true, Modify: true,
Delete: true, Delete: true,
Share: true, Share: true,
Download: true, Download: true,
},
}, },
} }
err = fb.SaveSettings(settings) st := getStorage(db)
err = st.Settings.Save(set)
checkErr(err) checkErr(err)
err = fb.SaveAuther(&auth.JSONAuth{}) err = st.Auth.Save(&auth.JSONAuth{})
checkErr(err) checkErr(err)
password, err := lib.HashPwd("admin") password, err := users.HashPwd("admin")
checkErr(err) checkErr(err)
user := &lib.User{ user := &users.User{
Username: "admin", Username: "admin",
Password: password, Password: password,
LockPassword: false, LockPassword: false,
} }
fb.ApplyDefaults(user) set.Defaults.Apply(user)
user.Perm.Admin = true user.Perm.Admin = true
err = fb.SaveUser(user) err = st.Users.Save(user)
checkErr(err) checkErr(err)
} }
@ -160,3 +165,11 @@ func startServer(cmd *cobra.Command, handler http.Handler) {
log.Fatal(err) 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
}

View File

@ -6,7 +6,8 @@ import (
"os" "os"
"text/tabwriter" "text/tabwriter"
"github.com/filebrowser/filebrowser/settings"
"github.com/filebrowser/filebrowser/users"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/pflag" "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) 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") 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().StringSlice("commands", nil, "a list of the commands a user can execute")
cmd.Flags().String("scope", "", "scope for users") cmd.Flags().String("scope", "", "scope for users")
cmd.Flags().String("locale", "en", "locale 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 { func getViewMode(cmd *cobra.Command) users.ViewMode {
viewMode := lib.ViewMode(mustGetString(cmd, "viewMode")) viewMode := users.ViewMode(mustGetString(cmd, "viewMode"))
if viewMode != lib.ListViewMode && viewMode != lib.MosaicViewMode { if viewMode != users.ListViewMode && viewMode != users.MosaicViewMode {
checkErr(errors.New("view mode must be \"" + string(lib.ListViewMode) + "\" or \"" + string(lib.MosaicViewMode) + "\"")) checkErr(errors.New("view mode must be \"" + string(users.ListViewMode) + "\" or \"" + string(users.MosaicViewMode) + "\""))
} }
return viewMode 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) { visit := func(flag *pflag.Flag) {
switch flag.Name { switch flag.Name {
case "scope": case "scope":

View File

@ -1,7 +1,7 @@
package cmd package cmd
import ( import (
"github.com/filebrowser/filebrowser/users"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -30,28 +30,28 @@ var usersLsCmd = &cobra.Command{
var findUsers = func(cmd *cobra.Command, args []string) { var findUsers = func(cmd *cobra.Command, args []string) {
db := getDB() db := getDB()
defer db.Close() defer db.Close()
st := getFileBrowser(db) st := getStorage(db)
username, _ := cmd.Flags().GetString("username") username, _ := cmd.Flags().GetString("username")
id, _ := cmd.Flags().GetUint("id") id, _ := cmd.Flags().GetUint("id")
var err error var err error
var users []*lib.User var list []*users.User
var user *lib.User var user *users.User
if username != "" { if username != "" {
user, err = st.GetUser(username) user, err = st.Users.Get(username)
} else if id != 0 { } else if id != 0 {
user, err = st.GetUser(id) user, err = st.Users.Get(id)
} else { } else {
users, err = st.GetUsers() list, err = st.Users.Gets()
} }
checkErr(err) checkErr(err)
if user != nil { if user != nil {
users = []*lib.User{user} list = []*users.User{user}
} }
printUsers(users) printUsers(list)
} }

View File

@ -1,7 +1,7 @@
package cmd package cmd
import ( import (
"github.com/filebrowser/filebrowser/users"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -23,24 +23,25 @@ var usersNewCmd = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
db := getDB() db := getDB()
defer db.Close() defer db.Close()
st := getFileBrowser(db) st := getStorage(db)
settings := st.GetSettings() s, err := st.Settings.Get()
getUserDefaults(cmd, &settings.Defaults, false) checkErr(err)
getUserDefaults(cmd, &s.Defaults, false)
password, _ := cmd.Flags().GetString("password") password, _ := cmd.Flags().GetString("password")
password, err := lib.HashPwd(password) password, err = users.HashPwd(password)
checkErr(err) checkErr(err)
user := &lib.User{ user := &users.User{
Username: mustGetString(cmd, "username"), Username: mustGetString(cmd, "username"),
Password: password, Password: password,
LockPassword: mustGetBool(cmd, "lockPassword"), LockPassword: mustGetBool(cmd, "lockPassword"),
} }
st.ApplyDefaults(user) s.Defaults.Apply(user)
err = st.SaveUser(user) err = st.Users.Save(user)
checkErr(err) checkErr(err)
printUsers([]*lib.User{user}) printUsers([]*users.User{user})
}, },
} }

View File

@ -20,7 +20,7 @@ var usersRmCmd = &cobra.Command{
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
db := getDB() db := getDB()
defer db.Close() defer db.Close()
st := getFileBrowser(db) st := getStorage(db)
username, _ := cmd.Flags().GetString("username") username, _ := cmd.Flags().GetString("username")
id, _ := cmd.Flags().GetUint("id") id, _ := cmd.Flags().GetUint("id")
@ -28,9 +28,9 @@ var usersRmCmd = &cobra.Command{
var err error var err error
if username != "" { if username != "" {
err = st.DeleteUser(username) err = st.Users.Delete(username)
} else { } else {
err = st.DeleteUser(id) err = st.Users.Delete(id)
} }
checkErr(err) checkErr(err)

View File

@ -1,7 +1,8 @@
package cmd package cmd
import ( import (
"github.com/filebrowser/filebrowser/settings"
"github.com/filebrowser/filebrowser/users"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -23,24 +24,24 @@ options you want to change.`,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
db := getDB() db := getDB()
defer db.Close() defer db.Close()
st := getFileBrowser(db) st := getStorage(db)
id, _ := cmd.Flags().GetUint("id") id, _ := cmd.Flags().GetUint("id")
username := mustGetString(cmd, "username") username := mustGetString(cmd, "username")
password := mustGetString(cmd, "password") password := mustGetString(cmd, "password")
var user *lib.User var user *users.User
var err error var err error
if id != 0 { if id != 0 {
user, err = st.GetUser(id) user, err = st.Users.Get(id)
} else { } else {
user, err = st.GetUser(username) user, err = st.Users.Get(username)
} }
checkErr(err) checkErr(err)
defaults := lib.UserDefaults{ defaults := settings.UserDefaults{
Scope: user.Scope, Scope: user.Scope,
Locale: user.Locale, Locale: user.Locale,
ViewMode: user.ViewMode, ViewMode: user.ViewMode,
@ -62,12 +63,12 @@ options you want to change.`,
} }
if password != "" { if password != "" {
user.Password, err = lib.HashPwd(password) user.Password, err = users.HashPwd(password)
checkErr(err) checkErr(err)
} }
err = st.UpdateUser(user) err = st.Users.Update(user)
checkErr(err) checkErr(err)
printUsers([]*lib.User{user}) printUsers([]*users.User{user})
}, },
} }

View File

@ -5,8 +5,8 @@ import (
"os" "os"
"github.com/asdine/storm" "github.com/asdine/storm"
"github.com/filebrowser/filebrowser/bolt" "github.com/filebrowser/filebrowser/storage"
"github.com/filebrowser/filebrowser/storage/bolt"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -38,8 +38,6 @@ func getDB() *storm.DB {
return db return db
} }
func getFileBrowser(db *storm.DB) *lib.FileBrowser { func getStorage(db *storm.DB) *storage.Storage {
fb, err := lib.NewFileBrowser(&bolt.Backend{DB: db}) return bolt.NewStorage(db)
checkErr(err)
return fb
} }

View File

@ -3,7 +3,7 @@ package cmd
import ( import (
"fmt" "fmt"
"github.com/filebrowser/filebrowser/version"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -15,6 +15,6 @@ var versionCmd = &cobra.Command{
Use: "version", Use: "version",
Short: "Print the version number", Short: "Print the version number",
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
fmt.Println("File Browser Version " + lib.Version) fmt.Println("File Browser Version " + version.Version)
}, },
} }

View File

@ -3,14 +3,15 @@ package errors
import "errors" import "errors"
var ( var (
ErrEmptyKey = errors.New("empty key") ErrEmptyKey = errors.New("empty key")
ErrExist = errors.New("the resource already exists") ErrExist = errors.New("the resource already exists")
ErrNotExist = errors.New("the resource does not exist") ErrNotExist = errors.New("the resource does not exist")
ErrEmptyPassword = errors.New("password is empty") ErrEmptyPassword = errors.New("password is empty")
ErrEmptyUsername = errors.New("username is empty") ErrEmptyUsername = errors.New("username is empty")
ErrEmptyRequest = errors.New("empty request") ErrEmptyRequest = errors.New("empty request")
ErrScopeIsRelative = errors.New("scope is a relative path") ErrScopeIsRelative = errors.New("scope is a relative path")
ErrInvalidDataType = errors.New("invalid data type") ErrInvalidDataType = errors.New("invalid data type")
ErrIsDirectory = errors.New("file is directory") ErrIsDirectory = errors.New("file is directory")
ErrInvalidOption = errors.New("invalid option") ErrInvalidOption = errors.New("invalid option")
ErrInvalidAuthMethod = errors.New("invalid auth method")
) )

View File

@ -15,10 +15,10 @@ type modifyRequest struct {
func NewHandler(storage *storage.Storage) (http.Handler, error) { func NewHandler(storage *storage.Storage) (http.Handler, error) {
r := mux.NewRouter() r := mux.NewRouter()
/* index, static := e.getStaticHandlers() index, static := getStaticHandlers(storage)
r.PathPrefix("/static").Handler(static) r.PathPrefix("/static").Handler(static)
r.NotFoundHandler = index */ r.NotFoundHandler = index
api := r.PathPrefix("/api").Subrouter() 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("/signup", handle(signupHandler, "", storage))
api.Handle("/renew", handle(renewHandler, "", storage)) api.Handle("/renew", handle(renewHandler, "", storage))
/* users := api.PathPrefix("/users").Subrouter() users := api.PathPrefix("/users").Subrouter()
users.HandleFunc("", e.auth(e.usersGetHandler)).Methods("GET") users.Handle("", handle(usersGetHandler, "", storage)).Methods("GET")
users.HandleFunc("", e.auth(e.userPostHandler)).Methods("POST") users.Handle("", handle(userPostHandler, "", storage)).Methods("POST")
users.HandleFunc("/{id:[0-9]+}", e.auth(e.userPutHandler)).Methods("PUT") users.Handle("/{id:[0-9]+}", handle(userPutHandler, "", storage)).Methods("PUT")
users.HandleFunc("/{id:[0-9]+}", e.auth(e.userGetHandler)).Methods("GET") users.Handle("/{id:[0-9]+}", handle(userGetHandler, "", storage)).Methods("GET")
users.HandleFunc("/{id:[0-9]+}", e.auth(e.userDeleteHandler)).Methods("DELETE") */ 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(resourceGetHandler, "/api/resources", storage)).Methods("GET")
api.PathPrefix("/resources").Handler(handle(resourceDeleteHandler, "/api/resources", storage)).Methods("DELETE") 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(settingsGetHandler, "", storage)).Methods("GET")
api.Handle("/settings", handle(settingsPutHandler, "", storage)).Methods("PUT") api.Handle("/settings", handle(settingsPutHandler, "", storage)).Methods("PUT")
/* api.PathPrefix("/raw").HandlerFunc(e.auth(e.rawHandler)).Methods("GET") api.PathPrefix("/raw").Handler(handle(rawHandler, "/api/raw", storage)).Methods("GET")
api.PathPrefix("/command").HandlerFunc(e.auth(e.commandsHandler)) /* api.PathPrefix("/command").HandlerFunc(e.auth(e.commandsHandler))
api.PathPrefix("/search").HandlerFunc(e.auth(e.searchHandler)) */ api.PathPrefix("/search").HandlerFunc(e.auth(e.searchHandler)) */
return r, nil return r, nil

View File

@ -1,7 +1,17 @@
package http package http
/* import (
const apiRawPrefix = "/api/raw" "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) { func parseQueryFiles(r *http.Request, f *files.FileInfo, u *users.User) ([]string, error) {
files := []string{} 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) { var rawHandler = withUser(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) {
path, user, ok := e.getResourceData(w, r, apiRawPrefix) if !d.user.Perm.Download {
if !ok { return http.StatusAccepted, nil
return
} }
if !user.Perm.Download { file, err := files.NewFileInfo(d.user.Fs, r.URL.Path, d.user.Perm.Modify, d)
httpErr(w, r, http.StatusForbidden, nil)
return
}
file, err := files.NewFileInfo(user.Fs, path, user.Perm.Modify)
if err != nil { if err != nil {
httpErr(w, r, httpFsErr(err), err) return errToStatus(err), err
return
} }
if !file.IsDir { if !file.IsDir {
fileHandler(w, r, file, user) return rawFileHandler(w, r, file)
return
} }
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 { if err != nil {
httpErr(w, r, http.StatusInternalServerError, err) return err
return }
// 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) extension, ar, err := parseQueryAlgorithm(r)
if err != nil { if err != nil {
httpErr(w, r, http.StatusInternalServerError, err) return http.StatusInternalServerError, err
return
} }
name := file.Name name := file.Name
@ -88,53 +137,24 @@ func (e *env) rawHandler(w http.ResponseWriter, r *http.Request) {
err = ar.Create(w) err = ar.Create(w)
if err != nil { if err != nil {
httpErr(w, r, http.StatusInternalServerError, err) return http.StatusInternalServerError, err
return
} }
defer ar.Close() defer ar.Close()
for _, fname := range filenames { for _, fname := range filenames {
info, err := user.Fs.Stat(fname) err = addFile(ar, d, fname)
if err != nil { if err != nil {
httpErr(w, r, http.StatusInternalServerError, err) return 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 0, nil
} }
func fileHandler(w http.ResponseWriter, r *http.Request, file *files.File, user *users.User) { func rawFileHandler(w http.ResponseWriter, r *http.Request, file *files.FileInfo) (int, error) {
fd, err := user.Fs.Open(file.Path) fd, err := file.Fs.Open(file.Path)
if err != nil { if err != nil {
httpErr(w, r, http.StatusInternalServerError, err) return http.StatusInternalServerError, err
return
} }
defer fd.Close() 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) http.ServeContent(w, r, file.Name, file.ModTime, fd)
} */ return 0, nil
}

View File

@ -15,8 +15,6 @@ import (
"github.com/filebrowser/filebrowser/fileutils" "github.com/filebrowser/filebrowser/fileutils"
) )
// TODO: trim path
var resourceGetHandler = withUser(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) { 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) file, err := files.NewFileInfo(d.user.Fs, r.URL.Path, d.user.Perm.Modify, d)
if err != nil { if err != nil {

View File

@ -1,40 +1,39 @@
package http package http
/*
import ( import (
"encoding/json" "encoding/json"
"text/template"
"log" "log"
"net/http"
"os" "os"
"path/filepath" "path/filepath"
"strings" "strings"
"github.com/GeertJohan/go.rice"
"github.com/filebrowser/filebrowser/auth" "github.com/filebrowser/filebrowser/auth"
"github.com/filebrowser/filebrowser/storage" "github.com/filebrowser/filebrowser/storage"
"github.com/filebrowser/filebrowser/version" "github.com/filebrowser/filebrowser/version"
) )
func getStaticData(storage *storage.Storage) (map[string]interface{}, error) { func handleWithStaticData(w http.ResponseWriter, r *http.Request, d *data, box *rice.Box, file, contentType string) (int, error) {
settings, err := storage.Settings.Get() w.Header().Set("Content-Type", contentType)
if err != nil {
return nil, err
}
staticURL := strings.TrimPrefix(settings.BaseURL+"/static", "/") staticURL := strings.TrimPrefix(d.settings.BaseURL+"/static", "/")
data := map[string]interface{}{ data := map[string]interface{}{
"Name": settings.Branding.Name, "Name": d.settings.Branding.Name,
"DisableExternal": settings.Branding.DisableExternal, "DisableExternal": d.settings.Branding.DisableExternal,
"BaseURL": settings.BaseURL, "BaseURL": d.settings.BaseURL,
"Version": version.Version, "Version": version.Version,
"StaticURL": staticURL, "StaticURL": staticURL,
"Signup": settings.Signup, "Signup": d.settings.Signup,
"NoAuth": settings.AuthMethod == auth.MethodNoAuth, "NoAuth": d.settings.AuthMethod == auth.MethodNoAuth,
"CSS": false, "CSS": false,
"ReCaptcha": false, "ReCaptcha": false,
} }
if settings.Branding.Files != "" { if d.settings.Branding.Files != "" {
path := filepath.Join(settings.Branding.Files, "custom.css") path := filepath.Join(d.settings.Branding.Files, "custom.css")
_, err := os.Stat(path) _, err := os.Stat(path)
if err != nil && !os.IsNotExist(err) { if err != nil && !os.IsNotExist(err) {
@ -46,10 +45,10 @@ func getStaticData(storage *storage.Storage) (map[string]interface{}, error) {
} }
} }
if settings.AuthMethod == auth.MethodJSONAuth { if d.settings.AuthMethod == auth.MethodJSONAuth {
raw, err := storage.Auth.Get() raw, err := d.store.Auth.Get(d.settings.AuthMethod)
if err != nil { if err != nil {
return nil, err return http.StatusInternalServerError, err
} }
auther := raw.(*auth.JSONAuth) 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) 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") box := rice.MustFindBox("../frontend/dist")
handler := http.FileServer(box.HTTPBox()) handler := http.FileServer(box.HTTPBox())
handleWithData := func(w http.ResponseWriter, r *http.Request, file string, contentType string) { index := handle(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) {
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) {
if r.Method != http.MethodGet { if r.Method != http.MethodGet {
httpErr(w, r, http.StatusNotFound, nil) return http.StatusNotFound, nil
return
} }
w.Header().Set("x-frame-options", "SAMEORIGIN") w.Header().Set("x-frame-options", "SAMEORIGIN")
w.Header().Set("x-xss-protection", "1; mode=block") 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) { static := handle(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) {
e.RLockSettings() if r.Method != http.MethodGet {
defer e.RUnlockSettings() return http.StatusNotFound, nil
}
if e.GetSettings().Branding.Files != "" { if d.settings.Branding.Files != "" {
if strings.HasPrefix(r.URL.Path, "img/") { 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 { if _, err := os.Stat(path); err == nil {
http.ServeFile(w, r, path) http.ServeFile(w, r, path)
return return 0, nil
} }
} else if r.URL.Path == "custom.css" && e.GetSettings().Branding.Files != "" { } else if r.URL.Path == "custom.css" && d.settings.Branding.Files != "" {
http.ServeFile(w, r, filepath.Join(e.GetSettings().Branding.Files, "custom.css")) http.ServeFile(w, r, filepath.Join(d.settings.Branding.Files, "custom.css"))
return return 0, nil
} }
} }
if !strings.HasSuffix(r.URL.Path, ".js") { if !strings.HasSuffix(r.URL.Path, ".js") {
handler.ServeHTTP(w, r) 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 return index, static
} }
*/

View File

@ -5,6 +5,7 @@ import (
"net/http" "net/http"
"sort" "sort"
"strconv" "strconv"
"strings"
"github.com/filebrowser/filebrowser/errors" "github.com/filebrowser/filebrowser/errors"
"github.com/filebrowser/filebrowser/users" "github.com/filebrowser/filebrowser/users"
@ -99,81 +100,59 @@ var userDeleteHandler = withSelfOrAdmin(func(w http.ResponseWriter, r *http.Requ
return http.StatusOK, nil return http.StatusOK, nil
}) })
/* var userPostHandler = withAdmin(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) {
req, err := getUser(w, r)
func (e *env) userPostHandler(w http.ResponseWriter, r *http.Request) { if err != nil {
_, ok := e.getAdminUser(w, r) return http.StatusBadRequest, err
if !ok {
return
}
req, ok := getUser(w, r)
if !ok {
return
} }
if len(req.Which) != 0 { if len(req.Which) != 0 {
httpErr(w, r, http.StatusBadRequest, nil) return http.StatusBadRequest, nil
return
} }
if req.Data.Password == "" { if req.Data.Password == "" {
httpErr(w, r, http.StatusBadRequest, lib.ErrEmptyPassword) return http.StatusBadRequest, errors.ErrEmptyPassword
return
} }
var err error req.Data.Password, err = users.HashPwd(req.Data.Password)
req.Data.Password, err = lib.HashPwd(req.Data.Password)
if err != nil { if err != nil {
httpErr(w, r, http.StatusInternalServerError, err) return http.StatusInternalServerError, err
return
} }
err = e.SaveUser(req.Data) err = d.store.Users.Save(req.Data)
if err != nil { if err != nil {
httpErr(w, r, http.StatusInternalServerError, err) return http.StatusInternalServerError, err
return
} }
w.Header().Set("Location", "/settings/users/"+strconv.FormatUint(uint64(req.Data.ID), 10)) 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) { var userPutHandler = withSelfOrAdmin(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) {
sessionUser, modifiedID, ok := e.userSelfOrAdmin(w, r) req, err := getUser(w, r)
if !ok { if err != nil {
return return http.StatusBadRequest, err
} }
req, ok := getUser(w, r) if req.Data.ID != d.raw.(uint) {
if !ok { return http.StatusBadRequest, nil
return
} }
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 len(req.Which) == 1 && req.Which[0] == "all" {
if !sessionUser.Perm.Admin { if !d.user.Perm.Admin {
httpErr(w, r, http.StatusForbidden, nil) return http.StatusForbidden, err
return
} }
if req.Data.Password != "" { if req.Data.Password != "" {
req.Data.Password, err = lib.HashPwd(req.Data.Password) req.Data.Password, err = users.HashPwd(req.Data.Password)
} else { } else {
var suser *users.User var suser *users.User
suser, err = e.GetUser(modifiedID) suser, err = d.store.Users.Get(d.raw.(uint))
req.Data.Password = suser.Password req.Data.Password = suser.Password
} }
if err != nil { if err != nil {
httpErr(w, r, http.StatusInternalServerError, err) return http.StatusInternalServerError, err
return
} }
req.Which = []string{} req.Which = []string{}
@ -181,28 +160,27 @@ func (e *env) userPutHandler(w http.ResponseWriter, r *http.Request) {
for k, v := range req.Which { for k, v := range req.Which {
if v == "password" { if v == "password" {
if !sessionUser.Perm.Admin && sessionUser.LockPassword { if !d.user.Perm.Admin && d.user.LockPassword {
httpErr(w, r, http.StatusForbidden, nil) return http.StatusForbidden, nil
return
} }
req.Data.Password, err = lib.HashPwd(req.Data.Password) req.Data.Password, err = users.HashPwd(req.Data.Password)
if err != nil { if err != nil {
httpErr(w, r, http.StatusInternalServerError, err) return http.StatusInternalServerError, err
return
} }
} }
if !sessionUser.Perm.Admin && (v == "scope" || v == "perm" || v == "username") { if !d.user.Perm.Admin && (v == "scope" || v == "perm" || v == "username") {
httpErr(w, r, http.StatusForbidden, nil) return http.StatusForbidden, nil
return
} }
req.Which[k] = strings.Title(v) 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 { if err != nil {
httpErr(w, r, http.StatusInternalServerError, err) return http.StatusInternalServerError, err
} }
} */
return http.StatusOK, nil
})

33
storage/bolt/auth.go Normal file
View File

@ -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)
}

View File

@ -1,9 +1,25 @@
package bolt 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 // NewStorage creates a storage.Storage based on Bolt DB.
// using Bolt DB. func NewStorage(db *storm.DB) *storage.Storage {
type Backend struct { users := users.NewStorage(usersBackend{db: db})
DB *storm.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,
}
} }

View File

@ -2,49 +2,18 @@ package bolt
import ( import (
"github.com/asdine/storm" "github.com/asdine/storm"
"github.com/filebrowser/filebrowser/auth" "github.com/filebrowser/filebrowser/settings"
) )
func (b Backend) get(name string, to interface{}) error { type settingsBackend struct {
err := b.DB.Get("config", name, to) db *storm.DB
if err == storm.ErrNotFound {
return lib.ErrNotExist
}
return err
} }
func (b Backend) save(name string, from interface{}) error { func (s settingsBackend) Get() (*settings.Settings, error) {
return b.DB.Set("config", name, from)
}
func (b Backend) GetSettings() (*settings.Settings, error) {
settings := &settings.Settings{} settings := &settings.Settings{}
return settings, b.get("settings", settings) return settings, get(s.db, "settings", settings)
} }
func (b Backend) SaveSettings(s *settings.Settings) error { func (s settingsBackend) Save(settings *settings.Settings) error {
return b.save("settings", s) return save(s.db, "settings", settings)
}
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)
} }

View File

@ -3,43 +3,48 @@ package bolt
import ( import (
"github.com/asdine/storm" "github.com/asdine/storm"
"github.com/asdine/storm/q" "github.com/asdine/storm/q"
"github.com/filebrowser/filebrowser/errors"
"github.com/filebrowser/filebrowser/share"
) )
func (s Backend) GetLinkByHash(hash string) (*lib.ShareLink, error) { type shareBackend struct {
var v lib.ShareLink db *storm.DB
err := s.DB.One("Hash", hash, &v) }
func (s shareBackend) GetByHash(hash string) (*share.Link, error) {
var v share.Link
err := s.db.One("Hash", hash, &v)
if err == storm.ErrNotFound { if err == storm.ErrNotFound {
return nil, lib.ErrNotExist return nil, errors.ErrNotExist
} }
return &v, err return &v, err
} }
func (s Backend) GetLinkPermanent(path string) (*lib.ShareLink, error) { func (s shareBackend) GetPermanent(path string) (*share.Link, error) {
var v lib.ShareLink var v share.Link
err := s.DB.Select(q.Eq("Path", path), q.Eq("Expires", false)).First(&v) err := s.db.Select(q.Eq("Path", path), q.Eq("Expires", false)).First(&v)
if err == storm.ErrNotFound { if err == storm.ErrNotFound {
return nil, lib.ErrNotExist return nil, errors.ErrNotExist
} }
return &v, err return &v, err
} }
func (s Backend) GetLinksByPath(hash string) ([]*lib.ShareLink, error) { func (s shareBackend) Gets(hash string) ([]*share.Link, error) {
var v []*lib.ShareLink var v []*share.Link
err := s.DB.Find("Path", hash, &v) err := s.db.Find("Path", hash, &v)
if err == storm.ErrNotFound { if err == storm.ErrNotFound {
return v, lib.ErrNotExist return v, errors.ErrNotExist
} }
return v, err return v, err
} }
func (s Backend) SaveLink(l *lib.ShareLink) error { func (s shareBackend) Save(l *share.Link) error {
return s.DB.Save(l) return s.db.Save(l)
} }
func (s Backend) DeleteLink(hash string) error { func (s shareBackend) Delete(hash string) error {
return s.DB.DeleteStruct(&lib.ShareLink{Hash: hash}) return s.db.DeleteStruct(&share.Link{Hash: hash})
} }

View File

@ -4,14 +4,19 @@ import (
"reflect" "reflect"
"github.com/asdine/storm" "github.com/asdine/storm"
"github.com/filebrowser/filebrowser/errors"
"github.com/filebrowser/filebrowser/users"
) )
func (st Backend) GetUserByID(id uint) (*lib.User, error) { type usersBackend struct {
user := &lib.User{} db *storm.DB
err := st.DB.One("ID", id, user) }
func (st usersBackend) GetByID(id uint) (*users.User, error) {
user := &users.User{}
err := st.db.One("ID", id, user)
if err == storm.ErrNotFound { if err == storm.ErrNotFound {
return nil, lib.ErrNotExist return nil, errors.ErrNotExist
} }
if err != nil { if err != nil {
@ -21,11 +26,11 @@ func (st Backend) GetUserByID(id uint) (*lib.User, error) {
return user, nil return user, nil
} }
func (st Backend) GetUserByUsername(username string) (*lib.User, error) { func (st usersBackend) GetByUsername(username string) (*users.User, error) {
user := &lib.User{} user := &users.User{}
err := st.DB.One("Username", username, user) err := st.db.One("Username", username, user)
if err == storm.ErrNotFound { if err == storm.ErrNotFound {
return nil, lib.ErrNotExist return nil, errors.ErrNotExist
} }
if err != nil { if err != nil {
@ -35,11 +40,11 @@ func (st Backend) GetUserByUsername(username string) (*lib.User, error) {
return user, nil return user, nil
} }
func (st Backend) GetUsers() ([]*lib.User, error) { func (st usersBackend) Gets() ([]*users.User, error) {
users := []*lib.User{} users := []*users.User{}
err := st.DB.All(&users) err := st.db.All(&users)
if err == storm.ErrNotFound { if err == storm.ErrNotFound {
return nil, lib.ErrNotExist return nil, errors.ErrNotExist
} }
if err != nil { if err != nil {
@ -49,14 +54,14 @@ func (st Backend) GetUsers() ([]*lib.User, error) {
return users, err 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 { if len(fields) == 0 {
return st.SaveUser(user) return st.Save(user)
} }
for _, field := range fields { for _, field := range fields {
val := reflect.ValueOf(user).Elem().FieldByName(field).Interface() 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 return err
} }
} }
@ -64,23 +69,23 @@ func (st Backend) UpdateUser(user *lib.User, fields ...string) error {
return nil return nil
} }
func (st Backend) SaveUser(user *lib.User) error { func (st usersBackend) Save(user *users.User) error {
err := st.DB.Save(user) err := st.db.Save(user)
if err == storm.ErrAlreadyExists { if err == storm.ErrAlreadyExists {
return lib.ErrExist return errors.ErrExist
} }
return err return err
} }
func (st Backend) DeleteUserByID(id uint) error { func (st usersBackend) DeleteByID(id uint) error {
return st.DB.DeleteStruct(&lib.User{ID: id}) return st.db.DeleteStruct(&users.User{ID: id})
} }
func (st Backend) DeleteUserByUsername(username string) error { func (st usersBackend) DeleteByUsername(username string) error {
user, err := st.GetUserByUsername(username) user, err := st.GetByUsername(username)
if err != nil { if err != nil {
return err return err
} }
return st.DB.DeleteStruct(user) return st.db.DeleteStruct(user)
} }

19
storage/bolt/utils.go Normal file
View File

@ -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)
}

View File

@ -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
}