-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added function for processing authorization event (#31)
* Added function for processing authorization event * code smells * Added function tests * added more unit tests for function app * Excluded contextrequest from code coverage * Fix datetime issue in unit tests --------- Co-authored-by: acn-dgopa <acn-dgopa@dev-acn-tje-14>
- Loading branch information
Showing
16 changed files
with
727 additions
and
13 deletions.
There are no files selected for viewing
30 changes: 30 additions & 0 deletions
30
Altinn.Auth.AuditLog.Functions.Tests/Altinn.Auth.AuditLog.Functions.Tests.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net7.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
|
||
<IsPackable>false</IsPackable> | ||
<IsTestProject>true</IsTestProject> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" /> | ||
<PackageReference Include="Moq" Version="4.20.69" /> | ||
<PackageReference Include="xunit" Version="2.4.2" /> | ||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5"> | ||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | ||
<PrivateAssets>all</PrivateAssets> | ||
</PackageReference> | ||
<PackageReference Include="coverlet.collector" Version="3.2.0"> | ||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | ||
<PrivateAssets>all</PrivateAssets> | ||
</PackageReference> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\src\Functions\Altinn.Auth.AuditLog.Functions\Altinn.Auth.AuditLog.Functions.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |
148 changes: 148 additions & 0 deletions
148
Altinn.Auth.AuditLog.Functions.Tests/Clients/AuditLogClientTest.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
using Altinn.Auth.AuditLog.Functions.Clients; | ||
using Altinn.Auth.AuditLog.Functions.Clients.Interfaces; | ||
using Altinn.Auth.AuditLog.Functions.Configuration; | ||
using Altinn.Auth.AuditLog.Functions.Models; | ||
using Altinn.Auth.AuditLog.Functions.Tests.Helpers; | ||
using Azure.Messaging; | ||
using Microsoft.Extensions.Logging; | ||
using Microsoft.Extensions.Options; | ||
using Moq; | ||
using Moq.Protected; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Net; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace Altinn.Auth.AuditLog.Functions.Tests.Clients | ||
{ | ||
public class AuditLogClientTest | ||
{ | ||
Mock<ILogger<IAuditLogClient>> _loggerMock = new Mock<ILogger<IAuditLogClient>>(); | ||
IOptions<PlatformSettings> _platformSettings = Options.Create(new PlatformSettings | ||
{ | ||
AuditLogApiEndpoint = "https://platform.test.altinn.cloud/" | ||
}); | ||
|
||
private readonly AuthenticationEvent authenticationEvent = new AuthenticationEvent() | ||
{ | ||
UserId = "20000003", | ||
Created = DateTime.UtcNow, | ||
AuthenticationMethod = "BankId", | ||
EventType = "LoggedIn", | ||
SessionId = "83343b4c-865d-4e6c-888d-33bc7533ea2d", | ||
AuthenticationLevel = "4", | ||
}; | ||
|
||
/// <summary> | ||
/// Verify that the endpoint the client sends a request to is set correctly | ||
/// </summary> | ||
[Fact] | ||
public async Task SaveAuthenticationEvent_SuccessResponse() | ||
{ | ||
// Arrange | ||
var handlerMock = CreateMessageHandlerMock( | ||
"https://platform.test.altinn.cloud/auditlog/api/v1/authenticationevent", | ||
HttpStatusCode.OK); | ||
|
||
var client = new AuditLogClient(_loggerMock.Object, new HttpClient(handlerMock.Object), _platformSettings); | ||
// Act | ||
await client.SaveAuthenticationEvent(authenticationEvent); | ||
|
||
// Assert | ||
handlerMock.VerifyAll(); | ||
} | ||
|
||
[Fact] | ||
public async Task SaveAuthenticationEvent_NonSuccessResponse_ErrorLoggedAndExceptionThrown() | ||
{ | ||
// Arrange | ||
var handlerMock = CreateMessageHandlerMock( | ||
"https://platform.test.altinn.cloud/auditlog/api/v1/authenticationevent", | ||
HttpStatusCode.ServiceUnavailable); | ||
|
||
var client = CreateTestInstance(handlerMock.Object); | ||
|
||
// Act | ||
|
||
await Assert.ThrowsAsync<HttpRequestException>(async () => await client.SaveAuthenticationEvent(authenticationEvent)); | ||
|
||
// Assert | ||
handlerMock.VerifyAll(); | ||
_loggerMock.Verify(x => x.Log( | ||
LogLevel.Error, | ||
It.IsAny<EventId>(), | ||
It.Is<It.IsAnyType>((v, t) => v.ToString().Contains("SaveAuthenticationEvent failed with status code ServiceUnavailable")), | ||
It.IsAny<Exception>(), | ||
(Func<It.IsAnyType, Exception, string>)It.IsAny<object>()), Times.Once); | ||
} | ||
|
||
/// <summary> | ||
/// Verify that the endpoint the client sends a request to is set correctly | ||
/// </summary> | ||
[Fact] | ||
public async Task SaveAuthorizationEvent_SuccessResponse() | ||
{ | ||
// Arrange | ||
var handlerMock = CreateMessageHandlerMock( | ||
"https://platform.test.altinn.cloud/auditlog/api/v1/authorizationevent", | ||
HttpStatusCode.OK); | ||
|
||
var client = new AuditLogClient(_loggerMock.Object, new HttpClient(handlerMock.Object), _platformSettings); | ||
// Act | ||
await client.SaveAuthorizationEvent(TestDataHelper.GetAuthorizationEvent()); | ||
|
||
// Assert | ||
handlerMock.VerifyAll(); | ||
} | ||
|
||
[Fact] | ||
public async Task SaveAuthorizationEvent_NonSuccessResponse_ErrorLoggedAndExceptionThrown() | ||
{ | ||
// Arrange | ||
var handlerMock = CreateMessageHandlerMock( | ||
"https://platform.test.altinn.cloud/auditlog/api/v1/authorizationevent", | ||
HttpStatusCode.ServiceUnavailable); | ||
|
||
var client = CreateTestInstance(handlerMock.Object); | ||
|
||
// Act | ||
|
||
await Assert.ThrowsAsync<HttpRequestException>(async () => await client.SaveAuthorizationEvent(TestDataHelper.GetAuthorizationEvent())); | ||
|
||
// Assert | ||
handlerMock.VerifyAll(); | ||
_loggerMock.Verify(x => x.Log( | ||
LogLevel.Error, | ||
It.IsAny<EventId>(), | ||
It.Is<It.IsAnyType>((v, t) => v.ToString().Contains("SaveAuthorizationEvent failed with status code ServiceUnavailable")), | ||
It.IsAny<Exception>(), | ||
(Func<It.IsAnyType, Exception, string>)It.IsAny<object>()), Times.Once); | ||
} | ||
|
||
private static Mock<HttpMessageHandler> CreateMessageHandlerMock(string clientEndpoint, HttpStatusCode statusCode) | ||
{ | ||
var messageHandlerMock = new Mock<HttpMessageHandler>(MockBehavior.Strict); | ||
|
||
messageHandlerMock.Protected() | ||
.Setup<Task<HttpResponseMessage>>("SendAsync", ItExpr.Is<HttpRequestMessage>(rm => rm.RequestUri.Equals(clientEndpoint)), ItExpr.IsAny<CancellationToken>()) | ||
.ReturnsAsync((HttpRequestMessage request, CancellationToken token) => | ||
{ | ||
var response = new HttpResponseMessage(statusCode); | ||
return response; | ||
}) | ||
.Verifiable(); | ||
|
||
return messageHandlerMock; | ||
} | ||
|
||
private AuditLogClient CreateTestInstance(HttpMessageHandler messageHandlerMock) | ||
{ | ||
return new AuditLogClient( | ||
_loggerMock.Object, | ||
new HttpClient(messageHandlerMock), | ||
_platformSettings); | ||
} | ||
} | ||
} |
72 changes: 72 additions & 0 deletions
72
Altinn.Auth.AuditLog.Functions.Tests/Functions/AuthorizationEventsProcessorTest.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
using Altinn.Auth.AuditLog.Functions.Clients.Interfaces; | ||
using Altinn.Auth.AuditLog.Functions.Models; | ||
using Altinn.Auth.AuditLog.Functions.Tests.Helpers; | ||
using Altinn.Auth.AuditLog.Functions.Tests.Utils; | ||
using Azure.Messaging; | ||
using Microsoft.Extensions.Logging; | ||
using Moq; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Globalization; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace Altinn.Auth.AuditLog.Functions.Tests.Functions | ||
{ | ||
public class AuthorizationEventsProcessorTest | ||
{ | ||
Mock<ILogger<AuthorizationEventsProcessor>> _loggerMock = new Mock<ILogger<AuthorizationEventsProcessor>>(); | ||
|
||
[Fact] | ||
public async Task Run_ConfirmDeserializationOfAuthorizationEvent() | ||
{ | ||
|
||
// Arrange | ||
string serializedAuthorizationEvent = "{" + | ||
"\"TimeStamp\":\"0001-01-01T00:00:00\",\"SubjectUserId\":\"2000000\",\"SubjectParty\":\"\"," + | ||
"\"ResourcePartyId\":\"1000\",\"Resource\":\"taxreport\",\"InstanceId\":\"1000/26133fb5-a9f2-45d4-90b1-f6d93ad40713\"," + | ||
"\"Operation\":\"read\",\"TimeToDelete\":\"\",\"IpAdress\":\"192.0.2.1\"," + | ||
"\"ContextRequestJson\":{\"ReturnPolicyIdList\":false," + | ||
"\"AccessSubject\":[{\"Attribute\":[{\"Id\":\"urn:altinn:userid\",\"Value\":\"1\",\"DataType\":null,\"IncludeInResult\":false}," + | ||
"{\"Id\":\"urn:altinn:role\",\"Value\":\"dagl\",\"DataType\":null,\"IncludeInResult\":false}," + | ||
"{\"Id\":\"urn:altinn:role\",\"Value\":\"utinn\",\"DataType\":null,\"IncludeInResult\":false}]}]," + | ||
"\"Action\":[{\"Attribute\":[{\"Id\":\"urn:oasis:names:tc:xacml:1.0:action:action-id\",\"Value\":\"read\"," + | ||
"\"DataType\":\"http://www.w3.org/2001/XMLSchema#string\",\"IncludeInResult\":false}]}]," + | ||
"\"Resources\":[{\"Attribute\":[{\"Id\":\"urn:altinn:instance-id\",\"Value\":\"1000/26133fb5-a9f2-45d4-90b1-f6d93ad40713\"," + | ||
"\"DataType\":null,\"IncludeInResult\":true},{\"Id\":\"urn:altinn:org\",\"Value\":\"skd\"," + | ||
"\"DataType\":null,\"IncludeInResult\":false},{\"Id\":\"urn:altinn:app\",\"Value\":\"taxreport\"," + | ||
"\"DataType\":null,\"IncludeInResult\":false},{\"Id\":\"urn:altinn:partyid\",\"Value\":\"1000\"," + | ||
"\"DataType\":null,\"IncludeInResult\":false},{\"Id\":\"urn:altinn:task\",\"Value\":\"formfilling\"," + | ||
"\"DataType\":null,\"IncludeInResult\":false}]}]}}\r\n"; | ||
|
||
Mock<IAuditLogClient> clientMock = new(); | ||
clientMock.Setup(c => c.SaveAuthorizationEvent(It.Is<AuthorizationEvent>(c => AssertExpectedAuthorizationEvent(c, TestDataHelper.GetAuthorizationEvent())))) | ||
.Returns(Task.CompletedTask); | ||
|
||
AuthorizationEventsProcessor sut = new AuthorizationEventsProcessor(clientMock.Object); | ||
|
||
// Act | ||
await sut.Run(serializedAuthorizationEvent, null); | ||
|
||
// Assert | ||
|
||
clientMock.VerifyAll(); | ||
} | ||
|
||
private static bool AssertExpectedAuthorizationEvent(AuthorizationEvent actualAuthorizationEvent, AuthorizationEvent expectedAuthorizationEvent) | ||
{ | ||
Assert.Equal(expectedAuthorizationEvent.InstanceId, actualAuthorizationEvent.InstanceId); | ||
Assert.Equal(expectedAuthorizationEvent.Operation, actualAuthorizationEvent.Operation); | ||
Assert.Equal(expectedAuthorizationEvent.Resource, actualAuthorizationEvent.Resource); | ||
Assert.Equal(expectedAuthorizationEvent.IpAdress, actualAuthorizationEvent.IpAdress); | ||
Assert.Equal(expectedAuthorizationEvent.TimeToDelete, actualAuthorizationEvent.TimeToDelete); | ||
Assert.Equal(expectedAuthorizationEvent.TimeStamp, actualAuthorizationEvent.TimeStamp); | ||
AssertionUtil.AssertCollections(expectedAuthorizationEvent.ContextRequestJson.Action, actualAuthorizationEvent.ContextRequestJson.Action, AssertionUtil.AssertRuleEqual); | ||
AssertionUtil.AssertCollections(expectedAuthorizationEvent.ContextRequestJson.AccessSubject, actualAuthorizationEvent.ContextRequestJson.AccessSubject, AssertionUtil.AssertRuleEqual); | ||
AssertionUtil.AssertCollections(expectedAuthorizationEvent.ContextRequestJson.Resources, actualAuthorizationEvent.ContextRequestJson.Resources, AssertionUtil.AssertRuleEqual); | ||
Assert.Equal(expectedAuthorizationEvent.ContextRequestJson.ReturnPolicyIdList, actualAuthorizationEvent.ContextRequestJson.ReturnPolicyIdList); | ||
return true; | ||
} | ||
} | ||
} |
63 changes: 63 additions & 0 deletions
63
Altinn.Auth.AuditLog.Functions.Tests/Functions/EventsProcessorTest.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
using Altinn.Auth.AuditLog.Functions.Clients.Interfaces; | ||
using Altinn.Auth.AuditLog.Functions.Models; | ||
using Azure.Messaging; | ||
using Microsoft.Extensions.Logging; | ||
using Moq; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Globalization; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace Altinn.Auth.AuditLog.Functions.Tests.Functions | ||
{ | ||
public class EventsProcessorTest | ||
{ | ||
Mock<ILogger<EventsProcessor>> _loggerMock = new Mock<ILogger<EventsProcessor>>(); | ||
|
||
[Fact] | ||
public async Task Run_ConfirmDeserializationOfAuthenticationEvent() | ||
{ | ||
|
||
// Arrange | ||
string serializedAuthenticationEvent = "{\"Created\":\"2023-09-07T06:24:43.971899Z\",\"UserId\":\"20000003\",\"SupplierId\":null,\"EventType\":\"LoggedIn\",\"OrgNumber\":null,\"AuthenticationMethod\":\"BankId\",\"AuthenticationLevel\":\"4\",\"SessionId\":\"83343b4c-865d-4e6c-888d-33bc7533ea2d\"}\r\n"; | ||
|
||
AuthenticationEvent expectedAuthenticationEvent = new AuthenticationEvent() | ||
{ | ||
UserId = "20000003", | ||
Created = DateTimeOffset.Parse("2023-09-07T06:24:43.971899Z").UtcDateTime, | ||
AuthenticationMethod = "BankId", | ||
EventType = "LoggedIn", | ||
SessionId = "83343b4c-865d-4e6c-888d-33bc7533ea2d", | ||
AuthenticationLevel = "4", | ||
}; | ||
|
||
Mock<IAuditLogClient> clientMock = new(); | ||
clientMock.Setup(c => c.SaveAuthenticationEvent(It.Is<AuthenticationEvent>(c => AssertExpectedAuthenticationEvent(c, expectedAuthenticationEvent)))) | ||
.Returns(Task.CompletedTask); | ||
|
||
EventsProcessor sut = new EventsProcessor(_loggerMock.Object, clientMock.Object); | ||
|
||
// Act | ||
await sut.Run(serializedAuthenticationEvent, null); | ||
|
||
// Assert | ||
|
||
clientMock.VerifyAll(); | ||
} | ||
|
||
private static bool AssertExpectedAuthenticationEvent(AuthenticationEvent actualAuthenticationEvent, AuthenticationEvent expectedAuthenticationEvent) | ||
{ | ||
Assert.Equal(expectedAuthenticationEvent.SessionId, actualAuthenticationEvent.SessionId); | ||
Assert.Equal(expectedAuthenticationEvent.AuthenticationLevel, actualAuthenticationEvent.AuthenticationLevel); | ||
Assert.Equal(expectedAuthenticationEvent.AuthenticationMethod, actualAuthenticationEvent.AuthenticationMethod); | ||
Assert.Equal(expectedAuthenticationEvent.Created, actualAuthenticationEvent.Created); | ||
Assert.Equal(expectedAuthenticationEvent.EventType, actualAuthenticationEvent.EventType); | ||
Assert.Equal(expectedAuthenticationEvent.OrgNumber, actualAuthenticationEvent.OrgNumber); | ||
Assert.Equal(expectedAuthenticationEvent.SupplierId, actualAuthenticationEvent.SupplierId); | ||
Assert.Equal(expectedAuthenticationEvent.UserId, actualAuthenticationEvent.UserId); | ||
return true; | ||
} | ||
} | ||
} |
Oops, something went wrong.