feat: merge with master

License: MIT
Signed-off-by: Henrique Dias <hacdias@gmail.com>
This commit is contained in:
Henrique Dias 2019-01-06 12:34:46 +00:00
commit 2d33e29bec
10 changed files with 79 additions and 158 deletions

View File

@ -34,13 +34,6 @@ func addConfigFlags(cmd *cobra.Command) {
cmd.Flags().StringP("baseURL", "b", "/", "base url of this installation")
cmd.Flags().BoolP("signup", "s", false, "allow users to signup")
cmd.Flags().String("shell", "", "shell command to which other commands should be appended")
cmd.Flags().String("scope", "", "scope to prepend to a user's scope when it is relative (default is current working directory)")
cmd.Flags().StringP("address", "a", "127.0.0.1", "default address to listen to")
cmd.Flags().StringP("log", "l", "stderr", "log output")
cmd.Flags().IntP("port", "p", 0, "default port to listen to")
cmd.Flags().String("tls.cert", "", "tls certificate path")
cmd.Flags().String("tls.key", "", "tls key path")
cmd.Flags().String("auth.method", string(auth.MethodJSONAuth), "authentication type")
cmd.Flags().String("auth.header", "", "HTTP header for auth.method=proxy")
@ -102,13 +95,6 @@ func printSettings(s *settings.Settings, auther auth.Auther) {
fmt.Fprintf(w, "Sign up:\t%t\n", s.Signup)
fmt.Fprintf(w, "Auth method:\t%s\n", s.AuthMethod)
fmt.Fprintf(w, "Shell:\t%s\t\n", strings.Join(s.Shell, " "))
fmt.Fprintf(w, "Log:\t%s\t\n", s.Log)
fmt.Fprintf(w, "Scope:\t%s\t\n", s.Scope)
fmt.Fprintln(w, "\nServer:")
fmt.Fprintf(w, "\tAddress:\t%s\n", s.Server.Address)
fmt.Fprintf(w, "\tPort:\t%d\n", s.Server.Port)
fmt.Fprintf(w, "\tTLS Cert:\t%s\n", s.Server.TLSCert)
fmt.Fprintf(w, "\tTLS Key:\t%s\n", s.Server.TLSKey)
fmt.Fprintln(w, "\nBranding:")
fmt.Fprintf(w, "\tName:\t%s\n", s.Branding.Name)
fmt.Fprintf(w, "\tFiles override:\t%s\n", s.Branding.Files)

View File

@ -49,18 +49,11 @@ override the options.`,
s := &settings.Settings{
Key: generateRandomBytes(64), // 256 bit
BaseURL: mustGetString(cmd, "baseURL"),
Log: mustGetString(cmd, "log"),
Signup: mustGetBool(cmd, "signup"),
Scope: scope,
Shell: strings.Split(strings.TrimSpace(mustGetString(cmd, "shell")), " "),
AuthMethod: authMethod,
Defaults: defaults,
Server: settings.Server{
Address: mustGetString(cmd, "address"),
Port: mustGetInt(cmd, "port"),
TLSCert: mustGetString(cmd, "tls.cert"),
TLSKey: mustGetString(cmd, "tls.key"),
},
Branding: settings.Branding{
Name: mustGetString(cmd, "branding.name"),
DisableExternal: mustGetBool(cmd, "branding.disableExternal"),

View File

@ -44,16 +44,6 @@ you want to change.`,
s.Branding.DisableExternal = mustGetBool(cmd, flag.Name)
case "branding.files":
s.Branding.Files = mustGetString(cmd, flag.Name)
case "log":
s.Log = mustGetString(cmd, flag.Name)
case "address":
s.Server.Address = mustGetString(cmd, flag.Name)
case "port":
s.Server.Port = mustGetInt(cmd, flag.Name)
case "tls.cert":
s.Server.TLSCert = mustGetString(cmd, flag.Name)
case "tls.key":
s.Server.TLSKey = mustGetString(cmd, flag.Name)
}
})

View File

@ -1,7 +1,7 @@
package cmd
import (
"crypto/rand"
"path/filepath"
"crypto/tls"
"io/ioutil"
"log"
@ -13,12 +13,10 @@ import (
"github.com/asdine/storm"
"github.com/filebrowser/filebrowser/v2/auth"
"github.com/filebrowser/filebrowser/v2/settings"
"github.com/filebrowser/filebrowser/v2/storage"
"github.com/filebrowser/filebrowser/v2/users"
fbhttp "github.com/filebrowser/filebrowser/v2/http"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
lumberjack "gopkg.in/natefinch/lumberjack.v2"
)
@ -29,12 +27,12 @@ var (
func init() {
rootCmd.PersistentFlags().StringVarP(&databasePath, "database", "d", "./filebrowser.db", "path to the database")
rootCmd.Flags().StringP("address", "a", "", "address to listen on (default comes from database)")
rootCmd.Flags().StringP("log", "l", "", "log output (default comes from database)")
rootCmd.Flags().IntP("port", "p", 0, "port to listen on (default comes from database)")
rootCmd.Flags().StringP("cert", "c", "", "tls certificate (default comes from database)")
rootCmd.Flags().StringP("key", "k", "", "tls key (default comes from database)")
rootCmd.Flags().StringP("scope", "s", "", "scope to prepend to a user's scope when it is relative (default comes from database)")
rootCmd.Flags().StringP("address", "a", "127.0.0.1", "address to listen on")
rootCmd.Flags().StringP("log", "l", "stdout", "log output")
rootCmd.Flags().IntP("port", "p", 80, "port to listen on")
rootCmd.Flags().StringP("cert", "c", "", "tls certificate")
rootCmd.Flags().StringP("key", "k", "", "tls key")
rootCmd.Flags().StringP("scope", "s", ".", "scope to prepend to a user's scope when it is relative")
}
var rootCmd = &cobra.Command{
@ -45,29 +43,12 @@ manage your user and all the configurations without accessing the
web interface.
If you've never run File Browser, you will need to create the database.
See 'filebrowser help config init' for more information.
This command is used to start up the server. By default it starts listening
on localhost on a random port unless specified otherwise in the database or
via flags.
Use the available flags to override the database/default options. These flags
values won't be persisted to the database. To persist configuration to the database
use the command 'filebrowser config set'.`,
Run: func(cmd *cobra.Command, args []string) {
if _, err := os.Stat(databasePath); os.IsNotExist(err) {
quickSetup(cmd)
}
db := getDB()
defer db.Close()
st := getStorage(db)
startServer(cmd, st)
},
See 'filebrowser help config init' for more information.`,
Run: serveAndListen,
}
func setupLogger(s *settings.Settings) {
switch s.Log {
func serveAndListen(cmd *cobra.Command, args []string) {
switch logMethod := mustGetString(cmd, "log"); logMethod {
case "stdout":
log.SetOutput(os.Stdout)
case "stderr":
@ -76,29 +57,58 @@ func setupLogger(s *settings.Settings) {
log.SetOutput(ioutil.Discard)
default:
log.SetOutput(&lumberjack.Logger{
Filename: s.Log,
Filename: logMethod,
MaxSize: 100,
MaxAge: 14,
MaxBackups: 10,
})
}
}
func serverVisitAndReplace(cmd *cobra.Command, s *settings.Settings) {
cmd.Flags().Visit(func(flag *pflag.Flag) {
switch flag.Name {
case "log":
s.Log = mustGetString(cmd, flag.Name)
case "address":
s.Server.Address = mustGetString(cmd, flag.Name)
case "port":
s.Server.Port = mustGetInt(cmd, flag.Name)
case "cert":
s.Server.TLSCert = mustGetString(cmd, flag.Name)
case "key":
s.Server.TLSKey = mustGetString(cmd, flag.Name)
}
})
if _, err := os.Stat(databasePath); os.IsNotExist(err) {
quickSetup(cmd)
}
db := getDB()
defer db.Close()
st := getStorage(db)
port := mustGetInt(cmd, "port")
address := mustGetString(cmd, "address")
cert := mustGetString(cmd, "cert")
key := mustGetString(cmd, "key")
scope := mustGetString(cmd, "scope")
if scope != "." {
var err error
scope, err = filepath.Abs(scope)
checkErr(err)
settings, err := st.Settings.Get()
checkErr(err)
settings.Scope = scope
err = st.Settings.Save(settings)
checkErr(err)
}
handler, err := fbhttp.NewHandler(st)
checkErr(err)
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)
checkErr(err)
} else {
listener, err = net.Listen("tcp", address+":"+strconv.Itoa(port))
checkErr(err)
}
log.Println("Listening on", listener.Addr().String())
if err := http.Serve(listener, handler); err != nil {
log.Fatal(err)
}
}
func quickSetup(cmd *cobra.Command) {
@ -116,16 +126,8 @@ func quickSetup(cmd *cobra.Command) {
set := &settings.Settings{
Key: generateRandomBytes(64), // 256 bit
BaseURL: "",
Scope: scope,
Log: "stderr",
Signup: false,
AuthMethod: auth.MethodJSONAuth,
Server: settings.Server{
Port: 0,
Address: "127.0.0.1",
TLSCert: mustGetString(cmd, "cert"),
TLSKey: mustGetString(cmd, "key"),
},
Defaults: settings.UserDefaults{
Scope: ".",
Locale: "en",
@ -142,7 +144,6 @@ func quickSetup(cmd *cobra.Command) {
},
}
serverVisitAndReplace(cmd, set)
st := getStorage(db)
err = st.Settings.Save(set)
@ -166,47 +167,3 @@ func quickSetup(cmd *cobra.Command) {
err = st.Users.Save(user)
checkErr(err)
}
func startServer(cmd *cobra.Command, st *storage.Storage) {
settings, err := st.Settings.Get()
checkErr(err)
scope := mustGetString(cmd, "scope")
if scope != "" {
settings.Scope = scope
err = st.Settings.Save(settings)
checkErr(err)
}
serverVisitAndReplace(cmd, settings)
setupLogger(settings)
handler, err := fbhttp.NewHandler(st)
checkErr(err)
var listener net.Listener
if settings.Server.TLSKey != "" && settings.Server.TLSCert != "" {
cer, err := tls.LoadX509KeyPair(settings.Server.TLSCert, settings.Server.TLSKey)
checkErr(err)
config := &tls.Config{Certificates: []tls.Certificate{cer}}
listener, err = tls.Listen("tcp", settings.Server.Address+":"+strconv.Itoa(settings.Server.Port), config)
checkErr(err)
} else {
listener, err = net.Listen("tcp", settings.Server.Address+":"+strconv.Itoa(settings.Server.Port))
checkErr(err)
}
log.Println("Listening on", listener.Addr().String())
if err := http.Serve(listener, handler); err != nil {
log.Fatal(err)
}
}
func generateRandomBytes(n int) []byte {
b := make([]byte, n)
_, err := rand.Read(b)
checkErr(err)
// Note that err == nil only if we read len(b) bytes.
return b
}

View File

@ -1,6 +1,7 @@
package cmd
import (
"crypto/rand"
"errors"
"os"
@ -53,3 +54,11 @@ func getDB() *storm.DB {
func getStorage(db *storm.DB) *storage.Storage {
return bolt.NewStorage(db)
}
func generateRandomBytes(n int) []byte {
b := make([]byte, n)
_, err := rand.Read(b)
checkErr(err)
// Note that err == nil only if we read len(b) bytes.
return b
}

View File

@ -76,7 +76,7 @@ func NewFileInfo(opts FileOptions) (*FileInfo, error) {
return file, file.readListing(opts.Checker)
}
err = file.detectType(opts.Modify)
err = file.detectType(opts.Modify, true)
if err != nil {
return nil, err
}
@ -126,7 +126,7 @@ func (i *FileInfo) Checksum(algo string) error {
return nil
}
func (i *FileInfo) detectType(modify bool) error {
func (i *FileInfo) detectType(modify, saveContent bool) error {
reader, err := i.Fs.Open(i.Path)
if err != nil {
return err
@ -160,17 +160,20 @@ func (i *FileInfo) detectType(modify bool) error {
return nil
default:
i.Type = "text"
afs := &afero.Afero{Fs: i.Fs}
content, err := afs.ReadFile(i.Path)
if err != nil {
return err
}
if !modify {
i.Type = "textImmutable"
}
i.Content = string(content)
if saveContent {
afs := &afero.Afero{Fs: i.Fs}
content, err := afs.ReadFile(i.Path)
if err != nil {
return err
}
i.Content = string(content)
}
}
return nil
@ -238,7 +241,7 @@ func (i *FileInfo) readListing(checker rules.Checker) error {
} else {
listing.NumFiles++
err := file.detectType(true)
err := file.detectType(true, false)
if err != nil {
return err
}

@ -1 +1 @@
Subproject commit 95fc3dfdfbe21b1d55538add66bf0d5f38197320
Subproject commit 0e7d4ef110ee550375d4bf15dfa9ded70214076a

View File

@ -85,9 +85,7 @@ func getStaticHandlers(storage *storage.Storage) (http.Handler, http.Handler) {
return http.StatusNotFound, nil
}
w.Header().Set("x-frame-options", "SAMEORIGIN")
w.Header().Set("x-xss-protection", "1; mode=block")
return handleWithStaticData(w, r, d, box, "index.html", "text/html; charset=utf-8")
}, "", storage)

View File

@ -9,9 +9,7 @@ type AuthMethod string
type Settings struct {
Key []byte `json:"key"`
BaseURL string `json:"baseURL"`
Log string `json:"log"`
Scope string `json:"scope"`
Server Server `json:"server"`
Signup bool `json:"signup"`
Defaults UserDefaults `json:"defaults"`
AuthMethod AuthMethod `json:"authMethod"`
@ -21,14 +19,6 @@ type Settings struct {
Rules []rules.Rule `json:"rules"`
}
// Server settings.
type Server struct {
Port int `json:"port"`
Address string `json:"address"`
TLSCert string `json:"tlsCert"`
TLSKey string `json:"tlsKey"`
}
// GetRules implements rules.Provider.
func (s *Settings) GetRules() []rules.Rule {
return s.Rules

View File

@ -111,7 +111,6 @@ func importConf(db *storm.DB, path string, sto *storage.Storage) error {
s := &settings.Settings{
Key: key,
BaseURL: cfg.BaseURL,
Log: cfg.Log,
Signup: false,
Defaults: settings.UserDefaults{
Scope: cfg.Defaults.Scope,
@ -129,10 +128,6 @@ func importConf(db *storm.DB, path string, sto *storage.Storage) error {
Download: true,
},
},
Server: settings.Server{
Address: cfg.Address,
Port: cfg.Port,
},
}
var auther auth.Auther