[java-oidfed-common] branch main updated: Also store trust mark expiration times into the client information extension
Codeberg
noreply at shibboleth.net
Mon Oct 5 13:43:53 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/f94cab943665874344bbdaeb3416ff7025018572
The following commit(s) were added to refs/heads/main by this push:
new f94cab9 Also store trust mark expiration times into the client information extension
f94cab9 is described below
commit f94cab943665874344bbdaeb3416ff7025018572
Author: Henri Mikkonen <henri.mikkonen at iki.fi>
AuthorDate: Mon Oct 5 16:43:16 2026 +0300
Also store trust mark expiration times into the client information extension
---
.../support/ClientInformationExtensionSupport.java | 42 ++++++++++++++++++--
.../metadata/util/EntityStatementHelper.java | 45 ++++++++++++++++++++++
2 files changed, 84 insertions(+), 3 deletions(-)
diff --git a/oidfed-common-api/src/main/java/net/shibboleth/oidfed/support/ClientInformationExtensionSupport.java b/oidfed-common-api/src/main/java/net/shibboleth/oidfed/support/ClientInformationExtensionSupport.java
index 42584b8..f9e5407 100644
--- a/oidfed-common-api/src/main/java/net/shibboleth/oidfed/support/ClientInformationExtensionSupport.java
+++ b/oidfed-common-api/src/main/java/net/shibboleth/oidfed/support/ClientInformationExtensionSupport.java
@@ -14,6 +14,7 @@
package net.shibboleth.oidfed.support;
+import java.time.Instant;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -26,6 +27,7 @@ import javax.annotation.Nullable;
import com.nimbusds.openid.connect.sdk.rp.OIDCClientInformation;
import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.collection.Pair;
/**
* Helper methods for our client information extensions related to OpenID federation.
@@ -71,12 +73,13 @@ public class ClientInformationExtensionSupport {
}
/**
- * Parse validated trust mark IDs from the given client information..
+ * Parse validated trust mark IDs from the given client information. The {@link Pair} is transformed from a map,
+ * as added by {@link #addValidatedTrustMarkIds(OIDCClientInformation, Map)}.
*
* @param clientInformation client information
* @return validated trust mark IDs
*/
- @Nullable public static Map<String, List<String>> parseValidatedTrustMarkIds(
+ @Nullable public static Map<String, List<Pair<String,Instant>>> parseValidatedTrustMarkIds(
@Nonnull final OIDCClientInformation clientInformation) {
return Optional.ofNullable(clientInformation.getOIDCMetadata().getCustomField(KEY_VALIDATED_TRUST_MARK_IDS))
.filter(Map.class::isInstance)
@@ -87,9 +90,42 @@ public class ClientInformationExtensionSupport {
.collect(Collectors.toMap(entry -> entry.getKey().toString(),
entry -> ((List<?>) entry.getValue()).stream()
.filter(Objects::nonNull)
- .map(Objects::toString)
+ .filter(Map.class::isInstance)
+ .map(obj -> (Map<?,?>) obj)
+ .map(pairMap -> {
+ if (pairMap.get("type") instanceof String string) {
+ if (pairMap.get("exp") instanceof Long expiration) {
+ return new Pair<>(string, Instant.ofEpochMilli(expiration));
+ }
+ }
+ return null;
+ })
+ .filter(Objects::nonNull)
.toList())))
.orElse(null);
}
+ /**
+ * Adds the given map of validated trust mark IDs into the given client information object. The {@link Pair} is
+ * transformed into a map.
+ *
+ * @param clientInformation client information
+ * @param trustMarkIds validated trust mark IDs
+ */
+ public static void addValidatedTrustMarkIds(@Nonnull final OIDCClientInformation clientInformation,
+ @Nonnull final Map<String, List<Pair<String, Instant>>> trustMarkIds) {
+ final Map<String, List<Map<String, Object>>> result = trustMarkIds.entrySet().stream()
+ .collect(Collectors.toMap(entry -> entry.getKey(), entry -> entry.getValue().stream()
+ .filter(pair -> pair.getFirst() != null && pair.getSecond() != null)
+ .map(pair -> {
+ final Object type = pair.getFirst();
+ final Instant exp = pair.getSecond();
+ assert exp != null;
+ return Map.of(
+ "type", type,
+ "exp", exp.toEpochMilli());
+ })
+ .toList()));
+ clientInformation.getOIDCMetadata().setCustomField(KEY_VALIDATED_TRUST_MARK_IDS, result);
+ }
}
diff --git a/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/metadata/util/EntityStatementHelper.java b/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/metadata/util/EntityStatementHelper.java
index 65f2351..21b3154 100644
--- a/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/metadata/util/EntityStatementHelper.java
+++ b/oidfed-common-impl/src/main/java/net/shibboleth/oidfed/metadata/util/EntityStatementHelper.java
@@ -15,10 +15,13 @@
package net.shibboleth.oidfed.metadata.util;
import java.text.ParseException;
+import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Comparator;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.Objects;
import javax.annotation.Nonnull;
@@ -34,9 +37,11 @@ import com.nimbusds.jwt.SignedJWT;
import net.shibboleth.oidfed.metadata.EntityConfiguration;
import net.shibboleth.oidfed.metadata.EntityStatement;
import net.shibboleth.oidfed.metadata.SubordinateStatement;
+import net.shibboleth.oidfed.metadata.TrustMark;
import net.shibboleth.oidfed.metadata.impl.EntityConfigurationImpl;
import net.shibboleth.oidfed.metadata.impl.SubordinateStatementImpl;
import net.shibboleth.shared.annotation.constraint.NonnullElements;
+import net.shibboleth.shared.collection.Pair;
import net.shibboleth.shared.logic.ConstraintViolationException;
import net.shibboleth.shared.primitive.LoggerFactory;
@@ -232,4 +237,44 @@ public class EntityStatementHelper {
}
return true;
}
+
+ /**
+ * Parse the given map of trust marks into map of pairs containing the trust mark type and its expiration time.
+ * The expiration time is taken from the trust mark if it exists, or via given maximum lifetime if not. If both
+ * are defined, the one that expires earlier is used.
+ *
+ * @param trustMarks map of trust marks per entity ID
+ * @param maximumLifetime maximum lifetime for trust marks
+ * @return map of trust mark types and their expiration per entity ID
+ */
+ @Nullable public static Map<String,List<Pair<String,Instant>>> parseExpirableTrustMarkIds(
+ @Nullable final Map<String, List<TrustMark>> trustMarks, @Nonnull final Duration maximumLifetime) {
+ if (trustMarks == null || trustMarks.isEmpty()) {
+ log.debug("No trust marks given, returning null");
+ return null;
+ }
+ final Map<String,List<Pair<String,Instant>>> result = new HashMap<>();
+ final Instant maximumExpiration = Instant.now().plus(maximumLifetime);
+ for (final String entity : trustMarks.keySet()) {
+ final List<Pair<String,Instant>> pairs = new ArrayList<>();
+ final List<TrustMark> entityTrustMarks = trustMarks.get(entity);
+ if (entityTrustMarks == null) {
+ log.warn("Null trust marks found for entity {}, ignoring it from the result", entity);
+ continue;
+ }
+ for (final TrustMark trustMark : entityTrustMarks) {
+ final String trustMarkType = trustMark.getParsedPayload().getTrustMarkType();
+ if (trustMarkType == null) {
+ log.warn("Null trust mark type found for entity {}, ignoring it from the result", entity);
+ continue;
+ }
+ final Instant trustMarkExpiration = trustMark.getParsedPayload().getExpiration();
+ final Instant expiration = trustMarkExpiration == null ? maximumExpiration :
+ trustMarkExpiration.isBefore(maximumExpiration) ? trustMarkExpiration : maximumExpiration;
+ pairs.add(new Pair<>(trustMarkType, expiration));
+ }
+ result.put(entity, pairs);
+ }
+ return result;
+ }
}
\ No newline at end of file
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list