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 + } +} 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/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/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", "."] 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" });