updated settings to work :)

This commit is contained in:
Graham Steffaniak 2023-09-03 12:28:00 -05:00
parent ea77a1962a
commit 50958430f7
24 changed files with 194 additions and 420 deletions

View File

@ -3,14 +3,13 @@ package auth
import ( import (
"net/http" "net/http"
"github.com/gtsteffaniak/filebrowser/settings"
"github.com/gtsteffaniak/filebrowser/users" "github.com/gtsteffaniak/filebrowser/users"
) )
// Auther is the authentication interface. // Auther is the authentication interface.
type Auther interface { type Auther interface {
// Auth is called to authenticate a request. // Auth is called to authenticate a request.
Auth(r *http.Request, usr users.Store, stg *settings.Settings, srv *settings.Server) (*users.User, error) Auth(r *http.Request, usr users.Store) (*users.User, error)
// LoginPage indicates if this auther needs a login page. // LoginPage indicates if this auther needs a login page.
LoginPage() bool LoginPage() bool
} }

View File

@ -31,7 +31,7 @@ type HookAuth struct {
} }
// Auth authenticates the user via a json in content body. // Auth authenticates the user via a json in content body.
func (a *HookAuth) Auth(r *http.Request, usr users.Store, stg *settings.Settings, srv *settings.Server) (*users.User, error) { func (a *HookAuth) Auth(r *http.Request, usr users.Store) (*users.User, error) {
var cred hookCred var cred hookCred
if r.Body == nil { if r.Body == nil {
@ -44,8 +44,8 @@ func (a *HookAuth) Auth(r *http.Request, usr users.Store, stg *settings.Settings
} }
a.Users = usr a.Users = usr
a.Settings = stg a.Settings = &settings.GlobalConfiguration
a.Server = srv a.Server = &settings.GlobalConfiguration.Server
a.Cred = cred a.Cred = cred
action, err := a.RunCommand() action, err := a.RunCommand()
@ -150,7 +150,6 @@ func (a *HookAuth) SaveUser() (*users.User, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
// create user with the provided credentials // create user with the provided credentials
d := &users.User{ d := &users.User{
Username: a.Cred.Username, Username: a.Cred.Username,

View File

@ -23,7 +23,8 @@ type JSONAuth struct {
} }
// Auth authenticates the user via a json in content body. // Auth authenticates the user via a json in content body.
func (a JSONAuth) Auth(r *http.Request, usr users.Store, stg *settings.Settings, srv *settings.Server) (*users.User, error) { func (a JSONAuth) Auth(r *http.Request, usr users.Store) (*users.User, error) {
config := &settings.GlobalConfiguration
var cred jsonCred var cred jsonCred
if r.Body == nil { if r.Body == nil {
@ -48,7 +49,7 @@ func (a JSONAuth) Auth(r *http.Request, usr users.Store, stg *settings.Settings,
} }
} }
u, err := usr.Get(srv.Root, cred.Username) u, err := usr.Get(config.Server.Root, cred.Username)
if err != nil || !users.CheckPwd(cred.Password, u.Password) { if err != nil || !users.CheckPwd(cred.Password, u.Password) {
return nil, os.ErrPermission return nil, os.ErrPermission
} }

View File

@ -14,8 +14,8 @@ const MethodNoAuth = "noauth"
type NoAuth struct{} type NoAuth struct{}
// Auth uses authenticates user 1. // Auth uses authenticates user 1.
func (a NoAuth) Auth(r *http.Request, usr users.Store, stg *settings.Settings, srv *settings.Server) (*users.User, error) { func (a NoAuth) Auth(r *http.Request, usr users.Store) (*users.User, error) {
return usr.Get(srv.Root, uint(1)) return usr.Get(settings.GlobalConfiguration.Server.Root, uint(1))
} }
// LoginPage tells that no auth doesn't require a login page. // LoginPage tells that no auth doesn't require a login page.

View File

@ -4,8 +4,9 @@ import (
"net/http" "net/http"
"os" "os"
"github.com/gtsteffaniak/filebrowser/errors"
"github.com/gtsteffaniak/filebrowser/settings" "github.com/gtsteffaniak/filebrowser/settings"
"github.com/gtsteffaniak/filebrowser/errors"
"github.com/gtsteffaniak/filebrowser/users" "github.com/gtsteffaniak/filebrowser/users"
) )
@ -18,9 +19,9 @@ type ProxyAuth struct {
} }
// Auth authenticates the user via an HTTP header. // Auth authenticates the user via an HTTP header.
func (a ProxyAuth) Auth(r *http.Request, usr users.Store, stg *settings.Settings, srv *settings.Server) (*users.User, error) { func (a ProxyAuth) Auth(r *http.Request, usr users.Store) (*users.User, error) {
username := r.Header.Get(a.Header) username := r.Header.Get(a.Header)
user, err := usr.Get(srv.Root, username) user, err := usr.Get(settings.GlobalConfiguration.Server.Root, username)
if err == errors.ErrNotExist { if err == errors.ErrNotExist {
return nil, os.ErrPermission return nil, os.ErrPermission
} }

View File

@ -1,162 +0,0 @@
package cmd
import (
"encoding/json"
nerrors "errors"
"fmt"
"os"
"strings"
"text/tabwriter"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/gtsteffaniak/filebrowser/auth"
"github.com/gtsteffaniak/filebrowser/errors"
"github.com/gtsteffaniak/filebrowser/settings"
)
func init() {
rootCmd.AddCommand(configCmd)
}
var configCmd = &cobra.Command{
Use: "config",
Short: "Configuration management utility",
Long: `Configuration management utility.`,
Args: cobra.NoArgs,
}
func addConfigFlags(flags *pflag.FlagSet) {
addUserFlags(flags)
flags.BoolP("signup", "s", false, "allow users to signup")
flags.String("shell", "", "shell command to which other commands should be appended")
flags.String("recaptcha.host", "https://www.google.com", "use another host for ReCAPTCHA. recaptcha.net might be useful in China")
flags.String("recaptcha.key", "", "ReCaptcha site key")
flags.String("recaptcha.secret", "", "ReCaptcha secret")
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() auth.Auther {
method := settings.GlobalConfiguration.Auth.Method
var defaultAuther map[string]interface{}
var auther auth.Auther
if method == "proxy" {
header := settings.GlobalConfiguration.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 == "noauth" {
auther = &auth.NoAuth{}
}
if method == "password" {
jsonAuth := &auth.JSONAuth{}
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 {
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 == "hook" {
command := settings.GlobalConfiguration.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 auther
}
func printSettings(ser *settings.Server, set *settings.Settings, auther auth.Auther) {
w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0) //nolint:gomnd
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.Auth.Method)
fmt.Fprintf(w, "Shell:\t%s\t\n", strings.Join(set.Shell, " "))
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, "\tBase URL:\t%s\n", ser.BaseURL)
fmt.Fprintf(w, "\tRoot:\t%s\n", ser.Root)
fmt.Fprintf(w, "\tSocket:\t%s\n", ser.Socket)
fmt.Fprintf(w, "\tAddress:\t%s\n", ser.Address)
fmt.Fprintf(w, "\tTLS Cert:\t%s\n", ser.TLSCert)
fmt.Fprintf(w, "\tTLS Key:\t%s\n", ser.TLSKey)
fmt.Fprintf(w, "\tExec Enabled:\t%t\n", ser.EnableExec)
fmt.Fprintln(w, "\nDefaults:")
fmt.Fprintf(w, "\tScope:\t%s\n", set.UserDefaults.Scope)
fmt.Fprintf(w, "\tLocale:\t%s\n", set.UserDefaults.Locale)
fmt.Fprintf(w, "\tView mode:\t%s\n", set.UserDefaults.ViewMode)
fmt.Fprintf(w, "\tSingle Click:\t%t\n", set.UserDefaults.SingleClick)
fmt.Fprintf(w, "\tCommands:\t%s\n", strings.Join(set.UserDefaults.Commands, " "))
fmt.Fprintf(w, "\tSorting:\n")
fmt.Fprintf(w, "\t\tBy:\t%s\n", set.UserDefaults.Sorting.By)
fmt.Fprintf(w, "\t\tAsc:\t%t\n", set.UserDefaults.Sorting.Asc)
fmt.Fprintf(w, "\tPermissions:\n")
fmt.Fprintf(w, "\t\tAdmin:\t%t\n", set.UserDefaults.Perm.Admin)
fmt.Fprintf(w, "\t\tExecute:\t%t\n", set.UserDefaults.Perm.Execute)
fmt.Fprintf(w, "\t\tCreate:\t%t\n", set.UserDefaults.Perm.Create)
fmt.Fprintf(w, "\t\tRename:\t%t\n", set.UserDefaults.Perm.Rename)
fmt.Fprintf(w, "\t\tModify:\t%t\n", set.UserDefaults.Perm.Modify)
fmt.Fprintf(w, "\t\tDelete:\t%t\n", set.UserDefaults.Perm.Delete)
fmt.Fprintf(w, "\t\tShare:\t%t\n", set.UserDefaults.Perm.Share)
fmt.Fprintf(w, "\t\tDownload:\t%t\n", set.UserDefaults.Perm.Download)
w.Flush()
b, err := json.MarshalIndent(auther, "", " ")
checkErr(err)
fmt.Printf("\nAuther configuration (raw):\n\n%s\n\n", string(b))
}

View File

@ -1,25 +0,0 @@
package cmd
import (
"github.com/spf13/cobra"
)
func init() {
configCmd.AddCommand(configCatCmd)
}
var configCatCmd = &cobra.Command{
Use: "cat",
Short: "Prints the configuration",
Long: `Prints the configuration.`,
Args: cobra.NoArgs,
Run: python(func(cmd *cobra.Command, args []string, d pythonData) {
set, err := d.store.Settings.Get()
checkErr(err)
ser, err := d.store.Settings.GetServer()
checkErr(err)
auther, err := d.store.Auth.Get(set.Auth.Method)
checkErr(err)
printSettings(ser, set, auther)
}, pythonConfig{}),
}

View File

@ -1,37 +0,0 @@
package cmd
import (
"github.com/spf13/cobra"
)
func init() {
configCmd.AddCommand(configExportCmd)
}
var configExportCmd = &cobra.Command{
Use: "export <path>",
Short: "Export the configuration to a file",
Long: `Export the configuration to a file. The path must be for a
json or yaml file. This exported configuration can be changed,
and imported again with 'config import' command.`,
Args: jsonYamlArg,
Run: python(func(cmd *cobra.Command, args []string, d pythonData) {
settings, err := d.store.Settings.Get()
checkErr(err)
server, err := d.store.Settings.GetServer()
checkErr(err)
auther, err := d.store.Auth.Get(settings.Auth.Method)
checkErr(err)
data := &settingsFile{
Settings: settings,
Auther: auther,
Server: server,
}
err = marshal(args[0], data)
checkErr(err)
}, pythonConfig{}),
}

View File

@ -3,9 +3,9 @@ package cmd
import ( import (
"encoding/json" "encoding/json"
"errors" "errors"
"log"
"path/filepath" "path/filepath"
"reflect" "reflect"
"log"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -13,10 +13,6 @@ import (
"github.com/gtsteffaniak/filebrowser/settings" "github.com/gtsteffaniak/filebrowser/settings"
) )
func init() {
configCmd.AddCommand(configImportCmd)
}
type settingsFile struct { type settingsFile struct {
Settings *settings.Settings `json:"settings"` Settings *settings.Settings `json:"settings"`
Server *settings.Server `json:"server"` Server *settings.Server `json:"server"`
@ -61,7 +57,7 @@ The path must be for a json or yaml file.`,
} else { } else {
rawAuther = file.Auther rawAuther = file.Auther
} }
log.Println("config_import",file.Settings.Auth) log.Println("config_import", file.Settings.Auth)
var auther auth.Auther var auther auth.Auther
switch file.Settings.Auth.Method { switch file.Settings.Auth.Method {
case "password": case "password":
@ -79,7 +75,6 @@ The path must be for a json or yaml file.`,
err = d.store.Auth.Save(auther) err = d.store.Auth.Save(auther)
checkErr(err) checkErr(err)
printSettings(file.Server, file.Settings, auther)
}, pythonConfig{allowNoDB: true}), }, pythonConfig{allowNoDB: true}),
} }

View File

@ -5,14 +5,11 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/gtsteffaniak/filebrowser/auth"
"github.com/gtsteffaniak/filebrowser/errors"
"github.com/gtsteffaniak/filebrowser/settings" "github.com/gtsteffaniak/filebrowser/settings"
) )
func init() {
configCmd.AddCommand(configInitCmd)
addConfigFlags(configInitCmd.Flags())
}
var configInitCmd = &cobra.Command{ var configInitCmd = &cobra.Command{
Use: "init", Use: "init",
Short: "Initialize a new database", Short: "Initialize a new database",
@ -38,6 +35,45 @@ 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(&s.Server, &s, auther)
}, pythonConfig{noDB: true}), }, pythonConfig{noDB: true}),
} }
//nolint:gocyclo
func getAuthentication() auth.Auther {
method := settings.GlobalConfiguration.Auth.Method
var auther auth.Auther
if method == "proxy" {
header := settings.GlobalConfiguration.Auth.Header
auther = &auth.ProxyAuth{Header: header}
}
if method == "noauth" {
auther = &auth.NoAuth{}
}
if method == "password" {
jsonAuth := &auth.JSONAuth{}
host := settings.GlobalConfiguration.Auth.Recaptcha.Host
key := settings.GlobalConfiguration.Auth.Recaptcha.Key
secret := settings.GlobalConfiguration.Auth.Recaptcha.Secret
if key != "" && secret != "" {
jsonAuth.ReCaptcha = &auth.ReCaptcha{
Host: host,
Key: key,
Secret: secret,
}
}
auther = jsonAuth
}
if method == "hook" {
command := settings.GlobalConfiguration.Auth.Command
auther = &auth.HookAuth{Command: command}
}
if auther == nil {
panic(errors.ErrInvalidAuthMethod)
}
return auther
}

View File

@ -1,74 +0,0 @@
package cmd
import (
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
func init() {
configCmd.AddCommand(configSetCmd)
addConfigFlags(configSetCmd.Flags())
}
var configSetCmd = &cobra.Command{
Use: "set",
Short: "Updates the configuration",
Long: `Updates the configuration. Set the flags for the options
you want to change. Other options will remain unchanged.`,
Args: cobra.NoArgs,
Run: python(func(cmd *cobra.Command, args []string, d pythonData) {
flags := cmd.Flags()
set, err := d.store.Settings.Get()
checkErr(err)
ser, err := d.store.Settings.GetServer()
checkErr(err)
flags.Visit(func(flag *pflag.Flag) {
switch flag.Name {
case "baseurl":
ser.BaseURL = mustGetString(flags, flag.Name)
case "root":
ser.Root = mustGetString(flags, flag.Name)
case "socket":
ser.Socket = mustGetString(flags, flag.Name)
case "cert":
ser.TLSCert = mustGetString(flags, flag.Name)
case "key":
ser.TLSKey = mustGetString(flags, flag.Name)
case "address":
ser.Address = mustGetString(flags, flag.Name)
case "port":
ser.Port = 8080
case "log":
ser.Log = mustGetString(flags, flag.Name)
case "signup":
set.Signup = mustGetBool(flags, flag.Name)
case "shell":
set.Shell = convertCmdStrToCmdArray(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.UserDefaults, false)
// read the defaults
auther := getAuthentication()
err = d.store.Auth.Save(auther)
checkErr(err)
err = d.store.Settings.Save(set)
checkErr(err)
err = d.store.Settings.SaveServer(ser)
checkErr(err)
printSettings(ser, set, auther)
}, pythonConfig{}),
}

View File

@ -210,50 +210,18 @@ func setupLog(logMethod string) {
} }
func quickSetup(flags *pflag.FlagSet, d pythonData) { func quickSetup(flags *pflag.FlagSet, d pythonData) {
set := &settings.Settings{ settings.GlobalConfiguration.Key = generateKey()
Key: generateKey(),
Signup: false,
CreateUserDir: false,
UserHomeBasePath: settings.DefaultUsersHomeBasePath,
UserDefaults: settings.UserDefaults{
Scope: ".",
Locale: "en",
SingleClick: false,
Perm: users.Permissions{
Admin: false,
Execute: true,
Create: true,
Rename: true,
Modify: true,
Delete: true,
Share: true,
Download: true,
},
},
Frontend: settings.Frontend{},
Commands: nil,
Shell: nil,
Rules: nil,
}
var err error var err error
if settings.GlobalConfiguration.Auth.Method == "noauth" { if settings.GlobalConfiguration.Auth.Method == "noauth" {
set.Auth.Method = "noauth" settings.GlobalConfiguration.Auth.Method = "noauth"
err = d.store.Auth.Save(&auth.NoAuth{}) err = d.store.Auth.Save(&auth.NoAuth{})
} else { } else {
set.Auth.Method = "password" settings.GlobalConfiguration.Auth.Method = "password"
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(&settings.GlobalConfiguration)
checkErr(err) checkErr(err)
err = d.store.Settings.SaveServer(&settings.GlobalConfiguration.Server)
ser := &settings.Server{
BaseURL: getParam(flags, "baseurl"),
Log: getParam(flags, "log"),
TLSKey: getParam(flags, "key"),
TLSCert: getParam(flags, "cert"),
Root: getParam(flags, "root"),
}
err = d.store.Settings.SaveServer(ser)
checkErr(err) checkErr(err)
username := getParam(flags, "username") username := getParam(flags, "username")
@ -274,7 +242,7 @@ func quickSetup(flags *pflag.FlagSet, d pythonData) {
LockPassword: false, LockPassword: false,
} }
set.UserDefaults.Apply(user) settings.GlobalConfiguration.UserDefaults.Apply(user)
user.Perm.Admin = true user.Perm.Admin = true
err = d.store.Users.Save(user) err = d.store.Users.Save(user)

View File

@ -19,7 +19,6 @@ var usersAddCmd = &cobra.Command{
Run: python(func(cmd *cobra.Command, args []string, d pythonData) { Run: python(func(cmd *cobra.Command, args []string, d pythonData) {
s, err := d.store.Settings.Get() s, err := d.store.Settings.Get()
checkErr(err) checkErr(err)
getUserDefaults(cmd.Flags(), &s.UserDefaults, false)
password, err := users.HashPwd(args[1]) password, err := users.HashPwd(args[1])
checkErr(err) checkErr(err)

View File

@ -49,7 +49,6 @@ options you want to change.`,
Sorting: user.Sorting, Sorting: user.Sorting,
Commands: user.Commands, Commands: user.Commands,
} }
getUserDefaults(flags, &defaults, false)
user.Scope = defaults.Scope user.Scope = defaults.Scope
user.Locale = defaults.Locale user.Locale = defaults.Locale
user.ViewMode = defaults.ViewMode user.ViewMode = defaults.ViewMode

View File

@ -1,11 +1,11 @@
server: server:
indexingInterval: 5 indexingInterval: 60
numImageProcessors: 2 numImageProcessors: 8
socket: "" socket: ""
tlsKey: "" tlsKey: ""
tlsCert: "" tlsCert: ""
enableThumbnails: false enableThumbnails: true
resizePreview: true resizePreview: false
typeDetectionByHeader: true typeDetectionByHeader: true
port: 8080 port: 8080
baseURL: "/" baseURL: "/"
@ -21,7 +21,7 @@ auth:
header: "" header: ""
method: noauth method: noauth
command: "" command: ""
signup: false signup: true
shell: "" shell: ""
frontend: frontend:
name: "" name: ""
@ -34,7 +34,7 @@ userDefaults:
scope: "" scope: ""
locale: "" locale: ""
viewMode: "" viewMode: ""
singleClick: true singleClick: false
sorting: sorting:
by: "" by: ""
asc: true asc: true

View File

@ -9,12 +9,11 @@ require (
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/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/google/go-cmp v0.5.9
github.com/gorilla/mux v1.8.0 github.com/gorilla/mux v1.8.0
github.com/gorilla/websocket v1.5.0
github.com/maruel/natural v1.1.0 github.com/maruel/natural v1.1.0
github.com/marusama/semaphore/v2 v2.5.0 github.com/marusama/semaphore/v2 v2.5.0
github.com/mholt/archiver/v3 v3.5.1 github.com/mholt/archiver/v3 v3.5.1
github.com/pelletier/go-toml/v2 v2.0.9
github.com/shirou/gopsutil/v3 v3.23.7 github.com/shirou/gopsutil/v3 v3.23.7
github.com/spf13/afero v1.9.5 github.com/spf13/afero v1.9.5
github.com/spf13/cobra v1.7.0 github.com/spf13/cobra v1.7.0
@ -22,7 +21,6 @@ require (
github.com/spf13/viper v1.16.0 github.com/spf13/viper v1.16.0
github.com/stretchr/testify v1.8.4 github.com/stretchr/testify v1.8.4
github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce
go.etcd.io/bbolt v1.3.7
golang.org/x/crypto v0.12.0 golang.org/x/crypto v0.12.0
golang.org/x/image v0.11.0 golang.org/x/image v0.11.0
golang.org/x/text v0.12.0 golang.org/x/text v0.12.0
@ -51,6 +49,7 @@ require (
github.com/mattn/go-isatty v0.0.14 // 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/pelletier/go-toml/v2 v2.0.9 // indirect
github.com/pierrec/lz4/v4 v4.1.2 // indirect github.com/pierrec/lz4/v4 v4.1.2 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
@ -60,6 +59,7 @@ require (
github.com/ulikunitz/xz v0.5.9 // indirect github.com/ulikunitz/xz v0.5.9 // indirect
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
github.com/yusufpapurcu/wmi v1.2.3 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect
go.etcd.io/bbolt v1.3.7 // 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 golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect

View File

@ -178,8 +178,6 @@ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5m
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=

View File

@ -107,7 +107,7 @@ var loginHandler = func(w http.ResponseWriter, r *http.Request, d *data) (int, e
return http.StatusInternalServerError, err return http.StatusInternalServerError, err
} }
user, err := auther.Auth(r, d.store.Users, d.settings, d.server) user, err := auther.Auth(r, d.store.Users)
if err == os.ErrPermission { if err == os.ErrPermission {
return http.StatusForbidden, nil return http.StatusForbidden, nil
} else if err != nil { } else if err != nil {
@ -177,6 +177,7 @@ var renewHandler = withUser(func(w http.ResponseWriter, r *http.Request, d *data
}) })
func printToken(w http.ResponseWriter, _ *http.Request, d *data, user *users.User) (int, error) { func printToken(w http.ResponseWriter, _ *http.Request, d *data, user *users.User) (int, error) {
log.Printf("%#v", user)
claims := &authToken{ claims := &authToken{
User: userInfo{ User: userInfo{
ID: user.ID, ID: user.ID,

View File

@ -1,43 +1,31 @@
package settings package settings
import ( import (
"fmt"
"log" "log"
"os" "os"
"path/filepath"
"github.com/goccy/go-yaml" "github.com/goccy/go-yaml"
) )
var GlobalConfiguration Settings var GlobalConfiguration Settings
var configYml = "filebrowser.yaml"
func Initialize() { func Initialize() {
// Open and read the YAML file yamlData := loadConfigFile()
yamlFile, err := os.Open("filebrowser.yaml") GlobalConfiguration = setDefaults()
err := yaml.Unmarshal(yamlData, &GlobalConfiguration)
if err != nil { if err != nil {
log.Println("Error opening config file: ", err) log.Fatalf("Error unmarshaling YAML data: %v", err)
log.Println("Using default config only") }
// Get the current directory }
dir, err := os.Getwd()
if err != nil {
fmt.Println("Error:", err)
return
}
// Use the filepath package to join the directory and file names func loadConfigFile() []byte {
err = filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { // Open and read the YAML file
if err != nil { yamlFile, err := os.Open(configYml)
fmt.Println("Error:", err) if err != nil {
return err log.Printf("Error opening config file: %v\nUsing default config only", err)
}
// Check if it's a regular file (not a directory)
if !info.IsDir() {
fmt.Println(path)
}
return nil
})
setDefaults() setDefaults()
return return []byte{}
} }
defer yamlFile.Close() defer yamlFile.Close()
@ -51,22 +39,16 @@ func Initialize() {
if err != nil { if err != nil {
log.Fatalf("Error reading YAML data: %v", err) log.Fatalf("Error reading YAML data: %v", err)
} }
// Unmarshal the YAML data into the Settings struct return yamlData
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() { func setDefaults() Settings {
GlobalConfiguration = Settings{ return Settings{
Signup: true, Signup: true,
Server: Server{ Server: Server{
IndexingInterval: 5, IndexingInterval: 5,
Port: 8080, Port: 8080,
NumImageProcessors: 1, NumImageProcessors: 4,
BaseURL: "", BaseURL: "",
}, },
Auth: Auth{ Auth: Auth{
@ -75,5 +57,8 @@ func setDefaults() {
Host: "", Host: "",
}, },
}, },
UserDefaults: UserDefaults{
HideDotfiles: true,
},
} }
} }

View File

@ -1,10 +1,46 @@
package settings package settings
import ( import (
"log"
"testing" "testing"
"github.com/goccy/go-yaml"
"github.com/google/go-cmp/cmp"
) )
func TestConfigLoad(t *testing.T) { func TestConfigLoadChanged(t *testing.T) {
Initialize() configYml = "./testingConfig.yaml"
t.Log("Say bye") yamlData := loadConfigFile()
// Marshal the YAML data to a more human-readable format
newConfig := setDefaults()
GlobalConfiguration := setDefaults()
err := yaml.Unmarshal(yamlData, &newConfig)
if err != nil {
log.Fatalf("Error unmarshaling YAML data: %v", err)
}
// Use go-cmp to compare the two structs
if diff := cmp.Diff(newConfig, GlobalConfiguration); diff == "" {
t.Errorf("No change when there should have been (-want +got):\n%s", diff)
}
}
func TestConfigLoadSpecificValues(t *testing.T) {
configYml = "./testingConfig.yaml"
yamlData := loadConfigFile()
// Marshal the YAML data to a more human-readable format
newConfig := setDefaults()
GlobalConfiguration := setDefaults()
err := yaml.Unmarshal(yamlData, &newConfig)
if err != nil {
log.Fatalf("Error unmarshaling YAML data: %v", err)
}
if GlobalConfiguration.Auth.Method == newConfig.Auth.Method {
log.Fatalf("Differences should have been found, but were not on Auth method")
}
if GlobalConfiguration.UserDefaults.HideDotfiles == newConfig.UserDefaults.HideDotfiles {
log.Fatalf("Differences should have been found, but were not on Auth method")
}
} }

View File

@ -64,7 +64,6 @@ type Server struct {
Log string `json:"log"` Log string `json:"log"`
Database string `json:"database"` Database string `json:"database"`
Root string `json:"root"` Root string `json:"root"`
EnablePreviewResize bool `json:"enablePreviewResize"`
} }
type Frontend struct { type Frontend struct {

View File

@ -0,0 +1,52 @@
server:
indexingInterval: 5
numImageProcessors: 4
socket: ""
tlsKey: ""
tlsCert: ""
enableThumbnails: false
resizePreview: true
typeDetectionByHeader: true
port: 8080
baseURL: "/"
address: ""
log: "stdout"
database: "database.db"
root: "/srv"
auth:
recaptcha:
host: ""
key: ""
secret: ""
header: ""
method: json
command: ""
signup: false
shell: ""
frontend:
name: ""
disableExternal: false
disableUsedPercentage: true
files: ""
theme: ""
color: ""
userDefaults:
scope: ""
locale: ""
viewMode: ""
singleClick: true
sorting:
by: ""
asc: true
perm:
admin: true
execute: true
create: true
rename: true
modify: true
delete: true
share: true
download: true
commands: []
hideDotfiles: false
dateFormat: false

View File

@ -1,12 +1,15 @@
package bolt package bolt
import ( import (
"log"
"github.com/asdine/storm/v3" "github.com/asdine/storm/v3"
"github.com/gtsteffaniak/filebrowser/errors" "github.com/gtsteffaniak/filebrowser/errors"
) )
func get(db *storm.DB, name string, to interface{}) error { func get(db *storm.DB, name string, to interface{}) error {
log.Printf("name, %v , to %#v", name, to)
err := db.Get("config", name, to) err := db.Get("config", name, to)
if err == storm.ErrNotFound { if err == storm.ErrNotFound {
return errors.ErrNotExist return errors.ErrNotExist
@ -16,5 +19,6 @@ func get(db *storm.DB, name string, to interface{}) error {
} }
func save(db *storm.DB, name string, from interface{}) error { func save(db *storm.DB, name string, from interface{}) error {
log.Printf("name, %v , from %#v", name, from)
return db.Set("config", name, from) return db.Set("config", name, from)
} }

View File

@ -56,7 +56,7 @@
<p> <p>
<input <input
type="checkbox" type="checkbox"
v-model="settings.branding.disableExternal" v-model="settings.frontend.disableExternal"
id="branding-links" id="branding-links"
/> />
{{ $t("settings.disableExternalLinks") }} {{ $t("settings.disableExternalLinks") }}
@ -65,7 +65,7 @@
<p> <p>
<input <input
type="checkbox" type="checkbox"
v-model="settings.branding.disableUsedPercentage" v-model="settings.frontend.disableUsedPercentage"
id="branding-links" id="branding-links"
/> />
{{ $t("settings.disableUsedDiskPercentage") }} {{ $t("settings.disableUsedDiskPercentage") }}
@ -75,7 +75,7 @@
<label for="theme">{{ $t("settings.themes.title") }}</label> <label for="theme">{{ $t("settings.themes.title") }}</label>
<themes <themes
class="input input--block" class="input input--block"
:theme.sync="settings.branding.theme" :theme.sync="settings.frontend.theme"
id="theme" id="theme"
></themes> ></themes>
</p> </p>
@ -85,7 +85,7 @@
<input <input
class="input input--block" class="input input--block"
type="text" type="text"
v-model="settings.branding.name" v-model="settings.frontend.name"
id="branding-name" id="branding-name"
/> />
</p> </p>
@ -97,7 +97,7 @@
<input <input
class="input input--block" class="input input--block"
type="text" type="text"
v-model="settings.branding.files" v-model="settings.frontend.files"
id="branding-files" id="branding-files"
/> />
</p> </p>