mirror of
https://github.com/filebrowser/filebrowser.git
synced 2026-07-25 08:54:13 +00:00
Unit tests for Settings.CreateUserHome (derives a per-user home, rejects a colliding scope, preserves an explicit scope) plus proxy and hook regression tests asserting that with CreateUserDir enabled two provisioned users receive distinct home directories instead of the server root. Refs GHSA-j7jh-37pf-mf8h, GHSA-j2fc-28fx-hc8q
123 lines
3.5 KiB
Go
123 lines
3.5 KiB
Go
package auth
|
|
|
|
import (
|
|
"net/http"
|
|
"testing"
|
|
|
|
fberrors "github.com/filebrowser/filebrowser/v2/errors"
|
|
"github.com/filebrowser/filebrowser/v2/settings"
|
|
"github.com/filebrowser/filebrowser/v2/users"
|
|
)
|
|
|
|
type mockUserStore struct {
|
|
users map[string]*users.User
|
|
}
|
|
|
|
func (m *mockUserStore) Get(_ string, _ bool, id interface{}) (*users.User, error) {
|
|
if v, ok := id.(string); ok {
|
|
if u, ok := m.users[v]; ok {
|
|
return u, nil
|
|
}
|
|
}
|
|
return nil, fberrors.ErrNotExist
|
|
}
|
|
|
|
func (m *mockUserStore) GetByScope(_ string) (*users.User, error) { return nil, fberrors.ErrNotExist }
|
|
func (m *mockUserStore) Gets(_ string, _ bool) ([]*users.User, error) { return nil, nil }
|
|
func (m *mockUserStore) Update(_ *users.User, _ ...string) error { return nil }
|
|
func (m *mockUserStore) Save(user *users.User) error {
|
|
m.users[user.Username] = user
|
|
return nil
|
|
}
|
|
func (m *mockUserStore) Delete(_ interface{}) error { return nil }
|
|
func (m *mockUserStore) LastUpdate(_ uint) int64 { return 0 }
|
|
|
|
func TestProxyAuthCreateUserRestrictsDefaults(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
store := &mockUserStore{users: make(map[string]*users.User)}
|
|
srv := &settings.Server{Root: t.TempDir()}
|
|
|
|
s := &settings.Settings{
|
|
Key: []byte("key"),
|
|
AuthMethod: MethodProxyAuth,
|
|
Defaults: settings.UserDefaults{
|
|
Perm: users.Permissions{
|
|
Admin: true,
|
|
Execute: true,
|
|
Create: true,
|
|
Rename: true,
|
|
Modify: true,
|
|
Delete: true,
|
|
Share: true,
|
|
Download: true,
|
|
},
|
|
Commands: []string{"git", "ls", "cat", "id"},
|
|
},
|
|
}
|
|
|
|
auth := ProxyAuth{Header: "X-Remote-User"}
|
|
req, _ := http.NewRequest(http.MethodGet, "/", http.NoBody)
|
|
req.Header.Set("X-Remote-User", "newproxyuser")
|
|
|
|
user, err := auth.Auth(req, store, s, srv)
|
|
if err != nil {
|
|
t.Fatalf("Auth() error: %v", err)
|
|
}
|
|
|
|
if user.Perm.Admin {
|
|
t.Error("auto-provisioned proxy user should not have Admin permission")
|
|
}
|
|
if user.Perm.Execute {
|
|
t.Error("auto-provisioned proxy user should not have Execute permission")
|
|
}
|
|
if len(user.Commands) != 0 {
|
|
t.Errorf("auto-provisioned proxy user should have empty Commands, got %v", user.Commands)
|
|
}
|
|
if !user.Perm.Create {
|
|
t.Error("auto-provisioned proxy user should retain Create permission from defaults")
|
|
}
|
|
}
|
|
|
|
// With CreateUserDir enabled, two distinct proxy-authenticated users must each
|
|
// receive their own home directory instead of both inheriting the server root.
|
|
func TestProxyAuthCreateUserDirIsolatesScope(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
store := &mockUserStore{users: make(map[string]*users.User)}
|
|
srv := &settings.Server{Root: t.TempDir()}
|
|
s := &settings.Settings{
|
|
Key: []byte("key"),
|
|
AuthMethod: MethodProxyAuth,
|
|
CreateUserDir: true,
|
|
UserHomeBasePath: "/users",
|
|
Defaults: settings.UserDefaults{
|
|
Scope: ".",
|
|
Perm: users.Permissions{Create: true},
|
|
},
|
|
}
|
|
|
|
auth := ProxyAuth{Header: "X-Remote-User"}
|
|
provision := func(name string) *users.User {
|
|
req, _ := http.NewRequest(http.MethodGet, "/", http.NoBody)
|
|
req.Header.Set("X-Remote-User", name)
|
|
u, err := auth.Auth(req, store, s, srv)
|
|
if err != nil {
|
|
t.Fatalf("Auth(%q) error: %v", name, err)
|
|
}
|
|
return u
|
|
}
|
|
|
|
alice := provision("alice")
|
|
bob := provision("bob")
|
|
|
|
if alice.Scope == "/" || bob.Scope == "/" {
|
|
t.Fatalf("provisioned users inherited the server root: alice=%q bob=%q", alice.Scope, bob.Scope)
|
|
}
|
|
if alice.Scope == bob.Scope {
|
|
t.Fatalf("distinct users must get distinct scopes, both got %q", alice.Scope)
|
|
}
|
|
if alice.Scope != "/users/alice" {
|
|
t.Errorf("expected /users/alice, got %q", alice.Scope)
|
|
}
|
|
}
|