Merge pull request #1 from filebrowser/master

update 20190109
This commit is contained in:
光子 2019-01-09 09:32:52 +08:00 committed by GitHub
commit b4b578b90f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 252 additions and 201 deletions

View File

@ -3,7 +3,7 @@ project_name: filebrowser
build:
env:
- CGO_ENABLED=0
main: cli/main.go
main: main.go
binary: filebrowser
goos:
- darwin
@ -50,8 +50,9 @@ dockers:
goos: linux
goarch: amd64
goarm: ''
image: filebrowser/filebrowser
image_templates:
- "filebrowser/filebrowser:latest"
- "filebrowser/filebrowser:{{ .Tag }}"
skip_push: true
tag_templates:
- "{{ .Tag }}"
- latest
extra_files:
- .docker.json

View File

@ -32,7 +32,7 @@ jobs:
repo: filebrowser/filebrowser
branch: master
- stage: release
script: ./wizard.sh -r
script: ./wizard.sh -r "$TRAVIS_TAG"
if: tag IS present
deploy:
provider: releases

View File

@ -2,11 +2,10 @@ FROM scratch
COPY --from=filebrowser/dev /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
VOLUME /tmp
VOLUME /srv
EXPOSE 80
COPY .filebrowser.docker.json /.filebrowser.json
COPY .docker.json /.filebrowser.json
COPY filebrowser /filebrowser
ENTRYPOINT [ "/filebrowser" ]

View File

@ -15,5 +15,5 @@ type NoAuth struct{}
// Auth uses authenticates user 1.
func (a NoAuth) Auth(r *http.Request, sto *users.Storage, root string) (*users.User, error) {
return sto.Get(root, 1)
return sto.Get(root, uint(1))
}

View File

@ -11,10 +11,11 @@ func init() {
}
var cmdsCmd = &cobra.Command{
Use: "cmds",
Short: "Command runner management utility",
Long: `Command runner management utility.`,
Args: cobra.NoArgs,
Use: "cmds",
Version: rootCmd.Version,
Short: "Command runner management utility",
Long: `Command runner management utility.`,
Args: cobra.NoArgs,
}
func printEvents(m map[string][]string) {

View File

@ -13,7 +13,15 @@ func init() {
var cmdsRmCmd = &cobra.Command{
Use: "rm <event> <index> [index_end]",
Short: "Removes a command from an event hooker",
Long: `Removes a command from an event hooker.`,
Long: `Removes a command from an event hooker. The provided index
is the same that's printed when you run 'cmds ls'. Note
that after each removal/addition, the index of the
commands change. So be careful when removing them after each
other.
You can also specify an optional parameter (index_end) so
you can remove all commands from 'index' to 'index_end',
including 'index_end'.`,
Args: func(cmd *cobra.Command, args []string) error {
if err := cobra.RangeArgs(2, 3)(cmd, args); err != nil {
return err

View File

@ -20,10 +20,11 @@ func init() {
}
var configCmd = &cobra.Command{
Use: "config",
Short: "Configuration management utility",
Long: `Configuration management utility.`,
Args: cobra.NoArgs,
Use: "config",
Version: rootCmd.Version,
Short: "Configuration management utility",
Long: `Configuration management utility.`,
Args: cobra.NoArgs,
}
func addConfigFlags(flags *pflag.FlagSet) {

View File

@ -9,9 +9,12 @@ func init() {
}
var configExportCmd = &cobra.Command{
Use: "export <filename>",
Short: "Export the configuration to a file.",
Args: jsonYamlArg,
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)

View File

@ -22,12 +22,16 @@ type settingsFile struct {
}
var configImportCmd = &cobra.Command{
Use: "import <filename>",
Short: `Import a configuration file. This will replace all the existing
Use: "import <path>",
Short: "Import a configuration file",
Long: `Import a configuration file. This will replace all the existing
configuration. Can be used with or without unexisting databases.
If used with a nonexisting database, a key will be generated
automatically. Otherwise the key will be kept the same as in the
database.`,
database.
The path must be for a json or yaml file.`,
Args: jsonYamlArg,
Run: python(func(cmd *cobra.Command, args []string, d pythonData) {
var key []byte

View File

@ -18,7 +18,7 @@ var configInitCmd = &cobra.Command{
Short: "Initialize a new database",
Long: `Initialize a new database to use with File Browser. All of
this options can be changed in the future with the command
"filebrowser config set". The user related flags apply
'filebrowser config set'. The user related flags apply
to the defaults when creating new users and you don't
override the options.`,
Args: cobra.NoArgs,

View File

@ -17,7 +17,7 @@ var configSetCmd = &cobra.Command{
Use: "set",
Short: "Updates the configuration",
Long: `Updates the configuration. Set the flags for the options
you want to change.`,
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()

View File

@ -9,8 +9,8 @@ import (
"sort"
"strings"
"github.com/spf13/pflag"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
func init() {

View File

@ -12,10 +12,11 @@ func init() {
}
var hashCmd = &cobra.Command{
Use: "hash <password>",
Short: "Hashes a password",
Long: `Hashes a password using bcrypt algorithm.`,
Args: cobra.ExactArgs(1),
Use: "hash <password>",
Version: rootCmd.Version,
Short: "Hashes a password",
Long: `Hashes a password using bcrypt algorithm.`,
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
pwd, err := users.HashPwd(args[0])
checkErr(err)

View File

@ -2,7 +2,6 @@ package cmd
import (
"crypto/tls"
"errors"
"io/ioutil"
"log"
"net"
@ -16,7 +15,8 @@ import (
"github.com/filebrowser/filebrowser/v2/settings"
"github.com/filebrowser/filebrowser/v2/storage"
"github.com/filebrowser/filebrowser/v2/users"
"github.com/mitchellh/go-homedir"
"github.com/filebrowser/filebrowser/v2/version"
homedir "github.com/mitchellh/go-homedir"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
v "github.com/spf13/viper"
@ -29,11 +29,15 @@ var (
func init() {
cobra.OnInitialize(initConfig)
rootCmd.SetVersionTemplate("File Browser version {{printf \"%s\" .Version}}\n")
flags := rootCmd.Flags()
persistent := rootCmd.PersistentFlags()
persistent.StringVarP(&cfgFile, "config", "c", "", "config file path")
persistent.StringP("database", "d", "./filebrowser.db", "database path")
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\")")
@ -50,49 +54,14 @@ func addServerFlags(flags *pflag.FlagSet) {
flags.StringP("baseurl", "b", "", "base url")
}
// NOTE: we could simply bind the flags to viper and use IsSet.
// Although there is a bug on Viper that always returns true on IsSet
// if a flag is binded. Our alternative way is to manually check
// the flag and then the value from env/config/gotten by viper.
// https://github.com/spf13/viper/pull/331
func getStringViperFlag(flags *pflag.FlagSet, key string) (string, bool) {
value := ""
set := false
// If set on Flags, use it.
flags.Visit(func(flag *pflag.Flag) {
if flag.Name == key {
set = true
value, _ = flags.GetString(key)
}
})
if set {
return value, set
}
// If set through viper (env, config), return it.
if v.IsSet(key) {
return v.GetString(key), true
}
// Otherwise use default value on flags.
value, _ = flags.GetString(key)
return value, false
}
func mustGetStringViperFlag(flags *pflag.FlagSet, key string) string {
val, _ := getStringViperFlag(flags, key)
return val
}
var rootCmd = &cobra.Command{
Use: "filebrowser",
Short: "A stylish web-based file browser",
Use: "filebrowser",
Version: version.Version,
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.
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
@ -111,46 +80,50 @@ If you don't set "config", it will look for a configuration file called
The precedence of the configuration values are as follows:
- flag
- environment variable
- flags
- environment variables
- configuration file
- 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 equals to the path.
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) {
log.Println(cfgFile)
if !d.hadDB {
quickSetup(cmd.Flags(), d)
}
server := getServerWithViper(cmd.Flags(), d.store)
server := getRunParams(cmd.Flags(), d.store)
setupLog(server.Log)
root, err := filepath.Abs(server.Root)
checkErr(err)
server.Root = root
handler, err := fbhttp.NewHandler(d.store, server)
checkErr(err)
adr := server.Address + ":" + server.Port
var listener net.Listener
if server.TLSKey != "" && server.TLSCert != "" {
cer, err := tls.LoadX509KeyPair(server.TLSCert, server.TLSKey)
checkErr(err)
config := &tls.Config{Certificates: []tls.Certificate{cer}}
listener, err = tls.Listen("tcp", server.Address+":"+server.Port, config)
listener, err = tls.Listen("tcp", adr, &tls.Config{Certificates: []tls.Certificate{cer}})
checkErr(err)
} else {
listener, err = net.Listen("tcp", server.Address+":"+server.Port)
listener, err = net.Listen("tcp", adr)
checkErr(err)
}
handler, err := fbhttp.NewHandler(d.store, server)
checkErr(err)
log.Println("Listening on", listener.Addr().String())
if err := http.Serve(listener, handler); err != nil {
log.Fatal(err)
@ -158,41 +131,70 @@ user created with the credentials from options "username" and "password".`,
}, pythonConfig{allowNoDB: true}),
}
func getServerWithViper(flags *pflag.FlagSet, st *storage.Storage) *settings.Server {
func getRunParams(flags *pflag.FlagSet, st *storage.Storage) *settings.Server {
server, err := st.Settings.GetServer()
checkErr(err)
if val, set := getStringViperFlag(flags, "root"); set {
if val, set := getParamB(flags, "root"); set {
server.Root = val
}
if val, set := getStringViperFlag(flags, "baseurl"); set {
if val, set := getParamB(flags, "baseurl"); set {
server.BaseURL = val
}
if val, set := getStringViperFlag(flags, "address"); set {
if val, set := getParamB(flags, "address"); set {
server.Address = val
}
if val, set := getStringViperFlag(flags, "port"); set {
if val, set := getParamB(flags, "port"); set {
server.Port = val
}
if val, set := getStringViperFlag(flags, "log"); set {
if val, set := getParamB(flags, "log"); set {
server.Log = val
}
if val, set := getStringViperFlag(flags, "key"); set {
if val, set := getParamB(flags, "key"); set {
server.TLSKey = val
}
if val, set := getStringViperFlag(flags, "cert"); set {
if val, set := getParamB(flags, "cert"); set {
server.TLSCert = val
}
return server
}
// getParamB returns a parameter as a string and a boolean to tell if it is different from the default
//
// NOTE: we could simply bind the flags to viper and use IsSet.
// Although there is a bug on Viper that always returns true on IsSet
// if a flag is binded. Our alternative way is to manually check
// the flag and then the value from env/config/gotten by viper.
// https://github.com/spf13/viper/pull/331
func getParamB(flags *pflag.FlagSet, key string) (string, bool) {
value, _ := flags.GetString(key)
// If set on Flags, use it.
if flags.Changed(key) {
return value, true
}
// If set through viper (env, config), return it.
if v.IsSet(key) {
return v.GetString(key), true
}
// Otherwise use default value on flags.
return value, false
}
func getParam(flags *pflag.FlagSet, key string) string {
val, _ := getParamB(flags, key)
return val
}
func setupLog(logMethod string) {
switch logMethod {
case "stdout":
@ -209,14 +211,12 @@ func setupLog(logMethod string) {
MaxBackups: 10,
})
}
}
func quickSetup(flags *pflag.FlagSet, d pythonData) {
set := &settings.Settings{
Key: generateRandomBytes(64), // 256 bit
Signup: false,
AuthMethod: auth.MethodJSONAuth,
Key: generateRandomBytes(64), // 256 bit
Signup: false,
Defaults: settings.UserDefaults{
Scope: ".",
Locale: "en",
@ -233,27 +233,34 @@ func quickSetup(flags *pflag.FlagSet, d pythonData) {
},
}
ser := &settings.Server{
BaseURL: mustGetStringViperFlag(flags, "baseurl"),
Port: mustGetStringViperFlag(flags, "port"),
Log: mustGetStringViperFlag(flags, "log"),
TLSKey: mustGetStringViperFlag(flags, "key"),
TLSCert: mustGetStringViperFlag(flags, "cert"),
Address: mustGetStringViperFlag(flags, "address"),
Root: mustGetStringViperFlag(flags, "root"),
var err error
if _, noauth := getParamB(flags, "noauth"); noauth {
set.AuthMethod = auth.MethodNoAuth
err = d.store.Auth.Save(&auth.NoAuth{})
} else {
set.AuthMethod = auth.MethodJSONAuth
err = d.store.Auth.Save(&auth.JSONAuth{})
}
err := d.store.Settings.Save(set)
checkErr(err)
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)
checkErr(err)
err = d.store.Auth.Save(&auth.JSONAuth{})
checkErr(err)
username := mustGetStringViperFlag(flags, "username")
password := mustGetStringViperFlag(flags, "password")
username := getParam(flags, "username")
password := getParam(flags, "password")
if password == "" {
password, err = users.HashPwd("admin")
@ -261,7 +268,7 @@ func quickSetup(flags *pflag.FlagSet, d pythonData) {
}
if username == "" || password == "" {
checkErr(errors.New("username and password cannot be empty during quick setup"))
log.Fatal("username and password cannot be empty during quick setup")
}
user := &users.User{
@ -297,7 +304,9 @@ func initConfig() {
if _, ok := err.(v.ConfigParseError); ok {
panic(err)
}
// TODO: log.Println("No config file provided")
cfgFile = "No config file used"
} else {
cfgFile = "Using config file: " + v.ConfigFileUsed()
}
// else TODO: log.Println("Using config file:", v.ConfigFileUsed())
}

View File

@ -17,7 +17,15 @@ func init() {
var rulesRmCommand = &cobra.Command{
Use: "rm <index> [index_end]",
Short: "Remove a global rule or user rule",
Long: `Remove a global rule or user rule.`,
Long: `Remove a global rule or user rule. The provided index
is the same that's printed when you run 'rules ls'. Note
that after each removal/addition, the index of the
commands change. So be careful when removing them after each
other.
You can also specify an optional parameter (index_end) so
you can remove all commands from 'index' to 'index_end',
including 'index_end'.`,
Args: func(cmd *cobra.Command, args []string) error {
if err := cobra.RangeArgs(1, 2)(cmd, args); err != nil {
return err

View File

@ -18,8 +18,9 @@ func init() {
}
var rulesCmd = &cobra.Command{
Use: "rules",
Short: "Rules management utility",
Use: "rules",
Version: rootCmd.Version,
Short: "Rules management utility",
Long: `On each subcommand you'll have available at least two flags:
"username" and "id". You must either set only one of them
or none. If you set one of them, the command will apply to
@ -42,14 +43,14 @@ func runRules(st *storage.Storage, cmd *cobra.Command, users func(*users.User),
return
}
settings, err := st.Settings.Get()
s, err := st.Settings.Get()
checkErr(err)
if global != nil {
global(settings)
global(s)
}
printRules(settings.Rules, id)
printRules(s.Rules, id)
}
func getUserIdentifier(flags *pflag.FlagSet) interface{} {

View File

@ -14,8 +14,9 @@ func init() {
}
var upgradeCmd = &cobra.Command{
Use: "upgrade",
Short: "Upgrades an old configuration",
Use: "upgrade",
Version: rootCmd.Version,
Short: "Upgrades an old configuration",
Long: `Upgrades an old configuration. This command DOES NOT
import share links because they are incompatible with
this version.`,
@ -24,7 +25,7 @@ this version.`,
flags := cmd.Flags()
oldDB := mustGetString(flags, "old.database")
oldConf := mustGetString(flags, "old.config")
err := importer.Import(oldDB, oldConf, mustGetStringViperFlag(flags, "database"))
err := importer.Import(oldDB, oldConf, getParam(flags, "database"))
checkErr(err)
},
}

View File

@ -18,10 +18,11 @@ func init() {
}
var usersCmd = &cobra.Command{
Use: "users",
Short: "Users management utility",
Long: `Users management utility.`,
Args: cobra.NoArgs,
Use: "users",
Version: rootCmd.Version,
Short: "Users management utility",
Long: `Users management utility.`,
Args: cobra.NoArgs,
}
func printUsers(users []*users.User) {

View File

@ -9,9 +9,11 @@ func init() {
}
var usersExportCmd = &cobra.Command{
Use: "export <filename>",
Short: "Export all users.",
Args: jsonYamlArg,
Use: "export <path>",
Short: "Export all users to a file.",
Long: `Export all users to a json or yaml file. Please indicate the
path to the file where you want to write the users.`,
Args: jsonYamlArg,
Run: python(func(cmd *cobra.Command, args []string, d pythonData) {
list, err := d.store.Users.Gets("")
checkErr(err)

View File

@ -16,9 +16,13 @@ func init() {
}
var usersImportCmd = &cobra.Command{
Use: "import <filename>",
Short: "Import users from a file.",
Args: jsonYamlArg,
Use: "import <path>",
Short: "Import users from a file",
Long: `Import users from a file. The path must be for a json or yaml
file. You can use this command to import new users to your
installation. For that, just don't place their ID on the files
list or set it to 0.`,
Args: jsonYamlArg,
Run: python(func(cmd *cobra.Command, args []string, d pythonData) {
fd, err := os.Open(args[0])
checkErr(err)
@ -36,16 +40,16 @@ var usersImportCmd = &cobra.Command{
if mustGetBool(cmd.Flags(), "replace") {
oldUsers, err := d.store.Users.Gets("")
checkErr(err)
err = marshal("users.backup.json", list)
checkErr(err)
for _, user := range oldUsers {
err = d.store.Users.Delete(user.ID)
checkErr(err)
}
}
overwrite := mustGetBool(cmd.Flags(), "overwrite")
for _, user := range list {

View File

@ -26,8 +26,10 @@ options you want to change.`,
password := mustGetString(flags, "password")
newUsername := mustGetString(flags, "username")
var err error
var user *users.User
var (
err error
user *users.User
)
if id != 0 {
user, err = d.store.Users.Get("", id)

View File

@ -19,8 +19,7 @@ import (
func checkErr(err error) {
if err != nil {
fmt.Println(err)
os.Exit(1)
log.Fatal(err)
}
}
@ -67,7 +66,7 @@ func python(fn pythonFunc, cfg pythonConfig) cobraFunc {
return func(cmd *cobra.Command, args []string) {
data := pythonData{hadDB: true}
path := mustGetStringViperFlag(cmd.Flags(), "database")
path := getParam(cmd.Flags(), "database")
_, err := os.Stat(path)
if os.IsNotExist(err) {

View File

@ -1,20 +1,32 @@
package cmd
import (
"fmt"
"text/template"
"github.com/filebrowser/filebrowser/v2/version"
"github.com/spf13/cobra"
)
func init() {
rootCmd.AddCommand(versionCmd)
cmdsCmd.AddCommand(versionCmd)
configCmd.AddCommand(versionCmd)
hashCmd.AddCommand(versionCmd)
upgradeCmd.AddCommand(versionCmd)
rulesCmd.AddCommand(versionCmd)
usersCmd.AddCommand(versionCmd)
}
var versionCmd = &cobra.Command{
Use: "version",
Short: "Print the version number",
Short: "Print the version number of File Browser",
Long: `All software has versions. This is File Browser's`,
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("File Browser Version " + version.Version)
// https://github.com/spf13/cobra/issues/724
t := template.New("version")
template.Must(t.Parse(rootCmd.VersionTemplate()))
err := t.Execute(rootCmd.OutOrStdout(), rootCmd)
if err != nil {
rootCmd.Println(err)
}
},
}

View File

@ -7,7 +7,7 @@ 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/users"

View File

@ -9,7 +9,7 @@ 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"

View File

@ -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 {
@ -33,7 +33,7 @@ type oldAuth struct {
}
type oldConf struct {
Port string `json:"port" yaml:"port" toml:"port"`
Port string `json:"port" yaml:"port" toml:"port"`
BaseURL string `json:"baseURL" yaml:"baseURL" toml:"baseURL"`
Log string `json:"log" yaml:"log" toml:"log"`
Address string `json:"address" yaml:"address" toml:"address"`
@ -62,14 +62,14 @@ var defaults = &oldConf{
},
}
func importConf(db *storm.DB, path string, sto *storage.Storage) error {
func readConf(path string) (*oldConf, error) {
cfg := &oldConf{}
if path != "" {
ext := filepath.Ext(path)
fd, err := os.Open(path)
if err != nil {
return err
return nil, err
}
defer fd.Close()
@ -81,23 +81,32 @@ func importConf(db *storm.DB, path string, sto *storage.Storage) error {
case ".yaml", ".yml":
err = yaml.NewDecoder(fd).Decode(cfg)
default:
return errors.New("unsupported config extension " + ext)
return nil, errors.New("unsupported config extension " + ext)
}
if err != nil {
return err
return nil, err
}
} else {
cfg = defaults
path, err := filepath.Abs(".")
if err != nil {
return err
return nil, err
}
cfg.Defaults.Scope = path
}
return cfg, nil
}
func importConf(db *storm.DB, path string, sto *storage.Storage) error {
cfg, err := readConf(path)
if err != nil {
return err
}
commands := map[string][]string{}
err := db.Get("config", "commands", &commands)
err = db.Get("config", "commands", &commands)
if err != nil {
return err
}
@ -109,8 +118,8 @@ func importConf(db *storm.DB, path string, sto *storage.Storage) error {
}
s := &settings.Settings{
Key: key,
Signup: false,
Key: key,
Signup: false,
Defaults: settings.UserDefaults{
Scope: cfg.Defaults.Scope,
Commands: cfg.Defaults.Commands,
@ -130,10 +139,10 @@ func importConf(db *storm.DB, path string, sto *storage.Storage) error {
}
server := &settings.Server{
BaseURL : cfg.BaseURL,
Port : cfg.Port,
Address : cfg.Address,
Log : cfg.Log,
BaseURL: cfg.BaseURL,
Port: cfg.Port,
Address: cfg.Address,
Log: cfg.Log,
}
var auther auth.Auther

View File

@ -12,32 +12,29 @@ type usersBackend struct {
db *storm.DB
}
func (st usersBackend) GetByID(id uint) (*users.User, error) {
user := &users.User{}
err := st.db.One("ID", id, user)
if err == storm.ErrNotFound {
return nil, errors.ErrNotExist
func (st usersBackend) GetBy(i interface{}) (user *users.User, err error) {
user = &users.User{}
var arg string
switch i.(type) {
case uint:
arg = "ID"
case string:
arg = "Username"
default:
return nil, errors.ErrInvalidDataType
}
err = st.db.One(arg, i, user)
if err != nil {
if err == storm.ErrNotFound {
return nil, errors.ErrNotExist
}
return nil, err
}
return user, nil
}
func (st usersBackend) GetByUsername(username string) (*users.User, error) {
user := &users.User{}
err := st.db.One("Username", username, user)
if err == storm.ErrNotFound {
return nil, errors.ErrNotExist
}
if err != nil {
return nil, err
}
return user, nil
return
}
func (st usersBackend) Gets() ([]*users.User, error) {
@ -82,7 +79,7 @@ func (st usersBackend) DeleteByID(id uint) error {
}
func (st usersBackend) DeleteByUsername(username string) error {
user, err := st.GetByUsername(username)
user, err := st.GetBy(username)
if err != nil {
return err
}

View File

@ -9,8 +9,7 @@ import (
// StorageBackend is the interface to implement for a users storage.
type StorageBackend interface {
GetByID(uint) (*User, error)
GetByUsername(string) (*User, error)
GetBy(interface{}) (*User, error)
Gets() ([]*User, error)
Save(u *User) error
Update(u *User, fields ...string) error
@ -36,27 +35,13 @@ func NewStorage(back StorageBackend) *Storage {
// Get allows you to get a user by its name or username. The provided
// id must be a string for username lookup or a uint for id lookup. If id
// is neither, a ErrInvalidDataType will be returned.
func (s *Storage) Get(baseScope string, id interface{}) (*User, error) {
var (
user *User
err error
)
switch id.(type) {
case string:
user, err = s.back.GetByUsername(id.(string))
case uint:
user, err = s.back.GetByID(id.(uint))
default:
return nil, errors.ErrInvalidDataType
}
func (s *Storage) Get(baseScope string, id interface{}) (user *User, err error) {
user, err = s.back.GetBy(id)
if err != nil {
return nil, err
return
}
user.Clean(baseScope)
return user, err
return
}
// Gets gets a list of all users.

View File

@ -131,7 +131,7 @@ pushRicebox () {
git clone git@github.com:filebrowser/caddy caddy
cd caddy
cp $base/http/rice-box.go ./
cp ../http/rice-box.go ./
sed -i 's/package lib/package caddy/g' ./rice-box.go
git checkout -b update-rice-box origin/master
git config --local user.name "Filebrowser Bot"
@ -238,8 +238,11 @@ release () {
exit 1
fi
set +e
git rev-parse --verify --quiet release
if [ $? -ne 0 ]; then
exitcode=$?
set -e
if [ $exitcode -ne 0 ]; then
git checkout -b release "$semver"
else
git checkout release