[java-oidfed-common] 03/03: Update trust mark details output for the test-resolution admin flow
Codeberg
noreply at shibboleth.net
Thu Jun 4 14:13:08 UTC 2026
This is an automated email from the git hooks/post-receive script.
codeberg pushed a commit to branch main
in repository java-oidfed-common.
View the commit online:
https://codeberg.org/Shibboleth/java-oidfed-common/commit/0647a5b12abbc925668ae960edd27919bd43ed7f
commit 0647a5b12abbc925668ae960edd27919bd43ed7f
Author: Henri Mikkonen <henri.mikkonen at iki.fi>
AuthorDate: Thu Jun 4 17:12:36 2026 +0300
Update trust mark details output for the test-resolution admin flow
- If includeTrustMark flag is set, the output contains iss/sub/iat/exp/type details in addition to the raw JWT
- Also improved flow testincludeTrustMark
---
.../test-trust-chain-resolution-beans.xml | 3 +-
.../admin/oidfed/test-trust-chain-resolution.vm | 9 +-
.../flow/TestTrustChainResolutionFlowTest.java | 134 ++++++++++++++++++++-
3 files changed, 139 insertions(+), 7 deletions(-)
diff --git a/oidfed-common-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/admin/oidfed/test-trust-chain-resolution/test-trust-chain-resolution-beans.xml b/oidfed-common-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/admin/oidfed/test-trust-chain-resolution/test-trust-chain-resolution-beans.xml
index 7a3d6ac..69f5ebe 100644
--- a/oidfed-common-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/admin/oidfed/test-trust-chain-resolution/test-trust-chain-resolution-beans.xml
+++ b/oidfed-common-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/admin/oidfed/test-trust-chain-resolution/test-trust-chain-resolution-beans.xml
@@ -61,7 +61,8 @@
p:trustEngine-ref="shibboleth.oidfed.DefaultEntityConfigurationTrustEngine"
p:delegationTrustEngine-ref="shibboleth.oidfed.DefaultDelegatedTrustMarkTrustEngine">
<property name="trustChainTrustMarksParsingStrategy">
- <bean class="net.shibboleth.oidfed.profile.navigate.DefaultTrustChainTrustMarksParsingStrategy"/>
+ <bean class="net.shibboleth.oidfed.profile.navigate.DefaultTrustChainTrustMarksParsingStrategy"
+ p:objectMapper-ref="shibboleth.oidfed.JWTPayloadJSONObjectMapper"/>
</property>
<property name="trustedTrustMarkIssuersLookupStrategy">
<bean class="net.shibboleth.oidfed.profile.navigate.DefaultTrustChainTrustedTrustMarkIssuersLookupStrategy"/>
diff --git a/oidfed-common-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/views/admin/oidfed/test-trust-chain-resolution.vm b/oidfed-common-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/views/admin/oidfed/test-trust-chain-resolution.vm
index 0d8017d..30a7949 100644
--- a/oidfed-common-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/views/admin/oidfed/test-trust-chain-resolution.vm
+++ b/oidfed-common-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/views/admin/oidfed/test-trust-chain-resolution.vm
@@ -55,7 +55,14 @@
]#if($includeTrustMark),
"trust_mark_details" : [
#foreach ($trustMark in $trustMarks.get($index - 1))
- "$trustMark.serialize()"#if( $foreach.hasNext ),#end
+ {
+ "trust_mark_type": "$trustMark.getParsedPayload().getTrustMarkType()",
+ "issuer": "$trustMark.getIssuer()",
+ "subject" : "$trustMark.getParsedPayload().getSubject()",
+ "issuedAt" : "$trustMark.getParsedPayload().getIssuedAt()",
+ "expiresAt" : "$trustMark.getParsedPayload().getExpiration()",
+ "rawJwt" : "$trustMark.getJwt().serialize()"
+ }#if( $foreach.hasNext ),#end
#end
]#end
}#if( $foreach.hasNext ),#end
diff --git a/oidfed-common-conf-impl/src/test/java/net/shibboleth/oidfed/flow/TestTrustChainResolutionFlowTest.java b/oidfed-common-conf-impl/src/test/java/net/shibboleth/oidfed/flow/TestTrustChainResolutionFlowTest.java
index 0a750e6..eccc979 100644
--- a/oidfed-common-conf-impl/src/test/java/net/shibboleth/oidfed/flow/TestTrustChainResolutionFlowTest.java
+++ b/oidfed-common-conf-impl/src/test/java/net/shibboleth/oidfed/flow/TestTrustChainResolutionFlowTest.java
@@ -91,16 +91,122 @@ public class TestTrustChainResolutionFlowTest extends AbstractFederationFlowTest
assertResponseArraySize(0);
}
- /**
- * Test the flow without any parameters.
- *
- * @throws Exception if an error occurs
- */
@Test
public void testWithOnlyEntityIDParameter() throws Exception {
request.setMethod("GET");
final String entityId = super.uniqueClientId();
request.addParameter("entityID", entityId);
+ request.addParameter("includeTrustMark", "true");
+
+ final String trustMark = TrustChainTestUtil.trustMark(JWSAlgorithm.RS256, trustMarkIssuerKey, trustMarkIssuerId,
+ entityId, "https://example.org/email-allowing-trust-mark", Instant.now().plusSeconds(300)).serialize();
+ final OIDCClientMetadata metadata = new OIDCClientMetadata();
+ metadata.setRedirectionURI(new URI(redirectUri));
+ metadata.setJWKSet(new JWKSet(rpKey.toPublicJWK()));
+
+ final String rpEntityConfiguration = rpEntityConfiguration(entityId, metadata, List.of(Map.of(
+ "trust_mark_type", "https://example.org/email-allowing-trust-mark",
+ "trust_mark", trustMark)), leafKey);
+ rpConfigureMockHttpClient(entityId, rpEntityConfiguration);
+ try {
+ mapResponse(entityConfigurationUrl(trustMarkIssuerId),
+ mockResponse(trustMarkIssuerConfiguration(trustMarkIssuerId)));
+ mapResponse(subordinateStatementUrl(anchorFetchEndpoint, trustMarkIssuerId),
+ mockResponse(subordinateStatement(trustMarkIssuerId,
+ Map.of("federation_entity", CollectionSupport.emptyMap()), trustMarkIssuerKey)));
+ mapResponse(trustMarkStatusEndpoint, mockResponse(200, "application/trust-mark-status-response+jwt",
+ trustMarkStatusResponse(trustMarkIssuerId, trustMark, "active", trustMarkIssuerKey)));
+ } catch (UnsupportedOperationException | IOException e) {
+ Assert.fail("Could not initialize mock HTTP client", e);
+ }
+
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+
+ final FlowExecutionOutcome outcome = result.getOutcome();
+ assertEquals(outcome.getId(), "ResponseView");
+ assertResponseArraySize(1);
+ }
+
+ @Test
+ public void testWithTrustMarkDetailsParameterNullStatusNoValidationRequired() throws Exception {
+ request.setMethod("GET");
+ final String entityId = super.uniqueClientId();
+ request.addParameter("entityID", entityId);
+ request.addParameter("includeTrustMark", "true");
+
+ final String trustMark = TrustChainTestUtil.trustMark(JWSAlgorithm.RS256, trustMarkIssuerKey, trustMarkIssuerId,
+ entityId, "https://example.org/email-allowing-trust-mark", Instant.now().plusSeconds(300)).serialize();
+ final OIDCClientMetadata metadata = new OIDCClientMetadata();
+ metadata.setRedirectionURI(new URI(redirectUri));
+ metadata.setJWKSet(new JWKSet(rpKey.toPublicJWK()));
+
+ final String rpEntityConfiguration = rpEntityConfiguration(entityId, metadata, List.of(Map.of(
+ "trust_mark_type", "https://example.org/email-allowing-trust-mark",
+ "trust_mark", trustMark)), leafKey);
+ rpConfigureMockHttpClient(entityId, rpEntityConfiguration);
+ try {
+ mapResponse(entityConfigurationUrl(trustMarkIssuerId),
+ mockResponse(trustMarkIssuerConfiguration(trustMarkIssuerId)));
+ mapResponse(subordinateStatementUrl(anchorFetchEndpoint, trustMarkIssuerId),
+ mockResponse(subordinateStatement(trustMarkIssuerId,
+ Map.of("federation_entity", CollectionSupport.emptyMap()), trustMarkIssuerKey)));
+ } catch (UnsupportedOperationException | IOException e) {
+ Assert.fail("Could not initialize mock HTTP client", e);
+ }
+
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+
+ final FlowExecutionOutcome outcome = result.getOutcome();
+ assertEquals(outcome.getId(), "ResponseView");
+ assertResponseArraySize(1);
+ assertTrustMarkDetails(1);
+ }
+
+ @Test
+ public void testWithTrustMarkDetailsParameterInvalidStatusRemoteValidationRequired() throws Exception {
+ request.setMethod("GET");
+ final String entityId = super.uniqueClientId();
+ request.addParameter("entityID", entityId);
+ request.addParameter("includeTrustMark", "true");
+ request.addParameter("remoteTrustMarkValidation", "true");
+
+ final String trustMark = TrustChainTestUtil.trustMark(JWSAlgorithm.RS256, trustMarkIssuerKey, trustMarkIssuerId,
+ entityId, "https://example.org/email-allowing-trust-mark", Instant.now().plusSeconds(300)).serialize();
+ final OIDCClientMetadata metadata = new OIDCClientMetadata();
+ metadata.setRedirectionURI(new URI(redirectUri));
+ metadata.setJWKSet(new JWKSet(rpKey.toPublicJWK()));
+
+ final String rpEntityConfiguration = rpEntityConfiguration(entityId, metadata, List.of(Map.of(
+ "trust_mark_type", "https://example.org/email-allowing-trust-mark",
+ "trust_mark", trustMark)), leafKey);
+ rpConfigureMockHttpClient(entityId, rpEntityConfiguration);
+ try {
+ mapResponse(entityConfigurationUrl(trustMarkIssuerId),
+ mockResponse(trustMarkIssuerConfiguration(trustMarkIssuerId)));
+ mapResponse(subordinateStatementUrl(anchorFetchEndpoint, trustMarkIssuerId),
+ mockResponse(subordinateStatement(trustMarkIssuerId,
+ Map.of("federation_entity", CollectionSupport.emptyMap()), trustMarkIssuerKey)));
+ mapResponse(trustMarkStatusEndpoint, mockResponse(200, "application/trust-mark-status-response+jwt",
+ trustMarkStatusResponse(trustMarkIssuerId, trustMark, "invalid", trustMarkIssuerKey)));
+ } catch (UnsupportedOperationException | IOException e) {
+ Assert.fail("Could not initialize mock HTTP client", e);
+ }
+
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+
+ final FlowExecutionOutcome outcome = result.getOutcome();
+ assertEquals(outcome.getId(), "ResponseView");
+ assertResponseArraySize(1);
+ assertTrustMarkDetails(0);
+ }
+
+ @Test
+ public void testWithTrustMarkDetailsParameterValidStatusRemoteValidationRequired() throws Exception {
+ request.setMethod("GET");
+ final String entityId = super.uniqueClientId();
+ request.addParameter("entityID", entityId);
+ request.addParameter("includeTrustMark", "true");
+ request.addParameter("remoteTrustMarkValidation", "true");
final String trustMark = TrustChainTestUtil.trustMark(JWSAlgorithm.RS256, trustMarkIssuerKey, trustMarkIssuerId,
entityId, "https://example.org/email-allowing-trust-mark", Instant.now().plusSeconds(300)).serialize();
@@ -129,6 +235,7 @@ public class TestTrustChainResolutionFlowTest extends AbstractFederationFlowTest
final FlowExecutionOutcome outcome = result.getOutcome();
assertEquals(outcome.getId(), "ResponseView");
assertResponseArraySize(1);
+ assertTrustMarkDetails(1);
}
protected void assertResponseArraySize(final int expected) {
@@ -139,4 +246,21 @@ public class TestTrustChainResolutionFlowTest extends AbstractFederationFlowTest
Assert.fail("Could not deserialize response", e);
}
}
+
+ protected void assertTrustMarkDetails(final int expected) {
+ final ObjectMapper objectMapper = new ObjectMapper();
+ try {
+ final List<?> rootArray = objectMapper.readValue(response.getContentAsString(), List.class);
+ if (rootArray.get(0) instanceof Map<?,?> map) {
+ if (map.get("trust_mark_details") instanceof List<?> details) {
+ Assert.assertEquals(details.size(), expected);
+ return;
+ }
+ }
+ } catch (JsonProcessingException | UnsupportedEncodingException e) {
+ Assert.fail("Could not deserialize response", e);
+ }
+ Assert.fail("Unexpected trust_mark_details");
+ }
+
}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list