From 32c9d11727819c6888b83f789510f2291b4839ac Mon Sep 17 00:00:00 2001 From: Hunor Tot-Bagi Date: Tue, 5 Mar 2024 13:44:25 +0100 Subject: [PATCH 1/4] Consumer API: Cancel identity deletion process (#534) * wip * fear: CancelDeletionProcessDuringGracePeriod * feature: add new domain error * feat: add method to check if device that starts deletion process actually belongs to identity * refactor: adapt tests to newly implement feature (check if device belongs to identity) * test: add new test start deletion process as owner from another device * feat: wip handler * test: add handler tests for cancellation of a deletion process during grace period handler * feat: add handler for cancellation of a deletion process during grace period * chore: fix formatting issues * fear: add migration for CancelledAt & CancelledByDevice * chore: fix formatting issues * chore: move command creation into arrange section * chore: rename property * chore: remove unused directives * refactor: get device id from _userContext * chore: rename files, folders, methods & classes so they do not contain "DuringGracePeriod" * feat: add properties to CancelDeletionProcessResponse * refactor: fix test * refactor: fix test * chore: no action could lead to 400BadRequest * chore: fix formatting issues * refactor: change logic * chore: rename id to deletionProcessId * chore: remove redundant using * fix: handler didn't have IRequestHandler<> and now properly returns response * fix: CancelDeletionProcess return IdentityDeletionProcess * chore: typo * refactor: change to hardcoded datetime * chore: change to hardcoded datetime * refactor: change domain error * fix: set TieridBeforeDeletion to null * chore: rename tests * refactor: get deletionProcess from StartDeletionProcessAsOwner * refactor: fix tests * refactor: change logic * refactor: fix handler * refactor: add assertion on database * refactor: modify test * fix: add check for ensure identity owns device * refactor: rename & create optimized CreateHandler method * refactor: change status check * chore: remove unused error * chore: fix nullable issue * refactor: fix naming & optinal parameter * chore: rename * refactor: fix wrong method usage * refactor: remove private Cancel method * feat: add new error chore: remove unused error * refactor: change error message * refactor: rely on the deletionProcess.Cancel method * test: add new test when deletion process is in wrong status * refactor: extract method & add more assertions * test: add auditLog assertions * refactor: set optional parameter * fix: remove unused assertion * chore: remove unused using * refactor: assert DeletionProcessStatus * refactor: add assertion * chore: fix formatting issues * chore: remove unused domain error * refactor * refactor: add missing assertions * refactor: move CreateIdentity methods into TestDataGenerator * chore: remove unused using * refactor: acting only once --------- Co-authored-by: Timo Notheisen <65653426+tnotheis@users.noreply.github.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> Co-authored-by: Timo Notheisen --- .../CancelDeletionProcessCommand.cs | 13 + .../CancelDeletionProcessResponse.cs | 19 + .../Commands/CancelDeletionProcess/Handler.cs | 38 + .../Controllers/IdentitiesController.cs | 10 + .../Entities/Identities/Identity.cs | 25 +- .../Identities/IdentityDeletionProcess.cs | 15 + .../IdentityDeletionProcessAuditLogEntry.cs | 5 + ...questedByCancelDeletionProcess.Designer.cs | 873 +++++++++ ...cationsRequestedByCancelDeletionProcess.cs | 42 + .../DevicesDbContextModelSnapshot.cs | 1731 ++++++++-------- ...questedByCancelDeletionProcess.Designer.cs | 878 +++++++++ ...cationsRequestedByCancelDeletionProcess.cs | 42 + .../ApplicationDbContextModelSnapshot.cs | 1741 +++++++++-------- .../TestDataGenerator.cs | 8 +- .../CancelDeletionProcess/HandlerTests.cs | 70 + .../Identities/ApproveDeletionProcessTests.cs | 4 +- .../Identities/CancelDeletionProcessTests.cs | 69 + .../DeletionGracePeriodReminderTests.cs | 7 +- .../StartDeletionProcessAsOwnerTests.cs | 33 +- .../Devices.Domain.Tests/TestDataGenerator.cs | 19 + 20 files changed, 3900 insertions(+), 1742 deletions(-) create mode 100644 Modules/Devices/src/Devices.Application/Identities/Commands/CancelDeletionProcess/CancelDeletionProcessCommand.cs create mode 100644 Modules/Devices/src/Devices.Application/Identities/Commands/CancelDeletionProcess/CancelDeletionProcessResponse.cs create mode 100644 Modules/Devices/src/Devices.Application/Identities/Commands/CancelDeletionProcess/Handler.cs create mode 100644 Modules/Devices/src/Devices.Infrastructure.Database.Postgres/Migrations/20240222122512_AddModificationsRequestedByCancelDeletionProcess.Designer.cs create mode 100644 Modules/Devices/src/Devices.Infrastructure.Database.Postgres/Migrations/20240222122512_AddModificationsRequestedByCancelDeletionProcess.cs create mode 100644 Modules/Devices/src/Devices.Infrastructure.Database.SqlServer/Migrations/20240222122457_AddModificationsRequestedByCancelDeletionProcess.Designer.cs create mode 100644 Modules/Devices/src/Devices.Infrastructure.Database.SqlServer/Migrations/20240222122457_AddModificationsRequestedByCancelDeletionProcess.cs create mode 100644 Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/CancelDeletionProcess/HandlerTests.cs create mode 100644 Modules/Devices/test/Devices.Domain.Tests/Identities/CancelDeletionProcessTests.cs diff --git a/Modules/Devices/src/Devices.Application/Identities/Commands/CancelDeletionProcess/CancelDeletionProcessCommand.cs b/Modules/Devices/src/Devices.Application/Identities/Commands/CancelDeletionProcess/CancelDeletionProcessCommand.cs new file mode 100644 index 0000000000..de59b86966 --- /dev/null +++ b/Modules/Devices/src/Devices.Application/Identities/Commands/CancelDeletionProcess/CancelDeletionProcessCommand.cs @@ -0,0 +1,13 @@ +using MediatR; + +namespace Backbone.Modules.Devices.Application.Identities.Commands.CancelDeletionProcess; + +public class CancelDeletionProcessCommand : IRequest +{ + public CancelDeletionProcessCommand(string deletionProcessId) + { + DeletionProcessId = deletionProcessId; + } + + public string DeletionProcessId { get; set; } +} diff --git a/Modules/Devices/src/Devices.Application/Identities/Commands/CancelDeletionProcess/CancelDeletionProcessResponse.cs b/Modules/Devices/src/Devices.Application/Identities/Commands/CancelDeletionProcess/CancelDeletionProcessResponse.cs new file mode 100644 index 0000000000..b18ba08548 --- /dev/null +++ b/Modules/Devices/src/Devices.Application/Identities/Commands/CancelDeletionProcess/CancelDeletionProcessResponse.cs @@ -0,0 +1,19 @@ +using Backbone.DevelopmentKit.Identity.ValueObjects; +using Backbone.Modules.Devices.Domain.Entities.Identities; + +namespace Backbone.Modules.Devices.Application.Identities.Commands.CancelDeletionProcess; +public class CancelDeletionProcessResponse +{ + public CancelDeletionProcessResponse(IdentityDeletionProcess deletionProcess) + { + Id = deletionProcess.Id; + Status = deletionProcess.Status; + CancelledAt = deletionProcess.CancelledAt ?? throw new Exception($"The '{nameof(IdentityDeletionProcess.CancelledAt)}' property of the given deletion process must not be null."); + CancelledByDevice = deletionProcess.CancelledByDevice ?? throw new Exception($"The '{nameof(IdentityDeletionProcess.CancelledByDevice)}' property of the given deletion process must not be null."); + } + + public string Id { get; } + public DeletionProcessStatus Status { get; } + public DateTime CancelledAt { get; } + public string CancelledByDevice { get; } +} diff --git a/Modules/Devices/src/Devices.Application/Identities/Commands/CancelDeletionProcess/Handler.cs b/Modules/Devices/src/Devices.Application/Identities/Commands/CancelDeletionProcess/Handler.cs new file mode 100644 index 0000000000..271dd23c1a --- /dev/null +++ b/Modules/Devices/src/Devices.Application/Identities/Commands/CancelDeletionProcess/Handler.cs @@ -0,0 +1,38 @@ +using Backbone.BuildingBlocks.Application.Abstractions.Exceptions; +using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.UserContext; +using Backbone.BuildingBlocks.Domain; +using Backbone.Modules.Devices.Application.Infrastructure.Persistence.Repository; +using Backbone.Modules.Devices.Domain.Entities.Identities; +using MediatR; + +namespace Backbone.Modules.Devices.Application.Identities.Commands.CancelDeletionProcess; +public class Handler : IRequestHandler +{ + private readonly IIdentitiesRepository _identitiesRepository; + private readonly IUserContext _userContext; + + public Handler(IIdentitiesRepository identitiesRepository, IUserContext userContext) + { + _identitiesRepository = identitiesRepository; + _userContext = userContext; + } + + public async Task Handle(CancelDeletionProcessCommand request, CancellationToken cancellationToken) + { + var identity = await _identitiesRepository.FindByAddress(_userContext.GetAddress(), cancellationToken, true) ?? throw new NotFoundException(nameof(Identity)); + + var deviceId = _userContext.GetDeviceId(); + var deletionProcessIdResult = IdentityDeletionProcessId.Create(request.DeletionProcessId); + + if (deletionProcessIdResult.IsFailure) + throw new DomainException(deletionProcessIdResult.Error); + + var deletionProcessId = deletionProcessIdResult.Value; + + var deletionProcess = identity.CancelDeletionProcess(deletionProcessId, deviceId); + + await _identitiesRepository.Update(identity, cancellationToken); + + return new CancelDeletionProcessResponse(deletionProcess); + } +} diff --git a/Modules/Devices/src/Devices.ConsumerApi/Controllers/IdentitiesController.cs b/Modules/Devices/src/Devices.ConsumerApi/Controllers/IdentitiesController.cs index 0fee5fdb82..d7a4d4637a 100644 --- a/Modules/Devices/src/Devices.ConsumerApi/Controllers/IdentitiesController.cs +++ b/Modules/Devices/src/Devices.ConsumerApi/Controllers/IdentitiesController.cs @@ -4,6 +4,7 @@ using Backbone.BuildingBlocks.Application.Abstractions.Exceptions; using Backbone.Modules.Devices.Application.Devices.DTOs; using Backbone.Modules.Devices.Application.Identities.Commands.ApproveDeletionProcess; +using Backbone.Modules.Devices.Application.Identities.Commands.CancelDeletionProcess; using Backbone.Modules.Devices.Application.Identities.Commands.CreateIdentity; using Backbone.Modules.Devices.Application.Identities.Commands.StartDeletionProcessAsOwner; using Backbone.Modules.Devices.Application.Identities.Queries.GetDeletionProcess; @@ -95,6 +96,15 @@ public async Task GetDeletionProcesses(CancellationToken cancella var response = await _mediator.Send(new GetDeletionProcessesQuery(), cancellationToken); return Ok(response); } + + [HttpPut("Self/DeletionProcesses/{id}/Cancel")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesError(StatusCodes.Status404NotFound)] + public async Task CancelDeletionProcess([FromRoute] string id, CancellationToken cancellationToken) + { + var response = await _mediator.Send(new CancelDeletionProcessCommand(id), cancellationToken); + return Ok(response); + } } public class CreateIdentityRequest diff --git a/Modules/Devices/src/Devices.Domain/Entities/Identities/Identity.cs b/Modules/Devices/src/Devices.Domain/Entities/Identities/Identity.cs index 7b5301aa12..c561d2ff67 100644 --- a/Modules/Devices/src/Devices.Domain/Entities/Identities/Identity.cs +++ b/Modules/Devices/src/Devices.Domain/Entities/Identities/Identity.cs @@ -71,6 +71,7 @@ public IdentityDeletionProcess StartDeletionProcessAsSupport() public IdentityDeletionProcess StartDeletionProcessAsOwner(DeviceId asDevice) { EnsureNoActiveProcessExists(); + EnsureIdentityOwnsDevice(asDevice); TierIdBeforeDeletion = TierId; @@ -84,6 +85,12 @@ public IdentityDeletionProcess StartDeletionProcessAsOwner(DeviceId asDevice) return deletionProcess; } + private void EnsureIdentityOwnsDevice(DeviceId currentDeviceId) + { + if (!Devices.Exists(device => device.Id == currentDeviceId)) + throw new DomainException(GenericDomainErrors.NotFound(nameof(Device))); + } + public void DeletionProcessApprovalReminder1Sent() { EnsureDeletionProcessInStatusExists(DeletionProcessStatus.WaitingForApproval); @@ -165,12 +172,28 @@ public void DeletionGracePeriodReminder3Sent() { return DeletionProcesses.FirstOrDefault(x => x.Status == deletionProcessStatus); } + + public IdentityDeletionProcess CancelDeletionProcess(IdentityDeletionProcessId deletionProcessId, DeviceId canceledByDeviceId) + { + EnsureIdentityOwnsDevice(canceledByDeviceId); + + var deletionProcess = DeletionProcesses.FirstOrDefault(x => x.Id == deletionProcessId) ?? + throw new DomainException(GenericDomainErrors.NotFound(nameof(IdentityDeletionProcess))); + + deletionProcess.Cancel(Address, canceledByDeviceId); + TierId = TierIdBeforeDeletion; + TierIdBeforeDeletion = null; + Status = IdentityStatus.Active; + + return deletionProcess; + } } public enum DeletionProcessStatus { WaitingForApproval = 0, - Approved = 1 + Approved = 1, + Cancelled = 2 } public enum IdentityStatus diff --git a/Modules/Devices/src/Devices.Domain/Entities/Identities/IdentityDeletionProcess.cs b/Modules/Devices/src/Devices.Domain/Entities/Identities/IdentityDeletionProcess.cs index 76b415a66c..3fb48c610d 100644 --- a/Modules/Devices/src/Devices.Domain/Entities/Identities/IdentityDeletionProcess.cs +++ b/Modules/Devices/src/Devices.Domain/Entities/Identities/IdentityDeletionProcess.cs @@ -65,6 +65,9 @@ private void Approve(DeviceId createdByDevice) public DateTime? ApprovedAt { get; private set; } public DeviceId? ApprovedByDevice { get; private set; } + public DateTime? CancelledAt { get; private set; } + public DeviceId? CancelledByDevice { get; private set; } + public DateTime? GracePeriodEndsAt { get; private set; } public DateTime? GracePeriodReminder1SentAt { get; private set; } @@ -126,4 +129,16 @@ public void Approve(IdentityAddress address, DeviceId approvedByDevice) Approve(approvedByDevice); _auditLog.Add(IdentityDeletionProcessAuditLogEntry.ProcessApproved(Id, address, approvedByDevice)); } + + public void Cancel(IdentityAddress address, DeviceId cancelledByDevice) + { + if (Status != DeletionProcessStatus.Approved) + throw new DomainException(DomainErrors.NoDeletionProcessWithRequiredStatusExists()); + + Status = DeletionProcessStatus.Cancelled; + CancelledAt = SystemTime.UtcNow; + CancelledByDevice = cancelledByDevice; + + _auditLog.Add(IdentityDeletionProcessAuditLogEntry.ProcessCancelled(Id, address, cancelledByDevice)); + } } diff --git a/Modules/Devices/src/Devices.Domain/Entities/Identities/IdentityDeletionProcessAuditLogEntry.cs b/Modules/Devices/src/Devices.Domain/Entities/Identities/IdentityDeletionProcessAuditLogEntry.cs index 64f30d56f5..b7d11a908a 100644 --- a/Modules/Devices/src/Devices.Domain/Entities/Identities/IdentityDeletionProcessAuditLogEntry.cs +++ b/Modules/Devices/src/Devices.Domain/Entities/Identities/IdentityDeletionProcessAuditLogEntry.cs @@ -20,6 +20,11 @@ public static IdentityDeletionProcessAuditLogEntry ProcessApproved(IdentityDelet return new IdentityDeletionProcessAuditLogEntry(processId, "The deletion process was approved.", Hasher.HashUtf8(identityAddress.StringValue), Hasher.HashUtf8(deviceId.StringValue), DeletionProcessStatus.WaitingForApproval, DeletionProcessStatus.Approved); } + public static IdentityDeletionProcessAuditLogEntry ProcessCancelled(IdentityDeletionProcessId processId, IdentityAddress identityAddress, DeviceId deviceId) + { + return new IdentityDeletionProcessAuditLogEntry(processId, "The deletion process was cancelled.", Hasher.HashUtf8(identityAddress.StringValue), Hasher.HashUtf8(deviceId.StringValue), DeletionProcessStatus.Approved, DeletionProcessStatus.Cancelled); + } + public static IdentityDeletionProcessAuditLogEntry ApprovalReminder1Sent(IdentityDeletionProcessId processId, IdentityAddress identityAddress) { return new IdentityDeletionProcessAuditLogEntry(processId, "The first approval reminder notification has been sent.", Hasher.HashUtf8(identityAddress.StringValue), null, DeletionProcessStatus.WaitingForApproval, DeletionProcessStatus.WaitingForApproval); diff --git a/Modules/Devices/src/Devices.Infrastructure.Database.Postgres/Migrations/20240222122512_AddModificationsRequestedByCancelDeletionProcess.Designer.cs b/Modules/Devices/src/Devices.Infrastructure.Database.Postgres/Migrations/20240222122512_AddModificationsRequestedByCancelDeletionProcess.Designer.cs new file mode 100644 index 0000000000..7450cb1fd9 --- /dev/null +++ b/Modules/Devices/src/Devices.Infrastructure.Database.Postgres/Migrations/20240222122512_AddModificationsRequestedByCancelDeletionProcess.Designer.cs @@ -0,0 +1,873 @@ +// +using System; +using Backbone.Modules.Devices.Infrastructure.Persistence.Database; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace Backbone.Modules.Devices.Infrastructure.Database.Postgres.Migrations +{ + [DbContext(typeof(DevicesDbContext))] + [Migration("20240222122512_AddModificationsRequestedByCancelDeletionProcess")] + partial class AddModificationsRequestedByCancelDeletionProcess + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.1") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Aggregates.PushNotifications.PnsRegistration", b => + { + b.Property("DeviceId") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.Property("AppId") + .IsRequired() + .HasColumnType("text"); + + b.Property("DevicePushIdentifier") + .IsRequired() + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.Property("Environment") + .HasColumnType("integer"); + + b.Property("Handle") + .IsRequired() + .HasMaxLength(200) + .IsUnicode(true) + .HasColumnType("character varying(200)") + .IsFixedLength(false); + + b.Property("IdentityAddress") + .IsRequired() + .HasMaxLength(36) + .IsUnicode(false) + .HasColumnType("character(36)") + .IsFixedLength(); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("DeviceId"); + + b.ToTable("PnsRegistrations"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Aggregates.Tier.Tier", b => + { + b.Property("Id") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.Property("Name") + .IsRequired() + .HasMaxLength(30) + .IsUnicode(true) + .HasColumnType("character varying(30)") + .IsFixedLength(false); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("Tiers"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Challenge", b => + { + b.Property("Id") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.Property("ExpiresAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("Challenges", "Challenges", t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", b => + { + b.Property("Id") + .HasColumnType("text"); + + b.Property("AccessFailedCount") + .HasColumnType("integer"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DeviceId") + .IsRequired() + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.Property("LastLoginAt") + .HasColumnType("timestamp with time zone"); + + b.Property("LockoutEnabled") + .HasColumnType("boolean"); + + b.Property("LockoutEnd") + .HasColumnType("timestamp with time zone"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("PasswordHash") + .HasColumnType("text"); + + b.Property("SecurityStamp") + .HasColumnType("text"); + + b.Property("UserName") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.HasKey("Id"); + + b.HasIndex("DeviceId") + .IsUnique(); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.Device", b => + { + b.Property("Id") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatedByDevice") + .IsRequired() + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DeletedByDevice") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.Property("IdentityAddress") + .IsRequired() + .HasMaxLength(36) + .IsUnicode(false) + .HasColumnType("character(36)") + .IsFixedLength(); + + b.HasKey("Id"); + + b.HasIndex("IdentityAddress"); + + b.ToTable("Devices"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.Identity", b => + { + b.Property("Address") + .HasMaxLength(36) + .IsUnicode(false) + .HasColumnType("character(36)") + .IsFixedLength(); + + b.Property("ClientId") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DeletionGracePeriodEndsAt") + .HasColumnType("timestamp with time zone"); + + b.Property("IdentityVersion") + .HasColumnType("smallint"); + + b.Property("PublicKey") + .IsRequired() + .HasColumnType("bytea"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("TierId") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.Property("TierIdBeforeDeletion") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.HasKey("Address"); + + b.ToTable("Identities"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcess", b => + { + b.Property("Id") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.Property("ApprovalReminder1SentAt") + .HasColumnType("timestamp with time zone"); + + b.Property("ApprovalReminder2SentAt") + .HasColumnType("timestamp with time zone"); + + b.Property("ApprovalReminder3SentAt") + .HasColumnType("timestamp with time zone"); + + b.Property("ApprovedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("ApprovedByDevice") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.Property("CancelledAt") + .HasColumnType("timestamp with time zone"); + + b.Property("CancelledByDevice") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("GracePeriodEndsAt") + .HasColumnType("timestamp with time zone"); + + b.Property("GracePeriodReminder1SentAt") + .HasColumnType("timestamp with time zone"); + + b.Property("GracePeriodReminder2SentAt") + .HasColumnType("timestamp with time zone"); + + b.Property("GracePeriodReminder3SentAt") + .HasColumnType("timestamp with time zone"); + + b.Property("IdentityAddress") + .HasMaxLength(36) + .IsUnicode(false) + .HasColumnType("character(36)") + .IsFixedLength(); + + b.Property("Status") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("IdentityAddress"); + + b.ToTable("IdentityDeletionProcesses", (string)null); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcessAuditLogEntry", b => + { + b.Property("Id") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DeviceIdHash") + .HasColumnType("bytea"); + + b.Property("IdentityAddressHash") + .IsRequired() + .HasColumnType("bytea"); + + b.Property("IdentityDeletionProcessId") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.Property("Message") + .IsRequired() + .HasColumnType("text"); + + b.Property("NewStatus") + .HasColumnType("integer"); + + b.Property("OldStatus") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("IdentityDeletionProcessId"); + + b.ToTable("IdentityDeletionProcessAuditLog", (string)null); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreApplication", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("text"); + + b.Property("ApplicationType") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("ClientId") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("ClientSecret") + .HasColumnType("text"); + + b.Property("ClientType") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("ConcurrencyToken") + .IsConcurrencyToken() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("ConsentType") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DefaultTier") + .IsRequired() + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.Property("DisplayName") + .HasColumnType("text"); + + b.Property("DisplayNames") + .HasColumnType("text"); + + b.Property("JsonWebKeySet") + .HasColumnType("text"); + + b.Property("MaxIdentities") + .HasColumnType("integer"); + + b.Property("Permissions") + .HasColumnType("text"); + + b.Property("PostLogoutRedirectUris") + .HasColumnType("text"); + + b.Property("Properties") + .HasColumnType("text"); + + b.Property("RedirectUris") + .HasColumnType("text"); + + b.Property("Requirements") + .HasColumnType("text"); + + b.Property("Settings") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("ClientId") + .IsUnique(); + + b.HasIndex("DefaultTier"); + + b.ToTable("OpenIddictApplications", (string)null); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreAuthorization", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("text"); + + b.Property("ApplicationId") + .HasColumnType("text"); + + b.Property("ConcurrencyToken") + .IsConcurrencyToken() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("CreationDate") + .HasColumnType("timestamp with time zone"); + + b.Property("Properties") + .HasColumnType("text"); + + b.Property("Scopes") + .HasColumnType("text"); + + b.Property("Status") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("Subject") + .HasMaxLength(400) + .HasColumnType("character varying(400)"); + + b.Property("Type") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.HasIndex("ApplicationId", "Status", "Subject", "Type"); + + b.ToTable("OpenIddictAuthorizations", (string)null); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreScope", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("text"); + + b.Property("ConcurrencyToken") + .IsConcurrencyToken() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("Description") + .HasColumnType("text"); + + b.Property("Descriptions") + .HasColumnType("text"); + + b.Property("DisplayName") + .HasColumnType("text"); + + b.Property("DisplayNames") + .HasColumnType("text"); + + b.Property("Name") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("Properties") + .HasColumnType("text"); + + b.Property("Resources") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("OpenIddictScopes", (string)null); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("text"); + + b.Property("ApplicationId") + .HasColumnType("text"); + + b.Property("AuthorizationId") + .HasColumnType("text"); + + b.Property("ConcurrencyToken") + .IsConcurrencyToken() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("CreationDate") + .HasColumnType("timestamp with time zone"); + + b.Property("ExpirationDate") + .HasColumnType("timestamp with time zone"); + + b.Property("Payload") + .HasColumnType("text"); + + b.Property("Properties") + .HasColumnType("text"); + + b.Property("RedemptionDate") + .HasColumnType("timestamp with time zone"); + + b.Property("ReferenceId") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Status") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("Subject") + .HasMaxLength(400) + .HasColumnType("character varying(400)"); + + b.Property("Type") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.HasIndex("AuthorizationId"); + + b.HasIndex("ReferenceId") + .IsUnique(); + + b.HasIndex("ApplicationId", "Status", "Subject", "Type"); + + b.ToTable("OpenIddictTokens", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("text"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("text"); + + b.Property("ClaimValue") + .HasColumnType("text"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("text"); + + b.Property("ClaimValue") + .HasColumnType("text"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("text"); + + b.Property("ProviderKey") + .HasColumnType("text"); + + b.Property("ProviderDisplayName") + .HasColumnType("text"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("text"); + + b.Property("RoleId") + .HasColumnType("text"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("text"); + + b.Property("LoginProvider") + .HasColumnType("text"); + + b.Property("Name") + .HasColumnType("text"); + + b.Property("Value") + .HasColumnType("text"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.Device", "Device") + .WithOne("User") + .HasForeignKey("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", "DeviceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Device"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.Device", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.Identity", "Identity") + .WithMany("Devices") + .HasForeignKey("IdentityAddress") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Identity"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcess", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.Identity", null) + .WithMany("DeletionProcesses") + .HasForeignKey("IdentityAddress"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcessAuditLogEntry", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcess", null) + .WithMany("AuditLog") + .HasForeignKey("IdentityDeletionProcessId"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreApplication", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Aggregates.Tier.Tier", null) + .WithMany() + .HasForeignKey("DefaultTier") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreAuthorization", b => + { + b.HasOne("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreApplication", "Application") + .WithMany("Authorizations") + .HasForeignKey("ApplicationId"); + + b.Navigation("Application"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreToken", b => + { + b.HasOne("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreApplication", "Application") + .WithMany("Tokens") + .HasForeignKey("ApplicationId"); + + b.HasOne("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreAuthorization", "Authorization") + .WithMany("Tokens") + .HasForeignKey("AuthorizationId"); + + b.Navigation("Application"); + + b.Navigation("Authorization"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.Device", b => + { + b.Navigation("User") + .IsRequired(); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.Identity", b => + { + b.Navigation("DeletionProcesses"); + + b.Navigation("Devices"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcess", b => + { + b.Navigation("AuditLog"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreApplication", b => + { + b.Navigation("Authorizations"); + + b.Navigation("Tokens"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreAuthorization", b => + { + b.Navigation("Tokens"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Modules/Devices/src/Devices.Infrastructure.Database.Postgres/Migrations/20240222122512_AddModificationsRequestedByCancelDeletionProcess.cs b/Modules/Devices/src/Devices.Infrastructure.Database.Postgres/Migrations/20240222122512_AddModificationsRequestedByCancelDeletionProcess.cs new file mode 100644 index 0000000000..de127fa238 --- /dev/null +++ b/Modules/Devices/src/Devices.Infrastructure.Database.Postgres/Migrations/20240222122512_AddModificationsRequestedByCancelDeletionProcess.cs @@ -0,0 +1,42 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Backbone.Modules.Devices.Infrastructure.Database.Postgres.Migrations +{ + /// + public partial class AddModificationsRequestedByCancelDeletionProcess : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "CancelledAt", + table: "IdentityDeletionProcesses", + type: "timestamp with time zone", + nullable: true); + + migrationBuilder.AddColumn( + name: "CancelledByDevice", + table: "IdentityDeletionProcesses", + type: "character(20)", + unicode: false, + fixedLength: true, + maxLength: 20, + nullable: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "CancelledAt", + table: "IdentityDeletionProcesses"); + + migrationBuilder.DropColumn( + name: "CancelledByDevice", + table: "IdentityDeletionProcesses"); + } + } +} diff --git a/Modules/Devices/src/Devices.Infrastructure.Database.Postgres/Migrations/DevicesDbContextModelSnapshot.cs b/Modules/Devices/src/Devices.Infrastructure.Database.Postgres/Migrations/DevicesDbContextModelSnapshot.cs index f3bfcfd9cb..87d482aaa9 100644 --- a/Modules/Devices/src/Devices.Infrastructure.Database.Postgres/Migrations/DevicesDbContextModelSnapshot.cs +++ b/Modules/Devices/src/Devices.Infrastructure.Database.Postgres/Migrations/DevicesDbContextModelSnapshot.cs @@ -1,861 +1,870 @@ -// -using System; -using Backbone.Modules.Devices.Infrastructure.Persistence.Database; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable - -namespace Devices.Infrastructure.Database.Postgres.Migrations -{ - [DbContext(typeof(DevicesDbContext))] - partial class DevicesDbContextModelSnapshot : ModelSnapshot - { - protected override void BuildModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "8.0.1") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); - - modelBuilder.Entity("Backbone.Modules.Devices.Domain.Aggregates.PushNotifications.PnsRegistration", b => - { - b.Property("DeviceId") - .HasMaxLength(20) - .IsUnicode(false) - .HasColumnType("character(20)") - .IsFixedLength(); - - b.Property("AppId") - .IsRequired() - .HasColumnType("text"); - - b.Property("DevicePushIdentifier") - .IsRequired() - .HasMaxLength(20) - .IsUnicode(false) - .HasColumnType("character(20)") - .IsFixedLength(); - - b.Property("Environment") - .HasColumnType("integer"); - - b.Property("Handle") - .IsRequired() - .HasMaxLength(200) - .IsUnicode(true) - .HasColumnType("character varying(200)") - .IsFixedLength(false); - - b.Property("IdentityAddress") - .IsRequired() - .HasMaxLength(36) - .IsUnicode(false) - .HasColumnType("character(36)") - .IsFixedLength(); - - b.Property("UpdatedAt") - .HasColumnType("timestamp with time zone"); - - b.HasKey("DeviceId"); - - b.ToTable("PnsRegistrations"); - }); - - modelBuilder.Entity("Backbone.Modules.Devices.Domain.Aggregates.Tier.Tier", b => - { - b.Property("Id") - .HasMaxLength(20) - .IsUnicode(false) - .HasColumnType("character(20)") - .IsFixedLength(); - - b.Property("Name") - .IsRequired() - .HasMaxLength(30) - .IsUnicode(true) - .HasColumnType("character varying(30)") - .IsFixedLength(false); - - b.HasKey("Id"); - - b.HasIndex("Name") - .IsUnique(); - - b.ToTable("Tiers"); - }); - - modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Challenge", b => - { - b.Property("Id") - .HasMaxLength(20) - .IsUnicode(false) - .HasColumnType("character(20)") - .IsFixedLength(); - - b.Property("ExpiresAt") - .HasColumnType("timestamp with time zone"); - - b.HasKey("Id"); - - b.ToTable("Challenges", "Challenges", t => - { - t.ExcludeFromMigrations(); - }); - }); - - modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", b => - { - b.Property("Id") - .HasColumnType("text"); - - b.Property("AccessFailedCount") - .HasColumnType("integer"); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("text"); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("DeviceId") - .IsRequired() - .HasMaxLength(20) - .IsUnicode(false) - .HasColumnType("character(20)") - .IsFixedLength(); - - b.Property("LastLoginAt") - .HasColumnType("timestamp with time zone"); - - b.Property("LockoutEnabled") - .HasColumnType("boolean"); - - b.Property("LockoutEnd") - .HasColumnType("timestamp with time zone"); - - b.Property("NormalizedUserName") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.Property("PasswordHash") - .HasColumnType("text"); - - b.Property("SecurityStamp") - .HasColumnType("text"); - - b.Property("UserName") - .HasMaxLength(20) - .IsUnicode(false) - .HasColumnType("character(20)") - .IsFixedLength(); - - b.HasKey("Id"); - - b.HasIndex("DeviceId") - .IsUnique(); - - b.HasIndex("NormalizedUserName") - .IsUnique() - .HasDatabaseName("UserNameIndex"); - - b.ToTable("AspNetUsers", (string)null); - }); - - modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.Device", b => - { - b.Property("Id") - .HasMaxLength(20) - .IsUnicode(false) - .HasColumnType("character(20)") - .IsFixedLength(); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("CreatedByDevice") - .IsRequired() - .HasMaxLength(20) - .IsUnicode(false) - .HasColumnType("character(20)") - .IsFixedLength(); - - b.Property("DeletedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("DeletedByDevice") - .HasMaxLength(20) - .IsUnicode(false) - .HasColumnType("character(20)") - .IsFixedLength(); - - b.Property("IdentityAddress") - .IsRequired() - .HasMaxLength(36) - .IsUnicode(false) - .HasColumnType("character(36)") - .IsFixedLength(); - - b.HasKey("Id"); - - b.HasIndex("IdentityAddress"); - - b.ToTable("Devices"); - }); - - modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.Identity", b => - { - b.Property("Address") - .HasMaxLength(36) - .IsUnicode(false) - .HasColumnType("character(36)") - .IsFixedLength(); - - b.Property("ClientId") - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("DeletionGracePeriodEndsAt") - .HasColumnType("timestamp with time zone"); - - b.Property("IdentityVersion") - .HasColumnType("smallint"); - - b.Property("PublicKey") - .IsRequired() - .HasColumnType("bytea"); - - b.Property("Status") - .HasColumnType("integer"); - - b.Property("TierId") - .HasMaxLength(20) - .IsUnicode(false) - .HasColumnType("character(20)") - .IsFixedLength(); - - b.Property("TierIdBeforeDeletion") - .HasMaxLength(20) - .IsUnicode(false) - .HasColumnType("character(20)") - .IsFixedLength(); - - b.HasKey("Address"); - - b.ToTable("Identities"); - }); - - modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcess", b => - { - b.Property("Id") - .HasMaxLength(20) - .IsUnicode(false) - .HasColumnType("character(20)") - .IsFixedLength(); - - b.Property("ApprovalReminder1SentAt") - .HasColumnType("timestamp with time zone"); - - b.Property("ApprovalReminder2SentAt") - .HasColumnType("timestamp with time zone"); - - b.Property("ApprovalReminder3SentAt") - .HasColumnType("timestamp with time zone"); - - b.Property("ApprovedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("ApprovedByDevice") - .HasMaxLength(20) - .IsUnicode(false) - .HasColumnType("character(20)") - .IsFixedLength(); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("GracePeriodEndsAt") - .HasColumnType("timestamp with time zone"); - - b.Property("GracePeriodReminder1SentAt") - .HasColumnType("timestamp with time zone"); - - b.Property("GracePeriodReminder2SentAt") - .HasColumnType("timestamp with time zone"); - - b.Property("GracePeriodReminder3SentAt") - .HasColumnType("timestamp with time zone"); - - b.Property("IdentityAddress") - .HasMaxLength(36) - .IsUnicode(false) - .HasColumnType("character(36)") - .IsFixedLength(); - - b.Property("Status") - .HasColumnType("integer"); - - b.HasKey("Id"); - - b.HasIndex("IdentityAddress"); - - b.ToTable("IdentityDeletionProcesses", (string)null); - }); - - modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcessAuditLogEntry", b => - { - b.Property("Id") - .HasMaxLength(20) - .IsUnicode(false) - .HasColumnType("character(20)") - .IsFixedLength(); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("DeviceIdHash") - .HasColumnType("bytea"); - - b.Property("IdentityAddressHash") - .IsRequired() - .HasColumnType("bytea"); - - b.Property("IdentityDeletionProcessId") - .HasMaxLength(20) - .IsUnicode(false) - .HasColumnType("character(20)") - .IsFixedLength(); - - b.Property("Message") - .IsRequired() - .HasColumnType("text"); - - b.Property("NewStatus") - .HasColumnType("integer"); - - b.Property("OldStatus") - .HasColumnType("integer"); - - b.HasKey("Id"); - - b.HasIndex("IdentityDeletionProcessId"); - - b.ToTable("IdentityDeletionProcessAuditLog", (string)null); - }); - - modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreApplication", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("text"); - - b.Property("ApplicationType") - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("ClientId") - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.Property("ClientSecret") - .HasColumnType("text"); - - b.Property("ClientType") - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("ConcurrencyToken") - .IsConcurrencyToken() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("ConsentType") - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("CreatedAt") - .HasColumnType("timestamp with time zone"); - - b.Property("DefaultTier") - .IsRequired() - .HasMaxLength(20) - .IsUnicode(false) - .HasColumnType("character(20)") - .IsFixedLength(); - - b.Property("DisplayName") - .HasColumnType("text"); - - b.Property("DisplayNames") - .HasColumnType("text"); - - b.Property("JsonWebKeySet") - .HasColumnType("text"); - - b.Property("MaxIdentities") - .HasColumnType("integer"); - - b.Property("Permissions") - .HasColumnType("text"); - - b.Property("PostLogoutRedirectUris") - .HasColumnType("text"); - - b.Property("Properties") - .HasColumnType("text"); - - b.Property("RedirectUris") - .HasColumnType("text"); - - b.Property("Requirements") - .HasColumnType("text"); - - b.Property("Settings") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.HasIndex("ClientId") - .IsUnique(); - - b.HasIndex("DefaultTier"); - - b.ToTable("OpenIddictApplications", (string)null); - }); - - modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreAuthorization", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("text"); - - b.Property("ApplicationId") - .HasColumnType("text"); - - b.Property("ConcurrencyToken") - .IsConcurrencyToken() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("CreationDate") - .HasColumnType("timestamp with time zone"); - - b.Property("Properties") - .HasColumnType("text"); - - b.Property("Scopes") - .HasColumnType("text"); - - b.Property("Status") - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("Subject") - .HasMaxLength(400) - .HasColumnType("character varying(400)"); - - b.Property("Type") - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.HasKey("Id"); - - b.HasIndex("ApplicationId", "Status", "Subject", "Type"); - - b.ToTable("OpenIddictAuthorizations", (string)null); - }); - - modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreScope", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("text"); - - b.Property("ConcurrencyToken") - .IsConcurrencyToken() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("Descriptions") - .HasColumnType("text"); - - b.Property("DisplayName") - .HasColumnType("text"); - - b.Property("DisplayNames") - .HasColumnType("text"); - - b.Property("Name") - .HasMaxLength(200) - .HasColumnType("character varying(200)"); - - b.Property("Properties") - .HasColumnType("text"); - - b.Property("Resources") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.HasIndex("Name") - .IsUnique(); - - b.ToTable("OpenIddictScopes", (string)null); - }); - - modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreToken", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("text"); - - b.Property("ApplicationId") - .HasColumnType("text"); - - b.Property("AuthorizationId") - .HasColumnType("text"); - - b.Property("ConcurrencyToken") - .IsConcurrencyToken() - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("CreationDate") - .HasColumnType("timestamp with time zone"); - - b.Property("ExpirationDate") - .HasColumnType("timestamp with time zone"); - - b.Property("Payload") - .HasColumnType("text"); - - b.Property("Properties") - .HasColumnType("text"); - - b.Property("RedemptionDate") - .HasColumnType("timestamp with time zone"); - - b.Property("ReferenceId") - .HasMaxLength(100) - .HasColumnType("character varying(100)"); - - b.Property("Status") - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.Property("Subject") - .HasMaxLength(400) - .HasColumnType("character varying(400)"); - - b.Property("Type") - .HasMaxLength(50) - .HasColumnType("character varying(50)"); - - b.HasKey("Id"); - - b.HasIndex("AuthorizationId"); - - b.HasIndex("ReferenceId") - .IsUnique(); - - b.HasIndex("ApplicationId", "Status", "Subject", "Type"); - - b.ToTable("OpenIddictTokens", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => - { - b.Property("Id") - .HasColumnType("text"); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("text"); - - b.Property("Name") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.Property("NormalizedName") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.HasKey("Id"); - - b.HasIndex("NormalizedName") - .IsUnique() - .HasDatabaseName("RoleNameIndex"); - - b.ToTable("AspNetRoles", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("ClaimType") - .HasColumnType("text"); - - b.Property("ClaimValue") - .HasColumnType("text"); - - b.Property("RoleId") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.HasIndex("RoleId"); - - b.ToTable("AspNetRoleClaims", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("ClaimType") - .HasColumnType("text"); - - b.Property("ClaimValue") - .HasColumnType("text"); - - b.Property("UserId") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AspNetUserClaims", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => - { - b.Property("LoginProvider") - .HasColumnType("text"); - - b.Property("ProviderKey") - .HasColumnType("text"); - - b.Property("ProviderDisplayName") - .HasColumnType("text"); - - b.Property("UserId") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("LoginProvider", "ProviderKey"); - - b.HasIndex("UserId"); - - b.ToTable("AspNetUserLogins", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => - { - b.Property("UserId") - .HasColumnType("text"); - - b.Property("RoleId") - .HasColumnType("text"); - - b.HasKey("UserId", "RoleId"); - - b.HasIndex("RoleId"); - - b.ToTable("AspNetUserRoles", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => - { - b.Property("UserId") - .HasColumnType("text"); - - b.Property("LoginProvider") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Value") - .HasColumnType("text"); - - b.HasKey("UserId", "LoginProvider", "Name"); - - b.ToTable("AspNetUserTokens", (string)null); - }); - - modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", b => - { - b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.Device", "Device") - .WithOne("User") - .HasForeignKey("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", "DeviceId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Device"); - }); - - modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.Device", b => - { - b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.Identity", "Identity") - .WithMany("Devices") - .HasForeignKey("IdentityAddress") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Identity"); - }); - - modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcess", b => - { - b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.Identity", null) - .WithMany("DeletionProcesses") - .HasForeignKey("IdentityAddress"); - }); - - modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcessAuditLogEntry", b => - { - b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcess", null) - .WithMany("AuditLog") - .HasForeignKey("IdentityDeletionProcessId"); - }); - - modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreApplication", b => - { - b.HasOne("Backbone.Modules.Devices.Domain.Aggregates.Tier.Tier", null) - .WithMany() - .HasForeignKey("DefaultTier") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - }); - - modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreAuthorization", b => - { - b.HasOne("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreApplication", "Application") - .WithMany("Authorizations") - .HasForeignKey("ApplicationId"); - - b.Navigation("Application"); - }); - - modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreToken", b => - { - b.HasOne("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreApplication", "Application") - .WithMany("Tokens") - .HasForeignKey("ApplicationId"); - - b.HasOne("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreAuthorization", "Authorization") - .WithMany("Tokens") - .HasForeignKey("AuthorizationId"); - - b.Navigation("Application"); - - b.Navigation("Authorization"); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => - { - b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => - { - b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => - { - b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => - { - b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => - { - b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.Device", b => - { - b.Navigation("User") - .IsRequired(); - }); - - modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.Identity", b => - { - b.Navigation("DeletionProcesses"); - - b.Navigation("Devices"); - }); - - modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcess", b => - { - b.Navigation("AuditLog"); - }); - - modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreApplication", b => - { - b.Navigation("Authorizations"); - - b.Navigation("Tokens"); - }); - - modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreAuthorization", b => - { - b.Navigation("Tokens"); - }); -#pragma warning restore 612, 618 - } - } -} +// +using System; +using Backbone.Modules.Devices.Infrastructure.Persistence.Database; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace Devices.Infrastructure.Database.Postgres.Migrations +{ + [DbContext(typeof(DevicesDbContext))] + partial class DevicesDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.1") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Aggregates.PushNotifications.PnsRegistration", b => + { + b.Property("DeviceId") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.Property("AppId") + .IsRequired() + .HasColumnType("text"); + + b.Property("DevicePushIdentifier") + .IsRequired() + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.Property("Environment") + .HasColumnType("integer"); + + b.Property("Handle") + .IsRequired() + .HasMaxLength(200) + .IsUnicode(true) + .HasColumnType("character varying(200)") + .IsFixedLength(false); + + b.Property("IdentityAddress") + .IsRequired() + .HasMaxLength(36) + .IsUnicode(false) + .HasColumnType("character(36)") + .IsFixedLength(); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("DeviceId"); + + b.ToTable("PnsRegistrations"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Aggregates.Tier.Tier", b => + { + b.Property("Id") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.Property("Name") + .IsRequired() + .HasMaxLength(30) + .IsUnicode(true) + .HasColumnType("character varying(30)") + .IsFixedLength(false); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("Tiers"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Challenge", b => + { + b.Property("Id") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.Property("ExpiresAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("Challenges", "Challenges", t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", b => + { + b.Property("Id") + .HasColumnType("text"); + + b.Property("AccessFailedCount") + .HasColumnType("integer"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DeviceId") + .IsRequired() + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.Property("LastLoginAt") + .HasColumnType("timestamp with time zone"); + + b.Property("LockoutEnabled") + .HasColumnType("boolean"); + + b.Property("LockoutEnd") + .HasColumnType("timestamp with time zone"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("PasswordHash") + .HasColumnType("text"); + + b.Property("SecurityStamp") + .HasColumnType("text"); + + b.Property("UserName") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.HasKey("Id"); + + b.HasIndex("DeviceId") + .IsUnique(); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.Device", b => + { + b.Property("Id") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatedByDevice") + .IsRequired() + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DeletedByDevice") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.Property("IdentityAddress") + .IsRequired() + .HasMaxLength(36) + .IsUnicode(false) + .HasColumnType("character(36)") + .IsFixedLength(); + + b.HasKey("Id"); + + b.HasIndex("IdentityAddress"); + + b.ToTable("Devices"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.Identity", b => + { + b.Property("Address") + .HasMaxLength(36) + .IsUnicode(false) + .HasColumnType("character(36)") + .IsFixedLength(); + + b.Property("ClientId") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DeletionGracePeriodEndsAt") + .HasColumnType("timestamp with time zone"); + + b.Property("IdentityVersion") + .HasColumnType("smallint"); + + b.Property("PublicKey") + .IsRequired() + .HasColumnType("bytea"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("TierId") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.Property("TierIdBeforeDeletion") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.HasKey("Address"); + + b.ToTable("Identities"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcess", b => + { + b.Property("Id") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.Property("ApprovalReminder1SentAt") + .HasColumnType("timestamp with time zone"); + + b.Property("ApprovalReminder2SentAt") + .HasColumnType("timestamp with time zone"); + + b.Property("ApprovalReminder3SentAt") + .HasColumnType("timestamp with time zone"); + + b.Property("ApprovedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("ApprovedByDevice") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.Property("CancelledAt") + .HasColumnType("timestamp with time zone"); + + b.Property("CancelledByDevice") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("GracePeriodEndsAt") + .HasColumnType("timestamp with time zone"); + + b.Property("GracePeriodReminder1SentAt") + .HasColumnType("timestamp with time zone"); + + b.Property("GracePeriodReminder2SentAt") + .HasColumnType("timestamp with time zone"); + + b.Property("GracePeriodReminder3SentAt") + .HasColumnType("timestamp with time zone"); + + b.Property("IdentityAddress") + .HasMaxLength(36) + .IsUnicode(false) + .HasColumnType("character(36)") + .IsFixedLength(); + + b.Property("Status") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("IdentityAddress"); + + b.ToTable("IdentityDeletionProcesses", (string)null); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcessAuditLogEntry", b => + { + b.Property("Id") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DeviceIdHash") + .HasColumnType("bytea"); + + b.Property("IdentityAddressHash") + .IsRequired() + .HasColumnType("bytea"); + + b.Property("IdentityDeletionProcessId") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.Property("Message") + .IsRequired() + .HasColumnType("text"); + + b.Property("NewStatus") + .HasColumnType("integer"); + + b.Property("OldStatus") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("IdentityDeletionProcessId"); + + b.ToTable("IdentityDeletionProcessAuditLog", (string)null); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreApplication", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("text"); + + b.Property("ApplicationType") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("ClientId") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("ClientSecret") + .HasColumnType("text"); + + b.Property("ClientType") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("ConcurrencyToken") + .IsConcurrencyToken() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("ConsentType") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DefaultTier") + .IsRequired() + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.Property("DisplayName") + .HasColumnType("text"); + + b.Property("DisplayNames") + .HasColumnType("text"); + + b.Property("JsonWebKeySet") + .HasColumnType("text"); + + b.Property("MaxIdentities") + .HasColumnType("integer"); + + b.Property("Permissions") + .HasColumnType("text"); + + b.Property("PostLogoutRedirectUris") + .HasColumnType("text"); + + b.Property("Properties") + .HasColumnType("text"); + + b.Property("RedirectUris") + .HasColumnType("text"); + + b.Property("Requirements") + .HasColumnType("text"); + + b.Property("Settings") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("ClientId") + .IsUnique(); + + b.HasIndex("DefaultTier"); + + b.ToTable("OpenIddictApplications", (string)null); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreAuthorization", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("text"); + + b.Property("ApplicationId") + .HasColumnType("text"); + + b.Property("ConcurrencyToken") + .IsConcurrencyToken() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("CreationDate") + .HasColumnType("timestamp with time zone"); + + b.Property("Properties") + .HasColumnType("text"); + + b.Property("Scopes") + .HasColumnType("text"); + + b.Property("Status") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("Subject") + .HasMaxLength(400) + .HasColumnType("character varying(400)"); + + b.Property("Type") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.HasIndex("ApplicationId", "Status", "Subject", "Type"); + + b.ToTable("OpenIddictAuthorizations", (string)null); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreScope", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("text"); + + b.Property("ConcurrencyToken") + .IsConcurrencyToken() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("Description") + .HasColumnType("text"); + + b.Property("Descriptions") + .HasColumnType("text"); + + b.Property("DisplayName") + .HasColumnType("text"); + + b.Property("DisplayNames") + .HasColumnType("text"); + + b.Property("Name") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("Properties") + .HasColumnType("text"); + + b.Property("Resources") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("OpenIddictScopes", (string)null); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("text"); + + b.Property("ApplicationId") + .HasColumnType("text"); + + b.Property("AuthorizationId") + .HasColumnType("text"); + + b.Property("ConcurrencyToken") + .IsConcurrencyToken() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("CreationDate") + .HasColumnType("timestamp with time zone"); + + b.Property("ExpirationDate") + .HasColumnType("timestamp with time zone"); + + b.Property("Payload") + .HasColumnType("text"); + + b.Property("Properties") + .HasColumnType("text"); + + b.Property("RedemptionDate") + .HasColumnType("timestamp with time zone"); + + b.Property("ReferenceId") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Status") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("Subject") + .HasMaxLength(400) + .HasColumnType("character varying(400)"); + + b.Property("Type") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.HasIndex("AuthorizationId"); + + b.HasIndex("ReferenceId") + .IsUnique(); + + b.HasIndex("ApplicationId", "Status", "Subject", "Type"); + + b.ToTable("OpenIddictTokens", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("text"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("text"); + + b.Property("ClaimValue") + .HasColumnType("text"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("text"); + + b.Property("ClaimValue") + .HasColumnType("text"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("text"); + + b.Property("ProviderKey") + .HasColumnType("text"); + + b.Property("ProviderDisplayName") + .HasColumnType("text"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("text"); + + b.Property("RoleId") + .HasColumnType("text"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("text"); + + b.Property("LoginProvider") + .HasColumnType("text"); + + b.Property("Name") + .HasColumnType("text"); + + b.Property("Value") + .HasColumnType("text"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.Device", "Device") + .WithOne("User") + .HasForeignKey("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", "DeviceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Device"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.Device", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.Identity", "Identity") + .WithMany("Devices") + .HasForeignKey("IdentityAddress") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Identity"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcess", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.Identity", null) + .WithMany("DeletionProcesses") + .HasForeignKey("IdentityAddress"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcessAuditLogEntry", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcess", null) + .WithMany("AuditLog") + .HasForeignKey("IdentityDeletionProcessId"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreApplication", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Aggregates.Tier.Tier", null) + .WithMany() + .HasForeignKey("DefaultTier") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreAuthorization", b => + { + b.HasOne("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreApplication", "Application") + .WithMany("Authorizations") + .HasForeignKey("ApplicationId"); + + b.Navigation("Application"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreToken", b => + { + b.HasOne("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreApplication", "Application") + .WithMany("Tokens") + .HasForeignKey("ApplicationId"); + + b.HasOne("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreAuthorization", "Authorization") + .WithMany("Tokens") + .HasForeignKey("AuthorizationId"); + + b.Navigation("Application"); + + b.Navigation("Authorization"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.Device", b => + { + b.Navigation("User") + .IsRequired(); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.Identity", b => + { + b.Navigation("DeletionProcesses"); + + b.Navigation("Devices"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcess", b => + { + b.Navigation("AuditLog"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreApplication", b => + { + b.Navigation("Authorizations"); + + b.Navigation("Tokens"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreAuthorization", b => + { + b.Navigation("Tokens"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Modules/Devices/src/Devices.Infrastructure.Database.SqlServer/Migrations/20240222122457_AddModificationsRequestedByCancelDeletionProcess.Designer.cs b/Modules/Devices/src/Devices.Infrastructure.Database.SqlServer/Migrations/20240222122457_AddModificationsRequestedByCancelDeletionProcess.Designer.cs new file mode 100644 index 0000000000..2e57c67129 --- /dev/null +++ b/Modules/Devices/src/Devices.Infrastructure.Database.SqlServer/Migrations/20240222122457_AddModificationsRequestedByCancelDeletionProcess.Designer.cs @@ -0,0 +1,878 @@ +// +using System; +using Backbone.Modules.Devices.Infrastructure.Persistence.Database; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Backbone.Modules.Devices.Infrastructure.Database.SqlServer.Migrations +{ + [DbContext(typeof(DevicesDbContext))] + [Migration("20240222122457_AddModificationsRequestedByCancelDeletionProcess")] + partial class AddModificationsRequestedByCancelDeletionProcess + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.1") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Aggregates.PushNotifications.PnsRegistration", b => + { + b.Property("DeviceId") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.Property("AppId") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("DevicePushIdentifier") + .IsRequired() + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.Property("Environment") + .HasColumnType("int"); + + b.Property("Handle") + .IsRequired() + .HasMaxLength(200) + .IsUnicode(true) + .HasColumnType("nvarchar(200)") + .IsFixedLength(false); + + b.Property("IdentityAddress") + .IsRequired() + .HasMaxLength(36) + .IsUnicode(false) + .HasColumnType("char(36)") + .IsFixedLength(); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.HasKey("DeviceId"); + + b.ToTable("PnsRegistrations"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Aggregates.Tier.Tier", b => + { + b.Property("Id") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.Property("Name") + .IsRequired() + .HasMaxLength(30) + .IsUnicode(true) + .HasColumnType("nvarchar(30)") + .IsFixedLength(false); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("Tiers"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Challenge", b => + { + b.Property("Id") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.Property("ExpiresAt") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.ToTable("Challenges", "Challenges", t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", b => + { + b.Property("Id") + .HasColumnType("nvarchar(450)"); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeviceId") + .IsRequired() + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.Property("LastLoginAt") + .HasColumnType("datetime2"); + + b.Property("LockoutEnabled") + .HasColumnType("bit"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("PasswordHash") + .HasColumnType("nvarchar(max)"); + + b.Property("SecurityStamp") + .HasColumnType("nvarchar(max)"); + + b.Property("UserName") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.HasKey("Id"); + + b.HasIndex("DeviceId") + .IsUnique(); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex") + .HasFilter("[NormalizedUserName] IS NOT NULL"); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.Device", b => + { + b.Property("Id") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedByDevice") + .IsRequired() + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("DeletedByDevice") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.Property("IdentityAddress") + .IsRequired() + .HasMaxLength(36) + .IsUnicode(false) + .HasColumnType("char(36)") + .IsFixedLength(); + + b.HasKey("Id"); + + b.HasIndex("IdentityAddress"); + + b.ToTable("Devices"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.Identity", b => + { + b.Property("Address") + .HasMaxLength(36) + .IsUnicode(false) + .HasColumnType("char(36)") + .IsFixedLength(); + + b.Property("ClientId") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeletionGracePeriodEndsAt") + .HasColumnType("datetime2"); + + b.Property("IdentityVersion") + .HasColumnType("tinyint"); + + b.Property("PublicKey") + .IsRequired() + .HasColumnType("varbinary(max)"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("TierId") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.Property("TierIdBeforeDeletion") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.HasKey("Address"); + + b.ToTable("Identities"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcess", b => + { + b.Property("Id") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.Property("ApprovalReminder1SentAt") + .HasColumnType("datetime2"); + + b.Property("ApprovalReminder2SentAt") + .HasColumnType("datetime2"); + + b.Property("ApprovalReminder3SentAt") + .HasColumnType("datetime2"); + + b.Property("ApprovedAt") + .HasColumnType("datetime2"); + + b.Property("ApprovedByDevice") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.Property("CancelledAt") + .HasColumnType("datetime2"); + + b.Property("CancelledByDevice") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("GracePeriodEndsAt") + .HasColumnType("datetime2"); + + b.Property("GracePeriodReminder1SentAt") + .HasColumnType("datetime2"); + + b.Property("GracePeriodReminder2SentAt") + .HasColumnType("datetime2"); + + b.Property("GracePeriodReminder3SentAt") + .HasColumnType("datetime2"); + + b.Property("IdentityAddress") + .HasMaxLength(36) + .IsUnicode(false) + .HasColumnType("char(36)") + .IsFixedLength(); + + b.Property("Status") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("IdentityAddress"); + + b.ToTable("IdentityDeletionProcesses", (string)null); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcessAuditLogEntry", b => + { + b.Property("Id") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeviceIdHash") + .HasColumnType("varbinary(max)"); + + b.Property("IdentityAddressHash") + .IsRequired() + .HasColumnType("varbinary(max)"); + + b.Property("IdentityDeletionProcessId") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.Property("Message") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("NewStatus") + .HasColumnType("int"); + + b.Property("OldStatus") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("IdentityDeletionProcessId"); + + b.ToTable("IdentityDeletionProcessAuditLog", (string)null); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreApplication", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("nvarchar(450)"); + + b.Property("ApplicationType") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("ClientId") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("ClientSecret") + .HasColumnType("nvarchar(max)"); + + b.Property("ClientType") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("ConcurrencyToken") + .IsConcurrencyToken() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("ConsentType") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DefaultTier") + .IsRequired() + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.Property("DisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("DisplayNames") + .HasColumnType("nvarchar(max)"); + + b.Property("JsonWebKeySet") + .HasColumnType("nvarchar(max)"); + + b.Property("MaxIdentities") + .HasColumnType("int"); + + b.Property("Permissions") + .HasColumnType("nvarchar(max)"); + + b.Property("PostLogoutRedirectUris") + .HasColumnType("nvarchar(max)"); + + b.Property("Properties") + .HasColumnType("nvarchar(max)"); + + b.Property("RedirectUris") + .HasColumnType("nvarchar(max)"); + + b.Property("Requirements") + .HasColumnType("nvarchar(max)"); + + b.Property("Settings") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("ClientId") + .IsUnique() + .HasFilter("[ClientId] IS NOT NULL"); + + b.HasIndex("DefaultTier"); + + b.ToTable("OpenIddictApplications", (string)null); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreAuthorization", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("nvarchar(450)"); + + b.Property("ApplicationId") + .HasColumnType("nvarchar(450)"); + + b.Property("ConcurrencyToken") + .IsConcurrencyToken() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Properties") + .HasColumnType("nvarchar(max)"); + + b.Property("Scopes") + .HasColumnType("nvarchar(max)"); + + b.Property("Status") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Subject") + .HasMaxLength(400) + .HasColumnType("nvarchar(400)"); + + b.Property("Type") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.HasIndex("ApplicationId", "Status", "Subject", "Type"); + + b.ToTable("OpenIddictAuthorizations", (string)null); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreScope", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("nvarchar(450)"); + + b.Property("ConcurrencyToken") + .IsConcurrencyToken() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("Descriptions") + .HasColumnType("nvarchar(max)"); + + b.Property("DisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("DisplayNames") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("Properties") + .HasColumnType("nvarchar(max)"); + + b.Property("Resources") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique() + .HasFilter("[Name] IS NOT NULL"); + + b.ToTable("OpenIddictScopes", (string)null); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("nvarchar(450)"); + + b.Property("ApplicationId") + .HasColumnType("nvarchar(450)"); + + b.Property("AuthorizationId") + .HasColumnType("nvarchar(450)"); + + b.Property("ConcurrencyToken") + .IsConcurrencyToken() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("ExpirationDate") + .HasColumnType("datetime2"); + + b.Property("Payload") + .HasColumnType("nvarchar(max)"); + + b.Property("Properties") + .HasColumnType("nvarchar(max)"); + + b.Property("RedemptionDate") + .HasColumnType("datetime2"); + + b.Property("ReferenceId") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("Status") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Subject") + .HasMaxLength(400) + .HasColumnType("nvarchar(400)"); + + b.Property("Type") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.HasIndex("AuthorizationId"); + + b.HasIndex("ReferenceId") + .IsUnique() + .HasFilter("[ReferenceId] IS NOT NULL"); + + b.HasIndex("ApplicationId", "Status", "Subject", "Type"); + + b.ToTable("OpenIddictTokens", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("nvarchar(450)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex") + .HasFilter("[NormalizedName] IS NOT NULL"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderKey") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("nvarchar(450)"); + + b.Property("RoleId") + .HasColumnType("nvarchar(450)"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("nvarchar(450)"); + + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("Name") + .HasColumnType("nvarchar(450)"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.Device", "Device") + .WithOne("User") + .HasForeignKey("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", "DeviceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Device"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.Device", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.Identity", "Identity") + .WithMany("Devices") + .HasForeignKey("IdentityAddress") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Identity"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcess", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.Identity", null) + .WithMany("DeletionProcesses") + .HasForeignKey("IdentityAddress"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcessAuditLogEntry", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcess", null) + .WithMany("AuditLog") + .HasForeignKey("IdentityDeletionProcessId"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreApplication", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Aggregates.Tier.Tier", null) + .WithMany() + .HasForeignKey("DefaultTier") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreAuthorization", b => + { + b.HasOne("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreApplication", "Application") + .WithMany("Authorizations") + .HasForeignKey("ApplicationId"); + + b.Navigation("Application"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreToken", b => + { + b.HasOne("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreApplication", "Application") + .WithMany("Tokens") + .HasForeignKey("ApplicationId"); + + b.HasOne("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreAuthorization", "Authorization") + .WithMany("Tokens") + .HasForeignKey("AuthorizationId"); + + b.Navigation("Application"); + + b.Navigation("Authorization"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.Device", b => + { + b.Navigation("User") + .IsRequired(); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.Identity", b => + { + b.Navigation("DeletionProcesses"); + + b.Navigation("Devices"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcess", b => + { + b.Navigation("AuditLog"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreApplication", b => + { + b.Navigation("Authorizations"); + + b.Navigation("Tokens"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreAuthorization", b => + { + b.Navigation("Tokens"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Modules/Devices/src/Devices.Infrastructure.Database.SqlServer/Migrations/20240222122457_AddModificationsRequestedByCancelDeletionProcess.cs b/Modules/Devices/src/Devices.Infrastructure.Database.SqlServer/Migrations/20240222122457_AddModificationsRequestedByCancelDeletionProcess.cs new file mode 100644 index 0000000000..e2f7fb8d95 --- /dev/null +++ b/Modules/Devices/src/Devices.Infrastructure.Database.SqlServer/Migrations/20240222122457_AddModificationsRequestedByCancelDeletionProcess.cs @@ -0,0 +1,42 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Backbone.Modules.Devices.Infrastructure.Database.SqlServer.Migrations +{ + /// + public partial class AddModificationsRequestedByCancelDeletionProcess : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "CancelledAt", + table: "IdentityDeletionProcesses", + type: "datetime2", + nullable: true); + + migrationBuilder.AddColumn( + name: "CancelledByDevice", + table: "IdentityDeletionProcesses", + type: "char(20)", + unicode: false, + fixedLength: true, + maxLength: 20, + nullable: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "CancelledAt", + table: "IdentityDeletionProcesses"); + + migrationBuilder.DropColumn( + name: "CancelledByDevice", + table: "IdentityDeletionProcesses"); + } + } +} diff --git a/Modules/Devices/src/Devices.Infrastructure.Database.SqlServer/Migrations/ApplicationDbContextModelSnapshot.cs b/Modules/Devices/src/Devices.Infrastructure.Database.SqlServer/Migrations/ApplicationDbContextModelSnapshot.cs index c3ca46fae6..fdaee05a4c 100644 --- a/Modules/Devices/src/Devices.Infrastructure.Database.SqlServer/Migrations/ApplicationDbContextModelSnapshot.cs +++ b/Modules/Devices/src/Devices.Infrastructure.Database.SqlServer/Migrations/ApplicationDbContextModelSnapshot.cs @@ -1,866 +1,875 @@ -// -using System; -using Backbone.Modules.Devices.Infrastructure.Persistence.Database; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; - -#nullable disable - -namespace Backbone.Modules.Devices.Infrastructure.Database.SqlServer.Migrations -{ - [DbContext(typeof(DevicesDbContext))] - partial class ApplicationDbContextModelSnapshot : ModelSnapshot - { - protected override void BuildModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "8.0.1") - .HasAnnotation("Relational:MaxIdentifierLength", 128); - - SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); - - modelBuilder.Entity("Backbone.Modules.Devices.Domain.Aggregates.PushNotifications.PnsRegistration", b => - { - b.Property("DeviceId") - .HasMaxLength(20) - .IsUnicode(false) - .HasColumnType("char(20)") - .IsFixedLength(); - - b.Property("AppId") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("DevicePushIdentifier") - .IsRequired() - .HasMaxLength(20) - .IsUnicode(false) - .HasColumnType("char(20)") - .IsFixedLength(); - - b.Property("Environment") - .HasColumnType("int"); - - b.Property("Handle") - .IsRequired() - .HasMaxLength(200) - .IsUnicode(true) - .HasColumnType("nvarchar(200)") - .IsFixedLength(false); - - b.Property("IdentityAddress") - .IsRequired() - .HasMaxLength(36) - .IsUnicode(false) - .HasColumnType("char(36)") - .IsFixedLength(); - - b.Property("UpdatedAt") - .HasColumnType("datetime2"); - - b.HasKey("DeviceId"); - - b.ToTable("PnsRegistrations"); - }); - - modelBuilder.Entity("Backbone.Modules.Devices.Domain.Aggregates.Tier.Tier", b => - { - b.Property("Id") - .HasMaxLength(20) - .IsUnicode(false) - .HasColumnType("char(20)") - .IsFixedLength(); - - b.Property("Name") - .IsRequired() - .HasMaxLength(30) - .IsUnicode(true) - .HasColumnType("nvarchar(30)") - .IsFixedLength(false); - - b.HasKey("Id"); - - b.HasIndex("Name") - .IsUnique(); - - b.ToTable("Tiers"); - }); - - modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Challenge", b => - { - b.Property("Id") - .HasMaxLength(20) - .IsUnicode(false) - .HasColumnType("char(20)") - .IsFixedLength(); - - b.Property("ExpiresAt") - .HasColumnType("datetime2"); - - b.HasKey("Id"); - - b.ToTable("Challenges", "Challenges", t => - { - t.ExcludeFromMigrations(); - }); - }); - - modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", b => - { - b.Property("Id") - .HasColumnType("nvarchar(450)"); - - b.Property("AccessFailedCount") - .HasColumnType("int"); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("nvarchar(max)"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("DeviceId") - .IsRequired() - .HasMaxLength(20) - .IsUnicode(false) - .HasColumnType("char(20)") - .IsFixedLength(); - - b.Property("LastLoginAt") - .HasColumnType("datetime2"); - - b.Property("LockoutEnabled") - .HasColumnType("bit"); - - b.Property("LockoutEnd") - .HasColumnType("datetimeoffset"); - - b.Property("NormalizedUserName") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("PasswordHash") - .HasColumnType("nvarchar(max)"); - - b.Property("SecurityStamp") - .HasColumnType("nvarchar(max)"); - - b.Property("UserName") - .HasMaxLength(20) - .IsUnicode(false) - .HasColumnType("char(20)") - .IsFixedLength(); - - b.HasKey("Id"); - - b.HasIndex("DeviceId") - .IsUnique(); - - b.HasIndex("NormalizedUserName") - .IsUnique() - .HasDatabaseName("UserNameIndex") - .HasFilter("[NormalizedUserName] IS NOT NULL"); - - b.ToTable("AspNetUsers", (string)null); - }); - - modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.Device", b => - { - b.Property("Id") - .HasMaxLength(20) - .IsUnicode(false) - .HasColumnType("char(20)") - .IsFixedLength(); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("CreatedByDevice") - .IsRequired() - .HasMaxLength(20) - .IsUnicode(false) - .HasColumnType("char(20)") - .IsFixedLength(); - - b.Property("DeletedAt") - .HasColumnType("datetime2"); - - b.Property("DeletedByDevice") - .HasMaxLength(20) - .IsUnicode(false) - .HasColumnType("char(20)") - .IsFixedLength(); - - b.Property("IdentityAddress") - .IsRequired() - .HasMaxLength(36) - .IsUnicode(false) - .HasColumnType("char(36)") - .IsFixedLength(); - - b.HasKey("Id"); - - b.HasIndex("IdentityAddress"); - - b.ToTable("Devices"); - }); - - modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.Identity", b => - { - b.Property("Address") - .HasMaxLength(36) - .IsUnicode(false) - .HasColumnType("char(36)") - .IsFixedLength(); - - b.Property("ClientId") - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("DeletionGracePeriodEndsAt") - .HasColumnType("datetime2"); - - b.Property("IdentityVersion") - .HasColumnType("tinyint"); - - b.Property("PublicKey") - .IsRequired() - .HasColumnType("varbinary(max)"); - - b.Property("Status") - .HasColumnType("int"); - - b.Property("TierId") - .HasMaxLength(20) - .IsUnicode(false) - .HasColumnType("char(20)") - .IsFixedLength(); - - b.Property("TierIdBeforeDeletion") - .HasMaxLength(20) - .IsUnicode(false) - .HasColumnType("char(20)") - .IsFixedLength(); - - b.HasKey("Address"); - - b.ToTable("Identities"); - }); - - modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcess", b => - { - b.Property("Id") - .HasMaxLength(20) - .IsUnicode(false) - .HasColumnType("char(20)") - .IsFixedLength(); - - b.Property("ApprovalReminder1SentAt") - .HasColumnType("datetime2"); - - b.Property("ApprovalReminder2SentAt") - .HasColumnType("datetime2"); - - b.Property("ApprovalReminder3SentAt") - .HasColumnType("datetime2"); - - b.Property("ApprovedAt") - .HasColumnType("datetime2"); - - b.Property("ApprovedByDevice") - .HasMaxLength(20) - .IsUnicode(false) - .HasColumnType("char(20)") - .IsFixedLength(); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("GracePeriodEndsAt") - .HasColumnType("datetime2"); - - b.Property("GracePeriodReminder1SentAt") - .HasColumnType("datetime2"); - - b.Property("GracePeriodReminder2SentAt") - .HasColumnType("datetime2"); - - b.Property("GracePeriodReminder3SentAt") - .HasColumnType("datetime2"); - - b.Property("IdentityAddress") - .HasMaxLength(36) - .IsUnicode(false) - .HasColumnType("char(36)") - .IsFixedLength(); - - b.Property("Status") - .HasColumnType("int"); - - b.HasKey("Id"); - - b.HasIndex("IdentityAddress"); - - b.ToTable("IdentityDeletionProcesses", (string)null); - }); - - modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcessAuditLogEntry", b => - { - b.Property("Id") - .HasMaxLength(20) - .IsUnicode(false) - .HasColumnType("char(20)") - .IsFixedLength(); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("DeviceIdHash") - .HasColumnType("varbinary(max)"); - - b.Property("IdentityAddressHash") - .IsRequired() - .HasColumnType("varbinary(max)"); - - b.Property("IdentityDeletionProcessId") - .HasMaxLength(20) - .IsUnicode(false) - .HasColumnType("char(20)") - .IsFixedLength(); - - b.Property("Message") - .IsRequired() - .HasColumnType("nvarchar(max)"); - - b.Property("NewStatus") - .HasColumnType("int"); - - b.Property("OldStatus") - .HasColumnType("int"); - - b.HasKey("Id"); - - b.HasIndex("IdentityDeletionProcessId"); - - b.ToTable("IdentityDeletionProcessAuditLog", (string)null); - }); - - modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreApplication", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("nvarchar(450)"); - - b.Property("ApplicationType") - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.Property("ClientId") - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b.Property("ClientSecret") - .HasColumnType("nvarchar(max)"); - - b.Property("ClientType") - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.Property("ConcurrencyToken") - .IsConcurrencyToken() - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.Property("ConsentType") - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.Property("CreatedAt") - .HasColumnType("datetime2"); - - b.Property("DefaultTier") - .IsRequired() - .HasMaxLength(20) - .IsUnicode(false) - .HasColumnType("char(20)") - .IsFixedLength(); - - b.Property("DisplayName") - .HasColumnType("nvarchar(max)"); - - b.Property("DisplayNames") - .HasColumnType("nvarchar(max)"); - - b.Property("JsonWebKeySet") - .HasColumnType("nvarchar(max)"); - - b.Property("MaxIdentities") - .HasColumnType("int"); - - b.Property("Permissions") - .HasColumnType("nvarchar(max)"); - - b.Property("PostLogoutRedirectUris") - .HasColumnType("nvarchar(max)"); - - b.Property("Properties") - .HasColumnType("nvarchar(max)"); - - b.Property("RedirectUris") - .HasColumnType("nvarchar(max)"); - - b.Property("Requirements") - .HasColumnType("nvarchar(max)"); - - b.Property("Settings") - .HasColumnType("nvarchar(max)"); - - b.HasKey("Id"); - - b.HasIndex("ClientId") - .IsUnique() - .HasFilter("[ClientId] IS NOT NULL"); - - b.HasIndex("DefaultTier"); - - b.ToTable("OpenIddictApplications", (string)null); - }); - - modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreAuthorization", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("nvarchar(450)"); - - b.Property("ApplicationId") - .HasColumnType("nvarchar(450)"); - - b.Property("ConcurrencyToken") - .IsConcurrencyToken() - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.Property("CreationDate") - .HasColumnType("datetime2"); - - b.Property("Properties") - .HasColumnType("nvarchar(max)"); - - b.Property("Scopes") - .HasColumnType("nvarchar(max)"); - - b.Property("Status") - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.Property("Subject") - .HasMaxLength(400) - .HasColumnType("nvarchar(400)"); - - b.Property("Type") - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.HasKey("Id"); - - b.HasIndex("ApplicationId", "Status", "Subject", "Type"); - - b.ToTable("OpenIddictAuthorizations", (string)null); - }); - - modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreScope", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("nvarchar(450)"); - - b.Property("ConcurrencyToken") - .IsConcurrencyToken() - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.Property("Description") - .HasColumnType("nvarchar(max)"); - - b.Property("Descriptions") - .HasColumnType("nvarchar(max)"); - - b.Property("DisplayName") - .HasColumnType("nvarchar(max)"); - - b.Property("DisplayNames") - .HasColumnType("nvarchar(max)"); - - b.Property("Name") - .HasMaxLength(200) - .HasColumnType("nvarchar(200)"); - - b.Property("Properties") - .HasColumnType("nvarchar(max)"); - - b.Property("Resources") - .HasColumnType("nvarchar(max)"); - - b.HasKey("Id"); - - b.HasIndex("Name") - .IsUnique() - .HasFilter("[Name] IS NOT NULL"); - - b.ToTable("OpenIddictScopes", (string)null); - }); - - modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreToken", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("nvarchar(450)"); - - b.Property("ApplicationId") - .HasColumnType("nvarchar(450)"); - - b.Property("AuthorizationId") - .HasColumnType("nvarchar(450)"); - - b.Property("ConcurrencyToken") - .IsConcurrencyToken() - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.Property("CreationDate") - .HasColumnType("datetime2"); - - b.Property("ExpirationDate") - .HasColumnType("datetime2"); - - b.Property("Payload") - .HasColumnType("nvarchar(max)"); - - b.Property("Properties") - .HasColumnType("nvarchar(max)"); - - b.Property("RedemptionDate") - .HasColumnType("datetime2"); - - b.Property("ReferenceId") - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b.Property("Status") - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.Property("Subject") - .HasMaxLength(400) - .HasColumnType("nvarchar(400)"); - - b.Property("Type") - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.HasKey("Id"); - - b.HasIndex("AuthorizationId"); - - b.HasIndex("ReferenceId") - .IsUnique() - .HasFilter("[ReferenceId] IS NOT NULL"); - - b.HasIndex("ApplicationId", "Status", "Subject", "Type"); - - b.ToTable("OpenIddictTokens", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => - { - b.Property("Id") - .HasColumnType("nvarchar(450)"); - - b.Property("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("nvarchar(max)"); - - b.Property("Name") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.Property("NormalizedName") - .HasMaxLength(256) - .HasColumnType("nvarchar(256)"); - - b.HasKey("Id"); - - b.HasIndex("NormalizedName") - .IsUnique() - .HasDatabaseName("RoleNameIndex") - .HasFilter("[NormalizedName] IS NOT NULL"); - - b.ToTable("AspNetRoles", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("ClaimType") - .HasColumnType("nvarchar(max)"); - - b.Property("ClaimValue") - .HasColumnType("nvarchar(max)"); - - b.Property("RoleId") - .IsRequired() - .HasColumnType("nvarchar(450)"); - - b.HasKey("Id"); - - b.HasIndex("RoleId"); - - b.ToTable("AspNetRoleClaims", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); - - b.Property("ClaimType") - .HasColumnType("nvarchar(max)"); - - b.Property("ClaimValue") - .HasColumnType("nvarchar(max)"); - - b.Property("UserId") - .IsRequired() - .HasColumnType("nvarchar(450)"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AspNetUserClaims", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => - { - b.Property("LoginProvider") - .HasColumnType("nvarchar(450)"); - - b.Property("ProviderKey") - .HasColumnType("nvarchar(450)"); - - b.Property("ProviderDisplayName") - .HasColumnType("nvarchar(max)"); - - b.Property("UserId") - .IsRequired() - .HasColumnType("nvarchar(450)"); - - b.HasKey("LoginProvider", "ProviderKey"); - - b.HasIndex("UserId"); - - b.ToTable("AspNetUserLogins", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => - { - b.Property("UserId") - .HasColumnType("nvarchar(450)"); - - b.Property("RoleId") - .HasColumnType("nvarchar(450)"); - - b.HasKey("UserId", "RoleId"); - - b.HasIndex("RoleId"); - - b.ToTable("AspNetUserRoles", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => - { - b.Property("UserId") - .HasColumnType("nvarchar(450)"); - - b.Property("LoginProvider") - .HasColumnType("nvarchar(450)"); - - b.Property("Name") - .HasColumnType("nvarchar(450)"); - - b.Property("Value") - .HasColumnType("nvarchar(max)"); - - b.HasKey("UserId", "LoginProvider", "Name"); - - b.ToTable("AspNetUserTokens", (string)null); - }); - - modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", b => - { - b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.Device", "Device") - .WithOne("User") - .HasForeignKey("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", "DeviceId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Device"); - }); - - modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.Device", b => - { - b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.Identity", "Identity") - .WithMany("Devices") - .HasForeignKey("IdentityAddress") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Identity"); - }); - - modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcess", b => - { - b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.Identity", null) - .WithMany("DeletionProcesses") - .HasForeignKey("IdentityAddress"); - }); - - modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcessAuditLogEntry", b => - { - b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcess", null) - .WithMany("AuditLog") - .HasForeignKey("IdentityDeletionProcessId"); - }); - - modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreApplication", b => - { - b.HasOne("Backbone.Modules.Devices.Domain.Aggregates.Tier.Tier", null) - .WithMany() - .HasForeignKey("DefaultTier") - .OnDelete(DeleteBehavior.Restrict) - .IsRequired(); - }); - - modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreAuthorization", b => - { - b.HasOne("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreApplication", "Application") - .WithMany("Authorizations") - .HasForeignKey("ApplicationId"); - - b.Navigation("Application"); - }); - - modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreToken", b => - { - b.HasOne("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreApplication", "Application") - .WithMany("Tokens") - .HasForeignKey("ApplicationId"); - - b.HasOne("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreAuthorization", "Authorization") - .WithMany("Tokens") - .HasForeignKey("AuthorizationId"); - - b.Navigation("Application"); - - b.Navigation("Authorization"); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => - { - b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => - { - b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => - { - b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => - { - b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => - { - b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.Device", b => - { - b.Navigation("User") - .IsRequired(); - }); - - modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.Identity", b => - { - b.Navigation("DeletionProcesses"); - - b.Navigation("Devices"); - }); - - modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcess", b => - { - b.Navigation("AuditLog"); - }); - - modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreApplication", b => - { - b.Navigation("Authorizations"); - - b.Navigation("Tokens"); - }); - - modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreAuthorization", b => - { - b.Navigation("Tokens"); - }); -#pragma warning restore 612, 618 - } - } -} +// +using System; +using Backbone.Modules.Devices.Infrastructure.Persistence.Database; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Backbone.Modules.Devices.Infrastructure.Database.SqlServer.Migrations +{ + [DbContext(typeof(DevicesDbContext))] + partial class ApplicationDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.1") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Aggregates.PushNotifications.PnsRegistration", b => + { + b.Property("DeviceId") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.Property("AppId") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("DevicePushIdentifier") + .IsRequired() + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.Property("Environment") + .HasColumnType("int"); + + b.Property("Handle") + .IsRequired() + .HasMaxLength(200) + .IsUnicode(true) + .HasColumnType("nvarchar(200)") + .IsFixedLength(false); + + b.Property("IdentityAddress") + .IsRequired() + .HasMaxLength(36) + .IsUnicode(false) + .HasColumnType("char(36)") + .IsFixedLength(); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.HasKey("DeviceId"); + + b.ToTable("PnsRegistrations"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Aggregates.Tier.Tier", b => + { + b.Property("Id") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.Property("Name") + .IsRequired() + .HasMaxLength(30) + .IsUnicode(true) + .HasColumnType("nvarchar(30)") + .IsFixedLength(false); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("Tiers"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Challenge", b => + { + b.Property("Id") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.Property("ExpiresAt") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.ToTable("Challenges", "Challenges", t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", b => + { + b.Property("Id") + .HasColumnType("nvarchar(450)"); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeviceId") + .IsRequired() + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.Property("LastLoginAt") + .HasColumnType("datetime2"); + + b.Property("LockoutEnabled") + .HasColumnType("bit"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("PasswordHash") + .HasColumnType("nvarchar(max)"); + + b.Property("SecurityStamp") + .HasColumnType("nvarchar(max)"); + + b.Property("UserName") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.HasKey("Id"); + + b.HasIndex("DeviceId") + .IsUnique(); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex") + .HasFilter("[NormalizedUserName] IS NOT NULL"); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.Device", b => + { + b.Property("Id") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedByDevice") + .IsRequired() + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("DeletedByDevice") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.Property("IdentityAddress") + .IsRequired() + .HasMaxLength(36) + .IsUnicode(false) + .HasColumnType("char(36)") + .IsFixedLength(); + + b.HasKey("Id"); + + b.HasIndex("IdentityAddress"); + + b.ToTable("Devices"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.Identity", b => + { + b.Property("Address") + .HasMaxLength(36) + .IsUnicode(false) + .HasColumnType("char(36)") + .IsFixedLength(); + + b.Property("ClientId") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeletionGracePeriodEndsAt") + .HasColumnType("datetime2"); + + b.Property("IdentityVersion") + .HasColumnType("tinyint"); + + b.Property("PublicKey") + .IsRequired() + .HasColumnType("varbinary(max)"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("TierId") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.Property("TierIdBeforeDeletion") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.HasKey("Address"); + + b.ToTable("Identities"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcess", b => + { + b.Property("Id") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.Property("ApprovalReminder1SentAt") + .HasColumnType("datetime2"); + + b.Property("ApprovalReminder2SentAt") + .HasColumnType("datetime2"); + + b.Property("ApprovalReminder3SentAt") + .HasColumnType("datetime2"); + + b.Property("ApprovedAt") + .HasColumnType("datetime2"); + + b.Property("ApprovedByDevice") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.Property("CancelledAt") + .HasColumnType("datetime2"); + + b.Property("CancelledByDevice") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("GracePeriodEndsAt") + .HasColumnType("datetime2"); + + b.Property("GracePeriodReminder1SentAt") + .HasColumnType("datetime2"); + + b.Property("GracePeriodReminder2SentAt") + .HasColumnType("datetime2"); + + b.Property("GracePeriodReminder3SentAt") + .HasColumnType("datetime2"); + + b.Property("IdentityAddress") + .HasMaxLength(36) + .IsUnicode(false) + .HasColumnType("char(36)") + .IsFixedLength(); + + b.Property("Status") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("IdentityAddress"); + + b.ToTable("IdentityDeletionProcesses", (string)null); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcessAuditLogEntry", b => + { + b.Property("Id") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeviceIdHash") + .HasColumnType("varbinary(max)"); + + b.Property("IdentityAddressHash") + .IsRequired() + .HasColumnType("varbinary(max)"); + + b.Property("IdentityDeletionProcessId") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.Property("Message") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("NewStatus") + .HasColumnType("int"); + + b.Property("OldStatus") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("IdentityDeletionProcessId"); + + b.ToTable("IdentityDeletionProcessAuditLog", (string)null); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreApplication", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("nvarchar(450)"); + + b.Property("ApplicationType") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("ClientId") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("ClientSecret") + .HasColumnType("nvarchar(max)"); + + b.Property("ClientType") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("ConcurrencyToken") + .IsConcurrencyToken() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("ConsentType") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DefaultTier") + .IsRequired() + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.Property("DisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("DisplayNames") + .HasColumnType("nvarchar(max)"); + + b.Property("JsonWebKeySet") + .HasColumnType("nvarchar(max)"); + + b.Property("MaxIdentities") + .HasColumnType("int"); + + b.Property("Permissions") + .HasColumnType("nvarchar(max)"); + + b.Property("PostLogoutRedirectUris") + .HasColumnType("nvarchar(max)"); + + b.Property("Properties") + .HasColumnType("nvarchar(max)"); + + b.Property("RedirectUris") + .HasColumnType("nvarchar(max)"); + + b.Property("Requirements") + .HasColumnType("nvarchar(max)"); + + b.Property("Settings") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("ClientId") + .IsUnique() + .HasFilter("[ClientId] IS NOT NULL"); + + b.HasIndex("DefaultTier"); + + b.ToTable("OpenIddictApplications", (string)null); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreAuthorization", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("nvarchar(450)"); + + b.Property("ApplicationId") + .HasColumnType("nvarchar(450)"); + + b.Property("ConcurrencyToken") + .IsConcurrencyToken() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Properties") + .HasColumnType("nvarchar(max)"); + + b.Property("Scopes") + .HasColumnType("nvarchar(max)"); + + b.Property("Status") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Subject") + .HasMaxLength(400) + .HasColumnType("nvarchar(400)"); + + b.Property("Type") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.HasIndex("ApplicationId", "Status", "Subject", "Type"); + + b.ToTable("OpenIddictAuthorizations", (string)null); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreScope", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("nvarchar(450)"); + + b.Property("ConcurrencyToken") + .IsConcurrencyToken() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("Descriptions") + .HasColumnType("nvarchar(max)"); + + b.Property("DisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("DisplayNames") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("Properties") + .HasColumnType("nvarchar(max)"); + + b.Property("Resources") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique() + .HasFilter("[Name] IS NOT NULL"); + + b.ToTable("OpenIddictScopes", (string)null); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("nvarchar(450)"); + + b.Property("ApplicationId") + .HasColumnType("nvarchar(450)"); + + b.Property("AuthorizationId") + .HasColumnType("nvarchar(450)"); + + b.Property("ConcurrencyToken") + .IsConcurrencyToken() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("ExpirationDate") + .HasColumnType("datetime2"); + + b.Property("Payload") + .HasColumnType("nvarchar(max)"); + + b.Property("Properties") + .HasColumnType("nvarchar(max)"); + + b.Property("RedemptionDate") + .HasColumnType("datetime2"); + + b.Property("ReferenceId") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("Status") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Subject") + .HasMaxLength(400) + .HasColumnType("nvarchar(400)"); + + b.Property("Type") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.HasIndex("AuthorizationId"); + + b.HasIndex("ReferenceId") + .IsUnique() + .HasFilter("[ReferenceId] IS NOT NULL"); + + b.HasIndex("ApplicationId", "Status", "Subject", "Type"); + + b.ToTable("OpenIddictTokens", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("nvarchar(450)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex") + .HasFilter("[NormalizedName] IS NOT NULL"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderKey") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("nvarchar(450)"); + + b.Property("RoleId") + .HasColumnType("nvarchar(450)"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("nvarchar(450)"); + + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("Name") + .HasColumnType("nvarchar(450)"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.Device", "Device") + .WithOne("User") + .HasForeignKey("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", "DeviceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Device"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.Device", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.Identity", "Identity") + .WithMany("Devices") + .HasForeignKey("IdentityAddress") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Identity"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcess", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.Identity", null) + .WithMany("DeletionProcesses") + .HasForeignKey("IdentityAddress"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcessAuditLogEntry", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcess", null) + .WithMany("AuditLog") + .HasForeignKey("IdentityDeletionProcessId"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreApplication", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Aggregates.Tier.Tier", null) + .WithMany() + .HasForeignKey("DefaultTier") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreAuthorization", b => + { + b.HasOne("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreApplication", "Application") + .WithMany("Authorizations") + .HasForeignKey("ApplicationId"); + + b.Navigation("Application"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreToken", b => + { + b.HasOne("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreApplication", "Application") + .WithMany("Tokens") + .HasForeignKey("ApplicationId"); + + b.HasOne("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreAuthorization", "Authorization") + .WithMany("Tokens") + .HasForeignKey("AuthorizationId"); + + b.Navigation("Application"); + + b.Navigation("Authorization"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.Device", b => + { + b.Navigation("User") + .IsRequired(); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.Identity", b => + { + b.Navigation("DeletionProcesses"); + + b.Navigation("Devices"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcess", b => + { + b.Navigation("AuditLog"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreApplication", b => + { + b.Navigation("Authorizations"); + + b.Navigation("Tokens"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreAuthorization", b => + { + b.Navigation("Tokens"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Modules/Devices/test/Devices.Application.Tests/TestDataGenerator.cs b/Modules/Devices/test/Devices.Application.Tests/TestDataGenerator.cs index 221e7537c6..39a4a2826b 100644 --- a/Modules/Devices/test/Devices.Application.Tests/TestDataGenerator.cs +++ b/Modules/Devices/test/Devices.Application.Tests/TestDataGenerator.cs @@ -35,16 +35,14 @@ public static Identity CreateIdentityWithOneDevice() return identity; } - public static Identity CreateIdentityWithApprovedDeletionProcess(DateTime approvalDate) + public static Identity CreateIdentityWithApprovedDeletionProcess(DateTime? approvalDate = null) { - var currentDateTime = SystemTime.UtcNow; + approvalDate ??= SystemTime.UtcNow; var identity = CreateIdentityWithOneDevice(); - SystemTime.Set(approvalDate); + SystemTime.Set(approvalDate.Value); identity.StartDeletionProcessAsOwner(identity.Devices[0].Id); - SystemTime.Set(currentDateTime); - return identity; } diff --git a/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/CancelDeletionProcess/HandlerTests.cs b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/CancelDeletionProcess/HandlerTests.cs new file mode 100644 index 0000000000..08204f3020 --- /dev/null +++ b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/CancelDeletionProcess/HandlerTests.cs @@ -0,0 +1,70 @@ +using Backbone.BuildingBlocks.Application.Abstractions.Exceptions; +using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.UserContext; +using Backbone.Modules.Devices.Application.Identities.Commands.CancelDeletionProcess; +using Backbone.Modules.Devices.Application.Infrastructure.Persistence.Repository; +using Backbone.Modules.Devices.Domain.Entities.Identities; +using FakeItEasy; +using FluentAssertions; +using Xunit; +using static Backbone.UnitTestTools.Data.TestDataGenerator; + +namespace Backbone.Modules.Devices.Application.Tests.Tests.Identities.Commands.CancelDeletionProcess; +public class HandlerTests +{ + [Fact] + public async Task Happy_path() + { + // Arrange + var activeIdentity = TestDataGenerator.CreateIdentityWithApprovedDeletionProcess(); + var activeDevice = activeIdentity.Devices[0]; + var deletionProcess = activeIdentity.GetDeletionProcessInStatus(DeletionProcessStatus.Approved)!; + + var mockIdentitiesRepository = A.Fake(); + var fakeUserContext = A.Fake(); + + A.CallTo(() => mockIdentitiesRepository.FindByAddress(activeIdentity.Address, CancellationToken.None, A._)) + .Returns(activeIdentity); + A.CallTo(() => fakeUserContext.GetAddress()).Returns(activeIdentity.Address); + A.CallTo(() => fakeUserContext.GetDeviceId()).Returns(activeDevice.Id); + + var handler = CreateHandler(mockIdentitiesRepository, fakeUserContext); + var command = new CancelDeletionProcessCommand(deletionProcess.Id); + + // Act + var response = await handler.Handle(command, CancellationToken.None); + + // Assert + A.CallTo(() => mockIdentitiesRepository.Update(A.That.Matches(i => + i.Address == activeIdentity.Address + && i.Status == IdentityStatus.Active + && i.DeletionProcesses[0].Status == DeletionProcessStatus.Cancelled + && i.DeletionProcesses[0].Id == deletionProcess.Id), A._)) + .MustHaveHappenedOnceExactly(); + + response.Status.Should().Be(DeletionProcessStatus.Cancelled); + } + + [Fact] + public void Cannot_start_when_given_identity_does_not_exist() + { + // Arrange + var address = CreateRandomIdentityAddress(); + var fakeIdentitiesRepository = A.Fake(); + + A.CallTo(() => fakeIdentitiesRepository.FindByAddress(address, CancellationToken.None, A._)).Returns(null); + + var handler = CreateHandler(fakeIdentitiesRepository); + + // Act + var acting = async () => await handler.Handle(new CancelDeletionProcessCommand(address), CancellationToken.None); + + // Assert + acting.Should().ThrowAsync(); + } + + private static Handler CreateHandler(IIdentitiesRepository identitiesRepository, IUserContext? userContext = null) + { + userContext ??= A.Fake(); + return new Handler(identitiesRepository, userContext); + } +} diff --git a/Modules/Devices/test/Devices.Domain.Tests/Identities/ApproveDeletionProcessTests.cs b/Modules/Devices/test/Devices.Domain.Tests/Identities/ApproveDeletionProcessTests.cs index 430cfd0580..646a464640 100644 --- a/Modules/Devices/test/Devices.Domain.Tests/Identities/ApproveDeletionProcessTests.cs +++ b/Modules/Devices/test/Devices.Domain.Tests/Identities/ApproveDeletionProcessTests.cs @@ -49,7 +49,9 @@ public void Throws_when_deletion_process_is_not_in_status_waiting_for_approval() { // Arrange var identity = CreateIdentity(); - var deletionProcess = identity.StartDeletionProcessAsOwner(DeviceId.Parse("DVC")); + var activeDevice = new Device(identity); + identity.Devices.Add(activeDevice); + var deletionProcess = identity.StartDeletionProcessAsOwner(activeDevice.Id); // Act var acting = () => identity.ApproveDeletionProcess(deletionProcess.Id, DeviceId.Parse("DVC")); diff --git a/Modules/Devices/test/Devices.Domain.Tests/Identities/CancelDeletionProcessTests.cs b/Modules/Devices/test/Devices.Domain.Tests/Identities/CancelDeletionProcessTests.cs new file mode 100644 index 0000000000..25c5b28ab2 --- /dev/null +++ b/Modules/Devices/test/Devices.Domain.Tests/Identities/CancelDeletionProcessTests.cs @@ -0,0 +1,69 @@ +using Backbone.BuildingBlocks.Domain; +using Backbone.Modules.Devices.Domain.Entities.Identities; +using Backbone.Tooling; +using FluentAssertions; +using Xunit; + +namespace Backbone.Modules.Devices.Domain.Tests.Identities; +public class CancelDeletionProcessTests +{ + [Fact] + public void Cancel_deletion_process() + { + // Arrange + SystemTime.Set(DateTime.Parse("2024-01-01")); + var identity = TestDataGenerator.CreateIdentityWithApprovedDeletionProcess(); + var tierIdBeforeDeletion = identity.TierIdBeforeDeletion; + + // Act + var deletionProcess = identity.CancelDeletionProcess(identity.DeletionProcesses[0].Id, identity.Devices[0].Id); + + // Assert + identity.TierId.Should().Be(tierIdBeforeDeletion); + identity.TierIdBeforeDeletion.Should().Be(null); + identity.Status.Should().Be(IdentityStatus.Active); + deletionProcess.Status.Should().Be(DeletionProcessStatus.Cancelled); + deletionProcess.CancelledAt.Should().Be(DateTime.Parse("2024-01-01")); + deletionProcess.CancelledByDevice.Should().Be(identity.Devices[0].Id); + AssertAuditLogEntryWasCreated(deletionProcess); + } + + [Fact] + public void Throws_when_deletion_process_does_not_exist() + { + // Arrange + var identity = TestDataGenerator.CreateIdentity(); + identity.Devices.Add(new Device(identity)); + var deviceId = identity.Devices[0].Id; + var deletionProcessId = IdentityDeletionProcessId.Create("IDP00000000000000001").Value; + + // Act + var acting = () => identity.CancelDeletionProcess(deletionProcessId, deviceId); + + // Assert + acting.Should().Throw().Which.Message.Should().Contain("IdentityDeletionProcess"); + } + + [Fact] + public void Throws_when_deletion_process_is_in_wrong_status() + { + // Arrange + var identity = TestDataGenerator.CreateIdentityWithDeletionProcessWaitingForApproval(); + + // Act + var acting = () => identity.CancelDeletionProcess(identity.DeletionProcesses[0].Id, identity.Devices[0].Id); + + // Assert + acting.Should().Throw().Which.Code.Should().Be("error.platform.validation.device.noDeletionProcessWithRequiredStatusExists"); + } + + private static void AssertAuditLogEntryWasCreated(IdentityDeletionProcess deletionProcess) + { + deletionProcess.AuditLog.Should().HaveCount(2); + + var auditLogEntry = deletionProcess.AuditLog[1]; + auditLogEntry.ProcessId.Should().Be(deletionProcess.Id); + auditLogEntry.OldStatus.Should().Be(DeletionProcessStatus.Approved); + auditLogEntry.NewStatus.Should().Be(DeletionProcessStatus.Cancelled); + } +} diff --git a/Modules/Devices/test/Devices.Domain.Tests/Identities/DeletionGracePeriodReminderTests.cs b/Modules/Devices/test/Devices.Domain.Tests/Identities/DeletionGracePeriodReminderTests.cs index 9e372c464c..59aca9a4b9 100644 --- a/Modules/Devices/test/Devices.Domain.Tests/Identities/DeletionGracePeriodReminderTests.cs +++ b/Modules/Devices/test/Devices.Domain.Tests/Identities/DeletionGracePeriodReminderTests.cs @@ -121,8 +121,11 @@ private static void AssertAuditLogEntryWasCreated(IdentityDeletionProcess deleti private static Identity CreateIdentityWithApprovedDeletionProcess() { var identity = CreateIdentity(); - Hasher.SetHasher(new DummyHasher([1, 2, 3])); - identity.StartDeletionProcessAsOwner(new Device(identity).Id); + var device = new Device(identity); + identity.Devices.Add(device); + Hasher.SetHasher(new DummyHasher(new byte[] { 1, 2, 3 })); + + identity.StartDeletionProcessAsOwner(device.Id); return identity; } diff --git a/Modules/Devices/test/Devices.Domain.Tests/Identities/StartDeletionProcessAsOwnerTests.cs b/Modules/Devices/test/Devices.Domain.Tests/Identities/StartDeletionProcessAsOwnerTests.cs index d99434e7af..91ace6a70c 100644 --- a/Modules/Devices/test/Devices.Domain.Tests/Identities/StartDeletionProcessAsOwnerTests.cs +++ b/Modules/Devices/test/Devices.Domain.Tests/Identities/StartDeletionProcessAsOwnerTests.cs @@ -17,12 +17,13 @@ public void Start_deletion_process() // Arrange SystemTime.Set(DateTime.Parse("2000-01-01")); var activeIdentity = CreateIdentity(); - var activeDevice = DeviceId.Parse("DVC"); + var activeDevice = new Device(activeIdentity); + activeIdentity.Devices.Add(activeDevice); Hasher.SetHasher(new DummyHasher([1, 2, 3])); // Act - var deletionProcess = activeIdentity.StartDeletionProcessAsOwner(activeDevice); + var deletionProcess = activeIdentity.StartDeletionProcessAsOwner(activeDevice.Id); // Assert activeIdentity.DeletionGracePeriodEndsAt.Should().Be(DateTime.Parse("2000-01-31")); @@ -32,7 +33,7 @@ public void Start_deletion_process() AssertDeletionProcessWasStarted(activeIdentity); deletionProcess.Status.Should().Be(DeletionProcessStatus.Approved); deletionProcess.ApprovedAt.Should().Be(SystemTime.UtcNow); - deletionProcess.ApprovedByDevice.Should().Be(activeDevice); + deletionProcess.ApprovedByDevice.Should().Be(activeDevice.Id); deletionProcess.GracePeriodEndsAt.Should().Be(DateTime.Parse("2000-01-31")); AssertAuditLogEntryWasCreated(deletionProcess); @@ -42,17 +43,37 @@ public void Start_deletion_process() auditLogEntry.NewStatus.Should().Be(DeletionProcessStatus.Approved); } + [Fact] + public void Throws_when_device_not_owned_by_identity() + { + // Arrange + SystemTime.Set(DateTime.Parse("2020-01-01")); + var identity = TestDataGenerator.CreateIdentity(); + var device = new Device(identity); + + identity.Devices.Add(device); + + // Act + var acting = () => identity.StartDeletionProcessAsOwner(DeviceId.Parse("DVC")); + + // Assert + var exception = acting.Should().Throw().Which; + exception.Code.Should().Be("error.platform.recordNotFound"); + exception.Message.Should().Contain("Device"); + } + [Fact] public void Only_one_active_deletion_process_is_allowed_when_started() { // Arrange var activeIdentity = CreateIdentity(); - var activeDevice = DeviceId.Parse("DVC"); + var activeDevice = new Device(activeIdentity); + activeIdentity.Devices.Add(activeDevice); - activeIdentity.StartDeletionProcessAsOwner(activeDevice); + activeIdentity.StartDeletionProcessAsOwner(activeDevice.Id); // Act - var acting = () => activeIdentity.StartDeletionProcessAsOwner(activeDevice); + var acting = () => activeIdentity.StartDeletionProcessAsOwner(activeDevice.Id); // Assert acting.Should().Throw().Which.Code.Should().Be("error.platform.validation.device.onlyOneActiveDeletionProcessAllowed"); diff --git a/Modules/Devices/test/Devices.Domain.Tests/TestDataGenerator.cs b/Modules/Devices/test/Devices.Domain.Tests/TestDataGenerator.cs index ea212a927d..22b4bfcf10 100644 --- a/Modules/Devices/test/Devices.Domain.Tests/TestDataGenerator.cs +++ b/Modules/Devices/test/Devices.Domain.Tests/TestDataGenerator.cs @@ -1,5 +1,6 @@ using Backbone.Modules.Devices.Domain.Aggregates.Tier; using Backbone.Modules.Devices.Domain.Entities.Identities; +using Backbone.Modules.Devices.Domain.Tests.Identities.TestDoubles; using static Backbone.UnitTestTools.Data.TestDataGenerator; namespace Backbone.Modules.Devices.Domain.Tests; @@ -28,4 +29,22 @@ public static string GenerateString(int resultLength, char[]? chars = null) Random random = new(); return new string(Enumerable.Repeat(chars, resultLength).Select(s => s[random.Next(s.Length)]).ToArray()); } + + public static Identity CreateIdentityWithApprovedDeletionProcess() + { + var identity = CreateIdentity(); + var device = new Device(identity); + identity.Devices.Add(device); + identity.StartDeletionProcessAsOwner(device.Id); + return identity; + } + + public static Identity CreateIdentityWithDeletionProcessWaitingForApproval() + { + var identity = CreateIdentity(); + identity.Devices.Add(new Device(identity)); + Hasher.SetHasher(new DummyHasher([1, 2, 3])); + identity.StartDeletionProcessAsSupport(); + return identity; + } } From 08bddb164b21d740481688c26156cd9a0602a172 Mon Sep 17 00:00:00 2001 From: Timo Notheisen <65653426+tnotheis@users.noreply.github.com> Date: Wed, 6 Mar 2024 07:40:40 +0100 Subject: [PATCH 2/4] Remove SpecFlowCucumberResultsExporter (#549) --- .../AdminApi.Tests.Integration.csproj | 1 - .../AdminApi.Tests.Integration/Hooks/Hooks.cs | 16 -- .../AdminApi.Tests.Integration/specflow.json | 7 - Backbone.sln | 7 - .../EventArgs/FeatureEventArgs.cs | 15 -- .../EventArgs/ReportEventArgs.cs | 16 -- .../EventArgs/ScenarioEventArgs.cs | 15 -- .../EventArgs/StepEventArgs.cs | 15 -- .../Extensions/Exporter.cs | 20 -- .../Extensions/ExtensionMethods.cs | 90 ------- .../Extensions/JsonReporter.cs | 32 --- .../Extensions/ReportContractResolver.cs | 43 ---- .../Extensions/ReportingStepDefinitions.cs | 11 - .../ImplicitUsings.cs | 1 - .../Model/Embedding.cs | 18 -- .../Model/ExceptionData.cs | 34 --- .../Model/Feature.cs | 18 -- .../Model/Report.cs | 6 - .../Model/ReportItem.cs | 19 -- .../Model/Row.cs | 10 - .../Model/Scenario.cs | 8 - .../Model/Step.cs | 19 -- .../Model/StepResult.cs | 13 - .../Model/TableParam.cs | 27 -- .../Model/TaggedReportItem.cs | 11 - .../Model/TestResult.cs | 10 - .../Reporting/Reporter.cs | 36 --- .../Reporting/Reporters.Events.cs | 76 ------ .../Reporting/Reporters.SpecFlowHooks.cs | 178 ------------- .../Reporting/Reporters.cs | 240 ------------------ .../SpecFlowCucumberResultsExporter.csproj | 21 -- .../ConsumerApi.Tests.Integration.csproj | 1 - ConsumerApi.Tests.Integration/Hooks/Hooks.cs | 13 - ConsumerApi.Tests.Integration/specflow.json | 7 - 34 files changed, 1054 deletions(-) delete mode 100644 AdminApi/test/AdminApi.Tests.Integration/Hooks/Hooks.cs delete mode 100644 AdminApi/test/AdminApi.Tests.Integration/specflow.json delete mode 100644 BuildingBlocks/src/SpecFlowCucumberResultsExporter/EventArgs/FeatureEventArgs.cs delete mode 100644 BuildingBlocks/src/SpecFlowCucumberResultsExporter/EventArgs/ReportEventArgs.cs delete mode 100644 BuildingBlocks/src/SpecFlowCucumberResultsExporter/EventArgs/ScenarioEventArgs.cs delete mode 100644 BuildingBlocks/src/SpecFlowCucumberResultsExporter/EventArgs/StepEventArgs.cs delete mode 100644 BuildingBlocks/src/SpecFlowCucumberResultsExporter/Extensions/Exporter.cs delete mode 100644 BuildingBlocks/src/SpecFlowCucumberResultsExporter/Extensions/ExtensionMethods.cs delete mode 100644 BuildingBlocks/src/SpecFlowCucumberResultsExporter/Extensions/JsonReporter.cs delete mode 100644 BuildingBlocks/src/SpecFlowCucumberResultsExporter/Extensions/ReportContractResolver.cs delete mode 100644 BuildingBlocks/src/SpecFlowCucumberResultsExporter/Extensions/ReportingStepDefinitions.cs delete mode 100644 BuildingBlocks/src/SpecFlowCucumberResultsExporter/ImplicitUsings.cs delete mode 100644 BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/Embedding.cs delete mode 100644 BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/ExceptionData.cs delete mode 100644 BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/Feature.cs delete mode 100644 BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/Report.cs delete mode 100644 BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/ReportItem.cs delete mode 100644 BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/Row.cs delete mode 100644 BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/Scenario.cs delete mode 100644 BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/Step.cs delete mode 100644 BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/StepResult.cs delete mode 100644 BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/TableParam.cs delete mode 100644 BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/TaggedReportItem.cs delete mode 100644 BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/TestResult.cs delete mode 100644 BuildingBlocks/src/SpecFlowCucumberResultsExporter/Reporting/Reporter.cs delete mode 100644 BuildingBlocks/src/SpecFlowCucumberResultsExporter/Reporting/Reporters.Events.cs delete mode 100644 BuildingBlocks/src/SpecFlowCucumberResultsExporter/Reporting/Reporters.SpecFlowHooks.cs delete mode 100644 BuildingBlocks/src/SpecFlowCucumberResultsExporter/Reporting/Reporters.cs delete mode 100644 BuildingBlocks/src/SpecFlowCucumberResultsExporter/SpecFlowCucumberResultsExporter.csproj delete mode 100644 ConsumerApi.Tests.Integration/Hooks/Hooks.cs delete mode 100644 ConsumerApi.Tests.Integration/specflow.json diff --git a/AdminApi/test/AdminApi.Tests.Integration/AdminApi.Tests.Integration.csproj b/AdminApi/test/AdminApi.Tests.Integration/AdminApi.Tests.Integration.csproj index e1ab985c5f..a87db86baa 100644 --- a/AdminApi/test/AdminApi.Tests.Integration/AdminApi.Tests.Integration.csproj +++ b/AdminApi/test/AdminApi.Tests.Integration/AdminApi.Tests.Integration.csproj @@ -22,7 +22,6 @@ - diff --git a/AdminApi/test/AdminApi.Tests.Integration/Hooks/Hooks.cs b/AdminApi/test/AdminApi.Tests.Integration/Hooks/Hooks.cs deleted file mode 100644 index 8651580ce8..0000000000 --- a/AdminApi/test/AdminApi.Tests.Integration/Hooks/Hooks.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Backbone.SpecFlowCucumberResultsExporter.Extensions; - -namespace Backbone.AdminApi.Tests.Integration.Hooks; - -[Binding] -public sealed class Hooks -{ - // For additional details on SpecFlow hooks see http://go.specflow.org/doc-hooks - - [BeforeTestRun(Order = 0)] - public static void BeforeTestRun() - { - // Export test results to cucumber format - Exporter.ExportToCucumber(); - } -} diff --git a/AdminApi/test/AdminApi.Tests.Integration/specflow.json b/AdminApi/test/AdminApi.Tests.Integration/specflow.json deleted file mode 100644 index 9bd535cd7d..0000000000 --- a/AdminApi/test/AdminApi.Tests.Integration/specflow.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "stepAssemblies": [ - { - "assembly": "Backbone.SpecFlowCucumberResultsExporter" - } - ] -} diff --git a/Backbone.sln b/Backbone.sln index d3bd5b40a0..6c88db2fbf 100644 --- a/Backbone.sln +++ b/Backbone.sln @@ -191,8 +191,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Devices.Infrastructure.Test EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Devices.AdminCli", "Modules\Devices\src\Devices.AdminCli\Devices.AdminCli.csproj", "{E7B3FFFA-3B6B-45F9-BFD0-0D3344AF979F}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SpecFlowCucumberResultsExporter", "BuildingBlocks\src\SpecFlowCucumberResultsExporter\SpecFlowCucumberResultsExporter.csproj", "{5CD9D570-BC18-47F3-8646-15EC5C7B70AB}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Files.Jobs.SanityCheck", "Modules\Files\src\Files.Jobs.SanityCheck\Files.Jobs.SanityCheck.csproj", "{1BB56A85-74F8-497F-983C-274D51B25CF4}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Files.Jobs.SanityCheck.Tests", "Modules\Files\test\Files.Jobs.SanityCheck.Tests\Files.Jobs.SanityCheck.Tests.csproj", "{6289332A-DBF2-4B99-BEFB-AC01A4C9D262}" @@ -535,10 +533,6 @@ Global {E7B3FFFA-3B6B-45F9-BFD0-0D3344AF979F}.Debug|Any CPU.Build.0 = Debug|Any CPU {E7B3FFFA-3B6B-45F9-BFD0-0D3344AF979F}.Release|Any CPU.ActiveCfg = Release|Any CPU {E7B3FFFA-3B6B-45F9-BFD0-0D3344AF979F}.Release|Any CPU.Build.0 = Release|Any CPU - {5CD9D570-BC18-47F3-8646-15EC5C7B70AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5CD9D570-BC18-47F3-8646-15EC5C7B70AB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5CD9D570-BC18-47F3-8646-15EC5C7B70AB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5CD9D570-BC18-47F3-8646-15EC5C7B70AB}.Release|Any CPU.Build.0 = Release|Any CPU {1BB56A85-74F8-497F-983C-274D51B25CF4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {1BB56A85-74F8-497F-983C-274D51B25CF4}.Debug|Any CPU.Build.0 = Debug|Any CPU {1BB56A85-74F8-497F-983C-274D51B25CF4}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -745,7 +739,6 @@ Global {40F14114-44B0-4EE0-A653-6C8205F6F28C} = {F31B1655-A11B-4F30-9BC7-7418B8B915D7} {19BE44FE-8852-40DD-AE70-EFA8B1E28730} = {F31B1655-A11B-4F30-9BC7-7418B8B915D7} {E7B3FFFA-3B6B-45F9-BFD0-0D3344AF979F} = {AAE79377-8414-4C23-BF0C-678B68A24BC7} - {5CD9D570-BC18-47F3-8646-15EC5C7B70AB} = {06D714AE-EDF4-421C-9340-EDA6FCDF491F} {1BB56A85-74F8-497F-983C-274D51B25CF4} = {3D324161-C287-4DC0-A9FD-FA3B1A6643FD} {6289332A-DBF2-4B99-BEFB-AC01A4C9D262} = {2D0BC8E9-ED6B-49D9-937C-1616ED40FB3E} {360430CE-6850-4A67-88ED-E9508B7D2658} = {06D714AE-EDF4-421C-9340-EDA6FCDF491F} diff --git a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/EventArgs/FeatureEventArgs.cs b/BuildingBlocks/src/SpecFlowCucumberResultsExporter/EventArgs/FeatureEventArgs.cs deleted file mode 100644 index 256e179040..0000000000 --- a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/EventArgs/FeatureEventArgs.cs +++ /dev/null @@ -1,15 +0,0 @@ -using Backbone.SpecFlowCucumberResultsExporter.Model; -using Backbone.SpecFlowCucumberResultsExporter.Reporting; - -namespace Backbone.SpecFlowCucumberResultsExporter.EventArgs; - -public class FeatureEventArgs : ReportEventArgs -{ - public FeatureEventArgs(Reporter reporter) - : base(reporter) - { - Feature = Reporter.CurrentFeature; - } - - public Feature Feature { get; internal set; } -} diff --git a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/EventArgs/ReportEventArgs.cs b/BuildingBlocks/src/SpecFlowCucumberResultsExporter/EventArgs/ReportEventArgs.cs deleted file mode 100644 index 59f3b798b5..0000000000 --- a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/EventArgs/ReportEventArgs.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Backbone.SpecFlowCucumberResultsExporter.Model; -using Backbone.SpecFlowCucumberResultsExporter.Reporting; - -namespace Backbone.SpecFlowCucumberResultsExporter.EventArgs; - -public class ReportEventArgs : System.EventArgs -{ - public ReportEventArgs(Reporter reporter) - { - Reporter = reporter; - Report = reporter.Report; - } - - public Reporter Reporter { get; internal set; } - public Report Report { get; internal set; } -} diff --git a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/EventArgs/ScenarioEventArgs.cs b/BuildingBlocks/src/SpecFlowCucumberResultsExporter/EventArgs/ScenarioEventArgs.cs deleted file mode 100644 index 45f5a9e5d4..0000000000 --- a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/EventArgs/ScenarioEventArgs.cs +++ /dev/null @@ -1,15 +0,0 @@ -using Backbone.SpecFlowCucumberResultsExporter.Model; -using Backbone.SpecFlowCucumberResultsExporter.Reporting; - -namespace Backbone.SpecFlowCucumberResultsExporter.EventArgs; - -public class ScenarioEventArgs : FeatureEventArgs -{ - public ScenarioEventArgs(Reporter reporter) - : base(reporter) - { - Scenario = Reporter.CurrentScenario; - } - - public Scenario Scenario { get; internal set; } -} diff --git a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/EventArgs/StepEventArgs.cs b/BuildingBlocks/src/SpecFlowCucumberResultsExporter/EventArgs/StepEventArgs.cs deleted file mode 100644 index 335d47e8ff..0000000000 --- a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/EventArgs/StepEventArgs.cs +++ /dev/null @@ -1,15 +0,0 @@ -using Backbone.SpecFlowCucumberResultsExporter.Model; -using Backbone.SpecFlowCucumberResultsExporter.Reporting; - -namespace Backbone.SpecFlowCucumberResultsExporter.EventArgs; - -public class StepEventArgs : ScenarioEventArgs -{ - public StepEventArgs(Reporter reporter) - : base(reporter) - { - Step = reporter.CurrentStep; - } - - public Step Step { get; internal set; } -} diff --git a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Extensions/Exporter.cs b/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Extensions/Exporter.cs deleted file mode 100644 index 1f3276d717..0000000000 --- a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Extensions/Exporter.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Backbone.SpecFlowCucumberResultsExporter.Reporting; - -namespace Backbone.SpecFlowCucumberResultsExporter.Extensions; -public class Exporter : ReportingStepDefinitions -{ - public static void ExportToCucumber(string path = default, string fileName = default) - { - path ??= "../../../TestResults/"; - fileName ??= $"specflow_cucumber_{DateTimeOffset.UtcNow:yyyyMMdd}.json"; - - Reporters.Add(new JsonReporter()); - - Reporters.FinishedReport += (_, args) => - { - var file = new FileInfo(Path.Combine(path, fileName)); - file.Directory?.Create(); - File.WriteAllText(file.FullName, args.Reporter.WriteToString()); - }; - } -} diff --git a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Extensions/ExtensionMethods.cs b/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Extensions/ExtensionMethods.cs deleted file mode 100644 index edd65fd59d..0000000000 --- a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Extensions/ExtensionMethods.cs +++ /dev/null @@ -1,90 +0,0 @@ -using System.Reflection; -using Backbone.SpecFlowCucumberResultsExporter.Model; - -namespace Backbone.SpecFlowCucumberResultsExporter.Extensions; - -public static class Extensions -{ - public static TestResult GetResult(this IEnumerable items) - { - return items.Select(x => x.Result).GetResult(); - } - - public static TestResult GetResult(this IEnumerable results) - { - var testResults = results as TestResult[] ?? results.ToArray(); - if (testResults.Any(x => x == TestResult.Failed)) - { - return TestResult.Failed; - } - - if (testResults.Any(x => x == TestResult.Pending)) - { - return TestResult.Pending; - } - - if (testResults.Any(x => x == TestResult.Skipped)) - { - return TestResult.Skipped; - } - - if (testResults.Any(x => x == TestResult.Undefined)) - { - return TestResult.Undefined; - } - - return TestResult.Passed; - } - - internal static TestResult ToTestResult(this ScenarioExecutionStatus executionStatus) - { - switch (executionStatus) - { - case ScenarioExecutionStatus.OK: - return TestResult.Passed; - case ScenarioExecutionStatus.StepDefinitionPending: - return TestResult.Pending; - case ScenarioExecutionStatus.TestError: - return TestResult.Failed; - default: - return TestResult.Undefined; - } - } - - internal static IEnumerable GetPendingSteps(this ScenarioContext scenarioContext) - { - return typeof(ScenarioContext) - .GetProperty("PendingSteps", BindingFlags.NonPublic | BindingFlags.Instance)! - .GetValue(scenarioContext, null) as IEnumerable - ?? []; - } - - internal static string ReplaceFirst(this string s, string find, string replace) - { - var first = s.IndexOf(find, StringComparison.Ordinal); - return s[..first] + replace + s[(first + find.Length)..]; - } - - internal static string GetParamName(this MethodInfo method, int index) - { - var retVal = string.Empty; - - if (method != null && method.GetParameters().Length > index) - { - retVal = method.GetParameters()[index].Name; - } - - - return retVal; - } - - internal static ExceptionInfo ToExceptionInfo(this Exception ex) - { - if (ex == null) - { - return null; - } - - return new ExceptionInfo(ex); - } -} diff --git a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Extensions/JsonReporter.cs b/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Extensions/JsonReporter.cs deleted file mode 100644 index 40047d6063..0000000000 --- a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Extensions/JsonReporter.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System.Text; -using Backbone.SpecFlowCucumberResultsExporter.Reporting; -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; - -namespace Backbone.SpecFlowCucumberResultsExporter.Extensions; - -public class JsonReporter : Reporter -{ - public JsonSerializerSettings JsonSerializerSettings { get; set; } - - public JsonReporter() - { - var list = new JsonConverter[] { new StringEnumConverter() }.ToList(); - - JsonSerializerSettings = new JsonSerializerSettings - { - Formatting = Formatting.Indented, - ContractResolver = new ReportContractResolver(), - NullValueHandling = NullValueHandling.Ignore, - Converters = list - }; - } - - public override void WriteToStream(Stream stream) - { - var s = JsonConvert.SerializeObject(Report.Features, JsonSerializerSettings); - var bytes = Encoding.UTF8.GetBytes(s); - using var memoryStream = new MemoryStream(bytes); - memoryStream.CopyTo(stream); - } -} diff --git a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Extensions/ReportContractResolver.cs b/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Extensions/ReportContractResolver.cs deleted file mode 100644 index 3df25a93cd..0000000000 --- a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Extensions/ReportContractResolver.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System.Text; -using Newtonsoft.Json; -using Newtonsoft.Json.Serialization; - -namespace Backbone.SpecFlowCucumberResultsExporter.Extensions; - -public class ReportContractResolver : DefaultContractResolver -{ - protected override IList CreateProperties(Type type, MemberSerialization memberSerialization) - { - var properties = base.CreateProperties(type, memberSerialization); - - foreach (var property in properties) - { - property.PropertyName = ConvertPropertyName(property.PropertyName); - } - - return properties; - } - - private string ConvertPropertyName(string name) - { - var result = new StringBuilder(); - - for (var i = 0; i < name.Length; i++) - { - var c = name[i]; - if (char.IsUpper(c)) - { - if (i > 0) - { - result.Append('_'); - } - result.Append(c.ToString().ToLower()); - } - else - { - result.Append(c); - } - } - return result.ToString(); - } -} diff --git a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Extensions/ReportingStepDefinitions.cs b/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Extensions/ReportingStepDefinitions.cs deleted file mode 100644 index df5f9c4f0e..0000000000 --- a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Extensions/ReportingStepDefinitions.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Backbone.SpecFlowCucumberResultsExporter.Reporting; - -namespace Backbone.SpecFlowCucumberResultsExporter.Extensions; - -public abstract class ReportingStepDefinitions : ContextBoundObject -{ - public async Task ReportStep(ScenarioContext scenarioContext, Func stepFunc, params object[] args) - { - await Reporters.ExecuteStep(scenarioContext, stepFunc, args); - } -} diff --git a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/ImplicitUsings.cs b/BuildingBlocks/src/SpecFlowCucumberResultsExporter/ImplicitUsings.cs deleted file mode 100644 index a25a2a1d36..0000000000 --- a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/ImplicitUsings.cs +++ /dev/null @@ -1 +0,0 @@ -global using TechTalk.SpecFlow; diff --git a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/Embedding.cs b/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/Embedding.cs deleted file mode 100644 index 0872fe070f..0000000000 --- a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/Embedding.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Newtonsoft.Json; - -namespace Backbone.SpecFlowCucumberResultsExporter.Model; - -public class Embedding -{ - public Embedding(string mimeType, string base64data) - { - MimeType = mimeType; - Base64Data = base64data; - } - - [JsonProperty("mime_type")] - public string MimeType { get; set; } - - [JsonProperty("data")] - public string Base64Data { get; set; } -} diff --git a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/ExceptionData.cs b/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/ExceptionData.cs deleted file mode 100644 index e2d16cf32a..0000000000 --- a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/ExceptionData.cs +++ /dev/null @@ -1,34 +0,0 @@ -using Backbone.SpecFlowCucumberResultsExporter.Extensions; - -namespace Backbone.SpecFlowCucumberResultsExporter.Model; - -/// -/// Contains the information about an . -/// -/// -/// Exceptions are not serializable to xml, due to the -/// IDictionary Data property. That's why this class is used -/// -public class ExceptionInfo -{ - public ExceptionInfo() - { - } - - public ExceptionInfo(Exception ex) - { - ExceptionType = ex.GetType().FullName; - HelpLink = ex.HelpLink; - InnerException = ex.InnerException.ToExceptionInfo(); - Message = ex.Message; - Source = ex.Source; - StackTrace = ex.StackTrace; - } - - public string ExceptionType { get; set; } - public string HelpLink { get; set; } - public ExceptionInfo InnerException { get; set; } - public string Message { get; set; } - public string Source { get; set; } - public string StackTrace { get; set; } -} diff --git a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/Feature.cs b/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/Feature.cs deleted file mode 100644 index aa41dab030..0000000000 --- a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/Feature.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace Backbone.SpecFlowCucumberResultsExporter.Model; - -public class Feature : TaggedReportItem -{ - private string _description; - - private const string DEFAULT_URI = "/uri/placeholder"; - - public new string Description - { - get => _description; - set => _description = string.IsNullOrEmpty(value) ? value : value.Replace("\r", ""); - } - public string Uri { get; set; } = DEFAULT_URI; - - public List Elements { get; set; } - public new string Keyword => "Feature"; -} diff --git a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/Report.cs b/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/Report.cs deleted file mode 100644 index 37a11ad4d0..0000000000 --- a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/Report.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Backbone.SpecFlowCucumberResultsExporter.Model; - -public class Report : ReportItem -{ - public List Features { get; set; } -} diff --git a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/ReportItem.cs b/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/ReportItem.cs deleted file mode 100644 index 9be6ade8b7..0000000000 --- a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/ReportItem.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Newtonsoft.Json; - -namespace Backbone.SpecFlowCucumberResultsExporter.Model; - -public abstract class ReportItem -{ - public static readonly int LINE_FILLER = 0; - public string Name { get; set; } - public string Id { get; set; } - public string Description { get; set; } - [JsonIgnore] - public DateTime StartTime { get; set; } - [JsonIgnore] - public DateTime EndTime { get; set; } - public virtual TestResult Result { get; set; } - public int Line => LINE_FILLER; - public string Keyword { get; set; } - -} diff --git a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/Row.cs b/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/Row.cs deleted file mode 100644 index a5b77b19e6..0000000000 --- a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/Row.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Backbone.SpecFlowCucumberResultsExporter.Model; - -public class Row -{ - public static readonly int LINE_FILLER = 0; - - public List Cells { get; set; } - - public int Line => LINE_FILLER; -} diff --git a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/Scenario.cs b/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/Scenario.cs deleted file mode 100644 index ffce9d8f11..0000000000 --- a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/Scenario.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Backbone.SpecFlowCucumberResultsExporter.Model; - -public class Scenario : TaggedReportItem -{ - public List Steps { get; set; } - public new string Keyword => "Scenario"; - public string Type => "scenario"; -} diff --git a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/Step.cs b/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/Step.cs deleted file mode 100644 index c1527edf60..0000000000 --- a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/Step.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Newtonsoft.Json; - -namespace Backbone.SpecFlowCucumberResultsExporter.Model; - -public class Step : ReportItem -{ - public string MultiLineParameter { get; set; } - public ExceptionInfo Exception { get; set; } - public new StepResult Result { get; set; } - public List Rows { get; set; } - - [JsonProperty("embeddings")] - public List Embeddings { get; set; } = []; - - public void AddEmbedding(string mimeType, string base64data) - { - Embeddings.Add(new Embedding(mimeType, base64data)); - } -} diff --git a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/StepResult.cs b/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/StepResult.cs deleted file mode 100644 index 99593dbec9..0000000000 --- a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/StepResult.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Newtonsoft.Json; - -namespace Backbone.SpecFlowCucumberResultsExporter.Model; - -public class StepResult -{ - public long Duration { get; set; } - - public TestResult Status { get; set; } - - [JsonProperty("error_message")] - public string Error { get; set; } -} diff --git a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/TableParam.cs b/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/TableParam.cs deleted file mode 100644 index df78e1c1d6..0000000000 --- a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/TableParam.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Xml.Serialization; - -namespace Backbone.SpecFlowCucumberResultsExporter.Model; - -public class TableParam -{ - public List Columns { get; set; } - - [XmlIgnore] - public List> Rows { get; set; } - - public int GetMaxColumnCharacters(int columnIndex) - { - var result = 0; - foreach (var row in Rows) - { - foreach (var value in row.Values) - { - if (value.Length > result) - { - result = value.Length; - } - } - } - return result; - } -} diff --git a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/TaggedReportItem.cs b/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/TaggedReportItem.cs deleted file mode 100644 index 356114d8ee..0000000000 --- a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/TaggedReportItem.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Backbone.SpecFlowCucumberResultsExporter.Model; - -public class Tag : ReportItem -{ - public new string Name { get; set; } -} - -public class TaggedReportItem : ReportItem -{ - public List Tags { get; set; } -} diff --git a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/TestResult.cs b/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/TestResult.cs deleted file mode 100644 index f970fc1d5b..0000000000 --- a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Model/TestResult.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Backbone.SpecFlowCucumberResultsExporter.Model; - -public enum TestResult -{ - Undefined = 0, - Passed, - Failed, - Skipped, - Pending -} diff --git a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Reporting/Reporter.cs b/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Reporting/Reporter.cs deleted file mode 100644 index 8a696bd1fe..0000000000 --- a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Reporting/Reporter.cs +++ /dev/null @@ -1,36 +0,0 @@ -using Backbone.SpecFlowCucumberResultsExporter.Model; - -namespace Backbone.SpecFlowCucumberResultsExporter.Reporting; - -public abstract class Reporter -{ - public Feature CurrentFeature { get; internal set; } - - public Scenario CurrentScenario { get; internal set; } - - public Step CurrentStep { get; internal set; } - - public virtual string Name => GetType().FullName!; - - public Report Report { get; set; } - - public virtual void WriteToFile(string path) - { - using var memoryStream = new MemoryStream(); - WriteToStream(memoryStream); - memoryStream.Seek(0L, SeekOrigin.Begin); - using var destination = File.Create(path); - memoryStream.CopyTo(destination); - } - - public abstract void WriteToStream(Stream stream); - - public string WriteToString() - { - using var memoryStream = new MemoryStream(); - WriteToStream(memoryStream); - memoryStream.Position = 0L; - using var streamReader = new StreamReader(memoryStream); - return streamReader.ReadToEnd(); - } -} diff --git a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Reporting/Reporters.Events.cs b/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Reporting/Reporters.Events.cs deleted file mode 100644 index e182188d18..0000000000 --- a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Reporting/Reporters.Events.cs +++ /dev/null @@ -1,76 +0,0 @@ -using Backbone.SpecFlowCucumberResultsExporter.EventArgs; - -namespace Backbone.SpecFlowCucumberResultsExporter.Reporting; - -public partial class Reporters -{ - #region Events - - public static event EventHandler StartedReport; - - public static event EventHandler FinishedReport; - - public static event EventHandler StartedFeature; - - public static event EventHandler FinishedFeature; - - public static event EventHandler StartedScenario; - - public static event EventHandler FinishedScenario; - - public static event EventHandler StartedStep; - - public static event EventHandler FinishedStep; - - #endregion Events - - #region Event Raising - - internal static void OnStartedReport(Reporter reporter) - { - RaiseEvent(StartedReport, new ReportEventArgs(reporter)); - } - - internal static void OnFinishedReport(Reporter reporter) - { - RaiseEvent(FinishedReport, new ReportEventArgs(reporter)); - } - - internal static void OnStartedFeature(Reporter reporter) - { - RaiseEvent(StartedFeature, new FeatureEventArgs(reporter)); - } - - internal static void OnFinishedFeature(Reporter reporter) - { - RaiseEvent(FinishedFeature, new FeatureEventArgs(reporter)); - } - - internal static void OnStartedScenario(Reporter reporter) - { - RaiseEvent(StartedScenario, new ScenarioEventArgs(reporter)); - } - - internal static void OnFinishedScenario(Reporter reporter) - { - RaiseEvent(FinishedScenario, new ScenarioEventArgs(reporter)); - } - - internal static void OnStartedStep(Reporter reporter) - { - RaiseEvent(StartedStep, new StepEventArgs(reporter)); - } - - internal static void OnFinishedStep(Reporter reporter) - { - RaiseEvent(FinishedStep, new StepEventArgs(reporter)); - } - - private static void RaiseEvent(EventHandler handler, T args) - where T : ReportEventArgs - { - handler?.Invoke(null, args); - } - - #endregion Event Raising -} diff --git a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Reporting/Reporters.SpecFlowHooks.cs b/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Reporting/Reporters.SpecFlowHooks.cs deleted file mode 100644 index abb8df6793..0000000000 --- a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Reporting/Reporters.SpecFlowHooks.cs +++ /dev/null @@ -1,178 +0,0 @@ -using Backbone.SpecFlowCucumberResultsExporter.Extensions; -using Backbone.SpecFlowCucumberResultsExporter.Model; - -namespace Backbone.SpecFlowCucumberResultsExporter.Reporting; - -public partial class Reporters -{ - private static bool _testRunIsFirstFeature; - - [AfterFeature] - internal static void AfterFeature() - { - foreach (var reporter in REPORTERS) - { - var feature = reporter.CurrentFeature; - - var scenarioOutlineGroups = feature!.Elements.GroupBy(scenario => scenario.Name) - .Where((scenarioGrp, _) => scenarioGrp.Count() > 1) - .Select((scenarioGrp, _) => scenarioGrp.ToList()); - - foreach (var scenarioOutlineGroup in scenarioOutlineGroups) - { - for (var i = 0; i < scenarioOutlineGroup.Count; i++) - { - scenarioOutlineGroup[i].Name = $"{scenarioOutlineGroup[i].Name} (example {i + 1})"; - } - } - - feature.Result = feature.Elements.Exists(o => o.Result == TestResult.Failed) - ? TestResult.Failed - : TestResult.Passed; - - feature.EndTime = CurrentRunTime; - OnFinishedFeature(reporter); - reporter.CurrentFeature = null; - } - } - - [AfterScenario] - internal static void AfterScenario() - { - foreach (var reporter in REPORTERS.ToArray()) - { - var scenario = reporter.CurrentScenario; - scenario!.EndTime = CurrentRunTime; - scenario.Result = scenario.Steps.Exists(o => o.Result.Status == TestResult.Failed) - ? TestResult.Failed - : TestResult.Passed; - OnFinishedScenario(reporter); - reporter.CurrentScenario = null; - } - } - - [AfterTestRun] - internal static void AfterTestRun() - { - foreach (var reporter in REPORTERS) - { - reporter.Report.EndTime = CurrentRunTime; - OnFinishedReport(reporter); - } - } - - [AfterStep] - internal static void AfterStep(ScenarioContext scenarioContext) - { - var endTime = CurrentRunTime; - var result = scenarioContext.ScenarioExecutionStatus.ToTestResult(); - var error = scenarioContext.TestError?.ToExceptionInfo().Message; - error = error == null && result == TestResult.Pending ? new PendingStepException().ToExceptionInfo().Message : string.Empty; - - foreach (var reporter in REPORTERS.ToArray()) - { - var step = reporter.CurrentStep; - step!.EndTime = CurrentRunTime; - step.Result = new StepResult - { - Duration = (long)((endTime - reporter.CurrentStep!.StartTime).TotalMilliseconds * 1000000), - Status = result, - Error = error - }; - OnFinishedStep(reporter); - reporter.CurrentStep = null; - } - } - - - [BeforeFeature] - internal static void BeforeFeature(FeatureContext featureContext) - { - var startTime = CurrentRunTime; - - // Init reports when the first feature runs. This is intentionally not done in - // BeforeTestRun(), to make sure other [BeforeTestRun] annotated methods can perform - // initialization before the reports are created. - if (_testRunIsFirstFeature) - { - foreach (var reporter in REPORTERS) - { - reporter.Report = new Report - { - Features = [], - StartTime = startTime - }; - - OnStartedReport(reporter); - } - - _testRunIsFirstFeature = false; - } - - foreach (var reporter in REPORTERS) - { - var featureId = featureContext.FeatureInfo.Title.Replace(" ", "-").ToLower(); - var feature = new Feature - { - Tags = featureContext.FeatureInfo.Tags.Select(tag => new Tag() { Name = "@" + tag }).ToList(), - Elements = [], - StartTime = startTime, - Name = featureContext.FeatureInfo.Title, - Description = featureContext.FeatureInfo.Description, - Id = featureId, - Uri = $"/{featureId}" - }; - - reporter.Report.Features.Add(feature); - reporter.CurrentFeature = feature; - - OnStartedFeature(reporter); - } - } - - [BeforeScenario] - internal static void BeforeScenario(ScenarioContext scenarioContext) - { - var startTime = CurrentRunTime; - - foreach (var reporter in REPORTERS) - { - var scenario = new Scenario - { - Tags = scenarioContext.ScenarioInfo.Tags.Select(tag => new Tag() { Name = "@" + tag }).ToList(), - StartTime = startTime, - Name = scenarioContext.ScenarioInfo.Title, - Steps = [], - Description = scenarioContext.ScenarioInfo.Title - }; - - reporter.CurrentFeature!.Elements.Add(scenario); - reporter.CurrentScenario = scenario; - - OnStartedScenario(reporter); - } - } - - [BeforeTestRun] - internal static void BeforeTestRun() - { - _testRunIsFirstFeature = true; - } - - [BeforeStep] - internal static void BeforeStep(ScenarioContext scenarioContext) - { - var startTime = CurrentRunTime; - - foreach (var reporter in REPORTERS) - { - var step = CreateStep(scenarioContext, startTime); - - reporter.CurrentScenario!.Steps.Add(step); - reporter.CurrentStep = step; - - OnStartedStep(reporter); - } - } - -} diff --git a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Reporting/Reporters.cs b/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Reporting/Reporters.cs deleted file mode 100644 index 9a445f881c..0000000000 --- a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/Reporting/Reporters.cs +++ /dev/null @@ -1,240 +0,0 @@ -using System.Reflection; -using System.Text.RegularExpressions; -using Backbone.SpecFlowCucumberResultsExporter.Extensions; -using Backbone.SpecFlowCucumberResultsExporter.Model; - -namespace Backbone.SpecFlowCucumberResultsExporter.Reporting; - -[Binding] -public partial class Reporters -{ - #region Private/Internal - - private static readonly List REPORTERS = []; - - /// - /// Returns the current date/time which is used during the test run. It can set to a fixed - /// datetime by - /// - internal static DateTime CurrentRunTime - { - get - { - if (FixedRunTime.HasValue) - { - return FixedRunTime.Value; - } - return DateTime.Now; - } - } - - private static void AddStepRows(ref Step step, Table table) - { - step.Rows = [new() { Cells = table.Header.ToList() }]; - foreach (var tableRow in table.Rows) - { - step.Rows.Add(new Row() { Cells = tableRow.Select(x => x.Value).ToList() }); - } - } - - internal static Step CreateStep(ScenarioContext scenarioContext, DateTime startTime, MethodBase method = null, params object[] args) - { - var stepInfo = ScenarioStepContext.Current.StepInfo; - - var step = new Step - { - Name = stepInfo.Text, - StartTime = startTime, - Keyword = scenarioContext.CurrentScenarioBlock + " ", - Id = stepInfo.Text.Replace(" ", "-").ToLower() - }; - - var attr = method?.GetCustomAttributes(true).OfType().FirstOrDefault(); - if (attr != null) - { - // Handle regex style - if (!string.IsNullOrEmpty(attr.Regex)) - { - step.Name = attr.Regex; - - foreach (var arg in args) - { - if (arg is Table table) - { - AddStepRows(ref step, table); - } - else - { - var titleRegex = new Regex(step.Name); - var match = titleRegex.Match(step.Name); - if (match.Groups.Count > 1) - { - step.Name = step.Name.ReplaceFirst(match.Groups[1].Value, arg.ToString()); - } - else - { - step.MultiLineParameter = arg.ToString(); - } - } - } - } - else - { - var methodName = method.Name; - if (methodName.Contains('_')) - { - // underscore style - step.Name = methodName.Replace("_", " "); - step.Name = step.Name[(step.Name.IndexOf(' ') + 1)..]; - - var methodInfo = method as MethodInfo; - for (var i = 0; i < args.Length; i++) - { - var arg = args[i]; - if (arg is Table table) - { - AddStepRows(ref step, table); - } - else - { - var name = methodInfo.GetParamName(i).ToUpper(); - var value = arg.ToString(); - if (step.Name.Contains(name + " ")) - { - step.Name = step.Name.ReplaceFirst(name + " ", value + " "); - } - else - { - step.Name = step.Name.ReplaceFirst(" " + name, " " + value); - } - } - } - } - else - { - // pascal naming style - throw new NotSupportedException("Pascal naming style not supported yet"); - } - } - } - else - { - var table = stepInfo.Table; - if (table != null) - { - AddStepRows(ref step, table); - } - step.MultiLineParameter = stepInfo.MultilineText; - } - - return step; - } - - internal static async Task ExecuteStep(ScenarioContext scenarioContext, Func stepFunc, params object[] args) - { - await ExecuteStep(scenarioContext, stepFunc, null, args); - } - - internal static async Task ExecuteStep(ScenarioContext scenarioContext, Func stepFunc, MethodBase methodBase, params object[] args) - { - methodBase ??= stepFunc.Method; - - var currentSteps = new Dictionary(); - - var startTime = CurrentRunTime; - foreach (var reporter in GetAll()) - { - currentSteps.Add(reporter, reporter.CurrentStep); - - var step = CreateStep(scenarioContext, startTime, methodBase, args); - - var stepContainer = reporter.CurrentScenario; - stepContainer!.Steps.Add(step); - reporter.CurrentStep = step; - OnStartedStep(reporter); - } - - Exception actionException = null; - try - { - if (!stepFunc.Method.GetParameters().Any()) - { - await ((Task)stepFunc.Method.Invoke(stepFunc.Target, null))!; - } - else - { - await ((Task)stepFunc.Method.Invoke(stepFunc.Target, args))!; - } - } - catch (Exception ex) - { - if (ex is TargetInvocationException && ex.InnerException != null) - { - // Exceptions thrown by ReportingMessageSink are wrapped in a TargetInvocationException - actionException = ex.InnerException; - } - else - { - actionException = ex; - } - } - finally - { - var endTime = CurrentRunTime; - - TestResult testResult; - if (actionException != null) - { - testResult = TestResult.Pending; - } - else - testResult = actionException == null ? TestResult.Passed : TestResult.Failed; - - - foreach (var reporter in GetAll()) - { - reporter.CurrentStep!.EndTime = endTime; - reporter.CurrentStep.Result = new StepResult - { - Duration = - (long)((endTime - reporter.CurrentStep.StartTime).TotalMilliseconds * 1000000), - Status = testResult, - Error = actionException != null ? actionException.ToExceptionInfo().Message : string.Empty - }; - - OnFinishedStep(reporter); - - reporter.CurrentStep = currentSteps[reporter]; - } - - if (actionException != null) - { -#pragma warning disable CA2219 - throw actionException; -#pragma warning restore CA2219 - } - } - } - - #endregion Private/Internal - - #region Public - - /// - /// Set fixed start and end times. Useful for automated tests. - /// - public static DateTime? FixedRunTime { get; set; } - - public static Reporter Add(Reporter reporter) - { - REPORTERS.Add(reporter); - return reporter; - } - - public static IEnumerable GetAll() - { - return REPORTERS; - } - - #endregion Public -} diff --git a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/SpecFlowCucumberResultsExporter.csproj b/BuildingBlocks/src/SpecFlowCucumberResultsExporter/SpecFlowCucumberResultsExporter.csproj deleted file mode 100644 index 841eaca467..0000000000 --- a/BuildingBlocks/src/SpecFlowCucumberResultsExporter/SpecFlowCucumberResultsExporter.csproj +++ /dev/null @@ -1,21 +0,0 @@ - - - - Library - disable - - - - - - - - - - - - - - - - diff --git a/ConsumerApi.Tests.Integration/ConsumerApi.Tests.Integration.csproj b/ConsumerApi.Tests.Integration/ConsumerApi.Tests.Integration.csproj index 69cb9f7b81..80acb66845 100644 --- a/ConsumerApi.Tests.Integration/ConsumerApi.Tests.Integration.csproj +++ b/ConsumerApi.Tests.Integration/ConsumerApi.Tests.Integration.csproj @@ -24,7 +24,6 @@ - diff --git a/ConsumerApi.Tests.Integration/Hooks/Hooks.cs b/ConsumerApi.Tests.Integration/Hooks/Hooks.cs deleted file mode 100644 index 123bd2e74f..0000000000 --- a/ConsumerApi.Tests.Integration/Hooks/Hooks.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Backbone.SpecFlowCucumberResultsExporter.Extensions; - -namespace Backbone.ConsumerApi.Tests.Integration.Hooks; -[Binding] -public sealed class Hooks -{ - [BeforeTestRun(Order = 0)] - public static void BeforeTestRun() - { - // Export test results to cucumber format - Exporter.ExportToCucumber(); - } -} diff --git a/ConsumerApi.Tests.Integration/specflow.json b/ConsumerApi.Tests.Integration/specflow.json deleted file mode 100644 index 9bd535cd7d..0000000000 --- a/ConsumerApi.Tests.Integration/specflow.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "stepAssemblies": [ - { - "assembly": "Backbone.SpecFlowCucumberResultsExporter" - } - ] -} From ed47b99150b067e4f39b202aad412aa4fa30a7b9 Mon Sep 17 00:00:00 2001 From: Timo Notheisen <65653426+tnotheis@users.noreply.github.com> Date: Wed, 6 Mar 2024 09:12:33 +0100 Subject: [PATCH 3/4] Improve `dotnet test` output in pipelines (#550) * ci: test * test: let test fail * ci: add missing quote * ci: correct path * chore: install logger in all test projects * chore: set default formatter for xml * ci: use logger in all dotnet test calls * ci: remove test pipeline * test: install logger in remaining projects * test: install logger in remaining projects * test: remove duplicated references to GitHubActionsTestLogger * ci: convert test script to sh * ci: convert checkFormatting script to sh * ci: fix checkFormatting script name * test: remove intentionally failing test * ci: try to not use logger for postgres integration tests * ci: try to not include passed and skipped tests for sql server integration tests * ci: make scripts executable * chore: try to remove everything regarding SpecflowCucumberExporter * chore: remove redundant backtick * Revert "ci: try to not include passed and skipped tests for sql server integration tests" This reverts commit 85dadf7278013fae6feef599b513789dad3989ab. * Revert "ci: try to not use logger for postgres integration tests" This reverts commit 5b350c55f377f1969ad1df67c13a359e067eb2fa. * ci: set DOTNET_CONSOLE_ANSI_COLOR for all dotnet test actions * ci: use github action to run transport tests * chore: add "--no-build" flag to `dotnet publish` command in AdminCli's Dockerfile * chore: remove "/property:WarningLevel=0" from all commands * ci: let test fail * chore: remove publish stage from Admin CLI Dockerfile * chore: remove dotnet build from Admin CLI Dockerfile * chore: fix compiler warnings * Revert "ci: let test fail" This reverts commit b25a1292073bb90b08474c87622f2f5eb85c16ad. * Revert "ci: use github action to run transport tests" This reverts commit fae8312a19c9d017c34d0ba8cf7d082d997e7ba5. * chore: remove unnecessary using directive --- .ci/checkFormatting.js | 5 ---- .ci/checkFormatting.sh | 3 ++ .ci/integrationTest.postgres.sh | 4 +-- .ci/integrationTest.sqlserver.sh | 4 +-- .ci/test.js | 7 ----- .ci/test.sh | 5 ++++ .github/workflows/test.yml | 12 +++++--- .vscode/settings.json | 3 ++ AdminApi/src/AdminApi/Dockerfile | 2 +- AdminApi/src/AdminApi/Program.cs | 2 +- .../AdminApi.Tests.Integration.csproj | 4 +++ .../Backbone.Tests.ArchUnit.csproj | 5 ++++ .../src/UnitTestTools/UnitTestTools.csproj | 4 +++ .../BuildingBlocks.API.Tests.csproj | 5 ++++ .../BuildingBlocks.Application.Tests.csproj | 4 +++ ...BuildingBlocks.Infrastructure.Tests.csproj | 4 +++ .../test/Crypto.Tests/Crypto.Tests.csproj | 4 +++ .../DevelopmentKit.Identity.Tests.csproj | 4 +++ .../StronglyTypedIds.Tests.csproj | 5 ++++ .../test/Tooling.Tests/Tooling.Tests.csproj | 4 +++ .../UnitTestTools.Tests.csproj | 5 ++++ .../ConsumerApi.Tests.Integration.csproj | 4 +++ ConsumerApi/Dockerfile | 2 +- ConsumerApi/Program.cs | 5 ++-- .../Devices/src/Devices.AdminCli/Dockerfile | 7 ++--- .../Devices.Application.Tests.csproj | 8 +++-- .../Devices.Domain.Tests.csproj | 8 +++-- .../Devices.Infrastructure.Tests.csproj | 4 +++ .../src/Files.Jobs.SanityCheck/Dockerfile | 2 +- .../Files.Application.Tests.csproj | 5 ++++ .../Files.Jobs.SanityCheck.Tests.csproj | 4 +++ .../Messages.Application.Tests.csproj | 4 +++ .../Quotas.Application.Tests.csproj | 4 +++ .../Quotas.Domain.Tests.csproj | 4 +++ .../Quotas.Infrastructure.Tests.csproj | 30 +++++++++++-------- .../Relationships.Application.Tests.csproj | 4 +++ .../Relationships.Domain.Tests.csproj | 4 +++ .../Synchronization.Application.Tests.csproj | 4 +++ .../Synchronization.Domain.Tests.csproj | 4 +++ .../Tokens.Application.Tests.csproj | 4 +++ scripts/windows/efcore/add_migration.ps1 | 2 +- 41 files changed, 158 insertions(+), 50 deletions(-) delete mode 100755 .ci/checkFormatting.js create mode 100755 .ci/checkFormatting.sh delete mode 100755 .ci/test.js create mode 100755 .ci/test.sh diff --git a/.ci/checkFormatting.js b/.ci/checkFormatting.js deleted file mode 100755 index 1df686bee9..0000000000 --- a/.ci/checkFormatting.js +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env node - -import { $ } from "zx"; - -$`dotnet format --verify-no-changes`; diff --git a/.ci/checkFormatting.sh b/.ci/checkFormatting.sh new file mode 100755 index 0000000000..7d0b3db278 --- /dev/null +++ b/.ci/checkFormatting.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +dotnet format --verify-no-changes diff --git a/.ci/integrationTest.postgres.sh b/.ci/integrationTest.postgres.sh index a7c38393d5..87479daeb2 100755 --- a/.ci/integrationTest.postgres.sh +++ b/.ci/integrationTest.postgres.sh @@ -9,7 +9,7 @@ dockerCompose down dockerCompose build dockerCompose up -d dotnet restore "Backbone.sln" -dotnet build /property:WarningLevel=0 --no-restore "Backbone.sln" +dotnet build --no-restore "Backbone.sln" export CONSUMER_API_BASE_ADDRESS="http://localhost:5000" export ADMIN_API_BASE_ADDRESS="http://localhost:5173" -dotnet test --no-restore --no-build --filter "Category=Integration&TestCategory!~ignore" "Backbone.sln" +dotnet test --no-restore --no-build --filter "Category=Integration&TestCategory!~ignore" --logger "GitHubActions;summary.includePassedTests=true;summary.includeSkippedTests=true" "Backbone.sln" diff --git a/.ci/integrationTest.sqlserver.sh b/.ci/integrationTest.sqlserver.sh index 29fb809520..be8e4a3e38 100755 --- a/.ci/integrationTest.sqlserver.sh +++ b/.ci/integrationTest.sqlserver.sh @@ -9,7 +9,7 @@ dockerCompose down dockerCompose build dockerCompose up -d dotnet restore "Backbone.sln" -dotnet build /property:WarningLevel=0 --no-restore "Backbone.sln" +dotnet build --no-restore "Backbone.sln" export CONSUMER_API_BASE_ADDRESS="http://localhost:5000" export ADMIN_API_BASE_ADDRESS="http://localhost:5173" -dotnet test --no-restore --no-build --filter "Category=Integration&TestCategory!~ignore" "Backbone.sln" +dotnet test --no-restore --no-build --filter "Category=Integration&TestCategory!~ignore" --logger "GitHubActions;summary.includePassedTests=true;summary.includeSkippedTests=true" "Backbone.sln" diff --git a/.ci/test.js b/.ci/test.js deleted file mode 100755 index ada65c7921..0000000000 --- a/.ci/test.js +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env node - -import { $ } from "zx"; - -await $`dotnet restore "Backbone.sln"`; -await $`dotnet build /property:WarningLevel=0 --no-restore "Backbone.sln"`; -await $`dotnet test --no-restore --no-build "Backbone.sln" --filter "Category!=Integration"`; diff --git a/.ci/test.sh b/.ci/test.sh new file mode 100755 index 0000000000..14ea54a6da --- /dev/null +++ b/.ci/test.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +dotnet restore "Backbone.sln" +dotnet build --no-restore "Backbone.sln" +dotnet test --no-restore --no-build --filter "Category!=Integration" --logger "GitHubActions;summary.includePassedTests=true;summary.includeSkippedTests=true" "Backbone.sln" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6dd00964b3..7fda10ecdf 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -30,7 +30,7 @@ jobs: with: dotnet-version: "8.0.x" - name: Check formatting - run: ./.ci/checkFormatting.js + run: ./.ci/checkFormatting.sh test: runs-on: ubuntu-latest @@ -38,14 +38,14 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 - - name: Install script dependencies - run: npm install --prefix ./.ci - name: Setup dotnet uses: actions/setup-dotnet@v4 with: dotnet-version: "8.0.x" - name: Run tests - run: ./.ci/test.js + run: ./.ci/test.sh + env: + DOTNET_CONSOLE_ANSI_COLOR: true integration-test-sqlserver: name: Run Integration Tests (on SQL Server) @@ -66,6 +66,8 @@ jobs: with: name: integration-test-sqlserver-docker-logs path: docker-log.txt + env: + DOTNET_CONSOLE_ANSI_COLOR: true integration-test-postgres: name: Run Integration Tests (on Postgres) @@ -86,6 +88,8 @@ jobs: with: name: integration-test-postgres-docker-logs path: docker-log.txt + env: + DOTNET_CONSOLE_ANSI_COLOR: true transport-test-sqlserver: name: Run transport Tests (on SQL Server) diff --git a/.vscode/settings.json b/.vscode/settings.json index ae8449e4ac..3666534e1e 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -20,6 +20,9 @@ "[html]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, + "[xml]": { + "editor.defaultFormatter": "DotJoshJohnson.xml" + }, "editor.formatOnSave": true, "editor.formatOnPaste": true, "files.autoSave": "off", diff --git a/AdminApi/src/AdminApi/Dockerfile b/AdminApi/src/AdminApi/Dockerfile index 7897915c2c..b7df73fae9 100644 --- a/AdminApi/src/AdminApi/Dockerfile +++ b/AdminApi/src/AdminApi/Dockerfile @@ -89,7 +89,7 @@ RUN dotnet restore "AdminApi/src/AdminApi/AdminApi.csproj" COPY . . -RUN dotnet publish /property:WarningLevel=0 /p:UseAppHost=false --no-restore --configuration Release --output /app/publish "/src/AdminApi/src/AdminApi/AdminApi.csproj" +RUN dotnet publish /p:UseAppHost=false --no-restore --configuration Release --output /app/publish "/src/AdminApi/src/AdminApi/AdminApi.csproj" RUN dotnet publish --configuration Release --output /app/publish/health "HealthCheck/HealthCheck.csproj" ### Final #### diff --git a/AdminApi/src/AdminApi/Program.cs b/AdminApi/src/AdminApi/Program.cs index a8e3ed1dbc..92d59729fc 100644 --- a/AdminApi/src/AdminApi/Program.cs +++ b/AdminApi/src/AdminApi/Program.cs @@ -94,7 +94,7 @@ static void ConfigureServices(IServiceCollection services, IConfiguration config .ConfigureAndValidate(configuration.Bind) .ConfigureAndValidate(options => configuration.GetSection("Modules:Devices:Application").Bind(options)); -#pragma warning disable ASP0000 We retrieve the Configuration via IOptions here so that it is validated +#pragma warning disable ASP0000 // We retrieve the Configuration via IOptions here so that it is validated var parsedConfiguration = services.BuildServiceProvider().GetRequiredService>().Value; #pragma warning restore ASP0000 diff --git a/AdminApi/test/AdminApi.Tests.Integration/AdminApi.Tests.Integration.csproj b/AdminApi/test/AdminApi.Tests.Integration/AdminApi.Tests.Integration.csproj index a87db86baa..a2f89e9055 100644 --- a/AdminApi/test/AdminApi.Tests.Integration/AdminApi.Tests.Integration.csproj +++ b/AdminApi/test/AdminApi.Tests.Integration/AdminApi.Tests.Integration.csproj @@ -19,6 +19,10 @@ + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + diff --git a/Backbone.Tests.ArchUnit/Backbone.Tests.ArchUnit.csproj b/Backbone.Tests.ArchUnit/Backbone.Tests.ArchUnit.csproj index 5db60f8be3..0b93007873 100644 --- a/Backbone.Tests.ArchUnit/Backbone.Tests.ArchUnit.csproj +++ b/Backbone.Tests.ArchUnit/Backbone.Tests.ArchUnit.csproj @@ -8,6 +8,11 @@ + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/BuildingBlocks/src/UnitTestTools/UnitTestTools.csproj b/BuildingBlocks/src/UnitTestTools/UnitTestTools.csproj index 4005467675..b9d6db1aa7 100644 --- a/BuildingBlocks/src/UnitTestTools/UnitTestTools.csproj +++ b/BuildingBlocks/src/UnitTestTools/UnitTestTools.csproj @@ -2,6 +2,10 @@ + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + diff --git a/BuildingBlocks/test/BuildingBlocks.API.Tests/BuildingBlocks.API.Tests.csproj b/BuildingBlocks/test/BuildingBlocks.API.Tests/BuildingBlocks.API.Tests.csproj index 024dbc3b0a..86d1525930 100644 --- a/BuildingBlocks/test/BuildingBlocks.API.Tests/BuildingBlocks.API.Tests.csproj +++ b/BuildingBlocks/test/BuildingBlocks.API.Tests/BuildingBlocks.API.Tests.csproj @@ -6,6 +6,11 @@ + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + all diff --git a/BuildingBlocks/test/BuildingBlocks.Application.Tests/BuildingBlocks.Application.Tests.csproj b/BuildingBlocks/test/BuildingBlocks.Application.Tests/BuildingBlocks.Application.Tests.csproj index 4ae11cf3b3..f09f380f5d 100644 --- a/BuildingBlocks/test/BuildingBlocks.Application.Tests/BuildingBlocks.Application.Tests.csproj +++ b/BuildingBlocks/test/BuildingBlocks.Application.Tests/BuildingBlocks.Application.Tests.csproj @@ -8,6 +8,10 @@ + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/BuildingBlocks/test/BuildingBlocks.Infrastructure.Tests/BuildingBlocks.Infrastructure.Tests.csproj b/BuildingBlocks/test/BuildingBlocks.Infrastructure.Tests/BuildingBlocks.Infrastructure.Tests.csproj index 77cc310614..ea7c9c627b 100644 --- a/BuildingBlocks/test/BuildingBlocks.Infrastructure.Tests/BuildingBlocks.Infrastructure.Tests.csproj +++ b/BuildingBlocks/test/BuildingBlocks.Infrastructure.Tests/BuildingBlocks.Infrastructure.Tests.csproj @@ -9,6 +9,10 @@ + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + diff --git a/BuildingBlocks/test/Crypto.Tests/Crypto.Tests.csproj b/BuildingBlocks/test/Crypto.Tests/Crypto.Tests.csproj index 69675eafdd..b837f1c658 100644 --- a/BuildingBlocks/test/Crypto.Tests/Crypto.Tests.csproj +++ b/BuildingBlocks/test/Crypto.Tests/Crypto.Tests.csproj @@ -10,6 +10,10 @@ + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + diff --git a/BuildingBlocks/test/DevelopmentKit.Identity.Tests/DevelopmentKit.Identity.Tests.csproj b/BuildingBlocks/test/DevelopmentKit.Identity.Tests/DevelopmentKit.Identity.Tests.csproj index 2b972fea96..3ab1e40b38 100644 --- a/BuildingBlocks/test/DevelopmentKit.Identity.Tests/DevelopmentKit.Identity.Tests.csproj +++ b/BuildingBlocks/test/DevelopmentKit.Identity.Tests/DevelopmentKit.Identity.Tests.csproj @@ -6,6 +6,10 @@ + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + diff --git a/BuildingBlocks/test/StronglyTypedIds.Tests/StronglyTypedIds.Tests.csproj b/BuildingBlocks/test/StronglyTypedIds.Tests/StronglyTypedIds.Tests.csproj index d673f3fa50..be8fbc0ec2 100644 --- a/BuildingBlocks/test/StronglyTypedIds.Tests/StronglyTypedIds.Tests.csproj +++ b/BuildingBlocks/test/StronglyTypedIds.Tests/StronglyTypedIds.Tests.csproj @@ -6,6 +6,11 @@ + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + all diff --git a/BuildingBlocks/test/Tooling.Tests/Tooling.Tests.csproj b/BuildingBlocks/test/Tooling.Tests/Tooling.Tests.csproj index ef86dd407d..61455ed879 100644 --- a/BuildingBlocks/test/Tooling.Tests/Tooling.Tests.csproj +++ b/BuildingBlocks/test/Tooling.Tests/Tooling.Tests.csproj @@ -6,6 +6,10 @@ + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + diff --git a/BuildingBlocks/test/UnitTestTools.Tests/UnitTestTools.Tests.csproj b/BuildingBlocks/test/UnitTestTools.Tests/UnitTestTools.Tests.csproj index c067d5df77..b9b87e39a6 100644 --- a/BuildingBlocks/test/UnitTestTools.Tests/UnitTestTools.Tests.csproj +++ b/BuildingBlocks/test/UnitTestTools.Tests/UnitTestTools.Tests.csproj @@ -6,6 +6,11 @@ + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + all diff --git a/ConsumerApi.Tests.Integration/ConsumerApi.Tests.Integration.csproj b/ConsumerApi.Tests.Integration/ConsumerApi.Tests.Integration.csproj index 80acb66845..f266025eb5 100644 --- a/ConsumerApi.Tests.Integration/ConsumerApi.Tests.Integration.csproj +++ b/ConsumerApi.Tests.Integration/ConsumerApi.Tests.Integration.csproj @@ -20,6 +20,10 @@ + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + diff --git a/ConsumerApi/Dockerfile b/ConsumerApi/Dockerfile index 38352a695c..a3327b8ae2 100644 --- a/ConsumerApi/Dockerfile +++ b/ConsumerApi/Dockerfile @@ -54,7 +54,7 @@ WORKDIR /src COPY . . RUN dotnet restore "ConsumerApi/ConsumerApi.csproj" -RUN dotnet publish /property:WarningLevel=0 --configuration Release --output /app/publish --no-restore "ConsumerApi/ConsumerApi.csproj" +RUN dotnet publish --configuration Release --output /app/publish --no-restore "ConsumerApi/ConsumerApi.csproj" RUN dotnet publish --configuration Release --output /app/publish/health "HealthCheck/HealthCheck.csproj" ### Final #### diff --git a/ConsumerApi/Program.cs b/ConsumerApi/Program.cs index 9cbedaf7a3..4164f21a62 100644 --- a/ConsumerApi/Program.cs +++ b/ConsumerApi/Program.cs @@ -155,9 +155,8 @@ static void ConfigureServices(IServiceCollection services, IConfiguration config services.ConfigureAndValidate(configuration.Bind); -#pragma warning disable ASP0000 We retrieve the BackboneConfiguration via IOptions here so that it is validated - var parsedConfiguration = - services.BuildServiceProvider().GetRequiredService>().Value; +#pragma warning disable ASP0000 // We retrieve the BackboneConfiguration via IOptions here so that it is validated + var parsedConfiguration = services.BuildServiceProvider().GetRequiredService>().Value; #pragma warning restore ASP0000 services .AddCustomAspNetCore(parsedConfiguration, environment) diff --git a/Modules/Devices/src/Devices.AdminCli/Dockerfile b/Modules/Devices/src/Devices.AdminCli/Dockerfile index e164854748..49d2e8665c 100644 --- a/Modules/Devices/src/Devices.AdminCli/Dockerfile +++ b/Modules/Devices/src/Devices.AdminCli/Dockerfile @@ -24,14 +24,11 @@ RUN dotnet restore "Modules/Devices/src/Devices.AdminCli/Devices.AdminCli.csproj COPY . . WORKDIR "/src/Modules/Devices/src/Devices.AdminCli" -RUN dotnet build /property:UseAppHost=true /property:DebugType=None --no-restore -c Release -o /app/build --self-contained true "Devices.AdminCli.csproj" - -FROM build AS publish -RUN dotnet publish "Devices.AdminCli.csproj" --no-restore -c Release -o /app/publish +RUN dotnet publish --no-restore -c Release -o /app/publish "Devices.AdminCli.csproj" FROM base AS final WORKDIR /app -COPY --from=publish /app/publish/Backbone.Modules.Devices.AdminCli ./backbone +COPY --from=build /app/publish/Backbone.Modules.Devices.AdminCli ./backbone ENV PATH="$PATH:/app" diff --git a/Modules/Devices/test/Devices.Application.Tests/Devices.Application.Tests.csproj b/Modules/Devices/test/Devices.Application.Tests/Devices.Application.Tests.csproj index 58f049c9a3..2dcff994e1 100644 --- a/Modules/Devices/test/Devices.Application.Tests/Devices.Application.Tests.csproj +++ b/Modules/Devices/test/Devices.Application.Tests/Devices.Application.Tests.csproj @@ -10,6 +10,10 @@ + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + all @@ -17,8 +21,8 @@ - - + + diff --git a/Modules/Devices/test/Devices.Domain.Tests/Devices.Domain.Tests.csproj b/Modules/Devices/test/Devices.Domain.Tests/Devices.Domain.Tests.csproj index c262da43cc..b2a74f67de 100644 --- a/Modules/Devices/test/Devices.Domain.Tests/Devices.Domain.Tests.csproj +++ b/Modules/Devices/test/Devices.Domain.Tests/Devices.Domain.Tests.csproj @@ -7,6 +7,10 @@ + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + @@ -20,7 +24,7 @@ - - + + diff --git a/Modules/Devices/test/Devices.Infrastructure.Tests/Devices.Infrastructure.Tests.csproj b/Modules/Devices/test/Devices.Infrastructure.Tests/Devices.Infrastructure.Tests.csproj index 42d7178d5a..f4a90e9616 100644 --- a/Modules/Devices/test/Devices.Infrastructure.Tests/Devices.Infrastructure.Tests.csproj +++ b/Modules/Devices/test/Devices.Infrastructure.Tests/Devices.Infrastructure.Tests.csproj @@ -10,6 +10,10 @@ + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + all diff --git a/Modules/Files/src/Files.Jobs.SanityCheck/Dockerfile b/Modules/Files/src/Files.Jobs.SanityCheck/Dockerfile index 5c4467264f..3f58e56abc 100644 --- a/Modules/Files/src/Files.Jobs.SanityCheck/Dockerfile +++ b/Modules/Files/src/Files.Jobs.SanityCheck/Dockerfile @@ -26,7 +26,7 @@ WORKDIR "/src/Modules/Files/src/Files.Jobs.SanityCheck" RUN dotnet build "Files.Jobs.SanityCheck.csproj" --configuration Release --output /app/build --no-restore FROM build AS publish -RUN dotnet publish /property:UseAppHost=false /property:WarningLevel=0 --configuration Release --output /app/publish --no-restore "Files.Jobs.SanityCheck.csproj" +RUN dotnet publish /property:UseAppHost=false --configuration Release --output /app/publish --no-restore "Files.Jobs.SanityCheck.csproj" FROM base AS final WORKDIR /app diff --git a/Modules/Files/test/Files.Application.Tests/Files.Application.Tests.csproj b/Modules/Files/test/Files.Application.Tests/Files.Application.Tests.csproj index 14d9f4181c..630bd1b59f 100644 --- a/Modules/Files/test/Files.Application.Tests/Files.Application.Tests.csproj +++ b/Modules/Files/test/Files.Application.Tests/Files.Application.Tests.csproj @@ -6,6 +6,11 @@ + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + all diff --git a/Modules/Files/test/Files.Jobs.SanityCheck.Tests/Files.Jobs.SanityCheck.Tests.csproj b/Modules/Files/test/Files.Jobs.SanityCheck.Tests/Files.Jobs.SanityCheck.Tests.csproj index c4971f0ef4..12b5f2246f 100644 --- a/Modules/Files/test/Files.Jobs.SanityCheck.Tests/Files.Jobs.SanityCheck.Tests.csproj +++ b/Modules/Files/test/Files.Jobs.SanityCheck.Tests/Files.Jobs.SanityCheck.Tests.csproj @@ -6,6 +6,10 @@ + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + diff --git a/Modules/Messages/test/Messages.Application.Tests/Messages.Application.Tests.csproj b/Modules/Messages/test/Messages.Application.Tests/Messages.Application.Tests.csproj index 9f72c3a8e0..d238a9dbb5 100644 --- a/Modules/Messages/test/Messages.Application.Tests/Messages.Application.Tests.csproj +++ b/Modules/Messages/test/Messages.Application.Tests/Messages.Application.Tests.csproj @@ -7,6 +7,10 @@ + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + diff --git a/Modules/Quotas/test/Quotas.Application.Tests/Quotas.Application.Tests.csproj b/Modules/Quotas/test/Quotas.Application.Tests/Quotas.Application.Tests.csproj index 6616e43652..5e434dded9 100644 --- a/Modules/Quotas/test/Quotas.Application.Tests/Quotas.Application.Tests.csproj +++ b/Modules/Quotas/test/Quotas.Application.Tests/Quotas.Application.Tests.csproj @@ -7,6 +7,10 @@ + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + diff --git a/Modules/Quotas/test/Quotas.Domain.Tests/Quotas.Domain.Tests.csproj b/Modules/Quotas/test/Quotas.Domain.Tests/Quotas.Domain.Tests.csproj index 64c2e6ef9e..803d02d0ef 100644 --- a/Modules/Quotas/test/Quotas.Domain.Tests/Quotas.Domain.Tests.csproj +++ b/Modules/Quotas/test/Quotas.Domain.Tests/Quotas.Domain.Tests.csproj @@ -6,6 +6,10 @@ + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + diff --git a/Modules/Quotas/test/Quotas.Infrastructure.Tests/Quotas.Infrastructure.Tests.csproj b/Modules/Quotas/test/Quotas.Infrastructure.Tests/Quotas.Infrastructure.Tests.csproj index d1cf692b04..4df8e48b16 100644 --- a/Modules/Quotas/test/Quotas.Infrastructure.Tests/Quotas.Infrastructure.Tests.csproj +++ b/Modules/Quotas/test/Quotas.Infrastructure.Tests/Quotas.Infrastructure.Tests.csproj @@ -6,20 +6,24 @@ - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + - - - - - + + + + + diff --git a/Modules/Relationships/test/Relationships.Application.Tests/Relationships.Application.Tests.csproj b/Modules/Relationships/test/Relationships.Application.Tests/Relationships.Application.Tests.csproj index 2cda9d5596..2ff2c122f8 100644 --- a/Modules/Relationships/test/Relationships.Application.Tests/Relationships.Application.Tests.csproj +++ b/Modules/Relationships/test/Relationships.Application.Tests/Relationships.Application.Tests.csproj @@ -8,6 +8,10 @@ + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + all diff --git a/Modules/Relationships/test/Relationships.Domain.Tests/Relationships.Domain.Tests.csproj b/Modules/Relationships/test/Relationships.Domain.Tests/Relationships.Domain.Tests.csproj index 4565128836..e02b97d5ce 100644 --- a/Modules/Relationships/test/Relationships.Domain.Tests/Relationships.Domain.Tests.csproj +++ b/Modules/Relationships/test/Relationships.Domain.Tests/Relationships.Domain.Tests.csproj @@ -7,6 +7,10 @@ + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + all diff --git a/Modules/Synchronization/test/Synchronization.Application.Tests/Synchronization.Application.Tests.csproj b/Modules/Synchronization/test/Synchronization.Application.Tests/Synchronization.Application.Tests.csproj index e187fedd29..ccc5d8b803 100644 --- a/Modules/Synchronization/test/Synchronization.Application.Tests/Synchronization.Application.Tests.csproj +++ b/Modules/Synchronization/test/Synchronization.Application.Tests/Synchronization.Application.Tests.csproj @@ -10,6 +10,10 @@ + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + all diff --git a/Modules/Synchronization/test/Synchronization.Domain.Tests/Synchronization.Domain.Tests.csproj b/Modules/Synchronization/test/Synchronization.Domain.Tests/Synchronization.Domain.Tests.csproj index 9e2be5bc4d..613faa2a37 100644 --- a/Modules/Synchronization/test/Synchronization.Domain.Tests/Synchronization.Domain.Tests.csproj +++ b/Modules/Synchronization/test/Synchronization.Domain.Tests/Synchronization.Domain.Tests.csproj @@ -6,6 +6,10 @@ + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + diff --git a/Modules/Tokens/test/Tokens.Application.Tests/Tokens.Application.Tests.csproj b/Modules/Tokens/test/Tokens.Application.Tests/Tokens.Application.Tests.csproj index 3589f64088..cddc89d11b 100644 --- a/Modules/Tokens/test/Tokens.Application.Tests/Tokens.Application.Tests.csproj +++ b/Modules/Tokens/test/Tokens.Application.Tests/Tokens.Application.Tests.csproj @@ -8,6 +8,10 @@ + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + all diff --git a/scripts/windows/efcore/add_migration.ps1 b/scripts/windows/efcore/add_migration.ps1 index 580aee8175..4f57607e01 100644 --- a/scripts/windows/efcore/add_migration.ps1 +++ b/scripts/windows/efcore/add_migration.ps1 @@ -39,7 +39,7 @@ function AddMigration { Invoke-Expression $cmd } -dotnet build /property:WarningLevel=0 $startupProject +dotnet build $startupProject switch ($provider) { "SqlServer" { From fd19aa30617ca8b1f805f9179ae31903b48f4206 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nikola=20Vetni=C4=87?= <62119280+NikolaVetnic@users.noreply.github.com> Date: Wed, 6 Mar 2024 12:39:27 +0100 Subject: [PATCH 4/4] Consumer API: Reject identity deletion process (#535) * feat: implement rejection of deletion process before approval * chore: fix a typo * feat: add reject identity deletion endpoint * feat: add RejectedAt and RejectedByDevice properties * chore: fix formatting * chore: remove IdentityAddress from RejectDeletionProcessResponse * chore: remove unused directives * chore: line endings * chore: remove unused directives * refactor: use SystemTime.UtcNow * refactor: use SystemTime * refactor: extract into separate method * chore: rename variable * chore: rename variable * refactor: remove ctor input parameter * chore: remove redundant status update * chore: rename input parameter * chore: change the method order in code * feat: add EnsureIdentityOwnsDevice method * test: check CreatedAt value * chore: reorganize lines * test: update condition * chore: reorganize lines * refactor: remove redundant date variable * chore: renamed mock repository variable to fake * test: use identity's own device in test * chore: rename class to plural * test: add reject deletion process test case when device is not owned by identity * test: use own device in test * test: update acting to start deletion process with own device * test: simplify method call * refactor: use hardcoded date * chore: rename variable * refactor: attempt to start deletion process with own device * test: change assertion * refactor: remove redundant handler tests as they are covered by the domain ones * chore: remove unused directives * refactor: reorganize class so that ctors are on top and private methods below their public ones * refactor: remove redundant assertion * feat: ensure deletion process is approved by device owned by identity * chore: move private Approve method beneath its first use * refactor: use device owned by identity and make code uniform in similar tests * refactor: use own device to approve deletion process * test: update assertions * test: add test when process is started by "not owned" device * refactor: remove handler tests covered by domain tests * feat: use RejectedAt instead of CreatedAt in dto * refactor: rename method and update exception thrown * test: update tests * chore: remove redundant call * test: add additional assertion * test: update tests with additional assertions * test: update assertions * refactor: extract method * test: update assertions * fix: fix missing usings * test: avoid having two acting statements * chore: change error code, method name and error message * feat: bring back RejectedAt and RejectedBy properties * refactor: remove two actings * Merge branch 'main' into nmshdb-44-rejection-of-deletion-process * test: fix broken test * chore: formatting * test: fix tests * test: fix tests --------- Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- .../Commands/RejectDeletionProcess/Handler.cs | 36 + .../RejectDeletionProcessCommand.cs | 12 + .../RejectDeletionProcessResponse.cs | 18 + .../Controllers/IdentitiesController.cs | 11 + .../src/Devices.Domain/DomainErrors.cs | 5 +- .../Entities/Identities/Identity.cs | 37 +- .../Identities/IdentityDeletionProcess.cs | 50 +- .../IdentityDeletionProcessAuditLogEntry.cs | 5 + ..._AddProcessRejectionProperties.Designer.cs | 873 +++++++++++++++++ ...223141956_AddProcessRejectionProperties.cs | 42 + .../DevicesDbContextModelSnapshot.cs | 9 + ..._AddProcessRejectionProperties.Designer.cs | 878 ++++++++++++++++++ ...223141945_AddProcessRejectionProperties.cs | 42 + .../ApplicationDbContextModelSnapshot.cs | 9 + .../ApproveDeletionProcess/HandlerTests.cs | 55 -- .../RejectDeletionProcess/HandlerTests.cs | 77 ++ .../Identities/ApproveDeletionProcessTests.cs | 44 +- .../Identities/CancelDeletionProcessTests.cs | 2 +- .../DeletionGracePeriodReminderTests.cs | 6 +- .../DeletionProcessApprovalReminderTests.cs | 6 +- .../Identities/RejectDeletionProcessTests.cs | 109 +++ 21 files changed, 2228 insertions(+), 98 deletions(-) create mode 100644 Modules/Devices/src/Devices.Application/Identities/Commands/RejectDeletionProcess/Handler.cs create mode 100644 Modules/Devices/src/Devices.Application/Identities/Commands/RejectDeletionProcess/RejectDeletionProcessCommand.cs create mode 100644 Modules/Devices/src/Devices.Application/Identities/Commands/RejectDeletionProcess/RejectDeletionProcessResponse.cs create mode 100644 Modules/Devices/src/Devices.Infrastructure.Database.Postgres/Migrations/20240223141956_AddProcessRejectionProperties.Designer.cs create mode 100644 Modules/Devices/src/Devices.Infrastructure.Database.Postgres/Migrations/20240223141956_AddProcessRejectionProperties.cs create mode 100644 Modules/Devices/src/Devices.Infrastructure.Database.SqlServer/Migrations/20240223141945_AddProcessRejectionProperties.Designer.cs create mode 100644 Modules/Devices/src/Devices.Infrastructure.Database.SqlServer/Migrations/20240223141945_AddProcessRejectionProperties.cs create mode 100644 Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/RejectDeletionProcess/HandlerTests.cs create mode 100644 Modules/Devices/test/Devices.Domain.Tests/Identities/RejectDeletionProcessTests.cs diff --git a/Modules/Devices/src/Devices.Application/Identities/Commands/RejectDeletionProcess/Handler.cs b/Modules/Devices/src/Devices.Application/Identities/Commands/RejectDeletionProcess/Handler.cs new file mode 100644 index 0000000000..162acf9f12 --- /dev/null +++ b/Modules/Devices/src/Devices.Application/Identities/Commands/RejectDeletionProcess/Handler.cs @@ -0,0 +1,36 @@ +using Backbone.BuildingBlocks.Application.Abstractions.Exceptions; +using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.UserContext; +using Backbone.BuildingBlocks.Domain; +using Backbone.Modules.Devices.Application.Infrastructure.Persistence.Repository; +using Backbone.Modules.Devices.Domain.Entities.Identities; +using MediatR; + +namespace Backbone.Modules.Devices.Application.Identities.Commands.RejectDeletionProcess; +public class Handler : IRequestHandler +{ + private readonly IIdentitiesRepository _identitiesRepository; + private readonly IUserContext _userContext; + + public Handler(IIdentitiesRepository identitiesRepository, IUserContext userContext) + { + _identitiesRepository = identitiesRepository; + _userContext = userContext; + } + + public async Task Handle(RejectDeletionProcessCommand request, CancellationToken cancellationToken) + { + var identity = await _identitiesRepository.FindByAddress(_userContext.GetAddress(), cancellationToken, track: true) ?? throw new NotFoundException(nameof(Identity)); + var deviceId = _userContext.GetDeviceId(); + + var deletionProcessIdResult = IdentityDeletionProcessId.Create(request.DeletionProcessId); + + if (deletionProcessIdResult.IsFailure) + throw new DomainException(deletionProcessIdResult.Error); + + var deletionProcessId = deletionProcessIdResult.Value; + var deletionProcess = identity.RejectDeletionProcess(deletionProcessId, deviceId); + await _identitiesRepository.Update(identity, cancellationToken); + + return new RejectDeletionProcessResponse(deletionProcess); + } +} diff --git a/Modules/Devices/src/Devices.Application/Identities/Commands/RejectDeletionProcess/RejectDeletionProcessCommand.cs b/Modules/Devices/src/Devices.Application/Identities/Commands/RejectDeletionProcess/RejectDeletionProcessCommand.cs new file mode 100644 index 0000000000..b9b9a466bc --- /dev/null +++ b/Modules/Devices/src/Devices.Application/Identities/Commands/RejectDeletionProcess/RejectDeletionProcessCommand.cs @@ -0,0 +1,12 @@ +using MediatR; + +namespace Backbone.Modules.Devices.Application.Identities.Commands.RejectDeletionProcess; +public class RejectDeletionProcessCommand : IRequest +{ + public RejectDeletionProcessCommand(string deletionProcessId) + { + DeletionProcessId = deletionProcessId; + } + + public string DeletionProcessId { get; set; } +} diff --git a/Modules/Devices/src/Devices.Application/Identities/Commands/RejectDeletionProcess/RejectDeletionProcessResponse.cs b/Modules/Devices/src/Devices.Application/Identities/Commands/RejectDeletionProcess/RejectDeletionProcessResponse.cs new file mode 100644 index 0000000000..7c3ebe2e69 --- /dev/null +++ b/Modules/Devices/src/Devices.Application/Identities/Commands/RejectDeletionProcess/RejectDeletionProcessResponse.cs @@ -0,0 +1,18 @@ +using Backbone.Modules.Devices.Domain.Entities.Identities; + +namespace Backbone.Modules.Devices.Application.Identities.Commands.RejectDeletionProcess; +public class RejectDeletionProcessResponse +{ + public RejectDeletionProcessResponse(IdentityDeletionProcess deletionProcess) + { + Id = deletionProcess.Id; + Status = deletionProcess.Status; + RejectedAt = deletionProcess.RejectedAt ?? throw new Exception($"The '{nameof(IdentityDeletionProcess.RejectedAt)}' property of the given deletion process must not be null."); + RejectedByDevice = deletionProcess.RejectedByDevice ?? throw new Exception($"The '{nameof(IdentityDeletionProcess.RejectedByDevice)}' property of the given deletion process must not be null."); + } + + public string Id { get; } + public DeletionProcessStatus Status { get; } + public DateTime RejectedAt { get; } + public string RejectedByDevice { get; } +} diff --git a/Modules/Devices/src/Devices.ConsumerApi/Controllers/IdentitiesController.cs b/Modules/Devices/src/Devices.ConsumerApi/Controllers/IdentitiesController.cs index d7a4d4637a..9cdc86535b 100644 --- a/Modules/Devices/src/Devices.ConsumerApi/Controllers/IdentitiesController.cs +++ b/Modules/Devices/src/Devices.ConsumerApi/Controllers/IdentitiesController.cs @@ -6,6 +6,7 @@ using Backbone.Modules.Devices.Application.Identities.Commands.ApproveDeletionProcess; using Backbone.Modules.Devices.Application.Identities.Commands.CancelDeletionProcess; using Backbone.Modules.Devices.Application.Identities.Commands.CreateIdentity; +using Backbone.Modules.Devices.Application.Identities.Commands.RejectDeletionProcess; using Backbone.Modules.Devices.Application.Identities.Commands.StartDeletionProcessAsOwner; using Backbone.Modules.Devices.Application.Identities.Queries.GetDeletionProcess; using Backbone.Modules.Devices.Application.Identities.Queries.GetDeletionProcesses; @@ -80,6 +81,16 @@ public async Task ApproveDeletionProcess([FromRoute] string id, C return Ok(response); } + [HttpPut("Self/DeletionProcesses/{id}/Reject")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesError(StatusCodes.Status400BadRequest)] + [ProducesError(StatusCodes.Status404NotFound)] + public async Task RejectDeletionProcess([FromRoute] string id, CancellationToken cancellationToken) + { + var response = await _mediator.Send(new RejectDeletionProcessCommand(id), cancellationToken); + return Ok(response); + } + [HttpGet("Self/DeletionProcesses/{id}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesError(StatusCodes.Status404NotFound)] diff --git a/Modules/Devices/src/Devices.Domain/DomainErrors.cs b/Modules/Devices/src/Devices.Domain/DomainErrors.cs index 1e15ad4cef..1a84ef5395 100644 --- a/Modules/Devices/src/Devices.Domain/DomainErrors.cs +++ b/Modules/Devices/src/Devices.Domain/DomainErrors.cs @@ -1,4 +1,5 @@ using Backbone.BuildingBlocks.Domain.Errors; +using Backbone.Modules.Devices.Domain.Entities.Identities; namespace Backbone.Modules.Devices.Domain; @@ -45,8 +46,8 @@ public static DomainError OnlyOneActiveDeletionProcessAllowed() return new DomainError("error.platform.validation.device.onlyOneActiveDeletionProcessAllowed", "Only one active deletion process is allowed."); } - public static DomainError NoDeletionProcessWithRequiredStatusExists() + public static DomainError DeletionProcessMustBeInStatus(DeletionProcessStatus deletionProcessStatus) { - return new DomainError("error.platform.validation.device.noDeletionProcessWithRequiredStatusExists", "The deletion process does not have the correct status to perform this action."); + return new DomainError($"error.platform.validation.device.deletionProcessMustBeInStatus{deletionProcessStatus}", $"The deletion process must be in status '{deletionProcessStatus}'."); } } diff --git a/Modules/Devices/src/Devices.Domain/Entities/Identities/Identity.cs b/Modules/Devices/src/Devices.Domain/Entities/Identities/Identity.cs index c561d2ff67..542cb2b134 100644 --- a/Modules/Devices/src/Devices.Domain/Entities/Identities/Identity.cs +++ b/Modules/Devices/src/Devices.Domain/Entities/Identities/Identity.cs @@ -85,12 +85,6 @@ public IdentityDeletionProcess StartDeletionProcessAsOwner(DeviceId asDevice) return deletionProcess; } - private void EnsureIdentityOwnsDevice(DeviceId currentDeviceId) - { - if (!Devices.Exists(device => device.Id == currentDeviceId)) - throw new DomainException(GenericDomainErrors.NotFound(nameof(Device))); - } - public void DeletionProcessApprovalReminder1Sent() { EnsureDeletionProcessInStatusExists(DeletionProcessStatus.WaitingForApproval); @@ -117,7 +111,9 @@ public void DeletionProcessApprovalReminder3Sent() public IdentityDeletionProcess ApproveDeletionProcess(IdentityDeletionProcessId deletionProcessId, DeviceId deviceId) { - var deletionProcess = DeletionProcesses.FirstOrDefault(x => x.Id == deletionProcessId) ?? throw new DomainException(GenericDomainErrors.NotFound(nameof(IdentityDeletionProcess))); + EnsureIdentityOwnsDevice(deviceId); + + var deletionProcess = GetDeletionProcess(deletionProcessId); deletionProcess.Approve(Address, deviceId); @@ -128,12 +124,28 @@ public IdentityDeletionProcess ApproveDeletionProcess(IdentityDeletionProcessId return deletionProcess; } + private IdentityDeletionProcess GetDeletionProcess(IdentityDeletionProcessId deletionProcessId) + { + var deletionProcess = DeletionProcesses.FirstOrDefault(x => x.Id == deletionProcessId) ?? throw new DomainException(GenericDomainErrors.NotFound(nameof(IdentityDeletionProcess))); + return deletionProcess; + } + + public IdentityDeletionProcess RejectDeletionProcess(IdentityDeletionProcessId deletionProcessId, DeviceId deviceId) + { + EnsureIdentityOwnsDevice(deviceId); + + var deletionProcess = GetDeletionProcess(deletionProcessId); + deletionProcess.Reject(Address, deviceId); + + return deletionProcess; + } + private void EnsureDeletionProcessInStatusExists(DeletionProcessStatus status) { var deletionProcess = DeletionProcesses.Any(d => d.Status == status); if (!deletionProcess) - throw new DomainException(DomainErrors.NoDeletionProcessWithRequiredStatusExists()); + throw new DomainException(DomainErrors.DeletionProcessMustBeInStatus(status)); } private void EnsureNoActiveProcessExists() @@ -144,6 +156,12 @@ private void EnsureNoActiveProcessExists() throw new DomainException(DomainErrors.OnlyOneActiveDeletionProcessAllowed()); } + private void EnsureIdentityOwnsDevice(DeviceId currentDeviceId) + { + if (!Devices.Exists(device => device.Id == currentDeviceId)) + throw new DomainException(GenericDomainErrors.NotFound(nameof(Device))); + } + public void DeletionGracePeriodReminder1Sent() { EnsureDeletionProcessInStatusExists(DeletionProcessStatus.Approved); @@ -193,7 +211,8 @@ public enum DeletionProcessStatus { WaitingForApproval = 0, Approved = 1, - Cancelled = 2 + Cancelled = 2, + Rejected = 3 } public enum IdentityStatus diff --git a/Modules/Devices/src/Devices.Domain/Entities/Identities/IdentityDeletionProcess.cs b/Modules/Devices/src/Devices.Domain/Entities/Identities/IdentityDeletionProcess.cs index 3fb48c610d..0bc5d52de5 100644 --- a/Modules/Devices/src/Devices.Domain/Entities/Identities/IdentityDeletionProcess.cs +++ b/Modules/Devices/src/Devices.Domain/Entities/Identities/IdentityDeletionProcess.cs @@ -16,16 +16,6 @@ private IdentityDeletionProcess() Id = null!; } - public static IdentityDeletionProcess StartAsSupport(IdentityAddress createdBy) - { - return new IdentityDeletionProcess(createdBy, DeletionProcessStatus.WaitingForApproval); - } - - public static IdentityDeletionProcess StartAsOwner(IdentityAddress createdBy, DeviceId createdByDeviceId) - { - return new IdentityDeletionProcess(createdBy, createdByDeviceId); - } - private IdentityDeletionProcess(IdentityAddress createdBy, DeletionProcessStatus status) { Id = IdentityDeletionProcessId.Generate(); @@ -53,6 +43,16 @@ private void Approve(DeviceId createdByDevice) GracePeriodEndsAt = SystemTime.UtcNow.AddDays(IdentityDeletionConfiguration.LengthOfGracePeriod); } + public static IdentityDeletionProcess StartAsSupport(IdentityAddress createdBy) + { + return new IdentityDeletionProcess(createdBy, DeletionProcessStatus.WaitingForApproval); + } + + public static IdentityDeletionProcess StartAsOwner(IdentityAddress createdBy, DeviceId createdByDeviceId) + { + return new IdentityDeletionProcess(createdBy, createdByDeviceId); + } + public IdentityDeletionProcessId Id { get; } public IReadOnlyList AuditLog => _auditLog; public DeletionProcessStatus Status { get; private set; } @@ -65,6 +65,9 @@ private void Approve(DeviceId createdByDevice) public DateTime? ApprovedAt { get; private set; } public DeviceId? ApprovedByDevice { get; private set; } + public DateTime? RejectedAt { get; private set; } + public DeviceId? RejectedByDevice { get; private set; } + public DateTime? CancelledAt { get; private set; } public DeviceId? CancelledByDevice { get; private set; } @@ -74,7 +77,6 @@ private void Approve(DeviceId createdByDevice) public DateTime? GracePeriodReminder2SentAt { get; private set; } public DateTime? GracePeriodReminder3SentAt { get; private set; } - public bool IsActive() { return Status is DeletionProcessStatus.Approved or DeletionProcessStatus.WaitingForApproval; @@ -123,17 +125,37 @@ public void GracePeriodReminder3Sent(IdentityAddress address) public void Approve(IdentityAddress address, DeviceId approvedByDevice) { - if (Status != DeletionProcessStatus.WaitingForApproval) - throw new DomainException(DomainErrors.NoDeletionProcessWithRequiredStatusExists()); + EnsureStatus(DeletionProcessStatus.WaitingForApproval); Approve(approvedByDevice); _auditLog.Add(IdentityDeletionProcessAuditLogEntry.ProcessApproved(Id, address, approvedByDevice)); } + public void Reject(IdentityAddress address, DeviceId rejectedByDevice) + { + EnsureStatus(DeletionProcessStatus.WaitingForApproval); + + Reject(rejectedByDevice); + _auditLog.Add(IdentityDeletionProcessAuditLogEntry.ProcessRejected(Id, address, rejectedByDevice)); + } + + private void EnsureStatus(DeletionProcessStatus deletionProcessStatus) + { + if (Status != deletionProcessStatus) + throw new DomainException(DomainErrors.DeletionProcessMustBeInStatus(deletionProcessStatus)); + } + + private void Reject(DeviceId rejectedByDevice) + { + Status = DeletionProcessStatus.Rejected; + RejectedAt = SystemTime.UtcNow; + RejectedByDevice = rejectedByDevice; + } + public void Cancel(IdentityAddress address, DeviceId cancelledByDevice) { if (Status != DeletionProcessStatus.Approved) - throw new DomainException(DomainErrors.NoDeletionProcessWithRequiredStatusExists()); + throw new DomainException(DomainErrors.DeletionProcessMustBeInStatus(DeletionProcessStatus.Approved)); Status = DeletionProcessStatus.Cancelled; CancelledAt = SystemTime.UtcNow; diff --git a/Modules/Devices/src/Devices.Domain/Entities/Identities/IdentityDeletionProcessAuditLogEntry.cs b/Modules/Devices/src/Devices.Domain/Entities/Identities/IdentityDeletionProcessAuditLogEntry.cs index b7d11a908a..f99277d709 100644 --- a/Modules/Devices/src/Devices.Domain/Entities/Identities/IdentityDeletionProcessAuditLogEntry.cs +++ b/Modules/Devices/src/Devices.Domain/Entities/Identities/IdentityDeletionProcessAuditLogEntry.cs @@ -20,6 +20,11 @@ public static IdentityDeletionProcessAuditLogEntry ProcessApproved(IdentityDelet return new IdentityDeletionProcessAuditLogEntry(processId, "The deletion process was approved.", Hasher.HashUtf8(identityAddress.StringValue), Hasher.HashUtf8(deviceId.StringValue), DeletionProcessStatus.WaitingForApproval, DeletionProcessStatus.Approved); } + public static IdentityDeletionProcessAuditLogEntry ProcessRejected(IdentityDeletionProcessId processId, IdentityAddress identityAddress, DeviceId deviceId) + { + return new IdentityDeletionProcessAuditLogEntry(processId, "The deletion process was rejected.", Hasher.HashUtf8(identityAddress.StringValue), Hasher.HashUtf8(deviceId.StringValue), DeletionProcessStatus.WaitingForApproval, DeletionProcessStatus.Rejected); + } + public static IdentityDeletionProcessAuditLogEntry ProcessCancelled(IdentityDeletionProcessId processId, IdentityAddress identityAddress, DeviceId deviceId) { return new IdentityDeletionProcessAuditLogEntry(processId, "The deletion process was cancelled.", Hasher.HashUtf8(identityAddress.StringValue), Hasher.HashUtf8(deviceId.StringValue), DeletionProcessStatus.Approved, DeletionProcessStatus.Cancelled); diff --git a/Modules/Devices/src/Devices.Infrastructure.Database.Postgres/Migrations/20240223141956_AddProcessRejectionProperties.Designer.cs b/Modules/Devices/src/Devices.Infrastructure.Database.Postgres/Migrations/20240223141956_AddProcessRejectionProperties.Designer.cs new file mode 100644 index 0000000000..e91d5ba1f5 --- /dev/null +++ b/Modules/Devices/src/Devices.Infrastructure.Database.Postgres/Migrations/20240223141956_AddProcessRejectionProperties.Designer.cs @@ -0,0 +1,873 @@ +// +using System; +using Backbone.Modules.Devices.Infrastructure.Persistence.Database; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace Backbone.Modules.Devices.Infrastructure.Database.Postgres.Migrations +{ + [DbContext(typeof(DevicesDbContext))] + [Migration("20240223141956_AddProcessRejectionProperties")] + partial class AddProcessRejectionProperties + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.1") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Aggregates.PushNotifications.PnsRegistration", b => + { + b.Property("DeviceId") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.Property("AppId") + .IsRequired() + .HasColumnType("text"); + + b.Property("DevicePushIdentifier") + .IsRequired() + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.Property("Environment") + .HasColumnType("integer"); + + b.Property("Handle") + .IsRequired() + .HasMaxLength(200) + .IsUnicode(true) + .HasColumnType("character varying(200)") + .IsFixedLength(false); + + b.Property("IdentityAddress") + .IsRequired() + .HasMaxLength(36) + .IsUnicode(false) + .HasColumnType("character(36)") + .IsFixedLength(); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("DeviceId"); + + b.ToTable("PnsRegistrations"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Aggregates.Tier.Tier", b => + { + b.Property("Id") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.Property("Name") + .IsRequired() + .HasMaxLength(30) + .IsUnicode(true) + .HasColumnType("character varying(30)") + .IsFixedLength(false); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("Tiers"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Challenge", b => + { + b.Property("Id") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.Property("ExpiresAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("Challenges", "Challenges", t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", b => + { + b.Property("Id") + .HasColumnType("text"); + + b.Property("AccessFailedCount") + .HasColumnType("integer"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DeviceId") + .IsRequired() + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.Property("LastLoginAt") + .HasColumnType("timestamp with time zone"); + + b.Property("LockoutEnabled") + .HasColumnType("boolean"); + + b.Property("LockoutEnd") + .HasColumnType("timestamp with time zone"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("PasswordHash") + .HasColumnType("text"); + + b.Property("SecurityStamp") + .HasColumnType("text"); + + b.Property("UserName") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.HasKey("Id"); + + b.HasIndex("DeviceId") + .IsUnique(); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.Device", b => + { + b.Property("Id") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("CreatedByDevice") + .IsRequired() + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.Property("DeletedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DeletedByDevice") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.Property("IdentityAddress") + .IsRequired() + .HasMaxLength(36) + .IsUnicode(false) + .HasColumnType("character(36)") + .IsFixedLength(); + + b.HasKey("Id"); + + b.HasIndex("IdentityAddress"); + + b.ToTable("Devices"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.Identity", b => + { + b.Property("Address") + .HasMaxLength(36) + .IsUnicode(false) + .HasColumnType("character(36)") + .IsFixedLength(); + + b.Property("ClientId") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DeletionGracePeriodEndsAt") + .HasColumnType("timestamp with time zone"); + + b.Property("IdentityVersion") + .HasColumnType("smallint"); + + b.Property("PublicKey") + .IsRequired() + .HasColumnType("bytea"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("TierId") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.Property("TierIdBeforeDeletion") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.HasKey("Address"); + + b.ToTable("Identities"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcess", b => + { + b.Property("Id") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.Property("ApprovalReminder1SentAt") + .HasColumnType("timestamp with time zone"); + + b.Property("ApprovalReminder2SentAt") + .HasColumnType("timestamp with time zone"); + + b.Property("ApprovalReminder3SentAt") + .HasColumnType("timestamp with time zone"); + + b.Property("ApprovedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("ApprovedByDevice") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("GracePeriodEndsAt") + .HasColumnType("timestamp with time zone"); + + b.Property("GracePeriodReminder1SentAt") + .HasColumnType("timestamp with time zone"); + + b.Property("GracePeriodReminder2SentAt") + .HasColumnType("timestamp with time zone"); + + b.Property("GracePeriodReminder3SentAt") + .HasColumnType("timestamp with time zone"); + + b.Property("IdentityAddress") + .HasMaxLength(36) + .IsUnicode(false) + .HasColumnType("character(36)") + .IsFixedLength(); + + b.Property("RejectedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("RejectedByDevice") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.Property("Status") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("IdentityAddress"); + + b.ToTable("IdentityDeletionProcesses", (string)null); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcessAuditLogEntry", b => + { + b.Property("Id") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DeviceIdHash") + .HasColumnType("bytea"); + + b.Property("IdentityAddressHash") + .IsRequired() + .HasColumnType("bytea"); + + b.Property("IdentityDeletionProcessId") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.Property("Message") + .IsRequired() + .HasColumnType("text"); + + b.Property("NewStatus") + .HasColumnType("integer"); + + b.Property("OldStatus") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("IdentityDeletionProcessId"); + + b.ToTable("IdentityDeletionProcessAuditLog", (string)null); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreApplication", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("text"); + + b.Property("ApplicationType") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("ClientId") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("ClientSecret") + .HasColumnType("text"); + + b.Property("ClientType") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("ConcurrencyToken") + .IsConcurrencyToken() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("ConsentType") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("DefaultTier") + .IsRequired() + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + + b.Property("DisplayName") + .HasColumnType("text"); + + b.Property("DisplayNames") + .HasColumnType("text"); + + b.Property("JsonWebKeySet") + .HasColumnType("text"); + + b.Property("MaxIdentities") + .HasColumnType("integer"); + + b.Property("Permissions") + .HasColumnType("text"); + + b.Property("PostLogoutRedirectUris") + .HasColumnType("text"); + + b.Property("Properties") + .HasColumnType("text"); + + b.Property("RedirectUris") + .HasColumnType("text"); + + b.Property("Requirements") + .HasColumnType("text"); + + b.Property("Settings") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("ClientId") + .IsUnique(); + + b.HasIndex("DefaultTier"); + + b.ToTable("OpenIddictApplications", (string)null); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreAuthorization", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("text"); + + b.Property("ApplicationId") + .HasColumnType("text"); + + b.Property("ConcurrencyToken") + .IsConcurrencyToken() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("CreationDate") + .HasColumnType("timestamp with time zone"); + + b.Property("Properties") + .HasColumnType("text"); + + b.Property("Scopes") + .HasColumnType("text"); + + b.Property("Status") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("Subject") + .HasMaxLength(400) + .HasColumnType("character varying(400)"); + + b.Property("Type") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.HasIndex("ApplicationId", "Status", "Subject", "Type"); + + b.ToTable("OpenIddictAuthorizations", (string)null); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreScope", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("text"); + + b.Property("ConcurrencyToken") + .IsConcurrencyToken() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("Description") + .HasColumnType("text"); + + b.Property("Descriptions") + .HasColumnType("text"); + + b.Property("DisplayName") + .HasColumnType("text"); + + b.Property("DisplayNames") + .HasColumnType("text"); + + b.Property("Name") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("Properties") + .HasColumnType("text"); + + b.Property("Resources") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("OpenIddictScopes", (string)null); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("text"); + + b.Property("ApplicationId") + .HasColumnType("text"); + + b.Property("AuthorizationId") + .HasColumnType("text"); + + b.Property("ConcurrencyToken") + .IsConcurrencyToken() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("CreationDate") + .HasColumnType("timestamp with time zone"); + + b.Property("ExpirationDate") + .HasColumnType("timestamp with time zone"); + + b.Property("Payload") + .HasColumnType("text"); + + b.Property("Properties") + .HasColumnType("text"); + + b.Property("RedemptionDate") + .HasColumnType("timestamp with time zone"); + + b.Property("ReferenceId") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Status") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("Subject") + .HasMaxLength(400) + .HasColumnType("character varying(400)"); + + b.Property("Type") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.HasIndex("AuthorizationId"); + + b.HasIndex("ReferenceId") + .IsUnique(); + + b.HasIndex("ApplicationId", "Status", "Subject", "Type"); + + b.ToTable("OpenIddictTokens", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("text"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("text"); + + b.Property("ClaimValue") + .HasColumnType("text"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("text"); + + b.Property("ClaimValue") + .HasColumnType("text"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("text"); + + b.Property("ProviderKey") + .HasColumnType("text"); + + b.Property("ProviderDisplayName") + .HasColumnType("text"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("text"); + + b.Property("RoleId") + .HasColumnType("text"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("text"); + + b.Property("LoginProvider") + .HasColumnType("text"); + + b.Property("Name") + .HasColumnType("text"); + + b.Property("Value") + .HasColumnType("text"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.Device", "Device") + .WithOne("User") + .HasForeignKey("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", "DeviceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Device"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.Device", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.Identity", "Identity") + .WithMany("Devices") + .HasForeignKey("IdentityAddress") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Identity"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcess", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.Identity", null) + .WithMany("DeletionProcesses") + .HasForeignKey("IdentityAddress"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcessAuditLogEntry", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcess", null) + .WithMany("AuditLog") + .HasForeignKey("IdentityDeletionProcessId"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreApplication", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Aggregates.Tier.Tier", null) + .WithMany() + .HasForeignKey("DefaultTier") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreAuthorization", b => + { + b.HasOne("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreApplication", "Application") + .WithMany("Authorizations") + .HasForeignKey("ApplicationId"); + + b.Navigation("Application"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreToken", b => + { + b.HasOne("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreApplication", "Application") + .WithMany("Tokens") + .HasForeignKey("ApplicationId"); + + b.HasOne("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreAuthorization", "Authorization") + .WithMany("Tokens") + .HasForeignKey("AuthorizationId"); + + b.Navigation("Application"); + + b.Navigation("Authorization"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.Device", b => + { + b.Navigation("User") + .IsRequired(); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.Identity", b => + { + b.Navigation("DeletionProcesses"); + + b.Navigation("Devices"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcess", b => + { + b.Navigation("AuditLog"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreApplication", b => + { + b.Navigation("Authorizations"); + + b.Navigation("Tokens"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreAuthorization", b => + { + b.Navigation("Tokens"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Modules/Devices/src/Devices.Infrastructure.Database.Postgres/Migrations/20240223141956_AddProcessRejectionProperties.cs b/Modules/Devices/src/Devices.Infrastructure.Database.Postgres/Migrations/20240223141956_AddProcessRejectionProperties.cs new file mode 100644 index 0000000000..c0351557ee --- /dev/null +++ b/Modules/Devices/src/Devices.Infrastructure.Database.Postgres/Migrations/20240223141956_AddProcessRejectionProperties.cs @@ -0,0 +1,42 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Backbone.Modules.Devices.Infrastructure.Database.Postgres.Migrations +{ + /// + public partial class AddProcessRejectionProperties : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "RejectedAt", + table: "IdentityDeletionProcesses", + type: "timestamp with time zone", + nullable: true); + + migrationBuilder.AddColumn( + name: "RejectedByDevice", + table: "IdentityDeletionProcesses", + type: "character(20)", + unicode: false, + fixedLength: true, + maxLength: 20, + nullable: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "RejectedAt", + table: "IdentityDeletionProcesses"); + + migrationBuilder.DropColumn( + name: "RejectedByDevice", + table: "IdentityDeletionProcesses"); + } + } +} diff --git a/Modules/Devices/src/Devices.Infrastructure.Database.Postgres/Migrations/DevicesDbContextModelSnapshot.cs b/Modules/Devices/src/Devices.Infrastructure.Database.Postgres/Migrations/DevicesDbContextModelSnapshot.cs index 87d482aaa9..c9385e3527 100644 --- a/Modules/Devices/src/Devices.Infrastructure.Database.Postgres/Migrations/DevicesDbContextModelSnapshot.cs +++ b/Modules/Devices/src/Devices.Infrastructure.Database.Postgres/Migrations/DevicesDbContextModelSnapshot.cs @@ -309,6 +309,15 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasColumnType("character(36)") .IsFixedLength(); + b.Property("RejectedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("RejectedByDevice") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("character(20)") + .IsFixedLength(); + b.Property("Status") .HasColumnType("integer"); diff --git a/Modules/Devices/src/Devices.Infrastructure.Database.SqlServer/Migrations/20240223141945_AddProcessRejectionProperties.Designer.cs b/Modules/Devices/src/Devices.Infrastructure.Database.SqlServer/Migrations/20240223141945_AddProcessRejectionProperties.Designer.cs new file mode 100644 index 0000000000..9089f1a688 --- /dev/null +++ b/Modules/Devices/src/Devices.Infrastructure.Database.SqlServer/Migrations/20240223141945_AddProcessRejectionProperties.Designer.cs @@ -0,0 +1,878 @@ +// +using System; +using Backbone.Modules.Devices.Infrastructure.Persistence.Database; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Backbone.Modules.Devices.Infrastructure.Database.SqlServer.Migrations +{ + [DbContext(typeof(DevicesDbContext))] + [Migration("20240223141945_AddProcessRejectionProperties")] + partial class AddProcessRejectionProperties + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.1") + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Aggregates.PushNotifications.PnsRegistration", b => + { + b.Property("DeviceId") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.Property("AppId") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("DevicePushIdentifier") + .IsRequired() + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.Property("Environment") + .HasColumnType("int"); + + b.Property("Handle") + .IsRequired() + .HasMaxLength(200) + .IsUnicode(true) + .HasColumnType("nvarchar(200)") + .IsFixedLength(false); + + b.Property("IdentityAddress") + .IsRequired() + .HasMaxLength(36) + .IsUnicode(false) + .HasColumnType("char(36)") + .IsFixedLength(); + + b.Property("UpdatedAt") + .HasColumnType("datetime2"); + + b.HasKey("DeviceId"); + + b.ToTable("PnsRegistrations"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Aggregates.Tier.Tier", b => + { + b.Property("Id") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.Property("Name") + .IsRequired() + .HasMaxLength(30) + .IsUnicode(true) + .HasColumnType("nvarchar(30)") + .IsFixedLength(false); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("Tiers"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Challenge", b => + { + b.Property("Id") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.Property("ExpiresAt") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.ToTable("Challenges", "Challenges", t => + { + t.ExcludeFromMigrations(); + }); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", b => + { + b.Property("Id") + .HasColumnType("nvarchar(450)"); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeviceId") + .IsRequired() + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.Property("LastLoginAt") + .HasColumnType("datetime2"); + + b.Property("LockoutEnabled") + .HasColumnType("bit"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("PasswordHash") + .HasColumnType("nvarchar(max)"); + + b.Property("SecurityStamp") + .HasColumnType("nvarchar(max)"); + + b.Property("UserName") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.HasKey("Id"); + + b.HasIndex("DeviceId") + .IsUnique(); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex") + .HasFilter("[NormalizedUserName] IS NOT NULL"); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.Device", b => + { + b.Property("Id") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("CreatedByDevice") + .IsRequired() + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.Property("DeletedAt") + .HasColumnType("datetime2"); + + b.Property("DeletedByDevice") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.Property("IdentityAddress") + .IsRequired() + .HasMaxLength(36) + .IsUnicode(false) + .HasColumnType("char(36)") + .IsFixedLength(); + + b.HasKey("Id"); + + b.HasIndex("IdentityAddress"); + + b.ToTable("Devices"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.Identity", b => + { + b.Property("Address") + .HasMaxLength(36) + .IsUnicode(false) + .HasColumnType("char(36)") + .IsFixedLength(); + + b.Property("ClientId") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeletionGracePeriodEndsAt") + .HasColumnType("datetime2"); + + b.Property("IdentityVersion") + .HasColumnType("tinyint"); + + b.Property("PublicKey") + .IsRequired() + .HasColumnType("varbinary(max)"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("TierId") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.Property("TierIdBeforeDeletion") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.HasKey("Address"); + + b.ToTable("Identities"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcess", b => + { + b.Property("Id") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.Property("ApprovalReminder1SentAt") + .HasColumnType("datetime2"); + + b.Property("ApprovalReminder2SentAt") + .HasColumnType("datetime2"); + + b.Property("ApprovalReminder3SentAt") + .HasColumnType("datetime2"); + + b.Property("ApprovedAt") + .HasColumnType("datetime2"); + + b.Property("ApprovedByDevice") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("GracePeriodEndsAt") + .HasColumnType("datetime2"); + + b.Property("GracePeriodReminder1SentAt") + .HasColumnType("datetime2"); + + b.Property("GracePeriodReminder2SentAt") + .HasColumnType("datetime2"); + + b.Property("GracePeriodReminder3SentAt") + .HasColumnType("datetime2"); + + b.Property("IdentityAddress") + .HasMaxLength(36) + .IsUnicode(false) + .HasColumnType("char(36)") + .IsFixedLength(); + + b.Property("RejectedAt") + .HasColumnType("datetime2"); + + b.Property("RejectedByDevice") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.Property("Status") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("IdentityAddress"); + + b.ToTable("IdentityDeletionProcesses", (string)null); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcessAuditLogEntry", b => + { + b.Property("Id") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DeviceIdHash") + .HasColumnType("varbinary(max)"); + + b.Property("IdentityAddressHash") + .IsRequired() + .HasColumnType("varbinary(max)"); + + b.Property("IdentityDeletionProcessId") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.Property("Message") + .IsRequired() + .HasColumnType("nvarchar(max)"); + + b.Property("NewStatus") + .HasColumnType("int"); + + b.Property("OldStatus") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("IdentityDeletionProcessId"); + + b.ToTable("IdentityDeletionProcessAuditLog", (string)null); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreApplication", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("nvarchar(450)"); + + b.Property("ApplicationType") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("ClientId") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("ClientSecret") + .HasColumnType("nvarchar(max)"); + + b.Property("ClientType") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("ConcurrencyToken") + .IsConcurrencyToken() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("ConsentType") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("CreatedAt") + .HasColumnType("datetime2"); + + b.Property("DefaultTier") + .IsRequired() + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + + b.Property("DisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("DisplayNames") + .HasColumnType("nvarchar(max)"); + + b.Property("JsonWebKeySet") + .HasColumnType("nvarchar(max)"); + + b.Property("MaxIdentities") + .HasColumnType("int"); + + b.Property("Permissions") + .HasColumnType("nvarchar(max)"); + + b.Property("PostLogoutRedirectUris") + .HasColumnType("nvarchar(max)"); + + b.Property("Properties") + .HasColumnType("nvarchar(max)"); + + b.Property("RedirectUris") + .HasColumnType("nvarchar(max)"); + + b.Property("Requirements") + .HasColumnType("nvarchar(max)"); + + b.Property("Settings") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("ClientId") + .IsUnique() + .HasFilter("[ClientId] IS NOT NULL"); + + b.HasIndex("DefaultTier"); + + b.ToTable("OpenIddictApplications", (string)null); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreAuthorization", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("nvarchar(450)"); + + b.Property("ApplicationId") + .HasColumnType("nvarchar(450)"); + + b.Property("ConcurrencyToken") + .IsConcurrencyToken() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("Properties") + .HasColumnType("nvarchar(max)"); + + b.Property("Scopes") + .HasColumnType("nvarchar(max)"); + + b.Property("Status") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Subject") + .HasMaxLength(400) + .HasColumnType("nvarchar(400)"); + + b.Property("Type") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.HasIndex("ApplicationId", "Status", "Subject", "Type"); + + b.ToTable("OpenIddictAuthorizations", (string)null); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreScope", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("nvarchar(450)"); + + b.Property("ConcurrencyToken") + .IsConcurrencyToken() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("Descriptions") + .HasColumnType("nvarchar(max)"); + + b.Property("DisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("DisplayNames") + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasMaxLength(200) + .HasColumnType("nvarchar(200)"); + + b.Property("Properties") + .HasColumnType("nvarchar(max)"); + + b.Property("Resources") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique() + .HasFilter("[Name] IS NOT NULL"); + + b.ToTable("OpenIddictScopes", (string)null); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreToken", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("nvarchar(450)"); + + b.Property("ApplicationId") + .HasColumnType("nvarchar(450)"); + + b.Property("AuthorizationId") + .HasColumnType("nvarchar(450)"); + + b.Property("ConcurrencyToken") + .IsConcurrencyToken() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("CreationDate") + .HasColumnType("datetime2"); + + b.Property("ExpirationDate") + .HasColumnType("datetime2"); + + b.Property("Payload") + .HasColumnType("nvarchar(max)"); + + b.Property("Properties") + .HasColumnType("nvarchar(max)"); + + b.Property("RedemptionDate") + .HasColumnType("datetime2"); + + b.Property("ReferenceId") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("Status") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Subject") + .HasMaxLength(400) + .HasColumnType("nvarchar(400)"); + + b.Property("Type") + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.HasKey("Id"); + + b.HasIndex("AuthorizationId"); + + b.HasIndex("ReferenceId") + .IsUnique() + .HasFilter("[ReferenceId] IS NOT NULL"); + + b.HasIndex("ApplicationId", "Status", "Subject", "Type"); + + b.ToTable("OpenIddictTokens", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("nvarchar(450)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex") + .HasFilter("[NormalizedName] IS NOT NULL"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderKey") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("nvarchar(450)"); + + b.Property("RoleId") + .HasColumnType("nvarchar(450)"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("nvarchar(450)"); + + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("Name") + .HasColumnType("nvarchar(450)"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.Device", "Device") + .WithOne("User") + .HasForeignKey("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", "DeviceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Device"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.Device", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.Identity", "Identity") + .WithMany("Devices") + .HasForeignKey("IdentityAddress") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Identity"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcess", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.Identity", null) + .WithMany("DeletionProcesses") + .HasForeignKey("IdentityAddress"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcessAuditLogEntry", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcess", null) + .WithMany("AuditLog") + .HasForeignKey("IdentityDeletionProcessId"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreApplication", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Aggregates.Tier.Tier", null) + .WithMany() + .HasForeignKey("DefaultTier") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreAuthorization", b => + { + b.HasOne("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreApplication", "Application") + .WithMany("Authorizations") + .HasForeignKey("ApplicationId"); + + b.Navigation("Application"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreToken", b => + { + b.HasOne("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreApplication", "Application") + .WithMany("Tokens") + .HasForeignKey("ApplicationId"); + + b.HasOne("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreAuthorization", "Authorization") + .WithMany("Tokens") + .HasForeignKey("AuthorizationId"); + + b.Navigation("Application"); + + b.Navigation("Authorization"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Backbone.Modules.Devices.Domain.Entities.Identities.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.Device", b => + { + b.Navigation("User") + .IsRequired(); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.Identity", b => + { + b.Navigation("DeletionProcesses"); + + b.Navigation("Devices"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Domain.Entities.Identities.IdentityDeletionProcess", b => + { + b.Navigation("AuditLog"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreApplication", b => + { + b.Navigation("Authorizations"); + + b.Navigation("Tokens"); + }); + + modelBuilder.Entity("Backbone.Modules.Devices.Infrastructure.OpenIddict.CustomOpenIddictEntityFrameworkCoreAuthorization", b => + { + b.Navigation("Tokens"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Modules/Devices/src/Devices.Infrastructure.Database.SqlServer/Migrations/20240223141945_AddProcessRejectionProperties.cs b/Modules/Devices/src/Devices.Infrastructure.Database.SqlServer/Migrations/20240223141945_AddProcessRejectionProperties.cs new file mode 100644 index 0000000000..7f397dedb0 --- /dev/null +++ b/Modules/Devices/src/Devices.Infrastructure.Database.SqlServer/Migrations/20240223141945_AddProcessRejectionProperties.cs @@ -0,0 +1,42 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Backbone.Modules.Devices.Infrastructure.Database.SqlServer.Migrations +{ + /// + public partial class AddProcessRejectionProperties : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "RejectedAt", + table: "IdentityDeletionProcesses", + type: "datetime2", + nullable: true); + + migrationBuilder.AddColumn( + name: "RejectedByDevice", + table: "IdentityDeletionProcesses", + type: "char(20)", + unicode: false, + fixedLength: true, + maxLength: 20, + nullable: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "RejectedAt", + table: "IdentityDeletionProcesses"); + + migrationBuilder.DropColumn( + name: "RejectedByDevice", + table: "IdentityDeletionProcesses"); + } + } +} diff --git a/Modules/Devices/src/Devices.Infrastructure.Database.SqlServer/Migrations/ApplicationDbContextModelSnapshot.cs b/Modules/Devices/src/Devices.Infrastructure.Database.SqlServer/Migrations/ApplicationDbContextModelSnapshot.cs index fdaee05a4c..1496e65760 100644 --- a/Modules/Devices/src/Devices.Infrastructure.Database.SqlServer/Migrations/ApplicationDbContextModelSnapshot.cs +++ b/Modules/Devices/src/Devices.Infrastructure.Database.SqlServer/Migrations/ApplicationDbContextModelSnapshot.cs @@ -310,6 +310,15 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasColumnType("char(36)") .IsFixedLength(); + b.Property("RejectedAt") + .HasColumnType("datetime2"); + + b.Property("RejectedByDevice") + .HasMaxLength(20) + .IsUnicode(false) + .HasColumnType("char(20)") + .IsFixedLength(); + b.Property("Status") .HasColumnType("int"); diff --git a/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/ApproveDeletionProcess/HandlerTests.cs b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/ApproveDeletionProcess/HandlerTests.cs index 7a2a034511..7b3bad696f 100644 --- a/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/ApproveDeletionProcess/HandlerTests.cs +++ b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/ApproveDeletionProcess/HandlerTests.cs @@ -1,7 +1,6 @@ using Backbone.BuildingBlocks.Application.Abstractions.Exceptions; using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.EventBus; using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.UserContext; -using Backbone.BuildingBlocks.Domain; using Backbone.Modules.Devices.Application.Identities.Commands.ApproveDeletionProcess; using Backbone.Modules.Devices.Application.Infrastructure.Persistence.Repository; using Backbone.Modules.Devices.Domain.Aggregates.Tier; @@ -78,60 +77,6 @@ public void Throws_when_given_identity_does_not_exist() acting.Should().AwaitThrowAsync().Which.Message.Should().Contain("Identity"); } - [Fact] - public void Throws_when_deletion_process_does_not_exist() - { - // Arrange - var utcNow = DateTime.Parse("2000-01-01"); - SystemTime.Set(utcNow); - - var identity = TestDataGenerator.CreateIdentityWithDeletionProcessWaitingForApproval(DateTime.Parse("2000-01-10")); - var identityDevice = identity.Devices[0]; - - var fakeUserContext = A.Fake(); - A.CallTo(() => fakeUserContext.GetAddress()).Returns(identity.Address); - A.CallTo(() => fakeUserContext.GetDeviceId()).Returns(identityDevice.Id); - - var mockIdentitiesRepository = A.Fake(); - A.CallTo(() => mockIdentitiesRepository.FindByAddress(identity.Address, A._, A._)) - .Returns(identity); - - var handler = CreateHandler(mockIdentitiesRepository, fakeUserContext); - - // Act - var acting = async () => await handler.Handle(new ApproveDeletionProcessCommand("IDP00000000000000001"), CancellationToken.None); - - // Assert - acting.Should().AwaitThrowAsync().Which.Code.Should().Be("error.platform.recordNotFound"); - } - - [Fact] - public void Throws_when_deletion_process_is_not_waiting_for_approval() - { - // Arrange - var utcNow = DateTime.Parse("2000-01-01"); - SystemTime.Set(utcNow); - - var identity = TestDataGenerator.CreateIdentityWithApprovedDeletionProcess(DateTime.Parse("2000-01-10")); - var identityDevice = identity.Devices[0]; - - var fakeUserContext = A.Fake(); - A.CallTo(() => fakeUserContext.GetAddress()).Returns(identity.Address); - A.CallTo(() => fakeUserContext.GetDeviceId()).Returns(identityDevice.Id); - - var mockIdentitiesRepository = A.Fake(); - A.CallTo(() => mockIdentitiesRepository.FindByAddress(identity.Address, A._, A._)) - .Returns(identity); - - var handler = CreateHandler(mockIdentitiesRepository, fakeUserContext); - - // Act - var acting = async () => await handler.Handle(new ApproveDeletionProcessCommand(identity.DeletionProcesses.FirstOrDefault()!.Id), CancellationToken.None); - - // Assert - acting.Should().AwaitThrowAsync().Which.Code.Should().Be("error.platform.validation.device.noDeletionProcessWithRequiredStatusExists"); - } - private static Handler CreateHandler(IIdentitiesRepository identitiesRepository, IUserContext userContext, IEventBus? eventBus = null) { eventBus ??= A.Fake(); diff --git a/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/RejectDeletionProcess/HandlerTests.cs b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/RejectDeletionProcess/HandlerTests.cs new file mode 100644 index 0000000000..739a07daba --- /dev/null +++ b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/RejectDeletionProcess/HandlerTests.cs @@ -0,0 +1,77 @@ +using Backbone.BuildingBlocks.Application.Abstractions.Exceptions; +using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.UserContext; +using Backbone.Modules.Devices.Application.Identities.Commands.RejectDeletionProcess; +using Backbone.Modules.Devices.Application.Infrastructure.Persistence.Repository; +using Backbone.Modules.Devices.Domain.Entities.Identities; +using Backbone.Tooling; +using Backbone.UnitTestTools.Extensions; +using FakeItEasy; +using FluentAssertions; +using Xunit; +using static Backbone.UnitTestTools.Data.TestDataGenerator; + +namespace Backbone.Modules.Devices.Application.Tests.Tests.Identities.Commands.RejectDeletionProcess; +public class HandlerTests +{ + [Fact] + public async void Happy_path() + { + // Arrange + var utcNow = DateTime.Parse("2000-01-01"); + SystemTime.Set(utcNow); + + var identity = TestDataGenerator.CreateIdentityWithDeletionProcessWaitingForApproval(utcNow); + var deletionProcess = identity.GetDeletionProcessInStatus(DeletionProcessStatus.WaitingForApproval)!; + var device = identity.Devices[0]; + + var fakeUserContext = A.Fake(); + A.CallTo(() => fakeUserContext.GetAddress()).Returns(identity.Address); + A.CallTo(() => fakeUserContext.GetDeviceId()).Returns(device.Id); + + var mockIdentitiesRepository = A.Fake(); + A.CallTo(() => mockIdentitiesRepository.FindByAddress(identity.Address, A._, A._)) + .Returns(identity); + + var handler = CreateHandler(mockIdentitiesRepository, fakeUserContext); + + // Act + var response = await handler.Handle(new RejectDeletionProcessCommand(deletionProcess.Id), CancellationToken.None); + + // Assert + A.CallTo(() => mockIdentitiesRepository.Update(A.That.Matches(i => + i.Address == identity.Address + && i.Status == IdentityStatus.Active + && i.DeletionProcesses.Any(d => d.Id == deletionProcess.Id)), A._)) + .MustHaveHappenedOnceExactly(); + + response.Id.Should().Be(deletionProcess.Id); + response.Status.Should().Be(DeletionProcessStatus.Rejected); + response.RejectedAt.Should().Be(utcNow); + response.RejectedByDevice.Should().Be(device.Id); + } + + [Fact] + public void Throws_when_given_identity_does_not_exist() + { + // Arrange + var address = CreateRandomIdentityAddress(); + var fakeIdentitiesRepository = A.Fake(); + var fakeUserContext = A.Fake(); + A.CallTo(() => fakeUserContext.GetAddress()).Returns(address); + + A.CallTo(() => fakeIdentitiesRepository.FindByAddress(address, A._, A._)).Returns(null); + + var handler = CreateHandler(fakeIdentitiesRepository, fakeUserContext); + + // Act + var acting = async () => await handler.Handle(new RejectDeletionProcessCommand("some-deletion-process-id"), CancellationToken.None); + + // Assert + acting.Should().AwaitThrowAsync().Which.Message.Should().Contain("Identity"); + } + + private static Handler CreateHandler(IIdentitiesRepository identitiesRepository, IUserContext userContext) + { + return new Handler(identitiesRepository, userContext); + } +} diff --git a/Modules/Devices/test/Devices.Domain.Tests/Identities/ApproveDeletionProcessTests.cs b/Modules/Devices/test/Devices.Domain.Tests/Identities/ApproveDeletionProcessTests.cs index 646a464640..008e809262 100644 --- a/Modules/Devices/test/Devices.Domain.Tests/Identities/ApproveDeletionProcessTests.cs +++ b/Modules/Devices/test/Devices.Domain.Tests/Identities/ApproveDeletionProcessTests.cs @@ -15,12 +15,13 @@ public class ApproveDeletionProcessTests public void Approve_deletion_process_waiting_for_approval() { // Arrange - var currentDateTime = DateTime.Parse("2000-01-01"); - SystemTime.Set(currentDateTime); + SystemTime.Set(DateTime.Parse("2000-01-01")); var identity = CreateIdentityWithDeletionProcessWaitingForApproval(); + identity.Devices.Add(new Device(identity)); + var deviceId = identity.Devices[0].Id; // Act - identity.ApproveDeletionProcess(identity.GetDeletionProcessInStatus(DeletionProcessStatus.WaitingForApproval)!.Id, DeviceId.Parse("DVC")); + identity.ApproveDeletionProcess(identity.GetDeletionProcessInStatus(DeletionProcessStatus.WaitingForApproval)!.Id, deviceId); // Assert identity.Status.Should().Be(IdentityStatus.ToBeDeleted); @@ -30,18 +31,37 @@ public void Approve_deletion_process_waiting_for_approval() AssertAuditLogEntryWasCreated(deletionProcess); } + [Fact] + public void Throws_when_device_not_owned_by_identity() + { + // Arrange + var identity = CreateIdentityWithDeletionProcessWaitingForApproval(); + + // Act + var acting = () => identity.ApproveDeletionProcess(identity.DeletionProcesses[0].Id, DeviceId.Parse("DVC")); + var exception = acting.Should().Throw().Which; + + // Assert + exception.Code.Should().Be("error.platform.recordNotFound"); + exception.Message.Should().Contain("Device"); + } + [Fact] public void Throws_when_deletion_process_does_not_exist() { // Arrange var identity = CreateIdentity(); - var identityDeletionProcessId = IdentityDeletionProcessId.Create("IDP00000000000000001").Value; + identity.Devices.Add(new Device(identity)); + var deviceId = identity.Devices[0].Id; + var deletionProcessId = IdentityDeletionProcessId.Create("IDP00000000000000001").Value; // Act - var acting = () => identity.ApproveDeletionProcess(identityDeletionProcessId, DeviceId.Parse("DVC")); + var acting = () => identity.ApproveDeletionProcess(deletionProcessId, deviceId); + var exception = acting.Should().Throw().Which; // Assert - acting.Should().Throw().Which.Code.Should().Be("error.platform.recordNotFound"); + exception.Code.Should().Be("error.platform.recordNotFound"); + exception.Message.Should().Contain("IdentityDeletionProcess"); } [Fact] @@ -49,15 +69,17 @@ public void Throws_when_deletion_process_is_not_in_status_waiting_for_approval() { // Arrange var identity = CreateIdentity(); - var activeDevice = new Device(identity); - identity.Devices.Add(activeDevice); - var deletionProcess = identity.StartDeletionProcessAsOwner(activeDevice.Id); + identity.Devices.Add(new Device(identity)); + var deviceId = identity.Devices[0].Id; + var deletionProcess = identity.StartDeletionProcessAsOwner(deviceId); // Act - var acting = () => identity.ApproveDeletionProcess(deletionProcess.Id, DeviceId.Parse("DVC")); + var acting = () => identity.ApproveDeletionProcess(deletionProcess.Id, deviceId); + var exception = acting.Should().Throw().Which; // Assert - acting.Should().Throw().Which.Code.Should().Be("error.platform.validation.device.noDeletionProcessWithRequiredStatusExists"); + exception.Code.Should().Be("error.platform.validation.device.deletionProcessMustBeInStatusWaitingForApproval"); + exception.Message.Should().Contain("WaitingForApproval"); } private static void AssertAuditLogEntryWasCreated(IdentityDeletionProcess deletionProcess) diff --git a/Modules/Devices/test/Devices.Domain.Tests/Identities/CancelDeletionProcessTests.cs b/Modules/Devices/test/Devices.Domain.Tests/Identities/CancelDeletionProcessTests.cs index 25c5b28ab2..8d0cb03724 100644 --- a/Modules/Devices/test/Devices.Domain.Tests/Identities/CancelDeletionProcessTests.cs +++ b/Modules/Devices/test/Devices.Domain.Tests/Identities/CancelDeletionProcessTests.cs @@ -54,7 +54,7 @@ public void Throws_when_deletion_process_is_in_wrong_status() var acting = () => identity.CancelDeletionProcess(identity.DeletionProcesses[0].Id, identity.Devices[0].Id); // Assert - acting.Should().Throw().Which.Code.Should().Be("error.platform.validation.device.noDeletionProcessWithRequiredStatusExists"); + acting.Should().Throw().Which.Code.Should().Be("error.platform.validation.device.deletionProcessMustBeInStatusApproved"); } private static void AssertAuditLogEntryWasCreated(IdentityDeletionProcess deletionProcess) diff --git a/Modules/Devices/test/Devices.Domain.Tests/Identities/DeletionGracePeriodReminderTests.cs b/Modules/Devices/test/Devices.Domain.Tests/Identities/DeletionGracePeriodReminderTests.cs index 59aca9a4b9..b6dbbf20c7 100644 --- a/Modules/Devices/test/Devices.Domain.Tests/Identities/DeletionGracePeriodReminderTests.cs +++ b/Modules/Devices/test/Devices.Domain.Tests/Identities/DeletionGracePeriodReminderTests.cs @@ -39,7 +39,7 @@ public void DeletionGracePeriodReminder1Sent_fails_when_no_approved_deletion_pro var acting = identity.DeletionGracePeriodReminder1Sent; // Assert - acting.Should().Throw().Which.Code.Should().Be("error.platform.validation.device.noDeletionProcessWithRequiredStatusExists"); + acting.Should().Throw().Which.Code.Should().Be("error.platform.validation.device.deletionProcessMustBeInStatusApproved"); } [Fact] @@ -71,7 +71,7 @@ public void DeletionGracePeriodReminder2Sent_fails_when_no_approved_deletion_pro var acting = identity.DeletionGracePeriodReminder2Sent; // Assert - acting.Should().Throw().Which.Code.Should().Be("error.platform.validation.device.noDeletionProcessWithRequiredStatusExists"); + acting.Should().Throw().Which.Code.Should().Be("error.platform.validation.device.deletionProcessMustBeInStatusApproved"); } [Fact] @@ -103,7 +103,7 @@ public void DeletionGracePeriodReminder3Sent_fails_when_no_approved_deletion_pro var acting = identity.DeletionGracePeriodReminder3Sent; // Assert - acting.Should().Throw().Which.Code.Should().Be("error.platform.validation.device.noDeletionProcessWithRequiredStatusExists"); + acting.Should().Throw().Which.Code.Should().Be("error.platform.validation.device.deletionProcessMustBeInStatusApproved"); } private static void AssertAuditLogEntryWasCreated(IdentityDeletionProcess deletionProcess) diff --git a/Modules/Devices/test/Devices.Domain.Tests/Identities/DeletionProcessApprovalReminderTests.cs b/Modules/Devices/test/Devices.Domain.Tests/Identities/DeletionProcessApprovalReminderTests.cs index f82ddd8b7a..b2afe2c341 100644 --- a/Modules/Devices/test/Devices.Domain.Tests/Identities/DeletionProcessApprovalReminderTests.cs +++ b/Modules/Devices/test/Devices.Domain.Tests/Identities/DeletionProcessApprovalReminderTests.cs @@ -40,7 +40,7 @@ public void DeletionProcessApprovalReminder1Sent_fails_when_no_deletion_process_ var acting = identity.DeletionProcessApprovalReminder1Sent; // Assert - acting.Should().Throw().Which.Code.Should().Be("error.platform.validation.device.noDeletionProcessWithRequiredStatusExists"); + acting.Should().Throw().Which.Code.Should().Be("error.platform.validation.device.deletionProcessMustBeInStatusWaitingForApproval"); } [Fact] @@ -72,7 +72,7 @@ public void DeletionProcessApprovalReminder2Sent_fails_when_no_deletion_process_ var acting = identity.DeletionProcessApprovalReminder2Sent; // Assert - acting.Should().Throw().Which.Code.Should().Be("error.platform.validation.device.noDeletionProcessWithRequiredStatusExists"); + acting.Should().Throw().Which.Code.Should().Be("error.platform.validation.device.deletionProcessMustBeInStatusWaitingForApproval"); } [Fact] @@ -104,7 +104,7 @@ public void DeletionProcessApprovalReminder3Sent_fails_when_no_deletion_process_ var acting = identity.DeletionProcessApprovalReminder3Sent; // Assert - acting.Should().Throw().Which.Code.Should().Be("error.platform.validation.device.noDeletionProcessWithRequiredStatusExists"); + acting.Should().Throw().Which.Code.Should().Be("error.platform.validation.device.deletionProcessMustBeInStatusWaitingForApproval"); } [Fact] diff --git a/Modules/Devices/test/Devices.Domain.Tests/Identities/RejectDeletionProcessTests.cs b/Modules/Devices/test/Devices.Domain.Tests/Identities/RejectDeletionProcessTests.cs new file mode 100644 index 0000000000..4be7986f0b --- /dev/null +++ b/Modules/Devices/test/Devices.Domain.Tests/Identities/RejectDeletionProcessTests.cs @@ -0,0 +1,109 @@ +using Backbone.BuildingBlocks.Domain; +using Backbone.DevelopmentKit.Identity.ValueObjects; +using Backbone.Modules.Devices.Domain.Aggregates.Tier; +using Backbone.Modules.Devices.Domain.Entities.Identities; +using Backbone.Modules.Devices.Domain.Tests.Identities.TestDoubles; +using Backbone.Tooling; +using FluentAssertions; +using Xunit; + +namespace Backbone.Modules.Devices.Domain.Tests.Identities; +public class RejectDeletionProcessTests +{ + [Fact] + public void Reject_deletion_process_waiting_for_approval() + { + // Arrange + SystemTime.Set(DateTime.Parse("2020-01-01")); + var identity = CreateIdentityWithDeletionProcessWaitingForApproval(); + identity.Devices.Add(new Device(identity)); + var deviceId = identity.Devices[0].Id; + + // Act + identity.RejectDeletionProcess(identity.DeletionProcesses[0].Id, deviceId); + + // Assert + var deletionProcess = identity.DeletionProcesses.FirstOrDefault(d => d.Status == DeletionProcessStatus.Rejected)!; + AssertAuditLogEntryWasCreated(deletionProcess); + } + + [Fact] + public void Throws_when_device_not_owned_by_identity() + { + // Arrange + var identity = CreateIdentityWithDeletionProcessWaitingForApproval(); + + // Act + var acting = () => identity.RejectDeletionProcess(identity.DeletionProcesses[0].Id, DeviceId.Parse("DVC")); + + // Assert + var exception = acting.Should().Throw().Which; + + exception.Code.Should().Be("error.platform.recordNotFound"); + exception.Message.Should().Contain("Device"); + } + + [Fact] + public void Throws_when_deletion_process_does_not_exist() + { + // Arrange + var identity = CreateIdentity(); + identity.Devices.Add(new Device(identity)); + var deviceId = identity.Devices[0].Id; + var deletionProcessId = IdentityDeletionProcessId.Create("IDP00000000000000001").Value; + + // Act + var acting = () => identity.RejectDeletionProcess(deletionProcessId, deviceId); + + // Assert + var exception = acting.Should().Throw().Which; + + exception.Code.Should().Be("error.platform.recordNotFound"); + exception.Message.Should().Contain("IdentityDeletionProcess"); + } + + [Fact] + public void Throws_when_deletion_process_is_not_in_status_waiting_for_approval() + { + // Arrange + var identity = CreateIdentity(); + identity.Devices.Add(new Device(identity)); + var deviceId = identity.Devices[0].Id; + var deletionProcess = identity.StartDeletionProcessAsOwner(deviceId); + + // Act + var acting = () => identity.RejectDeletionProcess(deletionProcess.Id, deviceId); + + // Assert + var exception = acting.Should().Throw().Which; + + exception.Code.Should().Be("error.platform.validation.device.deletionProcessMustBeInStatusWaitingForApproval"); + exception.Message.Should().Contain("WaitingForApproval"); + } + + private static void AssertAuditLogEntryWasCreated(IdentityDeletionProcess deletionProcess) + { + deletionProcess.AuditLog.Should().HaveCount(2); + + var auditLogEntry = deletionProcess.AuditLog[1]; + auditLogEntry.ProcessId.Should().Be(deletionProcess.Id); + auditLogEntry.CreatedAt.Should().Be(SystemTime.UtcNow); + auditLogEntry.IdentityAddressHash.Should().BeEquivalentTo(new byte[] { 1, 2, 3 }); + auditLogEntry.OldStatus.Should().Be(DeletionProcessStatus.WaitingForApproval); + auditLogEntry.NewStatus.Should().Be(DeletionProcessStatus.Rejected); + } + + private static Identity CreateIdentity() + { + var address = IdentityAddress.Create([], "id1"); + return new Identity("", address, [], TierId.Generate(), 1); + } + + private static Identity CreateIdentityWithDeletionProcessWaitingForApproval() + { + var identity = CreateIdentity(); + Hasher.SetHasher(new DummyHasher([1, 2, 3])); + identity.StartDeletionProcessAsSupport(); + return identity; + } +}