diff --git a/cmd/filebrowser/main.go b/cmd/filebrowser/main.go index b9d1f7b4..a9ef208a 100644 --- a/cmd/filebrowser/main.go +++ b/cmd/filebrowser/main.go @@ -37,10 +37,9 @@ var ( recaptchasecret string port int auth struct { - method string - loginHeader string + method string + header string } - noAuth bool allowCommands bool allowEdit bool allowNew bool @@ -76,9 +75,8 @@ func init() { flag.StringVar(&recaptchasecret, "recaptcha.secret", "", "ReCaptcha secret") // Auth settings - flag.BoolVar(&noAuth, "noAuth", false, "Disables authentication") - flag.StringVar(&auth.method, "auth.method", "default", "Switch between 'none', 'default' and 'proxy' authentication.") - flag.StringVar(&auth.loginHeader, "auth.loginHeader", "X-Forwarded-User", "The header name used for proxy authentication.") + flag.StringVar(&auth.method, "auth.method", "default", "Switch between 'none', 'default' and 'proxy' authentication") + flag.StringVar(&auth.header, "auth.header", "X-Forwarded-User", "The header name used for proxy authentication") } func setupViper() { @@ -89,7 +87,6 @@ func setupViper() { viper.SetDefault("BaseURL", "") viper.SetDefault("PrefixURL", "") viper.SetDefault("StaticGen", "") - viper.SetDefault("NoAuth", false) viper.BindPFlag("Port", flag.Lookup("port")) viper.BindPFlag("Address", flag.Lookup("address")) @@ -98,7 +95,6 @@ func setupViper() { viper.BindPFlag("BaseURL", flag.Lookup("baseurl")) viper.BindPFlag("PrefixURL", flag.Lookup("prefixurl")) viper.BindPFlag("StaticGen", flag.Lookup("staticgen")) - viper.BindPFlag("NoAuth", flag.Lookup("no-auth")) // User default values viper.SetDefault("Defaults.Scope", ".") @@ -129,11 +125,11 @@ func setupViper() { viper.BindPFlag("Recaptcha.Secret", flag.Lookup("recaptcha.secret")) // Auth settings - viper.SetDefault("AuthMethod", "default") - viper.SetDefault("LoginHeader", "X-Fowarded-User") + viper.SetDefault("Auth.Method", "default") + viper.SetDefault("Auth.Header", "X-Fowarded-User") - viper.BindPFlag("AuthMethod", flag.Lookup("auth.method")) - viper.BindPFlag("LoginHeader", flag.Lookup("auth.loginHeader")) + viper.BindPFlag("Auth.Method", flag.Lookup("auth.method")) + viper.BindPFlag("Auth.Header", flag.Lookup("auth.header")) viper.SetConfigName("filebrowser") viper.AddConfigPath(".") @@ -192,13 +188,13 @@ func main() { } // Validate the provided config before moving forward - if viper.GetString("AuthMethod") != "none" && viper.GetString("AuthMethod") != "default" && viper.GetString("AuthMethod") != "proxy" { + if viper.GetString("Auth.Method") != "none" && viper.GetString("Auth.Method") != "default" && viper.GetString("Auth.Method") != "proxy" { log.Fatal("The property 'auth.method' needs to be set to 'default' or 'proxy'.") } - if viper.GetString("AuthMethod") == "proxy" { - if viper.GetString("LoginHeader") == "" { - log.Fatal("The 'loginHeader' needs to be specified when 'proxy' authentication is used.") + if viper.GetString("Auth.Method") == "proxy" { + if viper.GetString("Auth.Header") == "" { + log.Fatal("The 'auth.header' needs to be specified when 'proxy' authentication is used.") } log.Println("[WARN] Filebrowser authentication is configured to 'proxy' authentication. This can cause a huge security issue if the infrastructure is not configured correctly.") } @@ -231,11 +227,10 @@ func handler() http.Handler { } fm := &filebrowser.FileBrowser{ - AuthMethod: viper.GetString("AuthMethod"), - LoginHeader: viper.GetString("LoginHeader"), - NoAuth: viper.GetBool("NoAuth"), - BaseURL: viper.GetString("BaseURL"), - PrefixURL: viper.GetString("PrefixURL"), + Auth: &filebrowser.Auth{ + Method: viper.GetString("Auth.Method"), + Header: viper.GetString("Auth.Header"), + }, ReCaptcha: &filebrowser.ReCaptcha{ Host: recaptchaHost, Key: viper.GetString("Recaptcha.Key"), @@ -264,6 +259,9 @@ func handler() http.Handler { }, } + fm.SetBaseURL(viper.GetString("BaseURL")) + fm.SetPrefixURL(viper.GetString("PrefixURL")) + err = fm.Setup() if err != nil { log.Fatal(err) diff --git a/filebrowser.go b/filebrowser.go index ddf26eac..04fb185e 100644 --- a/filebrowser.go +++ b/filebrowser.go @@ -48,6 +48,18 @@ type ReCaptcha struct { Secret string } +// Auth settings. +type Auth struct { + // Define if which of the following authentication mechansims should be used: + // - 'default', which requires a user and a password. + // - 'proxy', which requires a valid user and the user name has to be provided through an + // http header. + // - 'none', which allows anyone to access the filebrowser instance. + Method string + // If 'Method' is set to 'proxy' the header configured below is used to identify the user. + Header string +} + // FileBrowser is a file manager instance. It should be creating using the // 'New' function and not directly. type FileBrowser struct { @@ -74,19 +86,8 @@ type FileBrowser struct { // edited directly. Use SetBaseURL. BaseURL string - // NoAuth disables the authentication. When the authentication is disabled, - // there will only exist one user, called "admin". - NoAuth bool - - // Define if which of the following authentication mechansims should be used: - // - 'default', which requires a user and a password. - // - 'proxy', which requires a valid user and the user name has to be provided through an - // http header. - // - 'none', which allows anyone to access the filebrowser instance. - AuthMethod string - - // When 'AuthMethod' is set to 'proxy' the header configured below is used to identify the user. - LoginHeader string + // Authentication configuration. + Auth *Auth // ReCaptcha host, key and secret. ReCaptcha *ReCaptcha diff --git a/http/auth.go b/http/auth.go index d184e34a..d3d46eb5 100644 --- a/http/auth.go +++ b/http/auth.go @@ -51,14 +51,14 @@ func reCaptcha(host, secret, response string) (bool, error) { // authHandler processes the authentication for the user. func authHandler(c *fb.Context, w http.ResponseWriter, r *http.Request) (int, error) { - if c.NoAuth { + if c.Auth.Method == "none" { // NoAuth instances shouldn't call this method. return 0, nil } - if c.AuthMethod == "proxy" { + if c.Auth.Method == "proxy" { // Receive the Username from the Header and check if it exists. - u, err := c.Store.Users.GetByUsername(r.Header.Get(c.LoginHeader), c.NewFS) + u, err := c.Store.Users.GetByUsername(r.Header.Get(c.Auth.Header), c.NewFS) if err != nil { return http.StatusForbidden, nil } @@ -178,14 +178,14 @@ func (e extractor) ExtractToken(r *http.Request) (string, error) { // validateAuth is used to validate the authentication and returns the // User if it is valid. func validateAuth(c *fb.Context, r *http.Request) (bool, *fb.User) { - if c.NoAuth { + if c.Auth.Method == "none" { c.User = c.DefaultUser return true, c.User } // If proxy auth is used do not verify the JWT token if the header is provided. - if c.AuthMethod == "proxy" { - u, err := c.Store.Users.GetByUsername(r.Header.Get(c.LoginHeader), c.NewFS) + if c.Auth.Method == "proxy" { + u, err := c.Store.Users.GetByUsername(r.Header.Get(c.Auth.Header), c.NewFS) if err != nil { return false, nil } diff --git a/http/http.go b/http/http.go index 55e43eef..9ef409f4 100644 --- a/http/http.go +++ b/http/http.go @@ -228,7 +228,7 @@ func renderFile(c *fb.Context, w http.ResponseWriter, file string) (int, error) data := map[string]interface{}{ "BaseURL": c.RootURL(), - "NoAuth": c.NoAuth, + "NoAuth": c.Auth.Method == "none", "Version": fb.Version, "CSS": template.CSS(c.CSS), "ReCaptcha": c.ReCaptcha.Key != "" && c.ReCaptcha.Secret != "", diff --git a/http/users.go b/http/users.go index f924e304..aab4c89d 100644 --- a/http/users.go +++ b/http/users.go @@ -276,7 +276,7 @@ func usersPutHandler(c *fb.Context, w http.ResponseWriter, r *http.Request) (int // If we're updating the default user. Only for NoAuth // implementations. Used to change the viewMode. - if id == 0 && c.NoAuth { + if id == 0 && c.Auth.Method == "none" { c.DefaultUser.ViewMode = u.ViewMode return http.StatusOK, nil }