From f3cdb9890fab1acb05adf7af2b9d3f3bf96555ce Mon Sep 17 00:00:00 2001 From: Dhanalakshmi Gopalswamy <34273718+acn-dgopa@users.noreply.github.com> Date: Mon, 16 Dec 2024 09:56:59 +0100 Subject: [PATCH] System Register -Bug fixes (#944) * Fixed existing system register test that was not working and added null check for allowredirecturl * Helper method to validate for duplicate rights and unit tests for the helper method * Added more validation for the rights and unit tests for the same * Fixed failing tests --- .../Controllers/SystemRegisterController.cs | 54 ++- .../Helpers/AuthenticationHelper.cs | 44 +++ src/Core/Errors/ValidationErrors.cs | 16 +- .../SystemRegisterRepository.cs | 2 +- ...ltinn.Platform.Authentication.Tests.csproj | 15 + .../AuthenticationHelperTests.cs | 343 ++++++++++++++++++ .../SystemRegisterControllerTests.cs | 133 ++++++- .../SystemRegister/Json/SystemRegister01.json | 22 +- .../Json/SystemRegisterDuplicateResource.json | 45 +++ .../Json/SystemRegisterWithoutResource.json | 37 ++ .../Json/SystemRegisterWithoutRight.json | 23 +- .../Data/SystemRegister/Json/UpdateRight.json | 2 +- .../Json/UpdateRightDuplicate.json | 18 + .../Json/UpdateRightResourceIdExists.json | 10 + .../Json/UpdateRightResourceIdNotExist.json | 10 + 15 files changed, 756 insertions(+), 18 deletions(-) create mode 100644 test/Altinn.Platform.Authentication.Tests/AuthenticationHelperTests.cs create mode 100644 test/Altinn.Platform.Authentication.Tests/Data/SystemRegister/Json/SystemRegisterDuplicateResource.json create mode 100644 test/Altinn.Platform.Authentication.Tests/Data/SystemRegister/Json/SystemRegisterWithoutResource.json create mode 100644 test/Altinn.Platform.Authentication.Tests/Data/SystemRegister/Json/UpdateRightDuplicate.json create mode 100644 test/Altinn.Platform.Authentication.Tests/Data/SystemRegister/Json/UpdateRightResourceIdExists.json create mode 100644 test/Altinn.Platform.Authentication.Tests/Data/SystemRegister/Json/UpdateRightResourceIdNotExist.json diff --git a/src/Authentication/Controllers/SystemRegisterController.cs b/src/Authentication/Controllers/SystemRegisterController.cs index 35b689a1..fce70664 100644 --- a/src/Authentication/Controllers/SystemRegisterController.cs +++ b/src/Authentication/Controllers/SystemRegisterController.cs @@ -6,11 +6,11 @@ using Altinn.Authentication.Core.Problems; using Altinn.Authorization.ProblemDetails; using Altinn.Platform.Authentication.Core.Constants; +using Altinn.Platform.Authentication.Core.Errors; using Altinn.Platform.Authentication.Core.Models; using Altinn.Platform.Authentication.Core.SystemRegister.Models; using Altinn.Platform.Authentication.Helpers; using Altinn.Platform.Authentication.Services.Interfaces; -using Altinn.ResourceRegistry.Core.Errors; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; @@ -104,13 +104,29 @@ public async Task> GetRegisteredSystemInfo(string [HttpPut("vendor/{systemId}")] public async Task> UpdateWholeRegisteredSystem([FromBody] RegisteredSystem updateSystem, string systemId, CancellationToken cancellationToken = default) { + ValidationErrorBuilder errors = default; if (!AuthenticationHelper.HasWriteAccess(AuthenticationHelper.GetOrgNumber(updateSystem.Vendor.ID), User)) { return Forbid(); } + if (AuthenticationHelper.HasDuplicateRights(updateSystem.Rights)) + { + errors.Add(ValidationErrors.SystemRegister_ResourceId_Duplicates, [ + "/registersystemrequest/rights/resource" + ]); + } + List maskinPortenClients = await _systemRegisterService.GetMaskinportenClients(updateSystem.ClientId, cancellationToken); RegisteredSystem systemInfo = await _systemRegisterService.GetRegisteredSystemInfo(systemId); + + if (AuthenticationHelper.DoesResourceAlreadyExists(updateSystem.Rights, systemInfo.Rights)) + { + errors.Add(ValidationErrors.SystemRegister_ResourceId_AlreadyExists, [ + "/registersystemrequest/rights/resource" + ]); + } + foreach (string clientId in updateSystem.ClientId) { bool clientExistsForAnotherSystem = maskinPortenClients.FindAll(x => x.ClientId == clientId && x.SystemInternalId != systemInfo.InternalId).Count > 0; @@ -201,6 +217,13 @@ public async Task> CreateRegisteredSystem([FromBody] Register ]); } + if (AuthenticationHelper.HasDuplicateRights(registerNewSystem.Rights)) + { + errors.Add(ValidationErrors.SystemRegister_ResourceId_Duplicates, [ + "/registersystemrequest/rights/resource" + ]); + } + if (!AuthenticationHelper.IsValidRedirectUrl(registerNewSystem.AllowedRedirectUrls)) { errors.Add(ValidationErrors.SystemRegister_InValid_RedirectUrlFormat, [ @@ -245,14 +268,41 @@ public async Task> CreateRegisteredSystem([FromBody] Register /// true if changed [HttpPut("vendor/{systemId}/rights")] [Authorize(Policy = AuthzConstants.POLICY_SCOPE_SYSTEMREGISTER_WRITE)] - public async Task> UpdateRightsOnRegisteredSystem([FromBody] List rights, string systemId) + public async Task> UpdateRightsOnRegisteredSystem([FromBody] List rights, string systemId, CancellationToken cancellationToken = default) { + ValidationErrorBuilder errors = default; RegisteredSystem registerSystemResponse = await _systemRegisterService.GetRegisteredSystemInfo(systemId); if (!AuthenticationHelper.HasWriteAccess(registerSystemResponse.SystemVendorOrgNumber, User)) { return Forbid(); } + if (AuthenticationHelper.HasDuplicateRights(rights)) + { + errors.Add(ValidationErrors.SystemRegister_ResourceId_Duplicates, [ + "/registersystemrequest/rights/resource" + ]); + } + + if (AuthenticationHelper.DoesResourceAlreadyExists(rights, registerSystemResponse.Rights)) + { + errors.Add(ValidationErrors.SystemRegister_ResourceId_AlreadyExists, [ + "/registersystemrequest/rights/resource" + ]); + } + + if (!await _systemRegisterService.DoesResourceIdExists(rights, cancellationToken)) + { + errors.Add(ValidationErrors.SystemRegister_ResourceId_DoesNotExist, [ + "/registersystemrequest/rights/resource" + ]); + } + + if (errors.TryToActionResult(out var errorResult)) + { + return errorResult; + } + bool success = await _systemRegisterService.UpdateRightsForRegisteredSystem(rights, systemId); if (!success) { diff --git a/src/Authentication/Helpers/AuthenticationHelper.cs b/src/Authentication/Helpers/AuthenticationHelper.cs index 2fa7d184..4cddb100 100644 --- a/src/Authentication/Helpers/AuthenticationHelper.cs +++ b/src/Authentication/Helpers/AuthenticationHelper.cs @@ -383,5 +383,49 @@ public static int GetUserId(HttpContext context) return 0; } + + /// + /// Check for duplicates in the rights + /// + /// the resources that the system gives rights to + /// true if duplicate rights found + public static bool HasDuplicateRights(List rights) + { + var uniqueRights = new HashSet(); + + foreach (var right in rights) + { + var rightKey = $"{right.Action}:{string.Join(",", right.Resource.Select(r => $"{r.Id}:{r.Value}"))}"; + + if (!uniqueRights.Add(rightKey)) + { + return true; // Duplicate found + } + } + + return false; // No duplicates + } + + /// + /// Check for duplicates in the rights + /// + /// the resources that the system gives rights to + /// true if duplicate rights found + public static bool DoesResourceAlreadyExists(List rights, List existingRights) + { + var existingRightsSet = new HashSet(existingRights.Select(r => $"{r.Action}:{string.Join(",", r.Resource.Select(res => $"{res.Id}:{res.Value}"))}")); + + foreach (var right in rights) + { + var rightKey = $"{right.Action}:{string.Join(",", right.Resource.Select(r => $"{r.Id}:{r.Value}"))}"; + + if (existingRightsSet.Contains(rightKey)) + { + return true; // Duplicate found + } + } + + return false; // No duplicates + } } } diff --git a/src/Core/Errors/ValidationErrors.cs b/src/Core/Errors/ValidationErrors.cs index 39de6e15..126cca78 100644 --- a/src/Core/Errors/ValidationErrors.cs +++ b/src/Core/Errors/ValidationErrors.cs @@ -2,10 +2,10 @@ using Altinn.Authorization.ProblemDetails; -namespace Altinn.ResourceRegistry.Core.Errors; +namespace Altinn.Platform.Authentication.Core.Errors; /// -/// Validation errors for the Resource Registry. +/// Validation errors for the Authentication. /// public static class ValidationErrors { @@ -47,4 +47,16 @@ private static readonly ValidationErrorDescriptorFactory _factory /// public static ValidationErrorDescriptor SystemRegister_InValid_RedirectUrlFormat { get; } = _factory.Create(5, "One or more of the redirect urls format is not valid. The valid format is https://xxx.xx"); + + /// + /// Gets a validation error descriptor for duplicate resource(rights) id + /// + public static ValidationErrorDescriptor SystemRegister_ResourceId_Duplicates { get; } + = _factory.Create(6, "One or more duplicate rights found"); + + /// + /// Gets a validation error descriptor for already existing resource(rights) id + /// + public static ValidationErrorDescriptor SystemRegister_ResourceId_AlreadyExists { get; } + = _factory.Create(7, "One or all the resources in rights to be updated is already found in the system"); } diff --git a/src/Persistance/RepositoryImplementations/SystemRegisterRepository.cs b/src/Persistance/RepositoryImplementations/SystemRegisterRepository.cs index 69f80a26..2d781a06 100644 --- a/src/Persistance/RepositoryImplementations/SystemRegisterRepository.cs +++ b/src/Persistance/RepositoryImplementations/SystemRegisterRepository.cs @@ -364,7 +364,7 @@ private static ValueTask ConvertFromReaderToSystemRegister(Npg ClientId = clientIds, Rights = rights, IsVisible = reader.GetFieldValue("is_visible"), - AllowedRedirectUrls = reader.GetFieldValue>("allowedredirecturls").ConvertAll(delegate (string u) { return new Uri(u); }) + AllowedRedirectUrls = reader.IsDBNull("allowedredirecturls") ? null : reader.GetFieldValue>("allowedredirecturls")?.ConvertAll(delegate (string u) { return new Uri(u); }) }); } diff --git a/test/Altinn.Platform.Authentication.Tests/Altinn.Platform.Authentication.Tests.csproj b/test/Altinn.Platform.Authentication.Tests/Altinn.Platform.Authentication.Tests.csproj index a1a27cbb..a6b13f36 100644 --- a/test/Altinn.Platform.Authentication.Tests/Altinn.Platform.Authentication.Tests.csproj +++ b/test/Altinn.Platform.Authentication.Tests/Altinn.Platform.Authentication.Tests.csproj @@ -130,6 +130,12 @@ Always + + Always + + + Always + Always @@ -172,6 +178,15 @@ Always + + Always + + + Always + + + Always + Always diff --git a/test/Altinn.Platform.Authentication.Tests/AuthenticationHelperTests.cs b/test/Altinn.Platform.Authentication.Tests/AuthenticationHelperTests.cs new file mode 100644 index 00000000..534742f0 --- /dev/null +++ b/test/Altinn.Platform.Authentication.Tests/AuthenticationHelperTests.cs @@ -0,0 +1,343 @@ +using System.Collections.Generic; +using Altinn.Platform.Authentication.Core.Models; +using Altinn.Platform.Authentication.Helpers; +using Xunit; + +namespace Altinn.Platform.Authentication.Tests +{ + public class AuthenticationHelperTests + { + [Fact] + public void HasDuplicateRights_NoDuplicates_ReturnsFalse() + { + // Arrange + var rights = new List + { + new Right + { + Action = "Read", + Resource = new List + { + new AttributePair { Id = "urn:altinn:resource", Value = "value1" } + } + }, + new Right + { + Action = "Write", + Resource = new List + { + new AttributePair { Id = "urn:altinn:resource", Value = "value2" } + } + } + }; + + // Act + bool result = AuthenticationHelper.HasDuplicateRights(rights); + + // Assert + Assert.False(result); + } + + [Fact] + public void HasDuplicateRights_SameRights_DifferentActions_ReturnsFalse() + { + // Arrange + var rights = new List + { + new Right + { + Action = "Read", + Resource = new List + { + new AttributePair { Id = "urn:altinn:resource", Value = "value1" } + } + }, + new Right + { + Action = "Write", + Resource = new List + { + new AttributePair { Id = "urn:altinn:resource", Value = "value1" } + } + } + }; + + // Act + bool result = AuthenticationHelper.HasDuplicateRights(rights); + + // Assert + Assert.False(result); + } + + [Fact] + public void HasDuplicateRights_WithDuplicates_ReturnsTrue() + { + // Arrange + var rights = new List + { + new Right + { + Action = "Read", + Resource = new List + { + new AttributePair { Id = "urn:altinn:resource", Value = "value1" } + } + }, + new Right + { + Action = "Read", + Resource = new List + { + new AttributePair { Id = "urn:altinn:resource", Value = "value1" } + } + } + }; + + // Act + bool result = AuthenticationHelper.HasDuplicateRights(rights); + + // Assert + Assert.True(result); + } + + [Fact] + public void HasDuplicateRights_EmptyList_ReturnsFalse() + { + // Arrange + var rights = new List(); + + // Act + bool result = AuthenticationHelper.HasDuplicateRights(rights); + + // Assert + Assert.False(result); + } + + [Fact] + public void HasDuplicateRights_SingleRight_ReturnsFalse() + { + // Arrange + var rights = new List + { + new Right + { + Action = "Read", + Resource = new List + { + new AttributePair { Id = "urn:altinn:resource", Value = "value1" } + } + } + }; + + // Act + bool result = AuthenticationHelper.HasDuplicateRights(rights); + + // Assert + Assert.False(result); + } + + [Fact] + public void DoesResourceAlreadyExists_NoDuplicates_ReturnsFalse() + { + // Arrange + var newRights = new List + { + new Right + { + Action = "Read", + Resource = new List + { + new AttributePair { Id = "urn:altinn:resource", Value = "value1" } + } + } + }; + + var existingRights = new List + { + new Right + { + Action = "Write", + Resource = new List + { + new AttributePair { Id = "urn:altinn:resource", Value = "value2" } + } + } + }; + + // Act + bool result = AuthenticationHelper.DoesResourceAlreadyExists(newRights, existingRights); + + // Assert + Assert.False(result); + } + + [Fact] + public void DoesResourceAlreadyExists_NoDuplicates_DifferentActions_ReturnsFalse() + { + // Arrange + var newRights = new List + { + new Right + { + Action = "Read", + Resource = new List + { + new AttributePair { Id = "urn:altinn:resource", Value = "value1" } + } + } + }; + + var existingRights = new List + { + new Right + { + Action = "Write", + Resource = new List + { + new AttributePair { Id = "urn:altinn:resource", Value = "value1" } + } + } + }; + + // Act + bool result = AuthenticationHelper.DoesResourceAlreadyExists(newRights, existingRights); + + // Assert + Assert.False(result); + } + + [Fact] + public void DoesResourceAlreadyExists_NoDuplicates_DifferentResource_ReturnsFalse() + { + // Arrange + var newRights = new List + { + new Right + { + Action = "Read", + Resource = new List + { + new AttributePair { Id = "urn:altinn:resource", Value = "value1" } + } + } + }; + + var existingRights = new List + { + new Right + { + Action = "Read", + Resource = new List + { + new AttributePair { Id = "urn:altinn:resource", Value = "value2" } + } + } + }; + + // Act + bool result = AuthenticationHelper.DoesResourceAlreadyExists(newRights, existingRights); + + // Assert + Assert.False(result); + } + + [Fact] + public void DoesResourceAlreadyExists_WithDuplicates_ReturnsTrue() + { + // Arrange + var newRights = new List + { + new Right + { + Action = "Read", + Resource = new List + { + new AttributePair { Id = "urn:altinn:resource", Value = "value1" } + } + } + }; + + var existingRights = new List + { + new Right + { + Action = "Read", + Resource = new List + { + new AttributePair { Id = "urn:altinn:resource", Value = "value1" } + } + } + }; + + // Act + bool result = AuthenticationHelper.DoesResourceAlreadyExists(newRights, existingRights); + + // Assert + Assert.True(result); + } + + [Fact] + public void DoesResourceAlreadyExists_EmptyNewRights_ReturnsFalse() + { + // Arrange + var newRights = new List(); + + var existingRights = new List + { + new Right + { + Action = "Read", + Resource = new List + { + new AttributePair { Id = "urn:altinn:resource", Value = "value1" } + } + } + }; + + // Act + bool result = AuthenticationHelper.DoesResourceAlreadyExists(newRights, existingRights); + + // Assert + Assert.False(result); + } + + [Fact] + public void DoesResourceAlreadyExists_EmptyExistingRights_ReturnsFalse() + { + // Arrange + var newRights = new List + { + new Right + { + Action = "Read", + Resource = new List + { + new AttributePair { Id = "urn:altinn:resource", Value = "value1" } + } + } + }; + + var existingRights = new List(); + + // Act + bool result = AuthenticationHelper.DoesResourceAlreadyExists(newRights, existingRights); + + // Assert + Assert.False(result); + } + + [Fact] + public void DoesResourceAlreadyExists_BothListsEmpty_ReturnsFalse() + { + // Arrange + var newRights = new List(); + var existingRights = new List(); + + // Act + bool result = AuthenticationHelper.DoesResourceAlreadyExists(newRights, existingRights); + + // Assert + Assert.False(result); + } + } +} diff --git a/test/Altinn.Platform.Authentication.Tests/Controllers/SystemRegisterControllerTests.cs b/test/Altinn.Platform.Authentication.Tests/Controllers/SystemRegisterControllerTests.cs index 9af3e6bc..d22ca202 100644 --- a/test/Altinn.Platform.Authentication.Tests/Controllers/SystemRegisterControllerTests.cs +++ b/test/Altinn.Platform.Authentication.Tests/Controllers/SystemRegisterControllerTests.cs @@ -6,12 +6,14 @@ using System.Net.Http; using System.Net.Http.Headers; using System.Net.Http.Json; +using System.Security.Policy; using System.Text.Json; using System.Threading.Tasks; using Altinn.Authorization.ProblemDetails; using Altinn.Common.AccessToken.Services; using Altinn.Platform.Authentication.Clients.Interfaces; using Altinn.Platform.Authentication.Configuration; +using Altinn.Platform.Authentication.Core.Errors; using Altinn.Platform.Authentication.Core.Models; using Altinn.Platform.Authentication.Core.SystemRegister.Models; using Altinn.Platform.Authentication.Integration.ResourceRegister; @@ -21,13 +23,13 @@ using Altinn.Platform.Authentication.Tests.Mocks; using Altinn.Platform.Authentication.Tests.RepositoryDataAccess; using Altinn.Platform.Authentication.Tests.Utils; -using Altinn.ResourceRegistry.Core.Errors; using AltinnCore.Authentication.JwtCookie; using App.IntegrationTests.Utils; using Azure; using ICSharpCode.SharpZipLib.Zip; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc; +using Microsoft.Azure.KeyVault.Models; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; @@ -163,6 +165,22 @@ public async Task SystemRegister_Create_InvalidResourceId_BadRequest() Assert.Equal("One or all the resources in rights is not found in altinn's resource register", error.Detail); } + [Fact] + public async Task SystemRegister_Create_DuplicateResource_BadRequest() + { + // Arrange + string dataFileName = "Data/SystemRegister/Json/SystemRegisterDuplicateResource.json"; + + HttpResponseMessage response = await CreateSystemRegister(dataFileName); + Assert.Equal(System.Net.HttpStatusCode.BadRequest, response.StatusCode); + AltinnValidationProblemDetails problemDetails = await response.Content.ReadFromJsonAsync(); + Assert.NotNull(problemDetails); + Assert.Single(problemDetails.Errors); + AltinnValidationError error = problemDetails.Errors.Single(e => e.ErrorCode == ValidationErrors.SystemRegister_ResourceId_Duplicates.ErrorCode); + Assert.Equal("/registersystemrequest/rights/resource", error.Paths.Single(p => p.Equals("/registersystemrequest/rights/resource"))); + Assert.Equal("One or more duplicate rights found", error.Detail); + } + [Fact] public async Task SystemRegister_Create_InvalidRedirectUrl_BadRequest() { @@ -197,7 +215,7 @@ public async Task SystemRegister_Create_InvalidOrgIdentifier_BadRequest() [Fact] public async Task SystemRegister_Update_Success() { - string dataFileName = "Data/SystemRegister/Json/SystemRegister.json"; + string dataFileName = "Data/SystemRegister/Json/SystemRegisterWithoutRight.json"; HttpResponseMessage response = await CreateSystemRegister(dataFileName); if (response.IsSuccessStatusCode) @@ -254,6 +272,113 @@ public async Task SystemRegister_Update_BadRequest() } } + [Fact] + public async Task SystemRegister_Update_DuplicateResource_BadRequest() + { + string dataFileName = "Data/SystemRegister/Json/SystemRegister.json"; + HttpResponseMessage response = await CreateSystemRegister(dataFileName); + + if (response.IsSuccessStatusCode) + { + HttpClient client = CreateClient(); + string[] prefixes = { "altinn", "digdir" }; + string token = PrincipalUtil.GetOrgToken("digdir", "991825827", "altinn:authentication/systemregister.admin", prefixes); + client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token); + JsonSerializerOptions options = new JsonSerializerOptions() + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase + }; + + // Arrange + Stream dataStream = File.OpenRead("Data/SystemRegister/Json/UpdateRightDuplicate.json"); + StreamContent content = new StreamContent(dataStream); + content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); + + string systemID = "991825827_the_matrix"; + HttpRequestMessage request = new(HttpMethod.Put, $"/authentication/api/v1/systemregister/vendor/{systemID}/rights"); + request.Content = content; + HttpResponseMessage updateResponse = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead); + Assert.Equal(System.Net.HttpStatusCode.BadRequest, updateResponse.StatusCode); + AltinnValidationProblemDetails problemDetails = await updateResponse.Content.ReadFromJsonAsync(); + Assert.NotNull(problemDetails); + AltinnValidationError error = problemDetails.Errors.Single(e => e.ErrorCode == ValidationErrors.SystemRegister_ResourceId_Duplicates.ErrorCode); + Assert.Equal("/registersystemrequest/rights/resource", error.Paths.Single(p => p.Equals("/registersystemrequest/rights/resource"))); + Assert.Equal("One or more duplicate rights found", error.Detail); + } + } + + [Fact] + public async Task SystemRegister_Update_ResourceIdExists_BadRequest() + { + string dataFileName = "Data/SystemRegister/Json/SystemRegister.json"; + HttpResponseMessage response = await CreateSystemRegister(dataFileName); + + if (response.IsSuccessStatusCode) + { + HttpClient client = CreateClient(); + string[] prefixes = { "altinn", "digdir" }; + string token = PrincipalUtil.GetOrgToken("digdir", "991825827", "altinn:authentication/systemregister.admin", prefixes); + client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token); + JsonSerializerOptions options = new JsonSerializerOptions() + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase + }; + + // Arrange + Stream dataStream = File.OpenRead("Data/SystemRegister/Json/UpdateRightResourceIdExists.json"); + StreamContent content = new StreamContent(dataStream); + content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); + + string systemID = "991825827_the_matrix"; + HttpRequestMessage request = new(HttpMethod.Put, $"/authentication/api/v1/systemregister/vendor/{systemID}/rights"); + request.Content = content; + HttpResponseMessage updateResponse = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead); + Assert.Equal(System.Net.HttpStatusCode.BadRequest, updateResponse.StatusCode); + AltinnValidationProblemDetails problemDetails = await updateResponse.Content.ReadFromJsonAsync(); + Assert.NotNull(problemDetails); + Assert.Single(problemDetails.Errors); + AltinnValidationError error = problemDetails.Errors.Single(e => e.ErrorCode == ValidationErrors.SystemRegister_ResourceId_AlreadyExists.ErrorCode); + Assert.Equal("/registersystemrequest/rights/resource", error.Paths.Single(p => p.Equals("/registersystemrequest/rights/resource"))); + Assert.Equal("One or all the resources in rights to be updated is already found in the system", error.Detail); + } + } + + [Fact] + public async Task SystemRegister_Update_ResourceIdDoesNotExist_BadRequest() + { + string dataFileName = "Data/SystemRegister/Json/SystemRegister.json"; + HttpResponseMessage response = await CreateSystemRegister(dataFileName); + + if (response.IsSuccessStatusCode) + { + HttpClient client = CreateClient(); + string[] prefixes = { "altinn", "digdir" }; + string token = PrincipalUtil.GetOrgToken("digdir", "991825827", "altinn:authentication/systemregister.admin", prefixes); + client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token); + JsonSerializerOptions options = new JsonSerializerOptions() + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase + }; + + // Arrange + Stream dataStream = File.OpenRead("Data/SystemRegister/Json/UpdateRightResourceIdNotExist.json"); + StreamContent content = new StreamContent(dataStream); + content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); + + string systemID = "991825827_the_matrix"; + HttpRequestMessage request = new(HttpMethod.Put, $"/authentication/api/v1/systemregister/vendor/{systemID}/rights"); + request.Content = content; + HttpResponseMessage updateResponse = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead); + Assert.Equal(System.Net.HttpStatusCode.BadRequest, updateResponse.StatusCode); + AltinnValidationProblemDetails problemDetails = await updateResponse.Content.ReadFromJsonAsync(); + Assert.NotNull(problemDetails); + Assert.Single(problemDetails.Errors); + AltinnValidationError error = problemDetails.Errors.Single(e => e.ErrorCode == ValidationErrors.SystemRegister_ResourceId_DoesNotExist.ErrorCode); + Assert.Equal("/registersystemrequest/rights/resource", error.Paths.Single(p => p.Equals("/registersystemrequest/rights/resource"))); + Assert.Equal("One or all the resources in rights is not found in altinn's resource register", error.Detail); + } + } + [Fact] public async Task SystemRegister_Get_ListofAll() { @@ -269,7 +394,7 @@ public async Task SystemRegister_Get_ListofAll() HttpRequestMessage request = new(HttpMethod.Get, $"/authentication/api/v1/systemregister"); HttpResponseMessage getAllResponse = await client.SendAsync(request, HttpCompletionOption.ResponseContentRead); - List list = JsonSerializer.Deserialize>(await getAllResponse.Content.ReadAsStringAsync(), _options); + List list = JsonSerializer.Deserialize>(await getAllResponse.Content.ReadAsStringAsync(), _options); Assert.True(list.Count > 1); } } @@ -395,7 +520,7 @@ public async Task SystemRegister_Get_ProductDefaultRights_NoRights() HttpClient client = CreateClient(); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", TestTokenUtil.GetTestToken()); - HttpRequestMessage request = new(HttpMethod.Get, $"/authentication/api/v1/systemregister/vendor/{name}/rights"); + HttpRequestMessage request = new(HttpMethod.Get, $"/authentication/api/v1/systemregister/{name}/rights"); HttpResponseMessage rightsResponse = await client.SendAsync(request, HttpCompletionOption.ResponseContentRead); Assert.Equal(HttpStatusCode.NotFound, rightsResponse.StatusCode); } diff --git a/test/Altinn.Platform.Authentication.Tests/Data/SystemRegister/Json/SystemRegister01.json b/test/Altinn.Platform.Authentication.Tests/Data/SystemRegister/Json/SystemRegister01.json index 3ba997ff..73292a88 100644 --- a/test/Altinn.Platform.Authentication.Tests/Data/SystemRegister/Json/SystemRegister01.json +++ b/test/Altinn.Platform.Authentication.Tests/Data/SystemRegister/Json/SystemRegister01.json @@ -1,20 +1,32 @@ { - "systemId": "991825827_the_matrix_01", - "systemVendorOrgNumber": "991825827", - "systemName": "The Matrix 001", + "id": "991825827_the_matrix_01", + "vendor": { + "authority": "iso6523-actorid-upis", + "ID": "0192:991825827" + }, + "name": { + "nb": "The Matrix", + "en": "The Matrix", + "nn": "The Matrix" + }, + "description": { + "nb": "Test system", + "en": "Test system", + "nn": "Test system" + }, "rights": [ { "resource": [ { "id": "urn:altinn:resource", - "value": "ske_krav-og-betaling" + "value": "ske-krav-og-betalinger" } ] } ], "softDeleted": false, "clientId": [ - "32ef65ac-6e62-498d-880f-76c85c2052ae" + "32ef65ac-6e62-498d-880f-76c85c2052af" ], "isVisible": true } \ No newline at end of file diff --git a/test/Altinn.Platform.Authentication.Tests/Data/SystemRegister/Json/SystemRegisterDuplicateResource.json b/test/Altinn.Platform.Authentication.Tests/Data/SystemRegister/Json/SystemRegisterDuplicateResource.json new file mode 100644 index 00000000..41b9d575 --- /dev/null +++ b/test/Altinn.Platform.Authentication.Tests/Data/SystemRegister/Json/SystemRegisterDuplicateResource.json @@ -0,0 +1,45 @@ +{ + "id": "991825827_the_matrix", + "vendor": { + "authority": "iso6523-actorid-upis", + "ID": "0192:991825827" + }, + "name": { + "nb": "The Matrix", + "en": "The Matrix", + "nn": "The Matrix" + }, + "description": { + "nb": "Test system", + "en": "Test system", + "nn": "Test system" + }, + "rights": [ + { + "resource": [ + { + "id": "urn:altinn:resource", + "value": "ske-krav-og-betalinger" + } + ] + }, + { + "resource": [ + { + "id": "urn:altinn:resource", + "value": "ske-krav-og-betalinger" + } + ] + } + ], + "softDeleted": false, + "clientId": [ + "32ef65ac-6e62-498d-880f-76c85c2052ae" + ], + "allowedredirecturls": [ + "https://vg.no", + "https://nrk.no", + "https://altinn.no" + ], + "isVisible": true +} \ No newline at end of file diff --git a/test/Altinn.Platform.Authentication.Tests/Data/SystemRegister/Json/SystemRegisterWithoutResource.json b/test/Altinn.Platform.Authentication.Tests/Data/SystemRegister/Json/SystemRegisterWithoutResource.json new file mode 100644 index 00000000..17a1b588 --- /dev/null +++ b/test/Altinn.Platform.Authentication.Tests/Data/SystemRegister/Json/SystemRegisterWithoutResource.json @@ -0,0 +1,37 @@ +{ + "id": "991825827_the_matrix", + "vendor": { + "authority": "iso6523-actorid-upis", + "ID": "0192:991825827" + }, + "name": { + "nb": "The Matrix", + "en": "The Matrix", + "nn": "The Matrix" + }, + "description": { + "nb": "Test system", + "en": "Test system", + "nn": "Test system" + }, + "rights": [ + { + "resource": [ + { + "id": "urn:altinn:resource", + "value": "ske-krav-og-betalinger" + } + ] + } + ], + "softDeleted": false, + "clientId": [ + "32ef65ac-6e62-498d-880f-76c85c2052ae" + ], + "allowedredirecturls": [ + "https://vg.no", + "https://nrk.no", + "https://altinn.no" + ], + "isVisible": true +} \ No newline at end of file diff --git a/test/Altinn.Platform.Authentication.Tests/Data/SystemRegister/Json/SystemRegisterWithoutRight.json b/test/Altinn.Platform.Authentication.Tests/Data/SystemRegister/Json/SystemRegisterWithoutRight.json index 869a3d8b..1221695e 100644 --- a/test/Altinn.Platform.Authentication.Tests/Data/SystemRegister/Json/SystemRegisterWithoutRight.json +++ b/test/Altinn.Platform.Authentication.Tests/Data/SystemRegister/Json/SystemRegisterWithoutRight.json @@ -1,10 +1,27 @@ { - "systemId": "991825827_the_matrix", - "systemVendorOrgNumber": "991825827", - "systemName": "The Matrix", + "id": "991825827_the_matrix", + "vendor": { + "authority": "iso6523-actorid-upis", + "ID": "0192:991825827" + }, + "name": { + "nb": "The Matrix", + "en": "The Matrix", + "nn": "The Matrix" + }, + "description": { + "nb": "Test system", + "en": "Test system", + "nn": "Test system" + }, "softDeleted": false, "clientId": [ "32ef65ac-6e62-498d-880f-76c85c2052ae" ], + "allowedredirecturls": [ + "https://vg.no", + "https://nrk.no", + "https://altinn.no" + ], "isVisible": true } \ No newline at end of file diff --git a/test/Altinn.Platform.Authentication.Tests/Data/SystemRegister/Json/UpdateRight.json b/test/Altinn.Platform.Authentication.Tests/Data/SystemRegister/Json/UpdateRight.json index 1d25c665..d8ef6655 100644 --- a/test/Altinn.Platform.Authentication.Tests/Data/SystemRegister/Json/UpdateRight.json +++ b/test/Altinn.Platform.Authentication.Tests/Data/SystemRegister/Json/UpdateRight.json @@ -3,7 +3,7 @@ "resource": [ { "id": "urn:altinn:resource", - "value": "ske_kravogbetaling" + "value": "ske-krav-og-betalinger" } ] } diff --git a/test/Altinn.Platform.Authentication.Tests/Data/SystemRegister/Json/UpdateRightDuplicate.json b/test/Altinn.Platform.Authentication.Tests/Data/SystemRegister/Json/UpdateRightDuplicate.json new file mode 100644 index 00000000..dc923495 --- /dev/null +++ b/test/Altinn.Platform.Authentication.Tests/Data/SystemRegister/Json/UpdateRightDuplicate.json @@ -0,0 +1,18 @@ +[ + { + "resource": [ + { + "id": "urn:altinn:resource", + "value": "ske-krav-og-betalinger" + } + ] + }, + { + "resource": [ + { + "id": "urn:altinn:resource", + "value": "ske-krav-og-betalinger" + } + ] + } +] \ No newline at end of file diff --git a/test/Altinn.Platform.Authentication.Tests/Data/SystemRegister/Json/UpdateRightResourceIdExists.json b/test/Altinn.Platform.Authentication.Tests/Data/SystemRegister/Json/UpdateRightResourceIdExists.json new file mode 100644 index 00000000..d8ef6655 --- /dev/null +++ b/test/Altinn.Platform.Authentication.Tests/Data/SystemRegister/Json/UpdateRightResourceIdExists.json @@ -0,0 +1,10 @@ +[ + { + "resource": [ + { + "id": "urn:altinn:resource", + "value": "ske-krav-og-betalinger" + } + ] + } +] \ No newline at end of file diff --git a/test/Altinn.Platform.Authentication.Tests/Data/SystemRegister/Json/UpdateRightResourceIdNotExist.json b/test/Altinn.Platform.Authentication.Tests/Data/SystemRegister/Json/UpdateRightResourceIdNotExist.json new file mode 100644 index 00000000..6ecb66cb --- /dev/null +++ b/test/Altinn.Platform.Authentication.Tests/Data/SystemRegister/Json/UpdateRightResourceIdNotExist.json @@ -0,0 +1,10 @@ +[ + { + "resource": [ + { + "id": "urn:altinn:resource", + "value": "ske_krav-og-betalinger" + } + ] + } +] \ No newline at end of file