mirror of
https://github.com/ferdzo/fs.git
synced 2026-04-04 20:36:25 +00:00
170 lines
4.3 KiB
Go
170 lines
4.3 KiB
Go
package auth
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"errors"
|
|
"fs/metadata"
|
|
"fs/models"
|
|
"path/filepath"
|
|
"testing"
|
|
)
|
|
|
|
func TestAdminCreateListGetUser(t *testing.T) {
|
|
meta, svc := newTestAuthService(t)
|
|
|
|
created, err := svc.CreateUser(CreateUserInput{
|
|
AccessKeyID: "backup-user",
|
|
Policy: models.AuthPolicy{
|
|
Statements: []models.AuthPolicyStatement{
|
|
{
|
|
Effect: "allow",
|
|
Actions: []string{"s3:GetObject"},
|
|
Bucket: "backup-bucket",
|
|
Prefix: "restic/",
|
|
},
|
|
},
|
|
},
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("CreateUser returned error: %v", err)
|
|
}
|
|
if created.SecretKey == "" {
|
|
t.Fatalf("CreateUser should return generated secret")
|
|
}
|
|
if created.AccessKeyID != "backup-user" {
|
|
t.Fatalf("CreateUser access key mismatch: got %q", created.AccessKeyID)
|
|
}
|
|
if created.Policy.Principal != "backup-user" {
|
|
t.Fatalf("policy principal mismatch: got %q", created.Policy.Principal)
|
|
}
|
|
|
|
users, nextCursor, err := svc.ListUsers(100, "")
|
|
if err != nil {
|
|
t.Fatalf("ListUsers returned error: %v", err)
|
|
}
|
|
if nextCursor != "" {
|
|
t.Fatalf("unexpected next cursor: %q", nextCursor)
|
|
}
|
|
if len(users) != 1 {
|
|
t.Fatalf("ListUsers returned %d users, want 1", len(users))
|
|
}
|
|
if users[0].AccessKeyID != "backup-user" {
|
|
t.Fatalf("ListUsers returned wrong user: %q", users[0].AccessKeyID)
|
|
}
|
|
|
|
got, err := svc.GetUser("backup-user")
|
|
if err != nil {
|
|
t.Fatalf("GetUser returned error: %v", err)
|
|
}
|
|
if got.AccessKeyID != "backup-user" {
|
|
t.Fatalf("GetUser access key mismatch: got %q", got.AccessKeyID)
|
|
}
|
|
if got.Policy.Principal != "backup-user" {
|
|
t.Fatalf("GetUser policy principal mismatch: got %q", got.Policy.Principal)
|
|
}
|
|
if len(got.Policy.Statements) != 1 {
|
|
t.Fatalf("GetUser policy statement count = %d, want 1", len(got.Policy.Statements))
|
|
}
|
|
|
|
_ = meta
|
|
}
|
|
|
|
func TestCreateUserDuplicateFails(t *testing.T) {
|
|
_, svc := newTestAuthService(t)
|
|
|
|
input := CreateUserInput{
|
|
AccessKeyID: "duplicate-user",
|
|
SecretKey: "super-secret-1",
|
|
Policy: models.AuthPolicy{
|
|
Statements: []models.AuthPolicyStatement{
|
|
{Effect: "allow", Actions: []string{"s3:*"}, Bucket: "*", Prefix: "*"},
|
|
},
|
|
},
|
|
}
|
|
if _, err := svc.CreateUser(input); err != nil {
|
|
t.Fatalf("first CreateUser returned error: %v", err)
|
|
}
|
|
if _, err := svc.CreateUser(input); !errors.Is(err, ErrUserAlreadyExists) {
|
|
t.Fatalf("second CreateUser error = %v, want ErrUserAlreadyExists", err)
|
|
}
|
|
}
|
|
|
|
func TestCreateUserRejectsInvalidAccessKey(t *testing.T) {
|
|
_, svc := newTestAuthService(t)
|
|
|
|
_, err := svc.CreateUser(CreateUserInput{
|
|
AccessKeyID: "x",
|
|
SecretKey: "super-secret-1",
|
|
Policy: models.AuthPolicy{
|
|
Statements: []models.AuthPolicyStatement{
|
|
{Effect: "allow", Actions: []string{"s3:*"}, Bucket: "*", Prefix: "*"},
|
|
},
|
|
},
|
|
})
|
|
if !errors.Is(err, ErrInvalidUserInput) {
|
|
t.Fatalf("CreateUser error = %v, want ErrInvalidUserInput", err)
|
|
}
|
|
}
|
|
|
|
func TestDeleteUser(t *testing.T) {
|
|
_, svc := newTestAuthService(t)
|
|
|
|
_, err := svc.CreateUser(CreateUserInput{
|
|
AccessKeyID: "delete-user",
|
|
SecretKey: "super-secret-1",
|
|
Policy: models.AuthPolicy{
|
|
Statements: []models.AuthPolicyStatement{
|
|
{Effect: "allow", Actions: []string{"s3:*"}, Bucket: "*", Prefix: "*"},
|
|
},
|
|
},
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("CreateUser returned error: %v", err)
|
|
}
|
|
|
|
if err := svc.DeleteUser("delete-user"); err != nil {
|
|
t.Fatalf("DeleteUser returned error: %v", err)
|
|
}
|
|
if _, err := svc.GetUser("delete-user"); !errors.Is(err, ErrUserNotFound) {
|
|
t.Fatalf("GetUser after delete error = %v, want ErrUserNotFound", err)
|
|
}
|
|
}
|
|
|
|
func TestDeleteBootstrapUserRejected(t *testing.T) {
|
|
_, svc := newTestAuthService(t)
|
|
|
|
if err := svc.DeleteUser("root-user"); !errors.Is(err, ErrInvalidUserInput) {
|
|
t.Fatalf("DeleteUser bootstrap error = %v, want ErrInvalidUserInput", err)
|
|
}
|
|
}
|
|
|
|
func newTestAuthService(t *testing.T) (*metadata.MetadataHandler, *Service) {
|
|
t.Helper()
|
|
|
|
dbPath := filepath.Join(t.TempDir(), "metadata.db")
|
|
meta, err := metadata.NewMetadataHandler(dbPath)
|
|
if err != nil {
|
|
t.Fatalf("NewMetadataHandler returned error: %v", err)
|
|
}
|
|
t.Cleanup(func() {
|
|
_ = meta.Close()
|
|
})
|
|
|
|
masterKey := base64.StdEncoding.EncodeToString(make([]byte, 32))
|
|
cfg := ConfigFromValues(
|
|
true,
|
|
"us-east-1",
|
|
0,
|
|
0,
|
|
masterKey,
|
|
"root-user",
|
|
"root-secret-123",
|
|
"",
|
|
)
|
|
svc, err := NewService(cfg, meta)
|
|
if err != nil {
|
|
t.Fatalf("NewService returned error: %v", err)
|
|
}
|
|
return meta, svc
|
|
}
|