Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Instance authorization #531

Merged
merged 14 commits into from
Nov 28, 2024
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Altinn.Correspondence.sln
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Altinn.Correspondence.Tests
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Altinn.Correspondence.Integrations", "src\Altinn.Correspondence.Integrations\Altinn.Correspondence.Integrations.csproj", "{5C88BAAD-CF82-4D7A-8FB6-879605EF4E03}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Altinn.Correspondence.Common", "src\Altinn.Correspondence.Common\Altinn.Correspondence.Common.csproj", "{AC3CF570-F9E1-4616-A56B-FF94C89CBC0B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -47,6 +49,10 @@ Global
{5C88BAAD-CF82-4D7A-8FB6-879605EF4E03}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5C88BAAD-CF82-4D7A-8FB6-879605EF4E03}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5C88BAAD-CF82-4D7A-8FB6-879605EF4E03}.Release|Any CPU.Build.0 = Release|Any CPU
{AC3CF570-F9E1-4616-A56B-FF94C89CBC0B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AC3CF570-F9E1-4616-A56B-FF94C89CBC0B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AC3CF570-F9E1-4616-A56B-FF94C89CBC0B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AC3CF570-F9E1-4616-A56B-FF94C89CBC0B}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
90 changes: 90 additions & 0 deletions Test/Altinn.Correspondence.Tests/Helpers/AuthorizationOverride.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
using Altinn.Correspondence.Core.Models.Entities;
using Altinn.Correspondence.Core.Models.Enums;
using Altinn.Correspondence.Core.Repositories;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using System.Security.Claims;

namespace Altinn.Correspondence.Tests.Helpers;

public static class AuthorizationOverride
{
public static IServiceCollection OverrideAuthorization(this IServiceCollection services)
{
var altinnAuthorizationService = new Mock<IAltinnAuthorizationService>();
altinnAuthorizationService
.Setup(x => x.CheckAccessAsRecipient(
It.IsAny<ClaimsPrincipal>(),
It.IsAny<CorrespondenceEntity>(),
It.IsAny<CancellationToken>()))
.Returns((ClaimsPrincipal? user, CorrespondenceEntity corr, CancellationToken token) => {
return Task.FromResult(NotRecipient(user));
});

altinnAuthorizationService
.Setup(x => x.CheckAccessAsSender(
It.IsAny<ClaimsPrincipal>(),
It.IsAny<CorrespondenceEntity>(),
It.IsAny<CancellationToken>()))
.Returns((ClaimsPrincipal? user, CorrespondenceEntity corr, CancellationToken token) => {
return Task.FromResult(NotSender(user));
});

altinnAuthorizationService
.Setup(x => x.CheckAccessAsSender(
It.IsAny<ClaimsPrincipal>(),
It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<CancellationToken>()))
.Returns((ClaimsPrincipal? user, string resourceId, string sender, string? instance, CancellationToken token) => {
return Task.FromResult(NotSender(user));
});

altinnAuthorizationService
.Setup(x => x.CheckAccessAsAny(
It.IsAny<ClaimsPrincipal>(),
It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<CancellationToken>()))
.Returns((ClaimsPrincipal? user, string resource, string party, CancellationToken token) => {
return Task.FromResult(NotRecipient(user) || NotSender(user));
});
Ceredron marked this conversation as resolved.
Show resolved Hide resolved

altinnAuthorizationService
.Setup(x => x.CheckMigrationAccess(
It.IsAny<string>(),
It.IsAny<List<ResourceAccessLevel>>(),
It.IsAny<CancellationToken>()))
.Returns((string resourceId, IEnumerable<ResourceAccessLevel> levels, CancellationToken token) =>
{
return Task.FromResult(true);
});

altinnAuthorizationService
.Setup(x => x.CheckUserAccessAndGetMinimumAuthLevel(
It.IsAny<ClaimsPrincipal>(),
It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<List<ResourceAccessLevel>>(),
It.IsAny<string>(),
It.IsAny<CancellationToken>()))
.Returns((ClaimsPrincipal? user, string ssn, string resourceId, List<ResourceAccessLevel> rights, string recipientOrgNo, CancellationToken token) =>
{
return Task.FromResult<int?>(3);
});

return services.AddScoped(_ => altinnAuthorizationService.Object);
}

private static bool NotSender(ClaimsPrincipal? user)
{
return !user?.Claims.Any(c =>
c.Type == "notSender") ?? true;
}
private static bool NotRecipient(ClaimsPrincipal? user)
{
return !user?.Claims.Any(c =>
c.Type == "notRecipient") ?? true;
}
Ceredron marked this conversation as resolved.
Show resolved Hide resolved
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using Altinn.Correspondence.Core.Repositories;
using Altinn.Correspondence.Core.Services;
using Altinn.Correspondence.Integrations.Altinn.AccessManagement;
using Altinn.Correspondence.Integrations.Altinn.Authorization;
using Altinn.Correspondence.Integrations.Altinn.Events;
using Altinn.Correspondence.Integrations.Altinn.Notifications;
using Altinn.Correspondence.Integrations.Altinn.Register;
Expand All @@ -25,6 +24,7 @@ public class CustomWebApplicationFactory : WebApplicationFactory<Program>
{
internal Mock<IBackgroundJobClient>? HangfireBackgroundJobClient;


protected override void ConfigureWebHost(
IWebHostBuilder builder)
{
Expand All @@ -46,14 +46,16 @@ protected override void ConfigureWebHost(
services.AddScoped<IEventBus, ConsoleLogEventBus>();
services.AddScoped<IAltinnNotificationService, AltinnDevNotificationService>();
services.AddScoped<IDialogportenService, DialogportenDevService>();
services.AddScoped<IAltinnAuthorizationService, AltinnAuthorizationDevService>();
services.OverrideAuthorization();
services.AddScoped<IAltinnRegisterService, AltinnRegisterDevService>();
services.AddScoped<IAltinnAccessManagementService, AltinnAccessManagementDevService>();
var resourceRightsService = new Mock<IResourceRightsService>();
resourceRightsService.Setup(x => x.GetServiceOwnerOfResource(It.IsAny<string>(), It.IsAny<CancellationToken>())).ReturnsAsync("");
services.AddScoped(_ => resourceRightsService.Object);
});
}


public HttpClient CreateClientWithAddedClaims(params (string type, string value)[] claims)
{
var defaultClaims = new List<Claim>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using Altinn.Common.PEP.Authorization;
using Altinn.Correspondence.Application.Configuration;
using Altinn.Correspondence.Common.Constants;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Authorization.Infrastructure;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,13 @@ public async Task DeleteAttachment_AsRecipient_ReturnsForbidden()
Assert.Equal(HttpStatusCode.Forbidden, deleteResponse.StatusCode);
}
[Fact]
public async Task DeleteAttachment_AsWrongSender_ReturnsBadRequest()
public async Task DeleteAttachment_AsWrongSender_ReturnsUnauthorized()
{
// Arrange
var attachmentId = await AttachmentHelper.GetPublishedAttachment(_senderClient, _responseSerializerOptions);
var deleteResponse = await _wrongSenderClient.DeleteAsync($"correspondence/api/v1/attachment/{attachmentId}");
// Assert failure before correspondence is created
Assert.Equal(HttpStatusCode.BadRequest, deleteResponse.StatusCode);
Assert.Equal(HttpStatusCode.Unauthorized, deleteResponse.StatusCode);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public async Task DownloadAttachment_AsWrongSender_ReturnsBadRequest()
var data = await downloadResponse.Content.ReadFromJsonAsync<ProblemDetails>();

// Assert
Assert.Equal(HttpStatusCode.BadRequest, downloadResponse.StatusCode);
Assert.Equal(HttpStatusCode.Unauthorized, downloadResponse.StatusCode);
Assert.NotNull(data?.Title);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ public async Task InitializeAttachment_AsRecipient_ReturnsForbidden()
}

[Fact]
public async Task InitializeAttachment_As_Different_Sender_As_Token_ReturnsBadRequest()
public async Task InitializeAttachment_As_Different_Sender_As_Token_ReturnsUnauthorized()
{
var attachment = new AttachmentBuilder().CreateAttachment().Build();
var initializeAttachmentResponse = await _wrongSenderClient.PostAsJsonAsync("correspondence/api/v1/attachment", attachment);
Assert.Equal(HttpStatusCode.BadRequest, initializeAttachmentResponse.StatusCode);
Assert.Equal(HttpStatusCode.Unauthorized, initializeAttachmentResponse.StatusCode);
}

[Fact]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
using Altinn.Correspondence.Tests.Helpers;
using Altinn.Correspondence.Tests.TestingController.Attachment.Base;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace Altinn.Correspondence.Tests.TestingController.Attachment
{
Expand All @@ -31,11 +26,11 @@ public async Task GetAttachmentOverview_AsRecipient_ReturnsForbidden()
}

[Fact]
public async Task GetAttachmentOverview_As_Different_sender_ReturnsBadRequest()
public async Task GetAttachmentOverview_As_Different_sender_ReturnsUnauthorized()
{
var attachmentId = await AttachmentHelper.GetInitializedAttachment(_senderClient, _responseSerializerOptions);
var getAttachmentOverviewResponse = await _wrongSenderClient.GetAsync($"correspondence/api/v1/attachment/{attachmentId}");
Assert.Equal(HttpStatusCode.BadRequest, getAttachmentOverviewResponse.StatusCode);
Assert.Equal(HttpStatusCode.Unauthorized, getAttachmentOverviewResponse.StatusCode);
}

[Fact]
Expand All @@ -54,11 +49,11 @@ public async Task GetAttachmentDetails_AsRecipient_ReturnsForbidden()
}

[Fact]
public async Task GetAttachmentDetails_As_Different_sender_ReturnsBadRequest()
public async Task GetAttachmentDetails_As_Different_sender_ReturnsUnauthorized()
{
var attachmentId = await AttachmentHelper.GetInitializedAttachment(_senderClient, _responseSerializerOptions);
var getAttachmentOverviewResponse = await _wrongSenderClient.GetAsync($"correspondence/api/v1/attachment/{attachmentId}/details");
Assert.Equal(HttpStatusCode.BadRequest, getAttachmentOverviewResponse.StatusCode);
Assert.Equal(HttpStatusCode.Unauthorized, getAttachmentOverviewResponse.StatusCode);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public async Task UploadAttachmentData_WrongSender_Fails()
{
var attachmentId = await AttachmentHelper.GetInitializedAttachment(_senderClient, _responseSerializerOptions);
var uploadResponse = await AttachmentHelper.UploadAttachment(attachmentId, _wrongSenderClient);
Assert.Equal(HttpStatusCode.BadRequest, uploadResponse.StatusCode);
Assert.Equal(HttpStatusCode.Unauthorized, uploadResponse.StatusCode);
}

[Fact]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Altinn.Correspondence.Application.Configuration;
using Altinn.Correspondence.Common.Constants;
using System.Text.Json;

namespace Altinn.Correspondence.Tests.TestingController.Attachment.Base
Expand All @@ -18,8 +18,7 @@ public AttachmentTestBase(CustomWebApplicationFactory factory)
_recipientClient = factory.CreateClientWithAddedClaims(("scope", AuthorizationConstants.RecipientScope));
_wrongSenderClient = factory.CreateClientWithAddedClaims(
("scope", AuthorizationConstants.SenderScope),
("client_orgnr", "123456789"),
("consumer", "{\"authority\":\"iso6523-actorid-upis\",\"ID\":\"0192:123456789\"}")
("notSender", "true")
);
_responseSerializerOptions = new JsonSerializerOptions()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Altinn.Correspondence.Application.Configuration;
using Altinn.Correspondence.Common.Constants;
using System;
using System.Collections.Generic;
using System.Linq;
Expand All @@ -18,8 +18,14 @@ public class CorrespondenceTestBase : IClassFixture<CustomWebApplicationFactory>
public CorrespondenceTestBase(CustomWebApplicationFactory factory)
{
_factory = factory;
_senderClient = _factory.CreateClientWithAddedClaims(("scope", AuthorizationConstants.SenderScope));
_recipientClient = _factory.CreateClientWithAddedClaims(("scope", AuthorizationConstants.RecipientScope));
_senderClient = _factory.CreateClientWithAddedClaims(
("notRecipient", "true"),
("scope", AuthorizationConstants.SenderScope)
);
_recipientClient = _factory.CreateClientWithAddedClaims(
("notSender", "true"),
("scope", AuthorizationConstants.RecipientScope)
);
_responseSerializerOptions = new JsonSerializerOptions(new JsonSerializerOptions()
{
PropertyNameCaseInsensitive = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ public async Task DownloadCorrespondenceAttachment_AsRecipient_Succeeds()
}

[Fact]
public async Task DownloadCorrespondenceAttachment_WhenNotARecipient_Returns404()
public async Task DownloadCorrespondenceAttachment_WhenNotARecipient_Returns401()
{
// Arrange
var attachmentId = await AttachmentHelper.GetPublishedAttachment(_senderClient, _responseSerializerOptions);
Expand All @@ -203,10 +203,10 @@ public async Task DownloadCorrespondenceAttachment_WhenNotARecipient_Returns404(
// Act
var initializeCorrespondenceResponse = await _senderClient.PostAsJsonAsync("correspondence/api/v1/correspondence", payload, _responseSerializerOptions);
var response = await initializeCorrespondenceResponse.Content.ReadFromJsonAsync<InitializeCorrespondencesResponseExt>(_responseSerializerOptions);
var downloadResponse = await _recipientClient.GetAsync($"correspondence/api/v1/correspondence/{response?.Correspondences.FirstOrDefault().CorrespondenceId}/attachment/{attachmentId}/download");
var downloadResponse = await _senderClient.GetAsync($"correspondence/api/v1/correspondence/{response?.Correspondences.FirstOrDefault().CorrespondenceId}/attachment/{attachmentId}/download");

// Assert
Assert.Equal(HttpStatusCode.NotFound, downloadResponse.StatusCode);
Assert.Equal(HttpStatusCode.Unauthorized, downloadResponse.StatusCode);
}

[Fact]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using Altinn.Correspondence.API.Models;
using Altinn.Correspondence.API.Models.Enums;
using Altinn.Correspondence.Application.Configuration;
using Altinn.Correspondence.Common.Constants;
using Altinn.Correspondence.Core.Models.Notifications;
using Altinn.Correspondence.Core.Repositories;
using Altinn.Correspondence.Tests.Factories;
Expand Down
Loading
Loading