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) {
addServerFlags(flags)
addUserFlags(flags)
flags.BoolP("signup", "s", false, "allow users to signup")
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.secret", "", "ReCaptcha secret")
flags.String("branding.name", "", "replace 'File Browser' by this name")
flags.String("branding.color", "", "set the theme color")
flags.String("branding.files", "", "path to directory with images and custom styles")
flags.Bool("branding.disableExternal", false, "disable external links such as GitHub links")
flags.Bool("branding.disableUsedPercentage", false, "disable used disk percentage graph")
flags.String("frontend.name", "", "replace 'File Browser' by this name")
flags.String("frontend.color", "", "set the theme color")
flags.String("frontend.files", "", "path to directory with images and custom styles")
flags.Bool("frontend.disableExternal", false, "disable external links such as GitHub links")
flags.Bool("frontend.disableUsedPercentage", false, "disable used disk percentage graph")
}
//nolint:gocyclo
func getAuthentication(flags *pflag.FlagSet, defaults ...interface{}) (string, auth.Auther) {
method := mustGetString(flags, "auth.method")
func getAuthentication() (string, auth.Auther) {
method := settings.GlobalConfiguration.Auth.Method
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
if method == auth.MethodProxyAuth {
header := mustGetString(flags, "auth.header")
header := settings.GlobalConfiguration.Auth.Header
if header == "" {
header = defaultAuther["header"].(string)
}
@ -90,9 +71,9 @@ func getAuthentication(flags *pflag.FlagSet, defaults ...interface{}) (string, a
if method == auth.MethodJSONAuth {
jsonAuth := &auth.JSONAuth{}
host := mustGetString(flags, "recaptcha.host")
key := mustGetString(flags, "recaptcha.key")
secret := mustGetString(flags, "recaptcha.secret")
host := settings.GlobalConfiguration.Auth.Recaptcha.Host
key := settings.GlobalConfiguration.Auth.Recaptcha.Key
secret := settings.GlobalConfiguration.Auth.Recaptcha.Secret
if key == "" {
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 {
command := mustGetString(flags, "auth.command")
command := settings.GlobalConfiguration.Auth.Command
if command == "" {
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, "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.Fprintln(w, "\nBranding:")
fmt.Fprintf(w, "\tName:\t%s\n", set.Branding.Name)
fmt.Fprintf(w, "\tFiles override:\t%s\n", set.Branding.Files)
fmt.Fprintf(w, "\tDisable external links:\t%t\n", set.Branding.DisableExternal)
fmt.Fprintf(w, "\tDisable used disk percentage graph:\t%t\n", set.Branding.DisableUsedPercentage)
fmt.Fprintf(w, "\tColor:\t%s\n", set.Branding.Color)
fmt.Fprintln(w, "\nFrontend:")
fmt.Fprintf(w, "\tName:\t%s\n", set.Frontend.Name)
fmt.Fprintf(w, "\tFiles override:\t%s\n", set.Frontend.Files)
fmt.Fprintf(w, "\tDisable external links:\t%t\n", set.Frontend.DisableExternal)
fmt.Fprintf(w, "\tDisable used disk percentage graph:\t%t\n", set.Frontend.DisableUsedPercentage)
fmt.Fprintf(w, "\tColor:\t%s\n", set.Frontend.Color)
fmt.Fprintln(w, "\nServer:")
fmt.Fprintf(w, "\tLog:\t%s\n", ser.Log)
fmt.Fprintf(w, "\tPort:\t%s\n", ser.Port)

View File

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

View File

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

View File

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

View File

@ -26,33 +26,9 @@ override the options.`,
defaults := settings.UserDefaults{}
flags := cmd.Flags()
getUserDefaults(flags, &defaults, true)
authMethod, auther := getAuthentication(flags)
s := &settings.Settings{
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)
_, auther := getAuthentication()
ser := &settings.GlobalConfiguration.Server
err := d.store.Settings.Save(&settings.GlobalConfiguration)
checkErr(err)
err = d.store.Settings.SaveServer(ser)
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
need to call the main command to boot up the server.
`)
printSettings(ser, s, auther)
printSettings(ser, &settings.GlobalConfiguration, auther)
}, pythonConfig{noDB: true}),
}

View File

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

View File

@ -2,7 +2,6 @@ package cmd
import (
"crypto/tls"
"errors"
"io"
"io/fs"
"log"
@ -10,7 +9,6 @@ import (
"net/http"
"os"
"os/signal"
"path/filepath"
"strconv"
"strings"
"syscall"
@ -57,55 +55,19 @@ func init() {
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("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{
Use: "filebrowser",
Short: "A stylish web-based file browser",
Long: `File Browser CLI lets you create the database to use with File Browser,
manage your users and all the configurations without acessing the
web interface.
Long: `
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.
We're using Bolt DB which is a single file database and all managed
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
.filebrowser.{json, toml, yaml, yml} in the following directories:
filebrowser.{json, toml, yaml, yml} in the following directories:
- ./
- $HOME/
@ -119,70 +81,60 @@ The precedence of the configuration values are as follows:
- database values
- 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
the quick setup mode and a new database will be bootstraped and a new
user created with the credentials from options "username" and "password".`,
Run: python(func(cmd *cobra.Command, args []string, d pythonData) {
settings.Initialize()
serverConfig := settings.GlobalConfiguration.Server
log.Println(cfgFile)
if !d.hadDB {
quickSetup(cmd.Flags(), d)
}
// build img service
workersCount, err := cmd.Flags().GetInt("img-processors")
checkErr(err)
workersCount := serverConfig.NumImageProcessors
if workersCount < 1 {
log.Fatal("Image resize workers count could not be < 1")
}
imgSvc := img.New(workersCount)
var fileCache diskcache.Interface = diskcache.NewNoOp()
cacheDir, err := cmd.Flags().GetString("cache-dir")
checkErr(err)
cacheDir := "/tmp"
if cacheDir != "" {
if err := os.MkdirAll(cacheDir, 0700); err != nil { //nolint:govet,gomnd
log.Fatalf("can't make directory %s: %s", cacheDir, err)
}
fileCache = diskcache.New(afero.NewOsFs(), cacheDir)
}
// initialize indexing and schedule indexing ever n minutes (default 5)
indexingInterval := getEnvVariableAsUint32("INDEXING_INTERVAL")
go search.InitializeIndex(indexingInterval)
go search.InitializeIndex(serverConfig.IndexingInterval)
server := getRunParams(cmd.Flags(), d.store)
setupLog(server.Log)
root, err := filepath.Abs(server.Root)
_, err := os.Stat(serverConfig.Root)
checkErr(err)
server.Root = root
adr := server.Address + ":" + server.Port
var listener net.Listener
address := serverConfig.Address+":"+strconv.Itoa(serverConfig.Port)
switch {
case server.Socket != "":
listener, err = net.Listen("unix", server.Socket)
case serverConfig.Socket != "":
listener, err = net.Listen("unix", serverConfig.Socket)
checkErr(err)
socketPerm, err := cmd.Flags().GetUint32("socket-perm") //nolint:govet
checkErr(err)
err = os.Chmod(server.Socket, os.FileMode(socketPerm))
err = os.Chmod(serverConfig.Socket, os.FileMode(socketPerm))
checkErr(err)
case server.TLSKey != "" && server.TLSCert != "":
cer, err := tls.LoadX509KeyPair(server.TLSCert, server.TLSKey) //nolint:govet
case serverConfig.TLSKey != "" && serverConfig.TLSCert != "":
cer, err := tls.LoadX509KeyPair(serverConfig.TLSCert, serverConfig.TLSKey) //nolint:govet
checkErr(err)
listener, err = tls.Listen("tcp", adr, &tls.Config{
listener, err = tls.Listen("tcp", address, &tls.Config{
MinVersion: tls.VersionTLS12,
Certificates: []tls.Certificate{cer}},
)
checkErr(err)
default:
listener, err = net.Listen("tcp", adr)
listener, err = net.Listen("tcp", address)
checkErr(err)
}
@ -191,7 +143,7 @@ user created with the credentials from options "username" and "password".`,
go cleanupHandler(listener, sigc)
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)
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 {
server, err := st.Settings.GetServer()
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
}
@ -348,32 +238,28 @@ func quickSetup(flags *pflag.FlagSet, d pythonData) {
Download: true,
},
},
AuthMethod: "",
Branding: settings.Branding{},
Frontend: settings.Frontend{},
Commands: nil,
Shell: nil,
Rules: nil,
}
var err error
if _, noauth := getParamB(flags, "noauth"); noauth {
set.AuthMethod = auth.MethodNoAuth
if settings.GlobalConfiguration.Auth.Method == "noAuth" {
set.Auth.Method = "noAuth"
err = d.store.Auth.Save(&auth.NoAuth{})
} else {
set.AuthMethod = auth.MethodJSONAuth
}else{
set.Auth.Method = auth.MethodJSONAuth
err = d.store.Auth.Save(&auth.JSONAuth{})
}
err = d.store.Settings.Save(set)
checkErr(err)
ser := &settings.Server{
BaseURL: getParam(flags, "baseurl"),
Port: getParam(flags, "port"),
Log: getParam(flags, "log"),
TLSKey: getParam(flags, "key"),
TLSCert: getParam(flags, "cert"),
Address: getParam(flags, "address"),
Root: getParam(flags, "root"),
}
err = d.store.Settings.SaveServer(ser)
@ -408,7 +294,7 @@ func initConfig() {
if cfgFile == "" {
v.AddConfigPath(".")
v.AddConfigPath("/etc/filebrowser/")
v.SetConfigName(".filebrowser")
v.SetConfigName("filebrowser")
} else {
v.SetConfigFile(cfgFile)
}

View File

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

View File

@ -7,6 +7,7 @@ require (
github.com/disintegration/imaging v1.6.2
github.com/dsoprea/go-exif/v3 v3.0.1
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/gorilla/mux v1.8.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/dsoprea/go-logging v0.0.0-20200710184922-b02d349568dd // 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/go-errors/errors v1.4.2 // 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/pgzip v1.2.5 // 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/nwaples/rardecode v1.1.0 // indirect
github.com/pierrec/lz4/v4 v4.1.2 // indirect
@ -58,6 +62,7 @@ require (
github.com/yusufpapurcu/wmi v1.2.3 // indirect
golang.org/x/net v0.10.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/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.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/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/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
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-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-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/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
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/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
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/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
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/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/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/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4=
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-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-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-20200202164722-d101bd2416d5/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-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-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-20220722155257-8c9f86f7a55f/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-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-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.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
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) {
auther, err := d.store.Auth.Get(d.settings.AuthMethod)
auther, err := d.store.Auth.Get(d.settings.Auth.Method)
if err != nil {
return http.StatusInternalServerError, err
}

View File

@ -14,7 +14,7 @@ type settingsData struct {
UserHomeBasePath string `json:"userHomeBasePath"`
Defaults settings.UserDefaults `json:"defaults"`
Rules []rules.Rule `json:"rules"`
Branding settings.Branding `json:"branding"`
Frontend settings.Frontend `json:"frontend"`
Shell []string `json:"shell"`
Commands map[string][]string `json:"commands"`
}
@ -26,7 +26,7 @@ var settingsGetHandler = withAdmin(func(w http.ResponseWriter, r *http.Request,
UserHomeBasePath: d.settings.UserHomeBasePath,
Defaults: d.settings.Defaults,
Rules: d.settings.Rules,
Branding: d.settings.Branding,
Frontend: d.settings.Frontend,
Shell: d.settings.Shell,
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.Defaults = req.Defaults
d.settings.Rules = req.Rules
d.settings.Branding = req.Branding
d.settings.Frontend = req.Frontend
d.settings.Shell = req.Shell
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) {
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 {
return http.StatusInternalServerError, err
}
data := map[string]interface{}{
"Name": d.settings.Branding.Name,
"DisableExternal": d.settings.Branding.DisableExternal,
"DisableUsedPercentage": d.settings.Branding.DisableUsedPercentage,
"Color": d.settings.Branding.Color,
"Name": d.settings.Frontend.Name,
"DisableExternal": d.settings.Frontend.DisableExternal,
"DisableUsedPercentage": d.settings.Frontend.DisableUsedPercentage,
"Color": d.settings.Frontend.Color,
"BaseURL": d.server.BaseURL,
"Version": version.Version,
"StaticURL": path.Join(d.server.BaseURL, "/static"),
"Signup": d.settings.Signup,
"NoAuth": d.settings.AuthMethod == auth.MethodNoAuth,
"AuthMethod": d.settings.AuthMethod,
"NoAuth": d.settings.Auth.Method == auth.MethodNoAuth,
"AuthMethod": d.settings.Auth.Method,
"LoginPage": auther.LoginPage(),
"CSS": false,
"ReCaptcha": false,
"Theme": d.settings.Branding.Theme,
"Theme": d.settings.Frontend.Theme,
"EnableThumbs": d.server.EnableThumbnails,
"ResizePreview": d.server.ResizePreview,
"EnableExec": d.server.EnableExec,
}
if d.settings.Branding.Files != "" {
fPath := filepath.Join(d.settings.Branding.Files, "custom.css")
if d.settings.Frontend.Files != "" {
fPath := filepath.Join(d.settings.Frontend.Files, "custom.css")
_, err := os.Stat(fPath) //nolint:govet
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 {
raw, err := d.store.Auth.Get(d.settings.AuthMethod) //nolint:govet
if d.settings.Auth.Method == auth.MethodJSONAuth {
raw, err := d.store.Auth.Get(d.settings.Auth.Method) //nolint:govet
if err != nil {
return http.StatusInternalServerError, err
}
@ -115,15 +115,15 @@ func getStaticHandlers(store *storage.Storage, server *settings.Server, assetsFs
const maxAge = 86400 // 1 day
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/") {
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 {
http.ServeFile(w, r, fPath)
return 0, nil
}
} else if r.URL.Path == "custom.css" && d.settings.Branding.Files != "" {
http.ServeFile(w, r, filepath.Join(d.settings.Branding.Files, "custom.css"))
} else if r.URL.Path == "custom.css" && d.settings.Frontend.Files != "" {
http.ServeFile(w, r, filepath.Join(d.settings.Frontend.Files, "custom.css"))
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
}
func GetSettingsConfig(nameType string,Value string) string {
return nameType + Value
}

View File

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

View File

@ -2,7 +2,6 @@ package bolt
import (
"github.com/asdine/storm/v3"
"github.com/gtsteffaniak/filebrowser/settings"
)
@ -20,7 +19,10 @@ func (s settingsBackend) Save(set *settings.Settings) 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)
}

View File

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

View File

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