## What & why First half of **S-12c** (behandel-portal backend), per **ADR-0013** (decisions recorded in #84): - **BFF multi-realm auth.** A second JWT bearer scheme (`medewerker`) alongside the default `digid` scheme. On validation it lifts Keycloak's `realm_access.roles` onto the principal, and a `behandelaar` policy (medewerker scheme + `behandelaar` role) gates `/behandel/*`. Self-service keeps the digid scheme. - **Werkbak = Flowable tasks.** The domain `Werkbak` query reads the open `Beoordelen` tasks (§8.2, S-12b's `IUserTaskClient`) and enriches each with its aggregate's bsn + status; `GET /behandel/werkbak` (domain) is proxied by the BFF `GET /behandel/werkbak` behind the behandelaar policy. The read projection stays the anonymous openbaar model (no premature `IN_BEHANDELING`/personal-data plumbing — deferred in ADR-0008). Behavior: `/behandel/werkbak` is **401** without a token, **403** for a medewerker lacking the role, **200 + werkbak** for a behandelaar. **S-12c-2** (next): `POST /behandel/registrations/{id}/decide` → domain decision + complete the Flowable task. ## Definition of Done - [x] Linked issue: #13 (umbrella, `refs`); closes the adr-proposal #84 - [x] Tests first; red → green per layer - [x] Unit + acceptance green (`make unit`): domain 78, bff 23, acceptance 9 (+ acl/event-subscriber unaffected) - [x] api-client `test` green; openapi.json regenerated (drift guard passes) - [x] Mutation ≥ break(90): **domain 100%, bff 100%** - [x] ADR-0013 added; `Keycloak__MedewerkerAuthority` wired into compose - [ ] CI green (pending) Part of #13. closes #84 Reviewed-on: #85
This commit was merged in pull request #85.
This commit is contained in:
57
services/bff/Bff.Tests/BehandelEndpointTests.cs
Normal file
57
services/bff/Bff.Tests/BehandelEndpointTests.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using System.Net;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Net.Http.Json;
|
||||
using Bff.Api;
|
||||
|
||||
namespace Bff.Tests;
|
||||
|
||||
/// <summary>
|
||||
/// The behandel werkbak endpoint (S-12c): reached only with a medewerker-realm token that carries the
|
||||
/// <c>behandelaar</c> role. A missing token is 401; an authenticated medewerker without the role is
|
||||
/// 403; a behandelaar gets the werkbak (staff view, incl. bsn).
|
||||
/// </summary>
|
||||
public class BehandelEndpointTests
|
||||
{
|
||||
private static HttpRequestMessage Werkbak(string? bearer)
|
||||
{
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, "/behandel/werkbak");
|
||||
if (bearer is not null)
|
||||
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", bearer);
|
||||
return request;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Rejects_the_werkbak_without_a_token()
|
||||
{
|
||||
using var factory = new BffFactory();
|
||||
|
||||
var response = await factory.CreateClient().SendAsync(Werkbak(bearer: null));
|
||||
|
||||
Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Rejects_a_medewerker_without_the_behandelaar_role()
|
||||
{
|
||||
using var factory = new BffFactory();
|
||||
|
||||
var response = await factory.CreateClient().SendAsync(Werkbak(TestTokens.Medewerker("teamlead")));
|
||||
|
||||
Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Serves_the_werkbak_to_a_behandelaar()
|
||||
{
|
||||
using var factory = new BffFactory();
|
||||
factory.Domain.Werkbak.Add(new WerkbakItem("reg-1", "123456782", "InBehandeling"));
|
||||
|
||||
var response = await factory.CreateClient().SendAsync(Werkbak(TestTokens.Medewerker("behandelaar")));
|
||||
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
var items = await response.Content.ReadFromJsonAsync<List<WerkbakItem>>();
|
||||
var item = Assert.Single(items!);
|
||||
Assert.Equal("reg-1", item.RegistrationId);
|
||||
Assert.Equal("123456782", item.Bsn);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user