add settings/runtime.go
This commit is contained in:
parent
25c009a560
commit
b178c6af99
@ -28,7 +28,7 @@ override the options.`,
|
||||
authMethod, auther := getAuthentication(cmd)
|
||||
|
||||
s := &settings.Settings{
|
||||
Key: generateRandomBytes(64), // 256 bit
|
||||
Runtime: runtimeNonDefaults(),
|
||||
Signup: mustGetBool(cmd, "signup"),
|
||||
Shell: strings.Split(strings.TrimSpace(mustGetString(cmd, "shell")), " "),
|
||||
AuthMethod: authMethod,
|
||||
|
||||
89
cmd/root.go
89
cmd/root.go
@ -2,13 +2,13 @@ package cmd
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/filebrowser/filebrowser/v2/auth"
|
||||
@ -35,15 +35,16 @@ func init() {
|
||||
|
||||
pf.StringVarP(&cfgFile, "config", "c", "", "config file path")
|
||||
vaddP(pf, "database", "d", "./filebrowser.db", "path to the database")
|
||||
vaddP(f, "address", "a", "127.0.0.1", "address to listen on")
|
||||
vaddP(f, "log", "l", "stdout", "log output")
|
||||
vaddP(f, "port", "p", 8080, "port to listen on")
|
||||
vaddP(f, "cert", "t", "", "tls certificate")
|
||||
vaddP(f, "key", "k", "", "tls key")
|
||||
vaddP(f, "root", "r", ".", "root to prepend to relative paths")
|
||||
vaddP(f, "baseurl", "b", "", "base url")
|
||||
vaddP(f, "address", "a", settings.RuntimeDefaults["address"], "address to listen on")
|
||||
vaddP(f, "log", "l", settings.RuntimeDefaults["log"], "log output")
|
||||
vaddP(f, "port", "p", settings.RuntimeDefaults["port"], "port to listen on")
|
||||
vaddP(f, "cert", "t", settings.RuntimeDefaults["cert"], "tls certificate")
|
||||
vaddP(f, "key", "k", settings.RuntimeDefaults["key"], "tls key")
|
||||
vaddP(f, "root", "r", settings.RuntimeDefaults["root"], "root path to prepend to all relative paths")
|
||||
vaddP(f, "baseurl", "b", settings.RuntimeDefaults["baseurl"], "base url")
|
||||
vadd(f, "username", "admin", "username for the first user when using quick config")
|
||||
vadd(f, "password", "", "hashed password for the first user when using quick config (default \"admin\")")
|
||||
vaddP(f, "force", "f", false, "")
|
||||
|
||||
if err := v.BindPFlags(f); err != nil {
|
||||
panic(err)
|
||||
@ -97,7 +98,7 @@ user created with the credentials from options "username" and "password".`,
|
||||
|
||||
log.Println(cfgFile)
|
||||
|
||||
switch logMethod := v.GetString("log"); logMethod {
|
||||
switch logMethod := settings.RuntimeCfg["log"]; logMethod {
|
||||
case "stdout":
|
||||
log.SetOutput(os.Stdout)
|
||||
case "stderr":
|
||||
@ -117,44 +118,40 @@ user created with the credentials from options "username" and "password".`,
|
||||
quickSetup(d)
|
||||
}
|
||||
|
||||
// TODO: check if these fields (including baseurl) are available in the DB. proceed according to --force
|
||||
|
||||
port := v.GetInt("port")
|
||||
address := v.GetString("address")
|
||||
cert := v.GetString("cert")
|
||||
key := v.GetString("key")
|
||||
root := v.GetString("root")
|
||||
|
||||
root, err := filepath.Abs(root)
|
||||
checkErr(err)
|
||||
settings, err := d.store.Settings.Get()
|
||||
s, err := d.store.Settings.Get()
|
||||
checkErr(err)
|
||||
|
||||
// Despite Base URL and Scope being "server" type of
|
||||
// variables, we persist them to the database because
|
||||
// they are needed during the execution and not only
|
||||
// to start up the server.
|
||||
settings.BaseURL = v.GetString("baseurl")
|
||||
settings.Root = root
|
||||
err = d.store.Settings.Save(settings)
|
||||
checkErr(err)
|
||||
if !v.GetBool("force") {
|
||||
for k := range settings.RuntimeCfg {
|
||||
if y, ok := s.Runtime[k]; ok {
|
||||
settings.RuntimeCfg[k] = y
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handler, err := fbhttp.NewHandler(d.store)
|
||||
r, err := filepath.Abs(settings.RuntimeCfg["root"])
|
||||
checkErr(err)
|
||||
settings.RuntimeCfg["root"] = r
|
||||
|
||||
adr := settings.RuntimeCfg["address"] + ":" + settings.RuntimeCfg["port"]
|
||||
cert := settings.RuntimeCfg["cert"]
|
||||
key := settings.RuntimeCfg["key"]
|
||||
|
||||
var listener net.Listener
|
||||
|
||||
if key != "" && cert != "" {
|
||||
cer, err := tls.LoadX509KeyPair(cert, key)
|
||||
checkErr(err)
|
||||
config := &tls.Config{Certificates: []tls.Certificate{cer}}
|
||||
listener, err = tls.Listen("tcp", address+":"+strconv.Itoa(port), config)
|
||||
listener, err = tls.Listen("tcp", adr, &tls.Config{Certificates: []tls.Certificate{cer}})
|
||||
checkErr(err)
|
||||
} else {
|
||||
listener, err = net.Listen("tcp", address+":"+strconv.Itoa(port))
|
||||
listener, err = net.Listen("tcp", adr)
|
||||
checkErr(err)
|
||||
}
|
||||
|
||||
handler, err := fbhttp.NewHandler(d.store)
|
||||
checkErr(err)
|
||||
|
||||
log.Println("Listening on", listener.Addr().String())
|
||||
if err := http.Serve(listener, handler); err != nil {
|
||||
log.Fatal(err)
|
||||
@ -162,13 +159,26 @@ user created with the credentials from options "username" and "password".`,
|
||||
}, pythonConfig{allowNoDB: true}),
|
||||
}
|
||||
|
||||
func runtimeNonDefaults() (m map[string]string) {
|
||||
for k, d := range settings.RuntimeDefaults {
|
||||
if x, ok := settings.RuntimeCfg[k]; ok && (x != d) {
|
||||
log.Println(fmt.Sprintf("Non-default value for key '%s': %s [default: %s]", k, x, d))
|
||||
m[k] = x
|
||||
}
|
||||
}
|
||||
if settings.RuntimeCfg["key"] == "" {
|
||||
log.Println("Generate random 256 bit key")
|
||||
m["key"] = string(generateRandomBytes(64)) // 256 bit
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func quickSetup(d pythonData) {
|
||||
|
||||
// TODO: save also port, address, cert, key, scope; if their values differ from defaults
|
||||
log.Println("Executing quick setup...")
|
||||
|
||||
set := &settings.Settings{
|
||||
Key: generateRandomBytes(64), // 256 bit
|
||||
BaseURL: v.GetString("baseurl"),
|
||||
Runtime: runtimeNonDefaults(),
|
||||
Signup: false,
|
||||
AuthMethod: auth.MethodJSONAuth,
|
||||
Defaults: settings.UserDefaults{
|
||||
@ -216,6 +226,8 @@ func quickSetup(d pythonData) {
|
||||
|
||||
err = d.store.Users.Save(user)
|
||||
checkErr(err)
|
||||
|
||||
log.Println("Quick setup finished")
|
||||
}
|
||||
|
||||
func initConfig() {
|
||||
@ -239,6 +251,11 @@ func initConfig() {
|
||||
panic(err)
|
||||
}
|
||||
cfgFile = "No config file used"
|
||||
} else {
|
||||
cfgFile = "Using config file: " + v.ConfigFileUsed()
|
||||
}
|
||||
|
||||
for k := range settings.RuntimeDefaults {
|
||||
settings.RuntimeCfg[k] = v.GetString(k)
|
||||
}
|
||||
cfgFile = "Using config file: " + v.ConfigFileUsed()
|
||||
}
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"github.com/filebrowser/filebrowser/v2/settings"
|
||||
"github.com/filebrowser/filebrowser/v2/storage/bolt/importer"
|
||||
"github.com/spf13/cobra"
|
||||
v "github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@ -26,7 +26,7 @@ this version.`,
|
||||
oldDB := mustGetString(cmd, "old.database")
|
||||
oldConf := mustGetString(cmd, "old.config")
|
||||
|
||||
err := importer.Import(oldDB, oldConf, v.GetString("database"))
|
||||
err := importer.Import(oldDB, oldConf, settings.RuntimeCfg["database"])
|
||||
checkErr(err)
|
||||
},
|
||||
}
|
||||
|
||||
@ -7,9 +7,10 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
jwt "github.com/dgrijalva/jwt-go"
|
||||
"github.com/dgrijalva/jwt-go/request"
|
||||
"github.com/filebrowser/filebrowser/v2/errors"
|
||||
"github.com/filebrowser/filebrowser/v2/settings"
|
||||
"github.com/filebrowser/filebrowser/v2/users"
|
||||
)
|
||||
|
||||
@ -50,7 +51,7 @@ func (e extractor) ExtractToken(r *http.Request) (string, error) {
|
||||
func withUser(fn handleFunc) handleFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request, d *data) (int, error) {
|
||||
keyFunc := func(token *jwt.Token) (interface{}, error) {
|
||||
return d.settings.Key, nil
|
||||
return settings.RuntimeCfg["key"], nil
|
||||
}
|
||||
|
||||
var tk authToken
|
||||
@ -67,7 +68,7 @@ func withUser(fn handleFunc) handleFunc {
|
||||
w.Header().Add("X-Renew-Token", "true")
|
||||
}
|
||||
|
||||
d.user, err = d.store.Users.Get(d.settings.Root, tk.User.ID)
|
||||
d.user, err = d.store.Users.Get(settings.RuntimeCfg["root"], tk.User.ID)
|
||||
if err != nil {
|
||||
return http.StatusInternalServerError, err
|
||||
}
|
||||
@ -169,7 +170,7 @@ func printToken(w http.ResponseWriter, r *http.Request, d *data, user *users.Use
|
||||
}
|
||||
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
||||
signed, err := token.SignedString(d.settings.Key)
|
||||
signed, err := token.SignedString(settings.RuntimeCfg["key"])
|
||||
if err != nil {
|
||||
return http.StatusInternalServerError, err
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/filebrowser/filebrowser/v2/files"
|
||||
"github.com/filebrowser/filebrowser/v2/settings"
|
||||
)
|
||||
|
||||
var withHashFile = func(fn handleFunc) handleFunc {
|
||||
@ -13,7 +14,7 @@ var withHashFile = func(fn handleFunc) handleFunc {
|
||||
return errToStatus(err), err
|
||||
}
|
||||
|
||||
user, err := d.store.Users.Get(d.settings.Root, link.UserID)
|
||||
user, err := d.store.Users.Get(settings.RuntimeCfg["root"], link.UserID)
|
||||
if err != nil {
|
||||
return errToStatus(err), err
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/filebrowser/filebrowser/v2/errors"
|
||||
"github.com/filebrowser/filebrowser/v2/settings"
|
||||
"github.com/filebrowser/filebrowser/v2/share"
|
||||
)
|
||||
|
||||
@ -56,7 +57,7 @@ var sharePostHandler = withPermShare(func(w http.ResponseWriter, r *http.Request
|
||||
var err error
|
||||
s, err = d.store.Share.GetPermanent(r.URL.Path, d.user.ID)
|
||||
if err == nil {
|
||||
w.Write([]byte(d.settings.BaseURL + "/share/" + s.Hash))
|
||||
w.Write([]byte(settings.RuntimeCfg["baseurl"] + "/share/" + s.Hash))
|
||||
return 0, nil
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,8 +9,9 @@ import (
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/GeertJohan/go.rice"
|
||||
rice "github.com/GeertJohan/go.rice"
|
||||
"github.com/filebrowser/filebrowser/v2/auth"
|
||||
"github.com/filebrowser/filebrowser/v2/settings"
|
||||
"github.com/filebrowser/filebrowser/v2/storage"
|
||||
"github.com/filebrowser/filebrowser/v2/version"
|
||||
)
|
||||
@ -18,12 +19,12 @@ import (
|
||||
func handleWithStaticData(w http.ResponseWriter, r *http.Request, d *data, box *rice.Box, file, contentType string) (int, error) {
|
||||
w.Header().Set("Content-Type", contentType)
|
||||
|
||||
staticURL := strings.TrimPrefix(d.settings.BaseURL+"/static", "/")
|
||||
staticURL := strings.TrimPrefix(settings.RuntimeCfg["baseurl"]+"/static", "/")
|
||||
|
||||
data := map[string]interface{}{
|
||||
"Name": d.settings.Branding.Name,
|
||||
"DisableExternal": d.settings.Branding.DisableExternal,
|
||||
"BaseURL": d.settings.BaseURL,
|
||||
"BaseURL": settings.RuntimeCfg["baseurl"],
|
||||
"Version": version.Version,
|
||||
"StaticURL": staticURL,
|
||||
"Signup": d.settings.Signup,
|
||||
|
||||
@ -8,6 +8,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/filebrowser/filebrowser/v2/errors"
|
||||
"github.com/filebrowser/filebrowser/v2/settings"
|
||||
"github.com/filebrowser/filebrowser/v2/users"
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
@ -61,7 +62,7 @@ func withSelfOrAdmin(fn handleFunc) handleFunc {
|
||||
}
|
||||
|
||||
var usersGetHandler = withAdmin(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) {
|
||||
users, err := d.store.Users.Gets(d.settings.Root)
|
||||
users, err := d.store.Users.Gets(settings.RuntimeCfg["root"])
|
||||
if err != nil {
|
||||
return http.StatusInternalServerError, err
|
||||
}
|
||||
@ -78,7 +79,7 @@ var usersGetHandler = withAdmin(func(w http.ResponseWriter, r *http.Request, d *
|
||||
})
|
||||
|
||||
var userGetHandler = withSelfOrAdmin(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) {
|
||||
u, err := d.store.Users.Get(d.settings.Root, d.raw.(uint))
|
||||
u, err := d.store.Users.Get(settings.RuntimeCfg["root"], d.raw.(uint))
|
||||
if err == errors.ErrNotExist {
|
||||
return http.StatusNotFound, err
|
||||
}
|
||||
@ -147,7 +148,7 @@ var userPutHandler = withSelfOrAdmin(func(w http.ResponseWriter, r *http.Request
|
||||
req.Data.Password, err = users.HashPwd(req.Data.Password)
|
||||
} else {
|
||||
var suser *users.User
|
||||
suser, err = d.store.Users.Get(d.settings.Root, d.raw.(uint))
|
||||
suser, err = d.store.Users.Get(settings.RuntimeCfg["root"], d.raw.(uint))
|
||||
req.Data.Password = suser.Password
|
||||
}
|
||||
|
||||
|
||||
15
settings/runtime.go
Normal file
15
settings/runtime.go
Normal file
@ -0,0 +1,15 @@
|
||||
package settings
|
||||
|
||||
// RuntimeDefaults defines default values for runtime parameters
|
||||
var RuntimeDefaults = map[string]string{
|
||||
"root": ".",
|
||||
"baseurl": "",
|
||||
"address": "127.0.0.1",
|
||||
"port": "8080",
|
||||
"cert": "",
|
||||
"key": "",
|
||||
"log": "stdout",
|
||||
}
|
||||
|
||||
// RuntimeCfg contains parameters to be used at runtime
|
||||
var RuntimeCfg = map[string]string{}
|
||||
@ -7,9 +7,7 @@ type AuthMethod string
|
||||
|
||||
// Settings contain the main settings of the application.
|
||||
type Settings struct {
|
||||
Key []byte `json:"key"`
|
||||
BaseURL string `json:"baseURL"`
|
||||
Root string `json:"root"`
|
||||
Runtime map[string]string `json:"runtime"`
|
||||
Signup bool `json:"signup"`
|
||||
Defaults UserDefaults `json:"defaults"`
|
||||
AuthMethod AuthMethod `json:"authMethod"`
|
||||
|
||||
@ -1,9 +1,6 @@
|
||||
package settings
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/filebrowser/filebrowser/v2/errors"
|
||||
"github.com/filebrowser/filebrowser/v2/rules"
|
||||
"github.com/filebrowser/filebrowser/v2/users"
|
||||
)
|
||||
@ -39,12 +36,13 @@ var defaultEvents = []string{
|
||||
|
||||
// Save saves the settings for the current instance.
|
||||
func (s *Storage) Save(set *Settings) error {
|
||||
set.BaseURL = strings.TrimSuffix(set.BaseURL, "/")
|
||||
|
||||
if len(set.Key) == 0 {
|
||||
return errors.ErrEmptyKey
|
||||
}
|
||||
/*
|
||||
set.BaseURL = strings.TrimSuffix(set.BaseURL, "/")
|
||||
|
||||
if len(set.Key) == 0 {
|
||||
return errors.ErrEmptyKey
|
||||
}
|
||||
*/
|
||||
if set.Defaults.Locale == "" {
|
||||
set.Defaults.Locale = "en"
|
||||
}
|
||||
|
||||
@ -13,8 +13,8 @@ import (
|
||||
"github.com/asdine/storm"
|
||||
"github.com/filebrowser/filebrowser/v2/settings"
|
||||
"github.com/filebrowser/filebrowser/v2/storage"
|
||||
"github.com/pelletier/go-toml"
|
||||
"gopkg.in/yaml.v2"
|
||||
toml "github.com/pelletier/go-toml"
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
type oldDefs struct {
|
||||
@ -109,9 +109,9 @@ func importConf(db *storm.DB, path string, sto *storage.Storage) error {
|
||||
}
|
||||
|
||||
s := &settings.Settings{
|
||||
Key: key,
|
||||
BaseURL: cfg.BaseURL,
|
||||
Signup: false,
|
||||
//Key: key,
|
||||
//BaseURL: cfg.BaseURL,
|
||||
Signup: false,
|
||||
Defaults: settings.UserDefaults{
|
||||
Scope: cfg.Defaults.Scope,
|
||||
Commands: cfg.Defaults.Commands,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user