From 50956b30f2bfbbc0b111237f4d6eabe5137e59cb Mon Sep 17 00:00:00 2001 From: allanmckenzie Date: Tue, 14 Jul 2026 10:27:40 +0100 Subject: [PATCH] Fix agent prosecutor authority access JSON parsing (CIMD-3294 regression) ProsecutingAuthorityProvider.buildFromResponseJson parsed the agentProsecutorAuthorityAccess response field as an array of JsonObject elements, each with a "prosecutingAuthority" property. The field is actually an array of strings, so at runtime this threw "ClassCastException: org.eclipse.parsson.JsonStringImpl cannot be cast to jakarta.json.JsonObject" whenever a user had agent prosecutor access (e.g. mi-reportdata sjp resulted-cases-count and case-export endpoints). Restore the original, correct parsing from release/17.104.x-DD-41592 (getValuesAs(JsonString.class) + JsonString::getString). The commit that recreated this CIMD-3294 feature on the 25.104.x line (5f6e0925) reimplemented the parsing with the wrong element type and added no test for the agent-access path, so the regression shipped unnoticed. Add ProsecutingAuthorityProviderTest coverage for parsing the string array and for granting access via an agent prosecutor authority. Bump hearing.version 17.104.168 -> 17.104.176 in the root pom to satisfy enforce-moj-latest-interfaces (latest released hearing-query-api RAML). --- .../ProsecutingAuthorityProvider.java | 5 +-- .../ProsecutingAuthorityProviderTest.java | 36 +++++++++++++++++++ pom.xml | 2 +- 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/access-control-parent/access-control-providers/access-control-sjp-providers/src/main/java/uk/gov/moj/cpp/accesscontrol/sjp/providers/ProsecutingAuthorityProvider.java b/access-control-parent/access-control-providers/access-control-sjp-providers/src/main/java/uk/gov/moj/cpp/accesscontrol/sjp/providers/ProsecutingAuthorityProvider.java index 97f2dc0e..315a8445 100644 --- a/access-control-parent/access-control-providers/access-control-sjp-providers/src/main/java/uk/gov/moj/cpp/accesscontrol/sjp/providers/ProsecutingAuthorityProvider.java +++ b/access-control-parent/access-control-providers/access-control-sjp-providers/src/main/java/uk/gov/moj/cpp/accesscontrol/sjp/providers/ProsecutingAuthorityProvider.java @@ -11,6 +11,7 @@ import jakarta.inject.Inject; import jakarta.json.JsonObject; import jakarta.json.JsonObjectBuilder; +import jakarta.json.JsonString; import jakarta.json.JsonValue; import java.util.Collections; @@ -69,9 +70,9 @@ private ProsecutingAuthorityAccess buildFromResponseJson(final JsonObject respon final List agentProsecutors = Optional .ofNullable(responsePayload.getJsonArray("agentProsecutorAuthorityAccess")) - .map(agentAccess -> agentAccess.getValuesAs(JsonObject.class) + .map(agentAccess -> agentAccess.getValuesAs(JsonString.class) .stream() - .map(agent -> agent.getString("prosecutingAuthority")) + .map(JsonString::getString) .collect(Collectors.toList())) .orElse(Collections.emptyList()); diff --git a/access-control-parent/access-control-providers/access-control-sjp-providers/src/test/java/uk/gov/moj/cpp/accesscontrol/sjp/providers/ProsecutingAuthorityProviderTest.java b/access-control-parent/access-control-providers/access-control-sjp-providers/src/test/java/uk/gov/moj/cpp/accesscontrol/sjp/providers/ProsecutingAuthorityProviderTest.java index ca67f319..4f76528a 100644 --- a/access-control-parent/access-control-providers/access-control-sjp-providers/src/test/java/uk/gov/moj/cpp/accesscontrol/sjp/providers/ProsecutingAuthorityProviderTest.java +++ b/access-control-parent/access-control-providers/access-control-sjp-providers/src/test/java/uk/gov/moj/cpp/accesscontrol/sjp/providers/ProsecutingAuthorityProviderTest.java @@ -1,5 +1,6 @@ package uk.gov.moj.cpp.accesscontrol.sjp.providers; +import static java.util.Arrays.asList; import static java.util.UUID.randomUUID; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; @@ -162,6 +163,41 @@ public void shouldIgnoreAccessControlIfTheAccessControlDisabledPropertyIsTrueFor verify(logger).trace("Skipping prosecuting authority access control due to configuration"); } + @Test + public void shouldParseAgentProsecutorAuthorityAccessAsListOfStrings() { + + when(requester.requestAsAdmin(any())) + .thenReturn(userDetailsResponseWithAgentAccess(PROSECUTING_AUTHORITY, "TFL", "TVL")); + + final ProsecutingAuthorityAccess access = + prosecutingAuthorityProvider.getCurrentUsersProsecutingAuthorityAccess(callingEnvelope); + + assertThat(access.getProsecutingAuthority(), is(PROSECUTING_AUTHORITY)); + assertThat(access.getAgentProsecutorAuthorityAccess(), is(asList("TFL", "TVL"))); + + assertLogStatement(); + } + + @Test + public void shouldGrantAccessViaAgentProsecutorAuthority() { + + when(requester.requestAsAdmin(any())) + .thenReturn(userDetailsResponseWithAgentAccess(PROSECUTING_AUTHORITY, "TFL", "TVL")); + + assertThat(prosecutingAuthorityProvider.userHasProsecutingAuthorityAccess( + callingEnvelope, "TVL"), is(true)); + + assertLogStatement(); + } + + private JsonEnvelope userDetailsResponseWithAgentAccess(final String prosecutingAuthorityAccess, + final String... agentProsecutorAuthorities) { + return envelope() + .withPayloadOf(prosecutingAuthorityAccess, "prosecutingAuthorityAccess") + .withPayloadOf(agentProsecutorAuthorities, "agentProsecutorAuthorityAccess") + .build(); + } + private void givenUserHasNoProsecutingAuthorityAccess() { final JsonEnvelope build = JsonEnvelopeBuilder.envelope() .withPayloadOf("Fred Bloggs", "name") diff --git a/pom.xml b/pom.xml index 53534c5d..0c264213 100644 --- a/pom.xml +++ b/pom.xml @@ -55,7 +55,7 @@ 8.0.5 17.104.48 17.0.262 - 17.104.168 + 17.104.176 17.103.169 17.103.133 2.15.0