fix: use server options from DB too (#616)

License: MIT
Signed-off-by: Henrique Dias <hacdias@gmail.com>
This commit is contained in:
Henrique Dias 2019-01-08 14:07:55 +00:00 committed by GitHub
parent 76bf72902d
commit 72069207c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 270 additions and 179 deletions

8
.filebrowser.docker.json Normal file
View File

@ -0,0 +1,8 @@
{
"port": 80,
"baseURL": "",
"address": "",
"log": "stdout",
"database": "/database.db",
"root": "/srv"
}

View File

@ -6,6 +6,7 @@ VOLUME /tmp
VOLUME /srv VOLUME /srv
EXPOSE 80 EXPOSE 80
COPY .filebrowser.docker.json /.filebrowser.json
COPY filebrowser /filebrowser COPY filebrowser /filebrowser
ENTRYPOINT [ "/filebrowser" ] ENTRYPOINT [ "/filebrowser" ]

View File

@ -17,7 +17,7 @@ var cmdsLsCmd = &cobra.Command{
Run: python(func(cmd *cobra.Command, args []string, d pythonData) { Run: python(func(cmd *cobra.Command, args []string, d pythonData) {
s, err := d.store.Settings.Get() s, err := d.store.Settings.Get()
checkErr(err) checkErr(err)
evt := mustGetString(cmd, "event") evt := mustGetString(cmd.Flags(), "event")
if evt == "" { if evt == "" {
printEvents(s.Commands) printEvents(s.Commands)

View File

@ -27,6 +27,7 @@ var configCmd = &cobra.Command{
} }
func addConfigFlags(flags *pflag.FlagSet) { func addConfigFlags(flags *pflag.FlagSet) {
addServerFlags(flags)
addUserFlags(flags) addUserFlags(flags)
flags.BoolP("signup", "s", false, "allow users to signup") flags.BoolP("signup", "s", false, "allow users to signup")
flags.String("shell", "", "shell command to which other commands should be appended") flags.String("shell", "", "shell command to which other commands should be appended")
@ -43,12 +44,12 @@ func addConfigFlags(flags *pflag.FlagSet) {
flags.Bool("branding.disableExternal", false, "disable external links such as GitHub links") flags.Bool("branding.disableExternal", false, "disable external links such as GitHub links")
} }
func getAuthentication(cmd *cobra.Command) (settings.AuthMethod, auth.Auther) { func getAuthentication(flags *pflag.FlagSet) (settings.AuthMethod, auth.Auther) {
method := settings.AuthMethod(mustGetString(cmd, "auth.method")) method := settings.AuthMethod(mustGetString(flags, "auth.method"))
var auther auth.Auther var auther auth.Auther
if method == auth.MethodProxyAuth { if method == auth.MethodProxyAuth {
header := mustGetString(cmd, "auth.header") header := mustGetString(flags, "auth.header")
if header == "" { if header == "" {
panic(nerrors.New("you must set the flag 'auth.header' for method 'proxy'")) panic(nerrors.New("you must set the flag 'auth.header' for method 'proxy'"))
} }
@ -62,9 +63,9 @@ func getAuthentication(cmd *cobra.Command) (settings.AuthMethod, auth.Auther) {
if method == auth.MethodJSONAuth { if method == auth.MethodJSONAuth {
jsonAuth := &auth.JSONAuth{} jsonAuth := &auth.JSONAuth{}
host := mustGetString(cmd, "recaptcha.host") host := mustGetString(flags, "recaptcha.host")
key := mustGetString(cmd, "recaptcha.key") key := mustGetString(flags, "recaptcha.key")
secret := mustGetString(cmd, "recaptcha.secret") secret := mustGetString(flags, "recaptcha.secret")
if key != "" && secret != "" { if key != "" && secret != "" {
jsonAuth.ReCaptcha = &auth.ReCaptcha{ jsonAuth.ReCaptcha = &auth.ReCaptcha{
@ -84,33 +85,41 @@ func getAuthentication(cmd *cobra.Command) (settings.AuthMethod, auth.Auther) {
return method, auther return method, auther
} }
func printSettings(s *settings.Settings, auther auth.Auther) { func printSettings(ser *settings.Server, set *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, "Sign up:\t%t\n", s.Signup) fmt.Fprintf(w, "Sign up:\t%t\n", set.Signup)
fmt.Fprintf(w, "Auth method:\t%s\n", s.AuthMethod) fmt.Fprintf(w, "Auth method:\t%s\n", set.AuthMethod)
fmt.Fprintf(w, "Shell:\t%s\t\n", strings.Join(s.Shell, " ")) fmt.Fprintf(w, "Shell:\t%s\t\n", strings.Join(set.Shell, " "))
fmt.Fprintln(w, "\nBranding:") fmt.Fprintln(w, "\nBranding:")
fmt.Fprintf(w, "\tName:\t%s\n", s.Branding.Name) fmt.Fprintf(w, "\tName:\t%s\n", set.Branding.Name)
fmt.Fprintf(w, "\tFiles override:\t%s\n", s.Branding.Files) fmt.Fprintf(w, "\tFiles override:\t%s\n", set.Branding.Files)
fmt.Fprintf(w, "\tDisable external links:\t%t\n", s.Branding.DisableExternal) fmt.Fprintf(w, "\tDisable external links:\t%t\n", set.Branding.DisableExternal)
fmt.Fprintln(w, "\nServer:")
fmt.Fprintf(w, "\tLog:\t%s\n", ser.Log)
fmt.Fprintf(w, "\tPort:\t%s\n", ser.Port)
fmt.Fprintf(w, "\tBase URL:\t%s\n", ser.BaseURL)
fmt.Fprintf(w, "\tRoot:\t%s\n", ser.Root)
fmt.Fprintf(w, "\tAddress:\t%s\n", ser.Address)
fmt.Fprintf(w, "\tTLS Cert:\t%s\n", ser.TLSCert)
fmt.Fprintf(w, "\tTLS Key:\t%s\n", ser.TLSKey)
fmt.Fprintln(w, "\nDefaults:") fmt.Fprintln(w, "\nDefaults:")
fmt.Fprintf(w, "\tScope:\t%s\n", s.Defaults.Scope) fmt.Fprintf(w, "\tScope:\t%s\n", set.Defaults.Scope)
fmt.Fprintf(w, "\tLocale:\t%s\n", s.Defaults.Locale) fmt.Fprintf(w, "\tLocale:\t%s\n", set.Defaults.Locale)
fmt.Fprintf(w, "\tView mode:\t%s\n", s.Defaults.ViewMode) fmt.Fprintf(w, "\tView mode:\t%s\n", set.Defaults.ViewMode)
fmt.Fprintf(w, "\tCommands:\t%s\n", strings.Join(s.Defaults.Commands, " ")) fmt.Fprintf(w, "\tCommands:\t%s\n", strings.Join(set.Defaults.Commands, " "))
fmt.Fprintf(w, "\tSorting:\n") fmt.Fprintf(w, "\tSorting:\n")
fmt.Fprintf(w, "\t\tBy:\t%s\n", s.Defaults.Sorting.By) fmt.Fprintf(w, "\t\tBy:\t%s\n", set.Defaults.Sorting.By)
fmt.Fprintf(w, "\t\tAsc:\t%t\n", s.Defaults.Sorting.Asc) fmt.Fprintf(w, "\t\tAsc:\t%t\n", set.Defaults.Sorting.Asc)
fmt.Fprintf(w, "\tPermissions:\n") fmt.Fprintf(w, "\tPermissions:\n")
fmt.Fprintf(w, "\t\tAdmin:\t%t\n", s.Defaults.Perm.Admin) fmt.Fprintf(w, "\t\tAdmin:\t%t\n", set.Defaults.Perm.Admin)
fmt.Fprintf(w, "\t\tExecute:\t%t\n", s.Defaults.Perm.Execute) fmt.Fprintf(w, "\t\tExecute:\t%t\n", set.Defaults.Perm.Execute)
fmt.Fprintf(w, "\t\tCreate:\t%t\n", s.Defaults.Perm.Create) fmt.Fprintf(w, "\t\tCreate:\t%t\n", set.Defaults.Perm.Create)
fmt.Fprintf(w, "\t\tRename:\t%t\n", s.Defaults.Perm.Rename) fmt.Fprintf(w, "\t\tRename:\t%t\n", set.Defaults.Perm.Rename)
fmt.Fprintf(w, "\t\tModify:\t%t\n", s.Defaults.Perm.Modify) fmt.Fprintf(w, "\t\tModify:\t%t\n", set.Defaults.Perm.Modify)
fmt.Fprintf(w, "\t\tDelete:\t%t\n", s.Defaults.Perm.Delete) fmt.Fprintf(w, "\t\tDelete:\t%t\n", set.Defaults.Perm.Delete)
fmt.Fprintf(w, "\t\tShare:\t%t\n", s.Defaults.Perm.Share) fmt.Fprintf(w, "\t\tShare:\t%t\n", set.Defaults.Perm.Share)
fmt.Fprintf(w, "\t\tDownload:\t%t\n", s.Defaults.Perm.Download) fmt.Fprintf(w, "\t\tDownload:\t%t\n", set.Defaults.Perm.Download)
w.Flush() w.Flush()
b, err := json.MarshalIndent(auther, "", " ") b, err := json.MarshalIndent(auther, "", " ")

View File

@ -14,10 +14,12 @@ var configCatCmd = &cobra.Command{
Long: `Prints the configuration.`, Long: `Prints the configuration.`,
Args: cobra.NoArgs, Args: cobra.NoArgs,
Run: python(func(cmd *cobra.Command, args []string, d pythonData) { Run: python(func(cmd *cobra.Command, args []string, d pythonData) {
s, err := d.store.Settings.Get() set, err := d.store.Settings.Get()
checkErr(err) checkErr(err)
auther, err := d.store.Auth.Get(s.AuthMethod) ser, err := d.store.Settings.GetServer()
checkErr(err) checkErr(err)
printSettings(s, auther) auther, err := d.store.Auth.Get(set.AuthMethod)
checkErr(err)
printSettings(ser, set, auther)
}, pythonConfig{}), }, pythonConfig{}),
} }

View File

@ -16,12 +16,16 @@ var configExportCmd = &cobra.Command{
settings, err := d.store.Settings.Get() settings, err := d.store.Settings.Get()
checkErr(err) checkErr(err)
server, err := d.store.Settings.GetServer()
checkErr(err)
auther, err := d.store.Auth.Get(settings.AuthMethod) auther, err := d.store.Auth.Get(settings.AuthMethod)
checkErr(err) checkErr(err)
data := &settingsFile{ data := &settingsFile{
Settings: settings, Settings: settings,
Auther: auther, Auther: auther,
Server: server,
} }
err = marshal(args[0], data) err = marshal(args[0], data)

View File

@ -3,6 +3,7 @@ package cmd
import ( import (
"encoding/json" "encoding/json"
"errors" "errors"
"path/filepath"
"reflect" "reflect"
"github.com/filebrowser/filebrowser/v2/auth" "github.com/filebrowser/filebrowser/v2/auth"
@ -16,6 +17,7 @@ func init() {
type settingsFile struct { type settingsFile struct {
Settings *settings.Settings `json:"settings"` Settings *settings.Settings `json:"settings"`
Server *settings.Server `json:"server"`
Auther interface{} `json:"auther"` Auther interface{} `json:"auther"`
} }
@ -45,23 +47,32 @@ database.`,
err = d.store.Settings.Save(file.Settings) err = d.store.Settings.Save(file.Settings)
checkErr(err) checkErr(err)
autherInterf := cleanUpInterfaceMap(file.Auther.(map[interface{}]interface{})) err = d.store.Settings.SaveServer(file.Server)
checkErr(err)
var rawAuther interface{}
if filepath.Ext(args[0]) != ".json" {
rawAuther = cleanUpInterfaceMap(file.Auther.(map[interface{}]interface{}))
} else {
rawAuther = file.Auther
}
var auther auth.Auther var auther auth.Auther
switch file.Settings.AuthMethod { switch file.Settings.AuthMethod {
case auth.MethodJSONAuth: case auth.MethodJSONAuth:
auther = getAuther(auth.JSONAuth{}, autherInterf).(*auth.JSONAuth) auther = getAuther(auth.JSONAuth{}, rawAuther).(*auth.JSONAuth)
case auth.MethodNoAuth: case auth.MethodNoAuth:
auther = getAuther(auth.NoAuth{}, autherInterf).(*auth.NoAuth) auther = getAuther(auth.NoAuth{}, rawAuther).(*auth.NoAuth)
case auth.MethodProxyAuth: case auth.MethodProxyAuth:
auther = getAuther(auth.ProxyAuth{}, autherInterf).(*auth.ProxyAuth) auther = getAuther(auth.ProxyAuth{}, rawAuther).(*auth.ProxyAuth)
default: default:
checkErr(errors.New("invalid auth method")) checkErr(errors.New("invalid auth method"))
} }
err = d.store.Auth.Save(auther) err = d.store.Auth.Save(auther)
checkErr(err) checkErr(err)
printSettings(file.Settings, auther)
printSettings(file.Server, file.Settings, auther)
}, pythonConfig{allowNoDB: true}), }, pythonConfig{allowNoDB: true}),
} }

View File

@ -24,24 +24,37 @@ override the options.`,
Args: cobra.NoArgs, Args: cobra.NoArgs,
Run: python(func(cmd *cobra.Command, args []string, d pythonData) { Run: python(func(cmd *cobra.Command, args []string, d pythonData) {
defaults := settings.UserDefaults{} defaults := settings.UserDefaults{}
getUserDefaults(cmd, &defaults, true) flags := cmd.Flags()
authMethod, auther := getAuthentication(cmd) getUserDefaults(flags, &defaults, true)
authMethod, auther := getAuthentication(flags)
s := &settings.Settings{ s := &settings.Settings{
Key: generateRandomBytes(64), // 256 bit Key: generateRandomBytes(64), // 256 bit
Signup: mustGetBool(cmd, "signup"), Signup: mustGetBool(flags, "signup"),
Shell: strings.Split(strings.TrimSpace(mustGetString(cmd, "shell")), " "), Shell: strings.Split(strings.TrimSpace(mustGetString(flags, "shell")), " "),
AuthMethod: authMethod, AuthMethod: authMethod,
Defaults: defaults, Defaults: defaults,
Branding: settings.Branding{ Branding: settings.Branding{
Name: mustGetString(cmd, "branding.name"), Name: mustGetString(flags, "branding.name"),
DisableExternal: mustGetBool(cmd, "branding.disableExternal"), DisableExternal: mustGetBool(flags, "branding.disableExternal"),
Files: mustGetString(cmd, "branding.files"), Files: mustGetString(flags, "branding.files"),
}, },
} }
ser := &settings.Server{
Address: mustGetString(flags, "address"),
Root: mustGetString(flags, "root"),
BaseURL: mustGetString(flags, "baseurl"),
TLSKey: mustGetString(flags, "key"),
TLSCert: mustGetString(flags, "cert"),
Port: mustGetString(flags, "port"),
Log: mustGetString(flags, "log"),
}
err := d.store.Settings.Save(s) err := d.store.Settings.Save(s)
checkErr(err) checkErr(err)
err = d.store.Settings.SaveServer(ser)
checkErr(err)
err = d.store.Auth.Save(auther) err = d.store.Auth.Save(auther)
checkErr(err) checkErr(err)
@ -50,6 +63,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(s, auther) printSettings(ser, s, auther)
}, pythonConfig{noDB: true}), }, pythonConfig{noDB: true}),
} }

View File

@ -20,41 +20,61 @@ var configSetCmd = &cobra.Command{
you want to change.`, you want to change.`,
Args: cobra.NoArgs, Args: cobra.NoArgs,
Run: python(func(cmd *cobra.Command, args []string, d pythonData) { Run: python(func(cmd *cobra.Command, args []string, d pythonData) {
s, err := d.store.Settings.Get() flags := cmd.Flags()
set, err := d.store.Settings.Get()
checkErr(err)
ser, err := d.store.Settings.GetServer()
checkErr(err) checkErr(err)
hasAuth := false hasAuth := false
cmd.Flags().Visit(func(flag *pflag.Flag) { flags.Visit(func(flag *pflag.Flag) {
switch flag.Name { switch flag.Name {
case "baseurl":
ser.BaseURL = mustGetString(flags, flag.Name)
case "root":
ser.Root = mustGetString(flags, flag.Name)
case "cert":
ser.TLSCert = mustGetString(flags, flag.Name)
case "key":
ser.TLSKey = mustGetString(flags, flag.Name)
case "address":
ser.Address = mustGetString(flags, flag.Name)
case "port":
ser.Port = mustGetString(flags, flag.Name)
case "log":
ser.Log = mustGetString(flags, flag.Name)
case "signup": case "signup":
s.Signup = mustGetBool(cmd, flag.Name) set.Signup = mustGetBool(flags, flag.Name)
case "auth.method": case "auth.method":
hasAuth = true hasAuth = true
case "shell": case "shell":
s.Shell = strings.Split(strings.TrimSpace(mustGetString(cmd, flag.Name)), " ") set.Shell = strings.Split(strings.TrimSpace(mustGetString(flags, flag.Name)), " ")
case "branding.name": case "branding.name":
s.Branding.Name = mustGetString(cmd, flag.Name) set.Branding.Name = mustGetString(flags, flag.Name)
case "branding.disableExternal": case "branding.disableExternal":
s.Branding.DisableExternal = mustGetBool(cmd, flag.Name) set.Branding.DisableExternal = mustGetBool(flags, flag.Name)
case "branding.files": case "branding.files":
s.Branding.Files = mustGetString(cmd, flag.Name) set.Branding.Files = mustGetString(flags, flag.Name)
} }
}) })
getUserDefaults(cmd, &s.Defaults, false) getUserDefaults(flags, &set.Defaults, false)
var auther auth.Auther var auther auth.Auther
if hasAuth { if hasAuth {
s.AuthMethod, auther = getAuthentication(cmd) set.AuthMethod, auther = getAuthentication(flags)
err = d.store.Auth.Save(auther) err = d.store.Auth.Save(auther)
checkErr(err) checkErr(err)
} else { } else {
auther, err = d.store.Auth.Get(s.AuthMethod) auther, err = d.store.Auth.Get(set.AuthMethod)
checkErr(err) checkErr(err)
} }
err = d.store.Settings.Save(s) err = d.store.Settings.Save(set)
checkErr(err) checkErr(err)
printSettings(s, auther) err = d.store.Settings.SaveServer(ser)
checkErr(err)
printSettings(ser, set, auther)
}, pythonConfig{}), }, pythonConfig{}),
} }

View File

@ -40,7 +40,7 @@ var docsCmd = &cobra.Command{
Hidden: true, Hidden: true,
Args: cobra.NoArgs, Args: cobra.NoArgs,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
dir := mustGetString(cmd, "path") dir := mustGetString(cmd.Flags(), "path")
generateDocs(rootCmd, dir) generateDocs(rootCmd, dir)
names := []string{} names := []string{}

View File

@ -18,6 +18,7 @@ import (
"github.com/filebrowser/filebrowser/v2/users" "github.com/filebrowser/filebrowser/v2/users"
"github.com/mitchellh/go-homedir" "github.com/mitchellh/go-homedir"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/pflag"
v "github.com/spf13/viper" v "github.com/spf13/viper"
lumberjack "gopkg.in/natefinch/lumberjack.v2" lumberjack "gopkg.in/natefinch/lumberjack.v2"
) )
@ -28,29 +29,61 @@ var (
func init() { func init() {
cobra.OnInitialize(initConfig) cobra.OnInitialize(initConfig)
flags := rootCmd.Flags()
persistent := rootCmd.PersistentFlags()
f := rootCmd.Flags() persistent.StringVarP(&cfgFile, "config", "c", "", "config file path")
pf := rootCmd.PersistentFlags() persistent.StringP("database", "d", "./filebrowser.db", "database path")
flags.String("username", "admin", "username for the first user when using quick config")
flags.String("password", "", "hashed password for the first user when using quick config (default \"admin\")")
pf.StringVarP(&cfgFile, "config", "c", "", "config file path") addServerFlags(flags)
vaddP(pf, "database", "d", "./filebrowser.db", "path to the database")
vaddP(f, "address", "a", "127.0.0.1", "address to listen on")
vaddP(f, "log", "l", "stdout", "log output")
vaddP(f, "port", "p", "8080", "port to listen on")
vaddP(f, "cert", "t", "", "tls certificate")
vaddP(f, "key", "k", "", "tls key")
vaddP(f, "root", "r", ".", "root to prepend to relative paths")
vaddP(f, "baseurl", "b", "", "base url")
vadd(f, "username", "admin", "username for the first user when using quick config")
vadd(f, "password", "", "hashed password for the first user when using quick config (default \"admin\")")
if err := v.BindPFlags(f); err != nil {
panic(err)
} }
if err := v.BindPFlags(pf); err != nil { func addServerFlags(flags *pflag.FlagSet) {
panic(err) flags.StringP("address", "a", "127.0.0.1", "address to listen on")
flags.StringP("log", "l", "stdout", "log output")
flags.StringP("port", "p", "8080", "port to listen on")
flags.StringP("cert", "t", "", "tls certificate")
flags.StringP("key", "k", "", "tls key")
flags.StringP("root", "r", ".", "root to prepend to relative paths")
flags.StringP("baseurl", "b", "", "base url")
} }
// NOTE: we could simply bind the flags to viper and use IsSet.
// Although there is a bug on Viper that always returns true on IsSet
// if a flag is binded. Our alternative way is to manually check
// the flag and then the value from env/config/gotten by viper.
// https://github.com/spf13/viper/pull/331
func getStringViperFlag(flags *pflag.FlagSet, key string) (string, bool) {
value := ""
set := false
// If set on Flags, use it.
flags.Visit(func(flag *pflag.Flag) {
if flag.Name == key {
set = true
value, _ = flags.GetString(key)
}
})
if set {
return value, set
}
// If set through viper (env, config), return it.
if v.IsSet(key) {
return v.GetString(key), true
}
// Otherwise use default value on flags.
value, _ = flags.GetString(key)
return value, false
}
func mustGetStringViperFlag(flags *pflag.FlagSet, key string) string {
val, _ := getStringViperFlag(flags, key)
return val
} }
var rootCmd = &cobra.Command{ var rootCmd = &cobra.Command{
@ -92,10 +125,10 @@ the quick setup mode and a new database will be bootstraped and a new
user created with the credentials from options "username" and "password".`, user created with the credentials from options "username" and "password".`,
Run: python(func(cmd *cobra.Command, args []string, d pythonData) { Run: python(func(cmd *cobra.Command, args []string, d pythonData) {
if !d.hadDB { if !d.hadDB {
quickSetup(d) quickSetup(cmd.Flags(), d)
} }
server := getServer(d.store) server := getServerWithViper(cmd.Flags(), d.store)
setupLog(server.Log) setupLog(server.Log)
handler, err := fbhttp.NewHandler(d.store, server) handler, err := fbhttp.NewHandler(d.store, server)
@ -121,27 +154,40 @@ user created with the credentials from options "username" and "password".`,
}, pythonConfig{allowNoDB: true}), }, pythonConfig{allowNoDB: true}),
} }
// TODO: get server settings and only replace func getServerWithViper(flags *pflag.FlagSet, st *storage.Storage) *settings.Server {
// them if set on Viper. Although viper.IsSet server, err := st.Settings.GetServer()
// is bugged and if binded to a pflag, it will checkErr(err)
// always return true.
// Also, when doing that, add this options to if val, set := getStringViperFlag(flags, "root"); set {
// config init, config import, printConfig root, err := filepath.Abs(val)
// and config set since the DB values will actually
// be used. For now, despite being stored in the DB,
// they won't be used.
func getServer(st *storage.Storage) *settings.Server {
root := v.GetString("root")
root, err := filepath.Abs(root)
checkErr(err) checkErr(err)
server := &settings.Server{}
server.BaseURL = v.GetString("baseurl")
server.Root = root server.Root = root
server.Address = v.GetString("address") }
server.Port = v.GetString("port")
server.TLSKey = v.GetString("key") if val, set := getStringViperFlag(flags, "baseurl"); set {
server.TLSCert = v.GetString("cert") server.BaseURL = val
server.Log = v.GetString("log") }
if val, set := getStringViperFlag(flags, "address"); set {
server.Address = val
}
if val, set := getStringViperFlag(flags, "port"); set {
server.Port = val
}
if val, set := getStringViperFlag(flags, "log"); set {
server.Log = val
}
if val, set := getStringViperFlag(flags, "key"); set {
server.TLSKey = val
}
if val, set := getStringViperFlag(flags, "cert"); set {
server.TLSCert = val
}
return server return server
} }
@ -164,7 +210,7 @@ func setupLog(logMethod string) {
} }
func quickSetup(d pythonData) { func quickSetup(flags *pflag.FlagSet, d pythonData) {
set := &settings.Settings{ set := &settings.Settings{
Key: generateRandomBytes(64), // 256 bit Key: generateRandomBytes(64), // 256 bit
Signup: false, Signup: false,
@ -186,12 +232,13 @@ func quickSetup(d pythonData) {
} }
ser := &settings.Server{ ser := &settings.Server{
BaseURL: v.GetString("baseurl"), BaseURL: mustGetStringViperFlag(flags, "baseurl"),
Log: v.GetString("log"), Port: mustGetStringViperFlag(flags, "port"),
TLSKey: v.GetString("key"), Log: mustGetStringViperFlag(flags, "log"),
TLSCert: v.GetString("cert"), TLSKey: mustGetStringViperFlag(flags, "key"),
Address: v.GetString("address"), TLSCert: mustGetStringViperFlag(flags, "cert"),
Root: v.GetString("root"), Address: mustGetStringViperFlag(flags, "address"),
Root: mustGetStringViperFlag(flags, "root"),
} }
err := d.store.Settings.Save(set) err := d.store.Settings.Save(set)
@ -203,8 +250,8 @@ func quickSetup(d pythonData) {
err = d.store.Auth.Save(&auth.JSONAuth{}) err = d.store.Auth.Save(&auth.JSONAuth{})
checkErr(err) checkErr(err)
username := v.GetString("username") username := mustGetStringViperFlag(flags, "username")
password := v.GetString("password") password := mustGetStringViperFlag(flags, "password")
if password == "" { if password == "" {
password, err = users.HashPwd("admin") password, err = users.HashPwd("admin")

View File

@ -8,6 +8,7 @@ import (
"github.com/filebrowser/filebrowser/v2/storage" "github.com/filebrowser/filebrowser/v2/storage"
"github.com/filebrowser/filebrowser/v2/users" "github.com/filebrowser/filebrowser/v2/users"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/pflag"
) )
func init() { func init() {
@ -28,7 +29,7 @@ rules.`,
} }
func runRules(st *storage.Storage, cmd *cobra.Command, users func(*users.User), global func(*settings.Settings)) { func runRules(st *storage.Storage, cmd *cobra.Command, users func(*users.User), global func(*settings.Settings)) {
id := getUserIdentifier(cmd) id := getUserIdentifier(cmd.Flags())
if id != nil { if id != nil {
user, err := st.Users.Get("", id) user, err := st.Users.Get("", id)
checkErr(err) checkErr(err)
@ -51,9 +52,9 @@ func runRules(st *storage.Storage, cmd *cobra.Command, users func(*users.User),
printRules(settings.Rules, id) printRules(settings.Rules, id)
} }
func getUserIdentifier(cmd *cobra.Command) interface{} { func getUserIdentifier(flags *pflag.FlagSet) interface{} {
id := mustGetUint(cmd, "id") id := mustGetUint(flags, "id")
username := mustGetString(cmd, "username") username := mustGetString(flags, "username")
if id != 0 { if id != 0 {
return id return id

View File

@ -21,8 +21,8 @@ var rulesAddCmd = &cobra.Command{
Long: `Add a global rule or user rule.`, Long: `Add a global rule or user rule.`,
Args: cobra.ExactArgs(1), Args: cobra.ExactArgs(1),
Run: python(func(cmd *cobra.Command, args []string, d pythonData) { Run: python(func(cmd *cobra.Command, args []string, d pythonData) {
allow := mustGetBool(cmd, "allow") allow := mustGetBool(cmd.Flags(), "allow")
regex := mustGetBool(cmd, "regex") regex := mustGetBool(cmd.Flags(), "regex")
exp := args[0] exp := args[0]
if regex { if regex {

View File

@ -3,7 +3,6 @@ package cmd
import ( import (
"github.com/filebrowser/filebrowser/v2/storage/bolt/importer" "github.com/filebrowser/filebrowser/v2/storage/bolt/importer"
"github.com/spf13/cobra" "github.com/spf13/cobra"
v "github.com/spf13/viper"
) )
func init() { func init() {
@ -22,10 +21,10 @@ import share links because they are incompatible with
this version.`, this version.`,
Args: cobra.NoArgs, Args: cobra.NoArgs,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
oldDB := mustGetString(cmd, "old.database") flags := cmd.Flags()
oldConf := mustGetString(cmd, "old.config") oldDB := mustGetString(flags, "old.database")
oldConf := mustGetString(flags, "old.config")
err := importer.Import(oldDB, oldConf, v.GetString("database")) err := importer.Import(oldDB, oldConf, mustGetStringViperFlag(flags, "database"))
checkErr(err) checkErr(err)
}, },
} }

View File

@ -76,53 +76,53 @@ func addUserFlags(flags *pflag.FlagSet) {
flags.String("viewMode", string(users.ListViewMode), "view mode for users") flags.String("viewMode", string(users.ListViewMode), "view mode for users")
} }
func getViewMode(cmd *cobra.Command) users.ViewMode { func getViewMode(flags *pflag.FlagSet) users.ViewMode {
viewMode := users.ViewMode(mustGetString(cmd, "viewMode")) viewMode := users.ViewMode(mustGetString(flags, "viewMode"))
if viewMode != users.ListViewMode && viewMode != users.MosaicViewMode { if viewMode != users.ListViewMode && viewMode != users.MosaicViewMode {
checkErr(errors.New("view mode must be \"" + string(users.ListViewMode) + "\" or \"" + string(users.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 *settings.UserDefaults, all bool) { func getUserDefaults(flags *pflag.FlagSet, 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":
defaults.Scope = mustGetString(cmd, flag.Name) defaults.Scope = mustGetString(flags, flag.Name)
case "locale": case "locale":
defaults.Locale = mustGetString(cmd, flag.Name) defaults.Locale = mustGetString(flags, flag.Name)
case "viewMode": case "viewMode":
defaults.ViewMode = getViewMode(cmd) defaults.ViewMode = getViewMode(flags)
case "perm.admin": case "perm.admin":
defaults.Perm.Admin = mustGetBool(cmd, flag.Name) defaults.Perm.Admin = mustGetBool(flags, flag.Name)
case "perm.execute": case "perm.execute":
defaults.Perm.Execute = mustGetBool(cmd, flag.Name) defaults.Perm.Execute = mustGetBool(flags, flag.Name)
case "perm.create": case "perm.create":
defaults.Perm.Create = mustGetBool(cmd, flag.Name) defaults.Perm.Create = mustGetBool(flags, flag.Name)
case "perm.rename": case "perm.rename":
defaults.Perm.Rename = mustGetBool(cmd, flag.Name) defaults.Perm.Rename = mustGetBool(flags, flag.Name)
case "perm.modify": case "perm.modify":
defaults.Perm.Modify = mustGetBool(cmd, flag.Name) defaults.Perm.Modify = mustGetBool(flags, flag.Name)
case "perm.delete": case "perm.delete":
defaults.Perm.Delete = mustGetBool(cmd, flag.Name) defaults.Perm.Delete = mustGetBool(flags, flag.Name)
case "perm.share": case "perm.share":
defaults.Perm.Share = mustGetBool(cmd, flag.Name) defaults.Perm.Share = mustGetBool(flags, flag.Name)
case "perm.download": case "perm.download":
defaults.Perm.Download = mustGetBool(cmd, flag.Name) defaults.Perm.Download = mustGetBool(flags, flag.Name)
case "commands": case "commands":
commands, err := cmd.Flags().GetStringSlice(flag.Name) commands, err := flags.GetStringSlice(flag.Name)
checkErr(err) checkErr(err)
defaults.Commands = commands defaults.Commands = commands
case "sorting.by": case "sorting.by":
defaults.Sorting.By = mustGetString(cmd, flag.Name) defaults.Sorting.By = mustGetString(flags, flag.Name)
case "sorting.asc": case "sorting.asc":
defaults.Sorting.Asc = mustGetBool(cmd, flag.Name) defaults.Sorting.Asc = mustGetBool(flags, flag.Name)
} }
} }
if all { if all {
cmd.Flags().VisitAll(visit) flags.VisitAll(visit)
} else { } else {
cmd.Flags().Visit(visit) flags.Visit(visit)
} }
} }

View File

@ -18,7 +18,7 @@ var usersAddCmd = &cobra.Command{
Run: python(func(cmd *cobra.Command, args []string, d pythonData) { Run: python(func(cmd *cobra.Command, args []string, d pythonData) {
s, err := d.store.Settings.Get() s, err := d.store.Settings.Get()
checkErr(err) checkErr(err)
getUserDefaults(cmd, &s.Defaults, false) getUserDefaults(cmd.Flags(), &s.Defaults, false)
password, err := users.HashPwd(args[1]) password, err := users.HashPwd(args[1])
checkErr(err) checkErr(err)
@ -26,7 +26,7 @@ var usersAddCmd = &cobra.Command{
user := &users.User{ user := &users.User{
Username: args[0], Username: args[0],
Password: password, Password: password,
LockPassword: mustGetBool(cmd, "lockPassword"), LockPassword: mustGetBool(cmd.Flags(), "lockPassword"),
} }
s.Defaults.Apply(user) s.Defaults.Apply(user)

View File

@ -33,7 +33,7 @@ var usersImportCmd = &cobra.Command{
checkErr(err) checkErr(err)
} }
if mustGetBool(cmd, "replace") { if mustGetBool(cmd.Flags(), "replace") {
oldUsers, err := d.store.Users.Gets("") oldUsers, err := d.store.Users.Gets("")
checkErr(err) checkErr(err)
@ -46,7 +46,7 @@ var usersImportCmd = &cobra.Command{
} }
} }
overwrite := mustGetBool(cmd, "overwrite") overwrite := mustGetBool(cmd.Flags(), "overwrite")
for _, user := range list { for _, user := range list {
onDB, err := d.store.Users.Get("", user.ID) onDB, err := d.store.Users.Get("", user.ID)

View File

@ -22,8 +22,9 @@ options you want to change.`,
Args: cobra.ExactArgs(1), Args: cobra.ExactArgs(1),
Run: python(func(cmd *cobra.Command, args []string, d pythonData) { Run: python(func(cmd *cobra.Command, args []string, d pythonData) {
username, id := parseUsernameOrID(args[0]) username, id := parseUsernameOrID(args[0])
password := mustGetString(cmd, "password") flags := cmd.Flags()
newUsername := mustGetString(cmd, "username") password := mustGetString(flags, "password")
newUsername := mustGetString(flags, "username")
var err error var err error
var user *users.User var user *users.User
@ -44,14 +45,14 @@ options you want to change.`,
Sorting: user.Sorting, Sorting: user.Sorting,
Commands: user.Commands, Commands: user.Commands,
} }
getUserDefaults(cmd, &defaults, false) getUserDefaults(flags, &defaults, false)
user.Scope = defaults.Scope user.Scope = defaults.Scope
user.Locale = defaults.Locale user.Locale = defaults.Locale
user.ViewMode = defaults.ViewMode user.ViewMode = defaults.ViewMode
user.Perm = defaults.Perm user.Perm = defaults.Perm
user.Commands = defaults.Commands user.Commands = defaults.Commands
user.Sorting = defaults.Sorting user.Sorting = defaults.Sorting
user.LockPassword = mustGetBool(cmd, "lockPassword") user.LockPassword = mustGetBool(flags, "lockPassword")
if newUsername != "" { if newUsername != "" {
user.Username = newUsername user.Username = newUsername

View File

@ -14,34 +14,9 @@ import (
"github.com/filebrowser/filebrowser/v2/storage/bolt" "github.com/filebrowser/filebrowser/v2/storage/bolt"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/pflag" "github.com/spf13/pflag"
v "github.com/spf13/viper"
yaml "gopkg.in/yaml.v2" yaml "gopkg.in/yaml.v2"
) )
func vaddP(f *pflag.FlagSet, k, p string, i interface{}, u string) {
switch y := i.(type) {
case bool:
f.BoolP(k, p, y, u)
case int:
f.IntP(k, p, y, u)
case string:
f.StringP(k, p, y, u)
}
v.SetDefault(k, i)
}
func vadd(f *pflag.FlagSet, k string, i interface{}, u string) {
switch y := i.(type) {
case bool:
f.Bool(k, y, u)
case int:
f.Int(k, y, u)
case string:
f.String(k, y, u)
}
v.SetDefault(k, i)
}
func checkErr(err error) { func checkErr(err error) {
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
@ -49,20 +24,20 @@ func checkErr(err error) {
} }
} }
func mustGetString(cmd *cobra.Command, flag string) string { func mustGetString(flags *pflag.FlagSet, flag string) string {
s, err := cmd.Flags().GetString(flag) s, err := flags.GetString(flag)
checkErr(err) checkErr(err)
return s return s
} }
func mustGetBool(cmd *cobra.Command, flag string) bool { func mustGetBool(flags *pflag.FlagSet, flag string) bool {
b, err := cmd.Flags().GetBool(flag) b, err := flags.GetBool(flag)
checkErr(err) checkErr(err)
return b return b
} }
func mustGetUint(cmd *cobra.Command, flag string) uint { func mustGetUint(flags *pflag.FlagSet, flag string) uint {
b, err := cmd.Flags().GetUint(flag) b, err := flags.GetUint(flag)
checkErr(err) checkErr(err)
return b return b
} }
@ -92,7 +67,7 @@ func python(fn pythonFunc, cfg pythonConfig) cobraFunc {
return func(cmd *cobra.Command, args []string) { return func(cmd *cobra.Command, args []string) {
data := pythonData{hadDB: true} data := pythonData{hadDB: true}
path := v.GetString("database") path := mustGetStringViperFlag(cmd.Flags(), "database")
_, err := os.Stat(path) _, err := os.Stat(path)
if os.IsNotExist(err) { if os.IsNotExist(err) {