diff --git a/AdminUi/src/AdminUi/Extensions/DevicesServiceCollectionExtensions.cs b/AdminUi/src/AdminUi/Extensions/DevicesServiceCollectionExtensions.cs index 3f5ab9437d..54ae7157d9 100644 --- a/AdminUi/src/AdminUi/Extensions/DevicesServiceCollectionExtensions.cs +++ b/AdminUi/src/AdminUi/Extensions/DevicesServiceCollectionExtensions.cs @@ -15,8 +15,8 @@ public static IServiceCollection AddDevices(this IServiceCollection services, services.AddDatabase(options => { - options.ConnectionString = configuration.Infrastructure.SqlDatabase.ConnectionString; options.Provider = configuration.Infrastructure.SqlDatabase.Provider; + options.ConnectionString = configuration.Infrastructure.SqlDatabase.ConnectionString; }); services.AddSingleton(_ => SignatureHelper.CreateEd25519WithRawKeyFormat()); diff --git a/Backbone.sln.DotSettings b/Backbone.sln.DotSettings index 2b6eef206f..c1013a5907 100644 --- a/Backbone.sln.DotSettings +++ b/Backbone.sln.DotSettings @@ -38,7 +38,9 @@ True True True + True True True True - True + True + True diff --git a/BuildingBlocks/src/BuildingBlocks.Application.Abstractions/Infrastructure/Persistence/Database/IDbContext.cs b/BuildingBlocks/src/BuildingBlocks.Application.Abstractions/Infrastructure/Persistence/Database/IDbContext.cs index 04e4081c03..38b5d19c34 100644 --- a/BuildingBlocks/src/BuildingBlocks.Application.Abstractions/Infrastructure/Persistence/Database/IDbContext.cs +++ b/BuildingBlocks/src/BuildingBlocks.Application.Abstractions/Infrastructure/Persistence/Database/IDbContext.cs @@ -15,8 +15,8 @@ Task RunInTransaction(Func action, List errorNumbersToRetry, Task RunInTransaction(Func action, IsolationLevel isolationLevel); - Task RunInTransaction(Func> action, List errorNumbersToRetry, + Task RunInTransaction(Func> action, List? errorNumbersToRetry, IsolationLevel isolationLevel = IsolationLevel.ReadCommitted); - Task RunInTransaction(Func> func, IsolationLevel isolationLevel); + Task RunInTransaction(Func> func, IsolationLevel isolationLevel); } diff --git a/BuildingBlocks/src/BuildingBlocks.Infrastructure/Persistence/Database/AbstractDbContextBase.cs b/BuildingBlocks/src/BuildingBlocks.Infrastructure/Persistence/Database/AbstractDbContextBase.cs index d2dd9b9dec..2c1a28d204 100644 --- a/BuildingBlocks/src/BuildingBlocks.Infrastructure/Persistence/Database/AbstractDbContextBase.cs +++ b/BuildingBlocks/src/BuildingBlocks.Infrastructure/Persistence/Database/AbstractDbContextBase.cs @@ -69,17 +69,18 @@ public async Task RunInTransaction(Func action, IsolationLevel isolationLe await RunInTransaction(action, null, isolationLevel); } - public async Task RunInTransaction(Func> action, List? errorNumbersToRetry, + public async Task RunInTransaction(Func> action, List? errorNumbersToRetry, IsolationLevel isolationLevel = IsolationLevel.ReadCommitted) { - var response = default(T); + // the '!' is safe here because the default value is only returned after the action is executed, which is setting the response + var response = default(T)!; - await RunInTransaction(async () => response = await action(), errorNumbersToRetry, isolationLevel); + await RunInTransaction(async () => { response = await action(); }, errorNumbersToRetry, isolationLevel); return response; } - public async Task RunInTransaction(Func> func, IsolationLevel isolationLevel) + public async Task RunInTransaction(Func> func, IsolationLevel isolationLevel) { return await RunInTransaction(func, null, isolationLevel); } @@ -95,24 +96,4 @@ protected override void ConfigureConventions(ModelConfigurationBuilder configura configurationBuilder.Properties().HaveConversion(); configurationBuilder.Properties().HaveConversion(); } - - protected void RollBack() - { - var changedEntries = ChangeTracker.Entries().Where(x => x.State != EntityState.Unchanged).ToList(); - - foreach (var entry in changedEntries) - switch (entry.State) - { - case EntityState.Modified: - entry.CurrentValues.SetValues(entry.OriginalValues); - entry.State = EntityState.Unchanged; - break; - case EntityState.Added: - entry.State = EntityState.Detached; - break; - case EntityState.Deleted: - entry.State = EntityState.Unchanged; - break; - } - } } diff --git a/ConsumerApi.Tests.Integration/Features/Challenges/POST.feature b/ConsumerApi.Tests.Integration/Features/Challenges/POST.feature index 66d19358ff..064a62749a 100644 --- a/ConsumerApi.Tests.Integration/Features/Challenges/POST.feature +++ b/ConsumerApi.Tests.Integration/Features/Challenges/POST.feature @@ -17,24 +17,24 @@ Scenario: Creating a Challenge as an authenticated user And the response contains a Challenge And the Challenge contains information about the creator -@ignore("skipping_due_to_required_backbone_changes") -Scenario: Creating a Challenge with a JSON sent in the request content - When a POST request is sent to the Challenges endpoint with - | Key | Value | - | Content | {"this": "is some arbitrary json"} | - Then the response status code is 415 (Unsupported Media Type) - -@ignore("skipping_due_to_required_backbone_changes") -Scenario: Creating a Challenge with an invalid JSON sent in the request content - When a POST request is sent to the Challenges endpoint with - | Key | Value | - | Content | { "thisJSON": "has an extra }" }} | - Then the response status code is 415 (Unsupported Media Type) - -@ignore("skipping_due_to_required_backbone_changes") -Scenario: Creating a Challenge with an unsupported Content-Type header - When a POST request is sent to the Challenges endpoint with - | Key | Value | - | ContentType | application/xml | - | Content | is some arbitrary xml | - Then the response status code is 415 (Unsupported Media Type) +#@ignore("skipping_due_to_required_backbone_changes") +#Scenario: Creating a Challenge with a JSON sent in the request content +# When a POST request is sent to the Challenges endpoint with +# | Key | Value | +# | Content | {"this": "is some arbitrary json"} | +# Then the response status code is 415 (Unsupported Media Type) +# +#@ignore("skipping_due_to_required_backbone_changes") +#Scenario: Creating a Challenge with an invalid JSON sent in the request content +# When a POST request is sent to the Challenges endpoint with +# | Key | Value | +# | Content | { "thisJSON": "has an extra }" }} | +# Then the response status code is 415 (Unsupported Media Type) +# +#@ignore("skipping_due_to_required_backbone_changes") +#Scenario: Creating a Challenge with an unsupported Content-Type header +# When a POST request is sent to the Challenges endpoint with +# | Key | Value | +# | ContentType | application/xml | +# | Content | is some arbitrary xml | +# Then the response status code is 415 (Unsupported Media Type) diff --git a/ConsumerApi.Tests.Integration/Features/Challenges/{id}/GET.feature b/ConsumerApi.Tests.Integration/Features/Challenges/{id}/GET.feature index 5558069e89..32dc1559f4 100644 --- a/ConsumerApi.Tests.Integration/Features/Challenges/{id}/GET.feature +++ b/ConsumerApi.Tests.Integration/Features/Challenges/{id}/GET.feature @@ -21,23 +21,23 @@ Scenario: Requesting a nonexistent Challenge as an authenticated user When a GET request is sent to the Challenges/{id} endpoint with "CHLthisisnonexisting" Then the response status code is 404 (Not Found) -@ignore("skipping_due_to_required_backbone_changes") -Scenario: Requesting a Challenge with an unsupported Accept Header as an authenticated user - Given the user is authenticated - And the Accept header is 'application/xml' - When a GET request is sent to the Challenges/{id} endpoint with a valid Id - Then the response status code is 406 (Not Acceptable) - -@ignore("skipping_due_to_required_backbone_changes") -Scenario Outline: Requesting a Challenge with an invalid id as an authenticated user - Given the user is authenticated - When a GET request is sent to the Challenges/{id} endpoint with - Then the response status code is 400 (Bad Request) - And the response content includes an error with the error code "error.platform.invalidId" -Examples: - | id | description | - | CHLthishastoomanycharacters | More than 20 characters | - | CHLnotenoughchars | Less than 20 characters | - | !CHLdfhuwnjdfnjnjfnd | Contains invalid characters | - | CHL_frfssd_fdfdsed#_ | Contains invalid characters | - | PHLfdjfdjflndjkfndjk | Does not have CHL prefix | \ No newline at end of file +#@ignore("skipping_due_to_required_backbone_changes") +#Scenario: Requesting a Challenge with an unsupported Accept Header as an authenticated user +# Given the user is authenticated +# And the Accept header is 'application/xml' +# When a GET request is sent to the Challenges/{id} endpoint with a valid Id +# Then the response status code is 406 (Not Acceptable) +# +#@ignore("skipping_due_to_required_backbone_changes") +#Scenario Outline: Requesting a Challenge with an invalid id as an authenticated user +# Given the user is authenticated +# When a GET request is sent to the Challenges/{id} endpoint with +# Then the response status code is 400 (Bad Request) +# And the response content includes an error with the error code "error.platform.invalidId" +#Examples: +# | id | description | +# | CHLthishastoomanycharacters | More than 20 characters | +# | CHLnotenoughchars | Less than 20 characters | +# | !CHLdfhuwnjdfnjnjfnd | Contains invalid characters | +# | CHL_frfssd_fdfdsed#_ | Contains invalid characters | +# | PHLfdjfdjflndjkfndjk | Does not have CHL prefix | diff --git a/ConsumerApi.Tests.Integration/Features/Tokens/POST.feature b/ConsumerApi.Tests.Integration/Features/Tokens/POST.feature index 4bf68e32cf..a110edaa11 100644 --- a/ConsumerApi.Tests.Integration/Features/Tokens/POST.feature +++ b/ConsumerApi.Tests.Integration/Features/Tokens/POST.feature @@ -1,92 +1,92 @@ -@Integration -Feature: POST Token - -User creates a Token - -Scenario: Creating a Token as an authenticated user - Given the user is authenticated - When a POST request is sent to the Tokens endpoint with - | Key | Value | - | ContentType | application/json | - | Content | {"content": "QQ==","expiresAt": ""} | - Then the response status code is 201 (Created) - And the response contains a CreateTokenResponse - -Scenario: Creating a Token as an anonymous user - Given the user is unauthenticated - When a POST request is sent to the Tokens endpoint with - | Key | Value | - | ContentType | application/json | - | Content | {"content": "QQ==","expiresAt": ""} | - Then the response status code is 401 (Unauthorized) - -@ignore("skipping_due_to_required_backbone_changes") -Scenario: Creating a Token without the "Content" request content property - Given the user is authenticated - When a POST request is sent to the Tokens endpoint with - | Key | Value | - | Content | {"expiresAt": ""} | - Then the response status code is 400 (Bad Request) - And the response content includes an error with the error code "error.platform.validation.invalidPropertyValue" - -@ignore("skipping_due_to_required_backbone_changes") -Scenario: Creating a Token with an empty "Content" request content property - Given the user is authenticated - When a POST request is sent to the Tokens endpoint with - | Key | Value | - | Content | {"content": "","expiresAt": ""} | - Then the response status code is 400 (Bad Request) - And the response content includes an error with the error code "error.platform.validation.invalidPropertyValue" - -@ignore("skipping_due_to_required_backbone_changes") -Scenario: Creating a Token with an invalid base64 in the "Content" property - Given the user is authenticated - When a POST request is sent to the Tokens endpoint with - | Key | Value | - | Content | {"content": "","expiresAt": ""} | - Then the response status code is 400 (Bad Request) - And the response content includes an error with the error code "error.platform.validation.invalidPropertyValue" - -@ignore("skipping_due_to_required_backbone_changes") -Scenario: Creating a Token without the "expiresAt" request content property - Given the user is authenticated - When a POST request is sent to the Tokens endpoint with - | Key | Value | - | Content | {"content": "QQ=="} | - Then the response status code is 400 (Bad Request) - And the response content includes an error with the error code "error.platform.validation.invalidPropertyValue" - -@ignore("skipping_due_to_required_backbone_changes") -Scenario: Creating a Token with a date in the past in the "expiresAt" request content property - Given the user is authenticated - When a POST request is sent to the Tokens endpoint with - | Key | Value | - | Content | {"content": "QQ==","expiresAt": ""} | - Then the response status code is 400 (Bad Request) - And the response content includes an error with the error code "error.platform.validation.invalidPropertyValue" - -@ignore("skipping_due_to_required_backbone_changes") -Scenario: Creating a Token without a request content - Given the user is authenticated - When a POST request is sent to the Tokens endpoint with no request content - Then the response status code is 400 (Bad Request) - And the response content includes an error with the error code "error.platform.inputCannotBeParsed" - -Scenario: Creating a Token with an unsupported Content-Type - Given the user is authenticated - When a POST request is sent to the Tokens endpoint with - | Key | Value | - | ContentType | application/xml | - | Content | is some arbitrary xml | - Then the response status code is 415 (Unsupported Media Type) - -@ignore("skipping_due_to_required_backbone_changes") -Scenario Outline: Creating a Token with an invalid DateTime format in the "expiresAt" request content property - Given the user is authenticated - When a POST request is sent to the Tokens endpoint with '', '' - Then the response status code is 400 (Bad Request) - And the response content includes an error with the error code "error.platform.validation.invalidPropertyValue" -Examples: - | Content | ExpiresAt | - | QQ== | 31/12/9999 | - | QQ== | 13-2-9999 | +@Integration +Feature: POST Token + +User creates a Token + +Scenario: Creating a Token as an authenticated user + Given the user is authenticated + When a POST request is sent to the Tokens endpoint with + | Key | Value | + | ContentType | application/json | + | Content | {"content": "QQ==","expiresAt": ""} | + Then the response status code is 201 (Created) + And the response contains a CreateTokenResponse + +Scenario: Creating a Token as an anonymous user + Given the user is unauthenticated + When a POST request is sent to the Tokens endpoint with + | Key | Value | + | ContentType | application/json | + | Content | {"content": "QQ==","expiresAt": ""} | + Then the response status code is 401 (Unauthorized) + +#@ignore("skipping_due_to_required_backbone_changes") +#Scenario: Creating a Token without the "Content" request content property +# Given the user is authenticated +# When a POST request is sent to the Tokens endpoint with +# | Key | Value | +# | Content | {"expiresAt": ""} | +# Then the response status code is 400 (Bad Request) +# And the response content includes an error with the error code "error.platform.validation.invalidPropertyValue" +# +#@ignore("skipping_due_to_required_backbone_changes") +#Scenario: Creating a Token with an empty "Content" request content property +# Given the user is authenticated +# When a POST request is sent to the Tokens endpoint with +# | Key | Value | +# | Content | {"content": "","expiresAt": ""} | +# Then the response status code is 400 (Bad Request) +# And the response content includes an error with the error code "error.platform.validation.invalidPropertyValue" +# +#@ignore("skipping_due_to_required_backbone_changes") +#Scenario: Creating a Token with an invalid base64 in the "Content" property +# Given the user is authenticated +# When a POST request is sent to the Tokens endpoint with +# | Key | Value | +# | Content | {"content": "","expiresAt": ""} | +# Then the response status code is 400 (Bad Request) +# And the response content includes an error with the error code "error.platform.validation.invalidPropertyValue" +# +#@ignore("skipping_due_to_required_backbone_changes") +#Scenario: Creating a Token without the "expiresAt" request content property +# Given the user is authenticated +# When a POST request is sent to the Tokens endpoint with +# | Key | Value | +# | Content | {"content": "QQ=="} | +# Then the response status code is 400 (Bad Request) +# And the response content includes an error with the error code "error.platform.validation.invalidPropertyValue" +# +#@ignore("skipping_due_to_required_backbone_changes") +#Scenario: Creating a Token with a date in the past in the "expiresAt" request content property +# Given the user is authenticated +# When a POST request is sent to the Tokens endpoint with +# | Key | Value | +# | Content | {"content": "QQ==","expiresAt": ""} | +# Then the response status code is 400 (Bad Request) +# And the response content includes an error with the error code "error.platform.validation.invalidPropertyValue" +# +#@ignore("skipping_due_to_required_backbone_changes") +#Scenario: Creating a Token without a request content +# Given the user is authenticated +# When a POST request is sent to the Tokens endpoint with no request content +# Then the response status code is 400 (Bad Request) +# And the response content includes an error with the error code "error.platform.inputCannotBeParsed" + +Scenario: Creating a Token with an unsupported Content-Type + Given the user is authenticated + When a POST request is sent to the Tokens endpoint with + | Key | Value | + | ContentType | application/xml | + | Content | is some arbitrary xml | + Then the response status code is 415 (Unsupported Media Type) + +#@ignore("skipping_due_to_required_backbone_changes") +#Scenario Outline: Creating a Token with an invalid DateTime format in the "expiresAt" request content property +# Given the user is authenticated +# When a POST request is sent to the Tokens endpoint with '', '' +# Then the response status code is 400 (Bad Request) +# And the response content includes an error with the error code "error.platform.validation.invalidPropertyValue" +#Examples: +# | Content | ExpiresAt | +# | QQ== | 31/12/9999 | +# | QQ== | 13-2-9999 | diff --git a/ConsumerApi.Tests.Integration/Features/Tokens/{id}/GET.feature b/ConsumerApi.Tests.Integration/Features/Tokens/{id}/GET.feature index 0506dcb3d7..c59398501d 100644 --- a/ConsumerApi.Tests.Integration/Features/Tokens/{id}/GET.feature +++ b/ConsumerApi.Tests.Integration/Features/Tokens/{id}/GET.feature @@ -1,49 +1,49 @@ -@Integration -Feature: GET Token - -User requests a Token - -Scenario: Requesting an own Token as an authenticated user - Given the user is authenticated - And an own Token t - When a GET request is sent to the Tokens/{id} endpoint with t.Id - Then the response status code is 200 (OK) - And the response contains a Token - -Scenario: Requesting an own Token as an anonymous user - Given the user is unauthenticated - And an own Token t - When a GET request is sent to the Tokens/{id} endpoint with t.Id - Then the response status code is 200 (OK) - And the response contains a Token - -Scenario: Requesting a peer Token as an authenticated user - Given the user is authenticated - And a peer Token p - When a GET request is sent to the Tokens/{id} endpoint with p.Id - Then the response status code is 200 (OK) - And the response contains a Token - -Scenario: Requesting a nonexistent Token as an authenticated user - Given the user is authenticated - When a GET request is sent to the Tokens/{id} endpoint with "TOKthisisnonexisting" - Then the response status code is 404 (Not Found) - And the response content includes an error with the error code "error.platform.recordNotFound" - -@ignore("skipping_due_to_required_backbone_changes") -Scenario: Requesting a Token with an unsupported Accept Header - Given the Accept header is 'application/xml' - When a GET request is sent to the Tokens/{id} endpoint with a valid Id - Then the response status code is 406 (Not Acceptable) - -@ignore("skipping_due_to_required_backbone_changes") -Scenario Outline: Requesting a Token with an invalid id - When a GET request is sent to the Tokens/{id} endpoint with - Then the response status code is 400 (Bad Request) - And the response content includes an error with the error code "error.platform.invalidId" -Examples: - | id | description | - | TOKthishastoomanycharacters | More than 20 characters | - | TOKnotenoughchars | Less than 20 characters | - | TOK_frfssd_fdfdsed#_ | Contains invalid characters | - | POKfdjfdjflndjkfndjk | Does not have TOK prefix | \ No newline at end of file +@Integration +Feature: GET Token + +User requests a Token + +Scenario: Requesting an own Token as an authenticated user + Given the user is authenticated + And an own Token t + When a GET request is sent to the Tokens/{id} endpoint with t.Id + Then the response status code is 200 (OK) + And the response contains a Token + +Scenario: Requesting an own Token as an anonymous user + Given the user is unauthenticated + And an own Token t + When a GET request is sent to the Tokens/{id} endpoint with t.Id + Then the response status code is 200 (OK) + And the response contains a Token + +Scenario: Requesting a peer Token as an authenticated user + Given the user is authenticated + And a peer Token p + When a GET request is sent to the Tokens/{id} endpoint with p.Id + Then the response status code is 200 (OK) + And the response contains a Token + +Scenario: Requesting a nonexistent Token as an authenticated user + Given the user is authenticated + When a GET request is sent to the Tokens/{id} endpoint with "TOKthisisnonexisting" + Then the response status code is 404 (Not Found) + And the response content includes an error with the error code "error.platform.recordNotFound" + +#@ignore("skipping_due_to_required_backbone_changes") +#Scenario: Requesting a Token with an unsupported Accept Header +# Given the Accept header is 'application/xml' +# When a GET request is sent to the Tokens/{id} endpoint with a valid Id +# Then the response status code is 406 (Not Acceptable) +# +#@ignore("skipping_due_to_required_backbone_changes") +#Scenario Outline: Requesting a Token with an invalid id +# When a GET request is sent to the Tokens/{id} endpoint with +# Then the response status code is 400 (Bad Request) +# And the response content includes an error with the error code "error.platform.invalidId" +#Examples: +# | id | description | +# | TOKthishastoomanycharacters | More than 20 characters | +# | TOKnotenoughchars | Less than 20 characters | +# | TOK_frfssd_fdfdsed#_ | Contains invalid characters | +# | POKfdjfdjflndjkfndjk | Does not have TOK prefix | diff --git a/ConsumerApi/DevicesDbContextSeeder.cs b/ConsumerApi/DevicesDbContextSeeder.cs index 81ebb8b8d4..4ce81a5481 100644 --- a/ConsumerApi/DevicesDbContextSeeder.cs +++ b/ConsumerApi/DevicesDbContextSeeder.cs @@ -36,7 +36,7 @@ private async Task SeedEverything(DevicesDbContext context) private static async Task GetBasicTier(DevicesDbContext context) { - return await context.Tiers.GetBasicTier(CancellationToken.None) ?? null; + return await context.Tiers.GetBasicTier(CancellationToken.None); } private async Task SeedApplicationUsers(DevicesDbContext context) @@ -64,10 +64,9 @@ private async Task AddBasicTierToIdentities(DevicesDbContext context) { var basicTier = await GetBasicTier(context); if (basicTier == null) - { return; - } + // ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract await context.Identities.Where(i => i.TierId == null).ExecuteUpdateAsync(s => s.SetProperty(i => i.TierId, basicTier.Id)); } } diff --git a/Modules/Devices/src/Devices.Application/ApplicationOptions.cs b/Modules/Devices/src/Devices.Application/ApplicationOptions.cs index 5a6ab4002a..510ac3737a 100644 --- a/Modules/Devices/src/Devices.Application/ApplicationOptions.cs +++ b/Modules/Devices/src/Devices.Application/ApplicationOptions.cs @@ -7,7 +7,7 @@ public class ApplicationOptions [Required] [MinLength(3)] [MaxLength(3)] - public string AddressPrefix { get; set; } + public string AddressPrefix { get; set; } = null!; [Required] public PaginationOptions Pagination { get; set; } = new(); diff --git a/Modules/Devices/src/Devices.Application/ChallengeValidator.cs b/Modules/Devices/src/Devices.Application/ChallengeValidator.cs index 60b64dbecc..2eb12d6f1d 100644 --- a/Modules/Devices/src/Devices.Application/ChallengeValidator.cs +++ b/Modules/Devices/src/Devices.Application/ChallengeValidator.cs @@ -23,7 +23,7 @@ public ChallengeValidator(ISignatureHelper signatureHelper, IChallengesRepositor public async Task Validate(SignedChallengeDTO signedChallenge, PublicKey publicKey) { ValidateSignature(signedChallenge.Challenge, Signature.FromBytes(signedChallenge.Signature).Bytes, publicKey.Key); - await ValidateChallengeExpiracy(signedChallenge.Challenge); + await ValidateChallengeExpiry(signedChallenge.Challenge); } private void ValidateSignature(string challenge, byte[] signature, byte[] publicKey) @@ -37,7 +37,7 @@ private void ValidateSignature(string challenge, byte[] signature, byte[] public throw new OperationFailedException(ApplicationErrors.Devices.InvalidSignature()); } - private async Task ValidateChallengeExpiracy(string serializedChallenge) + private async Task ValidateChallengeExpiry(string serializedChallenge) { var deserializedChallenge = JsonSerializer.Deserialize(serializedChallenge, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }) ?? throw new NotFoundException(nameof(Challenge)); var challenge = await _challengesRepository.FindById(deserializedChallenge.Id, CancellationToken.None) ?? throw new NotFoundException(nameof(Challenge)); diff --git a/Modules/Devices/src/Devices.Application/ClientIdGenerator.cs b/Modules/Devices/src/Devices.Application/ClientIdGenerator.cs index 3fe75c36e9..57fe5d7463 100644 --- a/Modules/Devices/src/Devices.Application/ClientIdGenerator.cs +++ b/Modules/Devices/src/Devices.Application/ClientIdGenerator.cs @@ -10,11 +10,70 @@ public static class ClientIdGenerator public const string PREFIX = "CLT"; private static readonly char[] VALID_CHARS = - { - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' - }; + [ + 'A', + 'B', + 'C', + 'D', + 'E', + 'F', + 'G', + 'H', + 'I', + 'J', + 'K', + 'L', + 'M', + 'N', + 'O', + 'P', + 'Q', + 'R', + 'S', + 'T', + 'U', + 'V', + 'W', + 'X', + 'Y', + 'Z', + 'a', + 'b', + 'c', + 'd', + 'e', + 'f', + 'g', + 'h', + 'i', + 'j', + 'k', + 'l', + 'm', + 'n', + 'o', + 'p', + 'q', + 'r', + 's', + 't', + 'u', + 'v', + 'w', + 'x', + 'y', + 'z', + '0', + '1', + '2', + '3', + '4', + '5', + '6', + '7', + '8', + '9' + ]; public static string Generate() { diff --git a/Modules/Devices/src/Devices.Application/Clients/Commands/CreateClient/CreateClientCommand.cs b/Modules/Devices/src/Devices.Application/Clients/Commands/CreateClient/CreateClientCommand.cs index e82b718948..04fe823adf 100644 --- a/Modules/Devices/src/Devices.Application/Clients/Commands/CreateClient/CreateClientCommand.cs +++ b/Modules/Devices/src/Devices.Application/Clients/Commands/CreateClient/CreateClientCommand.cs @@ -4,7 +4,7 @@ namespace Backbone.Modules.Devices.Application.Clients.Commands.CreateClient; public class CreateClientCommand : IRequest { - public CreateClientCommand(string clientId, string displayName, string clientSecret, string defaultTier, int? maxIdentities) + public CreateClientCommand(string? clientId, string? displayName, string? clientSecret, string defaultTier, int? maxIdentities) { ClientId = clientId; DisplayName = displayName; @@ -13,11 +13,11 @@ public CreateClientCommand(string clientId, string displayName, string clientSec MaxIdentities = maxIdentities; } - public string ClientId { get; set; } + public string? ClientId { get; set; } - public string DisplayName { get; set; } + public string? DisplayName { get; set; } - public string ClientSecret { get; set; } + public string? ClientSecret { get; set; } public string DefaultTier { get; set; } diff --git a/Modules/Devices/src/Devices.Application/Clients/Commands/CreateClient/Handler.cs b/Modules/Devices/src/Devices.Application/Clients/Commands/CreateClient/Handler.cs index 4701a2f966..040d553ea7 100644 --- a/Modules/Devices/src/Devices.Application/Clients/Commands/CreateClient/Handler.cs +++ b/Modules/Devices/src/Devices.Application/Clients/Commands/CreateClient/Handler.cs @@ -51,6 +51,7 @@ private async Task GetTierId(string defaultTier, CancellationToken cance if (tierNameResult.IsSuccess) { var tier = await _tiersRepository.FindByName(tierNameResult.Value, cancellationToken); + if (tier != null) return tier.Id; } diff --git a/Modules/Devices/src/Devices.Application/Clients/Commands/UpdateClient/Handler.cs b/Modules/Devices/src/Devices.Application/Clients/Commands/UpdateClient/Handler.cs index e1bdb1a675..981c377335 100644 --- a/Modules/Devices/src/Devices.Application/Clients/Commands/UpdateClient/Handler.cs +++ b/Modules/Devices/src/Devices.Application/Clients/Commands/UpdateClient/Handler.cs @@ -1,5 +1,4 @@ using Backbone.BuildingBlocks.Application.Abstractions.Exceptions; -using Backbone.BuildingBlocks.Domain; using Backbone.Modules.Devices.Application.Infrastructure.Persistence.Repository; using Backbone.Modules.Devices.Domain.Aggregates.Tier; using Backbone.Modules.Devices.Domain.Entities; diff --git a/Modules/Devices/src/Devices.Application/Clients/DTOs/ClientDTO.cs b/Modules/Devices/src/Devices.Application/Clients/DTOs/ClientDTO.cs index 0afba6a910..3e3f120733 100644 --- a/Modules/Devices/src/Devices.Application/Clients/DTOs/ClientDTO.cs +++ b/Modules/Devices/src/Devices.Application/Clients/DTOs/ClientDTO.cs @@ -6,10 +6,10 @@ namespace Backbone.Modules.Devices.Application.Clients.DTOs; public class ClientDTO : IHaveCustomMapping { - public string ClientId { get; set; } - public string DisplayName { get; set; } - public string DefaultTier { get; set; } - public DateTime CreatedAt { get; set; } + public required string ClientId { get; set; } + public required string DisplayName { get; set; } + public required string DefaultTier { get; set; } + public required DateTime CreatedAt { get; set; } public int? MaxIdentities { get; set; } public void CreateMappings(Profile configuration) diff --git a/Modules/Devices/src/Devices.Application/DTOs/ChallengeDTO.cs b/Modules/Devices/src/Devices.Application/DTOs/ChallengeDTO.cs index ed5225c0ce..87105f576a 100644 --- a/Modules/Devices/src/Devices.Application/DTOs/ChallengeDTO.cs +++ b/Modules/Devices/src/Devices.Application/DTOs/ChallengeDTO.cs @@ -2,6 +2,6 @@ public class ChallengeDTO { - public string Id { get; set; } - public DateTime ExpiresAt { get; set; } + public required string Id { get; set; } + public required DateTime ExpiresAt { get; set; } } diff --git a/Modules/Devices/src/Devices.Application/DTOs/IdentitySummaryDTO.cs b/Modules/Devices/src/Devices.Application/DTOs/IdentitySummaryDTO.cs index e8551bd675..e207076841 100644 --- a/Modules/Devices/src/Devices.Application/DTOs/IdentitySummaryDTO.cs +++ b/Modules/Devices/src/Devices.Application/DTOs/IdentitySummaryDTO.cs @@ -1,4 +1,3 @@ -using Backbone.DevelopmentKit.Identity.ValueObjects; using Backbone.Modules.Devices.Application.Devices.DTOs; using Backbone.Modules.Devices.Domain.Entities.Identities; @@ -7,36 +6,37 @@ namespace Backbone.Modules.Devices.Application.DTOs; public class IdentitySummaryDTO { public string Address { get; set; } - public string ClientId { get; set; } + public string? ClientId { get; set; } public byte[] PublicKey { get; set; } - - public string TierId { get; set; } - public DateTime CreatedAt { get; set; } - public byte IdentityVersion { get; set; } - + public IEnumerable Devices { get; set; } public int NumberOfDevices { get; set; } - public IEnumerable Devices { get; set; } + public byte IdentityVersion { get; set; } - public IdentitySummaryDTO(IdentityAddress address, string clientId, byte[] publicKey, byte identityVersion, DateTime createdAt, IEnumerable devices, string tierId) + public string TierId { get; set; } + + public IdentitySummaryDTO(Identity identity) { - Address = address.ToString(); - ClientId = clientId; - PublicKey = publicKey; - IdentityVersion = identityVersion; - CreatedAt = createdAt; - Devices = devices.Select(it => new DeviceDTO() + ClientId = identity.ClientId; + + Address = identity.Address.ToString(); + PublicKey = identity.PublicKey; + CreatedAt = identity.CreatedAt; + + Devices = identity.Devices.Select(it => new DeviceDTO() { CreatedAt = it.CreatedAt, CreatedByDevice = it.CreatedByDevice, Id = it.Id, LastLogin = new LastLoginInformation { Time = it.User.LastLoginAt }, - Username = it.User.UserName + Username = it.User.UserName! }); - NumberOfDevices = devices.Count(); - TierId = tierId; - } + NumberOfDevices = identity.Devices.Count; + + IdentityVersion = identity.IdentityVersion; + TierId = identity.TierId!; + } } diff --git a/Modules/Devices/src/Devices.Application/Devices.Application.csproj b/Modules/Devices/src/Devices.Application/Devices.Application.csproj index 0f1809184c..2698d045a1 100644 --- a/Modules/Devices/src/Devices.Application/Devices.Application.csproj +++ b/Modules/Devices/src/Devices.Application/Devices.Application.csproj @@ -1,16 +1,20 @@ - + - - - - - - + + enable + - - - - - - + + + + + + + + + + + + + diff --git a/Modules/Devices/src/Devices.Application/Devices/Commands/ChangePassword/ChangePasswordCommand.cs b/Modules/Devices/src/Devices.Application/Devices/Commands/ChangePassword/ChangePasswordCommand.cs index 7541ade5e3..c5bb08f0a6 100644 --- a/Modules/Devices/src/Devices.Application/Devices/Commands/ChangePassword/ChangePasswordCommand.cs +++ b/Modules/Devices/src/Devices.Application/Devices/Commands/ChangePassword/ChangePasswordCommand.cs @@ -4,6 +4,6 @@ namespace Backbone.Modules.Devices.Application.Devices.Commands.ChangePassword; public class ChangePasswordCommand : IRequest { - public string OldPassword { get; set; } - public string NewPassword { get; set; } + public required string OldPassword { get; set; } + public required string NewPassword { get; set; } } diff --git a/Modules/Devices/src/Devices.Application/Devices/Commands/DeleteDevice/DeleteDeviceCommand.cs b/Modules/Devices/src/Devices.Application/Devices/Commands/DeleteDevice/DeleteDeviceCommand.cs index 646ff1da18..ce84c57bc8 100644 --- a/Modules/Devices/src/Devices.Application/Devices/Commands/DeleteDevice/DeleteDeviceCommand.cs +++ b/Modules/Devices/src/Devices.Application/Devices/Commands/DeleteDevice/DeleteDeviceCommand.cs @@ -1,9 +1,8 @@ -using Backbone.DevelopmentKit.Identity.ValueObjects; -using MediatR; +using MediatR; namespace Backbone.Modules.Devices.Application.Devices.Commands.DeleteDevice; public class DeleteDeviceCommand : IRequest { - public string DeviceId { get; set; } + public required string DeviceId { get; set; } } diff --git a/Modules/Devices/src/Devices.Application/Devices/Commands/DeleteDevice/Handler.cs b/Modules/Devices/src/Devices.Application/Devices/Commands/DeleteDevice/Handler.cs index abda78be05..332257db54 100644 --- a/Modules/Devices/src/Devices.Application/Devices/Commands/DeleteDevice/Handler.cs +++ b/Modules/Devices/src/Devices.Application/Devices/Commands/DeleteDevice/Handler.cs @@ -2,7 +2,6 @@ using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.UserContext; using Backbone.DevelopmentKit.Identity.ValueObjects; using Backbone.Modules.Devices.Application.Infrastructure.Persistence.Repository; -using Backbone.Modules.Devices.Domain.Entities; using Backbone.Modules.Devices.Domain.Entities.Identities; using MediatR; using Microsoft.Extensions.Logging; diff --git a/Modules/Devices/src/Devices.Application/Devices/Commands/RegisterDevice/Handler.cs b/Modules/Devices/src/Devices.Application/Devices/Commands/RegisterDevice/Handler.cs index 22cddc7dca..c9baebe8c0 100644 --- a/Modules/Devices/src/Devices.Application/Devices/Commands/RegisterDevice/Handler.cs +++ b/Modules/Devices/src/Devices.Application/Devices/Commands/RegisterDevice/Handler.cs @@ -40,12 +40,12 @@ public async Task Handle(RegisterDeviceCommand command, await _identitiesRepository.AddUser(user, command.DevicePassword); - _logger.CreatedDevice(user.DeviceId, user.Id, user.UserName); + _logger.CreatedDevice(user.DeviceId, user.Id, user.UserName!); return new RegisterDeviceResponse { Id = user.DeviceId, - Username = user.UserName, + Username = user.UserName!, CreatedByDevice = user.Device.CreatedByDevice, CreatedAt = user.Device.CreatedAt }; @@ -61,7 +61,7 @@ public override dynamic Read(ref Utf8JsonReader reader, Type typeToConvert, Json JsonTokenType.True => true, JsonTokenType.False => false, JsonTokenType.Number => reader.TryGetInt64(out var i) ? i : reader.GetDouble(), - JsonTokenType.String => reader.TryGetDateTime(out var datetime) ? datetime.ToString(CultureInfo.InvariantCulture) : reader.GetString(), + JsonTokenType.String => reader.TryGetDateTime(out var datetime) ? datetime.ToString(CultureInfo.InvariantCulture) : reader.GetString()!, JsonTokenType.StartObject => ReadObject(JsonDocument.ParseValue(ref reader).RootElement), _ => JsonDocument.ParseValue(ref reader).RootElement.Clone() // use JsonElement as fallback. }; @@ -69,7 +69,7 @@ public override dynamic Read(ref Utf8JsonReader reader, Type typeToConvert, Json private object ReadObject(JsonElement jsonElement) { - IDictionary expandoObject = new ExpandoObject(); + IDictionary expandoObject = new ExpandoObject(); foreach (var obj in jsonElement.EnumerateObject()) { var k = obj.Name; @@ -80,27 +80,27 @@ private object ReadObject(JsonElement jsonElement) return expandoObject; } - private object ReadValue(JsonElement jsonElement) + private object? ReadValue(JsonElement jsonElement) { return jsonElement.ValueKind switch { JsonValueKind.Object => ReadObject(jsonElement), JsonValueKind.Array => ReadList(jsonElement), - JsonValueKind.String => jsonElement.GetString(), + JsonValueKind.String => jsonElement.GetString()!, JsonValueKind.Number => jsonElement.TryGetInt64(out var i) ? i : jsonElement.GetDouble(), JsonValueKind.True => true, JsonValueKind.False => false, JsonValueKind.Undefined => null, JsonValueKind.Null => null, - _ => throw new ArgumentOutOfRangeException() + _ => throw new ArgumentOutOfRangeException(nameof(jsonElement.ValueKind)) }; } - private object ReadList(JsonElement jsonElement) + private List? ReadList(JsonElement jsonElement) { - var list = new List(); + var list = new List(); jsonElement.EnumerateArray().ToList().ForEach(j => list.Add(ReadValue(j))); - return list.Count == 0 ? null : list; + return (list.Count == 0 ? null : list); } public override void Write(Utf8JsonWriter writer, diff --git a/Modules/Devices/src/Devices.Application/Devices/Commands/RegisterDevice/RegisterDeviceCommand.cs b/Modules/Devices/src/Devices.Application/Devices/Commands/RegisterDevice/RegisterDeviceCommand.cs index ce78b1dcdf..603da8d6e8 100644 --- a/Modules/Devices/src/Devices.Application/Devices/Commands/RegisterDevice/RegisterDeviceCommand.cs +++ b/Modules/Devices/src/Devices.Application/Devices/Commands/RegisterDevice/RegisterDeviceCommand.cs @@ -5,6 +5,6 @@ namespace Backbone.Modules.Devices.Application.Devices.Commands.RegisterDevice; public class RegisterDeviceCommand : IRequest { - public string DevicePassword { get; set; } - public SignedChallengeDTO SignedChallenge { get; set; } + public required string DevicePassword { get; set; } + public required SignedChallengeDTO SignedChallenge { get; set; } } diff --git a/Modules/Devices/src/Devices.Application/Devices/Commands/RegisterDevice/RegisterDeviceResponse.cs b/Modules/Devices/src/Devices.Application/Devices/Commands/RegisterDevice/RegisterDeviceResponse.cs index c3e67a3706..c75c1c2bd7 100644 --- a/Modules/Devices/src/Devices.Application/Devices/Commands/RegisterDevice/RegisterDeviceResponse.cs +++ b/Modules/Devices/src/Devices.Application/Devices/Commands/RegisterDevice/RegisterDeviceResponse.cs @@ -4,8 +4,8 @@ namespace Backbone.Modules.Devices.Application.Devices.Commands.RegisterDevice; public class RegisterDeviceResponse { - public DeviceId Id { get; set; } - public string Username { get; set; } - public DateTime CreatedAt { get; set; } - public DeviceId CreatedByDevice { get; set; } + public required DeviceId Id { get; set; } + public required string Username { get; set; } + public required DateTime CreatedAt { get; set; } + public required DeviceId CreatedByDevice { get; set; } } diff --git a/Modules/Devices/src/Devices.Application/Devices/DTOs/DeviceDTO.cs b/Modules/Devices/src/Devices.Application/Devices/DTOs/DeviceDTO.cs index fe026d6816..db03486bb3 100644 --- a/Modules/Devices/src/Devices.Application/Devices/DTOs/DeviceDTO.cs +++ b/Modules/Devices/src/Devices.Application/Devices/DTOs/DeviceDTO.cs @@ -7,15 +7,11 @@ namespace Backbone.Modules.Devices.Application.Devices.DTOs; public class DeviceDTO : IHaveCustomMapping { - public DeviceId Id { get; set; } - - public string Username { get; set; } - - public DateTime CreatedAt { get; set; } - - public DeviceId CreatedByDevice { get; set; } - - public LastLoginInformation LastLogin { get; set; } + public required DeviceId Id { get; set; } + public required string Username { get; set; } + public required DateTime CreatedAt { get; set; } + public required DeviceId CreatedByDevice { get; set; } + public required LastLoginInformation LastLogin { get; set; } public void CreateMappings(Profile configuration) { diff --git a/Modules/Devices/src/Devices.Application/Devices/DTOs/PublicKey.cs b/Modules/Devices/src/Devices.Application/Devices/DTOs/PublicKey.cs index bd97a032ad..2c431662f0 100644 --- a/Modules/Devices/src/Devices.Application/Devices/DTOs/PublicKey.cs +++ b/Modules/Devices/src/Devices.Application/Devices/DTOs/PublicKey.cs @@ -33,7 +33,11 @@ public byte[] ToBytes() public static PublicKey FromBytes(byte[] bytes) { var publicKeyJsonString = Encoding.UTF8.GetString(bytes); - var publicKeyObject = JsonSerializer.Deserialize(publicKeyJsonString, new JsonSerializerOptions { Converters = { new DynamicJsonConverter() } }); + var publicKeyObject = + JsonSerializer.Deserialize( + publicKeyJsonString, + new JsonSerializerOptions { Converters = { new DynamicJsonConverter() } }) ?? + throw new Exception("Could not deserialize public key."); var key = Base64UrlEncoder.DecodeBytes((string)publicKeyObject.pub); var algorithm = (SignatureAlgorithm)publicKeyObject.alg; diff --git a/Modules/Devices/src/Devices.Application/Devices/DTOs/Signature.cs b/Modules/Devices/src/Devices.Application/Devices/DTOs/Signature.cs index e7ddb707ac..852592d38d 100644 --- a/Modules/Devices/src/Devices.Application/Devices/DTOs/Signature.cs +++ b/Modules/Devices/src/Devices.Application/Devices/DTOs/Signature.cs @@ -32,7 +32,11 @@ public byte[] ToBytes() public static Signature FromBytes(byte[] bytes) { var signatureJsonString = Encoding.UTF8.GetString(bytes); - var signatureObject = JsonSerializer.Deserialize(signatureJsonString, new JsonSerializerOptions { Converters = { new DynamicJsonConverter() } }); + var signatureObject = + JsonSerializer.Deserialize( + signatureJsonString, + new JsonSerializerOptions { Converters = { new DynamicJsonConverter() } }) ?? + throw new Exception("Could not deserialize signature."); var signature = Base64UrlEncoder.DecodeBytes((string)signatureObject.sig); var algorithm = (SignatureAlgorithm)signatureObject.alg; diff --git a/Modules/Devices/src/Devices.Application/Devices/DTOs/SignedChallengeDTO.cs b/Modules/Devices/src/Devices.Application/Devices/DTOs/SignedChallengeDTO.cs index 895a928aac..53b89fc095 100644 --- a/Modules/Devices/src/Devices.Application/Devices/DTOs/SignedChallengeDTO.cs +++ b/Modules/Devices/src/Devices.Application/Devices/DTOs/SignedChallengeDTO.cs @@ -2,6 +2,6 @@ public class SignedChallengeDTO { - public string Challenge { get; set; } - public byte[] Signature { get; set; } + public required string Challenge { get; set; } + public required byte[] Signature { get; set; } } diff --git a/Modules/Devices/src/Devices.Application/Extensions/TierQueryableExtensions.cs b/Modules/Devices/src/Devices.Application/Extensions/TierQueryableExtensions.cs index 7a761a624d..19fb93c1f4 100644 --- a/Modules/Devices/src/Devices.Application/Extensions/TierQueryableExtensions.cs +++ b/Modules/Devices/src/Devices.Application/Extensions/TierQueryableExtensions.cs @@ -5,7 +5,7 @@ namespace Backbone.Modules.Devices.Application.Extensions; public static class TierQueryableExtensions { - public static async Task GetBasicTier(this IQueryable query, CancellationToken cancellationToken) + public static async Task GetBasicTier(this IQueryable query, CancellationToken cancellationToken) { var basicTier = await query.FirstOrDefaultAsync(t => t.Name == TierName.BASIC_DEFAULT_NAME, cancellationToken); return basicTier; diff --git a/Modules/Devices/src/Devices.Application/Identities/Commands/ApproveDeletionProcess/ApproveDeletionProcessResponse.cs b/Modules/Devices/src/Devices.Application/Identities/Commands/ApproveDeletionProcess/ApproveDeletionProcessResponse.cs index 125b4b27e7..b5aaac4b0f 100644 --- a/Modules/Devices/src/Devices.Application/Identities/Commands/ApproveDeletionProcess/ApproveDeletionProcessResponse.cs +++ b/Modules/Devices/src/Devices.Application/Identities/Commands/ApproveDeletionProcess/ApproveDeletionProcessResponse.cs @@ -9,8 +9,8 @@ public ApproveDeletionProcessResponse(IdentityDeletionProcess deletionProcess) Id = deletionProcess.Id; Status = deletionProcess.Status; CreatedAt = deletionProcess.CreatedAt; - ApprovedAt = deletionProcess.ApprovedAt!.Value; - ApprovedByDevice = deletionProcess.ApprovedByDevice; + ApprovedAt = deletionProcess.ApprovedAt ?? throw new Exception($"The '{nameof(IdentityDeletionProcess.ApprovedAt)}' property of the given deletion process must not be null."); + ApprovedByDevice = deletionProcess.ApprovedByDevice ?? throw new Exception($"The '{nameof(IdentityDeletionProcess.ApprovedByDevice)}' property of the given deletion process must not be null."); } public string Id { get; } diff --git a/Modules/Devices/src/Devices.Application/Identities/Commands/ApproveDeletionProcess/Handler.cs b/Modules/Devices/src/Devices.Application/Identities/Commands/ApproveDeletionProcess/Handler.cs index eb532933f8..74f436de6c 100644 --- a/Modules/Devices/src/Devices.Application/Identities/Commands/ApproveDeletionProcess/Handler.cs +++ b/Modules/Devices/src/Devices.Application/Identities/Commands/ApproveDeletionProcess/Handler.cs @@ -2,7 +2,6 @@ using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.EventBus; using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.UserContext; using Backbone.BuildingBlocks.Domain; -using Backbone.BuildingBlocks.Domain.Errors; using Backbone.Modules.Devices.Application.Infrastructure.Persistence.Repository; using Backbone.Modules.Devices.Application.IntegrationEvents.Outgoing; using Backbone.Modules.Devices.Domain.Entities.Identities; @@ -40,7 +39,7 @@ public async Task Handle(ApproveDeletionProcessC await _identitiesRepository.Update(identity, cancellationToken); - _eventBus.Publish(new TierOfIdentityChangedIntegrationEvent(identity, oldTierId, newTierId)); + _eventBus.Publish(new TierOfIdentityChangedIntegrationEvent(identity, oldTierId!, newTierId!)); return new ApproveDeletionProcessResponse(deletionProcess); } diff --git a/Modules/Devices/src/Devices.Application/Identities/Commands/CreateIdentity/CreateIdentityCommand.cs b/Modules/Devices/src/Devices.Application/Identities/Commands/CreateIdentity/CreateIdentityCommand.cs index 838333bcf2..3fd13eaa84 100644 --- a/Modules/Devices/src/Devices.Application/Identities/Commands/CreateIdentity/CreateIdentityCommand.cs +++ b/Modules/Devices/src/Devices.Application/Identities/Commands/CreateIdentity/CreateIdentityCommand.cs @@ -5,10 +5,10 @@ namespace Backbone.Modules.Devices.Application.Identities.Commands.CreateIdentit public class CreateIdentityCommand : IRequest { - public string ClientId { get; set; } - public byte[] IdentityPublicKey { get; set; } - public string DevicePassword { get; set; } - public byte IdentityVersion { get; set; } - public SignedChallengeDTO SignedChallenge { get; set; } - public bool ShouldValidateChallenge { get; set; } = true; // Used to avoid challenge validation when creating Identities through the AdminApi for Integration tests purposes. + public required string ClientId { get; set; } + public required byte[] IdentityPublicKey { get; set; } + public required string DevicePassword { get; set; } + public required byte IdentityVersion { get; set; } + public required SignedChallengeDTO SignedChallenge { get; set; } + public bool ShouldValidateChallenge { get; set; } = true; // Used to avoid challenge validation when creating Identities through the AdminApi for Integration testing purposes. } diff --git a/Modules/Devices/src/Devices.Application/Identities/Commands/CreateIdentity/CreateIdentityResponse.cs b/Modules/Devices/src/Devices.Application/Identities/Commands/CreateIdentity/CreateIdentityResponse.cs index 7bc16829ec..6b50372a11 100644 --- a/Modules/Devices/src/Devices.Application/Identities/Commands/CreateIdentity/CreateIdentityResponse.cs +++ b/Modules/Devices/src/Devices.Application/Identities/Commands/CreateIdentity/CreateIdentityResponse.cs @@ -4,15 +4,14 @@ namespace Backbone.Modules.Devices.Application.Identities.Commands.CreateIdentit public class CreateIdentityResponse { - public IdentityAddress Address { get; set; } - public DateTime CreatedAt { get; set; } - - public CreateIdentityResponseDevice Device { get; set; } + public required IdentityAddress Address { get; set; } + public required DateTime CreatedAt { get; set; } + public required CreateIdentityResponseDevice Device { get; set; } } public class CreateIdentityResponseDevice { - public DeviceId Id { get; set; } - public string Username { get; set; } - public DateTime CreatedAt { get; set; } + public required DeviceId Id { get; set; } + public required string Username { get; set; } + public required DateTime CreatedAt { get; set; } } diff --git a/Modules/Devices/src/Devices.Application/Identities/Commands/CreateIdentity/Handler.cs b/Modules/Devices/src/Devices.Application/Identities/Commands/CreateIdentity/Handler.cs index 306a609198..91607f2444 100644 --- a/Modules/Devices/src/Devices.Application/Identities/Commands/CreateIdentity/Handler.cs +++ b/Modules/Devices/src/Devices.Application/Identities/Commands/CreateIdentity/Handler.cs @@ -4,6 +4,7 @@ using Backbone.Modules.Devices.Application.Devices.DTOs; using Backbone.Modules.Devices.Application.Infrastructure.Persistence.Repository; using Backbone.Modules.Devices.Application.IntegrationEvents.Outgoing; +using Backbone.Modules.Devices.Domain.Entities; using Backbone.Modules.Devices.Domain.Entities.Identities; using MediatR; using Microsoft.Extensions.Logging; @@ -36,7 +37,7 @@ public async Task Handle(CreateIdentityCommand command, if (command.ShouldValidateChallenge) await _challengeValidator.Validate(command.SignedChallenge, publicKey); - _logger.LogTrace("Challenge sucessfully validated."); + _logger.LogTrace("Challenge successfully validated."); var address = IdentityAddress.Create(publicKey.Key, _applicationOptions.AddressPrefix); @@ -47,7 +48,7 @@ public async Task Handle(CreateIdentityCommand command, if (addressAlreadyExists) throw new OperationFailedException(ApplicationErrors.Devices.AddressAlreadyExists()); - var client = await _oAuthClientsRepository.Find(command.ClientId, cancellationToken); + var client = await _oAuthClientsRepository.Find(command.ClientId, cancellationToken) ?? throw new NotFoundException(nameof(OAuthClient)); var clientIdentityCount = await _identitiesRepository.CountByClientId(command.ClientId, cancellationToken); @@ -60,7 +61,7 @@ public async Task Handle(CreateIdentityCommand command, await _identitiesRepository.AddUser(user, command.DevicePassword); - _logger.CreatedIdentity(newIdentity.Address, user.DeviceId, user.UserName); + _logger.CreatedIdentity(newIdentity.Address, user.DeviceId, user.UserName!); _eventBus.Publish(new IdentityCreatedIntegrationEvent(newIdentity)); @@ -71,7 +72,7 @@ public async Task Handle(CreateIdentityCommand command, Device = new CreateIdentityResponseDevice { Id = user.DeviceId, - Username = user.UserName, + Username = user.UserName!, CreatedAt = user.Device.CreatedAt } }; @@ -81,9 +82,9 @@ public async Task Handle(CreateIdentityCommand command, internal static partial class CreatedIdentityLogs { [LoggerMessage( - EventId = 436321, - EventName = "Devices.CreateIdentity.CreatedIdentity", - Level = LogLevel.Information, - Message = "Identity created. Address: '{address}', Device ID: '{deviceId}', Username: '{userName}'.")] + EventId = 436321, + EventName = "Devices.CreateIdentity.CreatedIdentity", + Level = LogLevel.Information, + Message = "Identity created. Address: '{address}', Device ID: '{deviceId}', Username: '{userName}'.")] public static partial void CreatedIdentity(this ILogger logger, IdentityAddress address, DeviceId deviceId, string userName); } diff --git a/Modules/Devices/src/Devices.Application/Identities/Commands/StartDeletionProcessAsOwner/Handler.cs b/Modules/Devices/src/Devices.Application/Identities/Commands/StartDeletionProcessAsOwner/Handler.cs index 278ae764aa..1c89c1a5e8 100644 --- a/Modules/Devices/src/Devices.Application/Identities/Commands/StartDeletionProcessAsOwner/Handler.cs +++ b/Modules/Devices/src/Devices.Application/Identities/Commands/StartDeletionProcessAsOwner/Handler.cs @@ -29,7 +29,7 @@ public async Task Handle(StartDeletionProce var deletionProcess = identity.StartDeletionProcessAsOwner(_userContext.GetDeviceId()); var newTierId = identity.TierId; - _eventBus.Publish(new TierOfIdentityChangedIntegrationEvent(identity, oldTierId, newTierId)); + _eventBus.Publish(new TierOfIdentityChangedIntegrationEvent(identity, oldTierId!, newTierId!)); await _identitiesRepository.Update(identity, cancellationToken); diff --git a/Modules/Devices/src/Devices.Application/Identities/Commands/StartDeletionProcessAsOwner/StartDeletionProcessAsOwnerResponse.cs b/Modules/Devices/src/Devices.Application/Identities/Commands/StartDeletionProcessAsOwner/StartDeletionProcessAsOwnerResponse.cs index 933c7bb01a..650ab379bc 100644 --- a/Modules/Devices/src/Devices.Application/Identities/Commands/StartDeletionProcessAsOwner/StartDeletionProcessAsOwnerResponse.cs +++ b/Modules/Devices/src/Devices.Application/Identities/Commands/StartDeletionProcessAsOwner/StartDeletionProcessAsOwnerResponse.cs @@ -10,8 +10,8 @@ public StartDeletionProcessAsOwnerResponse(IdentityDeletionProcess deletionProce Id = deletionProcess.Id; Status = deletionProcess.Status; CreatedAt = deletionProcess.CreatedAt; - ApprovedAt = deletionProcess.ApprovedAt.GetValueOrDefault(); - ApprovedByDevice = deletionProcess.ApprovedByDevice; + ApprovedAt = deletionProcess.ApprovedAt ?? throw new Exception($"The '{nameof(IdentityDeletionProcess.ApprovedAt)}' property of the given deletion process must not be null."); + ApprovedByDevice = deletionProcess.ApprovedByDevice ?? throw new Exception($"The '{nameof(IdentityDeletionProcess.ApprovedByDevice)}' property of the given deletion process must not be null."); GracePeriodEndsAt = deletionProcess.GracePeriodEndsAt.GetValueOrDefault(); } diff --git a/Modules/Devices/src/Devices.Application/Identities/Commands/UpdateIdentity/Handler.cs b/Modules/Devices/src/Devices.Application/Identities/Commands/UpdateIdentity/Handler.cs index cafe619df0..0ce38287a4 100644 --- a/Modules/Devices/src/Devices.Application/Identities/Commands/UpdateIdentity/Handler.cs +++ b/Modules/Devices/src/Devices.Application/Identities/Commands/UpdateIdentity/Handler.cs @@ -31,7 +31,7 @@ public async Task Handle(UpdateIdentityCommand request, CancellationToken cancel var identity = await _identitiesRepository.FindByAddress(request.Address, cancellationToken, track: true) ?? throw new NotFoundException(nameof(Identity)); - var tiers = await _tiersRepository.FindByIds(new List() { identity.TierId, newTierIdResult.Value }, cancellationToken); + var tiers = await _tiersRepository.FindByIds(new List() { identity.TierId!, newTierIdResult.Value }, cancellationToken); var oldTier = tiers.Single(t => t.Id == identity.TierId); var newTier = tiers.SingleOrDefault(t => t.Id == newTierIdResult.Value) ?? throw new NotFoundException(nameof(Tier)); diff --git a/Modules/Devices/src/Devices.Application/Identities/Commands/UpdateIdentity/UpdateIdentityCommand.cs b/Modules/Devices/src/Devices.Application/Identities/Commands/UpdateIdentity/UpdateIdentityCommand.cs index 3f39b56e51..7982d90452 100644 --- a/Modules/Devices/src/Devices.Application/Identities/Commands/UpdateIdentity/UpdateIdentityCommand.cs +++ b/Modules/Devices/src/Devices.Application/Identities/Commands/UpdateIdentity/UpdateIdentityCommand.cs @@ -3,6 +3,6 @@ namespace Backbone.Modules.Devices.Application.Identities.Commands.UpdateIdentity; public class UpdateIdentityCommand : IRequest { - public string Address { get; set; } - public string TierId { get; set; } + public required string Address { get; set; } + public required string TierId { get; set; } } diff --git a/Modules/Devices/src/Devices.Application/Identities/Queries/GetIdentity/GetIdentityResponse.cs b/Modules/Devices/src/Devices.Application/Identities/Queries/GetIdentity/GetIdentityResponse.cs index 23ddad3dcb..9d0a519b30 100644 --- a/Modules/Devices/src/Devices.Application/Identities/Queries/GetIdentity/GetIdentityResponse.cs +++ b/Modules/Devices/src/Devices.Application/Identities/Queries/GetIdentity/GetIdentityResponse.cs @@ -4,5 +4,5 @@ namespace Backbone.Modules.Devices.Application.Identities.Queries.GetIdentity; public class GetIdentityResponse : IdentitySummaryDTO { - public GetIdentityResponse(Identity identity) : base(identity.Address, identity.ClientId, identity.PublicKey, identity.IdentityVersion, identity.CreatedAt, identity.Devices, identity.TierId) { } + public GetIdentityResponse(Identity identity) : base(identity) { } } diff --git a/Modules/Devices/src/Devices.Application/Identities/Queries/ListIdentities/Handler.cs b/Modules/Devices/src/Devices.Application/Identities/Queries/ListIdentities/Handler.cs index 352bd54d45..8852c845c0 100644 --- a/Modules/Devices/src/Devices.Application/Identities/Queries/ListIdentities/Handler.cs +++ b/Modules/Devices/src/Devices.Application/Identities/Queries/ListIdentities/Handler.cs @@ -15,7 +15,7 @@ public Handler(IIdentitiesRepository repository) public async Task Handle(ListIdentitiesQuery request, CancellationToken cancellationToken) { var dbPaginationResult = await _identitiesRepository.FindAll(request.PaginationFilter, cancellationToken); - var identityDtos = dbPaginationResult.ItemsOnPage.Select(el => new IdentitySummaryDTO(el.Address, el.ClientId, el.PublicKey, el.IdentityVersion, el.CreatedAt, el.Devices, el.TierId)).ToList(); + var identityDtos = dbPaginationResult.ItemsOnPage.Select(el => new IdentitySummaryDTO(el)).ToList(); return new ListIdentitiesResponse(identityDtos, request.PaginationFilter, dbPaginationResult.TotalNumberOfItems); } diff --git a/Modules/Devices/src/Devices.Application/Infrastructure/Persistence/Repository/IChallengesRepository.cs b/Modules/Devices/src/Devices.Application/Infrastructure/Persistence/Repository/IChallengesRepository.cs index 6c6d27476d..8046339749 100644 --- a/Modules/Devices/src/Devices.Application/Infrastructure/Persistence/Repository/IChallengesRepository.cs +++ b/Modules/Devices/src/Devices.Application/Infrastructure/Persistence/Repository/IChallengesRepository.cs @@ -4,5 +4,5 @@ namespace Backbone.Modules.Devices.Application.Infrastructure.Persistence.Reposi public interface IChallengesRepository { - Task FindById(string id, CancellationToken cancellationToken, bool track = false); + Task FindById(string id, CancellationToken cancellationToken, bool track = false); } diff --git a/Modules/Devices/src/Devices.Application/Infrastructure/Persistence/Repository/IIdentitiesRepository.cs b/Modules/Devices/src/Devices.Application/Infrastructure/Persistence/Repository/IIdentitiesRepository.cs index be4fc0d2b1..250d1dfc2e 100644 --- a/Modules/Devices/src/Devices.Application/Infrastructure/Persistence/Repository/IIdentitiesRepository.cs +++ b/Modules/Devices/src/Devices.Application/Infrastructure/Persistence/Repository/IIdentitiesRepository.cs @@ -22,7 +22,7 @@ public interface IIdentitiesRepository #region Devices Task> FindAllDevicesOfIdentity(IdentityAddress identity, IEnumerable ids, PaginationFilter paginationFilter, CancellationToken cancellationToken); - Task GetDeviceById(DeviceId deviceId, CancellationToken cancellationToken, bool track = false); + Task GetDeviceById(DeviceId deviceId, CancellationToken cancellationToken, bool track = false); Task Update(Device device, CancellationToken cancellationToken); #endregion } diff --git a/Modules/Devices/src/Devices.Application/Infrastructure/Persistence/Repository/IOAuthClientsRepository.cs b/Modules/Devices/src/Devices.Application/Infrastructure/Persistence/Repository/IOAuthClientsRepository.cs index 245315dab6..f652f5f040 100644 --- a/Modules/Devices/src/Devices.Application/Infrastructure/Persistence/Repository/IOAuthClientsRepository.cs +++ b/Modules/Devices/src/Devices.Application/Infrastructure/Persistence/Repository/IOAuthClientsRepository.cs @@ -5,7 +5,7 @@ namespace Backbone.Modules.Devices.Application.Infrastructure.Persistence.Reposi public interface IOAuthClientsRepository { Task> FindAll(CancellationToken cancellationToken, bool track = false); - Task Find(string clientId, CancellationToken cancellationToken, bool track = false); + Task Find(string clientId, CancellationToken cancellationToken, bool track = false); Task Exists(string clientId, CancellationToken cancellationToken); Task Add(OAuthClient client, string clientSecret, CancellationToken cancellationToken); Task Update(OAuthClient client, CancellationToken cancellationToken); diff --git a/Modules/Devices/src/Devices.Application/Infrastructure/Persistence/Repository/IPnsRegistrationsRepository.cs b/Modules/Devices/src/Devices.Application/Infrastructure/Persistence/Repository/IPnsRegistrationsRepository.cs index 888df5f0a4..8dfac9eab5 100644 --- a/Modules/Devices/src/Devices.Application/Infrastructure/Persistence/Repository/IPnsRegistrationsRepository.cs +++ b/Modules/Devices/src/Devices.Application/Infrastructure/Persistence/Repository/IPnsRegistrationsRepository.cs @@ -8,6 +8,6 @@ public interface IPnsRegistrationsRepository Task Add(PnsRegistration registration, CancellationToken cancellationToken); Task Update(PnsRegistration registration, CancellationToken cancellationToken); Task> FindWithAddress(IdentityAddress address, CancellationToken cancellationToken, bool track = false); - Task FindByDeviceId(DeviceId deviceId, CancellationToken cancellationToken, bool track = false); + Task FindByDeviceId(DeviceId deviceId, CancellationToken cancellationToken, bool track = false); Task Delete(List deviceIds, CancellationToken cancellationToken); } diff --git a/Modules/Devices/src/Devices.Application/Infrastructure/Persistence/Repository/ITiersRepository.cs b/Modules/Devices/src/Devices.Application/Infrastructure/Persistence/Repository/ITiersRepository.cs index 1d173732b3..1f3de618af 100644 --- a/Modules/Devices/src/Devices.Application/Infrastructure/Persistence/Repository/ITiersRepository.cs +++ b/Modules/Devices/src/Devices.Application/Infrastructure/Persistence/Repository/ITiersRepository.cs @@ -10,9 +10,9 @@ public interface ITiersRepository Task ExistsWithId(TierId tierId, CancellationToken cancellationToken); Task ExistsWithName(TierName tierName, CancellationToken cancellationToken); Task> FindAll(PaginationFilter paginationFilter, CancellationToken cancellationToken); - Task GetBasicTierAsync(CancellationToken cancellationToken); - Task FindById(TierId tierId, CancellationToken cancellationToken); - Task FindByName(TierName tierName, CancellationToken cancellationToken, bool track = false); + Task FindBasicTier(CancellationToken cancellationToken); + Task FindById(TierId tierId, CancellationToken cancellationToken); + Task FindByName(TierName tierName, CancellationToken cancellationToken, bool track = false); Task Remove(Tier tier); Task GetNumberOfIdentitiesAssignedToTier(Tier tier, CancellationToken cancellationToken); Task GetNumberOfClientsWithDefaultTier(Tier tier, CancellationToken cancellationToken); diff --git a/Modules/Devices/src/Devices.Application/Infrastructure/PushNotifications/NotificationTextAttribute.cs b/Modules/Devices/src/Devices.Application/Infrastructure/PushNotifications/NotificationTextAttribute.cs index 38cac6b06f..ed5561f17b 100644 --- a/Modules/Devices/src/Devices.Application/Infrastructure/PushNotifications/NotificationTextAttribute.cs +++ b/Modules/Devices/src/Devices.Application/Infrastructure/PushNotifications/NotificationTextAttribute.cs @@ -5,6 +5,6 @@ public class NotificationTextAttribute : Attribute public const string DEFAULT_TITLE = "Aktualisierungen eingegangen"; public const string DEFAULT_BODY = "Es sind neue Aktualisierungen in der Enmeshed App vorhanden."; - public string Title { get; set; } - public string Body { get; set; } + public required string Title { get; set; } + public required string Body { get; set; } } diff --git a/Modules/Devices/src/Devices.Application/IntegrationEvents/Incoming/DatawalletModificationCreated/DatawalletModifiedIntegrationEvent.cs b/Modules/Devices/src/Devices.Application/IntegrationEvents/Incoming/DatawalletModificationCreated/DatawalletModifiedIntegrationEvent.cs index ab83847dcd..22de4e8df0 100644 --- a/Modules/Devices/src/Devices.Application/IntegrationEvents/Incoming/DatawalletModificationCreated/DatawalletModifiedIntegrationEvent.cs +++ b/Modules/Devices/src/Devices.Application/IntegrationEvents/Incoming/DatawalletModificationCreated/DatawalletModifiedIntegrationEvent.cs @@ -5,6 +5,6 @@ namespace Backbone.Modules.Devices.Application.IntegrationEvents.Incoming.Datawa public class DatawalletModifiedIntegrationEvent : IntegrationEvent { - public IdentityAddress Identity { get; set; } - public DeviceId ModifiedByDevice { get; set; } + public required IdentityAddress Identity { get; set; } + public required DeviceId ModifiedByDevice { get; set; } } diff --git a/Modules/Devices/src/Devices.Application/IntegrationEvents/Incoming/DatawalletModificationCreated/DatawalletModifiedIntegrationEventHandler.cs b/Modules/Devices/src/Devices.Application/IntegrationEvents/Incoming/DatawalletModificationCreated/DatawalletModifiedIntegrationEventHandler.cs index 1d6333cbcd..8c904de991 100644 --- a/Modules/Devices/src/Devices.Application/IntegrationEvents/Incoming/DatawalletModificationCreated/DatawalletModifiedIntegrationEventHandler.cs +++ b/Modules/Devices/src/Devices.Application/IntegrationEvents/Incoming/DatawalletModificationCreated/DatawalletModifiedIntegrationEventHandler.cs @@ -15,6 +15,7 @@ public DatawalletModifiedIntegrationEventHandler(IPushNotificationSender pushSen public async Task Handle(DatawalletModifiedIntegrationEvent integrationEvent) { - await _pushSenderService.SendNotification(integrationEvent.Identity, new DatawalletModificationsCreatedPushNotification(integrationEvent.ModifiedByDevice), CancellationToken.None); + var notification = new DatawalletModificationsCreatedPushNotification(integrationEvent.ModifiedByDevice); + await _pushSenderService.SendNotification(integrationEvent.Identity, notification, CancellationToken.None); } } diff --git a/Modules/Devices/src/Devices.Application/IntegrationEvents/Incoming/ExternalEventCreated/ExternalEventCreatedIntegrationEvent.cs b/Modules/Devices/src/Devices.Application/IntegrationEvents/Incoming/ExternalEventCreated/ExternalEventCreatedIntegrationEvent.cs index 4821c2d547..556503c01d 100644 --- a/Modules/Devices/src/Devices.Application/IntegrationEvents/Incoming/ExternalEventCreated/ExternalEventCreatedIntegrationEvent.cs +++ b/Modules/Devices/src/Devices.Application/IntegrationEvents/Incoming/ExternalEventCreated/ExternalEventCreatedIntegrationEvent.cs @@ -4,5 +4,5 @@ namespace Backbone.Modules.Devices.Application.IntegrationEvents.Incoming.Extern public class ExternalEventCreatedIntegrationEvent : IntegrationEvent { - public string Owner { get; set; } + public required string Owner { get; set; } } diff --git a/Modules/Devices/src/Devices.Application/IntegrationEvents/Outgoing/IdentityCreatedIntegrationEvent.cs b/Modules/Devices/src/Devices.Application/IntegrationEvents/Outgoing/IdentityCreatedIntegrationEvent.cs index acc671886c..254137b545 100644 --- a/Modules/Devices/src/Devices.Application/IntegrationEvents/Outgoing/IdentityCreatedIntegrationEvent.cs +++ b/Modules/Devices/src/Devices.Application/IntegrationEvents/Outgoing/IdentityCreatedIntegrationEvent.cs @@ -7,7 +7,7 @@ public class IdentityCreatedIntegrationEvent : IntegrationEvent public IdentityCreatedIntegrationEvent(Identity identity) : base($"{identity.Address}/Created") { Address = identity.Address; - Tier = identity.TierId; + Tier = identity.TierId!; } public string Address { get; } diff --git a/Modules/Devices/src/Devices.Application/PasswordGenerator.cs b/Modules/Devices/src/Devices.Application/PasswordGenerator.cs index df06e30220..e82fc20be6 100644 --- a/Modules/Devices/src/Devices.Application/PasswordGenerator.cs +++ b/Modules/Devices/src/Devices.Application/PasswordGenerator.cs @@ -1,4 +1,5 @@ -using System.Security.Cryptography; +using System.Diagnostics.CodeAnalysis; +using System.Security.Cryptography; using System.Text; namespace Backbone.Modules.Devices.Application; diff --git a/Modules/Devices/src/Devices.Application/PushNotifications/Commands/SendTestNotification/SendTestNotificationCommand.cs b/Modules/Devices/src/Devices.Application/PushNotifications/Commands/SendTestNotification/SendTestNotificationCommand.cs index 6347164cd5..a6f333fce1 100644 --- a/Modules/Devices/src/Devices.Application/PushNotifications/Commands/SendTestNotification/SendTestNotificationCommand.cs +++ b/Modules/Devices/src/Devices.Application/PushNotifications/Commands/SendTestNotification/SendTestNotificationCommand.cs @@ -4,5 +4,5 @@ namespace Backbone.Modules.Devices.Application.PushNotifications.Commands.SendTe public class SendTestNotificationCommand : IRequest { - public object Data { get; set; } + public required object Data { get; set; } } diff --git a/Modules/Devices/src/Devices.Application/PushNotifications/Commands/UpdateDeviceRegistration/UpdateDeviceRegistrationCommand.cs b/Modules/Devices/src/Devices.Application/PushNotifications/Commands/UpdateDeviceRegistration/UpdateDeviceRegistrationCommand.cs index cc033d2b00..b36157e804 100644 --- a/Modules/Devices/src/Devices.Application/PushNotifications/Commands/UpdateDeviceRegistration/UpdateDeviceRegistrationCommand.cs +++ b/Modules/Devices/src/Devices.Application/PushNotifications/Commands/UpdateDeviceRegistration/UpdateDeviceRegistrationCommand.cs @@ -4,8 +4,8 @@ namespace Backbone.Modules.Devices.Application.PushNotifications.Commands.Update public class UpdateDeviceRegistrationCommand : IRequest { - public string Platform { get; set; } - public string Handle { get; set; } - public string AppId { get; set; } + public required string Platform { get; set; } + public required string Handle { get; set; } + public required string AppId { get; set; } public string? Environment { get; set; } } diff --git a/Modules/Devices/src/Devices.Application/Tiers/Commands/DeleteTier/Handler.cs b/Modules/Devices/src/Devices.Application/Tiers/Commands/DeleteTier/Handler.cs index c55bcd7bc1..8cf627276d 100644 --- a/Modules/Devices/src/Devices.Application/Tiers/Commands/DeleteTier/Handler.cs +++ b/Modules/Devices/src/Devices.Application/Tiers/Commands/DeleteTier/Handler.cs @@ -1,4 +1,5 @@ -using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.EventBus; +using Backbone.BuildingBlocks.Application.Abstractions.Exceptions; +using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.EventBus; using Backbone.BuildingBlocks.Domain; using Backbone.Modules.Devices.Application.Infrastructure.Persistence.Repository; using Backbone.Modules.Devices.Application.IntegrationEvents.Outgoing; @@ -25,7 +26,7 @@ public async Task Handle(DeleteTierCommand request, CancellationToken cancellati if (tierIdResult.IsFailure) throw new DomainException(tierIdResult.Error); - var tier = await _tiersRepository.FindById(tierIdResult.Value, cancellationToken); + var tier = await _tiersRepository.FindById(tierIdResult.Value, cancellationToken) ?? throw new NotFoundException(nameof(Tier)); var clientsCount = await _tiersRepository.GetNumberOfClientsWithDefaultTier(tier, cancellationToken); diff --git a/Modules/Devices/src/Devices.Application/Users/Commands/SeedTestUsers/Handler.cs b/Modules/Devices/src/Devices.Application/Users/Commands/SeedTestUsers/Handler.cs index 5c5701b13a..a05e39d150 100644 --- a/Modules/Devices/src/Devices.Application/Users/Commands/SeedTestUsers/Handler.cs +++ b/Modules/Devices/src/Devices.Application/Users/Commands/SeedTestUsers/Handler.cs @@ -7,6 +7,7 @@ using Microsoft.AspNetCore.Identity; namespace Backbone.Modules.Devices.Application.Users.Commands.SeedTestUsers; + public class Handler : IRequestHandler { private readonly IPasswordHasher _passwordHasher; @@ -22,31 +23,29 @@ public Handler(IDevicesDbContext context, ITiersRepository tiersRepository, IPas public async Task Handle(SeedTestUsersCommand request, CancellationToken cancellationToken) { - var basicTier = await _tiersRepository.GetBasicTierAsync(cancellationToken); + var basicTier = await _tiersRepository.FindBasicTier(cancellationToken); - var user = new ApplicationUser + var user = new ApplicationUser(new Device(new Identity("test", + IdentityAddress.Create([1, 1, 1, 1, 1], "id1"), + [1, 1, 1, 1, 1], basicTier!.Id, 1 + ))) { SecurityStamp = Guid.NewGuid().ToString("D"), UserName = "USRa", NormalizedUserName = "USRA", - Device = new Device(new Identity("test", - IdentityAddress.Create(new byte[] { 1, 1, 1, 1, 1 }, "id1"), - new byte[] { 1, 1, 1, 1, 1 }, basicTier.Id, 1 - )), CreatedAt = SystemTime.UtcNow }; user.PasswordHash = _passwordHasher.HashPassword(user, "a"); await _dbContext.Set().AddAsync(user, cancellationToken); - user = new ApplicationUser + user = new ApplicationUser(new Device(new Identity("test", + IdentityAddress.Create([2, 2, 2, 2, 2], "id1"), + [2, 2, 2, 2, 2], basicTier.Id, 1 + ))) { SecurityStamp = Guid.NewGuid().ToString("D"), UserName = "USRb", NormalizedUserName = "USRB", - Device = new Device(new Identity("test", - IdentityAddress.Create(new byte[] { 2, 2, 2, 2, 2 }, "id1"), - new byte[] { 2, 2, 2, 2, 2 }, basicTier.Id, 1 - )), CreatedAt = SystemTime.UtcNow }; user.PasswordHash = _passwordHasher.HashPassword(user, "b"); diff --git a/Modules/Devices/src/Devices.ConsumerApi/DevicesModule.cs b/Modules/Devices/src/Devices.ConsumerApi/DevicesModule.cs index 4a34fbeabd..e4e3fc3259 100644 --- a/Modules/Devices/src/Devices.ConsumerApi/DevicesModule.cs +++ b/Modules/Devices/src/Devices.ConsumerApi/DevicesModule.cs @@ -7,7 +7,6 @@ using Backbone.Modules.Devices.Application.Extensions; using Backbone.Modules.Devices.Infrastructure.Persistence; using Backbone.Modules.Devices.Infrastructure.Persistence.Database; -using Backbone.Modules.Devices.Infrastructure.PushNotifications; using Backbone.Modules.Devices.Infrastructure.PushNotifications.DirectPush; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -31,8 +30,8 @@ public override void ConfigureServices(IServiceCollection services, IConfigurati services.AddDatabase(options => { - options.ConnectionString = parsedConfiguration.Infrastructure.SqlDatabase.ConnectionString; options.Provider = parsedConfiguration.Infrastructure.SqlDatabase.Provider; + options.ConnectionString = parsedConfiguration.Infrastructure.SqlDatabase.ConnectionString; }); services.AddSingleton(_ => SignatureHelper.CreateEd25519WithRawKeyFormat()); diff --git a/Modules/Devices/src/Devices.Domain/Aggregates/PushNotifications/DevicePushIdentifier.cs b/Modules/Devices/src/Devices.Domain/Aggregates/PushNotifications/DevicePushIdentifier.cs index 8175fd030a..c3d29f10ad 100644 --- a/Modules/Devices/src/Devices.Domain/Aggregates/PushNotifications/DevicePushIdentifier.cs +++ b/Modules/Devices/src/Devices.Domain/Aggregates/PushNotifications/DevicePushIdentifier.cs @@ -28,12 +28,12 @@ public static DevicePushIdentifier Parse(string stringValue) public class DevicePushIdentifierTypeConverter : TypeConverter { - public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) + public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType) { return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType); } - public override object? ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value) { var stringValue = value as string; diff --git a/Modules/Devices/src/Devices.Domain/Aggregates/PushNotifications/PnsRegistration.cs b/Modules/Devices/src/Devices.Domain/Aggregates/PushNotifications/PnsRegistration.cs index 22971a95bc..acf136bac6 100644 --- a/Modules/Devices/src/Devices.Domain/Aggregates/PushNotifications/PnsRegistration.cs +++ b/Modules/Devices/src/Devices.Domain/Aggregates/PushNotifications/PnsRegistration.cs @@ -7,7 +7,18 @@ namespace Backbone.Modules.Devices.Domain.Aggregates.PushNotifications; public class PnsRegistration { - private PnsRegistration() { } + // ReSharper disable once UnusedMember.Local + private PnsRegistration() + { + // This constructor is for EF Core only; initializing the properties with null is therefore not a problem + IdentityAddress = null!; + DeviceId = null!; + DevicePushIdentifier = null!; + Handle = null!; + UpdatedAt = SystemTime.UtcNow; + AppId = null!; + Environment = PushEnvironment.Development; + } public PnsRegistration(IdentityAddress identityAddress, DeviceId deviceId, PnsHandle handle, string appId, PushEnvironment environment) { diff --git a/Modules/Devices/src/Devices.Domain/Entities/Challenge.cs b/Modules/Devices/src/Devices.Domain/Entities/Challenge.cs index 3c7b184b03..87f4c46f27 100644 --- a/Modules/Devices/src/Devices.Domain/Entities/Challenge.cs +++ b/Modules/Devices/src/Devices.Domain/Entities/Challenge.cs @@ -4,9 +4,11 @@ namespace Backbone.Modules.Devices.Domain.Entities; public class Challenge { -#pragma warning disable CS8618 - private Challenge() { } -#pragma warning restore CS8618 + // ReSharper disable once UnusedMember.Local + private Challenge() + { + Id = null!; + } public string Id { get; set; } public DateTime ExpiresAt { get; set; } diff --git a/Modules/Devices/src/Devices.Domain/Entities/Identities/ApplicationUser.cs b/Modules/Devices/src/Devices.Domain/Entities/Identities/ApplicationUser.cs index 3e763214a8..65862211ae 100644 --- a/Modules/Devices/src/Devices.Domain/Entities/Identities/ApplicationUser.cs +++ b/Modules/Devices/src/Devices.Domain/Entities/Identities/ApplicationUser.cs @@ -8,9 +8,18 @@ public class ApplicationUser : IdentityUser { private readonly Device _device; -#pragma warning disable CS8618 - public ApplicationUser() : base(Username.New()) { } -#pragma warning restore CS8618 + // This constructor is required by AspnetCoreIdentity + public ApplicationUser() + { + _device = null!; + DeviceId = null!; + } + + public ApplicationUser(Device device) : base(Username.New()) + { + _device = device; + DeviceId = null!; + } public ApplicationUser(Identity identity, DeviceId? createdByDevice = null) : base(Username.New()) { diff --git a/Modules/Devices/src/Devices.Domain/Entities/Identities/Device.cs b/Modules/Devices/src/Devices.Domain/Entities/Identities/Device.cs index 631a213a81..a8963c83e0 100644 --- a/Modules/Devices/src/Devices.Domain/Entities/Identities/Device.cs +++ b/Modules/Devices/src/Devices.Domain/Entities/Identities/Device.cs @@ -8,23 +8,36 @@ namespace Backbone.Modules.Devices.Domain.Entities.Identities; public class Device { -#pragma warning disable CS8618 - private Device() { } -#pragma warning restore CS8618 + // ReSharper disable once UnusedMember.Local + private Device() + { + // This constructor is for EF Core only; initializing the properties with null is therefore not a problem + Id = null!; + IdentityAddress = null!; + Identity = null!; + User = null!; + CreatedByDevice = null!; + } -#pragma warning disable CS8618 public Device(Identity identity, DeviceId? createdByDevice = null) -#pragma warning restore CS8618 { Id = DeviceId.New(); CreatedAt = SystemTime.UtcNow; CreatedByDevice = createdByDevice ?? Id; - // The following distinction is unfortunatly necessary in order to make EF recognize that the identity already exists + User = null!; // This is just to satisfy the compiler; the property is actually set by EF core + + // The following distinction is unfortunately necessary in order to make EF recognize that the identity already exists if (identity.IsNew()) + { Identity = identity; + IdentityAddress = null!; // This is just to satisfy the compiler; the property is actually set by EF core + } else + { + Identity = null!; // This is just to satisfy the compiler; the property is actually set by EF core IdentityAddress = identity.Address; + } } public DeviceId Id { get; set; } diff --git a/Modules/Devices/src/Devices.Domain/Entities/Identities/Hasher.cs b/Modules/Devices/src/Devices.Domain/Entities/Identities/Hasher.cs index da0035cdb3..52d1bc8646 100644 --- a/Modules/Devices/src/Devices.Domain/Entities/Identities/Hasher.cs +++ b/Modules/Devices/src/Devices.Domain/Entities/Identities/Hasher.cs @@ -1,6 +1,5 @@ using System.Diagnostics; using System.Security.Cryptography; -using System.Text; using Microsoft.AspNetCore.Cryptography.KeyDerivation; namespace Backbone.Modules.Devices.Domain.Entities.Identities; diff --git a/Modules/Devices/src/Devices.Domain/Entities/Identities/Identity.cs b/Modules/Devices/src/Devices.Domain/Entities/Identities/Identity.cs index 3f143a5d84..4af07c158d 100644 --- a/Modules/Devices/src/Devices.Domain/Entities/Identities/Identity.cs +++ b/Modules/Devices/src/Devices.Domain/Entities/Identities/Identity.cs @@ -17,17 +17,17 @@ public Identity(string? clientId, IdentityAddress address, byte[] publicKey, Tie PublicKey = publicKey; IdentityVersion = identityVersion; CreatedAt = SystemTime.UtcNow; - Devices = new List(); + Devices = []; TierId = tierId; Status = IdentityStatus.Active; - _deletionProcesses = new List(); + _deletionProcesses = []; } - public string? ClientId { get; private set; } + public string? ClientId { get; } - public IdentityAddress Address { get; private set; } - public byte[] PublicKey { get; private set; } - public DateTime CreatedAt { get; private set; } + public IdentityAddress Address { get; } + public byte[] PublicKey { get; } + public DateTime CreatedAt { get; } public List Devices { get; } diff --git a/Modules/Devices/src/Devices.Domain/Entities/OAuthClient.cs b/Modules/Devices/src/Devices.Domain/Entities/OAuthClient.cs index 5e651a21f9..fcd716539e 100644 --- a/Modules/Devices/src/Devices.Domain/Entities/OAuthClient.cs +++ b/Modules/Devices/src/Devices.Domain/Entities/OAuthClient.cs @@ -1,5 +1,4 @@ -using Backbone.BuildingBlocks.Domain.Errors; -using Backbone.Modules.Devices.Domain.Aggregates.Tier; +using Backbone.Modules.Devices.Domain.Aggregates.Tier; namespace Backbone.Modules.Devices.Domain.Entities; public class OAuthClient diff --git a/Modules/Devices/src/Devices.Infrastructure/Devices.Infrastructure.csproj b/Modules/Devices/src/Devices.Infrastructure/Devices.Infrastructure.csproj index 28969763f0..b9b8b83be4 100644 --- a/Modules/Devices/src/Devices.Infrastructure/Devices.Infrastructure.csproj +++ b/Modules/Devices/src/Devices.Infrastructure/Devices.Infrastructure.csproj @@ -1,6 +1,7 @@  + enable diff --git a/Modules/Devices/src/Devices.Infrastructure/OpenIddict/CustomOpenIddictEntityFrameworkCoreApplication.cs b/Modules/Devices/src/Devices.Infrastructure/OpenIddict/CustomOpenIddictEntityFrameworkCoreApplication.cs index eabbc817fd..d7f82e2454 100644 --- a/Modules/Devices/src/Devices.Infrastructure/OpenIddict/CustomOpenIddictEntityFrameworkCoreApplication.cs +++ b/Modules/Devices/src/Devices.Infrastructure/OpenIddict/CustomOpenIddictEntityFrameworkCoreApplication.cs @@ -7,9 +7,9 @@ namespace Backbone.Modules.Devices.Infrastructure.OpenIddict; public class CustomOpenIddictEntityFrameworkCoreApplication : OpenIddictEntityFrameworkCoreApplication { - public TierId DefaultTier { get; set; } + public required TierId DefaultTier { get; set; } - public DateTime CreatedAt { get; set; } + public required DateTime CreatedAt { get; set; } public int? MaxIdentities { get; set; } diff --git a/Modules/Devices/src/Devices.Infrastructure/Persistence/Database/DevicesDbContext.cs b/Modules/Devices/src/Devices.Infrastructure/Persistence/Database/DevicesDbContext.cs index bb5be4eaf1..a1f35931ed 100644 --- a/Modules/Devices/src/Devices.Infrastructure/Persistence/Database/DevicesDbContext.cs +++ b/Modules/Devices/src/Devices.Infrastructure/Persistence/Database/DevicesDbContext.cs @@ -21,7 +21,7 @@ namespace Backbone.Modules.Devices.Infrastructure.Persistence.Database; public class DevicesDbContext : IdentityDbContext, IDevicesDbContext { - private readonly IServiceProvider _serviceProvider; + private readonly IServiceProvider? _serviceProvider; private const int MAX_RETRY_COUNT = 50000; private static readonly TimeSpan MAX_RETRY_DELAY = TimeSpan.FromSeconds(1); private const string SQLSERVER = "Microsoft.EntityFrameworkCore.SqlServer"; @@ -38,15 +38,15 @@ public DevicesDbContext(DbContextOptions options, IServiceProv _serviceProvider = serviceProvider; } - public DbSet Identities { get; set; } + public DbSet Identities { get; set; } = null!; - public DbSet Devices { get; set; } + public DbSet Devices { get; set; } = null!; - public DbSet Challenges { get; set; } + public DbSet Challenges { get; set; } = null!; - public DbSet Tiers { get; set; } + public DbSet Tiers { get; set; } = null!; - public DbSet PnsRegistrations { get; set; } + public DbSet PnsRegistrations { get; set; } = null!; public IQueryable SetReadOnly() where T : class { @@ -61,17 +61,17 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) optionsBuilder.AddInterceptors(_serviceProvider.GetRequiredService()); } - public async Task RunInTransaction(Func action, List errorNumbersToRetry, + public async Task RunInTransaction(Func action, List? errorNumbersToRetry, IsolationLevel isolationLevel = IsolationLevel.ReadCommitted) { - ExecutionStrategy? executionStrategy; + ExecutionStrategy executionStrategy; switch (Database.ProviderName) { case SQLSERVER: executionStrategy = new SqlServerRetryingExecutionStrategy(this, MAX_RETRY_COUNT, MAX_RETRY_DELAY, errorNumbersToRetry); break; case POSTGRES: - var errorCodesToRetry = errorNumbersToRetry != null ? errorNumbersToRetry.ConvertAll(x => x.ToString()) : new List(); + var errorCodesToRetry = errorNumbersToRetry != null ? errorNumbersToRetry.ConvertAll(x => x.ToString()) : []; executionStrategy = new NpgsqlRetryingExecutionStrategy(this, MAX_RETRY_COUNT, MAX_RETRY_DELAY, errorCodesToRetry); break; default: @@ -91,10 +91,11 @@ public async Task RunInTransaction(Func action, IsolationLevel isolationLe await RunInTransaction(action, null, isolationLevel); } - public async Task RunInTransaction(Func> action, List errorNumbersToRetry, + public async Task RunInTransaction(Func> action, List? errorNumbersToRetry, IsolationLevel isolationLevel = IsolationLevel.ReadCommitted) { - var response = default(T); + // the '!' is safe here because the default value is only returned after the action is executed, which is setting the response + var response = default(T)!; await RunInTransaction(async () => { response = await action(); }, errorNumbersToRetry, isolationLevel); diff --git a/Modules/Devices/src/Devices.Infrastructure/Persistence/Database/EntityConfigurations/IdentityEntityTypeConfiguration.cs b/Modules/Devices/src/Devices.Infrastructure/Persistence/Database/EntityConfigurations/IdentityEntityTypeConfiguration.cs index 25bdcc6810..e99afd36d8 100644 --- a/Modules/Devices/src/Devices.Infrastructure/Persistence/Database/EntityConfigurations/IdentityEntityTypeConfiguration.cs +++ b/Modules/Devices/src/Devices.Infrastructure/Persistence/Database/EntityConfigurations/IdentityEntityTypeConfiguration.cs @@ -10,5 +10,7 @@ public void Configure(EntityTypeBuilder builder) { builder.HasKey(x => x.Address); builder.Property(x => x.ClientId).HasMaxLength(200); + builder.Property(x => x.CreatedAt); + builder.Property(x => x.PublicKey); } } diff --git a/Modules/Devices/src/Devices.Infrastructure/Persistence/Database/QueryableExtensions/DeviceQueryableExtensions.cs b/Modules/Devices/src/Devices.Infrastructure/Persistence/Database/QueryableExtensions/DeviceQueryableExtensions.cs index 9e439dd5d6..d83692001a 100644 --- a/Modules/Devices/src/Devices.Infrastructure/Persistence/Database/QueryableExtensions/DeviceQueryableExtensions.cs +++ b/Modules/Devices/src/Devices.Infrastructure/Persistence/Database/QueryableExtensions/DeviceQueryableExtensions.cs @@ -1,4 +1,3 @@ -using Backbone.BuildingBlocks.Application.Abstractions.Exceptions; using Backbone.DevelopmentKit.Identity.ValueObjects; using Backbone.Modules.Devices.Domain.Entities.Identities; using Microsoft.EntityFrameworkCore; diff --git a/Modules/Devices/src/Devices.Infrastructure/Persistence/Database/QueryableExtensions/IdentityQueryableExtensions.cs b/Modules/Devices/src/Devices.Infrastructure/Persistence/Database/QueryableExtensions/IdentityQueryableExtensions.cs index 4707c69d2b..2c787b44e2 100644 --- a/Modules/Devices/src/Devices.Infrastructure/Persistence/Database/QueryableExtensions/IdentityQueryableExtensions.cs +++ b/Modules/Devices/src/Devices.Infrastructure/Persistence/Database/QueryableExtensions/IdentityQueryableExtensions.cs @@ -13,7 +13,7 @@ public static async Task FirstWithAddress(this IQueryable qu return identity; } - public static async Task FirstWithAddressOrDefault(this IQueryable query, IdentityAddress address, CancellationToken cancellationToken) + public static async Task FirstWithAddressOrDefault(this IQueryable query, IdentityAddress address, CancellationToken cancellationToken) { var identity = await query.FirstOrDefaultAsync(e => e.Address == address, cancellationToken); diff --git a/Modules/Devices/src/Devices.Infrastructure/Persistence/Database/QueryableExtensions/TierQueryableExtensions.cs b/Modules/Devices/src/Devices.Infrastructure/Persistence/Database/QueryableExtensions/TierQueryableExtensions.cs index 717851d84d..8613c08744 100644 --- a/Modules/Devices/src/Devices.Infrastructure/Persistence/Database/QueryableExtensions/TierQueryableExtensions.cs +++ b/Modules/Devices/src/Devices.Infrastructure/Persistence/Database/QueryableExtensions/TierQueryableExtensions.cs @@ -5,7 +5,7 @@ namespace Backbone.Modules.Devices.Infrastructure.Persistence.Database.Queryable public static class TierQueryableExtensions { - public static async Task GetBasicTier(this IQueryable query, CancellationToken cancellationToken) + public static async Task GetBasicTier(this IQueryable query, CancellationToken cancellationToken) { var basicTier = await query.FirstOrDefaultAsync(t => t.Name == TierName.BASIC_DEFAULT_NAME, cancellationToken); diff --git a/Modules/Devices/src/Devices.Infrastructure/Persistence/Database/ValueConverters/IdentityDeletionProcessAuditLogEntryIdEntityFrameworkValueConverter.cs b/Modules/Devices/src/Devices.Infrastructure/Persistence/Database/ValueConverters/IdentityDeletionProcessAuditLogEntryIdEntityFrameworkValueConverter.cs index e5896ba34f..82d46e12ff 100644 --- a/Modules/Devices/src/Devices.Infrastructure/Persistence/Database/ValueConverters/IdentityDeletionProcessAuditLogEntryIdEntityFrameworkValueConverter.cs +++ b/Modules/Devices/src/Devices.Infrastructure/Persistence/Database/ValueConverters/IdentityDeletionProcessAuditLogEntryIdEntityFrameworkValueConverter.cs @@ -1,5 +1,4 @@ -using Backbone.Modules.Devices.Domain.Aggregates.Tier; -using Backbone.Modules.Devices.Domain.Entities.Identities; +using Backbone.Modules.Devices.Domain.Entities.Identities; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; namespace Backbone.Modules.Devices.Infrastructure.Persistence.Database.ValueConverters; diff --git a/Modules/Devices/src/Devices.Infrastructure/Persistence/Database/ValueConverters/IdentityDeletionProcessIdEntityFrameworkValueConverter.cs b/Modules/Devices/src/Devices.Infrastructure/Persistence/Database/ValueConverters/IdentityDeletionProcessIdEntityFrameworkValueConverter.cs index 7ad8a8ce92..113548bf0c 100644 --- a/Modules/Devices/src/Devices.Infrastructure/Persistence/Database/ValueConverters/IdentityDeletionProcessIdEntityFrameworkValueConverter.cs +++ b/Modules/Devices/src/Devices.Infrastructure/Persistence/Database/ValueConverters/IdentityDeletionProcessIdEntityFrameworkValueConverter.cs @@ -1,5 +1,4 @@ -using Backbone.Modules.Devices.Domain.Aggregates.Tier; -using Backbone.Modules.Devices.Domain.Entities.Identities; +using Backbone.Modules.Devices.Domain.Entities.Identities; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; namespace Backbone.Modules.Devices.Infrastructure.Persistence.Database.ValueConverters; diff --git a/Modules/Devices/src/Devices.Infrastructure/Persistence/IServiceCollectionExtensions.cs b/Modules/Devices/src/Devices.Infrastructure/Persistence/IServiceCollectionExtensions.cs index 587e4d7f75..543df66b71 100644 --- a/Modules/Devices/src/Devices.Infrastructure/Persistence/IServiceCollectionExtensions.cs +++ b/Modules/Devices/src/Devices.Infrastructure/Persistence/IServiceCollectionExtensions.cs @@ -19,7 +19,7 @@ public static class IServiceCollectionExtensions public static void AddDatabase(this IServiceCollection services, Action setupOptions) { var options = new DbOptions(); - setupOptions?.Invoke(options); + setupOptions(options); services .AddDbContext(dbContextOptions => @@ -69,8 +69,8 @@ public static void AddRepositories(this IServiceCollection services) public class DbOptions { - public string Provider { get; set; } - public string ConnectionString { get; set; } + public string Provider { get; set; } = null!; + public string ConnectionString { get; set; } = null!; public RetryOptions RetryOptions { get; set; } = new(); } diff --git a/Modules/Devices/src/Devices.Infrastructure/Persistence/Repository/ChallengesRepository.cs b/Modules/Devices/src/Devices.Infrastructure/Persistence/Repository/ChallengesRepository.cs index a54141998d..764e1e5789 100644 --- a/Modules/Devices/src/Devices.Infrastructure/Persistence/Repository/ChallengesRepository.cs +++ b/Modules/Devices/src/Devices.Infrastructure/Persistence/Repository/ChallengesRepository.cs @@ -8,16 +8,14 @@ public class ChallengesRepository : IChallengesRepository { private readonly DbSet _challenges; private readonly IQueryable _readonlyChallenges; - private readonly DevicesDbContext _dbContext; public ChallengesRepository(DevicesDbContext dbContext) { _challenges = dbContext.Challenges; _readonlyChallenges = dbContext.Challenges.AsNoTracking(); - _dbContext = dbContext; } - public async Task FindById(string id, CancellationToken cancellationToken, bool track = false) + public async Task FindById(string id, CancellationToken cancellationToken, bool track = false) { return await (track ? _challenges : _readonlyChallenges) .Where(c => c.Id == id).FirstOrDefaultAsync(cancellationToken); diff --git a/Modules/Devices/src/Devices.Infrastructure/Persistence/Repository/IdentitiesRepository.cs b/Modules/Devices/src/Devices.Infrastructure/Persistence/Repository/IdentitiesRepository.cs index 608b2a7747..dc5de51be5 100644 --- a/Modules/Devices/src/Devices.Infrastructure/Persistence/Repository/IdentitiesRepository.cs +++ b/Modules/Devices/src/Devices.Infrastructure/Persistence/Repository/IdentitiesRepository.cs @@ -40,7 +40,7 @@ public async Task> FindAll(PaginationFilter paginat return paginationResult; } - public async Task FindByAddress(IdentityAddress address, CancellationToken cancellationToken, bool track = false) + public async Task FindByAddress(IdentityAddress address, CancellationToken cancellationToken, bool track = false) { return await (track ? _identities : _readonlyIdentities) .IncludeAll(_dbContext) @@ -87,7 +87,7 @@ public async Task> FindAllDevicesOfIdentity(IdentityA return await query.OrderAndPaginate(d => d.CreatedAt, paginationFilter, cancellationToken); } - public async Task GetDeviceById(DeviceId deviceId, CancellationToken cancellationToken, bool track = false) + public async Task GetDeviceById(DeviceId deviceId, CancellationToken cancellationToken, bool track = false) { return await (track ? _devices : _readonlyDevices) .NotDeleted() diff --git a/Modules/Devices/src/Devices.Infrastructure/Persistence/Repository/OAuthClientsRepository.cs b/Modules/Devices/src/Devices.Infrastructure/Persistence/Repository/OAuthClientsRepository.cs index fe6bdd377b..b7730524d1 100644 --- a/Modules/Devices/src/Devices.Infrastructure/Persistence/Repository/OAuthClientsRepository.cs +++ b/Modules/Devices/src/Devices.Infrastructure/Persistence/Repository/OAuthClientsRepository.cs @@ -33,7 +33,7 @@ public async Task> FindAll(CancellationToken cancellati return oAuthClients; } - public async Task Find(string clientId, CancellationToken cancellationToken, bool track = false) + public async Task Find(string clientId, CancellationToken cancellationToken, bool track = false) { if (_trackedApplications.TryGetValue(clientId, out var trackedApplication)) { @@ -138,7 +138,7 @@ private void Track(IEnumerable a } } - private void Track(CustomOpenIddictEntityFrameworkCoreApplication application) + private void Track(CustomOpenIddictEntityFrameworkCoreApplication? application) { if (application != null) { diff --git a/Modules/Devices/src/Devices.Infrastructure/Persistence/Repository/PnsRegistrationsRepository.cs b/Modules/Devices/src/Devices.Infrastructure/Persistence/Repository/PnsRegistrationsRepository.cs index 6f375a447f..63af2e462f 100644 --- a/Modules/Devices/src/Devices.Infrastructure/Persistence/Repository/PnsRegistrationsRepository.cs +++ b/Modules/Devices/src/Devices.Infrastructure/Persistence/Repository/PnsRegistrationsRepository.cs @@ -41,7 +41,7 @@ public async Task> FindWithAddress(IdentityAddress .Where(registration => registration.IdentityAddress == address).ToListAsync(cancellationToken); } - public async Task FindByDeviceId(DeviceId deviceId, CancellationToken cancellationToken, bool track = false) + public async Task FindByDeviceId(DeviceId deviceId, CancellationToken cancellationToken, bool track = false) { return await (track ? _registrations : _readonlyRegistrations) .FirstOrDefaultAsync(registration => registration.DeviceId == deviceId, cancellationToken); diff --git a/Modules/Devices/src/Devices.Infrastructure/Persistence/Repository/TiersRepository.cs b/Modules/Devices/src/Devices.Infrastructure/Persistence/Repository/TiersRepository.cs index 95019f5569..893e339de9 100644 --- a/Modules/Devices/src/Devices.Infrastructure/Persistence/Repository/TiersRepository.cs +++ b/Modules/Devices/src/Devices.Infrastructure/Persistence/Repository/TiersRepository.cs @@ -33,7 +33,7 @@ public async Task AddAsync(Tier tier, CancellationToken cancellationToken) await _dbContext.SaveChangesAsync(cancellationToken); } - public async Task FindByName(TierName tierName, CancellationToken cancellationToken, bool track = false) + public async Task FindByName(TierName tierName, CancellationToken cancellationToken, bool track = false) { return await (track ? _tiers : _readonlyTiers).FirstOrDefaultAsync(i => i.Name == tierName, cancellationToken); } @@ -71,12 +71,12 @@ public async Task> FindAll(PaginationFilter paginationF return paginationResult; } - public async Task FindById(TierId tierId, CancellationToken cancellationToken) + public async Task FindById(TierId tierId, CancellationToken cancellationToken) { return await _tiers.FirstOrDefaultAsync(t => t.Id == tierId, cancellationToken) ?? throw new NotFoundException(nameof(Tier)); } - public async Task GetBasicTierAsync(CancellationToken cancellationToken) + public async Task FindBasicTier(CancellationToken cancellationToken) { return await _tiers.GetBasicTier(cancellationToken); } diff --git a/Modules/Devices/src/Devices.Infrastructure/PushNotifications/DirectPush/ApplePushNotificationService/ApnsMessageBuilder.cs b/Modules/Devices/src/Devices.Infrastructure/PushNotifications/DirectPush/ApplePushNotificationService/ApnsMessageBuilder.cs index 1347bcf707..045f28e364 100644 --- a/Modules/Devices/src/Devices.Infrastructure/PushNotifications/DirectPush/ApplePushNotificationService/ApnsMessageBuilder.cs +++ b/Modules/Devices/src/Devices.Infrastructure/PushNotifications/DirectPush/ApplePushNotificationService/ApnsMessageBuilder.cs @@ -3,6 +3,8 @@ using System.Text.Json.Serialization; using Backbone.Tooling.Extensions; +// ReSharper disable UnusedAutoPropertyAccessor.Local + namespace Backbone.Modules.Devices.Infrastructure.PushNotifications.DirectPush.ApplePushNotificationService; public class ApnsMessageBuilder @@ -70,7 +72,7 @@ private class Payload public int NotificationId { get; set; } [JsonPropertyName("content")] - public NotificationContent Content { get; set; } + public NotificationContent? Content { get; set; } [JsonPropertyName("aps")] public PayloadAps Aps { get; } = new(); @@ -78,7 +80,7 @@ private class Payload public class PayloadAps { [JsonPropertyName("content-available")] - public string ContentAvailable { get; set; } + public string? ContentAvailable { get; set; } [JsonPropertyName("alert")] public ApsAlert Alert { get; } = new(); @@ -86,10 +88,10 @@ public class PayloadAps public class ApsAlert { [JsonPropertyName("title")] - public string Title { get; set; } + public string? Title { get; set; } [JsonPropertyName("body")] - public string Body { get; set; } + public string? Body { get; set; } } } } diff --git a/Modules/Devices/src/Devices.Infrastructure/PushNotifications/DirectPush/ApplePushNotificationService/ApplePushNotificationServiceConnector.cs b/Modules/Devices/src/Devices.Infrastructure/PushNotifications/DirectPush/ApplePushNotificationService/ApplePushNotificationServiceConnector.cs index 618d9ef9dc..667840a37a 100644 --- a/Modules/Devices/src/Devices.Infrastructure/PushNotifications/DirectPush/ApplePushNotificationService/ApplePushNotificationServiceConnector.cs +++ b/Modules/Devices/src/Devices.Infrastructure/PushNotifications/DirectPush/ApplePushNotificationService/ApplePushNotificationServiceConnector.cs @@ -1,5 +1,4 @@ using System.Reflection; -using System.Reflection.Metadata; using System.Text.Json; using Backbone.BuildingBlocks.Infrastructure.Exceptions; using Backbone.DevelopmentKit.Identity.ValueObjects; @@ -60,7 +59,7 @@ private async Task SendNotification(PnsRegistration registration, object notific var notificationId = GetNotificationId(notification); var notificationContent = new NotificationContent(registration.IdentityAddress, registration.DevicePushIdentifier, notification); - var keyInformation = _options.GetKeyInformationForBundleId(registration.AppId!); + var keyInformation = _options.GetKeyInformationForBundleId(registration.AppId); var jwt = _jwtGenerator.Generate(keyInformation.PrivateKey, keyInformation.KeyId, keyInformation.TeamId, registration.AppId); var request = new ApnsMessageBuilder(registration.AppId, BuildUrl(registration.Environment, registration.Handle.Value), jwt.Value) @@ -77,7 +76,7 @@ private async Task SendNotification(PnsRegistration registration, object notific sendResults.AddSuccess(registration.DeviceId); else { - var responseContent = JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync()); + var responseContent = JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync())!; if (responseContent.reason == "Unregistered") sendResults.AddFailure(registration.DeviceId, ErrorReason.InvalidHandle); else @@ -125,8 +124,8 @@ private static (string Title, string Body) GetNotificationText(object pushNotifi public static class TypeExtensions { - public static T GetCustomAttribute(this Type type) where T : Attribute + public static T? GetCustomAttribute(this Type type) where T : Attribute { - return (T)type.GetCustomAttribute(typeof(T)); + return (T?)type.GetCustomAttribute(typeof(T)); } } diff --git a/Modules/Devices/src/Devices.Infrastructure/PushNotifications/DirectPush/DirectPnsCommunicationOptions.cs b/Modules/Devices/src/Devices.Infrastructure/PushNotifications/DirectPush/DirectPnsCommunicationOptions.cs index 33852a2385..8ce39832d7 100644 --- a/Modules/Devices/src/Devices.Infrastructure/PushNotifications/DirectPush/DirectPnsCommunicationOptions.cs +++ b/Modules/Devices/src/Devices.Infrastructure/PushNotifications/DirectPush/DirectPnsCommunicationOptions.cs @@ -5,19 +5,21 @@ namespace Backbone.Modules.Devices.Infrastructure.PushNotifications.DirectPush; public class DirectPnsCommunicationOptions { - public FcmOptions Fcm { get; set; } + [Required] + public required FcmOptions Fcm { get; set; } = null!; - public ApnsOptions Apns { get; set; } + [Required] + public required ApnsOptions Apns { get; set; } = null!; public class FcmOptions { [Required] [MinLength(1)] - public Dictionary ServiceAccounts { get; set; } = new(); + public required Dictionary ServiceAccounts { get; set; } = []; [Required] [MinLength(1)] - public Dictionary Apps { get; set; } = new(); + public required Dictionary Apps { get; set; } = []; public class ServiceAccountInformation { @@ -46,10 +48,7 @@ public bool HasConfigForAppId(string appId) var serviceAccount = ServiceAccounts.GetValueOrDefault(app.ServiceAccountName); - if (serviceAccount == null) - return null; - - return serviceAccount.ServiceAccountJson; + return serviceAccount?.ServiceAccountJson; } public List GetSupportedAppIds() @@ -61,7 +60,7 @@ public class ServiceAccount { [Required] [MinLength(1)] - public string ServiceAccountJson { get; set; } = string.Empty; + public required string ServiceAccountJson { get; set; } = string.Empty; } } @@ -69,11 +68,11 @@ public class ApnsOptions { [Required] [MinLength(1)] - public Dictionary Keys { get; set; } = new(); + public required Dictionary Keys { get; set; } = new(); [Required] [MinLength(1)] - public Dictionary Bundles { get; set; } = new(); + public required Dictionary Bundles { get; set; } = new(); public bool HasConfigForBundleId(string bundleId) { @@ -84,11 +83,7 @@ public bool HasConfigForBundleId(string bundleId) public Key GetKeyInformationForBundleId(string bundleId) { var bundle = Bundles.GetValueOrDefault(bundleId); - - if (bundle == null) - return null; - - return Keys[bundle.KeyName]; + return bundle == null ? throw new Exception($"No bundle configuration for bundle id '{bundleId}' was found.") : Keys[bundle.KeyName]; } public Bundle GetBundleById(string bundleId) @@ -105,22 +100,22 @@ public class Bundle { [Required] [MinLength(1)] - public string KeyName { get; set; } + public required string KeyName { get; set; } } public class Key { [Required] [MinLength(1)] - public string TeamId { get; set; } = string.Empty; + public required string TeamId { get; set; } = string.Empty; [Required] [MinLength(1)] - public string KeyId { get; set; } = string.Empty; + public required string KeyId { get; set; } = string.Empty; [Required] [MinLength(1)] - public string PrivateKey { get; set; } = string.Empty; + public required string PrivateKey { get; set; } = string.Empty; } } } diff --git a/Modules/Devices/src/Devices.Infrastructure/PushNotifications/DirectPush/DirectPushService.cs b/Modules/Devices/src/Devices.Infrastructure/PushNotifications/DirectPush/DirectPushService.cs index 07740ce62a..2368c1ee00 100644 --- a/Modules/Devices/src/Devices.Infrastructure/PushNotifications/DirectPush/DirectPushService.cs +++ b/Modules/Devices/src/Devices.Infrastructure/PushNotifications/DirectPush/DirectPushService.cs @@ -45,7 +45,7 @@ private async Task HandleNotificationResponses(SendResults sendResults) var deviceIdsToDelete = new List(); foreach (var sendResult in sendResults.Failures) { - switch (sendResult.Error.Reason) + switch (sendResult.Error!.Reason) { case ErrorReason.InvalidHandle: _logger.DeletingDeviceRegistration(sendResult.DeviceId); @@ -109,7 +109,7 @@ public async Task DeleteRegistration(DeviceId deviceId, CancellationToken cancel } else { - await _pnsRegistrationsRepository.Delete(new List { deviceId }, cancellationToken); + await _pnsRegistrationsRepository.Delete([deviceId], cancellationToken); _logger.UnregisteredDevice(deviceId); } } diff --git a/Modules/Devices/src/Devices.Infrastructure/PushNotifications/DirectPush/FirebaseCloudMessaging/FirebaseCloudMessagingConnector.cs b/Modules/Devices/src/Devices.Infrastructure/PushNotifications/DirectPush/FirebaseCloudMessaging/FirebaseCloudMessagingConnector.cs index 73d618db27..12533a3f2f 100644 --- a/Modules/Devices/src/Devices.Infrastructure/PushNotifications/DirectPush/FirebaseCloudMessaging/FirebaseCloudMessagingConnector.cs +++ b/Modules/Devices/src/Devices.Infrastructure/PushNotifications/DirectPush/FirebaseCloudMessaging/FirebaseCloudMessagingConnector.cs @@ -115,8 +115,8 @@ private static int GetNotificationId(object pushNotification) public static class TypeExtensions { - public static T GetCustomAttribute(this Type type) where T : Attribute + public static T? GetCustomAttribute(this Type type) where T : Attribute { - return (T)type.GetCustomAttribute(typeof(T)); + return (T?)type.GetCustomAttribute(typeof(T)); } } diff --git a/Modules/Devices/src/Devices.Infrastructure/PushNotifications/DirectPush/Responses/SendResult.cs b/Modules/Devices/src/Devices.Infrastructure/PushNotifications/DirectPush/Responses/SendResult.cs index ecd74243ee..9c016234d4 100644 --- a/Modules/Devices/src/Devices.Infrastructure/PushNotifications/DirectPush/Responses/SendResult.cs +++ b/Modules/Devices/src/Devices.Infrastructure/PushNotifications/DirectPush/Responses/SendResult.cs @@ -1,21 +1,38 @@ -using Backbone.DevelopmentKit.Identity.ValueObjects; +using System.Diagnostics.CodeAnalysis; +using Backbone.DevelopmentKit.Identity.ValueObjects; namespace Backbone.Modules.Devices.Infrastructure.PushNotifications.DirectPush.Responses; public class SendResult { - public bool IsSuccess { get; private init; } + private SendResult(DeviceId deviceId) + { + DeviceId = deviceId; + IsSuccess = true; + } + + private SendResult(DeviceId deviceId, SendError error) + { + DeviceId = deviceId; + Error = error; + IsSuccess = false; + } + + public bool IsSuccess { get; } + + [MemberNotNullWhen(true, nameof(Error))] public bool IsFailure => !IsSuccess; - public SendError Error { get; private init; } + public DeviceId DeviceId { get; private set; } + public SendError? Error { get; private init; } public static SendResult Success(DeviceId deviceId) { - return new SendResult { IsSuccess = true, DeviceId = deviceId }; + return new SendResult(deviceId); } public static SendResult Failure(DeviceId deviceId, ErrorReason reason, string message = "") { - return new SendResult { IsSuccess = false, Error = new SendError(reason, message), DeviceId = deviceId }; + return new SendResult(deviceId, new SendError(reason, message)); } } diff --git a/Modules/Devices/src/Devices.Infrastructure/PushNotifications/IServiceCollectionExtensions.cs b/Modules/Devices/src/Devices.Infrastructure/PushNotifications/IServiceCollectionExtensions.cs index 7f904f1dbc..3974ca79d2 100644 --- a/Modules/Devices/src/Devices.Infrastructure/PushNotifications/IServiceCollectionExtensions.cs +++ b/Modules/Devices/src/Devices.Infrastructure/PushNotifications/IServiceCollectionExtensions.cs @@ -19,6 +19,8 @@ public static void AddPushNotifications(this IServiceCollection services, PushNo services.AddDummyPushNotifications(); break; case PROVIDER_DIRECT: + if (options.DirectPnsCommunication == null) + throw new Exception($"The '{nameof(PushNotificationOptions.DirectPnsCommunication)}' property must be provided when using the provider '${PROVIDER_DIRECT}'."); services.AddDirectPushNotifications(options.DirectPnsCommunication); break; default: @@ -32,8 +34,7 @@ public class PushNotificationOptions [Required] [RegularExpression( $"{IServiceCollectionExtensions.PROVIDER_DIRECT}|{IServiceCollectionExtensions.PROVIDER_DUMMY}")] - public string Provider { get; set; } + public string Provider { get; set; } = null!; -#nullable enable public DirectPnsCommunicationOptions? DirectPnsCommunication { get; set; } } 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 3a860bd7a2..ff106e06d2 100644 --- a/Modules/Devices/test/Devices.Application.Tests/Devices.Application.Tests.csproj +++ b/Modules/Devices/test/Devices.Application.Tests/Devices.Application.Tests.csproj @@ -2,6 +2,7 @@ false + enable diff --git a/Modules/Devices/test/Devices.Application.Tests/Tests/Clients/Commands/UpdateClient/HandlerTests.cs b/Modules/Devices/test/Devices.Application.Tests/Tests/Clients/Commands/UpdateClient/HandlerTests.cs index 21c6a1c4c7..643b80f5e5 100644 --- a/Modules/Devices/test/Devices.Application.Tests/Tests/Clients/Commands/UpdateClient/HandlerTests.cs +++ b/Modules/Devices/test/Devices.Application.Tests/Tests/Clients/Commands/UpdateClient/HandlerTests.cs @@ -1,5 +1,4 @@ using Backbone.BuildingBlocks.Application.Abstractions.Exceptions; -using Backbone.BuildingBlocks.Domain; using Backbone.Modules.Devices.Application.Clients.Commands.UpdateClient; using Backbone.Modules.Devices.Application.Infrastructure.Persistence.Repository; using Backbone.Modules.Devices.Application.Tests.Extensions; @@ -79,7 +78,7 @@ public async Task Change_Default_Tier_Of_Inexistent_Client() var command = new UpdateClientCommand(client.ClientId, newDefaultTier.Id, 1); var oAuthClientsRepository = A.Fake(); - A.CallTo(() => oAuthClientsRepository.Find(client.ClientId, A._, A._)).Returns((OAuthClient)null); + A.CallTo(() => oAuthClientsRepository.Find(client.ClientId, A._, A._)).Returns(null); var tiersRepository = A.Fake(); A.CallTo(() => tiersRepository.ExistsWithId(newDefaultTier.Id, A._)).Returns(true); @@ -129,7 +128,7 @@ public async Task Change_Max_Identities_Of_Inexistent_Client() var command = new UpdateClientCommand(client.ClientId, client.DefaultTier, 2); var oAuthClientsRepository = A.Fake(); - A.CallTo(() => oAuthClientsRepository.Find(client.ClientId, A._, A._)).Returns((OAuthClient)null); + A.CallTo(() => oAuthClientsRepository.Find(client.ClientId, A._, A._)).Returns(null); var tiersRepository = A.Fake(); A.CallTo(() => tiersRepository.ExistsWithId(client.DefaultTier, A._)).Returns(true); diff --git a/Modules/Devices/test/Devices.Application.Tests/Tests/Devices/Commands/DeleteDevice/HandlerTests.cs b/Modules/Devices/test/Devices.Application.Tests/Tests/Devices/Commands/DeleteDevice/HandlerTests.cs index dcd8f5f608..3c71bdde7d 100644 --- a/Modules/Devices/test/Devices.Application.Tests/Tests/Devices/Commands/DeleteDevice/HandlerTests.cs +++ b/Modules/Devices/test/Devices.Application.Tests/Tests/Devices/Commands/DeleteDevice/HandlerTests.cs @@ -2,7 +2,6 @@ using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.UserContext; using Backbone.Modules.Devices.Application.Devices.Commands.DeleteDevice; using Backbone.Modules.Devices.Application.Infrastructure.Persistence.Repository; -using Backbone.Modules.Devices.Domain.Entities; using Backbone.Modules.Devices.Domain.Entities.Identities; using Backbone.Tooling; using FakeItEasy; @@ -32,19 +31,20 @@ public async Task Deletes_unOnboarded_device_owned_by_identity() var handler = CreateHandler(mockIdentitiesRepository, fakeUserContext); - var deleteDeviceCommand = new DeleteDeviceCommand() + var deleteDeviceCommand = new DeleteDeviceCommand { DeviceId = unOnboardedDevice.Id }; var utcNow = DateTime.Parse("2000-01-01"); + SystemTime.Set(utcNow); // Act await handler.Handle(deleteDeviceCommand, CancellationToken.None); // Assert unOnboardedDevice.DeletedAt.Should().NotBeNull(); - unOnboardedDevice.DeletedAt.Should().BeAfter(utcNow); + unOnboardedDevice.DeletedAt.Should().Be(utcNow); unOnboardedDevice.DeletedByDevice.Should().Be(onboardedDevice.Id); A.CallTo(() => mockIdentitiesRepository.Update( @@ -65,7 +65,7 @@ public void Throws_if_given_device_id_does_not_exist() var handler = CreateHandler(mockIdentitiesRepository); - var deleteDeviceCommand = new DeleteDeviceCommand() + var deleteDeviceCommand = new DeleteDeviceCommand { DeviceId = nonExistentDeviceId }; @@ -89,7 +89,7 @@ private static Device CreateUnOnboardedDevice(Identity identity) return unOnboardedDevice; } - private static Device CreateOnboardedDevice(Identity identity = null) + private static Device CreateOnboardedDevice(Identity? identity = null) { identity ??= TestDataGenerator.CreateIdentity(); var onboardedDevice = new Device(identity); 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 534187ddb6..1df1e2f201 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 @@ -4,7 +4,6 @@ using Backbone.BuildingBlocks.Domain; using Backbone.Modules.Devices.Application.Identities.Commands.ApproveDeletionProcess; using Backbone.Modules.Devices.Application.Infrastructure.Persistence.Repository; -using Backbone.Modules.Devices.Application.IntegrationEvents.Outgoing; using Backbone.Modules.Devices.Domain.Aggregates.Tier; using Backbone.Modules.Devices.Domain.Entities.Identities; using Backbone.Tooling; @@ -68,7 +67,7 @@ public void Throws_when_given_identity_does_not_exist() var fakeUserContext = A.Fake(); A.CallTo(() => fakeUserContext.GetAddress()).Returns(address); - A.CallTo(() => fakeIdentitiesRepository.FindByAddress(address, A._, A._)).Returns(null); + A.CallTo(() => fakeIdentitiesRepository.FindByAddress(address, A._, A._)).Returns(null); var handler = CreateHandler(fakeIdentitiesRepository, fakeUserContext); @@ -133,7 +132,7 @@ public void Throws_when_deletion_process_is_not_waiting_for_approval() acting.Should().AwaitThrowAsync().Which.Code.Should().Be("error.platform.validation.device.noDeletionProcessWithRequiredStatusExists"); } - private static Handler CreateHandler(IIdentitiesRepository identitiesRepository, IUserContext userContext, IEventBus eventBus = null) + private static Handler CreateHandler(IIdentitiesRepository identitiesRepository, IUserContext userContext, IEventBus? eventBus = null) { eventBus ??= A.Fake(); return new Handler(identitiesRepository, userContext, eventBus); diff --git a/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/StartDeletionProcessAsOwner/HandlerTests.cs b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/StartDeletionProcessAsOwner/HandlerTests.cs index 64a264bd3b..6535bfbc5d 100644 --- a/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/StartDeletionProcessAsOwner/HandlerTests.cs +++ b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/StartDeletionProcessAsOwner/HandlerTests.cs @@ -2,7 +2,6 @@ using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.EventBus; using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.UserContext; using Backbone.DevelopmentKit.Identity.ValueObjects; -using Backbone.Modules.Devices.Application.Extensions; using Backbone.Modules.Devices.Application.Identities.Commands.StartDeletionProcessAsOwner; using Backbone.Modules.Devices.Application.Infrastructure.Persistence.Repository; using Backbone.Modules.Devices.Domain.Entities.Identities; @@ -64,7 +63,7 @@ public void Cannot_start_when_given_identity_does_not_exist() A._, A._, A._)) - .Returns(null); + .Returns(null); A.CallTo(() => fakeUserContext.GetAddressOrNull()).Returns(address); var handler = CreateHandler(fakeIdentitiesRepository, fakeUserContext); diff --git a/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/StartDeletionProcessAsSupport/HandlerTests.cs b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/StartDeletionProcessAsSupport/HandlerTests.cs index 9f97322140..6af5a04f10 100644 --- a/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/StartDeletionProcessAsSupport/HandlerTests.cs +++ b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/StartDeletionProcessAsSupport/HandlerTests.cs @@ -81,7 +81,7 @@ public void Cannot_start_when_given_identity_does_not_exist() address, A._, A._)) - .Returns(null); + .Returns(null); var handler = CreateHandler(fakeIdentitiesRepository); @@ -92,7 +92,7 @@ public void Cannot_start_when_given_identity_does_not_exist() acting.Should().AwaitThrowAsync().Which.Message.Should().Contain("Identity"); } - private static Handler CreateHandler(IIdentitiesRepository identitiesRepository, IEventBus eventBus = null) + private static Handler CreateHandler(IIdentitiesRepository identitiesRepository, IEventBus? eventBus = null) { eventBus ??= A.Fake(); return new Handler(identitiesRepository, eventBus); diff --git a/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/UpdateIdentity/HandlerTests.cs b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/UpdateIdentity/HandlerTests.cs index 6eb51967c3..6ef5744a71 100644 --- a/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/UpdateIdentity/HandlerTests.cs +++ b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/UpdateIdentity/HandlerTests.cs @@ -26,7 +26,7 @@ public async void Updates_the_identity_in_the_database() var oldTier = new Tier(TierName.Create("Old tier").Value); var newTier = new Tier(TierName.Create("New Tier").Value); - var identity = new Identity(CreateRandomDeviceId(), CreateRandomIdentityAddress(), new byte[] { 1, 1, 1, 1, 1 }, oldTier.Id, 1); + var identity = new Identity(CreateRandomDeviceId(), CreateRandomIdentityAddress(), [1, 1, 1, 1, 1], oldTier.Id, 1); A.CallTo(() => identitiesRepository.FindByAddress(identity.Address, A._, A._)).Returns(identity); A.CallTo(() => tiersRepository.FindByIds(A>._, A._)).Returns(new List() { oldTier, newTier }); @@ -55,7 +55,7 @@ public async void Publishes_TierOfIdentityChangedIntegrationEvent() var oldTier = new Tier(TierName.Create("Old tier").Value); var newTier = new Tier(TierName.Create("New Tier").Value); - var identity = new Identity(CreateRandomDeviceId(), CreateRandomIdentityAddress(), new byte[] { 1, 1, 1, 1, 1 }, oldTier.Id, 1); + var identity = new Identity(CreateRandomDeviceId(), CreateRandomIdentityAddress(), [1, 1, 1, 1, 1], oldTier.Id, 1); A.CallTo(() => identitiesRepository.FindByAddress(identity.Address, A._, A._)).Returns(identity); A.CallTo(() => tiersRepository.FindByIds(A>._, A._)).Returns(new List() { oldTier, newTier }); @@ -80,10 +80,10 @@ public void Fails_when_identity_does_not_exist() var oldTier = new Tier(TierName.Create("Tier name").Value); var newTier = new Tier(TierName.Create("Tier name").Value); - var identity = new Identity(CreateRandomDeviceId(), CreateRandomIdentityAddress(), new byte[] { 1, 1, 1, 1, 1 }, oldTier.Id, 1); + var identity = new Identity(CreateRandomDeviceId(), CreateRandomIdentityAddress(), [1, 1, 1, 1, 1], oldTier.Id, 1); A.CallTo(() => tiersRepository.FindByIds(A>._, A._)).Returns(new List() { oldTier, newTier }); - A.CallTo(() => identitiesRepository.FindByAddress(A._, A._, A._)).Returns((Identity)null); + A.CallTo(() => identitiesRepository.FindByAddress(A._, A._, A._)).Returns(null); var handler = CreateHandler(identitiesRepository, tiersRepository); var request = BuildRequest(newTier, identity); @@ -107,7 +107,7 @@ public void Fails_when_tier_does_not_exist() var oldTier = new Tier(TierName.Create("Tier name").Value); var newTier = new Tier(TierName.Create("Tier name").Value); - var identity = new Identity(CreateRandomDeviceId(), CreateRandomIdentityAddress(), new byte[] { 1, 1, 1, 1, 1 }, oldTier.Id, 1); + var identity = new Identity(CreateRandomDeviceId(), CreateRandomIdentityAddress(), [1, 1, 1, 1, 1], oldTier.Id, 1); A.CallTo(() => identitiesRepository.FindByAddress(identity.Address, A._, A._)).Returns(identity); A.CallTo(() => tiersRepository.FindByIds(A>._, A._)).Returns(new List() { oldTier }); @@ -134,7 +134,7 @@ public void Does_nothing_when_tiers_are_the_same() var oldAndNewTier = new Tier(TierName.Create("Tier name").Value); - var identity = new Identity(CreateRandomDeviceId(), CreateRandomIdentityAddress(), new byte[] { 1, 1, 1, 1, 1 }, oldAndNewTier.Id, 1); + var identity = new Identity(CreateRandomDeviceId(), CreateRandomIdentityAddress(), [1, 1, 1, 1, 1], oldAndNewTier.Id, 1); A.CallTo(() => identitiesRepository.FindByAddress(identity.Address, A._, A._)).Returns(identity); A.CallTo(() => tiersRepository.FindByIds(A>._, A._)).Returns(new List { oldAndNewTier }); diff --git a/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Queries/GetIdentity/FindByAddressStubRepository.cs b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Queries/GetIdentity/FindByAddressStubRepository.cs index a0481a6490..0e8fbd8e1e 100644 --- a/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Queries/GetIdentity/FindByAddressStubRepository.cs +++ b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Queries/GetIdentity/FindByAddressStubRepository.cs @@ -50,7 +50,7 @@ public Task> FindAllDevicesOfIdentity(IdentityAddress throw new NotImplementedException(); } - public Task GetDeviceById(DeviceId deviceId, CancellationToken cancellationToken, bool track = false) + public Task GetDeviceById(DeviceId deviceId, CancellationToken cancellationToken, bool track = false) { throw new NotImplementedException(); } @@ -65,8 +65,8 @@ public Task Update(Identity identity, CancellationToken cancellationToken) throw new NotImplementedException(); } - public Task FindByAddress(IdentityAddress address, CancellationToken cancellationToken, bool track = false) + public Task FindByAddress(IdentityAddress address, CancellationToken cancellationToken, bool track = false) { - return Task.FromResult(_identity); + return Task.FromResult((Identity?)_identity); } } diff --git a/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Queries/GetIdentity/HandlerTests.cs b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Queries/GetIdentity/HandlerTests.cs index 59ec2b1078..946a4f5706 100644 --- a/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Queries/GetIdentity/HandlerTests.cs +++ b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Queries/GetIdentity/HandlerTests.cs @@ -16,7 +16,7 @@ public class HandlerTests public async void Gets_identity_by_address() { // Arrange - var identity = new Identity(CreateRandomDeviceId(), CreateRandomIdentityAddress(), new byte[] { 1, 1, 1, 1, 1 }, TestDataGenerator.CreateRandomTierId(), 1); + var identity = new Identity(CreateRandomDeviceId(), CreateRandomIdentityAddress(), [1, 1, 1, 1, 1], TestDataGenerator.CreateRandomTierId(), 1); var handler = CreateHandler(new FindByAddressStubRepository(identity)); @@ -27,16 +27,16 @@ public async void Gets_identity_by_address() result.ClientId.Should().Be(identity.ClientId); result.Address.Should().Be(identity.Address); result.PublicKey.Should().BeEquivalentTo(identity.PublicKey); - result.TierId.Should().BeEquivalentTo(identity.TierId); + result.TierId.Should().BeEquivalentTo(identity.TierId!); result.IdentityVersion.Should().Be(1); } [Fact] - public async void Fails_when_no_identity_found() + public void Fails_when_no_identity_found() { // Arrange var identityRepository = A.Fake(); - A.CallTo(() => identityRepository.FindByAddress(A._, A._, A._)).Returns((Identity)null); + A.CallTo(() => identityRepository.FindByAddress(A._, A._, A._)).Returns(null); var handler = CreateHandler(identityRepository); diff --git a/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Queries/ListIdentities/FindAllStubRepository.cs b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Queries/ListIdentities/FindAllStubRepository.cs index d7bacd07aa..65076f2aec 100644 --- a/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Queries/ListIdentities/FindAllStubRepository.cs +++ b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Queries/ListIdentities/FindAllStubRepository.cs @@ -50,7 +50,7 @@ public Task> FindAllDevicesOfIdentity(IdentityAddress throw new NotImplementedException(); } - public Task GetDeviceById(DeviceId deviceId, CancellationToken cancellationToken, bool track = false) + public Task GetDeviceById(DeviceId deviceId, CancellationToken cancellationToken, bool track = false) { throw new NotImplementedException(); } @@ -65,7 +65,7 @@ public Task Update(Identity identity, CancellationToken cancellationToken) throw new NotImplementedException(); } - public Task FindByAddress(IdentityAddress address, CancellationToken cancellationToken, bool track = false) + public Task FindByAddress(IdentityAddress address, CancellationToken cancellationToken, bool track = false) { throw new NotImplementedException(); } diff --git a/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Queries/ListIdentities/HandlerTests.cs b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Queries/ListIdentities/HandlerTests.cs index 7eab6f59c8..a87a2dee5e 100644 --- a/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Queries/ListIdentities/HandlerTests.cs +++ b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Queries/ListIdentities/HandlerTests.cs @@ -36,19 +36,20 @@ public async void Returns_a_list_of_all_existing_identities() { // Arrange var request = new PaginationFilter(); - List identitiesList = new() - { - new(CreateRandomDeviceId(), - CreateRandomIdentityAddress(), - CreateRandomBytes(), - TestDataGenerator.CreateRandomTierId(), - 1), - new(CreateRandomDeviceId(), - CreateRandomIdentityAddress(), - CreateRandomBytes(), - TestDataGenerator.CreateRandomTierId(), - 1) - }; + List identitiesList = + [ + new Identity(CreateRandomDeviceId(), + CreateRandomIdentityAddress(), + CreateRandomBytes(), + TestDataGenerator.CreateRandomTierId(), + 1), + + new Identity(CreateRandomDeviceId(), + CreateRandomIdentityAddress(), + CreateRandomBytes(), + TestDataGenerator.CreateRandomTierId(), + 1) + ]; var handler = CreateHandler(new FindAllStubRepository(MakeDbPaginationResult(identitiesList))); @@ -67,10 +68,7 @@ public async void Returned_identities_have_all_properties_filled_as_expected() var expectedClientId = CreateRandomDeviceId(); var expectedAddress = CreateRandomIdentityAddress(); var expectedTierId = TestDataGenerator.CreateRandomTierId(); - List identitiesList = new() - { - new(expectedClientId, expectedAddress, Array.Empty(), expectedTierId, 1) - }; + List identitiesList = [new(expectedClientId, expectedAddress, [], expectedTierId, 1)]; var handler = CreateHandler(new FindAllStubRepository(MakeDbPaginationResult(identitiesList))); diff --git a/Modules/Devices/test/Devices.Application.Tests/Tests/Tiers/Commands/DeleteTier/HandlerTests.cs b/Modules/Devices/test/Devices.Application.Tests/Tests/Tiers/Commands/DeleteTier/HandlerTests.cs index be924f13a5..c24accdfae 100644 --- a/Modules/Devices/test/Devices.Application.Tests/Tests/Tiers/Commands/DeleteTier/HandlerTests.cs +++ b/Modules/Devices/test/Devices.Application.Tests/Tests/Tiers/Commands/DeleteTier/HandlerTests.cs @@ -9,6 +9,7 @@ using Xunit; namespace Backbone.Modules.Devices.Application.Tests.Tests.Tiers.Commands.DeleteTier; + public class HandlerTests { private readonly ITiersRepository _tiersRepository; @@ -28,7 +29,7 @@ public async Task Deletes_the_tier_from_the_database_and_publishes_TierDeletedIn // Arrange var tier = new Tier(TierName.Create("tier-name").Value); - A.CallTo(() => _tiersRepository.FindById(tier.Id, A._)).Returns(Task.FromResult(tier)); + A.CallTo(() => _tiersRepository.FindById(tier.Id, A._)).Returns(Task.FromResult(tier)); A.CallTo(() => _tiersRepository.GetNumberOfClientsWithDefaultTier(tier, A._)).Returns(Task.FromResult(0)); A.CallTo(() => _tiersRepository.GetNumberOfIdentitiesAssignedToTier(tier, A._)).Returns(Task.FromResult(0)); @@ -46,7 +47,7 @@ public async Task Cannot_delete_tier_if_CanBeDeleted_returns_an_error() // Arrange var tier = new Tier(TierName.Create("tier-name").Value); - A.CallTo(() => _tiersRepository.FindById(tier.Id, A._)).Returns(Task.FromResult(tier)); + A.CallTo(() => _tiersRepository.FindById(tier.Id, A._)).Returns(Task.FromResult(tier)); A.CallTo(() => _tiersRepository.GetNumberOfIdentitiesAssignedToTier(tier, A._)).Returns(1); A.CallTo(() => _tiersRepository.GetNumberOfIdentitiesAssignedToTier(tier, A._)).Returns(1); diff --git a/Modules/Devices/test/Devices.Application.Tests/Tests/Tiers/Queries/ListTiers/FindAllStubRepository.cs b/Modules/Devices/test/Devices.Application.Tests/Tests/Tiers/Queries/ListTiers/FindAllStubRepository.cs index 56b800fe39..2354f1d3d1 100644 --- a/Modules/Devices/test/Devices.Application.Tests/Tests/Tiers/Queries/ListTiers/FindAllStubRepository.cs +++ b/Modules/Devices/test/Devices.Application.Tests/Tests/Tiers/Queries/ListTiers/FindAllStubRepository.cs @@ -33,12 +33,12 @@ public Task> FindAll(PaginationFilter paginationFilter, return Task.FromResult(_tiers); } - public Task FindById(TierId tierId, CancellationToken cancellationToken) + public Task FindById(TierId tierId, CancellationToken cancellationToken) { throw new NotImplementedException(); } - public Task FindByName(TierName tierName, CancellationToken cancellationToken, bool track = false) + public Task FindByName(TierName tierName, CancellationToken cancellationToken, bool track = false) { throw new NotImplementedException(); } @@ -48,7 +48,7 @@ public Task> FindByIds(IEnumerable tiers, Cancellation throw new NotImplementedException(); } - public Task GetBasicTierAsync(CancellationToken cancellationToken) + public Task FindBasicTier(CancellationToken cancellationToken) { throw new NotImplementedException(); } diff --git a/Modules/Devices/test/Devices.Application.Tests/Tests/Tiers/Queries/ListTiers/HandlerTests.cs b/Modules/Devices/test/Devices.Application.Tests/Tests/Tiers/Queries/ListTiers/HandlerTests.cs index a82eee83a6..e58facc5d3 100644 --- a/Modules/Devices/test/Devices.Application.Tests/Tests/Tiers/Queries/ListTiers/HandlerTests.cs +++ b/Modules/Devices/test/Devices.Application.Tests/Tests/Tiers/Queries/ListTiers/HandlerTests.cs @@ -35,11 +35,11 @@ public async void Returns_a_list_of_all_existing_tiers() { // Arrange var request = new PaginationFilter(); - List tiersList = new() - { - new(TierName.Create("my-tier-name-1").Value), - new(TierName.Create("my-tier-name-2").Value) - }; + List tiersList = + [ + new Tier(TierName.Create("my-tier-name-1").Value), + new Tier(TierName.Create("my-tier-name-2").Value) + ]; var handler = CreateHandler(new FindAllStubRepository(MakeDbPaginationResult(tiersList))); @@ -56,10 +56,7 @@ public async void Returned_tiers_have_all_properties_filled_as_expected() // Arrange var request = new PaginationFilter(); var expectedName = TierName.Create("my-tier-name").Value; - List tiersList = new() - { - new(expectedName) - }; + List tiersList = [new Tier(expectedName)]; var handler = CreateHandler(new FindAllStubRepository(MakeDbPaginationResult(tiersList))); diff --git a/Modules/Devices/test/Devices.Domain.Tests/Domain/DeviceTests.cs b/Modules/Devices/test/Devices.Domain.Tests/Domain/DeviceTests.cs index 2964b2a2cc..3f98a2b6ff 100644 --- a/Modules/Devices/test/Devices.Domain.Tests/Domain/DeviceTests.cs +++ b/Modules/Devices/test/Devices.Domain.Tests/Domain/DeviceTests.cs @@ -1,5 +1,4 @@ using Backbone.BuildingBlocks.Domain; -using Backbone.Modules.Devices.Domain.Entities; using Backbone.Modules.Devices.Domain.Entities.Identities; using FluentAssertions; using Xunit; diff --git a/Modules/Devices/test/Devices.Domain.Tests/Identities/ApproveDeletionProcessTests.cs b/Modules/Devices/test/Devices.Domain.Tests/Identities/ApproveDeletionProcessTests.cs index a34b8cff91..d1e06ca99e 100644 --- a/Modules/Devices/test/Devices.Domain.Tests/Identities/ApproveDeletionProcessTests.cs +++ b/Modules/Devices/test/Devices.Domain.Tests/Identities/ApproveDeletionProcessTests.cs @@ -72,14 +72,14 @@ private static void AssertAuditLogEntryWasCreated(IdentityDeletionProcess deleti private static Identity CreateIdentity() { - var address = IdentityAddress.Create(Array.Empty(), "id1"); - return new Identity("", address, Array.Empty(), TierId.Generate(), 1); + var address = IdentityAddress.Create([], "id1"); + return new Identity("", address, [], TierId.Generate(), 1); } private static Identity CreateIdentityWithDeletionProcessWaitingForApproval() { var identity = CreateIdentity(); - Hasher.SetHasher(new DummyHasher(new byte[] { 1, 2, 3 })); + Hasher.SetHasher(new DummyHasher([1, 2, 3])); identity.StartDeletionProcessAsSupport(); return identity; } diff --git a/Modules/Devices/test/Devices.Domain.Tests/Identities/DeletionGracePeriodReminderTests.cs b/Modules/Devices/test/Devices.Domain.Tests/Identities/DeletionGracePeriodReminderTests.cs index b9e75d121d..e25817526c 100644 --- a/Modules/Devices/test/Devices.Domain.Tests/Identities/DeletionGracePeriodReminderTests.cs +++ b/Modules/Devices/test/Devices.Domain.Tests/Identities/DeletionGracePeriodReminderTests.cs @@ -121,7 +121,7 @@ private static void AssertAuditLogEntryWasCreated(IdentityDeletionProcess deleti private static Identity CreateIdentityWithApprovedDeletionProcess() { var identity = CreateIdentity(); - Hasher.SetHasher(new DummyHasher(new byte[] { 1, 2, 3 })); + Hasher.SetHasher(new DummyHasher([1, 2, 3])); identity.StartDeletionProcessAsOwner(new Device(identity).Id); return identity; diff --git a/Modules/Devices/test/Devices.Domain.Tests/Identities/DeletionProcessApprovalReminderTests.cs b/Modules/Devices/test/Devices.Domain.Tests/Identities/DeletionProcessApprovalReminderTests.cs index f2f0ecc79e..488a07c5c1 100644 --- a/Modules/Devices/test/Devices.Domain.Tests/Identities/DeletionProcessApprovalReminderTests.cs +++ b/Modules/Devices/test/Devices.Domain.Tests/Identities/DeletionProcessApprovalReminderTests.cs @@ -138,7 +138,7 @@ private static void AssertAuditLogEntryWasCreated(IdentityDeletionProcess deleti private static Identity CreateIdentityWithDeletionProcessWaitingForApproval() { var identity = CreateIdentity(); - Hasher.SetHasher(new DummyHasher(new byte[] { 1, 2, 3 })); + Hasher.SetHasher(new DummyHasher([1, 2, 3])); identity.StartDeletionProcessAsSupport(); 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 5e5ad1d674..25105f49c8 100644 --- a/Modules/Devices/test/Devices.Domain.Tests/Identities/StartDeletionProcessAsOwnerTests.cs +++ b/Modules/Devices/test/Devices.Domain.Tests/Identities/StartDeletionProcessAsOwnerTests.cs @@ -19,7 +19,7 @@ public void Start_deletion_process() var activeIdentity = CreateIdentity(); var activeDevice = DeviceId.Parse("DVC"); - Hasher.SetHasher(new DummyHasher(new byte[] { 1, 2, 3 })); + Hasher.SetHasher(new DummyHasher([1, 2, 3])); // Act var deletionProcess = activeIdentity.StartDeletionProcessAsOwner(activeDevice); diff --git a/Modules/Devices/test/Devices.Domain.Tests/Identities/StartDeletionProcessAsSupportTests.cs b/Modules/Devices/test/Devices.Domain.Tests/Identities/StartDeletionProcessAsSupportTests.cs index 373ebd526d..e02dba5e0b 100644 --- a/Modules/Devices/test/Devices.Domain.Tests/Identities/StartDeletionProcessAsSupportTests.cs +++ b/Modules/Devices/test/Devices.Domain.Tests/Identities/StartDeletionProcessAsSupportTests.cs @@ -18,7 +18,7 @@ public void Start_deletion_process() SystemTime.Set(DateTime.Parse("2000-01-01")); var activeIdentity = CreateIdentity(); - Hasher.SetHasher(new DummyHasher(new byte[] { 1, 2, 3 })); + Hasher.SetHasher(new DummyHasher([1, 2, 3])); // Act var deletionProcess = activeIdentity.StartDeletionProcessAsSupport(); diff --git a/Modules/Devices/test/Devices.Domain.Tests/Identities/TestDoubles/DummyHasher.cs b/Modules/Devices/test/Devices.Domain.Tests/Identities/TestDoubles/DummyHasher.cs index 699bafa79c..ea22abb1db 100644 --- a/Modules/Devices/test/Devices.Domain.Tests/Identities/TestDoubles/DummyHasher.cs +++ b/Modules/Devices/test/Devices.Domain.Tests/Identities/TestDoubles/DummyHasher.cs @@ -8,7 +8,7 @@ public class DummyHasher : IHasher public DummyHasher() { - _bytes = new byte[] { 1, 2, 3 }; + _bytes = [1, 2, 3]; } public DummyHasher(byte[] bytes) diff --git a/Modules/Devices/test/Devices.Domain.Tests/TestDataGenerator.cs b/Modules/Devices/test/Devices.Domain.Tests/TestDataGenerator.cs index 922a2e5c67..4526d3c541 100644 --- a/Modules/Devices/test/Devices.Domain.Tests/TestDataGenerator.cs +++ b/Modules/Devices/test/Devices.Domain.Tests/TestDataGenerator.cs @@ -23,7 +23,7 @@ public static Identity CreateIdentity() public static string GenerateString(int resultLength, char[]? chars = null) { - chars ??= new char[] { 'A', 'B', 'C' }; + chars ??= ['A', 'B', 'C']; Random random = new(); return new string(Enumerable.Repeat(chars, resultLength).Select(s => s[random.Next(s.Length)]).ToArray()); diff --git a/Modules/Devices/test/Devices.Domain.Tests/Tiers/TierTests.cs b/Modules/Devices/test/Devices.Domain.Tests/Tiers/TierTests.cs index 75935ab636..8940fa1492 100644 --- a/Modules/Devices/test/Devices.Domain.Tests/Tiers/TierTests.cs +++ b/Modules/Devices/test/Devices.Domain.Tests/Tiers/TierTests.cs @@ -52,7 +52,7 @@ public void Tier_with_related_identities_cannot_be_deleted() // Assert error!.Code.Should().Be("error.platform.validation.device.usedTierCannotBeDeleted"); - error!.Message.Should().Contain("Tier is assigned to one or more Identities"); + error.Message.Should().Contain("Tier is assigned to one or more Identities"); } [Fact] @@ -66,7 +66,7 @@ public void Tier_with_related_clients_cannot_be_deleted() // Assert error!.Code.Should().Be("error.platform.validation.device.usedTierCannotBeDeleted"); - error!.Message.Should().Contain("The Tier is used as the default Tier by one or more clients."); + error.Message.Should().Contain("The Tier is used as the default Tier by one or more clients."); } } diff --git a/Modules/Devices/test/Devices.Infrastructure.Tests/Tests/DirectPush/ApplePushNotificationServiceConnectorTests.cs b/Modules/Devices/test/Devices.Infrastructure.Tests/Tests/DirectPush/ApplePushNotificationServiceConnectorTests.cs index ada225b4e2..1ee2d68a48 100644 --- a/Modules/Devices/test/Devices.Infrastructure.Tests/Tests/DirectPush/ApplePushNotificationServiceConnectorTests.cs +++ b/Modules/Devices/test/Devices.Infrastructure.Tests/Tests/DirectPush/ApplePushNotificationServiceConnectorTests.cs @@ -42,7 +42,13 @@ private static ApplePushNotificationServiceConnector CreateConnector(HttpClient { Keys = new Dictionary() { - {"test-key-name", new DirectPnsCommunicationOptions.ApnsOptions.Key() {PrivateKey = "some-private-key"}} + {"test-key-name", new DirectPnsCommunicationOptions.ApnsOptions.Key + { + PrivateKey = "some-private-key", + TeamId = "some-team-id", + KeyId = "some-key-id" + } + } }, Bundles = new Dictionary() { diff --git a/Modules/Devices/test/Devices.Infrastructure.Tests/Tests/DirectPush/DirectPushServiceTests.cs b/Modules/Devices/test/Devices.Infrastructure.Tests/Tests/DirectPush/DirectPushServiceTests.cs index 7eb89ff870..04e017bd3f 100644 --- a/Modules/Devices/test/Devices.Infrastructure.Tests/Tests/DirectPush/DirectPushServiceTests.cs +++ b/Modules/Devices/test/Devices.Infrastructure.Tests/Tests/DirectPush/DirectPushServiceTests.cs @@ -23,7 +23,7 @@ public async void Update_of_a_registration_that_does_not_exist_yet() var mockPnsRegistrationsRepository = A.Fake(); A.CallTo(() => mockPnsRegistrationsRepository.FindByDeviceId(deviceId, A._, A._)) - .Returns((PnsRegistration)null).Once(); + .Returns(null).Once(); var directPushService = CreateDirectPushService(mockPnsRegistrationsRepository); @@ -98,7 +98,7 @@ public async void Trying_to_delete_non_existing_PnsRegistration_does_nothing() var mockPnsRegistrationsRepository = A.Fake(); A.CallTo(() => mockPnsRegistrationsRepository.FindByDeviceId(deviceId, A._, A._)) - .Returns((PnsRegistration)null); + .Returns(null); var directPushService = CreateDirectPushService(mockPnsRegistrationsRepository);