Skip to content

Commit

Permalink
Utilise non-admin roles in tests
Browse files Browse the repository at this point in the history
  • Loading branch information
andchiind committed Dec 12, 2023
1 parent a46a11e commit 7fbb49f
Show file tree
Hide file tree
Showing 7 changed files with 486 additions and 28 deletions.
304 changes: 304 additions & 0 deletions backend/api.test/Client/RoleAccessTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,304 @@
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using Api.Controllers.Models;
using Api.Database.Models;
using Api.Test.Mocks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.Extensions.DependencyInjection;
using Xunit;
namespace Api.Test
{
[Collection("Database collection")]
public class RoleAccessTests : IClassFixture<TestWebApplicationFactory<Program>>
{
private readonly HttpClient _client;
private readonly MockHttpContextAccessor _httpContextAccessor;
private readonly JsonSerializerOptions _serializerOptions =
new()
{
Converters =
{
new JsonStringEnumConverter()
},
PropertyNameCaseInsensitive = true
};

public RoleAccessTests(TestWebApplicationFactory<Program> factory)
{
_httpContextAccessor = (MockHttpContextAccessor)factory.Services.GetService<IHttpContextAccessor>()!;
_httpContextAccessor.SetHttpContextRoles(["Role.Admin"]);
//var x = new HttpContextAccessor();
_client = factory.CreateClient(new WebApplicationFactoryClientOptions
{
AllowAutoRedirect = false,
BaseAddress = new Uri("https://localhost:8000")
});
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
TestAuthHandler.AuthenticationScheme
);
}

[Fact]
public async Task AuthorisedPostPlantTest_NotFound()
{
// Arrange
_httpContextAccessor.SetHttpContextRoles(["User.TestInstallationAreaTest_Wrong"]);

string testInstallation = "AuthorisedPostPlantTest_NotFoundInstallation";
var installationQuery = new CreateInstallationQuery
{
InstallationCode = testInstallation,
Name = testInstallation
};

string testPlant = "AuthorisedPostPlantTest_NotFoundPlant";
var plantQuery = new CreatePlantQuery
{
InstallationCode = testInstallation,
PlantCode = testPlant,
Name = testPlant
};
var installationContent = new StringContent(
JsonSerializer.Serialize(installationQuery),
null,
"application/json"
);

var plantContent = new StringContent(
JsonSerializer.Serialize(plantQuery),
null,
"application/json"
);

// Act
string installationUrl = "/installations";
var installationResponse = await _client.PostAsync(installationUrl, installationContent);
string plantUrl = "/plants";
var plantResponse = await _client.PostAsync(plantUrl, plantContent);

// Assert
Assert.True(installationResponse.IsSuccessStatusCode);
Assert.False(plantResponse.IsSuccessStatusCode);
Assert.Equal("NotFound", plantResponse.StatusCode.ToString());
}

[Fact]
public async Task ExplicitlyAuthorisedPostPlantTest()
{
// Arrange
var accessRoleQuery = new CreateAccessRoleQuery
{
InstallationCode = "ExplicitlyAuthorisedPostPlantTestInstallation",
RoleName = "User.ExplicitlyAuthorisedPostPlantTestInstallation",
AccessLevel = RoleAccessLevel.USER
};
var accessRoleContent = new StringContent(
JsonSerializer.Serialize(accessRoleQuery),
null,
"application/json"
);

var testPose = new Pose
{
Position = new Position
{
X = 1,
Y = 2,
Z = 2
},
Orientation = new Orientation
{
X = 0,
Y = 0,
Z = 0,
W = 1
}
};

string testInstallation = "ExplicitlyAuthorisedPostPlantTestInstallation";
var installationQuery = new CreateInstallationQuery
{
InstallationCode = testInstallation,
Name = testInstallation
};

string testPlant = "ExplicitlyAuthorisedPostPlantTestPlant";
var plantQuery = new CreatePlantQuery
{
InstallationCode = testInstallation,
PlantCode = testPlant,
Name = testPlant
};

string testDeck = "ExplicitlyAuthorisedPostPlantTestDeck";
var deckQuery = new CreateDeckQuery
{
InstallationCode = testInstallation,
PlantCode = testPlant,
Name = testDeck
};

string testArea = "ExplicitlyAuthorisedPostPlantTestArea";
var areaQuery = new CreateAreaQuery
{
InstallationCode = testInstallation,
PlantCode = testPlant,
DeckName = testDeck,
AreaName = testArea,
DefaultLocalizationPose = testPose
};

var installationContent = new StringContent(
JsonSerializer.Serialize(installationQuery),
null,
"application/json"
);

var plantContent = new StringContent(
JsonSerializer.Serialize(plantQuery),
null,
"application/json"
);

var deckContent = new StringContent(
JsonSerializer.Serialize(deckQuery),
null,
"application/json"
);

var areaContent = new StringContent(
JsonSerializer.Serialize(areaQuery),
null,
"application/json"
);

// Act
string installationUrl = "/installations";
var installationResponse = await _client.PostAsync(installationUrl, installationContent);
string accessRoleUrl = "/access-roles";
var accessRoleResponse = await _client.PostAsync(accessRoleUrl, accessRoleContent);

// Only restrict ourselves to non-admin role after adding a role
_httpContextAccessor.SetHttpContextRoles(["User.ExplicitlyAuthorisedPostPlantTestInstallation"]);

string plantUrl = "/plants";
var plantResponse = await _client.PostAsync(plantUrl, plantContent);
string deckUrl = "/decks";
var deckResponse = await _client.PostAsync(deckUrl, deckContent);
string areaUrl = "/areas";
var areaResponse = await _client.PostAsync(areaUrl, areaContent);

// Assert
Assert.True(accessRoleResponse.IsSuccessStatusCode);
Assert.True(installationResponse.IsSuccessStatusCode);
Assert.True(plantResponse.IsSuccessStatusCode);
Assert.True(deckResponse.IsSuccessStatusCode);
Assert.True(areaResponse.IsSuccessStatusCode);
var area = await areaResponse.Content.ReadFromJsonAsync<AreaResponse>(_serializerOptions);
Assert.True(area != null);
}

[Fact]
public async Task AdminAuthorisedPostPlantTest()
{
// Arrange
var testPose = new Pose
{
Position = new Position
{
X = 1,
Y = 2,
Z = 2
},
Orientation = new Orientation
{
X = 0,
Y = 0,
Z = 0,
W = 1
}
};

string testInstallation = "AdminAuthorisedPostPlantTestInstallation";
var installationQuery = new CreateInstallationQuery
{
InstallationCode = testInstallation,
Name = testInstallation
};

string testPlant = "AdminAuthorisedPostPlantTestPlant";
var plantQuery = new CreatePlantQuery
{
InstallationCode = testInstallation,
PlantCode = testPlant,
Name = testPlant
};

string testDeck = "AdminAuthorisedPostPlantTestDeck";
var deckQuery = new CreateDeckQuery
{
InstallationCode = testInstallation,
PlantCode = testPlant,
Name = testDeck
};

string testArea = "AdminAuthorisedPostPlantTestArea";
var areaQuery = new CreateAreaQuery
{
InstallationCode = testInstallation,
PlantCode = testPlant,
DeckName = testDeck,
AreaName = testArea,
DefaultLocalizationPose = testPose
};

var installationContent = new StringContent(
JsonSerializer.Serialize(installationQuery),
null,
"application/json"
);

var plantContent = new StringContent(
JsonSerializer.Serialize(plantQuery),
null,
"application/json"
);

var deckContent = new StringContent(
JsonSerializer.Serialize(deckQuery),
null,
"application/json"
);

var areaContent = new StringContent(
JsonSerializer.Serialize(areaQuery),
null,
"application/json"
);

// Act
string installationUrl = "/installations";
var installationResponse = await _client.PostAsync(installationUrl, installationContent);
string plantUrl = "/plants";
var plantResponse = await _client.PostAsync(plantUrl, plantContent);
string deckUrl = "/decks";
var deckResponse = await _client.PostAsync(deckUrl, deckContent);
string areaUrl = "/areas";
var areaResponse = await _client.PostAsync(areaUrl, areaContent);

// Assert
Assert.True(installationResponse.IsSuccessStatusCode);
Assert.True(plantResponse.IsSuccessStatusCode);
Assert.True(deckResponse.IsSuccessStatusCode);
Assert.True(areaResponse.IsSuccessStatusCode);
var area = await areaResponse.Content.ReadFromJsonAsync<AreaResponse>(_serializerOptions);
Assert.True(area != null);
}
}
}
6 changes: 3 additions & 3 deletions backend/api.test/DbContextTestSetup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,9 @@ protected override Task<AuthenticateResult> HandleAuthenticateAsync()
{
var claims = new[]
{
new Claim(ClaimTypes.Name, "Test.User"),
new Claim(ClaimTypes.Role, "Role.Admin")
};
new Claim(ClaimTypes.Name, "Test.User"),
new Claim(ClaimTypes.Role, "Role.Admin")
};
var identity = new ClaimsIdentity(claims, AuthenticationScheme);
var principal = new ClaimsPrincipal(identity);
var ticket = new AuthenticationTicket(principal, AuthenticationScheme);
Expand Down
48 changes: 30 additions & 18 deletions backend/api.test/Mocks/HttpContextAccessorMock.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Security.Cryptography;
using Microsoft.AspNetCore.Http;
Expand All @@ -10,29 +11,40 @@ namespace Api.Test.Mocks
{
public class MockHttpContextAccessor : IHttpContextAccessor
{
private HttpContext? CustomRolesHttpContext { get; set; }

#pragma warning disable CA1859
private static HttpContext GetHttpContextWithRoles(List<string> roles)
#pragma warning restore CA1859
{
var context = new DefaultHttpContext();
var tokenHandler = new JwtSecurityTokenHandler();
var claims = roles.Select<string, Claim>((r) => new(ClaimTypes.Role, r)).ToList();

var rng = RandomNumberGenerator.Create();
byte[] key = new byte[32];
rng.GetBytes(key);
var securityKey = new SymmetricSecurityKey(key) { KeyId = Guid.NewGuid().ToString() };
var signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);

string issuer = Guid.NewGuid().ToString();
string jwtToken = tokenHandler.WriteToken(new JwtSecurityToken(issuer, null, claims, null, DateTime.UtcNow.AddMinutes(20), signingCredentials));
context.Request.Headers.Authorization = jwtToken;
return context;
}

public void SetHttpContextRoles(List<string> roles)
{
CustomRolesHttpContext = GetHttpContextWithRoles(roles);
}

public HttpContext? HttpContext
{
get
{
var context = new DefaultHttpContext();
var tokenHandler = new JwtSecurityTokenHandler();
var claims = new List<Claim>
{
new(ClaimTypes.Role, "Role.Admin"),
new(ClaimTypes.Role, "Role.User"),
new(ClaimTypes.Role, "Role.User.JSV")
};

var rng = RandomNumberGenerator.Create();
byte[] key = new byte[32];
rng.GetBytes(key);
var securityKey = new SymmetricSecurityKey(key) { KeyId = Guid.NewGuid().ToString() };
var signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
if (CustomRolesHttpContext is not null) return CustomRolesHttpContext;

string issuer = Guid.NewGuid().ToString();
string jwtToken = tokenHandler.WriteToken(new JwtSecurityToken(issuer, null, claims, null, DateTime.UtcNow.AddMinutes(20), signingCredentials));
context.Request.Headers.Authorization = jwtToken;
return context;
return GetHttpContextWithRoles(["Role.Admin", "Role.User", "Role.User.JSV"]);
}
set { }
}
Expand Down
2 changes: 1 addition & 1 deletion backend/api.test/TestWebApplicationFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ protected override void ConfigureWebHost(IWebHostBuilder builder)
{
services.AddScoped<IAccessRoleService, AccessRoleService>();
services.AddScoped<IIsarService, MockIsarService>();
services.AddScoped<IHttpContextAccessor, MockHttpContextAccessor>();
services.AddSingleton<IHttpContextAccessor, MockHttpContextAccessor>();
services.AddScoped<IEchoService, MockEchoService>();
services.AddScoped<IMapService, MockMapService>();
services.AddScoped<IBlobService, MockBlobService>();
Expand Down
Loading

0 comments on commit 7fbb49f

Please sign in to comment.