feat: activity log backend foundation

This commit is contained in:
fsylvain committed 2026-10-06 20:35:03 +02:00
1 parent 8907bb49fe
commit 50b1649965
74 files changed
+5949 -239

No files matched your search

@@ -1,20 +1,37 @@
package useCases
import (
"RenewCMS/internal/domain/audit"
"RenewCMS/internal/domain/hash"
"RenewCMS/internal/domain/user"
"context"
"errors"
)
type AuthenticateUserUseCase struct {
userRepository user.Repository
hasher hash.Hasher
recorder audit.Recorder
}
func NewAuthenticateUserUseCase(userRepository user.Repository, hasher hash.Hasher) *AuthenticateUserUseCase {
return &AuthenticateUserUseCase{userRepository, hasher}
func NewAuthenticateUserUseCase(userRepository user.Repository, hasher hash.Hasher, recorder audit.Recorder) *AuthenticateUserUseCase {
return &AuthenticateUserUseCase{userRepository, hasher, recorder}
}
func (a *AuthenticateUserUseCase) Authenticate(username string, password string) (user.User, error) {
func (a *AuthenticateUserUseCase) Authenticate(ctx context.Context, username string, password string) (user.User, error) {
dbUser, err := a.verifyCredentials(username, password)
if err != nil {
a.recordRejectedLogin(ctx, username, err)
return user.User{}, err
}
event := audit.NewEvent(audit.ActionLogin, audit.CategoryAuth)
event.Actor = audit.UserActor(dbUser)
a.recorder.Record(ctx, event)
return dbUser, nil
}
func (a *AuthenticateUserUseCase) verifyCredentials(username string, password string) (user.User, error) {
dbUser, err := a.userRepository.GetByUsername(username)
if err != nil {
return user.User{}, err
@@ -26,3 +43,24 @@ func (a *AuthenticateUserUseCase) Authenticate(username string, password string)
return dbUser, nil
}
func (a *AuthenticateUserUseCase) recordRejectedLogin(ctx context.Context, username string, cause error) {
if !errors.Is(cause, user.ErrUserNotFound) && !errors.Is(cause, user.ErrInvalidCredentials) {
return
}
reason := audit.ReasonWrongLogin
event := audit.NewEvent(audit.ActionLoginFailed, audit.CategoryAuth)
event.Actor = audit.AnonymousActor(username)
event.Outcome = audit.OutcomeFailed
event.FailureReason = &reason
event.Security = true
a.recorder.Record(ctx, event)
}
func (a *AuthenticateUserUseCase) Logout(ctx context.Context) {
origin, ok := audit.OriginFrom(ctx)
if !ok || origin.Actor.Type != audit.ActorUser {
return
}
a.recorder.Record(ctx, audit.NewEvent(audit.ActionLogout, audit.CategoryAuth))
}