1
0
forked from baron/baron-sso
Files
baron-sso/backend/internal/bootstrap/admin_account_test.go

160 lines
4.6 KiB
Go

package bootstrap
import (
"baron-sso-backend/internal/domain"
"context"
"errors"
"testing"
)
func TestEnsureSuperAdminCreatesIdentityLocalUserAndKetoRelation(t *testing.T) {
ctx := context.Background()
identityAdmin := &fakeSuperAdminIdentityAdmin{createdID: "identity-1"}
store := &fakeSuperAdminStore{}
result, err := EnsureSuperAdmin(ctx, identityAdmin, store, EnsureSuperAdminOptions{
Email: "new-admin@example.com",
Password: "Password!123",
Name: "New Admin",
Source: "test",
})
if err != nil {
t.Fatalf("EnsureSuperAdmin returned error: %v", err)
}
if !result.IdentityCreated {
t.Fatal("identity must be created")
}
if !result.LocalUserCreated {
t.Fatal("local user must be created")
}
if result.IdentityID != "identity-1" {
t.Fatalf("identity ID = %q, want identity-1", result.IdentityID)
}
if store.user == nil {
t.Fatal("local user was not stored")
}
if store.user.Email != "new-admin@example.com" {
t.Fatalf("local user email = %q", store.user.Email)
}
if store.user.Role != domain.RoleSuperAdmin {
t.Fatalf("local user role = %q, want %q", store.user.Role, domain.RoleSuperAdmin)
}
if len(store.ketoSubjects) != 1 || store.ketoSubjects[0] != "User:identity-1" {
t.Fatalf("keto subjects = %#v, want User:identity-1", store.ketoSubjects)
}
if identityAdmin.createdUser == nil || identityAdmin.createdUser.Attributes["role"] != domain.RoleSuperAdmin {
t.Fatalf("created identity attributes = %#v", identityAdmin.createdUser)
}
}
func TestEnsureSuperAdminPromotesExistingLocalUser(t *testing.T) {
ctx := context.Background()
identityAdmin := &fakeSuperAdminIdentityAdmin{existingID: "identity-1"}
store := &fakeSuperAdminStore{
user: &domain.User{
ID: "local-user-1",
Email: "existing@example.com",
Name: "Existing",
Role: domain.RoleUser,
Status: domain.UserStatusInactive,
},
}
result, err := EnsureSuperAdmin(ctx, identityAdmin, store, EnsureSuperAdminOptions{
Email: "existing@example.com",
Password: "Password!123",
Name: "Existing Admin",
Source: "test",
})
if err != nil {
t.Fatalf("EnsureSuperAdmin returned error: %v", err)
}
if result.IdentityCreated {
t.Fatal("existing identity must not be recreated")
}
if !result.LocalUserUpdated {
t.Fatal("local user must be promoted")
}
if store.user.Role != domain.RoleSuperAdmin {
t.Fatalf("local user role = %q, want %q", store.user.Role, domain.RoleSuperAdmin)
}
if store.user.Status != domain.UserStatusActive {
t.Fatalf("local user status = %q, want %q", store.user.Status, domain.UserStatusActive)
}
if len(store.ketoSubjects) != 1 || store.ketoSubjects[0] != "User:local-user-1" {
t.Fatalf("keto subjects = %#v, want User:local-user-1", store.ketoSubjects)
}
}
func TestEnsureSuperAdminRequiresPasswordForNewIdentity(t *testing.T) {
_, err := EnsureSuperAdmin(context.Background(), &fakeSuperAdminIdentityAdmin{}, &fakeSuperAdminStore{}, EnsureSuperAdminOptions{
Email: "new-admin@example.com",
Name: "New Admin",
})
if err == nil {
t.Fatal("expected error")
}
}
type fakeSuperAdminIdentityAdmin struct {
existingID string
createdID string
createdUser *domain.BrokerUser
createdSecret string
}
func (f *fakeSuperAdminIdentityAdmin) FindIdentityIDByIdentifier(ctx context.Context, identifier string) (string, error) {
return f.existingID, nil
}
func (f *fakeSuperAdminIdentityAdmin) CreateUser(ctx context.Context, user *domain.BrokerUser, password string) (string, error) {
if f.createdID == "" {
return "", errors.New("created id is not configured")
}
f.createdUser = user
f.createdSecret = password
return f.createdID, nil
}
func (f *fakeSuperAdminIdentityAdmin) UpdateIdentityPassword(ctx context.Context, identityID string, newPassword string) error {
return nil
}
type fakeSuperAdminStore struct {
user *domain.User
ketoSubjects []string
}
func (f *fakeSuperAdminStore) FindUserByEmail(ctx context.Context, email string) (*domain.User, error) {
if f.user == nil {
return nil, nil
}
return f.user, nil
}
func (f *fakeSuperAdminStore) CreateUser(ctx context.Context, user *domain.User) error {
copied := *user
f.user = &copied
return nil
}
func (f *fakeSuperAdminStore) UpdateUserSuperAdmin(ctx context.Context, userID string, name string) (*domain.User, error) {
if f.user == nil {
return nil, errors.New("user not found")
}
f.user.Role = domain.RoleSuperAdmin
f.user.Status = domain.UserStatusActive
if name != "" {
f.user.Name = name
}
return f.user, nil
}
func (f *fakeSuperAdminStore) EnqueueSuperAdminRelation(ctx context.Context, userID string) error {
f.ketoSubjects = append(f.ketoSubjects, "User:"+userID)
return nil
}