feat: activity log backend foundation
This commit is contained in:
1 parent
8907bb49fe
commit
50b1649965
74 files changed
+5949
-239
No files matched your search
+28
-28
@@ -221,9 +221,9 @@ func TestSHA256KeyGenerator(t *testing.T) {
|
||||
func TestCreateAPIKeyUseCase(t *testing.T) {
|
||||
t.Run("Use case: creating a key hashes it and stores no plaintext", func(t *testing.T) {
|
||||
repo := newMockAPIKeyRepo()
|
||||
uc := useCases.NewCreateAPIKeyUseCase(repo, &stubKeyGenerator{raw: "rcms_fake", prefix: "rcms_fake"}, apiKeyUnitClock)
|
||||
uc := useCases.NewCreateAPIKeyUseCase(repo, &stubKeyGenerator{raw: "rcms_fake", prefix: "rcms_fake"}, apiKeyUnitClock, discardRecorder)
|
||||
|
||||
created, err := uc.CreateAPIKey(useCases.CreateAPIKeyCommand{UserID: 2, Name: "ci"})
|
||||
created, err := uc.CreateAPIKey(testCtx, useCases.CreateAPIKeyCommand{UserID: 2, Name: "ci"})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
@@ -248,9 +248,9 @@ func TestCreateAPIKeyUseCase(t *testing.T) {
|
||||
t.Run("An expiry that is not in the future is refused and nothing is stored", func(t *testing.T) {
|
||||
for name, expiry := range map[string]time.Time{"in the past": apiKeyUnitNow.Add(-time.Hour), "exactly now": apiKeyUnitNow} {
|
||||
repo := newMockAPIKeyRepo()
|
||||
uc := useCases.NewCreateAPIKeyUseCase(repo, &stubKeyGenerator{raw: "rcms_fake", prefix: "rcms_fake"}, apiKeyUnitClock)
|
||||
uc := useCases.NewCreateAPIKeyUseCase(repo, &stubKeyGenerator{raw: "rcms_fake", prefix: "rcms_fake"}, apiKeyUnitClock, discardRecorder)
|
||||
|
||||
_, err := uc.CreateAPIKey(useCases.CreateAPIKeyCommand{UserID: 2, Name: "ci", ExpiresAt: &expiry})
|
||||
_, err := uc.CreateAPIKey(testCtx, useCases.CreateAPIKeyCommand{UserID: 2, Name: "ci", ExpiresAt: &expiry})
|
||||
if !errors.Is(err, apikey.ErrExpiryNotInFuture) {
|
||||
t.Errorf("%s: expected ErrExpiryNotInFuture, got %v", name, err)
|
||||
}
|
||||
@@ -263,9 +263,9 @@ func TestCreateAPIKeyUseCase(t *testing.T) {
|
||||
t.Run("A repository failure is returned", func(t *testing.T) {
|
||||
repo := newMockAPIKeyRepo()
|
||||
repo.fail.failNext("Create")
|
||||
uc := useCases.NewCreateAPIKeyUseCase(repo, &stubKeyGenerator{raw: "rcms_fake", prefix: "rcms_fake"}, apiKeyUnitClock)
|
||||
uc := useCases.NewCreateAPIKeyUseCase(repo, &stubKeyGenerator{raw: "rcms_fake", prefix: "rcms_fake"}, apiKeyUnitClock, discardRecorder)
|
||||
|
||||
if _, err := uc.CreateAPIKey(useCases.CreateAPIKeyCommand{UserID: 2, Name: "ci"}); !errors.Is(err, errRepositoryFailure) {
|
||||
if _, err := uc.CreateAPIKey(testCtx, useCases.CreateAPIKeyCommand{UserID: 2, Name: "ci"}); !errors.Is(err, errRepositoryFailure) {
|
||||
t.Errorf("expected the repository failure, got %v", err)
|
||||
}
|
||||
})
|
||||
@@ -486,9 +486,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)
|
||||
uc := useCases.NewRevokeAPIKeyUseCase(repo, apiKeyUnitUsers(), apiKeyUnitClock, discardRecorder)
|
||||
|
||||
if err := uc.RevokeAPIKey(2, stored.ID); err != nil {
|
||||
if err := uc.RevokeAPIKey(testCtx, 2, stored.ID); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if got := repo.keys[stored.ID].RevokedAt; got == nil || !got.Equal(apiKeyUnitNow) {
|
||||
@@ -499,9 +499,9 @@ func TestRevokeAPIKeyUseCase(t *testing.T) {
|
||||
t.Run("Another admin 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)
|
||||
uc := useCases.NewRevokeAPIKeyUseCase(repo, apiKeyUnitUsers(), apiKeyUnitClock, discardRecorder)
|
||||
|
||||
if err := uc.RevokeAPIKey(3, stored.ID); !errors.Is(err, apikey.ErrAPIKeyNotFound) {
|
||||
if err := uc.RevokeAPIKey(testCtx, 3, stored.ID); !errors.Is(err, apikey.ErrAPIKeyNotFound) {
|
||||
t.Errorf("expected ErrAPIKeyNotFound, got %v", err)
|
||||
}
|
||||
if repo.keys[stored.ID].RevokedAt != nil || repo.revokeCalls != 0 {
|
||||
@@ -512,9 +512,9 @@ func TestRevokeAPIKeyUseCase(t *testing.T) {
|
||||
t.Run("The owner 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)
|
||||
uc := useCases.NewRevokeAPIKeyUseCase(repo, apiKeyUnitUsers(), apiKeyUnitClock, discardRecorder)
|
||||
|
||||
if err := uc.RevokeAPIKey(1, stored.ID); err != nil {
|
||||
if err := uc.RevokeAPIKey(testCtx, 1, stored.ID); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if repo.keys[stored.ID].RevokedAt == nil {
|
||||
@@ -526,9 +526,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)
|
||||
uc := useCases.NewRevokeAPIKeyUseCase(repo, apiKeyUnitUsers(), apiKeyUnitClock, discardRecorder)
|
||||
|
||||
if err := uc.RevokeAPIKey(2, stored.ID); err != nil {
|
||||
if err := uc.RevokeAPIKey(testCtx, 2, stored.ID); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if got := repo.keys[stored.ID].RevokedAt; got == nil || !got.Equal(original) {
|
||||
@@ -539,16 +539,16 @@ func TestRevokeAPIKeyUseCase(t *testing.T) {
|
||||
t.Run("An unknown key, an unknown requester and repository failures are returned", func(t *testing.T) {
|
||||
repo := newMockAPIKeyRepo()
|
||||
stored := seedStubKey(repo, "rcms_a", nil)
|
||||
uc := useCases.NewRevokeAPIKeyUseCase(repo, apiKeyUnitUsers(), apiKeyUnitClock)
|
||||
uc := useCases.NewRevokeAPIKeyUseCase(repo, apiKeyUnitUsers(), apiKeyUnitClock, discardRecorder)
|
||||
|
||||
if err := uc.RevokeAPIKey(2, 999); !errors.Is(err, apikey.ErrAPIKeyNotFound) {
|
||||
if err := uc.RevokeAPIKey(testCtx, 2, 999); !errors.Is(err, apikey.ErrAPIKeyNotFound) {
|
||||
t.Errorf("expected ErrAPIKeyNotFound, got %v", err)
|
||||
}
|
||||
if err := uc.RevokeAPIKey(99, stored.ID); !errors.Is(err, user.ErrUserNotFound) {
|
||||
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(2, stored.ID); !errors.Is(err, errRepositoryFailure) {
|
||||
if err := uc.RevokeAPIKey(testCtx, 2, stored.ID); !errors.Is(err, errRepositoryFailure) {
|
||||
t.Errorf("expected the repository failure, got %v", err)
|
||||
}
|
||||
})
|
||||
@@ -566,9 +566,9 @@ func TestResetPasswordRevokesAPIKeys(t *testing.T) {
|
||||
keys := newMockAPIKeyRepo()
|
||||
seedStubKey(keys, "rcms_a", func(k *apikey.APIKey) { k.UserID = 2 })
|
||||
other := seedStubKey(keys, "rcms_c", func(k *apikey.APIKey) { k.UserID = 3 })
|
||||
uc := useCases.NewResetPasswordUseCase(resetUser(apiKeyUnitNow.Add(time.Hour)), &stubHasher{}, keys, apiKeyUnitClock)
|
||||
uc := useCases.NewResetPasswordUseCase(resetUser(apiKeyUnitNow.Add(time.Hour)), &stubHasher{}, keys, apiKeyUnitClock, discardRecorder)
|
||||
|
||||
if err := uc.ResetPassword("dev@example.com", "reset-code-1", "newpassword1"); err != nil {
|
||||
if err := uc.ResetPassword(testCtx, "dev@example.com", "reset-code-1", "newpassword1"); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if len(keys.revokeAllCalls) != 1 || keys.revokeAllCalls[0].userId != 2 || !keys.revokeAllCalls[0].at.Equal(apiKeyUnitNow) {
|
||||
@@ -594,9 +594,9 @@ func TestResetPasswordRevokesAPIKeys(t *testing.T) {
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
keys := newMockAPIKeyRepo()
|
||||
uc := useCases.NewResetPasswordUseCase(resetUser(tc.expiration), &stubHasher{}, keys, apiKeyUnitClock)
|
||||
uc := useCases.NewResetPasswordUseCase(resetUser(tc.expiration), &stubHasher{}, keys, apiKeyUnitClock, discardRecorder)
|
||||
|
||||
if err := uc.ResetPassword(tc.email, tc.code, "newpassword1"); !errors.Is(err, tc.want) {
|
||||
if err := uc.ResetPassword(testCtx, tc.email, tc.code, "newpassword1"); !errors.Is(err, tc.want) {
|
||||
t.Errorf("expected %v, got %v", tc.want, err)
|
||||
}
|
||||
if len(keys.revokeAllCalls) != 0 {
|
||||
@@ -610,14 +610,14 @@ func TestResetPasswordRevokesAPIKeys(t *testing.T) {
|
||||
keys := newMockAPIKeyRepo()
|
||||
users := resetUser(apiKeyUnitNow.Add(time.Hour))
|
||||
users.fail.failNext("ResetPassword")
|
||||
uc := useCases.NewResetPasswordUseCase(users, &stubHasher{}, keys, apiKeyUnitClock)
|
||||
if err := uc.ResetPassword("dev@example.com", "reset-code-1", "newpassword1"); !errors.Is(err, errRepositoryFailure) {
|
||||
uc := useCases.NewResetPasswordUseCase(users, &stubHasher{}, keys, apiKeyUnitClock, discardRecorder)
|
||||
if err := uc.ResetPassword(testCtx, "dev@example.com", "reset-code-1", "newpassword1"); !errors.Is(err, errRepositoryFailure) {
|
||||
t.Errorf("expected the repository failure, got %v", err)
|
||||
}
|
||||
|
||||
hashErr := errors.New("hash failed")
|
||||
uc = useCases.NewResetPasswordUseCase(resetUser(apiKeyUnitNow.Add(time.Hour)), &stubHasher{hashErr: hashErr}, keys, apiKeyUnitClock)
|
||||
if err := uc.ResetPassword("dev@example.com", "reset-code-1", "newpassword1"); !errors.Is(err, hashErr) {
|
||||
uc = useCases.NewResetPasswordUseCase(resetUser(apiKeyUnitNow.Add(time.Hour)), &stubHasher{hashErr: hashErr}, keys, apiKeyUnitClock, discardRecorder)
|
||||
if err := uc.ResetPassword(testCtx, "dev@example.com", "reset-code-1", "newpassword1"); !errors.Is(err, hashErr) {
|
||||
t.Errorf("expected the hash error, got %v", err)
|
||||
}
|
||||
if len(keys.revokeAllCalls) != 0 {
|
||||
@@ -629,9 +629,9 @@ func TestResetPasswordRevokesAPIKeys(t *testing.T) {
|
||||
keys := newMockAPIKeyRepo()
|
||||
keys.fail.failNext("RevokeAllByUser")
|
||||
users := resetUser(apiKeyUnitNow.Add(time.Hour))
|
||||
uc := useCases.NewResetPasswordUseCase(users, &stubHasher{}, keys, apiKeyUnitClock)
|
||||
uc := useCases.NewResetPasswordUseCase(users, &stubHasher{}, keys, apiKeyUnitClock, discardRecorder)
|
||||
|
||||
err := uc.ResetPassword("dev@example.com", "reset-code-1", "newpassword1")
|
||||
err := uc.ResetPassword(testCtx, "dev@example.com", "reset-code-1", "newpassword1")
|
||||
if !errors.Is(err, errRepositoryFailure) {
|
||||
t.Errorf("expected the revoke failure, got %v", err)
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user