mirror of
https://github.com/hacdias/webdav.git
synced 2026-09-22 03:20:41 +08:00
feat: allow disabling password check for delegated authentication
This commit is contained in:
@@ -106,7 +106,14 @@ cors:
|
|||||||
- Content-Length
|
- Content-Length
|
||||||
- Content-Range
|
- Content-Range
|
||||||
|
|
||||||
# The list of users. If users is empty, then there will be no authentication.
|
# The list of users. If the list is empty, then there will be no authentication.
|
||||||
|
# Otherwise, basic authentication will automatically be configured.
|
||||||
|
#
|
||||||
|
# If you're delegating the authentication to a different service, you can proxy
|
||||||
|
# the username using basic authentication, and then disable webdav's password
|
||||||
|
# check using the option:
|
||||||
|
#
|
||||||
|
# noPassword: true
|
||||||
users:
|
users:
|
||||||
# Example 'admin' user with plaintext password.
|
# Example 'admin' user with plaintext password.
|
||||||
- username: admin
|
- username: admin
|
||||||
|
|||||||
+3
-1
@@ -32,6 +32,7 @@ type Config struct {
|
|||||||
Key string
|
Key string
|
||||||
Prefix string
|
Prefix string
|
||||||
NoSniff bool
|
NoSniff bool
|
||||||
|
NoPassword bool
|
||||||
Log Log
|
Log Log
|
||||||
CORS CORS
|
CORS CORS
|
||||||
Users []User
|
Users []User
|
||||||
@@ -77,6 +78,7 @@ func ParseConfig(filename string, flags *pflag.FlagSet) (*Config, error) {
|
|||||||
v.SetDefault("Permissions", "R")
|
v.SetDefault("Permissions", "R")
|
||||||
v.SetDefault("Debug", false)
|
v.SetDefault("Debug", false)
|
||||||
v.SetDefault("NoSniff", false)
|
v.SetDefault("NoSniff", false)
|
||||||
|
v.SetDefault("NoPassword", false)
|
||||||
v.SetDefault("Log.Format", "console")
|
v.SetDefault("Log.Format", "console")
|
||||||
v.SetDefault("Log.Outputs", []string{"stderr"})
|
v.SetDefault("Log.Outputs", []string{"stderr"})
|
||||||
v.SetDefault("Log.Colors", true)
|
v.SetDefault("Log.Colors", true)
|
||||||
@@ -159,7 +161,7 @@ func (c *Config) Validate() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, u := range c.Users {
|
for _, u := range c.Users {
|
||||||
err := u.Validate()
|
err := u.Validate(c.NoPassword)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("invalid config: %w", err)
|
return fmt.Errorf("invalid config: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-3
@@ -17,12 +17,14 @@ type handlerUser struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Handler struct {
|
type Handler struct {
|
||||||
user *handlerUser
|
noPassword bool
|
||||||
users map[string]*handlerUser
|
user *handlerUser
|
||||||
|
users map[string]*handlerUser
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHandler(c *Config) (http.Handler, error) {
|
func NewHandler(c *Config) (http.Handler, error) {
|
||||||
h := &Handler{
|
h := &Handler{
|
||||||
|
noPassword: c.NoPassword,
|
||||||
user: &handlerUser{
|
user: &handlerUser{
|
||||||
User: User{
|
User: User{
|
||||||
UserPermissions: c.UserPermissions,
|
UserPermissions: c.UserPermissions,
|
||||||
@@ -67,6 +69,10 @@ func NewHandler(c *Config) (http.Handler, error) {
|
|||||||
zap.L().Warn("unprotected config: no users have been set, so no authentication will be used")
|
zap.L().Warn("unprotected config: no users have been set, so no authentication will be used")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if c.NoPassword {
|
||||||
|
zap.L().Warn("unprotected config: password check is disabled, only intended when delegating authentication to another service")
|
||||||
|
}
|
||||||
|
|
||||||
return h, nil
|
return h, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,7 +98,7 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !user.checkPassword(password) {
|
if !h.noPassword && !user.checkPassword(password) {
|
||||||
zap.L().Info("invalid password", zap.String("username", username), zap.String("remote_address", r.RemoteAddr))
|
zap.L().Info("invalid password", zap.String("username", username), zap.String("remote_address", r.RemoteAddr))
|
||||||
http.Error(w, "Not authorized", http.StatusUnauthorized)
|
http.Error(w, "Not authorized", http.StatusUnauthorized)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -183,6 +183,40 @@ users:
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestServerAuthenticationNoPassword(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
dir := makeTestDirectory(t, map[string][]byte{
|
||||||
|
"foo.txt": []byte("foo"),
|
||||||
|
"sub/bar.txt": []byte("bar"),
|
||||||
|
})
|
||||||
|
|
||||||
|
srv := makeTestServer(t, fmt.Sprintf(`
|
||||||
|
directory: %s
|
||||||
|
noPassword: true
|
||||||
|
permissions: CRUD
|
||||||
|
|
||||||
|
users:
|
||||||
|
- username: basic
|
||||||
|
`, dir))
|
||||||
|
|
||||||
|
t.Run("Basic Auth", func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
client := gowebdav.NewClient(srv.URL, "basic", "")
|
||||||
|
files, err := client.ReadDir("/")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Len(t, files, 2)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Unauthorized Wrong User", func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
client := gowebdav.NewClient(srv.URL, "wrong", "")
|
||||||
|
_, err := client.ReadDir("/")
|
||||||
|
require.ErrorContains(t, err, "401")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestServerRules(t *testing.T) {
|
func TestServerRules(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -24,12 +24,12 @@ func (u User) checkPassword(input string) bool {
|
|||||||
return u.Password == input
|
return u.Password == input
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *User) Validate() error {
|
func (u *User) Validate(noPassword bool) error {
|
||||||
if u.Username == "" {
|
if u.Username == "" {
|
||||||
return errors.New("invalid user: username must be set")
|
return errors.New("invalid user: username must be set")
|
||||||
}
|
}
|
||||||
|
|
||||||
if u.Password == "" {
|
if u.Password == "" && !noPassword {
|
||||||
return fmt.Errorf("invalid user %q: password must be set", u.Username)
|
return fmt.Errorf("invalid user %q: password must be set", u.Username)
|
||||||
} else if strings.HasPrefix(u.Password, "{env}") {
|
} else if strings.HasPrefix(u.Password, "{env}") {
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user