From 05ee700cca0bce5ea4ae25e251a510779ec97744 Mon Sep 17 00:00:00 2001 From: Timo Notheisen <65653426+tnotheis@users.noreply.github.com> Date: Wed, 4 Dec 2024 14:40:56 +0100 Subject: [PATCH] Possibility for the user to override the length of the grace period when starting an identity deletion process (#961) --- .../StartDeletionProcessAsOwner/Handler.cs | 2 +- .../StartDeletionProcessAsOwnerCommand.cs | 5 ++++- .../Controllers/IdentitiesController.cs | 5 +++-- .../Entities/Identities/Identity.cs | 4 ++-- .../Identities/IdentityDeletionProcess.cs | 13 +++++++------ .../StartDeletionProcessAsOwnerTests.cs | 16 ++++++++++++++++ 6 files changed, 33 insertions(+), 12 deletions(-) diff --git a/Modules/Devices/src/Devices.Application/Identities/Commands/StartDeletionProcessAsOwner/Handler.cs b/Modules/Devices/src/Devices.Application/Identities/Commands/StartDeletionProcessAsOwner/Handler.cs index 732503b184..abb7d6ebbf 100644 --- a/Modules/Devices/src/Devices.Application/Identities/Commands/StartDeletionProcessAsOwner/Handler.cs +++ b/Modules/Devices/src/Devices.Application/Identities/Commands/StartDeletionProcessAsOwner/Handler.cs @@ -27,7 +27,7 @@ public async Task Handle(StartDeletionProce { var identity = await _identitiesRepository.FindByAddress(_userContext.GetAddress(), cancellationToken, true) ?? throw new NotFoundException(nameof(Identity)); - var deletionProcess = identity.StartDeletionProcessAsOwner(_userContext.GetDeviceId()); + var deletionProcess = identity.StartDeletionProcessAsOwner(_userContext.GetDeviceId(), request.LengthOfGracePeriodInDays); try { diff --git a/Modules/Devices/src/Devices.Application/Identities/Commands/StartDeletionProcessAsOwner/StartDeletionProcessAsOwnerCommand.cs b/Modules/Devices/src/Devices.Application/Identities/Commands/StartDeletionProcessAsOwner/StartDeletionProcessAsOwnerCommand.cs index ed65e0a036..5f0085cde4 100644 --- a/Modules/Devices/src/Devices.Application/Identities/Commands/StartDeletionProcessAsOwner/StartDeletionProcessAsOwnerCommand.cs +++ b/Modules/Devices/src/Devices.Application/Identities/Commands/StartDeletionProcessAsOwner/StartDeletionProcessAsOwnerCommand.cs @@ -2,4 +2,7 @@ namespace Backbone.Modules.Devices.Application.Identities.Commands.StartDeletionProcessAsOwner; -public class StartDeletionProcessAsOwnerCommand : IRequest; +public class StartDeletionProcessAsOwnerCommand : IRequest +{ + public double? LengthOfGracePeriodInDays { get; set; } +} diff --git a/Modules/Devices/src/Devices.ConsumerApi/Controllers/IdentitiesController.cs b/Modules/Devices/src/Devices.ConsumerApi/Controllers/IdentitiesController.cs index d13bb3e942..36ebd9856e 100644 --- a/Modules/Devices/src/Devices.ConsumerApi/Controllers/IdentitiesController.cs +++ b/Modules/Devices/src/Devices.ConsumerApi/Controllers/IdentitiesController.cs @@ -70,9 +70,10 @@ public async Task CreateIdentity(CreateIdentityRequest request, C [HttpPost("Self/DeletionProcesses")] [ProducesResponseType(typeof(HttpResponseEnvelopeResult), StatusCodes.Status201Created)] [ProducesError(StatusCodes.Status400BadRequest)] - public async Task StartDeletionProcess(CancellationToken cancellationToken) + public async Task StartDeletionProcess(StartDeletionProcessAsOwnerCommand? request, CancellationToken cancellationToken) { - var response = await _mediator.Send(new StartDeletionProcessAsOwnerCommand(), cancellationToken); + request ??= new StartDeletionProcessAsOwnerCommand(); + var response = await _mediator.Send(request, cancellationToken); return Created("", response); } diff --git a/Modules/Devices/src/Devices.Domain/Entities/Identities/Identity.cs b/Modules/Devices/src/Devices.Domain/Entities/Identities/Identity.cs index 2bb93eef17..ab8a1387be 100644 --- a/Modules/Devices/src/Devices.Domain/Entities/Identities/Identity.cs +++ b/Modules/Devices/src/Devices.Domain/Entities/Identities/Identity.cs @@ -130,14 +130,14 @@ public IdentityDeletionProcess StartDeletionProcessAsSupport() return deletionProcess; } - public IdentityDeletionProcess StartDeletionProcessAsOwner(DeviceId asDevice) + public IdentityDeletionProcess StartDeletionProcessAsOwner(DeviceId asDevice, double? lengthOfGracePeriodInDays = null) { EnsureNoActiveProcessExists(); EnsureIdentityOwnsDevice(asDevice); TierIdBeforeDeletion = TierId; - var deletionProcess = IdentityDeletionProcess.StartAsOwner(Address, asDevice); + var deletionProcess = IdentityDeletionProcess.StartAsOwner(Address, asDevice, lengthOfGracePeriodInDays); _deletionProcesses.Add(deletionProcess); DeletionGracePeriodEndsAt = deletionProcess.GracePeriodEndsAt; diff --git a/Modules/Devices/src/Devices.Domain/Entities/Identities/IdentityDeletionProcess.cs b/Modules/Devices/src/Devices.Domain/Entities/Identities/IdentityDeletionProcess.cs index 9ae73b819f..94a5fa7dfe 100644 --- a/Modules/Devices/src/Devices.Domain/Entities/Identities/IdentityDeletionProcess.cs +++ b/Modules/Devices/src/Devices.Domain/Entities/Identities/IdentityDeletionProcess.cs @@ -31,13 +31,13 @@ private IdentityDeletionProcess(IdentityAddress createdBy, DeletionProcessStatus RaiseDomainEvent(new IdentityDeletionProcessStartedDomainEvent(createdBy, Id, null)); } - private IdentityDeletionProcess(IdentityAddress createdBy, DeviceId createdByDevice) + private IdentityDeletionProcess(IdentityAddress createdBy, DeviceId createdByDevice, double? lengthOfGracePeriodInDays) { Id = IdentityDeletionProcessId.Generate(); IdentityAddress = null!; CreatedAt = SystemTime.UtcNow; - ApproveInternally(createdBy, createdByDevice); + ApproveInternally(createdBy, createdByDevice, lengthOfGracePeriodInDays); _auditLog = [IdentityDeletionProcessAuditLogEntry.ProcessStartedByOwner(Id, createdBy, createdByDevice)]; } @@ -81,9 +81,9 @@ public static IdentityDeletionProcess StartAsSupport(IdentityAddress createdBy) return new IdentityDeletionProcess(createdBy, DeletionProcessStatus.WaitingForApproval); } - public static IdentityDeletionProcess StartAsOwner(IdentityAddress createdBy, DeviceId createdByDeviceId) + public static IdentityDeletionProcess StartAsOwner(IdentityAddress createdBy, DeviceId createdByDeviceId, double? lengthOfGracePeriodInDays) { - return new IdentityDeletionProcess(createdBy, createdByDeviceId); + return new IdentityDeletionProcess(createdBy, createdByDeviceId, lengthOfGracePeriodInDays); } public bool IsActive() @@ -150,11 +150,12 @@ public void Approve(IdentityAddress address, DeviceId approvedByDevice) _auditLog.Add(IdentityDeletionProcessAuditLogEntry.ProcessApproved(Id, address, approvedByDevice)); } - private void ApproveInternally(IdentityAddress address, DeviceId createdByDevice) + private void ApproveInternally(IdentityAddress address, DeviceId createdByDevice, double? lengthOfGracePeriodInDays = null) { + lengthOfGracePeriodInDays ??= IdentityDeletionConfiguration.Instance.LengthOfGracePeriodInDays; ApprovedAt = SystemTime.UtcNow; ApprovedByDevice = createdByDevice; - GracePeriodEndsAt = SystemTime.UtcNow.AddDays(IdentityDeletionConfiguration.Instance.LengthOfGracePeriodInDays); + GracePeriodEndsAt = SystemTime.UtcNow.AddDays(lengthOfGracePeriodInDays.Value); ChangeStatus(DeletionProcessStatus.Approved, address, address); } diff --git a/Modules/Devices/test/Devices.Domain.Tests/Identities/StartDeletionProcessAsOwnerTests.cs b/Modules/Devices/test/Devices.Domain.Tests/Identities/StartDeletionProcessAsOwnerTests.cs index 2a1a8c6c2c..8c350ea874 100644 --- a/Modules/Devices/test/Devices.Domain.Tests/Identities/StartDeletionProcessAsOwnerTests.cs +++ b/Modules/Devices/test/Devices.Domain.Tests/Identities/StartDeletionProcessAsOwnerTests.cs @@ -99,6 +99,22 @@ public void Raises_domain_events() identityToBeDeletedDomainEvent.IdentityAddress.Should().Be(activeIdentity.Address); } + [Fact] + public void Passing_a_lengthOfDeletionGracePeriod_overrides_the_configured_value() + { + //Arrange + var activeIdentity = TestDataGenerator.CreateIdentity(); + var activeDevice = activeIdentity.Devices[0]; + SystemTime.Set("2000-01-01"); + + //Act + activeIdentity.StartDeletionProcessAsOwner(activeDevice.Id, 1); + + // Assert + activeIdentity.DeletionGracePeriodEndsAt.Should().Be(DateTime.Parse("2000-01-02")); + activeIdentity.DeletionProcesses.First().GracePeriodEndsAt.Should().Be(DateTime.Parse("2000-01-02")); + } + private static void AssertDeletionProcessWasStarted(Identity activeIdentity) { activeIdentity.DeletionProcesses.Should().HaveCount(1);