updated auth method

This commit is contained in:
Graham Steffaniak 2023-09-01 09:00:02 -05:00
parent 736489b577
commit d0cca8f285
20 changed files with 206 additions and 272 deletions

View File

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

View File

@ -28,7 +28,6 @@ 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")
@ -41,38 +40,20 @@ func addConfigFlags(flags *pflag.FlagSet) {
flags.String("recaptcha.key", "", "ReCaptcha site key") flags.String("recaptcha.key", "", "ReCaptcha site key")
flags.String("recaptcha.secret", "", "ReCaptcha secret") flags.String("recaptcha.secret", "", "ReCaptcha secret")
flags.String("branding.name", "", "replace 'File Browser' by this name") flags.String("frontend.name", "", "replace 'File Browser' by this name")
flags.String("branding.color", "", "set the theme color") flags.String("frontend.color", "", "set the theme color")
flags.String("branding.files", "", "path to directory with images and custom styles") flags.String("frontend.files", "", "path to directory with images and custom styles")
flags.Bool("branding.disableExternal", false, "disable external links such as GitHub links") flags.Bool("frontend.disableExternal", false, "disable external links such as GitHub links")
flags.Bool("branding.disableUsedPercentage", false, "disable used disk percentage graph") flags.Bool("frontend.disableUsedPercentage", false, "disable used disk percentage graph")
} }
//nolint:gocyclo //nolint:gocyclo
func getAuthentication(flags *pflag.FlagSet, defaults ...interface{}) (string, auth.Auther) { func getAuthentication() (string, auth.Auther) {
method := mustGetString(flags, "auth.method") method := settings.GlobalConfiguration.Auth.Method
var defaultAuther map[string]interface{} var defaultAuther map[string]interface{}
if len(defaults) > 0 {
if hasAuth := defaults[0]; hasAuth != true {
for _, arg := range defaults {
switch def := arg.(type) {
case *settings.Settings:
method = def.AuthMethod
case auth.Auther:
ms, err := json.Marshal(def)
checkErr(err)
err = json.Unmarshal(ms, &defaultAuther)
checkErr(err)
}
}
}
}
var auther auth.Auther var auther auth.Auther
if method == auth.MethodProxyAuth { if method == auth.MethodProxyAuth {
header := mustGetString(flags, "auth.header") header := settings.GlobalConfiguration.Auth.Header
if header == "" { if header == "" {
header = defaultAuther["header"].(string) header = defaultAuther["header"].(string)
} }
@ -90,9 +71,9 @@ func getAuthentication(flags *pflag.FlagSet, defaults ...interface{}) (string, a
if method == auth.MethodJSONAuth { if method == auth.MethodJSONAuth {
jsonAuth := &auth.JSONAuth{} jsonAuth := &auth.JSONAuth{}
host := mustGetString(flags, "recaptcha.host") host := settings.GlobalConfiguration.Auth.Recaptcha.Host
key := mustGetString(flags, "recaptcha.key") key := settings.GlobalConfiguration.Auth.Recaptcha.Key
secret := mustGetString(flags, "recaptcha.secret") secret := settings.GlobalConfiguration.Auth.Recaptcha.Secret
if key == "" { if key == "" {
if kmap, ok := defaultAuther["recaptcha"].(map[string]interface{}); ok { if kmap, ok := defaultAuther["recaptcha"].(map[string]interface{}); ok {
@ -117,7 +98,7 @@ func getAuthentication(flags *pflag.FlagSet, defaults ...interface{}) (string, a
} }
if method == auth.MethodHookAuth { if method == auth.MethodHookAuth {
command := mustGetString(flags, "auth.command") command := settings.GlobalConfiguration.Auth.Command
if command == "" { if command == "" {
command = defaultAuther["command"].(string) command = defaultAuther["command"].(string)
@ -142,14 +123,14 @@ func printSettings(ser *settings.Server, set *settings.Settings, auther auth.Aut
fmt.Fprintf(w, "Sign up:\t%t\n", set.Signup) fmt.Fprintf(w, "Sign up:\t%t\n", set.Signup)
fmt.Fprintf(w, "Create User Dir:\t%t\n", set.CreateUserDir) fmt.Fprintf(w, "Create User Dir:\t%t\n", set.CreateUserDir)
fmt.Fprintf(w, "Auth method:\t%s\n", set.AuthMethod) fmt.Fprintf(w, "Auth method:\t%s\n", set.Auth.Method)
fmt.Fprintf(w, "Shell:\t%s\t\n", strings.Join(set.Shell, " ")) fmt.Fprintf(w, "Shell:\t%s\t\n", strings.Join(set.Shell, " "))
fmt.Fprintln(w, "\nBranding:") fmt.Fprintln(w, "\nFrontend:")
fmt.Fprintf(w, "\tName:\t%s\n", set.Branding.Name) fmt.Fprintf(w, "\tName:\t%s\n", set.Frontend.Name)
fmt.Fprintf(w, "\tFiles override:\t%s\n", set.Branding.Files) fmt.Fprintf(w, "\tFiles override:\t%s\n", set.Frontend.Files)
fmt.Fprintf(w, "\tDisable external links:\t%t\n", set.Branding.DisableExternal) fmt.Fprintf(w, "\tDisable external links:\t%t\n", set.Frontend.DisableExternal)
fmt.Fprintf(w, "\tDisable used disk percentage graph:\t%t\n", set.Branding.DisableUsedPercentage) fmt.Fprintf(w, "\tDisable used disk percentage graph:\t%t\n", set.Frontend.DisableUsedPercentage)
fmt.Fprintf(w, "\tColor:\t%s\n", set.Branding.Color) fmt.Fprintf(w, "\tColor:\t%s\n", set.Frontend.Color)
fmt.Fprintln(w, "\nServer:") fmt.Fprintln(w, "\nServer:")
fmt.Fprintf(w, "\tLog:\t%s\n", ser.Log) fmt.Fprintf(w, "\tLog:\t%s\n", ser.Log)
fmt.Fprintf(w, "\tPort:\t%s\n", ser.Port) fmt.Fprintf(w, "\tPort:\t%s\n", ser.Port)

View File

@ -18,7 +18,7 @@ var configCatCmd = &cobra.Command{
checkErr(err) checkErr(err)
ser, err := d.store.Settings.GetServer() ser, err := d.store.Settings.GetServer()
checkErr(err) checkErr(err)
auther, err := d.store.Auth.Get(set.AuthMethod) auther, err := d.store.Auth.Get(set.Auth.Method)
checkErr(err) checkErr(err)
printSettings(ser, set, auther) printSettings(ser, set, auther)
}, pythonConfig{}), }, pythonConfig{}),

View File

@ -22,7 +22,7 @@ and imported again with 'config import' command.`,
server, err := d.store.Settings.GetServer() server, err := d.store.Settings.GetServer()
checkErr(err) checkErr(err)
auther, err := d.store.Auth.Get(settings.AuthMethod) auther, err := d.store.Auth.Get(settings.Auth.Method)
checkErr(err) checkErr(err)
data := &settingsFile{ data := &settingsFile{

View File

@ -43,7 +43,6 @@ The path must be for a json or yaml file.`,
} else { } else {
key = generateKey() key = generateKey()
} }
file := settingsFile{} file := settingsFile{}
err := unmarshal(args[0], &file) err := unmarshal(args[0], &file)
checkErr(err) checkErr(err)
@ -63,7 +62,7 @@ The path must be for a json or yaml file.`,
} }
var auther auth.Auther var auther auth.Auther
switch file.Settings.AuthMethod { switch file.Settings.Auth.Method {
case auth.MethodJSONAuth: case auth.MethodJSONAuth:
auther = getAuther(auth.JSONAuth{}, rawAuther).(*auth.JSONAuth) auther = getAuther(auth.JSONAuth{}, rawAuther).(*auth.JSONAuth)
case auth.MethodNoAuth: case auth.MethodNoAuth:

View File

@ -26,33 +26,9 @@ override the options.`,
defaults := settings.UserDefaults{} defaults := settings.UserDefaults{}
flags := cmd.Flags() flags := cmd.Flags()
getUserDefaults(flags, &defaults, true) getUserDefaults(flags, &defaults, true)
authMethod, auther := getAuthentication(flags) _, auther := getAuthentication()
ser := &settings.GlobalConfiguration.Server
s := &settings.Settings{ err := d.store.Settings.Save(&settings.GlobalConfiguration)
Key: generateKey(),
Signup: mustGetBool(flags, "signup"),
Shell: convertCmdStrToCmdArray(mustGetString(flags, "shell")),
AuthMethod: authMethod,
Defaults: defaults,
Branding: settings.Branding{
Name: mustGetString(flags, "branding.name"),
DisableExternal: mustGetBool(flags, "branding.disableExternal"),
DisableUsedPercentage: mustGetBool(flags, "branding.DisableUsedPercentage"),
Files: mustGetString(flags, "branding.files"),
},
}
ser := &settings.Server{
Address: mustGetString(flags, "address"),
Socket: mustGetString(flags, "socket"),
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)
checkErr(err) checkErr(err)
err = d.store.Settings.SaveServer(ser) err = d.store.Settings.SaveServer(ser)
checkErr(err) checkErr(err)
@ -64,6 +40,6 @@ 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) printSettings(ser, &settings.GlobalConfiguration, auther)
}, pythonConfig{noDB: true}), }, pythonConfig{noDB: true}),
} }

View File

@ -24,7 +24,6 @@ you want to change. Other options will remain unchanged.`,
ser, err := d.store.Settings.GetServer() ser, err := d.store.Settings.GetServer()
checkErr(err) checkErr(err)
hasAuth := false
flags.Visit(func(flag *pflag.Flag) { flags.Visit(func(flag *pflag.Flag) {
switch flag.Name { switch flag.Name {
case "baseurl": case "baseurl":
@ -40,37 +39,30 @@ you want to change. Other options will remain unchanged.`,
case "address": case "address":
ser.Address = mustGetString(flags, flag.Name) ser.Address = mustGetString(flags, flag.Name)
case "port": case "port":
ser.Port = mustGetString(flags, flag.Name) ser.Port = 8080
case "log": case "log":
ser.Log = mustGetString(flags, flag.Name) ser.Log = mustGetString(flags, flag.Name)
case "signup": case "signup":
set.Signup = mustGetBool(flags, flag.Name) set.Signup = mustGetBool(flags, flag.Name)
case "auth.method":
hasAuth = true
case "shell": case "shell":
set.Shell = convertCmdStrToCmdArray(mustGetString(flags, flag.Name)) set.Shell = convertCmdStrToCmdArray(mustGetString(flags, flag.Name))
case "branding.name": case "frontend.name":
set.Branding.Name = mustGetString(flags, flag.Name) set.Frontend.Name = mustGetString(flags, flag.Name)
case "branding.color": case "frontend.color":
set.Branding.Color = mustGetString(flags, flag.Name) set.Frontend.Color = mustGetString(flags, flag.Name)
case "branding.disableExternal": case "frontend.disableExternal":
set.Branding.DisableExternal = mustGetBool(flags, flag.Name) set.Frontend.DisableExternal = mustGetBool(flags, flag.Name)
case "branding.disableUsedPercentage": case "frontend.disableUsedPercentage":
set.Branding.DisableUsedPercentage = mustGetBool(flags, flag.Name) set.Frontend.DisableUsedPercentage = mustGetBool(flags, flag.Name)
case "branding.files": case "frontend.files":
set.Branding.Files = mustGetString(flags, flag.Name) set.Frontend.Files = mustGetString(flags, flag.Name)
} }
}) })
getUserDefaults(flags, &set.Defaults, false) getUserDefaults(flags, &set.Defaults, false)
// read the defaults // read the defaults
auther, err := d.store.Auth.Get(set.AuthMethod) _, auther := getAuthentication()
checkErr(err)
// check if there are new flags for existing auth method
set.AuthMethod, auther = getAuthentication(flags, hasAuth, set, auther)
err = d.store.Auth.Save(auther) err = d.store.Auth.Save(auther)
checkErr(err) checkErr(err)
err = d.store.Settings.Save(set) err = d.store.Settings.Save(set)

View File

@ -2,7 +2,6 @@ package cmd
import ( import (
"crypto/tls" "crypto/tls"
"errors"
"io" "io"
"io/fs" "io/fs"
"log" "log"
@ -10,7 +9,6 @@ import (
"net/http" "net/http"
"os" "os"
"os/signal" "os/signal"
"path/filepath"
"strconv" "strconv"
"strings" "strings"
"syscall" "syscall"
@ -57,55 +55,19 @@ func init() {
flags.Bool("noauth", false, "use the noauth auther when using quick setup") flags.Bool("noauth", false, "use the noauth auther when using quick setup")
flags.String("username", "admin", "username for the first user when using quick config") 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\")") flags.String("password", "", "hashed password for the first user when using quick config (default \"admin\")")
addServerFlags(flags)
}
func getEnvVariableAsUint32(key string) uint32 {
valueStr := os.Getenv(key)
value, err := strconv.ParseUint(valueStr, 10, 32)
if err != nil {
return 5 // default value every 5 minutes
}
return uint32(value)
}
func addServerFlags(flags *pflag.FlagSet) {
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.String("socket", "", "socket to listen to (cannot be used with address, port, cert nor key flags)")
flags.Uint32("socket-perm", 0666, "unix socket file permissions") //nolint:gomnd
flags.StringP("baseurl", "b", "", "base url")
flags.String("cache-dir", "", "file cache directory (disabled if empty)")
flags.Int("img-processors", 4, "image processors count") //nolint:gomnd
flags.Bool("disable-thumbnails", false, "disable image thumbnails")
flags.Bool("disable-preview-resize", true, "disable resize of image previews")
flags.Bool("disable-exec", false, "disables Command Runner feature")
flags.Bool("disable-type-detection-by-header", false, "disables type detection by reading file headers")
} }
var rootCmd = &cobra.Command{ var rootCmd = &cobra.Command{
Use: "filebrowser", Use: "filebrowser",
Short: "A stylish web-based file browser", Short: "A stylish web-based file browser",
Long: `File Browser CLI lets you create the database to use with File Browser, Long: `
manage your users and all the configurations without acessing the
web interface.
If you've never run File Browser, you'll need to have a database for If you've never run File Browser, you'll need to have a database for
it. Don't worry: you don't need to setup a separate database server. it. Don't worry: you don't need to setup a separate database server.
We're using Bolt DB which is a single file database and all managed We're using Bolt DB which is a single file database and all managed
by ourselves. by ourselves.
For this specific command, all the flags you have available (except
"config" for the configuration file), can be given either through
environment variables or configuration files.
If you don't set "config", it will look for a configuration file called If you don't set "config", it will look for a configuration file called
.filebrowser.{json, toml, yaml, yml} in the following directories: filebrowser.{json, toml, yaml, yml} in the following directories:
- ./ - ./
- $HOME/ - $HOME/
@ -119,70 +81,60 @@ The precedence of the configuration values are as follows:
- database values - database values
- defaults - defaults
The environment variables are prefixed by "FB_" followed by the option
name in caps. So to set "database" via an env variable, you should
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 bootstraped and a new 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) {
settings.Initialize()
serverConfig := settings.GlobalConfiguration.Server
log.Println(cfgFile) log.Println(cfgFile)
if !d.hadDB { if !d.hadDB {
quickSetup(cmd.Flags(), d) quickSetup(cmd.Flags(), d)
} }
// build img service workersCount := serverConfig.NumImageProcessors
workersCount, err := cmd.Flags().GetInt("img-processors")
checkErr(err)
if workersCount < 1 { if workersCount < 1 {
log.Fatal("Image resize workers count could not be < 1") log.Fatal("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 := "/tmp"
checkErr(err)
if cacheDir != "" { if cacheDir != "" {
if err := os.MkdirAll(cacheDir, 0700); err != nil { //nolint:govet,gomnd if err := os.MkdirAll(cacheDir, 0700); err != nil { //nolint:govet,gomnd
log.Fatalf("can't make directory %s: %s", cacheDir, err) log.Fatalf("can't make directory %s: %s", cacheDir, err)
} }
fileCache = diskcache.New(afero.NewOsFs(), cacheDir) fileCache = diskcache.New(afero.NewOsFs(), cacheDir)
} }
// initialize indexing and schedule indexing ever n minutes (default 5) // initialize indexing and schedule indexing ever n minutes (default 5)
indexingInterval := getEnvVariableAsUint32("INDEXING_INTERVAL") go search.InitializeIndex(serverConfig.IndexingInterval)
go search.InitializeIndex(indexingInterval)
server := getRunParams(cmd.Flags(), d.store) _, err := os.Stat(serverConfig.Root)
setupLog(server.Log)
root, err := filepath.Abs(server.Root)
checkErr(err) checkErr(err)
server.Root = root
adr := server.Address + ":" + server.Port
var listener net.Listener var listener net.Listener
address := serverConfig.Address+":"+strconv.Itoa(serverConfig.Port)
switch { switch {
case server.Socket != "": case serverConfig.Socket != "":
listener, err = net.Listen("unix", server.Socket) listener, err = net.Listen("unix", serverConfig.Socket)
checkErr(err) checkErr(err)
socketPerm, err := cmd.Flags().GetUint32("socket-perm") //nolint:govet socketPerm, err := cmd.Flags().GetUint32("socket-perm") //nolint:govet
checkErr(err) checkErr(err)
err = os.Chmod(server.Socket, os.FileMode(socketPerm)) err = os.Chmod(serverConfig.Socket, os.FileMode(socketPerm))
checkErr(err) checkErr(err)
case server.TLSKey != "" && server.TLSCert != "": case serverConfig.TLSKey != "" && serverConfig.TLSCert != "":
cer, err := tls.LoadX509KeyPair(server.TLSCert, server.TLSKey) //nolint:govet cer, err := tls.LoadX509KeyPair(serverConfig.TLSCert, serverConfig.TLSKey) //nolint:govet
checkErr(err) checkErr(err)
listener, err = tls.Listen("tcp", adr, &tls.Config{ listener, err = tls.Listen("tcp", address, &tls.Config{
MinVersion: tls.VersionTLS12, MinVersion: tls.VersionTLS12,
Certificates: []tls.Certificate{cer}}, Certificates: []tls.Certificate{cer}},
) )
checkErr(err) checkErr(err)
default: default:
listener, err = net.Listen("tcp", adr) listener, err = net.Listen("tcp", address)
checkErr(err) checkErr(err)
} }
@ -191,7 +143,7 @@ user created with the credentials from options "username" and "password".`,
go cleanupHandler(listener, sigc) go cleanupHandler(listener, sigc)
assetsFs := dirFS{Dir: http.Dir("frontend/dist")} assetsFs := dirFS{Dir: http.Dir("frontend/dist")}
handler, err := fbhttp.NewHandler(imgSvc, fileCache, d.store, server, assetsFs) handler, err := fbhttp.NewHandler(imgSvc, fileCache, d.store, &serverConfig, assetsFs)
checkErr(err) checkErr(err)
defer listener.Close() defer listener.Close()
@ -215,68 +167,6 @@ func cleanupHandler(listener net.Listener, c chan os.Signal) { //nolint:interfac
func getRunParams(flags *pflag.FlagSet, st *storage.Storage) *settings.Server { func getRunParams(flags *pflag.FlagSet, st *storage.Storage) *settings.Server {
server, err := st.Settings.GetServer() server, err := st.Settings.GetServer()
checkErr(err) checkErr(err)
if val, set := getParamB(flags, "root"); set {
server.Root = val
}
if val, set := getParamB(flags, "baseurl"); set {
server.BaseURL = val
}
if val, set := getParamB(flags, "log"); set {
server.Log = val
}
isSocketSet := false
isAddrSet := false
if val, set := getParamB(flags, "address"); set {
server.Address = val
isAddrSet = isAddrSet || set
}
if val, set := getParamB(flags, "port"); set {
server.Port = val
isAddrSet = isAddrSet || set
}
if val, set := getParamB(flags, "key"); set {
server.TLSKey = val
isAddrSet = isAddrSet || set
}
if val, set := getParamB(flags, "cert"); set {
server.TLSCert = val
isAddrSet = isAddrSet || set
}
if val, set := getParamB(flags, "socket"); set {
server.Socket = val
isSocketSet = isSocketSet || set
}
if isAddrSet && isSocketSet {
checkErr(errors.New("--socket flag cannot be used with --address, --port, --key nor --cert"))
}
// Do not use saved Socket if address was manually set.
if isAddrSet && server.Socket != "" {
server.Socket = ""
}
_, disableThumbnails := getParamB(flags, "disable-thumbnails")
server.EnableThumbnails = !disableThumbnails
_, disablePreviewResize := getParamB(flags, "disable-preview-resize")
server.ResizePreview = !disablePreviewResize
_, disableTypeDetectionByHeader := getParamB(flags, "disable-type-detection-by-header")
server.TypeDetectionByHeader = !disableTypeDetectionByHeader
_, disableExec := getParamB(flags, "disable-exec")
server.EnableExec = !disableExec
return server return server
} }
@ -348,32 +238,28 @@ func quickSetup(flags *pflag.FlagSet, d pythonData) {
Download: true, Download: true,
}, },
}, },
AuthMethod: "", Frontend: settings.Frontend{},
Branding: settings.Branding{},
Commands: nil, Commands: nil,
Shell: nil, Shell: nil,
Rules: nil, Rules: nil,
} }
var err error var err error
if _, noauth := getParamB(flags, "noauth"); noauth { if settings.GlobalConfiguration.Auth.Method == "noAuth" {
set.AuthMethod = auth.MethodNoAuth set.Auth.Method = "noAuth"
err = d.store.Auth.Save(&auth.NoAuth{}) err = d.store.Auth.Save(&auth.NoAuth{})
} else { }else{
set.AuthMethod = auth.MethodJSONAuth set.Auth.Method = auth.MethodJSONAuth
err = d.store.Auth.Save(&auth.JSONAuth{}) err = d.store.Auth.Save(&auth.JSONAuth{})
} }
err = d.store.Settings.Save(set) err = d.store.Settings.Save(set)
checkErr(err) checkErr(err)
ser := &settings.Server{ ser := &settings.Server{
BaseURL: getParam(flags, "baseurl"), BaseURL: getParam(flags, "baseurl"),
Port: getParam(flags, "port"),
Log: getParam(flags, "log"), Log: getParam(flags, "log"),
TLSKey: getParam(flags, "key"), TLSKey: getParam(flags, "key"),
TLSCert: getParam(flags, "cert"), TLSCert: getParam(flags, "cert"),
Address: getParam(flags, "address"),
Root: getParam(flags, "root"), Root: getParam(flags, "root"),
} }
err = d.store.Settings.SaveServer(ser) err = d.store.Settings.SaveServer(ser)
@ -408,7 +294,7 @@ func initConfig() {
if cfgFile == "" { if cfgFile == "" {
v.AddConfigPath(".") v.AddConfigPath(".")
v.AddConfigPath("/etc/filebrowser/") v.AddConfigPath("/etc/filebrowser/")
v.SetConfigName(".filebrowser") v.SetConfigName("filebrowser")
} else { } else {
v.SetConfigFile(cfgFile) v.SetConfigFile(cfgFile)
} }

View File

@ -1,26 +1,27 @@
server: server:
port: 8080 port: 8050
baseURL: /files baseURL: /files
address: '' address: ''
log: stdout log: stdout
database: ./database.db database: ./database.db
root: /srv root: /srv
general:
disable-thumbnails: false disable-thumbnails: false
disable-preview-resize: false disable-preview-resize: false
disable-exec: false disable-exec: false
disable-type-detection-by-header: false disable-type-detection-by-header: false
auth: auth:
header: '' header: ''
method: '' method: 'noauth'
command: '' command: ''
signup: false signup: false
shell: '' shell: ''
branding: frontend:
name: '' name: ''
color: '' color: ''
files: '' files: ''
disableExternal: '' disableExternal: false
disableUsedPercentage: '' disableUsedPercentage: false
permissions: permissions:
Admin: false Admin: false
Execute: true Execute: true
@ -31,5 +32,4 @@ permissions:
Share: true Share: true
Download: true Download: true
commands: commands:
shell:
rules: rules:

View File

@ -7,6 +7,7 @@ require (
github.com/disintegration/imaging v1.6.2 github.com/disintegration/imaging v1.6.2
github.com/dsoprea/go-exif/v3 v3.0.1 github.com/dsoprea/go-exif/v3 v3.0.1
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568
github.com/goccy/go-yaml v1.11.0
github.com/golang-jwt/jwt/v4 v4.5.0 github.com/golang-jwt/jwt/v4 v4.5.0
github.com/gorilla/mux v1.8.0 github.com/gorilla/mux v1.8.0
github.com/gorilla/websocket v1.5.0 github.com/gorilla/websocket v1.5.0
@ -35,6 +36,7 @@ require (
github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect
github.com/dsoprea/go-logging v0.0.0-20200710184922-b02d349568dd // indirect github.com/dsoprea/go-logging v0.0.0-20200710184922-b02d349568dd // indirect
github.com/dsoprea/go-utility/v2 v2.0.0-20221003172846-a3e1774ef349 // indirect github.com/dsoprea/go-utility/v2 v2.0.0-20221003172846-a3e1774ef349 // indirect
github.com/fatih/color v1.13.0 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/go-errors/errors v1.4.2 // indirect github.com/go-errors/errors v1.4.2 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-ole/go-ole v1.2.6 // indirect
@ -45,6 +47,8 @@ require (
github.com/klauspost/compress v1.11.4 // indirect github.com/klauspost/compress v1.11.4 // indirect
github.com/klauspost/pgzip v1.2.5 // indirect github.com/klauspost/pgzip v1.2.5 // indirect
github.com/magiconair/properties v1.8.7 // indirect github.com/magiconair/properties v1.8.7 // indirect
github.com/mattn/go-colorable v0.1.12 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/nwaples/rardecode v1.1.0 // indirect github.com/nwaples/rardecode v1.1.0 // indirect
github.com/pierrec/lz4/v4 v4.1.2 // indirect github.com/pierrec/lz4/v4 v4.1.2 // indirect
@ -58,6 +62,7 @@ require (
github.com/yusufpapurcu/wmi v1.2.3 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect
golang.org/x/net v0.10.0 // indirect golang.org/x/net v0.10.0 // indirect
golang.org/x/sys v0.11.0 // indirect golang.org/x/sys v0.11.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect
) )

View File

@ -86,6 +86,8 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY=
@ -101,6 +103,11 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE=
github.com/goccy/go-yaml v1.11.0 h1:n7Z+zx8S9f9KgzG6KtQKf+kwqXZlLNR2F6018Dgau54=
github.com/goccy/go-yaml v1.11.0/go.mod h1:H+mJrWtjPTJAHvRbV09MCK9xYwODM+wRTVFFTWckfng=
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI= github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI=
@ -198,6 +205,7 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
@ -205,6 +213,12 @@ github.com/maruel/natural v1.1.0 h1:2z1NgP/Vae+gYrtC0VuvrTJ6U35OuyUqDdfluLqMWuQ=
github.com/maruel/natural v1.1.0/go.mod h1:eFVhYCcUOfZFxXoDZam8Ktya72wa79fNC3lc/leA0DQ= github.com/maruel/natural v1.1.0/go.mod h1:eFVhYCcUOfZFxXoDZam8Ktya72wa79fNC3lc/leA0DQ=
github.com/marusama/semaphore/v2 v2.5.0 h1:o/1QJD9DBYOWRnDhPwDVAXQn6mQYD0gZaS1Tpx6DJGM= github.com/marusama/semaphore/v2 v2.5.0 h1:o/1QJD9DBYOWRnDhPwDVAXQn6mQYD0gZaS1Tpx6DJGM=
github.com/marusama/semaphore/v2 v2.5.0/go.mod h1:z9nMiNUekt/LTpTUQdpp+4sJeYqUGpwMHfW0Z8V8fnQ= github.com/marusama/semaphore/v2 v2.5.0/go.mod h1:z9nMiNUekt/LTpTUQdpp+4sJeYqUGpwMHfW0Z8V8fnQ=
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mholt/archiver/v3 v3.5.1 h1:rDjOBX9JSF5BvoJGvjqK479aL70qh9DIpZCl+k7Clwo= github.com/mholt/archiver/v3 v3.5.1 h1:rDjOBX9JSF5BvoJGvjqK479aL70qh9DIpZCl+k7Clwo=
github.com/mholt/archiver/v3 v3.5.1/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4= github.com/mholt/archiver/v3 v3.5.1/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
@ -403,6 +417,7 @@ golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -427,6 +442,8 @@ golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@ -507,6 +524,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk=
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=

View File

@ -102,7 +102,7 @@ func withAdmin(fn handleFunc) handleFunc {
} }
var loginHandler = func(w http.ResponseWriter, r *http.Request, d *data) (int, error) { var loginHandler = func(w http.ResponseWriter, r *http.Request, d *data) (int, error) {
auther, err := d.store.Auth.Get(d.settings.AuthMethod) auther, err := d.store.Auth.Get(d.settings.Auth.Method)
if err != nil { if err != nil {
return http.StatusInternalServerError, err return http.StatusInternalServerError, err
} }

View File

@ -14,7 +14,7 @@ type settingsData struct {
UserHomeBasePath string `json:"userHomeBasePath"` UserHomeBasePath string `json:"userHomeBasePath"`
Defaults settings.UserDefaults `json:"defaults"` Defaults settings.UserDefaults `json:"defaults"`
Rules []rules.Rule `json:"rules"` Rules []rules.Rule `json:"rules"`
Branding settings.Branding `json:"branding"` Frontend settings.Frontend `json:"frontend"`
Shell []string `json:"shell"` Shell []string `json:"shell"`
Commands map[string][]string `json:"commands"` Commands map[string][]string `json:"commands"`
} }
@ -26,7 +26,7 @@ var settingsGetHandler = withAdmin(func(w http.ResponseWriter, r *http.Request,
UserHomeBasePath: d.settings.UserHomeBasePath, UserHomeBasePath: d.settings.UserHomeBasePath,
Defaults: d.settings.Defaults, Defaults: d.settings.Defaults,
Rules: d.settings.Rules, Rules: d.settings.Rules,
Branding: d.settings.Branding, Frontend: d.settings.Frontend,
Shell: d.settings.Shell, Shell: d.settings.Shell,
Commands: d.settings.Commands, Commands: d.settings.Commands,
} }
@ -46,7 +46,7 @@ var settingsPutHandler = withAdmin(func(w http.ResponseWriter, r *http.Request,
d.settings.UserHomeBasePath = req.UserHomeBasePath d.settings.UserHomeBasePath = req.UserHomeBasePath
d.settings.Defaults = req.Defaults d.settings.Defaults = req.Defaults
d.settings.Rules = req.Rules d.settings.Rules = req.Rules
d.settings.Branding = req.Branding d.settings.Frontend = req.Frontend
d.settings.Shell = req.Shell d.settings.Shell = req.Shell
d.settings.Commands = req.Commands d.settings.Commands = req.Commands

View File

@ -21,33 +21,33 @@ import (
func handleWithStaticData(w http.ResponseWriter, _ *http.Request, d *data, fSys fs.FS, file, contentType string) (int, error) { func handleWithStaticData(w http.ResponseWriter, _ *http.Request, d *data, fSys fs.FS, file, contentType string) (int, error) {
w.Header().Set("Content-Type", contentType) w.Header().Set("Content-Type", contentType)
auther, err := d.store.Auth.Get(d.settings.AuthMethod) auther, err := d.store.Auth.Get(d.settings.Auth.Method)
if err != nil { if err != nil {
return http.StatusInternalServerError, err return http.StatusInternalServerError, err
} }
data := map[string]interface{}{ data := map[string]interface{}{
"Name": d.settings.Branding.Name, "Name": d.settings.Frontend.Name,
"DisableExternal": d.settings.Branding.DisableExternal, "DisableExternal": d.settings.Frontend.DisableExternal,
"DisableUsedPercentage": d.settings.Branding.DisableUsedPercentage, "DisableUsedPercentage": d.settings.Frontend.DisableUsedPercentage,
"Color": d.settings.Branding.Color, "Color": d.settings.Frontend.Color,
"BaseURL": d.server.BaseURL, "BaseURL": d.server.BaseURL,
"Version": version.Version, "Version": version.Version,
"StaticURL": path.Join(d.server.BaseURL, "/static"), "StaticURL": path.Join(d.server.BaseURL, "/static"),
"Signup": d.settings.Signup, "Signup": d.settings.Signup,
"NoAuth": d.settings.AuthMethod == auth.MethodNoAuth, "NoAuth": d.settings.Auth.Method == auth.MethodNoAuth,
"AuthMethod": d.settings.AuthMethod, "AuthMethod": d.settings.Auth.Method,
"LoginPage": auther.LoginPage(), "LoginPage": auther.LoginPage(),
"CSS": false, "CSS": false,
"ReCaptcha": false, "ReCaptcha": false,
"Theme": d.settings.Branding.Theme, "Theme": d.settings.Frontend.Theme,
"EnableThumbs": d.server.EnableThumbnails, "EnableThumbs": d.server.EnableThumbnails,
"ResizePreview": d.server.ResizePreview, "ResizePreview": d.server.ResizePreview,
"EnableExec": d.server.EnableExec, "EnableExec": d.server.EnableExec,
} }
if d.settings.Branding.Files != "" { if d.settings.Frontend.Files != "" {
fPath := filepath.Join(d.settings.Branding.Files, "custom.css") fPath := filepath.Join(d.settings.Frontend.Files, "custom.css")
_, err := os.Stat(fPath) //nolint:govet _, err := os.Stat(fPath) //nolint:govet
if err != nil && !os.IsNotExist(err) { if err != nil && !os.IsNotExist(err) {
@ -59,8 +59,8 @@ func handleWithStaticData(w http.ResponseWriter, _ *http.Request, d *data, fSys
} }
} }
if d.settings.AuthMethod == auth.MethodJSONAuth { if d.settings.Auth.Method == auth.MethodJSONAuth {
raw, err := d.store.Auth.Get(d.settings.AuthMethod) //nolint:govet raw, err := d.store.Auth.Get(d.settings.Auth.Method) //nolint:govet
if err != nil { if err != nil {
return http.StatusInternalServerError, err return http.StatusInternalServerError, err
} }
@ -115,15 +115,15 @@ func getStaticHandlers(store *storage.Storage, server *settings.Server, assetsFs
const maxAge = 86400 // 1 day const maxAge = 86400 // 1 day
w.Header().Set("Cache-Control", fmt.Sprintf("public, max-age=%v", maxAge)) w.Header().Set("Cache-Control", fmt.Sprintf("public, max-age=%v", maxAge))
if d.settings.Branding.Files != "" { if d.settings.Frontend.Files != "" {
if strings.HasPrefix(r.URL.Path, "img/") { if strings.HasPrefix(r.URL.Path, "img/") {
fPath := filepath.Join(d.settings.Branding.Files, r.URL.Path) fPath := filepath.Join(d.settings.Frontend.Files, r.URL.Path)
if _, err := os.Stat(fPath); err == nil { if _, err := os.Stat(fPath); err == nil {
http.ServeFile(w, r, fPath) http.ServeFile(w, r, fPath)
return 0, nil return 0, nil
} }
} else if r.URL.Path == "custom.css" && d.settings.Branding.Files != "" { } else if r.URL.Path == "custom.css" && d.settings.Frontend.Files != "" {
http.ServeFile(w, r, filepath.Join(d.settings.Branding.Files, "custom.css")) http.ServeFile(w, r, filepath.Join(d.settings.Frontend.Files, "custom.css"))
return 0, nil return 0, nil
} }
} }

View File

@ -0,0 +1,50 @@
package settings
import (
"io/ioutil"
"log"
"os"
"github.com/goccy/go-yaml"
)
var GlobalConfiguration Settings
func Initialize() {
// Open and read the YAML file
yamlFile, err := os.Open("filebrowser.yml")
if err != nil {
log.Fatalf("Error opening YAML file: %v", err)
}
defer yamlFile.Close()
yamlData, err := ioutil.ReadAll(yamlFile)
if err != nil {
log.Fatalf("Error reading YAML data: %v", err)
}
setDefaults()
// Unmarshal the YAML data into the Settings struct
err = yaml.Unmarshal(yamlData, &GlobalConfiguration)
if err != nil {
log.Fatalf("Error unmarshaling YAML data: %v", err)
}
// Now you have the Settings struct with values from the YAML file
// You can access the values like: defaultSettings.Key, defaultSettings.Server.Port, etc.
}
func setDefaults() {
GlobalConfiguration = Settings{
Signup: true,
Server: Server{
IndexingInterval: 5,
Port: 8080,
NumImageProcessors: 1,
BaseURL: "/files",
},
Auth: Auth{
Recaptcha: Recaptcha{
Host: "",
},
},
}
}

View File

@ -35,3 +35,7 @@ func GenerateKey() ([]byte, error) {
return b, nil return b, nil
} }
func GetSettingsConfig(nameType string,Value string) string {
return nameType + Value
}

View File

@ -29,21 +29,31 @@ type Settings struct {
Shell []string `json:"shell"` Shell []string `json:"shell"`
Rules []rules.Rule `json:"rules"` Rules []rules.Rule `json:"rules"`
Server Server `json:"server"` Server Server `json:"server"`
AuthMethod string `json:"authMethod"` Auth Auth `json:"auth"`
Auth struct {
Header string `json:"header"`
Method string `json:"method"`
Command string `json:"command"`
Signup bool `json:"signup"`
Shell string `json:"shell"`
} `json:"auth"`
Branding Branding `json:"branding"` Frontend Frontend `json:"frontend"`
UserDefaults UserDefaults `json:"userDefaults"` UserDefaults UserDefaults `json:"userDefaults"`
} }
type Auth struct {
Recaptcha Recaptcha
Header string `json:"header"`
Method string `json:"method"`
Command string `json:"command"`
Signup bool `json:"signup"`
Shell string `json:"shell"`
}
type Recaptcha struct {
Host string
Key string
Secret string
}
type Server struct { type Server struct {
IndexingInterval uint32
NumImageProcessors int
Socket string `json:"socket"` Socket string `json:"socket"`
TLSKey string `json:"tlsKey"` TLSKey string `json:"tlsKey"`
TLSCert string `json:"tlsCert"` TLSCert string `json:"tlsCert"`
@ -52,7 +62,7 @@ type Server struct {
EnableExec bool `json:"enableExec"` EnableExec bool `json:"enableExec"`
TypeDetectionByHeader bool `json:"typeDetectionByHeader"` TypeDetectionByHeader bool `json:"typeDetectionByHeader"`
AuthHook string `json:"authHook"` AuthHook string `json:"authHook"`
Port string `json:"port"` Port int `json:"port"`
BaseURL string `json:"baseURL"` BaseURL string `json:"baseURL"`
Address string `json:"address"` Address string `json:"address"`
Log string `json:"log"` Log string `json:"log"`
@ -61,7 +71,7 @@ type Server struct {
EnablePreviewResize bool `json:"disable-preview-resize"` EnablePreviewResize bool `json:"disable-preview-resize"`
} }
type Branding struct { type Frontend struct {
Name string `json:"name"` Name string `json:"name"`
DisableExternal bool `json:"disableExternal"` DisableExternal bool `json:"disableExternal"`
DisableUsedPercentage bool `json:"disableUsedPercentage"` DisableUsedPercentage bool `json:"disableUsedPercentage"`

View File

@ -2,7 +2,6 @@ package bolt
import ( import (
"github.com/asdine/storm/v3" "github.com/asdine/storm/v3"
"github.com/gtsteffaniak/filebrowser/settings" "github.com/gtsteffaniak/filebrowser/settings"
) )
@ -20,7 +19,10 @@ func (s settingsBackend) Save(set *settings.Settings) error {
} }
func (s settingsBackend) GetServer() (*settings.Server, error) { func (s settingsBackend) GetServer() (*settings.Server, error) {
server := &settings.Server{} server := &settings.Server{
Port: 8080,
NumImageProcessors: 1,
}
return server, get(s.db, "server", server) return server, get(s.db, "server", server)
} }

View File

@ -140,7 +140,7 @@ func importConf(db *storm.DB, path string, sto *storage.Storage) error {
server := &settings.Server{ server := &settings.Server{
BaseURL: cfg.BaseURL, BaseURL: cfg.BaseURL,
Port: cfg.Port, Port: 8080,
Address: cfg.Address, Address: cfg.Address,
Log: cfg.Log, Log: cfg.Log,
} }
@ -149,13 +149,13 @@ func importConf(db *storm.DB, path string, sto *storage.Storage) error {
switch cfg.Auth.Method { switch cfg.Auth.Method {
case "proxy": case "proxy":
auther = &auth.ProxyAuth{Header: cfg.Auth.Header} auther = &auth.ProxyAuth{Header: cfg.Auth.Header}
s.AuthMethod = string(auth.MethodProxyAuth) s.Auth.Method = string(auth.MethodProxyAuth)
case "hook": case "hook":
auther = &auth.HookAuth{Command: cfg.Auth.Command} auther = &auth.HookAuth{Command: cfg.Auth.Command}
s.AuthMethod = string(auth.MethodHookAuth) s.Auth.Method = string(auth.MethodHookAuth)
case "none": case "none":
auther = &auth.NoAuth{} auther = &auth.NoAuth{}
s.AuthMethod = string(auth.MethodNoAuth) s.Auth.Method = string(auth.MethodNoAuth)
default: default:
auther = &auth.JSONAuth{ auther = &auth.JSONAuth{
ReCaptcha: &auth.ReCaptcha{ ReCaptcha: &auth.ReCaptcha{
@ -164,7 +164,7 @@ func importConf(db *storm.DB, path string, sto *storage.Storage) error {
Secret: cfg.ReCaptcha.Secret, Secret: cfg.ReCaptcha.Secret,
}, },
} }
s.AuthMethod = string(auth.MethodJSONAuth) s.Auth.Method = string(auth.MethodJSONAuth)
} }
err = sto.Auth.Save(auther) err = sto.Auth.Save(auther)

View File

@ -2,12 +2,14 @@ package importer
import ( import (
"github.com/asdine/storm/v3" "github.com/asdine/storm/v3"
"log"
"github.com/gtsteffaniak/filebrowser/storage/bolt" "github.com/gtsteffaniak/filebrowser/storage/bolt"
) )
// Import imports an old configuration to a newer database. // Import imports an old configuration to a newer database.
func Import(oldDBPath, oldConf, newDBPath string) error { func Import(oldDBPath, oldConf, newDBPath string) error {
log.Println(oldDBPath, oldConf, newDBPath)
oldDB, err := storm.Open(oldDBPath) oldDB, err := storm.Open(oldDBPath)
if err != nil { if err != nil {
return err return err