| | | 1 | | using ArturRios.Heimdall.Command.Input; |
| | | 2 | | using ArturRios.Heimdall.Command.Output; |
| | | 3 | | using ArturRios.Heimdall.Shared.Retention; |
| | | 4 | | using ArturRios.Mediator.Command; |
| | | 5 | | |
| | | 6 | | namespace ArturRios.Heimdall.WebApi.Retention; |
| | | 7 | | |
| | | 8 | | /// <summary> |
| | | 9 | | /// Runs <see cref="PseudonymiseAuditActorsCommand" /> on an interval, so the audit trail stops |
| | | 10 | | /// naming people, as actors or as targets, once it no longer needs to, and drops the tombstones of |
| | | 11 | | /// hard-deleted identities once nothing names them (NFR-21). |
| | | 12 | | /// </summary> |
| | | 13 | | public class AuditRetentionService( |
| | | 14 | | IServiceScopeFactory scopeFactory, |
| | | 15 | | DataRetentionOptions retention, |
| | | 16 | | ILogger<AuditRetentionService> logger) |
| | 899 | 17 | | : ScheduledPassService(scopeFactory, retention.PurgeInterval, logger) |
| | | 18 | | { |
| | | 19 | | protected override string StartupDescription => |
| | 899 | 20 | | $"Audit attribution pseudonymisation scheduled every {retention.PurgeInterval}, clearing " + |
| | 899 | 21 | | $"attributions and person targets after {retention.AuditActorRetention} and immediately " + |
| | 899 | 22 | | "for erased identities"; |
| | | 23 | | |
| | | 24 | | protected override async Task<string?> RunAsync(IServiceProvider scope) |
| | | 25 | | { |
| | 0 | 26 | | var mediator = scope.GetRequiredService<CommandMediator>(); |
| | | 27 | | |
| | 0 | 28 | | var result = await mediator |
| | 0 | 29 | | .ExecuteCommandAsync<PseudonymiseAuditActorsCommand, PseudonymiseAuditActorsCommandOutput>( |
| | 0 | 30 | | new PseudonymiseAuditActorsCommand()); |
| | | 31 | | |
| | 0 | 32 | | if (!result.Success) |
| | | 33 | | { |
| | 0 | 34 | | return $"Audit attribution pseudonymisation failed: {string.Join("; ", result.Errors)}"; |
| | | 35 | | } |
| | | 36 | | |
| | 0 | 37 | | var pseudonymised = result.Data!; |
| | | 38 | | |
| | 0 | 39 | | return pseudonymised.EntriesPseudonymised == 0 && pseudonymised.TargetsCleared == 0 |
| | 0 | 40 | | && pseudonymised.TombstonesRemoved == 0 |
| | 0 | 41 | | ? null |
| | 0 | 42 | | : $"Cleared the actor attribution from {pseudonymised.EntriesPseudonymised} audit entries " + |
| | 0 | 43 | | $"and the person target from {pseudonymised.TargetsCleared}, and removed " + |
| | 0 | 44 | | $"{pseudonymised.TombstonesRemoved} tombstones of hard-deleted identities"; |
| | 0 | 45 | | } |
| | | 46 | | } |