mirror of
https://github.com/filebrowser/filebrowser.git
synced 2025-07-30 03:40:26 +00:00
feat: better error handling for sys kill signals
This commit is contained in:
parent
21ad653b7e
commit
1582b8b2cd
10
cmd/cmd.go
10
cmd/cmd.go
@ -1,12 +1,6 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Execute executes the commands.
|
// Execute executes the commands.
|
||||||
func Execute() {
|
func Execute() error {
|
||||||
if err := rootCmd.Execute(); err != nil {
|
return rootCmd.Execute()
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -15,13 +15,18 @@ var cmdsAddCmd = &cobra.Command{
|
|||||||
Short: "Add a command to run on a specific event",
|
Short: "Add a command to run on a specific event",
|
||||||
Long: `Add a command to run on a specific event.`,
|
Long: `Add a command to run on a specific event.`,
|
||||||
Args: cobra.MinimumNArgs(2),
|
Args: cobra.MinimumNArgs(2),
|
||||||
Run: python(func(_ *cobra.Command, args []string, d pythonData) {
|
RunE: python(func(_ *cobra.Command, args []string, d *pythonData) error {
|
||||||
s, err := d.store.Settings.Get()
|
s, err := d.store.Settings.Get()
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
command := strings.Join(args[1:], " ")
|
command := strings.Join(args[1:], " ")
|
||||||
s.Commands[args[0]] = append(s.Commands[args[0]], command)
|
s.Commands[args[0]] = append(s.Commands[args[0]], command)
|
||||||
err = d.store.Settings.Save(s)
|
err = d.store.Settings.Save(s)
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
printEvents(s.Commands)
|
printEvents(s.Commands)
|
||||||
|
return nil
|
||||||
}, pythonConfig{}),
|
}, pythonConfig{}),
|
||||||
}
|
}
|
||||||
|
@ -14,10 +14,15 @@ var cmdsLsCmd = &cobra.Command{
|
|||||||
Short: "List all commands for each event",
|
Short: "List all commands for each event",
|
||||||
Long: `List all commands for each event.`,
|
Long: `List all commands for each event.`,
|
||||||
Args: cobra.NoArgs,
|
Args: cobra.NoArgs,
|
||||||
Run: python(func(cmd *cobra.Command, _ []string, d pythonData) {
|
RunE: python(func(cmd *cobra.Command, _ []string, d *pythonData) error {
|
||||||
s, err := d.store.Settings.Get()
|
s, err := d.store.Settings.Get()
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
evt := mustGetString(cmd.Flags(), "event")
|
return err
|
||||||
|
}
|
||||||
|
evt, err := getString(cmd.Flags(), "event")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if evt == "" {
|
if evt == "" {
|
||||||
printEvents(s.Commands)
|
printEvents(s.Commands)
|
||||||
@ -27,5 +32,6 @@ var cmdsLsCmd = &cobra.Command{
|
|||||||
show["after_"+evt] = s.Commands["after_"+evt]
|
show["after_"+evt] = s.Commands["after_"+evt]
|
||||||
printEvents(show)
|
printEvents(show)
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}, pythonConfig{}),
|
}, pythonConfig{}),
|
||||||
}
|
}
|
||||||
|
@ -35,22 +35,31 @@ including 'index_end'.`,
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
Run: python(func(_ *cobra.Command, args []string, d pythonData) {
|
RunE: python(func(_ *cobra.Command, args []string, d *pythonData) error {
|
||||||
s, err := d.store.Settings.Get()
|
s, err := d.store.Settings.Get()
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
evt := args[0]
|
evt := args[0]
|
||||||
|
|
||||||
i, err := strconv.Atoi(args[1])
|
i, err := strconv.Atoi(args[1])
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
f := i
|
f := i
|
||||||
if len(args) == 3 {
|
if len(args) == 3 {
|
||||||
f, err = strconv.Atoi(args[2])
|
f, err = strconv.Atoi(args[2])
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s.Commands[evt] = append(s.Commands[evt][:i], s.Commands[evt][f+1:]...)
|
s.Commands[evt] = append(s.Commands[evt][:i], s.Commands[evt][f+1:]...)
|
||||||
err = d.store.Settings.Save(s)
|
err = d.store.Settings.Save(s)
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
printEvents(s.Commands)
|
printEvents(s.Commands)
|
||||||
|
return nil
|
||||||
}, pythonConfig{}),
|
}, pythonConfig{}),
|
||||||
}
|
}
|
||||||
|
193
cmd/config.go
193
cmd/config.go
@ -55,9 +55,12 @@ func addConfigFlags(flags *pflag.FlagSet) {
|
|||||||
flags.String("dir-mode", fmt.Sprintf("%O", settings.DefaultDirMode), "Mode bits that new directories are created with")
|
flags.String("dir-mode", fmt.Sprintf("%O", settings.DefaultDirMode), "Mode bits that new directories are created with")
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:gocyclo
|
func getAuthMethod(flags *pflag.FlagSet, defaults ...interface{}) (settings.AuthMethod, map[string]interface{}, error) {
|
||||||
func getAuthentication(flags *pflag.FlagSet, defaults ...interface{}) (settings.AuthMethod, auth.Auther) {
|
methodStr, err := getString(flags, "auth.method")
|
||||||
method := settings.AuthMethod(mustGetString(flags, "auth.method"))
|
if err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
|
method := settings.AuthMethod(methodStr)
|
||||||
|
|
||||||
var defaultAuther map[string]interface{}
|
var defaultAuther map[string]interface{}
|
||||||
if len(defaults) > 0 {
|
if len(defaults) > 0 {
|
||||||
@ -68,83 +71,124 @@ func getAuthentication(flags *pflag.FlagSet, defaults ...interface{}) (settings.
|
|||||||
method = def.AuthMethod
|
method = def.AuthMethod
|
||||||
case auth.Auther:
|
case auth.Auther:
|
||||||
ms, err := json.Marshal(def)
|
ms, err := json.Marshal(def)
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
err = json.Unmarshal(ms, &defaultAuther)
|
err = json.Unmarshal(ms, &defaultAuther)
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var auther auth.Auther
|
return method, defaultAuther, nil
|
||||||
if method == auth.MethodProxyAuth {
|
|
||||||
header := mustGetString(flags, "auth.header")
|
|
||||||
|
|
||||||
if header == "" {
|
|
||||||
header = defaultAuther["header"].(string)
|
|
||||||
}
|
|
||||||
|
|
||||||
if header == "" {
|
|
||||||
checkErr(nerrors.New("you must set the flag 'auth.header' for method 'proxy'"))
|
|
||||||
}
|
|
||||||
|
|
||||||
auther = &auth.ProxyAuth{Header: header}
|
|
||||||
}
|
|
||||||
|
|
||||||
if method == auth.MethodNoAuth {
|
|
||||||
auther = &auth.NoAuth{}
|
|
||||||
}
|
|
||||||
|
|
||||||
if method == auth.MethodJSONAuth {
|
|
||||||
jsonAuth := &auth.JSONAuth{}
|
|
||||||
host := mustGetString(flags, "recaptcha.host")
|
|
||||||
key := mustGetString(flags, "recaptcha.key")
|
|
||||||
secret := mustGetString(flags, "recaptcha.secret")
|
|
||||||
|
|
||||||
if key == "" {
|
|
||||||
if kmap, ok := defaultAuther["recaptcha"].(map[string]interface{}); ok {
|
|
||||||
key = kmap["key"].(string)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if secret == "" {
|
|
||||||
if smap, ok := defaultAuther["recaptcha"].(map[string]interface{}); ok {
|
|
||||||
secret = smap["secret"].(string)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if key != "" && secret != "" {
|
|
||||||
jsonAuth.ReCaptcha = &auth.ReCaptcha{
|
|
||||||
Host: host,
|
|
||||||
Key: key,
|
|
||||||
Secret: secret,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
auther = jsonAuth
|
|
||||||
}
|
|
||||||
|
|
||||||
if method == auth.MethodHookAuth {
|
|
||||||
command := mustGetString(flags, "auth.command")
|
|
||||||
|
|
||||||
if command == "" {
|
|
||||||
command = defaultAuther["command"].(string)
|
|
||||||
}
|
|
||||||
|
|
||||||
if command == "" {
|
|
||||||
checkErr(nerrors.New("you must set the flag 'auth.command' for method 'hook'"))
|
|
||||||
}
|
|
||||||
|
|
||||||
auther = &auth.HookAuth{Command: command}
|
|
||||||
}
|
|
||||||
|
|
||||||
if auther == nil {
|
|
||||||
panic(errors.ErrInvalidAuthMethod)
|
|
||||||
}
|
|
||||||
|
|
||||||
return method, auther
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func printSettings(ser *settings.Server, set *settings.Settings, auther auth.Auther) {
|
func getProxyAuth(flags *pflag.FlagSet, defaultAuther map[string]interface{}) (auth.Auther, error) {
|
||||||
|
header, err := getString(flags, "auth.header")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if header == "" {
|
||||||
|
header = defaultAuther["header"].(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
if header == "" {
|
||||||
|
return nil, nerrors.New("you must set the flag 'auth.header' for method 'proxy'")
|
||||||
|
}
|
||||||
|
|
||||||
|
return &auth.ProxyAuth{Header: header}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getNoAuth() auth.Auther {
|
||||||
|
return &auth.NoAuth{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getJSONAuth(flags *pflag.FlagSet, defaultAuther map[string]interface{}) (auth.Auther, error) {
|
||||||
|
jsonAuth := &auth.JSONAuth{}
|
||||||
|
host, err := getString(flags, "recaptcha.host")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
key, err := getString(flags, "recaptcha.key")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
secret, err := getString(flags, "recaptcha.secret")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if key == "" {
|
||||||
|
if kmap, ok := defaultAuther["recaptcha"].(map[string]interface{}); ok {
|
||||||
|
key = kmap["key"].(string)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if secret == "" {
|
||||||
|
if smap, ok := defaultAuther["recaptcha"].(map[string]interface{}); ok {
|
||||||
|
secret = smap["secret"].(string)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if key != "" && secret != "" {
|
||||||
|
jsonAuth.ReCaptcha = &auth.ReCaptcha{
|
||||||
|
Host: host,
|
||||||
|
Key: key,
|
||||||
|
Secret: secret,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return jsonAuth, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getHookAuth(flags *pflag.FlagSet, defaultAuther map[string]interface{}) (auth.Auther, error) {
|
||||||
|
command, err := getString(flags, "auth.command")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if command == "" {
|
||||||
|
command = defaultAuther["command"].(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
if command == "" {
|
||||||
|
return nil, nerrors.New("you must set the flag 'auth.command' for method 'hook'")
|
||||||
|
}
|
||||||
|
|
||||||
|
return &auth.HookAuth{Command: command}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getAuthentication(flags *pflag.FlagSet, defaults ...interface{}) (settings.AuthMethod, auth.Auther, error) {
|
||||||
|
method, defaultAuther, err := getAuthMethod(flags, defaults...)
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var auther auth.Auther
|
||||||
|
switch method {
|
||||||
|
case auth.MethodProxyAuth:
|
||||||
|
auther, err = getProxyAuth(flags, defaultAuther)
|
||||||
|
case auth.MethodNoAuth:
|
||||||
|
auther = getNoAuth()
|
||||||
|
case auth.MethodJSONAuth:
|
||||||
|
auther, err = getJSONAuth(flags, defaultAuther)
|
||||||
|
case auth.MethodHookAuth:
|
||||||
|
auther, err = getHookAuth(flags, defaultAuther)
|
||||||
|
default:
|
||||||
|
return "", nil, errors.ErrInvalidAuthMethod
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return method, auther, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func printSettings(ser *settings.Server, set *settings.Settings, auther auth.Auther) error {
|
||||||
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", set.Signup)
|
fmt.Fprintf(w, "Sign up:\t%t\n", set.Signup)
|
||||||
@ -192,6 +236,9 @@ func printSettings(ser *settings.Server, set *settings.Settings, auther auth.Aut
|
|||||||
w.Flush()
|
w.Flush()
|
||||||
|
|
||||||
b, err := json.MarshalIndent(auther, "", " ")
|
b, err := json.MarshalIndent(auther, "", " ")
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
fmt.Printf("\nAuther configuration (raw):\n\n%s\n\n", string(b))
|
fmt.Printf("\nAuther configuration (raw):\n\n%s\n\n", string(b))
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -13,13 +13,19 @@ var configCatCmd = &cobra.Command{
|
|||||||
Short: "Prints the configuration",
|
Short: "Prints the configuration",
|
||||||
Long: `Prints the configuration.`,
|
Long: `Prints the configuration.`,
|
||||||
Args: cobra.NoArgs,
|
Args: cobra.NoArgs,
|
||||||
Run: python(func(_ *cobra.Command, _ []string, d pythonData) {
|
RunE: python(func(_ *cobra.Command, _ []string, d *pythonData) error {
|
||||||
set, err := d.store.Settings.Get()
|
set, err := d.store.Settings.Get()
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
ser, err := d.store.Settings.GetServer()
|
ser, err := d.store.Settings.GetServer()
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
auther, err := d.store.Auth.Get(set.AuthMethod)
|
auther, err := d.store.Auth.Get(set.AuthMethod)
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
printSettings(ser, set, auther)
|
return err
|
||||||
|
}
|
||||||
|
return printSettings(ser, set, auther)
|
||||||
}, pythonConfig{}),
|
}, pythonConfig{}),
|
||||||
}
|
}
|
||||||
|
@ -15,15 +15,21 @@ var configExportCmd = &cobra.Command{
|
|||||||
json or yaml file. This exported configuration can be changed,
|
json or yaml file. This exported configuration can be changed,
|
||||||
and imported again with 'config import' command.`,
|
and imported again with 'config import' command.`,
|
||||||
Args: jsonYamlArg,
|
Args: jsonYamlArg,
|
||||||
Run: python(func(_ *cobra.Command, args []string, d pythonData) {
|
RunE: python(func(_ *cobra.Command, args []string, d *pythonData) error {
|
||||||
settings, err := d.store.Settings.Get()
|
settings, err := d.store.Settings.Get()
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
server, err := d.store.Settings.GetServer()
|
server, err := d.store.Settings.GetServer()
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
auther, err := d.store.Auth.Get(settings.AuthMethod)
|
auther, err := d.store.Auth.Get(settings.AuthMethod)
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
data := &settingsFile{
|
data := &settingsFile{
|
||||||
Settings: settings,
|
Settings: settings,
|
||||||
@ -32,6 +38,9 @@ and imported again with 'config import' command.`,
|
|||||||
}
|
}
|
||||||
|
|
||||||
err = marshal(args[0], data)
|
err = marshal(args[0], data)
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}, pythonConfig{}),
|
}, pythonConfig{}),
|
||||||
}
|
}
|
||||||
|
@ -34,26 +34,35 @@ database.
|
|||||||
|
|
||||||
The path must be for a json or yaml file.`,
|
The path must be for a json or yaml file.`,
|
||||||
Args: jsonYamlArg,
|
Args: jsonYamlArg,
|
||||||
Run: python(func(_ *cobra.Command, args []string, d pythonData) {
|
RunE: python(func(_ *cobra.Command, args []string, d *pythonData) error {
|
||||||
var key []byte
|
var key []byte
|
||||||
|
var err error
|
||||||
if d.hadDB {
|
if d.hadDB {
|
||||||
settings, err := d.store.Settings.Get()
|
settings, settingErr := d.store.Settings.Get()
|
||||||
checkErr(err)
|
if settingErr != nil {
|
||||||
|
return settingErr
|
||||||
|
}
|
||||||
key = settings.Key
|
key = settings.Key
|
||||||
} else {
|
} else {
|
||||||
key = generateKey()
|
key = generateKey()
|
||||||
}
|
}
|
||||||
|
|
||||||
file := settingsFile{}
|
file := settingsFile{}
|
||||||
err := unmarshal(args[0], &file)
|
err = unmarshal(args[0], &file)
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
file.Settings.Key = key
|
file.Settings.Key = key
|
||||||
err = d.store.Settings.Save(file.Settings)
|
err = d.store.Settings.Save(file.Settings)
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
err = d.store.Settings.SaveServer(file.Server)
|
err = d.store.Settings.SaveServer(file.Server)
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
var rawAuther interface{}
|
var rawAuther interface{}
|
||||||
if filepath.Ext(args[0]) != ".json" {
|
if filepath.Ext(args[0]) != ".json" {
|
||||||
@ -63,32 +72,51 @@ The path must be for a json or yaml file.`,
|
|||||||
}
|
}
|
||||||
|
|
||||||
var auther auth.Auther
|
var auther auth.Auther
|
||||||
|
var autherErr error
|
||||||
switch file.Settings.AuthMethod {
|
switch file.Settings.AuthMethod {
|
||||||
case auth.MethodJSONAuth:
|
case auth.MethodJSONAuth:
|
||||||
auther = getAuther(auth.JSONAuth{}, rawAuther).(*auth.JSONAuth)
|
var a interface{}
|
||||||
|
a, autherErr = getAuther(auth.JSONAuth{}, rawAuther)
|
||||||
|
auther = a.(*auth.JSONAuth)
|
||||||
case auth.MethodNoAuth:
|
case auth.MethodNoAuth:
|
||||||
auther = getAuther(auth.NoAuth{}, rawAuther).(*auth.NoAuth)
|
var a interface{}
|
||||||
|
a, autherErr = getAuther(auth.NoAuth{}, rawAuther)
|
||||||
|
auther = a.(*auth.NoAuth)
|
||||||
case auth.MethodProxyAuth:
|
case auth.MethodProxyAuth:
|
||||||
auther = getAuther(auth.ProxyAuth{}, rawAuther).(*auth.ProxyAuth)
|
var a interface{}
|
||||||
|
a, autherErr = getAuther(auth.ProxyAuth{}, rawAuther)
|
||||||
|
auther = a.(*auth.ProxyAuth)
|
||||||
case auth.MethodHookAuth:
|
case auth.MethodHookAuth:
|
||||||
auther = getAuther(&auth.HookAuth{}, rawAuther).(*auth.HookAuth)
|
var a interface{}
|
||||||
|
a, autherErr = getAuther(&auth.HookAuth{}, rawAuther)
|
||||||
|
auther = a.(*auth.HookAuth)
|
||||||
default:
|
default:
|
||||||
checkErr(errors.New("invalid auth method"))
|
return errors.New("invalid auth method")
|
||||||
|
}
|
||||||
|
|
||||||
|
if autherErr != nil {
|
||||||
|
return autherErr
|
||||||
}
|
}
|
||||||
|
|
||||||
err = d.store.Auth.Save(auther)
|
err = d.store.Auth.Save(auther)
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
printSettings(file.Server, file.Settings, auther)
|
return printSettings(file.Server, file.Settings, auther)
|
||||||
}, pythonConfig{allowNoDB: true}),
|
}, pythonConfig{allowNoDB: true}),
|
||||||
}
|
}
|
||||||
|
|
||||||
func getAuther(sample auth.Auther, data interface{}) interface{} {
|
func getAuther(sample auth.Auther, data interface{}) (interface{}, error) {
|
||||||
authType := reflect.TypeOf(sample)
|
authType := reflect.TypeOf(sample)
|
||||||
auther := reflect.New(authType).Interface()
|
auther := reflect.New(authType).Interface()
|
||||||
bytes, err := json.Marshal(data)
|
bytes, err := json.Marshal(data)
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
err = json.Unmarshal(bytes, &auther)
|
err = json.Unmarshal(bytes, &auther)
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
return auther
|
return nil, err
|
||||||
|
}
|
||||||
|
return auther, nil
|
||||||
}
|
}
|
||||||
|
@ -22,54 +22,161 @@ this options can be changed in the future with the command
|
|||||||
to the defaults when creating new users and you don't
|
to the defaults when creating new users and you don't
|
||||||
override the options.`,
|
override the options.`,
|
||||||
Args: cobra.NoArgs,
|
Args: cobra.NoArgs,
|
||||||
Run: python(func(cmd *cobra.Command, _ []string, d pythonData) {
|
RunE: python(func(cmd *cobra.Command, _ []string, d *pythonData) error {
|
||||||
defaults := settings.UserDefaults{}
|
defaults := settings.UserDefaults{}
|
||||||
flags := cmd.Flags()
|
flags := cmd.Flags()
|
||||||
getUserDefaults(flags, &defaults, true)
|
err := getUserDefaults(flags, &defaults, true)
|
||||||
authMethod, auther := getAuthentication(flags)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
authMethod, auther, err := getAuthentication(flags)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
key := generateKey()
|
||||||
|
|
||||||
|
signup, err := getBool(flags, "signup")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
createUserDir, err := getBool(flags, "create-user-dir")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
minLength, err := getUint(flags, "minimum-password-length")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
shell, err := getString(flags, "shell")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
brandingName, err := getString(flags, "branding.name")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
brandingDisableExternal, err := getBool(flags, "branding.disableExternal")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
brandingDisableUsedPercentage, err := getBool(flags, "branding.disableUsedPercentage")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
brandingTheme, err := getString(flags, "branding.theme")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
brandingFiles, err := getString(flags, "branding.files")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
s := &settings.Settings{
|
s := &settings.Settings{
|
||||||
Key: generateKey(),
|
Key: key,
|
||||||
Signup: mustGetBool(flags, "signup"),
|
Signup: signup,
|
||||||
CreateUserDir: mustGetBool(flags, "create-user-dir"),
|
CreateUserDir: createUserDir,
|
||||||
MinimumPasswordLength: mustGetUint(flags, "minimum-password-length"),
|
MinimumPasswordLength: minLength,
|
||||||
Shell: convertCmdStrToCmdArray(mustGetString(flags, "shell")),
|
Shell: convertCmdStrToCmdArray(shell),
|
||||||
AuthMethod: authMethod,
|
AuthMethod: authMethod,
|
||||||
Defaults: defaults,
|
Defaults: defaults,
|
||||||
Branding: settings.Branding{
|
Branding: settings.Branding{
|
||||||
Name: mustGetString(flags, "branding.name"),
|
Name: brandingName,
|
||||||
DisableExternal: mustGetBool(flags, "branding.disableExternal"),
|
DisableExternal: brandingDisableExternal,
|
||||||
DisableUsedPercentage: mustGetBool(flags, "branding.disableUsedPercentage"),
|
DisableUsedPercentage: brandingDisableUsedPercentage,
|
||||||
Theme: mustGetString(flags, "branding.theme"),
|
Theme: brandingTheme,
|
||||||
Files: mustGetString(flags, "branding.files"),
|
Files: brandingFiles,
|
||||||
},
|
},
|
||||||
FileMode: mustGetMode(flags, "file-mode"),
|
}
|
||||||
DirMode: mustGetMode(flags, "dir-mode"),
|
|
||||||
|
s.FileMode, err = getMode(flags, "file-mode")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
s.DirMode, err = getMode(flags, "file-mode")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
address, err := getString(flags, "address")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
socket, err := getString(flags, "socket")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
root, err := getString(flags, "root")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
baseURL, err := getString(flags, "baseurl")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
tlsKey, err := getString(flags, "key")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
cert, err := getString(flags, "cert")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
port, err := getString(flags, "port")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
log, err := getString(flags, "log")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
ser := &settings.Server{
|
ser := &settings.Server{
|
||||||
Address: mustGetString(flags, "address"),
|
Address: address,
|
||||||
Socket: mustGetString(flags, "socket"),
|
Socket: socket,
|
||||||
Root: mustGetString(flags, "root"),
|
Root: root,
|
||||||
BaseURL: mustGetString(flags, "baseurl"),
|
BaseURL: baseURL,
|
||||||
TLSKey: mustGetString(flags, "key"),
|
TLSKey: tlsKey,
|
||||||
TLSCert: mustGetString(flags, "cert"),
|
TLSCert: cert,
|
||||||
Port: mustGetString(flags, "port"),
|
Port: port,
|
||||||
Log: mustGetString(flags, "log"),
|
Log: log,
|
||||||
}
|
}
|
||||||
|
|
||||||
err := d.store.Settings.Save(s)
|
err = d.store.Settings.Save(s)
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
err = d.store.Settings.SaveServer(ser)
|
err = d.store.Settings.SaveServer(ser)
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
err = d.store.Auth.Save(auther)
|
err = d.store.Auth.Save(auther)
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
fmt.Printf(`
|
fmt.Printf(`
|
||||||
Congratulations! You've set up your database to use with File Browser.
|
Congratulations! You've set up your database to use with File Browser.
|
||||||
Now add your first user via 'filebrowser users add' and then you just
|
Now add your first user via 'filebrowser users add' 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(ser, s, auther)
|
return printSettings(ser, s, auther)
|
||||||
}, pythonConfig{noDB: true}),
|
}, pythonConfig{noDB: true}),
|
||||||
}
|
}
|
||||||
|
@ -16,77 +16,105 @@ var configSetCmd = &cobra.Command{
|
|||||||
Long: `Updates the configuration. Set the flags for the options
|
Long: `Updates the configuration. Set the flags for the options
|
||||||
you want to change. Other options will remain unchanged.`,
|
you want to change. Other options will remain unchanged.`,
|
||||||
Args: cobra.NoArgs,
|
Args: cobra.NoArgs,
|
||||||
Run: python(func(cmd *cobra.Command, _ []string, d pythonData) {
|
RunE: python(func(cmd *cobra.Command, _ []string, d *pythonData) error {
|
||||||
flags := cmd.Flags()
|
flags := cmd.Flags()
|
||||||
set, err := d.store.Settings.Get()
|
set, err := d.store.Settings.Get()
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
ser, err := d.store.Settings.GetServer()
|
ser, err := d.store.Settings.GetServer()
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
hasAuth := false
|
hasAuth := false
|
||||||
flags.Visit(func(flag *pflag.Flag) {
|
flags.Visit(func(flag *pflag.Flag) {
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
switch flag.Name {
|
switch flag.Name {
|
||||||
case "baseurl":
|
case "baseurl":
|
||||||
ser.BaseURL = mustGetString(flags, flag.Name)
|
ser.BaseURL, err = getString(flags, flag.Name)
|
||||||
case "root":
|
case "root":
|
||||||
ser.Root = mustGetString(flags, flag.Name)
|
ser.Root, err = getString(flags, flag.Name)
|
||||||
case "socket":
|
case "socket":
|
||||||
ser.Socket = mustGetString(flags, flag.Name)
|
ser.Socket, err = getString(flags, flag.Name)
|
||||||
case "cert":
|
case "cert":
|
||||||
ser.TLSCert = mustGetString(flags, flag.Name)
|
ser.TLSCert, err = getString(flags, flag.Name)
|
||||||
case "key":
|
case "key":
|
||||||
ser.TLSKey = mustGetString(flags, flag.Name)
|
ser.TLSKey, err = getString(flags, flag.Name)
|
||||||
case "address":
|
case "address":
|
||||||
ser.Address = mustGetString(flags, flag.Name)
|
ser.Address, err = getString(flags, flag.Name)
|
||||||
case "port":
|
case "port":
|
||||||
ser.Port = mustGetString(flags, flag.Name)
|
ser.Port, err = getString(flags, flag.Name)
|
||||||
case "log":
|
case "log":
|
||||||
ser.Log = mustGetString(flags, flag.Name)
|
ser.Log, err = getString(flags, flag.Name)
|
||||||
case "signup":
|
case "signup":
|
||||||
set.Signup = mustGetBool(flags, flag.Name)
|
set.Signup, err = getBool(flags, flag.Name)
|
||||||
case "auth.method":
|
case "auth.method":
|
||||||
hasAuth = true
|
hasAuth = true
|
||||||
case "shell":
|
case "shell":
|
||||||
set.Shell = convertCmdStrToCmdArray(mustGetString(flags, flag.Name))
|
var shell string
|
||||||
|
shell, err = getString(flags, flag.Name)
|
||||||
|
set.Shell = convertCmdStrToCmdArray(shell)
|
||||||
case "create-user-dir":
|
case "create-user-dir":
|
||||||
set.CreateUserDir = mustGetBool(flags, flag.Name)
|
set.CreateUserDir, err = getBool(flags, flag.Name)
|
||||||
case "minimum-password-length":
|
case "minimum-password-length":
|
||||||
set.MinimumPasswordLength = mustGetUint(flags, flag.Name)
|
set.MinimumPasswordLength, err = getUint(flags, flag.Name)
|
||||||
case "branding.name":
|
case "branding.name":
|
||||||
set.Branding.Name = mustGetString(flags, flag.Name)
|
set.Branding.Name, err = getString(flags, flag.Name)
|
||||||
case "branding.color":
|
case "branding.color":
|
||||||
set.Branding.Color = mustGetString(flags, flag.Name)
|
set.Branding.Color, err = getString(flags, flag.Name)
|
||||||
case "branding.theme":
|
case "branding.theme":
|
||||||
set.Branding.Theme = mustGetString(flags, flag.Name)
|
set.Branding.Theme, err = getString(flags, flag.Name)
|
||||||
case "branding.disableExternal":
|
case "branding.disableExternal":
|
||||||
set.Branding.DisableExternal = mustGetBool(flags, flag.Name)
|
set.Branding.DisableExternal, err = getBool(flags, flag.Name)
|
||||||
case "branding.disableUsedPercentage":
|
case "branding.disableUsedPercentage":
|
||||||
set.Branding.DisableUsedPercentage = mustGetBool(flags, flag.Name)
|
set.Branding.DisableUsedPercentage, err = getBool(flags, flag.Name)
|
||||||
case "branding.files":
|
case "branding.files":
|
||||||
set.Branding.Files = mustGetString(flags, flag.Name)
|
set.Branding.Files, err = getString(flags, flag.Name)
|
||||||
case "file-mode":
|
case "file-mode":
|
||||||
set.FileMode = mustGetMode(flags, flag.Name)
|
set.FileMode, err = getMode(flags, flag.Name)
|
||||||
case "dir-mode":
|
case "dir-mode":
|
||||||
set.DirMode = mustGetMode(flags, flag.Name)
|
set.DirMode, err = getMode(flags, flag.Name)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
getUserDefaults(flags, &set.Defaults, false)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = getUserDefaults(flags, &set.Defaults, false)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// read the defaults
|
// read the defaults
|
||||||
auther, err := d.store.Auth.Get(set.AuthMethod)
|
auther, err := d.store.Auth.Get(set.AuthMethod)
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// check if there are new flags for existing auth method
|
// check if there are new flags for existing auth method
|
||||||
set.AuthMethod, auther = getAuthentication(flags, hasAuth, set, auther)
|
set.AuthMethod, auther, err = getAuthentication(flags, hasAuth, set, auther)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
err = d.store.Auth.Save(auther)
|
err = d.store.Auth.Save(auther)
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
err = d.store.Settings.Save(set)
|
err = d.store.Settings.Save(set)
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
err = d.store.Settings.SaveServer(ser)
|
err = d.store.Settings.SaveServer(ser)
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
printSettings(ser, set, auther)
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return printSettings(ser, set, auther)
|
||||||
}, pythonConfig{}),
|
}, pythonConfig{}),
|
||||||
}
|
}
|
||||||
|
37
cmd/docs.go
37
cmd/docs.go
@ -39,12 +39,19 @@ var docsCmd = &cobra.Command{
|
|||||||
Use: "docs",
|
Use: "docs",
|
||||||
Hidden: true,
|
Hidden: true,
|
||||||
Args: cobra.NoArgs,
|
Args: cobra.NoArgs,
|
||||||
Run: func(cmd *cobra.Command, _ []string) {
|
RunE: func(cmd *cobra.Command, _ []string) error {
|
||||||
dir := mustGetString(cmd.Flags(), "path")
|
dir, err := getString(cmd.Flags(), "path")
|
||||||
generateDocs(rootCmd, dir)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = generateDocs(rootCmd, dir)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
names := []string{}
|
names := []string{}
|
||||||
|
|
||||||
err := filepath.Walk(dir, func(_ string, info os.FileInfo, err error) error {
|
err = filepath.Walk(dir, func(_ string, info os.FileInfo, err error) error {
|
||||||
if err != nil || info.IsDir() {
|
if err != nil || info.IsDir() {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -56,30 +63,38 @@ var docsCmd = &cobra.Command{
|
|||||||
names = append(names, info.Name())
|
names = append(names, info.Name())
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
checkErr(err)
|
|
||||||
printToc(names)
|
printToc(names)
|
||||||
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateDocs(cmd *cobra.Command, dir string) {
|
func generateDocs(cmd *cobra.Command, dir string) error {
|
||||||
for _, c := range cmd.Commands() {
|
for _, c := range cmd.Commands() {
|
||||||
if !c.IsAvailableCommand() || c.IsAdditionalHelpTopicCommand() {
|
if !c.IsAvailableCommand() || c.IsAdditionalHelpTopicCommand() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
generateDocs(c, dir)
|
err := generateDocs(c, dir)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
basename := strings.Replace(cmd.CommandPath(), " ", "-", -1) + ".md"
|
basename := strings.Replace(cmd.CommandPath(), " ", "-", -1) + ".md"
|
||||||
filename := filepath.Join(dir, basename)
|
filename := filepath.Join(dir, basename)
|
||||||
f, err := os.Create(filename)
|
f, err := os.Create(filename)
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
generateMarkdown(cmd, f)
|
return generateMarkdown(cmd, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateMarkdown(cmd *cobra.Command, w io.Writer) {
|
func generateMarkdown(cmd *cobra.Command, w io.Writer) error {
|
||||||
cmd.InitDefaultHelpCmd()
|
cmd.InitDefaultHelpCmd()
|
||||||
cmd.InitDefaultHelpFlag()
|
cmd.InitDefaultHelpFlag()
|
||||||
|
|
||||||
@ -108,7 +123,7 @@ func generateMarkdown(cmd *cobra.Command, w io.Writer) {
|
|||||||
|
|
||||||
printOptions(buf, cmd)
|
printOptions(buf, cmd)
|
||||||
_, err := buf.WriteTo(w)
|
_, err := buf.WriteTo(w)
|
||||||
checkErr(err)
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateFlagsTable(fs *pflag.FlagSet, buf io.StringWriter) {
|
func generateFlagsTable(fs *pflag.FlagSet, buf io.StringWriter) {
|
||||||
|
@ -17,9 +17,12 @@ var hashCmd = &cobra.Command{
|
|||||||
Short: "Hashes a password",
|
Short: "Hashes a password",
|
||||||
Long: `Hashes a password using bcrypt algorithm.`,
|
Long: `Hashes a password using bcrypt algorithm.`,
|
||||||
Args: cobra.ExactArgs(1),
|
Args: cobra.ExactArgs(1),
|
||||||
Run: func(_ *cobra.Command, args []string) {
|
RunE: func(_ *cobra.Command, args []string) error {
|
||||||
pwd, err := users.HashPwd(args[0])
|
pwd, err := users.HashPwd(args[0])
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
fmt.Println(pwd)
|
fmt.Println(pwd)
|
||||||
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
122
cmd/root.go
122
cmd/root.go
@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"log"
|
"log"
|
||||||
@ -25,6 +26,7 @@ import (
|
|||||||
|
|
||||||
"github.com/filebrowser/filebrowser/v2/auth"
|
"github.com/filebrowser/filebrowser/v2/auth"
|
||||||
"github.com/filebrowser/filebrowser/v2/diskcache"
|
"github.com/filebrowser/filebrowser/v2/diskcache"
|
||||||
|
fbErrors "github.com/filebrowser/filebrowser/v2/errors"
|
||||||
"github.com/filebrowser/filebrowser/v2/frontend"
|
"github.com/filebrowser/filebrowser/v2/frontend"
|
||||||
fbhttp "github.com/filebrowser/filebrowser/v2/http"
|
fbhttp "github.com/filebrowser/filebrowser/v2/http"
|
||||||
"github.com/filebrowser/filebrowser/v2/img"
|
"github.com/filebrowser/filebrowser/v2/img"
|
||||||
@ -39,6 +41,7 @@ var (
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
cobra.OnInitialize(initConfig)
|
cobra.OnInitialize(initConfig)
|
||||||
|
rootCmd.SilenceUsage = true
|
||||||
cobra.MousetrapHelpText = ""
|
cobra.MousetrapHelpText = ""
|
||||||
|
|
||||||
rootCmd.SetVersionTemplate("File Browser version {{printf \"%s\" .Version}}\n")
|
rootCmd.SetVersionTemplate("File Browser version {{printf \"%s\" .Version}}\n")
|
||||||
@ -112,36 +115,48 @@ set FB_DATABASE.
|
|||||||
Also, if the database path doesn't exist, File Browser will enter into
|
Also, if the database path doesn't exist, File Browser will enter into
|
||||||
the quick setup mode and a new database will be bootstrapped and a new
|
the quick setup mode and a new database will be bootstrapped 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, _ []string, d pythonData) {
|
RunE: python(func(cmd *cobra.Command, _ []string, d *pythonData) error {
|
||||||
log.Println(cfgFile)
|
log.Println(cfgFile)
|
||||||
|
|
||||||
if !d.hadDB {
|
if !d.hadDB {
|
||||||
quickSetup(cmd.Flags(), d)
|
err := quickSetup(cmd.Flags(), *d)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// build img service
|
// build img service
|
||||||
workersCount, err := cmd.Flags().GetInt("img-processors")
|
workersCount, err := cmd.Flags().GetInt("img-processors")
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if workersCount < 1 {
|
if workersCount < 1 {
|
||||||
log.Fatal("Image resize workers count could not be < 1")
|
return errors.New("image resize workers count could not be < 1")
|
||||||
}
|
}
|
||||||
imgSvc := img.New(workersCount)
|
imgSvc := img.New(workersCount)
|
||||||
|
|
||||||
var fileCache diskcache.Interface = diskcache.NewNoOp()
|
var fileCache diskcache.Interface = diskcache.NewNoOp()
|
||||||
cacheDir, err := cmd.Flags().GetString("cache-dir")
|
cacheDir, err := cmd.Flags().GetString("cache-dir")
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if cacheDir != "" {
|
if cacheDir != "" {
|
||||||
if err := os.MkdirAll(cacheDir, 0700); err != nil { //nolint:govet
|
if err := os.MkdirAll(cacheDir, 0700); err != nil { //nolint:govet
|
||||||
log.Fatalf("can't make directory %s: %s", cacheDir, err)
|
return fmt.Errorf("can't make directory %s: %w", cacheDir, err)
|
||||||
}
|
}
|
||||||
fileCache = diskcache.New(afero.NewOsFs(), cacheDir)
|
fileCache = diskcache.New(afero.NewOsFs(), cacheDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
server := getRunParams(cmd.Flags(), d.store)
|
server, err := getRunParams(cmd.Flags(), d.store)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
setupLog(server.Log)
|
setupLog(server.Log)
|
||||||
|
|
||||||
root, err := filepath.Abs(server.Root)
|
root, err := filepath.Abs(server.Root)
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
server.Root = root
|
server.Root = root
|
||||||
|
|
||||||
adr := server.Address + ":" + server.Port
|
adr := server.Address + ":" + server.Port
|
||||||
@ -151,22 +166,34 @@ user created with the credentials from options "username" and "password".`,
|
|||||||
switch {
|
switch {
|
||||||
case server.Socket != "":
|
case server.Socket != "":
|
||||||
listener, err = net.Listen("unix", server.Socket)
|
listener, err = net.Listen("unix", server.Socket)
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
socketPerm, err := cmd.Flags().GetUint32("socket-perm") //nolint:govet
|
socketPerm, err := cmd.Flags().GetUint32("socket-perm") //nolint:govet
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
err = os.Chmod(server.Socket, os.FileMode(socketPerm))
|
err = os.Chmod(server.Socket, os.FileMode(socketPerm))
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
case server.TLSKey != "" && server.TLSCert != "":
|
case server.TLSKey != "" && server.TLSCert != "":
|
||||||
cer, err := tls.LoadX509KeyPair(server.TLSCert, server.TLSKey) //nolint:govet
|
cer, err := tls.LoadX509KeyPair(server.TLSCert, server.TLSKey) //nolint:govet
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
listener, err = tls.Listen("tcp", adr, &tls.Config{
|
listener, err = tls.Listen("tcp", adr, &tls.Config{
|
||||||
MinVersion: tls.VersionTLS12,
|
MinVersion: tls.VersionTLS12,
|
||||||
Certificates: []tls.Certificate{cer}},
|
Certificates: []tls.Certificate{cer}},
|
||||||
)
|
)
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
listener, err = net.Listen("tcp", adr)
|
listener, err = net.Listen("tcp", adr)
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assetsFs, err := fs.Sub(frontend.Assets(), "dist")
|
assetsFs, err := fs.Sub(frontend.Assets(), "dist")
|
||||||
@ -175,7 +202,9 @@ user created with the credentials from options "username" and "password".`,
|
|||||||
}
|
}
|
||||||
|
|
||||||
handler, err := fbhttp.NewHandler(imgSvc, fileCache, d.store, server, assetsFs)
|
handler, err := fbhttp.NewHandler(imgSvc, fileCache, d.store, server, assetsFs)
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
defer listener.Close()
|
defer listener.Close()
|
||||||
|
|
||||||
@ -194,8 +223,15 @@ user created with the credentials from options "username" and "password".`,
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
sigc := make(chan os.Signal, 1)
|
sigc := make(chan os.Signal, 1)
|
||||||
signal.Notify(sigc, os.Interrupt, syscall.SIGTERM)
|
signal.Notify(sigc,
|
||||||
<-sigc
|
os.Interrupt,
|
||||||
|
syscall.SIGHUP,
|
||||||
|
syscall.SIGINT,
|
||||||
|
syscall.SIGTERM,
|
||||||
|
syscall.SIGQUIT,
|
||||||
|
)
|
||||||
|
sig := <-sigc
|
||||||
|
log.Println("Got signal:", sig)
|
||||||
|
|
||||||
shutdownCtx, shutdownRelease := context.WithTimeout(context.Background(), 10*time.Second) //nolint:mnd
|
shutdownCtx, shutdownRelease := context.WithTimeout(context.Background(), 10*time.Second) //nolint:mnd
|
||||||
defer shutdownRelease()
|
defer shutdownRelease()
|
||||||
@ -204,13 +240,28 @@ user created with the credentials from options "username" and "password".`,
|
|||||||
log.Fatalf("HTTP shutdown error: %v", err)
|
log.Fatalf("HTTP shutdown error: %v", err)
|
||||||
}
|
}
|
||||||
log.Println("Graceful shutdown complete.")
|
log.Println("Graceful shutdown complete.")
|
||||||
|
|
||||||
|
switch sig {
|
||||||
|
case syscall.SIGHUP:
|
||||||
|
d.err = fbErrors.ErrSighup
|
||||||
|
case syscall.SIGINT:
|
||||||
|
d.err = fbErrors.ErrSigint
|
||||||
|
case syscall.SIGQUIT:
|
||||||
|
d.err = fbErrors.ErrSigquit
|
||||||
|
case syscall.SIGTERM:
|
||||||
|
d.err = fbErrors.ErrSigTerm
|
||||||
|
}
|
||||||
|
|
||||||
|
return d.err
|
||||||
}, pythonConfig{allowNoDB: true}),
|
}, pythonConfig{allowNoDB: true}),
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:gocyclo
|
//nolint:gocyclo
|
||||||
func getRunParams(flags *pflag.FlagSet, st *storage.Storage) *settings.Server {
|
func getRunParams(flags *pflag.FlagSet, st *storage.Storage) (*settings.Server, error) {
|
||||||
server, err := st.Settings.GetServer()
|
server, err := st.Settings.GetServer()
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
if val, set := getStringParamB(flags, "root"); set {
|
if val, set := getStringParamB(flags, "root"); set {
|
||||||
server.Root = val
|
server.Root = val
|
||||||
@ -253,7 +304,7 @@ func getRunParams(flags *pflag.FlagSet, st *storage.Storage) *settings.Server {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if isAddrSet && isSocketSet {
|
if isAddrSet && isSocketSet {
|
||||||
checkErr(errors.New("--socket flag cannot be used with --address, --port, --key nor --cert"))
|
return nil, errors.New("--socket flag cannot be used with --address, --port, --key nor --cert")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do not use saved Socket if address was manually set.
|
// Do not use saved Socket if address was manually set.
|
||||||
@ -284,7 +335,7 @@ func getRunParams(flags *pflag.FlagSet, st *storage.Storage) *settings.Server {
|
|||||||
server.TokenExpirationTime = val
|
server.TokenExpirationTime = val
|
||||||
}
|
}
|
||||||
|
|
||||||
return server
|
return server, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// getBoolParamB returns a parameter as a string and a boolean to tell if it is different from the default
|
// getBoolParamB returns a parameter as a string and a boolean to tell if it is different from the default
|
||||||
@ -363,7 +414,7 @@ func setupLog(logMethod string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func quickSetup(flags *pflag.FlagSet, d pythonData) {
|
func quickSetup(flags *pflag.FlagSet, d pythonData) error {
|
||||||
log.Println("Performing quick setup")
|
log.Println("Performing quick setup")
|
||||||
|
|
||||||
set := &settings.Settings{
|
set := &settings.Settings{
|
||||||
@ -406,10 +457,14 @@ func quickSetup(flags *pflag.FlagSet, d pythonData) {
|
|||||||
set.AuthMethod = auth.MethodJSONAuth
|
set.AuthMethod = auth.MethodJSONAuth
|
||||||
err = d.store.Auth.Save(&auth.JSONAuth{})
|
err = d.store.Auth.Save(&auth.JSONAuth{})
|
||||||
}
|
}
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
checkErr(err)
|
|
||||||
err = d.store.Settings.Save(set)
|
err = d.store.Settings.Save(set)
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
ser := &settings.Server{
|
ser := &settings.Server{
|
||||||
BaseURL: getStringParam(flags, "baseurl"),
|
BaseURL: getStringParam(flags, "baseurl"),
|
||||||
@ -422,7 +477,9 @@ func quickSetup(flags *pflag.FlagSet, d pythonData) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
err = d.store.Settings.SaveServer(ser)
|
err = d.store.Settings.SaveServer(ser)
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
username := getStringParam(flags, "username")
|
username := getStringParam(flags, "username")
|
||||||
password := getStringParam(flags, "password")
|
password := getStringParam(flags, "password")
|
||||||
@ -430,11 +487,15 @@ func quickSetup(flags *pflag.FlagSet, d pythonData) {
|
|||||||
if password == "" {
|
if password == "" {
|
||||||
var pwd string
|
var pwd string
|
||||||
pwd, err = users.RandomPwd(set.MinimumPasswordLength)
|
pwd, err = users.RandomPwd(set.MinimumPasswordLength)
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
log.Printf("User '%s' initialized with randomly generated password: %s\n", username, pwd)
|
log.Printf("User '%s' initialized with randomly generated password: %s\n", username, pwd)
|
||||||
password, err = users.ValidateAndHashPwd(pwd, set.MinimumPasswordLength)
|
password, err = users.ValidateAndHashPwd(pwd, set.MinimumPasswordLength)
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Printf("User '%s' initialize wth user-provided password\n", username)
|
log.Printf("User '%s' initialize wth user-provided password\n", username)
|
||||||
}
|
}
|
||||||
@ -452,14 +513,15 @@ func quickSetup(flags *pflag.FlagSet, d pythonData) {
|
|||||||
set.Defaults.Apply(user)
|
set.Defaults.Apply(user)
|
||||||
user.Perm.Admin = true
|
user.Perm.Admin = true
|
||||||
|
|
||||||
err = d.store.Users.Save(user)
|
return d.store.Users.Save(user)
|
||||||
checkErr(err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func initConfig() {
|
func initConfig() {
|
||||||
if cfgFile == "" {
|
if cfgFile == "" {
|
||||||
home, err := homedir.Dir()
|
home, err := homedir.Dir()
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
v.AddConfigPath(".")
|
v.AddConfigPath(".")
|
||||||
v.AddConfigPath(home)
|
v.AddConfigPath(home)
|
||||||
v.AddConfigPath("/etc/filebrowser/")
|
v.AddConfigPath("/etc/filebrowser/")
|
||||||
|
@ -40,27 +40,29 @@ including 'index_end'.`,
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
Run: python(func(cmd *cobra.Command, args []string, d pythonData) {
|
RunE: python(func(cmd *cobra.Command, args []string, d *pythonData) error {
|
||||||
i, err := strconv.Atoi(args[0])
|
i, err := strconv.Atoi(args[0])
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
f := i
|
f := i
|
||||||
if len(args) == 2 {
|
if len(args) == 2 {
|
||||||
f, err = strconv.Atoi(args[1])
|
f, err = strconv.Atoi(args[1])
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
user := func(u *users.User) {
|
user := func(u *users.User) error {
|
||||||
u.Rules = append(u.Rules[:i], u.Rules[f+1:]...)
|
u.Rules = append(u.Rules[:i], u.Rules[f+1:]...)
|
||||||
err := d.store.Users.Save(u)
|
return d.store.Users.Save(u)
|
||||||
checkErr(err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
global := func(s *settings.Settings) {
|
global := func(s *settings.Settings) error {
|
||||||
s.Rules = append(s.Rules[:i], s.Rules[f+1:]...)
|
s.Rules = append(s.Rules[:i], s.Rules[f+1:]...)
|
||||||
err := d.store.Settings.Save(s)
|
return d.store.Settings.Save(s)
|
||||||
checkErr(err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
runRules(d.store, cmd, user, global)
|
return runRules(d.store, cmd, user, global)
|
||||||
}, pythonConfig{}),
|
}, pythonConfig{}),
|
||||||
}
|
}
|
||||||
|
55
cmd/rules.go
55
cmd/rules.go
@ -29,41 +29,62 @@ rules.`,
|
|||||||
Args: cobra.NoArgs,
|
Args: cobra.NoArgs,
|
||||||
}
|
}
|
||||||
|
|
||||||
func runRules(st *storage.Storage, cmd *cobra.Command, usersFn func(*users.User), globalFn func(*settings.Settings)) {
|
func runRules(st *storage.Storage, cmd *cobra.Command, usersFn func(*users.User) error, globalFn func(*settings.Settings) error) error {
|
||||||
id := getUserIdentifier(cmd.Flags())
|
id, err := getUserIdentifier(cmd.Flags())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if id != nil {
|
if id != nil {
|
||||||
user, err := st.Users.Get("", id)
|
var user *users.User
|
||||||
checkErr(err)
|
user, err = st.Users.Get("", id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if usersFn != nil {
|
if usersFn != nil {
|
||||||
usersFn(user)
|
err = usersFn(user)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printRules(user.Rules, id)
|
printRules(user.Rules, id)
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
s, err := st.Settings.Get()
|
s, err := st.Settings.Get()
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if globalFn != nil {
|
if globalFn != nil {
|
||||||
globalFn(s)
|
err = globalFn(s)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printRules(s.Rules, id)
|
printRules(s.Rules, id)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getUserIdentifier(flags *pflag.FlagSet) interface{} {
|
func getUserIdentifier(flags *pflag.FlagSet) (interface{}, error) {
|
||||||
id := mustGetUint(flags, "id")
|
id, err := getUint(flags, "id")
|
||||||
username := mustGetString(flags, "username")
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
if id != 0 {
|
}
|
||||||
return id
|
username, err := getString(flags, "username")
|
||||||
} else if username != "" {
|
if err != nil {
|
||||||
return username
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
if id != 0 {
|
||||||
|
return id, nil
|
||||||
|
} else if username != "" {
|
||||||
|
return username, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func printRules(rulez []rules.Rule, id interface{}) {
|
func printRules(rulez []rules.Rule, id interface{}) {
|
||||||
|
@ -21,9 +21,15 @@ var rulesAddCmd = &cobra.Command{
|
|||||||
Short: "Add a global rule or user rule",
|
Short: "Add a global rule or user rule",
|
||||||
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) {
|
RunE: python(func(cmd *cobra.Command, args []string, d *pythonData) error {
|
||||||
allow := mustGetBool(cmd.Flags(), "allow")
|
allow, err := getBool(cmd.Flags(), "allow")
|
||||||
regex := mustGetBool(cmd.Flags(), "regex")
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
regex, err := getBool(cmd.Flags(), "regex")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
exp := args[0]
|
exp := args[0]
|
||||||
|
|
||||||
if regex {
|
if regex {
|
||||||
@ -41,18 +47,16 @@ var rulesAddCmd = &cobra.Command{
|
|||||||
rule.Path = exp
|
rule.Path = exp
|
||||||
}
|
}
|
||||||
|
|
||||||
user := func(u *users.User) {
|
user := func(u *users.User) error {
|
||||||
u.Rules = append(u.Rules, rule)
|
u.Rules = append(u.Rules, rule)
|
||||||
err := d.store.Users.Save(u)
|
return d.store.Users.Save(u)
|
||||||
checkErr(err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
global := func(s *settings.Settings) {
|
global := func(s *settings.Settings) error {
|
||||||
s.Rules = append(s.Rules, rule)
|
s.Rules = append(s.Rules, rule)
|
||||||
err := d.store.Settings.Save(s)
|
return d.store.Settings.Save(s)
|
||||||
checkErr(err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
runRules(d.store, cmd, user, global)
|
return runRules(d.store, cmd, user, global)
|
||||||
}, pythonConfig{}),
|
}, pythonConfig{}),
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ var rulesLsCommand = &cobra.Command{
|
|||||||
Short: "List global rules or user specific rules",
|
Short: "List global rules or user specific rules",
|
||||||
Long: `List global rules or user specific rules.`,
|
Long: `List global rules or user specific rules.`,
|
||||||
Args: cobra.NoArgs,
|
Args: cobra.NoArgs,
|
||||||
Run: python(func(cmd *cobra.Command, _ []string, d pythonData) {
|
RunE: python(func(cmd *cobra.Command, _ []string, d *pythonData) error {
|
||||||
runRules(d.store, cmd, nil, nil)
|
return runRules(d.store, cmd, nil, nil)
|
||||||
}, pythonConfig{}),
|
}, pythonConfig{}),
|
||||||
}
|
}
|
||||||
|
@ -21,11 +21,20 @@ var upgradeCmd = &cobra.Command{
|
|||||||
import share links because they are incompatible with
|
import share links because they are incompatible with
|
||||||
this version.`,
|
this version.`,
|
||||||
Args: cobra.NoArgs,
|
Args: cobra.NoArgs,
|
||||||
Run: func(cmd *cobra.Command, _ []string) {
|
RunE: func(cmd *cobra.Command, _ []string) error {
|
||||||
flags := cmd.Flags()
|
flags := cmd.Flags()
|
||||||
oldDB := mustGetString(flags, "old.database")
|
oldDB, err := getString(flags, "old.database")
|
||||||
oldConf := mustGetString(flags, "old.config")
|
if err != nil {
|
||||||
err := importer.Import(oldDB, oldConf, getStringParam(flags, "database"))
|
return err
|
||||||
checkErr(err)
|
}
|
||||||
|
oldConf, err := getString(flags, "old.config")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
db, err := getString(flags, "database")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return importer.Import(oldDB, oldConf, db)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
57
cmd/users.go
57
cmd/users.go
@ -79,50 +79,60 @@ func addUserFlags(flags *pflag.FlagSet) {
|
|||||||
flags.Bool("singleClick", false, "use single clicks only")
|
flags.Bool("singleClick", false, "use single clicks only")
|
||||||
}
|
}
|
||||||
|
|
||||||
func getViewMode(flags *pflag.FlagSet) users.ViewMode {
|
func getViewMode(flags *pflag.FlagSet) (users.ViewMode, error) {
|
||||||
viewMode := users.ViewMode(mustGetString(flags, "viewMode"))
|
viewModeStr, err := getString(flags, "viewMode")
|
||||||
if viewMode != users.ListViewMode && viewMode != users.MosaicViewMode {
|
if err != nil {
|
||||||
checkErr(errors.New("view mode must be \"" + string(users.ListViewMode) + "\" or \"" + string(users.MosaicViewMode) + "\""))
|
return "", err
|
||||||
}
|
}
|
||||||
return viewMode
|
viewMode := users.ViewMode(viewModeStr)
|
||||||
|
if viewMode != users.ListViewMode && viewMode != users.MosaicViewMode {
|
||||||
|
return "", errors.New("view mode must be \"" + string(users.ListViewMode) + "\" or \"" + string(users.MosaicViewMode) + "\"")
|
||||||
|
}
|
||||||
|
return viewMode, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:gocyclo
|
//nolint:gocyclo
|
||||||
func getUserDefaults(flags *pflag.FlagSet, defaults *settings.UserDefaults, all bool) {
|
func getUserDefaults(flags *pflag.FlagSet, defaults *settings.UserDefaults, all bool) error {
|
||||||
|
var visitErr error
|
||||||
visit := func(flag *pflag.Flag) {
|
visit := func(flag *pflag.Flag) {
|
||||||
|
if visitErr != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var err error
|
||||||
switch flag.Name {
|
switch flag.Name {
|
||||||
case "scope":
|
case "scope":
|
||||||
defaults.Scope = mustGetString(flags, flag.Name)
|
defaults.Scope, err = getString(flags, flag.Name)
|
||||||
case "locale":
|
case "locale":
|
||||||
defaults.Locale = mustGetString(flags, flag.Name)
|
defaults.Locale, err = getString(flags, flag.Name)
|
||||||
case "viewMode":
|
case "viewMode":
|
||||||
defaults.ViewMode = getViewMode(flags)
|
defaults.ViewMode, err = getViewMode(flags)
|
||||||
case "singleClick":
|
case "singleClick":
|
||||||
defaults.SingleClick = mustGetBool(flags, flag.Name)
|
defaults.SingleClick, err = getBool(flags, flag.Name)
|
||||||
case "perm.admin":
|
case "perm.admin":
|
||||||
defaults.Perm.Admin = mustGetBool(flags, flag.Name)
|
defaults.Perm.Admin, err = getBool(flags, flag.Name)
|
||||||
case "perm.execute":
|
case "perm.execute":
|
||||||
defaults.Perm.Execute = mustGetBool(flags, flag.Name)
|
defaults.Perm.Execute, err = getBool(flags, flag.Name)
|
||||||
case "perm.create":
|
case "perm.create":
|
||||||
defaults.Perm.Create = mustGetBool(flags, flag.Name)
|
defaults.Perm.Create, err = getBool(flags, flag.Name)
|
||||||
case "perm.rename":
|
case "perm.rename":
|
||||||
defaults.Perm.Rename = mustGetBool(flags, flag.Name)
|
defaults.Perm.Rename, err = getBool(flags, flag.Name)
|
||||||
case "perm.modify":
|
case "perm.modify":
|
||||||
defaults.Perm.Modify = mustGetBool(flags, flag.Name)
|
defaults.Perm.Modify, err = getBool(flags, flag.Name)
|
||||||
case "perm.delete":
|
case "perm.delete":
|
||||||
defaults.Perm.Delete = mustGetBool(flags, flag.Name)
|
defaults.Perm.Delete, err = getBool(flags, flag.Name)
|
||||||
case "perm.share":
|
case "perm.share":
|
||||||
defaults.Perm.Share = mustGetBool(flags, flag.Name)
|
defaults.Perm.Share, err = getBool(flags, flag.Name)
|
||||||
case "perm.download":
|
case "perm.download":
|
||||||
defaults.Perm.Download = mustGetBool(flags, flag.Name)
|
defaults.Perm.Download, err = getBool(flags, flag.Name)
|
||||||
case "commands":
|
case "commands":
|
||||||
commands, err := flags.GetStringSlice(flag.Name)
|
defaults.Commands, err = flags.GetStringSlice(flag.Name)
|
||||||
checkErr(err)
|
|
||||||
defaults.Commands = commands
|
|
||||||
case "sorting.by":
|
case "sorting.by":
|
||||||
defaults.Sorting.By = mustGetString(flags, flag.Name)
|
defaults.Sorting.By, err = getString(flags, flag.Name)
|
||||||
case "sorting.asc":
|
case "sorting.asc":
|
||||||
defaults.Sorting.Asc = mustGetBool(flags, flag.Name)
|
defaults.Sorting.Asc, err = getBool(flags, flag.Name)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
visitErr = err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,4 +141,5 @@ func getUserDefaults(flags *pflag.FlagSet, defaults *settings.UserDefaults, all
|
|||||||
} else {
|
} else {
|
||||||
flags.Visit(visit)
|
flags.Visit(visit)
|
||||||
}
|
}
|
||||||
|
return visitErr
|
||||||
}
|
}
|
||||||
|
@ -16,36 +16,57 @@ var usersAddCmd = &cobra.Command{
|
|||||||
Short: "Create a new user",
|
Short: "Create a new user",
|
||||||
Long: `Create a new user and add it to the database.`,
|
Long: `Create a new user and add it to the database.`,
|
||||||
Args: cobra.ExactArgs(2),
|
Args: cobra.ExactArgs(2),
|
||||||
Run: python(func(cmd *cobra.Command, args []string, d pythonData) {
|
RunE: python(func(cmd *cobra.Command, args []string, d *pythonData) error {
|
||||||
s, err := d.store.Settings.Get()
|
s, err := d.store.Settings.Get()
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
getUserDefaults(cmd.Flags(), &s.Defaults, false)
|
return err
|
||||||
|
}
|
||||||
|
err = getUserDefaults(cmd.Flags(), &s.Defaults, false)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
password, err := users.ValidateAndHashPwd(args[1], s.MinimumPasswordLength)
|
password, err := users.ValidateAndHashPwd(args[1], s.MinimumPasswordLength)
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
lockPassword, err := getBool(cmd.Flags(), "lockPassword")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
user := &users.User{
|
user := &users.User{
|
||||||
Username: args[0],
|
Username: args[0],
|
||||||
Password: password,
|
Password: password,
|
||||||
LockPassword: mustGetBool(cmd.Flags(), "lockPassword"),
|
LockPassword: lockPassword,
|
||||||
}
|
}
|
||||||
|
|
||||||
s.Defaults.Apply(user)
|
s.Defaults.Apply(user)
|
||||||
|
|
||||||
servSettings, err := d.store.Settings.GetServer()
|
servSettings, err := d.store.Settings.GetServer()
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
// since getUserDefaults() polluted s.Defaults.Scope
|
// since getUserDefaults() polluted s.Defaults.Scope
|
||||||
// which makes the Scope not the one saved in the db
|
// which makes the Scope not the one saved in the db
|
||||||
// we need the right s.Defaults.Scope here
|
// we need the right s.Defaults.Scope here
|
||||||
s2, err := d.store.Settings.Get()
|
s2, err := d.store.Settings.Get()
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
userHome, err := s2.MakeUserDir(user.Username, user.Scope, servSettings.Root)
|
userHome, err := s2.MakeUserDir(user.Username, user.Scope, servSettings.Root)
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
user.Scope = userHome
|
user.Scope = userHome
|
||||||
|
|
||||||
err = d.store.Users.Save(user)
|
err = d.store.Users.Save(user)
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
printUsers([]*users.User{user})
|
printUsers([]*users.User{user})
|
||||||
|
return nil
|
||||||
}, pythonConfig{}),
|
}, pythonConfig{}),
|
||||||
}
|
}
|
||||||
|
@ -14,11 +14,16 @@ var usersExportCmd = &cobra.Command{
|
|||||||
Long: `Export all users to a json or yaml file. Please indicate the
|
Long: `Export all users to a json or yaml file. Please indicate the
|
||||||
path to the file where you want to write the users.`,
|
path to the file where you want to write the users.`,
|
||||||
Args: jsonYamlArg,
|
Args: jsonYamlArg,
|
||||||
Run: python(func(_ *cobra.Command, args []string, d pythonData) {
|
RunE: python(func(_ *cobra.Command, args []string, d *pythonData) error {
|
||||||
list, err := d.store.Users.Gets("")
|
list, err := d.store.Users.Gets("")
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
err = marshal(args[0], list)
|
err = marshal(args[0], list)
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}, pythonConfig{}),
|
}, pythonConfig{}),
|
||||||
}
|
}
|
||||||
|
@ -16,17 +16,17 @@ var usersFindCmd = &cobra.Command{
|
|||||||
Short: "Find a user by username or id",
|
Short: "Find a user by username or id",
|
||||||
Long: `Find a user by username or id. If no flag is set, all users will be printed.`,
|
Long: `Find a user by username or id. If no flag is set, all users will be printed.`,
|
||||||
Args: cobra.ExactArgs(1),
|
Args: cobra.ExactArgs(1),
|
||||||
Run: findUsers,
|
RunE: findUsers,
|
||||||
}
|
}
|
||||||
|
|
||||||
var usersLsCmd = &cobra.Command{
|
var usersLsCmd = &cobra.Command{
|
||||||
Use: "ls",
|
Use: "ls",
|
||||||
Short: "List all users.",
|
Short: "List all users.",
|
||||||
Args: cobra.NoArgs,
|
Args: cobra.NoArgs,
|
||||||
Run: findUsers,
|
RunE: findUsers,
|
||||||
}
|
}
|
||||||
|
|
||||||
var findUsers = python(func(_ *cobra.Command, args []string, d pythonData) {
|
var findUsers = python(func(_ *cobra.Command, args []string, d *pythonData) error {
|
||||||
var (
|
var (
|
||||||
list []*users.User
|
list []*users.User
|
||||||
user *users.User
|
user *users.User
|
||||||
@ -46,6 +46,9 @@ var findUsers = python(func(_ *cobra.Command, args []string, d pythonData) {
|
|||||||
list, err = d.store.Users.Gets("")
|
list, err = d.store.Users.Gets("")
|
||||||
}
|
}
|
||||||
|
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
printUsers(list)
|
printUsers(list)
|
||||||
|
return nil
|
||||||
}, pythonConfig{})
|
}, pythonConfig{})
|
||||||
|
@ -25,34 +25,54 @@ file. You can use this command to import new users to your
|
|||||||
installation. For that, just don't place their ID on the files
|
installation. For that, just don't place their ID on the files
|
||||||
list or set it to 0.`,
|
list or set it to 0.`,
|
||||||
Args: jsonYamlArg,
|
Args: jsonYamlArg,
|
||||||
Run: python(func(cmd *cobra.Command, args []string, d pythonData) {
|
RunE: python(func(cmd *cobra.Command, args []string, d *pythonData) error {
|
||||||
fd, err := os.Open(args[0])
|
fd, err := os.Open(args[0])
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
defer fd.Close()
|
defer fd.Close()
|
||||||
|
|
||||||
list := []*users.User{}
|
list := []*users.User{}
|
||||||
err = unmarshal(args[0], &list)
|
err = unmarshal(args[0], &list)
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
for _, user := range list {
|
for _, user := range list {
|
||||||
err = user.Clean("")
|
err = user.Clean("")
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
}
|
return err
|
||||||
|
|
||||||
if mustGetBool(cmd.Flags(), "replace") {
|
|
||||||
oldUsers, err := d.store.Users.Gets("")
|
|
||||||
checkErr(err)
|
|
||||||
|
|
||||||
err = marshal("users.backup.json", list)
|
|
||||||
checkErr(err)
|
|
||||||
|
|
||||||
for _, user := range oldUsers {
|
|
||||||
err = d.store.Users.Delete(user.ID)
|
|
||||||
checkErr(err)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
overwrite := mustGetBool(cmd.Flags(), "overwrite")
|
replace, err := getBool(cmd.Flags(), "replace")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if replace {
|
||||||
|
oldUsers, userImportErr := d.store.Users.Gets("")
|
||||||
|
if userImportErr != nil {
|
||||||
|
return userImportErr
|
||||||
|
}
|
||||||
|
|
||||||
|
err = marshal("users.backup.json", list)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, user := range oldUsers {
|
||||||
|
err = d.store.Users.Delete(user.ID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
overwrite, err := getBool(cmd.Flags(), "overwrite")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
for _, user := range list {
|
for _, user := range list {
|
||||||
onDB, err := d.store.Users.Get("", user.ID)
|
onDB, err := d.store.Users.Get("", user.ID)
|
||||||
@ -60,7 +80,7 @@ list or set it to 0.`,
|
|||||||
// User exists in DB.
|
// User exists in DB.
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if !overwrite {
|
if !overwrite {
|
||||||
checkErr(errors.New("user " + strconv.Itoa(int(user.ID)) + " is already registered"))
|
return errors.New("user " + strconv.Itoa(int(user.ID)) + " is already registered")
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the usernames mismatch, check if there is another one in the DB
|
// If the usernames mismatch, check if there is another one in the DB
|
||||||
@ -68,7 +88,7 @@ list or set it to 0.`,
|
|||||||
// operation
|
// operation
|
||||||
if user.Username != onDB.Username {
|
if user.Username != onDB.Username {
|
||||||
if conflictuous, err := d.store.Users.Get("", user.Username); err == nil { //nolint:govet
|
if conflictuous, err := d.store.Users.Get("", user.Username); err == nil { //nolint:govet
|
||||||
checkErr(usernameConflictError(user.Username, conflictuous.ID, user.ID))
|
return usernameConflictError(user.Username, conflictuous.ID, user.ID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -78,8 +98,11 @@ list or set it to 0.`,
|
|||||||
}
|
}
|
||||||
|
|
||||||
err = d.store.Users.Save(user)
|
err = d.store.Users.Save(user)
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}, pythonConfig{}),
|
}, pythonConfig{}),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ var usersRmCmd = &cobra.Command{
|
|||||||
Short: "Delete a user by username or id",
|
Short: "Delete a user by username or id",
|
||||||
Long: `Delete a user by username or id`,
|
Long: `Delete a user by username or id`,
|
||||||
Args: cobra.ExactArgs(1),
|
Args: cobra.ExactArgs(1),
|
||||||
Run: python(func(_ *cobra.Command, args []string, d pythonData) {
|
RunE: python(func(_ *cobra.Command, args []string, d *pythonData) error {
|
||||||
username, id := parseUsernameOrID(args[0])
|
username, id := parseUsernameOrID(args[0])
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
@ -25,7 +25,10 @@ var usersRmCmd = &cobra.Command{
|
|||||||
err = d.store.Users.Delete(id)
|
err = d.store.Users.Delete(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
fmt.Println("user deleted successfully")
|
fmt.Println("user deleted successfully")
|
||||||
|
return nil
|
||||||
}, pythonConfig{}),
|
}, pythonConfig{}),
|
||||||
}
|
}
|
||||||
|
@ -21,14 +21,22 @@ var usersUpdateCmd = &cobra.Command{
|
|||||||
Long: `Updates an existing user. Set the flags for the
|
Long: `Updates an existing user. Set the flags for the
|
||||||
options you want to change.`,
|
options you want to change.`,
|
||||||
Args: cobra.ExactArgs(1),
|
Args: cobra.ExactArgs(1),
|
||||||
Run: python(func(cmd *cobra.Command, args []string, d pythonData) {
|
RunE: python(func(cmd *cobra.Command, args []string, d *pythonData) error {
|
||||||
username, id := parseUsernameOrID(args[0])
|
username, id := parseUsernameOrID(args[0])
|
||||||
flags := cmd.Flags()
|
flags := cmd.Flags()
|
||||||
password := mustGetString(flags, "password")
|
password, err := getString(flags, "password")
|
||||||
newUsername := mustGetString(flags, "username")
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
newUsername, err := getString(flags, "username")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
s, err := d.store.Settings.Get()
|
s, err := d.store.Settings.Get()
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
user *users.User
|
user *users.User
|
||||||
@ -40,7 +48,9 @@ options you want to change.`,
|
|||||||
user, err = d.store.Users.Get("", username)
|
user, err = d.store.Users.Get("", username)
|
||||||
}
|
}
|
||||||
|
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
defaults := settings.UserDefaults{
|
defaults := settings.UserDefaults{
|
||||||
Scope: user.Scope,
|
Scope: user.Scope,
|
||||||
@ -51,7 +61,10 @@ options you want to change.`,
|
|||||||
Sorting: user.Sorting,
|
Sorting: user.Sorting,
|
||||||
Commands: user.Commands,
|
Commands: user.Commands,
|
||||||
}
|
}
|
||||||
getUserDefaults(flags, &defaults, false)
|
err = getUserDefaults(flags, &defaults, false)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
user.Scope = defaults.Scope
|
user.Scope = defaults.Scope
|
||||||
user.Locale = defaults.Locale
|
user.Locale = defaults.Locale
|
||||||
user.ViewMode = defaults.ViewMode
|
user.ViewMode = defaults.ViewMode
|
||||||
@ -59,7 +72,10 @@ options you want to change.`,
|
|||||||
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(flags, "lockPassword")
|
user.LockPassword, err = getBool(flags, "lockPassword")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
if newUsername != "" {
|
if newUsername != "" {
|
||||||
user.Username = newUsername
|
user.Username = newUsername
|
||||||
@ -67,11 +83,16 @@ options you want to change.`,
|
|||||||
|
|
||||||
if password != "" {
|
if password != "" {
|
||||||
user.Password, err = users.ValidateAndHashPwd(password, s.MinimumPasswordLength)
|
user.Password, err = users.ValidateAndHashPwd(password, s.MinimumPasswordLength)
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = d.store.Users.Update(user)
|
err = d.store.Users.Update(user)
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
printUsers([]*users.User{user})
|
printUsers([]*users.User{user})
|
||||||
|
return nil
|
||||||
}, pythonConfig{}),
|
}, pythonConfig{}),
|
||||||
}
|
}
|
||||||
|
64
cmd/utils.go
64
cmd/utils.go
@ -23,45 +23,50 @@ import (
|
|||||||
|
|
||||||
const dbPerms = 0640
|
const dbPerms = 0640
|
||||||
|
|
||||||
func checkErr(err error) {
|
func returnErr(err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
return err
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func mustGetString(flags *pflag.FlagSet, flag string) string {
|
func getString(flags *pflag.FlagSet, flag string) (string, error) {
|
||||||
s, err := flags.GetString(flag)
|
s, err := flags.GetString(flag)
|
||||||
checkErr(err)
|
return s, returnErr(err)
|
||||||
return s
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func mustGetMode(flags *pflag.FlagSet, flag string) fs.FileMode {
|
func getMode(flags *pflag.FlagSet, flag string) (fs.FileMode, error) {
|
||||||
s := mustGetString(flags, flag)
|
s, err := getString(flags, flag)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
b, err := strconv.ParseUint(s, 0, 32)
|
b, err := strconv.ParseUint(s, 0, 32)
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
return fs.FileMode(b)
|
return 0, err
|
||||||
|
}
|
||||||
|
return fs.FileMode(b), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func mustGetBool(flags *pflag.FlagSet, flag string) bool {
|
func getBool(flags *pflag.FlagSet, flag string) (bool, error) {
|
||||||
b, err := flags.GetBool(flag)
|
b, err := flags.GetBool(flag)
|
||||||
checkErr(err)
|
return b, returnErr(err)
|
||||||
return b
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func mustGetUint(flags *pflag.FlagSet, flag string) uint {
|
func getUint(flags *pflag.FlagSet, flag string) (uint, error) {
|
||||||
b, err := flags.GetUint(flag)
|
b, err := flags.GetUint(flag)
|
||||||
checkErr(err)
|
return b, returnErr(err)
|
||||||
return b
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateKey() []byte {
|
func generateKey() []byte {
|
||||||
k, err := settings.GenerateKey()
|
k, err := settings.GenerateKey()
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
return k
|
return k
|
||||||
}
|
}
|
||||||
|
|
||||||
type cobraFunc func(cmd *cobra.Command, args []string)
|
type cobraFunc func(cmd *cobra.Command, args []string) error
|
||||||
type pythonFunc func(cmd *cobra.Command, args []string, data pythonData)
|
type pythonFunc func(cmd *cobra.Command, args []string, data *pythonData) error
|
||||||
|
|
||||||
type pythonConfig struct {
|
type pythonConfig struct {
|
||||||
noDB bool
|
noDB bool
|
||||||
@ -71,6 +76,7 @@ type pythonConfig struct {
|
|||||||
type pythonData struct {
|
type pythonData struct {
|
||||||
hadDB bool
|
hadDB bool
|
||||||
store *storage.Storage
|
store *storage.Storage
|
||||||
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
func dbExists(path string) (bool, error) {
|
func dbExists(path string) (bool, error) {
|
||||||
@ -94,8 +100,8 @@ func dbExists(path string) (bool, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func python(fn pythonFunc, cfg pythonConfig) cobraFunc {
|
func python(fn pythonFunc, cfg pythonConfig) cobraFunc {
|
||||||
return func(cmd *cobra.Command, args []string) {
|
return func(cmd *cobra.Command, args []string) error {
|
||||||
data := pythonData{hadDB: true}
|
data := &pythonData{hadDB: true}
|
||||||
|
|
||||||
path := getStringParam(cmd.Flags(), "database")
|
path := getStringParam(cmd.Flags(), "database")
|
||||||
absPath, err := filepath.Abs(path)
|
absPath, err := filepath.Abs(path)
|
||||||
@ -117,17 +123,23 @@ func python(fn pythonFunc, cfg pythonConfig) cobraFunc {
|
|||||||
log.Println("Using database: " + absPath)
|
log.Println("Using database: " + absPath)
|
||||||
data.hadDB = exists
|
data.hadDB = exists
|
||||||
db, err := storm.Open(path, storm.BoltOptions(dbPerms, nil))
|
db, err := storm.Open(path, storm.BoltOptions(dbPerms, nil))
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
defer db.Close()
|
defer db.Close()
|
||||||
data.store, err = bolt.NewStorage(db)
|
data.store, err = bolt.NewStorage(db)
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
fn(cmd, args, data)
|
return err
|
||||||
|
}
|
||||||
|
return fn(cmd, args, data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func marshal(filename string, data interface{}) error {
|
func marshal(filename string, data interface{}) error {
|
||||||
fd, err := os.Create(filename)
|
fd, err := os.Create(filename)
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
defer fd.Close()
|
defer fd.Close()
|
||||||
|
|
||||||
switch ext := filepath.Ext(filename); ext {
|
switch ext := filepath.Ext(filename); ext {
|
||||||
@ -145,7 +157,9 @@ func marshal(filename string, data interface{}) error {
|
|||||||
|
|
||||||
func unmarshal(filename string, data interface{}) error {
|
func unmarshal(filename string, data interface{}) error {
|
||||||
fd, err := os.Open(filename)
|
fd, err := os.Open(filename)
|
||||||
checkErr(err)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
defer fd.Close()
|
defer fd.Close()
|
||||||
|
|
||||||
switch ext := filepath.Ext(filename); ext {
|
switch ext := filepath.Ext(filename); ext {
|
||||||
|
@ -3,6 +3,15 @@ package errors
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
ExitCodeSigTerm = 128 + int(syscall.SIGTERM)
|
||||||
|
ExitCodeSighup = 128 + int(syscall.SIGHUP)
|
||||||
|
ExitCodeSigint = 128 + int(syscall.SIGINT)
|
||||||
|
ExitCodeSigquit = 128 + int(syscall.SIGQUIT)
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -22,6 +31,10 @@ var (
|
|||||||
ErrInvalidRequestParams = errors.New("invalid request params")
|
ErrInvalidRequestParams = errors.New("invalid request params")
|
||||||
ErrSourceIsParent = errors.New("source is parent")
|
ErrSourceIsParent = errors.New("source is parent")
|
||||||
ErrRootUserDeletion = errors.New("user with id 1 can't be deleted")
|
ErrRootUserDeletion = errors.New("user with id 1 can't be deleted")
|
||||||
|
ErrSigTerm = errors.New("exit on signal: sigterm")
|
||||||
|
ErrSighup = errors.New("exit on signal: sighup")
|
||||||
|
ErrSigint = errors.New("exit on signal: sigint")
|
||||||
|
ErrSigquit = errors.New("exit on signal: sigquit")
|
||||||
)
|
)
|
||||||
|
|
||||||
type ErrShortPassword struct {
|
type ErrShortPassword struct {
|
||||||
@ -31,3 +44,44 @@ type ErrShortPassword struct {
|
|||||||
func (e ErrShortPassword) Error() string {
|
func (e ErrShortPassword) Error() string {
|
||||||
return fmt.Sprintf("password is too short, minimum length is %d", e.MinimumLength)
|
return fmt.Sprintf("password is too short, minimum length is %d", e.MinimumLength)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetExitCode returns the exit code for a given error.
|
||||||
|
func GetExitCode(err error) int {
|
||||||
|
if err == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
exitCodeMap := map[error]int{
|
||||||
|
ErrSigTerm: ExitCodeSigTerm,
|
||||||
|
ErrSighup: ExitCodeSighup,
|
||||||
|
ErrSigint: ExitCodeSigint,
|
||||||
|
ErrSigquit: ExitCodeSigquit,
|
||||||
|
}
|
||||||
|
|
||||||
|
for e, code := range exitCodeMap {
|
||||||
|
if errors.Is(err, e) {
|
||||||
|
return code
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if exitErr, ok := err.(interface{ ExitCode() int }); ok {
|
||||||
|
return exitErr.ExitCode()
|
||||||
|
}
|
||||||
|
|
||||||
|
var pathErr *os.PathError
|
||||||
|
if errors.As(err, &pathErr) {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
var syscallErr *os.SyscallError
|
||||||
|
if errors.As(err, &syscallErr) {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
var errno syscall.Errno
|
||||||
|
if errors.As(err, &errno) {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
7
main.go
7
main.go
@ -1,9 +1,14 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
"github.com/filebrowser/filebrowser/v2/cmd"
|
"github.com/filebrowser/filebrowser/v2/cmd"
|
||||||
|
"github.com/filebrowser/filebrowser/v2/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
cmd.Execute()
|
if err := cmd.Execute(); err != nil {
|
||||||
|
os.Exit(errors.GetExitCode(err))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user