Compare commits
28 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
de2c2021d7 | ||
|
|
243b12d4c2 | ||
|
|
fa86894550 | ||
|
|
4a1e21baec | ||
|
|
0607e0df2d | ||
|
|
c2f1d07abc | ||
|
|
0d1074b6d9 | ||
|
|
65a53514d5 | ||
|
|
ce68f48fb4 | ||
|
|
5a03c75dc3 | ||
|
|
20d80bb054 | ||
|
|
cbdf3cafb6 | ||
|
|
1259fc1bbc | ||
|
|
4cf1f2f6b4 | ||
|
|
a90bb28cae | ||
|
|
e86dfbe8ff | ||
|
|
437a238aca | ||
|
|
e5fa0772c6 | ||
|
|
ba5c67d9da | ||
|
|
f3d007025e | ||
|
|
e7a39808dd | ||
|
|
2b7aa7a0c9 | ||
|
|
4d8f0c532b | ||
|
|
367e251a0e | ||
|
|
cc6f2f8bec | ||
|
|
007fde8186 | ||
|
|
552f8168ea | ||
|
|
42426e3e69 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -3,3 +3,4 @@
|
|||||||
*.bak
|
*.bak
|
||||||
_old
|
_old
|
||||||
rice-box.go
|
rice-box.go
|
||||||
|
.idea/
|
||||||
@@ -5,7 +5,6 @@ install: skip
|
|||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
packages:
|
packages:
|
||||||
- docker-ce
|
|
||||||
- pass
|
- pass
|
||||||
env:
|
env:
|
||||||
global:
|
global:
|
||||||
|
|||||||
@@ -10,4 +10,6 @@ import (
|
|||||||
type Auther interface {
|
type Auther interface {
|
||||||
// Auth is called to authenticate a request.
|
// Auth is called to authenticate a request.
|
||||||
Auth(r *http.Request, s *users.Storage, root string) (*users.User, error)
|
Auth(r *http.Request, s *users.Storage, root string) (*users.User, error)
|
||||||
|
// LoginPage indicates if this auther needs a login page.
|
||||||
|
LoginPage() bool
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,6 +59,11 @@ func (a JSONAuth) Auth(r *http.Request, sto *users.Storage, root string) (*users
|
|||||||
return u, nil
|
return u, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LoginPage tells that json auth doesn't require a login page.
|
||||||
|
func (a JSONAuth) LoginPage() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
const reCaptchaAPI = "/recaptcha/api/siteverify"
|
const reCaptchaAPI = "/recaptcha/api/siteverify"
|
||||||
|
|
||||||
// ReCaptcha identifies a recaptcha conenction.
|
// ReCaptcha identifies a recaptcha conenction.
|
||||||
|
|||||||
@@ -17,3 +17,8 @@ type NoAuth struct{}
|
|||||||
func (a NoAuth) Auth(r *http.Request, sto *users.Storage, root string) (*users.User, error) {
|
func (a NoAuth) Auth(r *http.Request, sto *users.Storage, root string) (*users.User, error) {
|
||||||
return sto.Get(root, uint(1))
|
return sto.Get(root, uint(1))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LoginPage tells that no auth doesn't require a login page.
|
||||||
|
func (a NoAuth) LoginPage() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|||||||
@@ -27,3 +27,8 @@ func (a ProxyAuth) Auth(r *http.Request, sto *users.Storage, root string) (*user
|
|||||||
|
|
||||||
return user, err
|
return user, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LoginPage tells that proxy auth doesn't require a login page.
|
||||||
|
func (a ProxyAuth) LoginPage() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|||||||
@@ -11,11 +11,10 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var cmdsCmd = &cobra.Command{
|
var cmdsCmd = &cobra.Command{
|
||||||
Use: "cmds",
|
Use: "cmds",
|
||||||
Version: rootCmd.Version,
|
Short: "Command runner management utility",
|
||||||
Short: "Command runner management utility",
|
Long: `Command runner management utility.`,
|
||||||
Long: `Command runner management utility.`,
|
Args: cobra.NoArgs,
|
||||||
Args: cobra.NoArgs,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func printEvents(m map[string][]string) {
|
func printEvents(m map[string][]string) {
|
||||||
|
|||||||
@@ -20,11 +20,10 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var configCmd = &cobra.Command{
|
var configCmd = &cobra.Command{
|
||||||
Use: "config",
|
Use: "config",
|
||||||
Version: rootCmd.Version,
|
Short: "Configuration management utility",
|
||||||
Short: "Configuration management utility",
|
Long: `Configuration management utility.`,
|
||||||
Long: `Configuration management utility.`,
|
Args: cobra.NoArgs,
|
||||||
Args: cobra.NoArgs,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func addConfigFlags(flags *pflag.FlagSet) {
|
func addConfigFlags(flags *pflag.FlagSet) {
|
||||||
@@ -90,6 +89,7 @@ func printSettings(ser *settings.Server, set *settings.Settings, auther auth.Aut
|
|||||||
w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
|
w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
|
||||||
|
|
||||||
fmt.Fprintf(w, "Sign up:\t%t\n", set.Signup)
|
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.AuthMethod)
|
||||||
fmt.Fprintf(w, "Shell:\t%s\t\n", strings.Join(set.Shell, " "))
|
fmt.Fprintf(w, "Shell:\t%s\t\n", strings.Join(set.Shell, " "))
|
||||||
fmt.Fprintln(w, "\nBranding:")
|
fmt.Fprintln(w, "\nBranding:")
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ func generateMarkdown(cmd *cobra.Command, w io.Writer) {
|
|||||||
checkErr(err)
|
checkErr(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateFlagsTable(fs *pflag.FlagSet, buf *bytes.Buffer) {
|
func generateFlagsTable(fs *pflag.FlagSet, buf io.StringWriter) {
|
||||||
buf.WriteString("| Name | Shorthand | Usage |\n")
|
buf.WriteString("| Name | Shorthand | Usage |\n")
|
||||||
buf.WriteString("|------|-----------|-------|\n")
|
buf.WriteString("|------|-----------|-------|\n")
|
||||||
|
|
||||||
|
|||||||
@@ -12,11 +12,10 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var hashCmd = &cobra.Command{
|
var hashCmd = &cobra.Command{
|
||||||
Use: "hash <password>",
|
Use: "hash <password>",
|
||||||
Version: rootCmd.Version,
|
Short: "Hashes a password",
|
||||||
Short: "Hashes a password",
|
Long: `Hashes a password using bcrypt algorithm.`,
|
||||||
Long: `Hashes a password using bcrypt algorithm.`,
|
Args: cobra.ExactArgs(1),
|
||||||
Args: cobra.ExactArgs(1),
|
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
pwd, err := users.HashPwd(args[0])
|
pwd, err := users.HashPwd(args[0])
|
||||||
checkErr(err)
|
checkErr(err)
|
||||||
|
|||||||
11
cmd/root.go
11
cmd/root.go
@@ -15,7 +15,6 @@ import (
|
|||||||
"github.com/filebrowser/filebrowser/v2/settings"
|
"github.com/filebrowser/filebrowser/v2/settings"
|
||||||
"github.com/filebrowser/filebrowser/v2/storage"
|
"github.com/filebrowser/filebrowser/v2/storage"
|
||||||
"github.com/filebrowser/filebrowser/v2/users"
|
"github.com/filebrowser/filebrowser/v2/users"
|
||||||
"github.com/filebrowser/filebrowser/v2/version"
|
|
||||||
homedir "github.com/mitchellh/go-homedir"
|
homedir "github.com/mitchellh/go-homedir"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
@@ -55,9 +54,8 @@ func addServerFlags(flags *pflag.FlagSet) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var rootCmd = &cobra.Command{
|
var rootCmd = &cobra.Command{
|
||||||
Use: "filebrowser",
|
Use: "filebrowser",
|
||||||
Version: version.Version,
|
Short: "A stylish web-based file browser",
|
||||||
Short: "A stylish web-based file browser",
|
|
||||||
Long: `File Browser CLI lets you create the database to use with 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
|
manage your users and all the configurations without acessing the
|
||||||
web interface.
|
web interface.
|
||||||
@@ -215,8 +213,9 @@ func setupLog(logMethod string) {
|
|||||||
|
|
||||||
func quickSetup(flags *pflag.FlagSet, d pythonData) {
|
func quickSetup(flags *pflag.FlagSet, d pythonData) {
|
||||||
set := &settings.Settings{
|
set := &settings.Settings{
|
||||||
Key: generateKey(),
|
Key: generateKey(),
|
||||||
Signup: false,
|
Signup: false,
|
||||||
|
CreateUserDir: false,
|
||||||
Defaults: settings.UserDefaults{
|
Defaults: settings.UserDefaults{
|
||||||
Scope: ".",
|
Scope: ".",
|
||||||
Locale: "en",
|
Locale: "en",
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ func init() {
|
|||||||
|
|
||||||
var rulesCmd = &cobra.Command{
|
var rulesCmd = &cobra.Command{
|
||||||
Use: "rules",
|
Use: "rules",
|
||||||
Version: rootCmd.Version,
|
|
||||||
Short: "Rules management utility",
|
Short: "Rules management utility",
|
||||||
Long: `On each subcommand you'll have available at least two flags:
|
Long: `On each subcommand you'll have available at least two flags:
|
||||||
"username" and "id". You must either set only one of them
|
"username" and "id". You must either set only one of them
|
||||||
|
|||||||
@@ -14,9 +14,8 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var upgradeCmd = &cobra.Command{
|
var upgradeCmd = &cobra.Command{
|
||||||
Use: "upgrade",
|
Use: "upgrade",
|
||||||
Version: rootCmd.Version,
|
Short: "Upgrades an old configuration",
|
||||||
Short: "Upgrades an old configuration",
|
|
||||||
Long: `Upgrades an old configuration. This command DOES NOT
|
Long: `Upgrades an old configuration. This command DOES NOT
|
||||||
import share links because they are incompatible with
|
import share links because they are incompatible with
|
||||||
this version.`,
|
this version.`,
|
||||||
|
|||||||
@@ -18,11 +18,10 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var usersCmd = &cobra.Command{
|
var usersCmd = &cobra.Command{
|
||||||
Use: "users",
|
Use: "users",
|
||||||
Version: rootCmd.Version,
|
Short: "Users management utility",
|
||||||
Short: "Users management utility",
|
Long: `Users management utility.`,
|
||||||
Long: `Users management utility.`,
|
Args: cobra.NoArgs,
|
||||||
Args: cobra.NoArgs,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func printUsers(users []*users.User) {
|
func printUsers(users []*users.User) {
|
||||||
|
|||||||
@@ -30,6 +30,19 @@ var usersAddCmd = &cobra.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
s.Defaults.Apply(user)
|
s.Defaults.Apply(user)
|
||||||
|
|
||||||
|
servSettings, err := d.store.Settings.GetServer()
|
||||||
|
checkErr(err)
|
||||||
|
//since getUserDefaults() polluted s.Defaults.Scope
|
||||||
|
//which makes the Scope not the one saved in the db
|
||||||
|
//we need the right s.Defaults.Scope here
|
||||||
|
s2, err := d.store.Settings.Get()
|
||||||
|
checkErr(err)
|
||||||
|
|
||||||
|
userHome, err := s2.MakeUserDir(user.Username, user.Scope, servSettings.Root)
|
||||||
|
checkErr(err)
|
||||||
|
user.Scope = userHome
|
||||||
|
|
||||||
err = d.store.Users.Save(user)
|
err = d.store.Users.Save(user)
|
||||||
checkErr(err)
|
checkErr(err)
|
||||||
printUsers([]*users.User{user})
|
printUsers([]*users.User{user})
|
||||||
|
|||||||
@@ -70,6 +70,10 @@ list or set it to 0.`,
|
|||||||
checkErr(usernameConflictError(user.Username, conflictuous.ID, user.ID))
|
checkErr(usernameConflictError(user.Username, conflictuous.ID, user.ID))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// If it doesn't exist, set the ID to 0 to automatically get a new
|
||||||
|
// one that make sense in this DB.
|
||||||
|
user.ID = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
err = d.store.Users.Save(user)
|
err = d.store.Users.Save(user)
|
||||||
|
|||||||
18
cmd/utils.go
18
cmd/utils.go
@@ -62,18 +62,20 @@ type pythonData struct {
|
|||||||
|
|
||||||
func dbExists(path string) (bool, error) {
|
func dbExists(path string) (bool, error) {
|
||||||
stat, err := os.Stat(path)
|
stat, err := os.Stat(path)
|
||||||
|
if err == nil {
|
||||||
|
return stat.Size() != 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
return false, nil
|
d := filepath.Dir(path)
|
||||||
} else if err != nil {
|
_, err = os.Stat(d)
|
||||||
return false, err
|
if os.IsNotExist(err) {
|
||||||
|
os.MkdirAll(d, 0700)
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if stat.Size() == 0 {
|
return false, err
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return true, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func python(fn pythonFunc, cfg pythonConfig) cobraFunc {
|
func python(fn pythonFunc, cfg pythonConfig) cobraFunc {
|
||||||
|
|||||||
@@ -1,32 +1,20 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"text/template"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/filebrowser/filebrowser/v2/version"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
rootCmd.AddCommand(versionCmd)
|
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{
|
var versionCmd = &cobra.Command{
|
||||||
Use: "version",
|
Use: "version",
|
||||||
Short: "Print the version number of File Browser",
|
Short: "Print the version number",
|
||||||
Long: `All software has versions. This is File Browser's`,
|
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
// https://github.com/spf13/cobra/issues/724
|
fmt.Println("File Browser Version " + version.Version)
|
||||||
t := template.New("version")
|
|
||||||
template.Must(t.Parse(rootCmd.VersionTemplate()))
|
|
||||||
err := t.Execute(rootCmd.OutOrStdout(), rootCmd)
|
|
||||||
if err != nil {
|
|
||||||
rootCmd.Println(err)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package files
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"sort"
|
"sort"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/maruel/natural"
|
"github.com/maruel/natural"
|
||||||
)
|
)
|
||||||
@@ -68,7 +69,7 @@ func (l byName) Less(i, j int) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
return natural.Less(l.Items[i].Name, l.Items[j].Name)
|
return natural.Less(strings.ToLower(l.Items[j].Name), strings.ToLower(l.Items[i].Name))
|
||||||
}
|
}
|
||||||
|
|
||||||
// By Size
|
// By Size
|
||||||
|
|||||||
2
frontend
2
frontend
Submodule frontend updated: 2ed87febcb...3ed2144a0e
4
go.mod
4
go.mod
@@ -21,12 +21,12 @@ require (
|
|||||||
github.com/kardianos/osext v0.0.0-20170510131534-ae77be60afb1 // indirect
|
github.com/kardianos/osext v0.0.0-20170510131534-ae77be60afb1 // indirect
|
||||||
github.com/kr/pretty v0.1.0 // indirect
|
github.com/kr/pretty v0.1.0 // indirect
|
||||||
github.com/maruel/natural v0.0.0-20180416170133-dbcb3e2e8cf1
|
github.com/maruel/natural v0.0.0-20180416170133-dbcb3e2e8cf1
|
||||||
github.com/mholt/archiver v3.1.0+incompatible
|
github.com/mholt/archiver v3.1.1+incompatible
|
||||||
github.com/mholt/caddy v0.11.1
|
github.com/mholt/caddy v0.11.1
|
||||||
github.com/mitchellh/go-homedir v1.0.0
|
github.com/mitchellh/go-homedir v1.0.0
|
||||||
github.com/nwaples/rardecode v1.0.0 // indirect
|
github.com/nwaples/rardecode v1.0.0 // indirect
|
||||||
github.com/pelletier/go-toml v1.2.0
|
github.com/pelletier/go-toml v1.2.0
|
||||||
github.com/pierrec/lz4 v2.0.5+incompatible // indirect
|
github.com/pierrec/lz4 v0.0.0-20190131084431-473cd7ce01a1 // indirect
|
||||||
github.com/spf13/afero v1.1.2
|
github.com/spf13/afero v1.1.2
|
||||||
github.com/spf13/cobra v0.0.3
|
github.com/spf13/cobra v0.0.3
|
||||||
github.com/spf13/pflag v1.0.3
|
github.com/spf13/pflag v1.0.3
|
||||||
|
|||||||
5
go.sum
5
go.sum
@@ -57,6 +57,8 @@ github.com/maruel/natural v0.0.0-20180416170133-dbcb3e2e8cf1 h1:PEhRT94KBTY4E0Kd
|
|||||||
github.com/maruel/natural v0.0.0-20180416170133-dbcb3e2e8cf1/go.mod h1:wI697HNhDFM/vBruYM3ckbszQ2+DOIeH9qdBKMdf288=
|
github.com/maruel/natural v0.0.0-20180416170133-dbcb3e2e8cf1/go.mod h1:wI697HNhDFM/vBruYM3ckbszQ2+DOIeH9qdBKMdf288=
|
||||||
github.com/mholt/archiver v3.1.0+incompatible h1:S1rFZ7umHtN6cG+6cusrfoXTMPqp6u/R89iKxBYJd4w=
|
github.com/mholt/archiver v3.1.0+incompatible h1:S1rFZ7umHtN6cG+6cusrfoXTMPqp6u/R89iKxBYJd4w=
|
||||||
github.com/mholt/archiver v3.1.0+incompatible/go.mod h1:Dh2dOXnSdiLxRiPoVfIr/fI1TwETms9B8CTWfeh7ROU=
|
github.com/mholt/archiver v3.1.0+incompatible/go.mod h1:Dh2dOXnSdiLxRiPoVfIr/fI1TwETms9B8CTWfeh7ROU=
|
||||||
|
github.com/mholt/archiver v3.1.1+incompatible h1:1dCVxuqs0dJseYEhi5pl7MYPH9zDa1wBi7mF09cbNkU=
|
||||||
|
github.com/mholt/archiver v3.1.1+incompatible/go.mod h1:Dh2dOXnSdiLxRiPoVfIr/fI1TwETms9B8CTWfeh7ROU=
|
||||||
github.com/mholt/caddy v0.11.1 h1:oNfejqftVesLoFxw53Gh17aBPNbTxQ9xJw1pn4IiAPk=
|
github.com/mholt/caddy v0.11.1 h1:oNfejqftVesLoFxw53Gh17aBPNbTxQ9xJw1pn4IiAPk=
|
||||||
github.com/mholt/caddy v0.11.1/go.mod h1:Wb1PlT4DAYSqOEd03MsqkdkXnTxA8v9pKjdpxbqM1kY=
|
github.com/mholt/caddy v0.11.1/go.mod h1:Wb1PlT4DAYSqOEd03MsqkdkXnTxA8v9pKjdpxbqM1kY=
|
||||||
github.com/mitchellh/go-homedir v1.0.0 h1:vKb8ShqSby24Yrqr/yDYkuFz8d0WUjys40rvnGC8aR0=
|
github.com/mitchellh/go-homedir v1.0.0 h1:vKb8ShqSby24Yrqr/yDYkuFz8d0WUjys40rvnGC8aR0=
|
||||||
@@ -67,8 +69,11 @@ github.com/nwaples/rardecode v1.0.0 h1:r7vGuS5akxOnR4JQSkko62RJ1ReCMXxQRPtxsiFMB
|
|||||||
github.com/nwaples/rardecode v1.0.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0=
|
github.com/nwaples/rardecode v1.0.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0=
|
||||||
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
|
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
|
||||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||||
|
github.com/pierrec/lz4 v0.0.0-20190131084431-473cd7ce01a1 h1:0utzB5Mn6QyMzIeOn+oD7pjKQLjJwfM9bz6TkPPdxcw=
|
||||||
|
github.com/pierrec/lz4 v0.0.0-20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
|
||||||
github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I=
|
github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I=
|
||||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||||
|
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
|
github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ type authToken struct {
|
|||||||
type extractor []string
|
type extractor []string
|
||||||
|
|
||||||
func (e extractor) ExtractToken(r *http.Request) (string, error) {
|
func (e extractor) ExtractToken(r *http.Request) (string, error) {
|
||||||
token, _ := request.AuthorizationHeaderExtractor.ExtractToken(r)
|
token, _ := request.HeaderExtractor{"X-Auth"}.ExtractToken(r)
|
||||||
|
|
||||||
// Checks if the token isn't empty and if it contains two dots.
|
// Checks if the token isn't empty and if it contains two dots.
|
||||||
// The former prevents incompatibility with URLs that previously
|
// The former prevents incompatibility with URLs that previously
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package http
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@@ -82,7 +81,6 @@ var rawHandler = withUser(func(w http.ResponseWriter, r *http.Request, d *data)
|
|||||||
func addFile(ar archiver.Writer, d *data, path string) error {
|
func addFile(ar archiver.Writer, d *data, path string) error {
|
||||||
// Checks are always done with paths with "/" as path separator.
|
// Checks are always done with paths with "/" as path separator.
|
||||||
path = strings.Replace(path, "\\", "/", -1)
|
path = strings.Replace(path, "\\", "/", -1)
|
||||||
fmt.Println(path)
|
|
||||||
if !d.Check(path) {
|
if !d.Check(path) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,22 +9,24 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type settingsData struct {
|
type settingsData struct {
|
||||||
Signup bool `json:"signup"`
|
Signup bool `json:"signup"`
|
||||||
Defaults settings.UserDefaults `json:"defaults"`
|
CreateUserDir bool `json:"createUserDir"`
|
||||||
Rules []rules.Rule `json:"rules"`
|
Defaults settings.UserDefaults `json:"defaults"`
|
||||||
Branding settings.Branding `json:"branding"`
|
Rules []rules.Rule `json:"rules"`
|
||||||
Shell []string `json:"shell"`
|
Branding settings.Branding `json:"branding"`
|
||||||
Commands map[string][]string `json:"commands"`
|
Shell []string `json:"shell"`
|
||||||
|
Commands map[string][]string `json:"commands"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var settingsGetHandler = withAdmin(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) {
|
var settingsGetHandler = withAdmin(func(w http.ResponseWriter, r *http.Request, d *data) (int, error) {
|
||||||
data := &settingsData{
|
data := &settingsData{
|
||||||
Signup: d.settings.Signup,
|
Signup: d.settings.Signup,
|
||||||
Defaults: d.settings.Defaults,
|
CreateUserDir: d.settings.CreateUserDir,
|
||||||
Rules: d.settings.Rules,
|
Defaults: d.settings.Defaults,
|
||||||
Branding: d.settings.Branding,
|
Rules: d.settings.Rules,
|
||||||
Shell: d.settings.Shell,
|
Branding: d.settings.Branding,
|
||||||
Commands: d.settings.Commands,
|
Shell: d.settings.Shell,
|
||||||
|
Commands: d.settings.Commands,
|
||||||
}
|
}
|
||||||
|
|
||||||
return renderJSON(w, r, data)
|
return renderJSON(w, r, data)
|
||||||
@@ -38,6 +40,7 @@ var settingsPutHandler = withAdmin(func(w http.ResponseWriter, r *http.Request,
|
|||||||
}
|
}
|
||||||
|
|
||||||
d.settings.Signup = req.Signup
|
d.settings.Signup = req.Signup
|
||||||
|
d.settings.CreateUserDir = req.CreateUserDir
|
||||||
d.settings.Defaults = req.Defaults
|
d.settings.Defaults = req.Defaults
|
||||||
d.settings.Rules = req.Rules
|
d.settings.Rules = req.Rules
|
||||||
d.settings.Branding = req.Branding
|
d.settings.Branding = req.Branding
|
||||||
|
|||||||
@@ -21,6 +21,11 @@ func handleWithStaticData(w http.ResponseWriter, r *http.Request, d *data, box *
|
|||||||
|
|
||||||
staticURL := strings.TrimPrefix(d.server.BaseURL+"/static", "/")
|
staticURL := strings.TrimPrefix(d.server.BaseURL+"/static", "/")
|
||||||
|
|
||||||
|
auther, err := d.store.Auth.Get(d.settings.AuthMethod)
|
||||||
|
if err != nil {
|
||||||
|
return http.StatusInternalServerError, err
|
||||||
|
}
|
||||||
|
|
||||||
data := map[string]interface{}{
|
data := map[string]interface{}{
|
||||||
"Name": d.settings.Branding.Name,
|
"Name": d.settings.Branding.Name,
|
||||||
"DisableExternal": d.settings.Branding.DisableExternal,
|
"DisableExternal": d.settings.Branding.DisableExternal,
|
||||||
@@ -29,6 +34,7 @@ func handleWithStaticData(w http.ResponseWriter, r *http.Request, d *data, box *
|
|||||||
"StaticURL": staticURL,
|
"StaticURL": staticURL,
|
||||||
"Signup": d.settings.Signup,
|
"Signup": d.settings.Signup,
|
||||||
"NoAuth": d.settings.AuthMethod == auth.MethodNoAuth,
|
"NoAuth": d.settings.AuthMethod == auth.MethodNoAuth,
|
||||||
|
"LoginPage": auther.LoginPage(),
|
||||||
"CSS": false,
|
"CSS": false,
|
||||||
"ReCaptcha": false,
|
"ReCaptcha": false,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package http
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -119,6 +120,14 @@ var userPostHandler = withAdmin(func(w http.ResponseWriter, r *http.Request, d *
|
|||||||
return http.StatusInternalServerError, err
|
return http.StatusInternalServerError, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
userHome, err := d.settings.MakeUserDir(req.Data.Username, req.Data.Scope, d.server.Root)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("create user: failed to mkdir user home dir: [%s]", userHome)
|
||||||
|
return http.StatusInternalServerError, err
|
||||||
|
}
|
||||||
|
req.Data.Scope = userHome
|
||||||
|
log.Printf("user: %s, home dir: [%s].", req.Data.Username, userHome)
|
||||||
|
|
||||||
err = d.store.Users.Save(req.Data)
|
err = d.store.Users.Save(req.Data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return http.StatusInternalServerError, err
|
return http.StatusInternalServerError, err
|
||||||
|
|||||||
75
settings/dir.go
Normal file
75
settings/dir.go
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
package settings
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/spf13/afero"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
invalidFilenameChars = regexp.MustCompile(`[^0-9A-Za-z@_\-.]`)
|
||||||
|
|
||||||
|
dashes = regexp.MustCompile(`[\-]+`)
|
||||||
|
)
|
||||||
|
|
||||||
|
// MakeUserDir makes the user directory according to settings.
|
||||||
|
func (settings *Settings) MakeUserDir(username, userScope, serverRoot string) (string, error) {
|
||||||
|
var err error
|
||||||
|
userScope = strings.TrimSpace(userScope)
|
||||||
|
if userScope == "" || userScope == "./" {
|
||||||
|
userScope = "."
|
||||||
|
}
|
||||||
|
|
||||||
|
if !settings.CreateUserDir {
|
||||||
|
return userScope, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
fs := afero.NewBasePathFs(afero.NewOsFs(), serverRoot)
|
||||||
|
|
||||||
|
// Use the default auto create logic only if specific scope is not the default scope
|
||||||
|
if userScope != settings.Defaults.Scope {
|
||||||
|
// Try create the dir, for example: settings.Defaults.Scope == "." and userScope == "./foo"
|
||||||
|
if userScope != "." {
|
||||||
|
err = fs.MkdirAll(userScope, os.ModePerm)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("create user: failed to mkdir user home dir: [%s]", userScope)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return userScope, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean username first
|
||||||
|
username = cleanUsername(username)
|
||||||
|
if username == "" || username == "-" || username == "." {
|
||||||
|
log.Printf("create user: invalid user for home dir creation: [%s]", username)
|
||||||
|
return "", errors.New("invalid user for home dir creation")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create default user dir
|
||||||
|
userHomeBase := settings.Defaults.Scope + string(os.PathSeparator) + "users"
|
||||||
|
userHome := userHomeBase + string(os.PathSeparator) + username
|
||||||
|
err = fs.MkdirAll(userHome, os.ModePerm)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("create user: failed to mkdir user home dir: [%s]", userHome)
|
||||||
|
} else {
|
||||||
|
log.Printf("create user: mkdir user home dir: [%s] successfully.", userHome)
|
||||||
|
}
|
||||||
|
return userHome, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func cleanUsername(s string) string {
|
||||||
|
// Remove any trailing space to avoid ending on -
|
||||||
|
s = strings.Trim(s, " ")
|
||||||
|
s = strings.Replace(s, "..", "", -1)
|
||||||
|
|
||||||
|
// Replace all characters which not in the list `0-9A-Za-z@_\-.` with a dash
|
||||||
|
s = invalidFilenameChars.ReplaceAllString(s, "-")
|
||||||
|
|
||||||
|
// Remove any multiple dashes caused by replacements above
|
||||||
|
s = dashes.ReplaceAllString(s, "-")
|
||||||
|
return s
|
||||||
|
}
|
||||||
@@ -12,14 +12,15 @@ type AuthMethod string
|
|||||||
|
|
||||||
// Settings contain the main settings of the application.
|
// Settings contain the main settings of the application.
|
||||||
type Settings struct {
|
type Settings struct {
|
||||||
Key []byte `json:"key"`
|
Key []byte `json:"key"`
|
||||||
Signup bool `json:"signup"`
|
Signup bool `json:"signup"`
|
||||||
Defaults UserDefaults `json:"defaults"`
|
CreateUserDir bool `json:"createUserDir"`
|
||||||
AuthMethod AuthMethod `json:"authMethod"`
|
Defaults UserDefaults `json:"defaults"`
|
||||||
Branding Branding `json:"branding"`
|
AuthMethod AuthMethod `json:"authMethod"`
|
||||||
Commands map[string][]string `json:"commands"`
|
Branding Branding `json:"branding"`
|
||||||
Shell []string `json:"shell"`
|
Commands map[string][]string `json:"commands"`
|
||||||
Rules []rules.Rule `json:"rules"`
|
Shell []string `json:"shell"`
|
||||||
|
Rules []rules.Rule `json:"rules"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRules implements rules.Provider.
|
// GetRules implements rules.Provider.
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
"github.com/filebrowser/filebrowser/v2/rules"
|
"github.com/filebrowser/filebrowser/v2/rules"
|
||||||
"github.com/filebrowser/filebrowser/v2/storage"
|
"github.com/filebrowser/filebrowser/v2/storage"
|
||||||
"github.com/filebrowser/filebrowser/v2/users"
|
"github.com/filebrowser/filebrowser/v2/users"
|
||||||
"go.etcd.io/bbolt"
|
bolt "go.etcd.io/bbolt"
|
||||||
)
|
)
|
||||||
|
|
||||||
type oldUser struct {
|
type oldUser struct {
|
||||||
@@ -55,7 +55,6 @@ func convertUsersToNew(old []*oldUser) ([]*users.User, error) {
|
|||||||
|
|
||||||
for _, oldUser := range old {
|
for _, oldUser := range old {
|
||||||
user := &users.User{
|
user := &users.User{
|
||||||
ID: uint(oldUser.ID),
|
|
||||||
Username: oldUser.Username,
|
Username: oldUser.Username,
|
||||||
Password: oldUser.Password,
|
Password: oldUser.Password,
|
||||||
Scope: oldUser.Scope,
|
Scope: oldUser.Scope,
|
||||||
|
|||||||
@@ -89,11 +89,11 @@ func (s *Storage) Save(user *User) error {
|
|||||||
// id must be a string for username lookup or a uint for id lookup. If id
|
// id must be a string for username lookup or a uint for id lookup. If id
|
||||||
// is neither, a ErrInvalidDataType will be returned.
|
// is neither, a ErrInvalidDataType will be returned.
|
||||||
func (s *Storage) Delete(id interface{}) (err error) {
|
func (s *Storage) Delete(id interface{}) (err error) {
|
||||||
switch id.(type) {
|
switch id := id.(type) {
|
||||||
case string:
|
case string:
|
||||||
err = s.back.DeleteByUsername(id.(string))
|
err = s.back.DeleteByUsername(id)
|
||||||
case uint:
|
case uint:
|
||||||
err = s.back.DeleteByID(id.(uint))
|
err = s.back.DeleteByID(id)
|
||||||
default:
|
default:
|
||||||
err = errors.ErrInvalidDataType
|
err = errors.ErrInvalidDataType
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,5 +2,5 @@ package version
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
// Version is the current File Browser version.
|
// Version is the current File Browser version.
|
||||||
Version = "v2.0.0"
|
Version = "v2.0.4"
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user