feat: more role backend and admin/writer roles additions and adjustments
This commit is contained in:
1 parent
8c6c6456da
commit
de142f6c5f
131 files changed
+2663
-435
No files matched your search
+29
-26
@@ -2,6 +2,7 @@ package test
|
||||
|
||||
import (
|
||||
"RenewCMS/internal/domain/apikey"
|
||||
"RenewCMS/internal/domain/role"
|
||||
"RenewCMS/internal/domain/user"
|
||||
"RenewCMS/internal/infrastructure/hashing"
|
||||
"RenewCMS/internal/infrastructure/useCases"
|
||||
@@ -173,6 +174,11 @@ func seedStubKey(repo *mockAPIKeyRepo, raw string, mutate func(*apikey.APIKey))
|
||||
return stored
|
||||
}
|
||||
|
||||
var (
|
||||
apiKeyOwnScope = role.NewGrantSet([]role.Grant{{Key: role.KeyAPIKeysView, Scope: role.ScopeOwn}, {Key: role.KeyAPIKeysRevoke, Scope: role.ScopeOwn}})
|
||||
apiKeyAllScope = role.NewGrantSet([]role.Grant{{Key: role.KeyAPIKeysView, Scope: role.ScopeAll}, {Key: role.KeyAPIKeysRevoke, Scope: role.ScopeAll}})
|
||||
)
|
||||
|
||||
func apiKeyUnitUsers() *mockUserRepo {
|
||||
users := newMockUserRepo()
|
||||
users.users[1] = user.User{ID: 1, Username: "marta", IsVerified: true, Role: user.RoleOwner}
|
||||
@@ -402,10 +408,10 @@ func TestListAPIKeysUseCase(t *testing.T) {
|
||||
return result
|
||||
}
|
||||
|
||||
t.Run("An admin lists only their own keys, newest first", func(t *testing.T) {
|
||||
t.Run("A caller with own scope lists only their own keys, newest first", func(t *testing.T) {
|
||||
repo := newMockAPIKeyRepo()
|
||||
seed(repo)
|
||||
entries, err := useCases.NewListAPIKeysUseCase(repo, apiKeyUnitUsers(), apiKeyUnitClock).ListAPIKeys(2)
|
||||
entries, err := useCases.NewListAPIKeysUseCase(repo, apiKeyUnitUsers(), apiKeyUnitClock).ListAPIKeys(2, apiKeyOwnScope)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
@@ -414,10 +420,10 @@ func TestListAPIKeysUseCase(t *testing.T) {
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("The owner lists every key, newest first", func(t *testing.T) {
|
||||
t.Run("A caller with all scope lists every key, newest first", func(t *testing.T) {
|
||||
repo := newMockAPIKeyRepo()
|
||||
seed(repo)
|
||||
entries, err := useCases.NewListAPIKeysUseCase(repo, apiKeyUnitUsers(), apiKeyUnitClock).ListAPIKeys(1)
|
||||
entries, err := useCases.NewListAPIKeysUseCase(repo, apiKeyUnitUsers(), apiKeyUnitClock).ListAPIKeys(1, apiKeyAllScope)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
@@ -436,7 +442,7 @@ func TestListAPIKeysUseCase(t *testing.T) {
|
||||
for _, raw := range []string{"rcms_first", "rcms_second", "rcms_third"} {
|
||||
seedStubKey(repo, raw, func(k *apikey.APIKey) { k.CreatedAt = same })
|
||||
}
|
||||
entries, err := useCases.NewListAPIKeysUseCase(repo, apiKeyUnitUsers(), apiKeyUnitClock).ListAPIKeys(2)
|
||||
entries, err := useCases.NewListAPIKeysUseCase(repo, apiKeyUnitUsers(), apiKeyUnitClock).ListAPIKeys(2, apiKeyOwnScope)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
@@ -455,7 +461,7 @@ func TestListAPIKeysUseCase(t *testing.T) {
|
||||
seedStubKey(repo, "rcms_expired", func(k *apikey.APIKey) { k.ExpiresAt = &expired })
|
||||
seedStubKey(repo, "rcms_both", func(k *apikey.APIKey) { k.ExpiresAt = &expired; k.RevokedAt = &revoked })
|
||||
|
||||
entries, _ := useCases.NewListAPIKeysUseCase(repo, apiKeyUnitUsers(), apiKeyUnitClock).ListAPIKeys(2)
|
||||
entries, _ := useCases.NewListAPIKeysUseCase(repo, apiKeyUnitUsers(), apiKeyUnitClock).ListAPIKeys(2, apiKeyOwnScope)
|
||||
statuses := map[string]apikey.Status{}
|
||||
for _, entry := range entries {
|
||||
statuses[entry.Key.Prefix] = entry.Status
|
||||
@@ -468,15 +474,15 @@ func TestListAPIKeysUseCase(t *testing.T) {
|
||||
t.Run("An unknown requester and repository failures are returned", func(t *testing.T) {
|
||||
repo := newMockAPIKeyRepo()
|
||||
uc := useCases.NewListAPIKeysUseCase(repo, apiKeyUnitUsers(), apiKeyUnitClock)
|
||||
if _, err := uc.ListAPIKeys(99); !errors.Is(err, user.ErrUserNotFound) {
|
||||
if _, err := uc.ListAPIKeys(99, apiKeyOwnScope); !errors.Is(err, user.ErrUserNotFound) {
|
||||
t.Errorf("expected ErrUserNotFound, got %v", err)
|
||||
}
|
||||
repo.fail.failNext("ListByUser")
|
||||
if _, err := uc.ListAPIKeys(2); !errors.Is(err, errRepositoryFailure) {
|
||||
if _, err := uc.ListAPIKeys(2, apiKeyOwnScope); !errors.Is(err, errRepositoryFailure) {
|
||||
t.Errorf("expected the repository failure, got %v", err)
|
||||
}
|
||||
repo.fail.failNext("ListAll")
|
||||
if _, err := uc.ListAPIKeys(1); !errors.Is(err, errRepositoryFailure) {
|
||||
if _, err := uc.ListAPIKeys(1, apiKeyAllScope); !errors.Is(err, errRepositoryFailure) {
|
||||
t.Errorf("expected the repository failure, got %v", err)
|
||||
}
|
||||
})
|
||||
@@ -486,9 +492,9 @@ func TestRevokeAPIKeyUseCase(t *testing.T) {
|
||||
t.Run("A creator revokes their own key at the clock's now", func(t *testing.T) {
|
||||
repo := newMockAPIKeyRepo()
|
||||
stored := seedStubKey(repo, "rcms_a", nil)
|
||||
uc := useCases.NewRevokeAPIKeyUseCase(repo, apiKeyUnitUsers(), apiKeyUnitClock, discardRecorder)
|
||||
uc := useCases.NewRevokeAPIKeyUseCase(repo, apiKeyUnitClock, discardRecorder)
|
||||
|
||||
if err := uc.RevokeAPIKey(testCtx, 2, stored.ID); err != nil {
|
||||
if err := uc.RevokeAPIKey(testCtx, 2, stored.ID, apiKeyOwnScope); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if got := repo.keys[stored.ID].RevokedAt; got == nil || !got.Equal(apiKeyUnitNow) {
|
||||
@@ -496,12 +502,12 @@ func TestRevokeAPIKeyUseCase(t *testing.T) {
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Another admin gets not found and the key stays active", func(t *testing.T) {
|
||||
t.Run("Another own-scope caller gets not found and the key stays active", func(t *testing.T) {
|
||||
repo := newMockAPIKeyRepo()
|
||||
stored := seedStubKey(repo, "rcms_a", nil)
|
||||
uc := useCases.NewRevokeAPIKeyUseCase(repo, apiKeyUnitUsers(), apiKeyUnitClock, discardRecorder)
|
||||
uc := useCases.NewRevokeAPIKeyUseCase(repo, apiKeyUnitClock, discardRecorder)
|
||||
|
||||
if err := uc.RevokeAPIKey(testCtx, 3, stored.ID); !errors.Is(err, apikey.ErrAPIKeyNotFound) {
|
||||
if err := uc.RevokeAPIKey(testCtx, 3, stored.ID, apiKeyOwnScope); !errors.Is(err, apikey.ErrAPIKeyNotFound) {
|
||||
t.Errorf("expected ErrAPIKeyNotFound, got %v", err)
|
||||
}
|
||||
if repo.keys[stored.ID].RevokedAt != nil || repo.revokeCalls != 0 {
|
||||
@@ -509,12 +515,12 @@ func TestRevokeAPIKeyUseCase(t *testing.T) {
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("The owner revokes any key", func(t *testing.T) {
|
||||
t.Run("A caller with all scope revokes any key", func(t *testing.T) {
|
||||
repo := newMockAPIKeyRepo()
|
||||
stored := seedStubKey(repo, "rcms_a", func(k *apikey.APIKey) { k.UserID = 3 })
|
||||
uc := useCases.NewRevokeAPIKeyUseCase(repo, apiKeyUnitUsers(), apiKeyUnitClock, discardRecorder)
|
||||
uc := useCases.NewRevokeAPIKeyUseCase(repo, apiKeyUnitClock, discardRecorder)
|
||||
|
||||
if err := uc.RevokeAPIKey(testCtx, 1, stored.ID); err != nil {
|
||||
if err := uc.RevokeAPIKey(testCtx, 1, stored.ID, apiKeyAllScope); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if repo.keys[stored.ID].RevokedAt == nil {
|
||||
@@ -526,9 +532,9 @@ func TestRevokeAPIKeyUseCase(t *testing.T) {
|
||||
repo := newMockAPIKeyRepo()
|
||||
original := apiKeyUnitNow.Add(-time.Hour)
|
||||
stored := seedStubKey(repo, "rcms_a", func(k *apikey.APIKey) { k.RevokedAt = &original })
|
||||
uc := useCases.NewRevokeAPIKeyUseCase(repo, apiKeyUnitUsers(), apiKeyUnitClock, discardRecorder)
|
||||
uc := useCases.NewRevokeAPIKeyUseCase(repo, apiKeyUnitClock, discardRecorder)
|
||||
|
||||
if err := uc.RevokeAPIKey(testCtx, 2, stored.ID); err != nil {
|
||||
if err := uc.RevokeAPIKey(testCtx, 2, stored.ID, apiKeyOwnScope); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if got := repo.keys[stored.ID].RevokedAt; got == nil || !got.Equal(original) {
|
||||
@@ -536,19 +542,16 @@ func TestRevokeAPIKeyUseCase(t *testing.T) {
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("An unknown key, an unknown requester and repository failures are returned", func(t *testing.T) {
|
||||
t.Run("An unknown key and repository failures are returned", func(t *testing.T) {
|
||||
repo := newMockAPIKeyRepo()
|
||||
stored := seedStubKey(repo, "rcms_a", nil)
|
||||
uc := useCases.NewRevokeAPIKeyUseCase(repo, apiKeyUnitUsers(), apiKeyUnitClock, discardRecorder)
|
||||
uc := useCases.NewRevokeAPIKeyUseCase(repo, apiKeyUnitClock, discardRecorder)
|
||||
|
||||
if err := uc.RevokeAPIKey(testCtx, 2, 999); !errors.Is(err, apikey.ErrAPIKeyNotFound) {
|
||||
if err := uc.RevokeAPIKey(testCtx, 2, 999, apiKeyOwnScope); !errors.Is(err, apikey.ErrAPIKeyNotFound) {
|
||||
t.Errorf("expected ErrAPIKeyNotFound, got %v", err)
|
||||
}
|
||||
if err := uc.RevokeAPIKey(testCtx, 99, stored.ID); !errors.Is(err, user.ErrUserNotFound) {
|
||||
t.Errorf("expected ErrUserNotFound, got %v", err)
|
||||
}
|
||||
repo.fail.failNext("Revoke")
|
||||
if err := uc.RevokeAPIKey(testCtx, 2, stored.ID); !errors.Is(err, errRepositoryFailure) {
|
||||
if err := uc.RevokeAPIKey(testCtx, 2, stored.ID, apiKeyOwnScope); !errors.Is(err, errRepositoryFailure) {
|
||||
t.Errorf("expected the repository failure, got %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
Reference in new issue
Block a user