From 49948b246247d7798496ddb0225620c809aee4f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Dybvik=20Langfors?= Date: Fri, 18 Oct 2024 17:45:53 +0200 Subject: [PATCH 1/3] fix: Return distinct actions in GetAlinnActions (#1298) ## Description GetAltinnActions now removes duplicate action/resource tuples, which results in simpler XACML requests and dialog tokens. ## Related Issue(s) - N/A ## Verification - [x] **Your** code builds clean without any errors or warnings - [x] Manual testing done (required) - [x] Relevant automated test added (if you find this hard, leave it and we'll help out) ## Summary by CodeRabbit - **New Features** - Improved handling of duplicate actions in the Altinn authorization process, ensuring a cleaner and more accurate list of actions. - **Bug Fixes** - Enhanced test coverage for action retrieval, ensuring the correct actions and attributes are validated. --- .../Authorization/DialogEntityExtensions.cs | 2 ++ .../DialogEntityExtensionsTests.cs | 27 +++++++++++++++---- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/Digdir.Domain.Dialogporten.Infrastructure/Altinn/Authorization/DialogEntityExtensions.cs b/src/Digdir.Domain.Dialogporten.Infrastructure/Altinn/Authorization/DialogEntityExtensions.cs index 109719191..0da3a792b 100644 --- a/src/Digdir.Domain.Dialogporten.Infrastructure/Altinn/Authorization/DialogEntityExtensions.cs +++ b/src/Digdir.Domain.Dialogporten.Infrastructure/Altinn/Authorization/DialogEntityExtensions.cs @@ -20,6 +20,8 @@ public static List GetAltinnActions(this DialogEntity dialogEntity .Select(x => new AltinnAction(GetReadActionForAuthorizationAttribute(x.AuthorizationAttribute!), x.AuthorizationAttribute))) // We always need to check if the user can read the main resource .Append(new AltinnAction(Constants.ReadAction, Constants.MainResource)) + .GroupBy(x => new { x.Name, x.AuthorizationAttribute }) + .Select(g => g.First()) // Remove duplicates by grouping .ToList(); } diff --git a/tests/Digdir.Domain.Dialogporten.Infrastructure.Unit.Tests/DialogEntityExtensionsTests.cs b/tests/Digdir.Domain.Dialogporten.Infrastructure.Unit.Tests/DialogEntityExtensionsTests.cs index ea7d4781d..a7b3b460d 100644 --- a/tests/Digdir.Domain.Dialogporten.Infrastructure.Unit.Tests/DialogEntityExtensionsTests.cs +++ b/tests/Digdir.Domain.Dialogporten.Infrastructure.Unit.Tests/DialogEntityExtensionsTests.cs @@ -1,5 +1,6 @@ using Digdir.Domain.Dialogporten.Application.Common.Authorization; using Digdir.Domain.Dialogporten.Domain.Dialogs.Entities; +using Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Actions; using Digdir.Domain.Dialogporten.Infrastructure.Altinn.Authorization; using Xunit; @@ -13,11 +14,23 @@ public void GetAltinnActionsShouldReturnCorrectActionsForTransmissionAuthorizati // Arrange var dialogEntity = new DialogEntity { - ApiActions = [], - GuiActions = [], + ApiActions = [ + new DialogApiAction { Action = "read" }, + new DialogApiAction { Action = "read" }, + new DialogApiAction { Action = "read", AuthorizationAttribute = "foo" }, + new DialogApiAction { Action = "transmissionread", AuthorizationAttribute = "bar" }, + new DialogApiAction { Action = "apiread" }, + ], + GuiActions = [ + new DialogGuiAction { Action = "read" }, + new DialogGuiAction { Action = "read" }, + new DialogGuiAction { Action = "read", AuthorizationAttribute = "foo" }, + new DialogGuiAction { Action = "transmissionread", AuthorizationAttribute = "bar" }, + new DialogGuiAction { Action = "guiread" }, + ], Transmissions = [ - new() { AuthorizationAttribute = "foo" }, + new() { AuthorizationAttribute = "bar" }, new() { AuthorizationAttribute = "urn:altinn:subresource:bar" }, new() { AuthorizationAttribute = "urn:altinn:task:Task_1" }, new() { AuthorizationAttribute = "urn:altinn:resource:some-service:element1" }, @@ -30,8 +43,12 @@ public void GetAltinnActionsShouldReturnCorrectActionsForTransmissionAuthorizati // Assert Assert.NotNull(actions); - Assert.NotEmpty(actions); - Assert.Contains(actions, a => a is { Name: Constants.TransmissionReadAction, AuthorizationAttribute: "foo" }); + Assert.Equal(9, actions.Count); + Assert.Contains(actions, a => a is { Name: Constants.ReadAction, AuthorizationAttribute: Constants.MainResource }); + Assert.Contains(actions, a => a is { Name: Constants.ReadAction, AuthorizationAttribute: "foo" }); + Assert.Contains(actions, a => a is { Name: Constants.TransmissionReadAction, AuthorizationAttribute: "bar" }); + Assert.Contains(actions, a => a is { Name: "apiread", AuthorizationAttribute: Constants.MainResource }); + Assert.Contains(actions, a => a is { Name: "guiread", AuthorizationAttribute: Constants.MainResource }); Assert.Contains(actions, a => a is { Name: Constants.TransmissionReadAction, AuthorizationAttribute: "urn:altinn:subresource:bar" }); Assert.Contains(actions, a => a is { Name: Constants.TransmissionReadAction, AuthorizationAttribute: "urn:altinn:task:Task_1" }); Assert.Contains(actions, a => a is { Name: Constants.ReadAction, AuthorizationAttribute: "urn:altinn:resource:some-service:element1" }); From 4fb42bbe0af6a9023369f0676be6f38e9fd7c780 Mon Sep 17 00:00:00 2001 From: Are Almaas Date: Fri, 18 Oct 2024 17:58:01 +0200 Subject: [PATCH 2/3] fix(infrastructure): use correct networking for servicebus (#1320) ## Description Service bus resolved the network in the same way as for Redis, so refactoring to do the same. Creating a new dnszone with the proper naming + a dnsgroup ## Related Issue(s) - #{issue number} ## Verification - [ ] **Your** code builds clean without any errors or warnings - [ ] Manual testing done (required) - [ ] Relevant automated test added (if you find this hard, leave it and we'll help out) ## Documentation - [ ] Documentation is updated (either in `docs`-directory, Altinnpedia or a separate linked PR in [altinn-studio-docs.](https://github.com/Altinn/altinn-studio-docs), if applicable) ## Summary by CodeRabbit - **New Features** - Introduced a private endpoint for enhanced secure connectivity to the Service Bus namespace. - Added a new module for managing a private DNS zone group. - **Improvements** - Updated DNS zone configurations for better resolution and security. - Enhanced naming conventions for resources to ensure compliance with character limits. --- .azure/modules/serviceBus/main.bicep | 54 +++++++++++++--------------- 1 file changed, 25 insertions(+), 29 deletions(-) diff --git a/.azure/modules/serviceBus/main.bicep b/.azure/modules/serviceBus/main.bicep index 74607b134..7fc130fa8 100644 --- a/.azure/modules/serviceBus/main.bicep +++ b/.azure/modules/serviceBus/main.bicep @@ -45,55 +45,51 @@ resource serviceBusNamespace 'Microsoft.ServiceBus/namespaces@2023-01-01-preview tags: tags } -resource privateEndpoint 'Microsoft.Network/privateEndpoints@2023-11-01' = { - name: '${serviceBusName}-pe' +// private endpoint name max characters is 80 +var serviceBusPrivateEndpointName = uniqueResourceName('${namePrefix}-service-bus-pe', 80) + +resource serviceBusPrivateEndpoint 'Microsoft.Network/privateEndpoints@2023-11-01' = { + name: serviceBusPrivateEndpointName location: location properties: { - subnet: { - id: subnetId - } - ipConfigurations: [ - { - name: 'default' - properties: { - groupId: 'namespace' - memberName: 'namespace' - // must be in the range of the subnet - privateIPAddress: '10.0.4.4' - } - } - ] privateLinkServiceConnections: [ { - name: '${namePrefix}-plsc' + name: serviceBusPrivateEndpointName properties: { privateLinkServiceId: serviceBusNamespace.id groupIds: [ 'namespace' ] - requestMessage: 'Connection to the Service Bus namespace ${serviceBusName} for Dialogporten' } } ] + customNetworkInterfaceName: uniqueResourceName('${namePrefix}-service-bus-pe-nic', 80) + subnet: { + id: subnetId + } } tags: tags } -var serviceBusDomainName = '${serviceBusName}.servicebus.windows.net' - module privateDnsZone '../privateDnsZone/main.bicep' = { - name: 'serviceBusPrivateDnsZone' + name: '${namePrefix}-service-bus-pdz' params: { namePrefix: namePrefix - defaultDomain: serviceBusDomainName + defaultDomain: 'privatelink.servicebus.windows.net' vnetId: vnetId - aRecords: [ - { - name: 'default' - ttl: 300 - ip: privateEndpoint.properties.ipConfigurations[0].properties.privateIPAddress - } - ] tags: tags } } + +module privateDnsZoneGroup '../privateDnsZoneGroup/main.bicep' = { + name: '${namePrefix}-service-bus-privateDnsZoneGroup' + dependsOn: [ + privateDnsZone + ] + params: { + name: 'default' + dnsZoneGroupName: 'privatelink-servicebus-windows-net' + dnsZoneId: privateDnsZone.outputs.id + privateEndpointName: serviceBusPrivateEndpoint.name + } +} From 71698bfec2c08cf7dcb667cf78264e8654dd367c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 21 Oct 2024 12:50:08 +0200 Subject: [PATCH 3/3] chore(deps): update dotnet monorepo (#1322) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [mcr.microsoft.com/dotnet/aspnet](https://redirect.github.com/dotnet/aspnetcore) | stage | digest | `b3cdb99` -> `3ded9cc` | | [mcr.microsoft.com/dotnet/sdk](https://redirect.github.com/dotnet/sdk) | final | digest | `ff705b9` -> `cab0284` | --- ### Configuration 📅 **Schedule**: Branch creation - "before 7am on Sunday,before 7am on Wednesday" (UTC), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://redirect.github.com/renovatebot/renovate/discussions) if that's undesired. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/digdir/dialogporten). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- src/Digdir.Domain.Dialogporten.ChangeDataCapture/Dockerfile | 4 ++-- src/Digdir.Domain.Dialogporten.GraphQL/Dockerfile | 4 ++-- .../MigrationBundle.dockerfile | 4 ++-- src/Digdir.Domain.Dialogporten.Janitor/Dockerfile | 4 ++-- src/Digdir.Domain.Dialogporten.Service/Dockerfile | 4 ++-- src/Digdir.Domain.Dialogporten.WebApi/Dockerfile | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Digdir.Domain.Dialogporten.ChangeDataCapture/Dockerfile b/src/Digdir.Domain.Dialogporten.ChangeDataCapture/Dockerfile index 89bdf7724..376d29a6e 100644 --- a/src/Digdir.Domain.Dialogporten.ChangeDataCapture/Dockerfile +++ b/src/Digdir.Domain.Dialogporten.ChangeDataCapture/Dockerfile @@ -1,7 +1,7 @@ -FROM mcr.microsoft.com/dotnet/aspnet:8.0.10@sha256:b3cdb99fb356091b6395f3444d355da8ae5d63572ba777bed95b65848d6e02be AS base +FROM mcr.microsoft.com/dotnet/aspnet:8.0.10@sha256:3ded9ccf06f222ec934311be4f9facda83d144331c028340e3a694733cad7d4b AS base WORKDIR /app -FROM mcr.microsoft.com/dotnet/sdk:8.0.403@sha256:ff705b99a06144190e2638f8ede64a753915df5ea27fff55f58d0eb5f7054b0b AS build +FROM mcr.microsoft.com/dotnet/sdk:8.0.403@sha256:cab0284cce7bc26d41055d0ac5859a69a8b75d9a201cd226999f4f00cc983f13 AS build WORKDIR /src COPY [".editorconfig", "."] diff --git a/src/Digdir.Domain.Dialogporten.GraphQL/Dockerfile b/src/Digdir.Domain.Dialogporten.GraphQL/Dockerfile index d6aeaca71..16a048da1 100644 --- a/src/Digdir.Domain.Dialogporten.GraphQL/Dockerfile +++ b/src/Digdir.Domain.Dialogporten.GraphQL/Dockerfile @@ -1,8 +1,8 @@ -FROM mcr.microsoft.com/dotnet/aspnet:8.0.10@sha256:b3cdb99fb356091b6395f3444d355da8ae5d63572ba777bed95b65848d6e02be AS base +FROM mcr.microsoft.com/dotnet/aspnet:8.0.10@sha256:3ded9ccf06f222ec934311be4f9facda83d144331c028340e3a694733cad7d4b AS base WORKDIR /app EXPOSE 8080 -FROM mcr.microsoft.com/dotnet/sdk:8.0.403@sha256:ff705b99a06144190e2638f8ede64a753915df5ea27fff55f58d0eb5f7054b0b AS build +FROM mcr.microsoft.com/dotnet/sdk:8.0.403@sha256:cab0284cce7bc26d41055d0ac5859a69a8b75d9a201cd226999f4f00cc983f13 AS build WORKDIR /src COPY [".editorconfig", "."] diff --git a/src/Digdir.Domain.Dialogporten.Infrastructure/MigrationBundle.dockerfile b/src/Digdir.Domain.Dialogporten.Infrastructure/MigrationBundle.dockerfile index 9afd21781..a3ac2cb13 100644 --- a/src/Digdir.Domain.Dialogporten.Infrastructure/MigrationBundle.dockerfile +++ b/src/Digdir.Domain.Dialogporten.Infrastructure/MigrationBundle.dockerfile @@ -1,7 +1,7 @@ -FROM mcr.microsoft.com/dotnet/aspnet:8.0.10@sha256:b3cdb99fb356091b6395f3444d355da8ae5d63572ba777bed95b65848d6e02be AS base +FROM mcr.microsoft.com/dotnet/aspnet:8.0.10@sha256:3ded9ccf06f222ec934311be4f9facda83d144331c028340e3a694733cad7d4b AS base WORKDIR /app -FROM mcr.microsoft.com/dotnet/sdk:8.0.403@sha256:ff705b99a06144190e2638f8ede64a753915df5ea27fff55f58d0eb5f7054b0b AS build +FROM mcr.microsoft.com/dotnet/sdk:8.0.403@sha256:cab0284cce7bc26d41055d0ac5859a69a8b75d9a201cd226999f4f00cc983f13 AS build WORKDIR /src COPY [".editorconfig", "."] diff --git a/src/Digdir.Domain.Dialogporten.Janitor/Dockerfile b/src/Digdir.Domain.Dialogporten.Janitor/Dockerfile index cf39f92c8..85f784d2c 100644 --- a/src/Digdir.Domain.Dialogporten.Janitor/Dockerfile +++ b/src/Digdir.Domain.Dialogporten.Janitor/Dockerfile @@ -1,7 +1,7 @@ -FROM mcr.microsoft.com/dotnet/aspnet:8.0.10@sha256:b3cdb99fb356091b6395f3444d355da8ae5d63572ba777bed95b65848d6e02be AS base +FROM mcr.microsoft.com/dotnet/aspnet:8.0.10@sha256:3ded9ccf06f222ec934311be4f9facda83d144331c028340e3a694733cad7d4b AS base WORKDIR /app -FROM mcr.microsoft.com/dotnet/sdk:8.0.403@sha256:ff705b99a06144190e2638f8ede64a753915df5ea27fff55f58d0eb5f7054b0b AS build +FROM mcr.microsoft.com/dotnet/sdk:8.0.403@sha256:cab0284cce7bc26d41055d0ac5859a69a8b75d9a201cd226999f4f00cc983f13 AS build WORKDIR /src COPY [".editorconfig", "."] diff --git a/src/Digdir.Domain.Dialogporten.Service/Dockerfile b/src/Digdir.Domain.Dialogporten.Service/Dockerfile index c994c2b49..75caaeb26 100644 --- a/src/Digdir.Domain.Dialogporten.Service/Dockerfile +++ b/src/Digdir.Domain.Dialogporten.Service/Dockerfile @@ -1,7 +1,7 @@ -FROM mcr.microsoft.com/dotnet/aspnet:8.0.10@sha256:b3cdb99fb356091b6395f3444d355da8ae5d63572ba777bed95b65848d6e02be AS base +FROM mcr.microsoft.com/dotnet/aspnet:8.0.10@sha256:3ded9ccf06f222ec934311be4f9facda83d144331c028340e3a694733cad7d4b AS base WORKDIR /app -FROM mcr.microsoft.com/dotnet/sdk:8.0.403@sha256:ff705b99a06144190e2638f8ede64a753915df5ea27fff55f58d0eb5f7054b0b AS build +FROM mcr.microsoft.com/dotnet/sdk:8.0.403@sha256:cab0284cce7bc26d41055d0ac5859a69a8b75d9a201cd226999f4f00cc983f13 AS build WORKDIR /src COPY [".editorconfig", "."] diff --git a/src/Digdir.Domain.Dialogporten.WebApi/Dockerfile b/src/Digdir.Domain.Dialogporten.WebApi/Dockerfile index 12082b5e2..a84e30e81 100644 --- a/src/Digdir.Domain.Dialogporten.WebApi/Dockerfile +++ b/src/Digdir.Domain.Dialogporten.WebApi/Dockerfile @@ -1,8 +1,8 @@ -FROM mcr.microsoft.com/dotnet/aspnet:8.0.10@sha256:b3cdb99fb356091b6395f3444d355da8ae5d63572ba777bed95b65848d6e02be AS base +FROM mcr.microsoft.com/dotnet/aspnet:8.0.10@sha256:3ded9ccf06f222ec934311be4f9facda83d144331c028340e3a694733cad7d4b AS base WORKDIR /app EXPOSE 8080 -FROM mcr.microsoft.com/dotnet/sdk:8.0.403@sha256:ff705b99a06144190e2638f8ede64a753915df5ea27fff55f58d0eb5f7054b0b AS build +FROM mcr.microsoft.com/dotnet/sdk:8.0.403@sha256:cab0284cce7bc26d41055d0ac5859a69a8b75d9a201cd226999f4f00cc983f13 AS build WORKDIR /src COPY [".editorconfig", "."]