Skip to content

Commit

Permalink
Merge branch 'main' into #827-Playwright-Test---Stappen-Nieuwswerkins…
Browse files Browse the repository at this point in the history
…tructies-Skills-Filter
  • Loading branch information
JustinICATT authored Oct 24, 2024
2 parents e215e02 + 1de9b5e commit 0cdb2af
Show file tree
Hide file tree
Showing 41 changed files with 1,446 additions and 665 deletions.
42 changes: 34 additions & 8 deletions Kiss.Bff.Test/AuthorizationCheckTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,24 @@ public class AuthorizationCheckTests
[ClassInitialize]
public static void ClassInit(TestContext _)
{
Environment.SetEnvironmentVariable("MANAGEMENTINFORMATIE_API_KEY", "eenZeerGeheimeSleutelMetMinimaal32TekensLang");
s_factory = new CustomWebApplicationFactory();
s_client = s_factory.CreateDefaultClient();
}

[ClassCleanup]
public static void ClassCleanup()
{
Environment.SetEnvironmentVariable("MANAGEMENTINFORMATIE_API_KEY", null);
s_client?.Dispose();
s_factory?.Dispose();
}

public static IEnumerable<object[]> GetControllersWithAuthorizeAttributeAndMethods()
public static IEnumerable<object[]> GetControllersMethodsWithDefaultAuthorizeAttributes()
{
// Define the controllers and methods to test here
var controllersWithMethodsToTest = new List<(Type controllerType, string methodName, Type[] parameterTypes)>
{
(typeof(ReadContactmomentenDetails), "Get", new[] { typeof(string), typeof(string), typeof(CancellationToken), typeof(int), typeof(int) }),
(typeof(GespreksresultatenController), "PutGespreksresultaat", new[] { typeof(Guid), typeof(GespreksresultaatModel), typeof(CancellationToken) }),
(typeof(GespreksresultatenController), "PostGespreksresultaat", new[] { typeof(GespreksresultaatModel), typeof(CancellationToken)}),
(typeof(GespreksresultatenController), "DeleteGespreksresultaat", new[] { typeof(Guid), typeof(CancellationToken)}),
Expand All @@ -69,16 +70,16 @@ public static IEnumerable<object[]> GetControllersWithAuthorizeAttributeAndMetho
[DataRow("/api/contactmomentendetails?id=1")]
[DataRow("/api/zaaksysteem/deeplinkconfig")]
[DataRow("/api/KanaalToevoegen", "post")]
public async Task Test(string url, string method = "get")
public async Task CallingEnpointsWithoutCredetialsShouldResultInAUnauthorizedResponse(string url, string method = "get")
{
using var request = new HttpRequestMessage(new(method), url);
using var response = await s_client.SendAsync(request);
Assert.AreEqual(Unauthorized, response.StatusCode);
}

[DataTestMethod]
[DynamicData(nameof(GetControllersWithAuthorizeAttributeAndMethods), DynamicDataSourceType.Method)]
public async Task TestAuthorizeAttribute(Type controllerType, string methodName, Type[] parameterTypes)
[DynamicData(nameof(GetControllersMethodsWithDefaultAuthorizeAttributes), DynamicDataSourceType.Method)]
public void TestAuthorizeAttribute(Type controllerType, string methodName, Type[] parameterTypes)
{
// Manually create an instance of the controller
var dbContextOptions = new DbContextOptionsBuilder<BeheerDbContext>()
Expand All @@ -100,10 +101,35 @@ public async Task TestAuthorizeAttribute(Type controllerType, string methodName,
var authorizeAttribute = method.GetCustomAttributes(typeof(AuthorizeAttribute), true)
.FirstOrDefault() as AuthorizeAttribute;

// Assert that the Authorize attribute exists and has the expected policy
Assert.IsNotNull(authorizeAttribute);
Assert.AreEqual(Policies.RedactiePolicy, authorizeAttribute.Policy);
// Assert that the method has the right auth attribute
Assert.AreEqual(Policies.RedactiePolicy, authorizeAttribute?.Policy);
}


[TestMethod]
public void TestAuthorizationOfManagementInformatieEndpoint()
{
var controllerType = typeof(ReadContactmomentenDetails);

var dbContext = new BeheerDbContext(new DbContextOptions<BeheerDbContext>());
var controller = Activator.CreateInstance(controllerType, dbContext) as ControllerBase;

Assert.IsNotNull(controller);

var methods = controllerType.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);

Assert.AreEqual(2, methods.Length);

for (var i = 0; i < methods.Length; i += 1)
{
var authorizeAttribute = methods[i].GetCustomAttributes(typeof(AuthorizeAttribute), true).FirstOrDefault() as AuthorizeAttribute;

Assert.IsNotNull(authorizeAttribute);
Assert.AreEqual(Policies.ExternSysteemPolicy, authorizeAttribute.Policy);
}
}

}
}


2 changes: 0 additions & 2 deletions Kiss.Bff.Test/PostKlantContactenCustomProxyTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ public void Setup()
_configurationMock = new Mock<IConfiguration>();
_getMedewerkerIdentificatieMock = new Mock<GetMedewerkerIdentificatie>();

_configurationMock.Setup(config => config["KLANTCONTACTEN_BASE_URL"]).Returns("https://fakeurl.com");

_httpContext = new DefaultHttpContext
{
User = new ClaimsPrincipal(new ClaimsIdentity(new Claim[]
Expand Down
34 changes: 34 additions & 0 deletions Kiss.Bff/Config/AuthenticationSetup.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
using System.Security.Claims;
using System.Text;
using System.Text.Json.Nodes;
using AngleSharp.Io;
using IdentityModel;
using Kiss;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.IdentityModel.Tokens;

namespace Kiss
{
public static class Policies
{
public const string RedactiePolicy = "RedactiePolicy";
public const string ExternSysteemPolicy = "ExternSysteemPolicy";
}

public static class KissClaimTypes
Expand Down Expand Up @@ -66,6 +71,8 @@ public class KissAuthOptions
public string? RedacteurRole { get; set; }
public string? MedewerkerIdentificatieClaimType { get; set; }
public int? TruncateMedewerkerIdentificatie { get; set; }

public string? JwtTokenAuthenticationSecret { get; set; }
}

public static class AuthenticationSetupExtensions
Expand Down Expand Up @@ -155,6 +162,23 @@ public static IServiceCollection AddKissAuth(this IServiceCollection services, A
});
}


if (authOptions.JwtTokenAuthenticationSecret != null)
{
authBuilder.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = false,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(authOptions.JwtTokenAuthenticationSecret))
};
});
}


services.AddDistributedMemoryCache();
services.AddOpenIdConnectAccessTokenManagement();

Expand All @@ -168,6 +192,16 @@ public static IServiceCollection AddKissAuth(this IServiceCollection services, A
new AuthorizationPolicyBuilder()
.RequireRole(redacteurRole)
.Build());


options.AddPolicy(Policies.ExternSysteemPolicy, policy =>
{
policy.RequireRole("ExternSysteem");
policy.AuthenticationSchemes.Add(JwtBearerDefaults.AuthenticationScheme);
});



});

return services;
Expand Down
52 changes: 52 additions & 0 deletions Kiss.Bff/Config/JwtAuthSetup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//using Microsoft.AspNetCore.Authentication.JwtBearer;
//using Microsoft.Extensions.DependencyInjection;
//using Microsoft.IdentityModel.Tokens;
//using System.Text;
//using Kiss;

//namespace Microsoft.Extensions.DependencyInjection
//{
// public static class JwtAuthSetupExtensions
// {
// public static IServiceCollection AddJwtAuth(this IServiceCollection services, Action<JwtAuthOptions> configureOptions)
// {
// var jwtOptions = new JwtAuthOptions();
// configureOptions(jwtOptions);

// jwtOptions.SecretKey = jwtOptions.SecretKey ?? string.Empty;

// services.AddAuthentication(options =>
// {
// options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
// options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
// })
// .AddJwtBearer(options =>
// {
// options.TokenValidationParameters = new TokenValidationParameters
// {
// ValidateIssuer = true,
// ValidateAudience = false,
// ValidateLifetime = true,
// ValidateIssuerSigningKey = true,
// IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtOptions.SecretKey))
// };
// });

// services.AddAuthorization(options =>
// {
// options.AddPolicy(Policies.ExternSysteemPolicy, policy =>
// {
// policy.RequireRole("ExternSysteem");
// policy.AuthenticationSchemes.Add(JwtBearerDefaults.AuthenticationScheme);
// });
// });

// return services;
// }
// }

// public class JwtAuthOptions
// {
// public string SecretKey { get; set; } = string.Empty;
// }
//}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public ReadContactmomentenDetails(BeheerDbContext db)
}

[HttpGet("/api/contactmomentdetails")]
[Authorize(Policy = Policies.ExternSysteemPolicy)]
public async Task<IActionResult> Get([FromQuery] string id, CancellationToken token)
{
var contactmoment = await _db.ContactMomentDetails
Expand All @@ -32,7 +33,7 @@ public async Task<IActionResult> Get([FromQuery] string id, CancellationToken to
}

[HttpGet("/api/contactmomentendetails")]
[Authorize(Policy = Policies.RedactiePolicy)]
[Authorize(Policy = Policies.ExternSysteemPolicy)]
public async Task<IActionResult> Get(
[FromQuery] string from,
[FromQuery] string to,
Expand Down
3 changes: 2 additions & 1 deletion Kiss.Bff/Kiss.Bff.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
Expand All @@ -16,6 +16,7 @@
<ItemGroup>
<PackageReference Include="Duende.AccessTokenManagement.OpenIdConnect" Version="1.1.0" />
<PackageReference Include="HtmlSanitizer" Version="8.0.723" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.10" />
<PackageReference Include="Microsoft.AspNetCore.DataProtection.EntityFrameworkCore" Version="6.0.16" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.29" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="6.0.29" />
Expand Down
8 changes: 7 additions & 1 deletion Kiss.Bff/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,14 @@
{
options.TruncateMedewerkerIdentificatie = truncate;
}
options.JwtTokenAuthenticationSecret = builder.Configuration["MANAGEMENTINFORMATIE_API_KEY"];
});

//builder.Services.AddJwtAuth(options =>
//{
// options.SecretKey = builder.Configuration["MANAGEMENTINFORMATIE_API_KEY"];
//});

builder.Services.AddKissProxy();
builder.Services.AddKvk(builder.Configuration["KVK_BASE_URL"], builder.Configuration["KVK_API_KEY"]);
builder.Services.AddHaalCentraal(builder.Configuration["HAAL_CENTRAAL_BASE_URL"], builder.Configuration["HAAL_CENTRAAL_API_KEY"]);
Expand Down Expand Up @@ -129,7 +135,7 @@
app.MapKissAuthEndpoints();
app.MapControllers();
app.MapKissProxy();
app.MapHealthChecks("/healthz");
app.MapHealthChecks("/healthz").AllowAnonymous();
app.MapFallbackToIndexHtml();

using (var scope = app.Services.CreateScope())
Expand Down
2 changes: 2 additions & 0 deletions src/components/SearchResultsCaption.vue
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ const zoekTermenCaption = computed(() => {
return `voor '${props.zoekTermen.handelsnaam}'.`;
} else if ("kvkNummer" in props.zoekTermen) {
return `voor '${props.zoekTermen.kvkNummer}'.`;
} else if ("vestigingsnummer" in props.zoekTermen) {
return `voor '${props.zoekTermen.vestigingsnummer}'.`;
} else {
return "";
}
Expand Down
3 changes: 1 addition & 2 deletions src/features/bedrijf/bedrijf-zoeken/BedrijvenOverzicht.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,9 @@
<script lang="ts" setup>
import type { Bedrijf } from "@/services/kvk";
import BedrijvenOverzichtRow from "./BedrijvenOverzichtRow.vue";
import type { Klant } from "@/services/klanten";
defineProps<{
records: Array<Bedrijf | Klant>;
records: Array<Bedrijf>;
navigateOnSingleResult?: boolean;
}>();
</script>
Loading

0 comments on commit 0cdb2af

Please sign in to comment.