[java-idp-oidc] branch main updated: JOIDC-123 - create scope predicate for use in activation conditions

Henri Mikkonen henri.mikkonen at iki.fi
Fri Oct 7 12:45:04 UTC 2022


This is an automated email from the git hooks/post-receive script.

hjmikkon pushed a commit to branch main
in repository java-idp-oidc.

View the commit online:
http://git.shibboleth.net/view/?p=java-idp-oidc.git;a=commit;h=2ad08aa6ab08b516ae614e244ce0ba64e02f7516

The following commit(s) were added to refs/heads/main by this push:
     new 2ad08aa6 JOIDC-123 - create scope predicate for use in activation conditions
2ad08aa6 is described below

commit 2ad08aa6ab08b516ae614e244ce0ba64e02f7516
Author: Henri Mikkonen <henri.mikkonen at iki.fi>
AuthorDate: Fri Oct 7 15:43:31 2022 +0300

    JOIDC-123 - create scope predicate for use in activation conditions
    
    https://shibboleth.atlassian.net/browse/JOIDC-123
    
    New global abstract predicate: shibboleth.oidc.Conditions.ValidatedScope
---
 .../context/logic/ValidatedScopePredicate.java     | 108 ++++++++++++++++++
 .../context/logic/ValidatedScopePredicateTest.java | 124 +++++++++++++++++++++
 .../META-INF/net.shibboleth.idp/postconfig.xml     |   3 +
 3 files changed, 235 insertions(+)

diff --git a/idp-oidc-extension-api/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/logic/ValidatedScopePredicate.java b/idp-oidc-extension-api/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/logic/ValidatedScopePredicate.java
new file mode 100644
index 00000000..0446bfa0
--- /dev/null
+++ b/idp-oidc-extension-api/src/main/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/logic/ValidatedScopePredicate.java
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements.  See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.idp.plugin.oidc.op.messaging.context.logic;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.function.Predicate;
+
+import javax.annotation.Nonnull;
+
+import org.opensaml.profile.context.ProfileRequestContext;
+
+import com.nimbusds.oauth2.sdk.Scope;
+
+import net.shibboleth.utilities.java.support.annotation.ParameterName;
+import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElements;
+import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
+import net.shibboleth.utilities.java.support.logic.StrategyIndirectedPredicate;
+
+import net.shibboleth.idp.plugin.oidc.op.profile.context.navigate.ValidatedScopeLookupFunction;
+
+/**
+ * Predicate that evaluates a {@link ProfileRequestContext} by looking for the validated {@link Scope} that matches
+ * one of a designated set of string values, a single value, or a generic predicate.
+ * 
+ * @since 3.3.0
+ */
+public class ValidatedScopePredicate  extends StrategyIndirectedPredicate<ProfileRequestContext, Scope> {
+
+    /**
+     * Constructor.
+     * 
+     * @param values hardwired set of values to check against
+     */
+    public ValidatedScopePredicate(
+            @Nonnull @NonnullElements @ParameterName(name="values") final Collection<String> values) {
+        super(new ValidatedScopeLookupFunction(),
+                scope -> scope == null ? false : scope.containsAll(Scope.parse(values)));
+    }
+
+    /**
+     * Constructor.
+     * 
+     * @param value a single value to check against
+     */
+    public ValidatedScopePredicate(@Nonnull @NotEmpty @ParameterName(name="value") final String value) {
+        this(Collections.singleton(value));
+    }
+
+    /**
+     * Constructor.
+     * 
+     * @param pred generalized predicate
+     */
+    public ValidatedScopePredicate(@Nonnull @ParameterName(name="pred") final Predicate<Scope> pred) {
+        super(new ValidatedScopeLookupFunction(), pred);
+    }
+    
+    /**
+     * Workaround for Spring type conversion ambiguities.
+     * 
+     * @param values hardwired set of values to check against
+     * 
+     * @return the predicate
+     */
+    @Nonnull public static ValidatedScopePredicate fromValues(
+            @Nonnull @NonnullElements final Collection<String> values) {
+        return new ValidatedScopePredicate(values);
+    }
+    
+    /**
+     * Workaround for Spring type conversion ambiguities.
+     * 
+     * @param value a single value to check against
+     * 
+     * @return the predicate
+     */
+    @Nonnull public static ValidatedScopePredicate fromValue(@Nonnull @NotEmpty final String value) {
+        return new ValidatedScopePredicate(value);
+    }
+
+    /**
+     * Workaround for Spring type conversion ambiguities.
+     * 
+     * @param pred generalized predicate
+     * 
+     * @return the predicate
+     */
+    @Nonnull public static ValidatedScopePredicate fromPredicate(@Nonnull final Predicate<Scope> pred) {
+        return new ValidatedScopePredicate(pred);
+    }
+
+}
diff --git a/idp-oidc-extension-api/src/test/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/logic/ValidatedScopePredicateTest.java b/idp-oidc-extension-api/src/test/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/logic/ValidatedScopePredicateTest.java
new file mode 100644
index 00000000..698b7172
--- /dev/null
+++ b/idp-oidc-extension-api/src/test/java/net/shibboleth/idp/plugin/oidc/op/messaging/context/logic/ValidatedScopePredicateTest.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements.  See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.idp.plugin.oidc.op.messaging.context.logic;
+
+import java.util.List;
+
+import org.opensaml.messaging.context.MessageContext;
+import org.opensaml.profile.context.ProfileRequestContext;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.nimbusds.oauth2.sdk.Scope;
+
+import net.shibboleth.idp.plugin.oidc.op.messaging.context.OIDCAuthenticationResponseContext;
+
+/**
+ * Unit tests for {@link ValidatedScopePredicate}.
+ */
+public class ValidatedScopePredicateTest {
+    
+    ValidatedScopePredicate predicate;
+
+    public ProfileRequestContext init(final Scope scope) {
+        final ProfileRequestContext prc = new ProfileRequestContext();
+        final MessageContext msgCtx = new MessageContext();
+        final OIDCAuthenticationResponseContext oidcResponseCtx = 
+                msgCtx.getSubcontext(OIDCAuthenticationResponseContext.class, true);
+        oidcResponseCtx.setScope(scope);
+        prc.setOutboundMessageContext(msgCtx);
+        return prc;
+    }
+
+    @Test
+    public void testSingleValue() {
+        predicate = new ValidatedScopePredicate("openid");
+        Assert.assertTrue(predicate.test(init(Scope.parse("openid profile"))));
+        Assert.assertTrue(predicate.test(init(Scope.parse("openid profile email address"))));
+        Assert.assertTrue(predicate.test(init(Scope.parse("openid email address profile"))));
+        Assert.assertFalse(predicate.test(init(Scope.parse("profile email address"))));
+        Assert.assertTrue(predicate.test(init(Scope.parse("openid"))));
+        Assert.assertFalse(predicate.test(init(null)));
+
+        predicate = ValidatedScopePredicate.fromValue("openid");
+        Assert.assertTrue(predicate.test(init(Scope.parse("openid profile"))));
+        Assert.assertTrue(predicate.test(init(Scope.parse("openid profile email address"))));
+        Assert.assertTrue(predicate.test(init(Scope.parse("openid email address profile"))));
+        Assert.assertFalse(predicate.test(init(Scope.parse("profile email address"))));
+        Assert.assertTrue(predicate.test(init(Scope.parse("openid"))));
+        Assert.assertFalse(predicate.test(init(null)));
+    }
+
+    @Test
+    public void testCollectionValues() {
+        predicate = new ValidatedScopePredicate(List.of("openid", "profile"));
+        Assert.assertTrue(predicate.test(init(Scope.parse("openid profile"))));
+        Assert.assertTrue(predicate.test(init(Scope.parse("openid profile email address"))));
+        Assert.assertTrue(predicate.test(init(Scope.parse("openid email address profile"))));
+        Assert.assertFalse(predicate.test(init(Scope.parse("profile email address"))));
+        Assert.assertFalse(predicate.test(init(Scope.parse("openid"))));
+        Assert.assertFalse(predicate.test(init(null)));
+
+        predicate = ValidatedScopePredicate.fromValues(List.of("openid", "profile"));
+        Assert.assertTrue(predicate.test(init(Scope.parse("openid profile"))));
+        Assert.assertTrue(predicate.test(init(Scope.parse("openid profile email address"))));
+        Assert.assertTrue(predicate.test(init(Scope.parse("openid email address profile"))));
+        Assert.assertFalse(predicate.test(init(Scope.parse("profile email address"))));
+        Assert.assertFalse(predicate.test(init(Scope.parse("openid"))));
+        Assert.assertFalse(predicate.test(init(null)));
+    }
+    
+    @Test
+    public void testPredicateAlwaysFalse() {
+        predicate = new ValidatedScopePredicate(prc -> Boolean.FALSE);
+        Assert.assertFalse(predicate.test(init(Scope.parse("openid profile"))));
+        Assert.assertFalse(predicate.test(init(Scope.parse("openid profile email address"))));
+        Assert.assertFalse(predicate.test(init(Scope.parse("openid email address profile"))));
+        Assert.assertFalse(predicate.test(init(Scope.parse("profile email address"))));
+        Assert.assertFalse(predicate.test(init(Scope.parse("openid"))));
+        Assert.assertFalse(predicate.test(init(null)));
+
+        predicate = ValidatedScopePredicate.fromPredicate(prc -> Boolean.FALSE);
+        Assert.assertFalse(predicate.test(init(Scope.parse("openid profile"))));
+        Assert.assertFalse(predicate.test(init(Scope.parse("openid profile email address"))));
+        Assert.assertFalse(predicate.test(init(Scope.parse("openid email address profile"))));
+        Assert.assertFalse(predicate.test(init(Scope.parse("profile email address"))));
+        Assert.assertFalse(predicate.test(init(Scope.parse("openid"))));
+        Assert.assertFalse(predicate.test(init(null)));
+    }
+
+    @Test
+    public void testPredicateAlwaysTrue() {
+        predicate = new ValidatedScopePredicate(prc -> Boolean.TRUE);
+        Assert.assertTrue(predicate.test(init(Scope.parse("openid profile"))));
+        Assert.assertTrue(predicate.test(init(Scope.parse("openid profile email address"))));
+        Assert.assertTrue(predicate.test(init(Scope.parse("openid email address profile"))));
+        Assert.assertTrue(predicate.test(init(Scope.parse("profile email address"))));
+        Assert.assertTrue(predicate.test(init(Scope.parse("openid"))));
+        Assert.assertTrue(predicate.test(init(null)));
+
+        predicate = ValidatedScopePredicate.fromPredicate(prc -> Boolean.TRUE);
+        Assert.assertTrue(predicate.test(init(Scope.parse("openid profile"))));
+        Assert.assertTrue(predicate.test(init(Scope.parse("openid profile email address"))));
+        Assert.assertTrue(predicate.test(init(Scope.parse("openid email address profile"))));
+        Assert.assertTrue(predicate.test(init(Scope.parse("profile email address"))));
+        Assert.assertTrue(predicate.test(init(Scope.parse("openid"))));
+        Assert.assertTrue(predicate.test(init(null)));
+    }
+
+}
diff --git a/idp-oidc-extension-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml b/idp-oidc-extension-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
index b038957a..9bf878ff 100644
--- a/idp-oidc-extension-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
+++ b/idp-oidc-extension-impl/src/main/resources/META-INF/net.shibboleth.idp/postconfig.xml
@@ -557,4 +557,7 @@
             class="net.shibboleth.idp.plugin.oidc.op.profile.context.navigate.TokenRequestTokenClaimsSetLookupFunction">
     </bean>
 
+    <bean id="shibboleth.oidc.Conditions.ValidatedScope"
+        class="net.shibboleth.idp.plugin.oidc.op.messaging.context.logic.ValidatedScopePredicate" abstract="true" />
+
 </beans>

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list