fix: log audit record failures instead of silently discarding

This commit is contained in:
2026-06-16 00:31:33 +02:00
committed by Milas Holsting
parent 5a0c8b7476
commit 57a2ff874a
2 changed files with 44 additions and 30 deletions

View File

@@ -10,6 +10,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"mal/internal/domain" "mal/internal/domain"
"mal/internal/observability"
"strings" "strings"
"time" "time"
@@ -74,22 +75,25 @@ func (s *authService) LoginForAPIToken(ctx context.Context, username, password,
return "", nil, err return "", nil, err
} }
metadataBytes, err := json.Marshal(struct { event := domain.AuditEvent{
UserID: user.ID,
Action: "api_token_created",
ResourceType: "api_token",
}
metadataBytes, marshalErr := json.Marshal(struct {
Name string `json:"name"` Name string `json:"name"`
}{Name: trimmedName}) }{Name: trimmedName})
if err == nil { if marshalErr == nil {
_ = s.auditSvc.Record(ctx, domain.AuditEvent{ event.MetadataJSON = metadataBytes
UserID: user.ID, }
Action: "api_token_created", if err := s.auditSvc.Record(ctx, event); err != nil {
ResourceType: "api_token", observability.Warn(
MetadataJSON: metadataBytes, "audit_record_failed",
}) "auth",
} else { "",
_ = s.auditSvc.Record(ctx, domain.AuditEvent{ map[string]any{"user_id": user.ID, "action": "api_token_created"},
UserID: user.ID, err,
Action: "api_token_created", )
ResourceType: "api_token",
})
} }
return rawToken, user, nil return rawToken, user, nil
@@ -152,11 +156,19 @@ func (s *authService) RevokeAllAPITokensForUser(ctx context.Context, userID stri
if err := s.repo.RevokeAllAPITokensForUser(ctx, userID); err != nil { if err := s.repo.RevokeAllAPITokensForUser(ctx, userID); err != nil {
return err return err
} }
_ = s.auditSvc.Record(ctx, domain.AuditEvent{ if err := s.auditSvc.Record(ctx, domain.AuditEvent{
UserID: userID, UserID: userID,
Action: "api_token_revoked_all", Action: "api_token_revoked_all",
ResourceType: "api_token", ResourceType: "api_token",
}) }); err != nil {
observability.Warn(
"audit_record_failed",
"auth",
"",
map[string]any{"user_id": userID, "action": "api_token_revoked_all"},
err,
)
}
return nil return nil
} }

View File

@@ -130,25 +130,27 @@ func (s *playbackService) SaveProgress(ctx context.Context, userID string, anime
return err return err
} }
event := domain.AuditEvent{
UserID: userID,
Action: "watch_progress_saved",
ResourceType: "anime",
ResourceID: strconv.FormatInt(animeID, 10),
}
metadataBytes, marshalErr := json.Marshal(struct { metadataBytes, marshalErr := json.Marshal(struct {
Episode int `json:"episode"` Episode int `json:"episode"`
TimeSeconds float64 `json:"time_seconds"` TimeSeconds float64 `json:"time_seconds"`
}{Episode: episode, TimeSeconds: timeSeconds}) }{Episode: episode, TimeSeconds: timeSeconds})
if marshalErr == nil { if marshalErr == nil {
_ = s.auditSvc.Record(ctx, domain.AuditEvent{ event.MetadataJSON = metadataBytes
UserID: userID, }
Action: "watch_progress_saved", if err := s.auditSvc.Record(ctx, event); err != nil {
ResourceType: "anime", observability.Warn(
ResourceID: strconv.FormatInt(animeID, 10), "audit_record_failed",
MetadataJSON: metadataBytes, "playback",
}) "",
} else { map[string]any{"user_id": userID, "anime_id": animeID, "action": "watch_progress_saved"},
_ = s.auditSvc.Record(ctx, domain.AuditEvent{ err,
UserID: userID, )
Action: "watch_progress_saved",
ResourceType: "anime",
ResourceID: strconv.FormatInt(animeID, 10),
})
} }
observability.Info("watch_progress_saved", "playback", "", map[string]any{ observability.Info("watch_progress_saved", "playback", "", map[string]any{
"anime_id": animeID, "anime_id": animeID,