[java-idp-oidc] branch main updated: JOIDC-6 - Release policy for OAuth2 scope values based on IdPAttributes
Henri Mikkonen
henri.mikkonen at iki.fi
Tue Jun 21 09:09:39 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=2e7eb9c58c38a348b08095eeda4327947733b022
The following commit(s) were added to refs/heads/main by this push:
new 2e7eb9c5 JOIDC-6 - Release policy for OAuth2 scope values based on IdPAttributes
2e7eb9c5 is described below
commit 2e7eb9c58c38a348b08095eeda4327947733b022
Author: Henri Mikkonen <henri.mikkonen at iki.fi>
AuthorDate: Tue Jun 21 12:08:52 2022 +0300
JOIDC-6 - Release policy for OAuth2 scope values based on IdPAttributes
https://shibboleth.atlassian.net/browse/JOIDC-6
Included unit tests for ScopeUtil.
---
.../idp/plugin/oidc/op/profile/ScopeUtilTest.java | 353 +++++++++++++++++++++
1 file changed, 353 insertions(+)
diff --git a/idp-oidc-extension-api/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/ScopeUtilTest.java b/idp-oidc-extension-api/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/ScopeUtilTest.java
new file mode 100644
index 00000000..b34914dc
--- /dev/null
+++ b/idp-oidc-extension-api/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/ScopeUtilTest.java
@@ -0,0 +1,353 @@
+/*
+ * 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.profile;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.nimbusds.oauth2.sdk.Scope;
+
+import net.shibboleth.idp.attribute.IdPAttribute;
+import net.shibboleth.idp.attribute.IdPAttributeValue;
+import net.shibboleth.idp.attribute.StringAttributeValue;
+import net.shibboleth.idp.attribute.resolver.ResolutionException;
+import net.shibboleth.idp.attribute.resolver.scripted.ScriptedIdPAttribute;
+
+/**
+ * Unit tests for {@link ScopeUtil}.
+ */
+public class ScopeUtilTest {
+
+ final String id = "mockId";
+
+ @Test
+ public void buildAttribute_nullScopeReturnsEmptyValuesList() {
+ final IdPAttribute attribute = ScopeUtil.buildAttribute(id, null);
+ Assert.assertNotNull(attribute);
+ Assert.assertEquals(attribute.getId(), id);
+ assertStringValues(attribute.getValues());
+ }
+
+ @Test
+ public void buildAttribute_emptyScopeReturnsEmptyValuesList() {
+ final IdPAttribute attribute = ScopeUtil.buildAttribute(id, new Scope());
+ Assert.assertNotNull(attribute);
+ Assert.assertEquals(attribute.getId(), id);
+ assertStringValues(attribute.getValues());
+ }
+
+ @Test
+ public void buildAttribute_shouldParseScopeValues() {
+ final IdPAttribute attribute = ScopeUtil.buildAttribute(id, Scope.parse("openid profile email phone"));
+ Assert.assertNotNull(attribute);
+ Assert.assertEquals(attribute.getId(), id);
+ assertStringValues(attribute.getValues(), "openid", "profile", "email", "phone");
+ }
+
+ @Test
+ public void setAttributeValues_nullScopeLeavesInitialValues() {
+ final IdPAttribute attribute = new IdPAttribute(id);
+ attribute.setValues(List.of(new StringAttributeValue("mock1"), new StringAttributeValue("mock2")));
+ ScopeUtil.setAttributeValues(attribute, null);
+ assertStringValues(attribute.getValues(), "mock1", "mock2");
+ }
+
+ @Test
+ public void setAttributeValues_emptyScopeLeavesInitialValues() {
+ final IdPAttribute attribute = new IdPAttribute(id);
+ attribute.setValues(List.of(new StringAttributeValue("mock1"), new StringAttributeValue("mock2")));
+ ScopeUtil.setAttributeValues(attribute, new Scope());
+ assertStringValues(attribute.getValues(), "mock1", "mock2");
+ }
+
+ @Test
+ public void setAttributeValues_scopeValuesSetToAttribute() {
+ final IdPAttribute attribute = new IdPAttribute(id);
+ attribute.setValues(List.of(new StringAttributeValue("mock1"), new StringAttributeValue("mock2")));
+ ScopeUtil.setAttributeValues(attribute, Scope.parse("openid profile email phone"));
+ assertStringValues(attribute.getValues(), "openid", "profile", "email", "phone");
+ }
+
+ @Test
+ public void populateScriptedAttribute_nullScopeLeavesInitialValues() {
+ final ScriptedIdPAttribute attribute = new MockScriptedIdPAttribute(id, "mock1", "mock2");
+ ScopeUtil.populateScriptedAttribute(attribute, (Scope) null);
+ assertStringValues(attribute, "mock1", "mock2");
+ }
+
+ @Test
+ public void populateScriptedAttribute_emptyScopeLeavesInitialValues() {
+ final ScriptedIdPAttribute attribute = new MockScriptedIdPAttribute(id, "mock1", "mock2");
+ ScopeUtil.populateScriptedAttribute(attribute, new Scope());
+ assertStringValues(attribute, "mock1", "mock2");
+ }
+
+ @Test
+ public void populateScriptedAttribute_scopeValuesAddedToAttribute() {
+ final ScriptedIdPAttribute attribute = new MockScriptedIdPAttribute(id, "mock1", "mock2");
+ ScopeUtil.populateScriptedAttribute(attribute, Scope.parse("openid profile email phone"));
+ assertStringValues(attribute, "mock1", "mock2", "openid", "profile", "email", "phone");
+ }
+
+ @Test
+ public void populateScriptedAttribute_nullSourceLeavesInitialValues() throws ResolutionException {
+ final ScriptedIdPAttribute attribute = new MockScriptedIdPAttribute(id, "mock1", "mock2");
+ ScopeUtil.populateScriptedAttribute(attribute, (ScriptedIdPAttribute) null);
+ assertStringValues(attribute, "mock1", "mock2");
+ }
+
+ @Test
+ public void populateScriptedAttribute_emptySourceLeavesInitialValues() throws ResolutionException {
+ final ScriptedIdPAttribute attribute = new MockScriptedIdPAttribute(id, "mock1", "mock2");
+ ScopeUtil.populateScriptedAttribute(attribute, new MockScriptedIdPAttribute("mockId"));
+ assertStringValues(attribute, "mock1", "mock2");
+ }
+
+ @Test
+ public void populateScriptedAttribute_sourceValuesAddedToAttribute() throws ResolutionException {
+ final ScriptedIdPAttribute attribute = new MockScriptedIdPAttribute(id, "mock1", "mock2");
+ ScopeUtil.populateScriptedAttribute(attribute, new MockScriptedIdPAttribute("mockId", "mock3", "mock4"));
+ assertStringValues(attribute, "mock1", "mock2", "mock3", "mock4");
+ }
+
+ @Test
+ public void buildScope_nullAttributeBuildsEmptyScope() {
+ final Scope scope = ScopeUtil.buildScope((IdPAttribute) null);
+ assertScopeValues(scope);
+ }
+
+ @Test
+ public void buildScope_emptyAttributeBuildsEmptyScope() {
+ final Scope scope = ScopeUtil.buildScope(new IdPAttribute(id));
+ assertScopeValues(scope);
+ }
+
+ @Test
+ public void buildScope_attributeValuesAreCopiedToScope() {
+ final IdPAttribute attribute = new IdPAttribute(id);
+ attribute.setValues(List.of(new StringAttributeValue("openid"), new StringAttributeValue("profile")));
+ final Scope scope = ScopeUtil.buildScope(attribute);
+ assertScopeValues(scope, "openid", "profile");
+ }
+
+ @Test
+ public void buildScope_nullScriptedAttributeBuildsEmptyScope() throws ResolutionException {
+ final Scope scope = ScopeUtil.buildScope((ScriptedIdPAttribute) null);
+ assertScopeValues(scope);
+ }
+
+ @Test
+ public void buildScope_emptyScriptedAttributeBuildsEmptyScope() throws ResolutionException {
+ final Scope scope = ScopeUtil.buildScope(new MockScriptedIdPAttribute(id));
+ assertScopeValues(scope);
+ }
+
+ @Test
+ public void buildScope_attributeScriptedValuesAreCopiedToScope() throws ResolutionException {
+ final ScriptedIdPAttribute attribute = new MockScriptedIdPAttribute(id, "openid", "profile");
+ final Scope scope = ScopeUtil.buildScope(attribute);
+ assertScopeValues(scope, "openid", "profile");
+ }
+
+ @Test
+ public void buildIntersectedScope_IdPAttribute_nullAttributeReturnsEmptyScope() {
+ final Scope scope = ScopeUtil.buildIntersectedScope((IdPAttribute) null, Scope.parse("openid profile"));
+ assertScopeValues(scope);
+ }
+
+ @Test
+ public void buildIntersectedScope_IdPAttribute_EmptyAttributeReturnsEmtpyScope() {
+ final Scope scope = ScopeUtil.buildIntersectedScope(new IdPAttribute(id), Scope.parse("openid profile"));
+ assertScopeValues(scope);
+ }
+
+ @Test
+ public void buildIntersectedScope_IdPAttribute_sameAttributeValuesKeepScope() {
+ final IdPAttribute attribute = new IdPAttribute(id);
+ attribute.setValues(List.of(new StringAttributeValue("openid"), new StringAttributeValue("profile")));
+ final Scope scope = ScopeUtil.buildIntersectedScope(attribute, Scope.parse("openid profile"));
+ assertScopeValues(scope, "openid", "profile");
+ }
+
+ @Test
+ public void buildIntersectedScope_IdPAttribute_sameAttributeValuesKeptInScope() {
+ final IdPAttribute attribute = new IdPAttribute(id);
+ attribute.setValues(List.of(new StringAttributeValue("openid")));
+ final Scope scope = ScopeUtil.buildIntersectedScope(attribute, Scope.parse("openid profile"));
+ assertScopeValues(scope, "openid");
+ }
+
+ @Test
+ public void buildIntersectedScope_IdPAttribute_sameScopeValuesKeptInScope() {
+ final IdPAttribute attribute = new IdPAttribute(id);
+ attribute.setValues(List.of(new StringAttributeValue("openid"), new StringAttributeValue("profile")));
+ final Scope scope = ScopeUtil.buildIntersectedScope(attribute, Scope.parse("openid"));
+ assertScopeValues(scope, "openid");
+ }
+
+ @Test
+ public void buildIntersectedScope_IdPAttribute_nullScopeKeepsAttributeValues() {
+ final IdPAttribute attribute = new IdPAttribute(id);
+ attribute.setValues(List.of(new StringAttributeValue("openid"), new StringAttributeValue("profile")));
+ final Scope scope = ScopeUtil.buildIntersectedScope(attribute, null);
+ assertScopeValues(scope, "openid", "profile");
+ }
+
+ @Test
+ public void buildIntersectedScope_IdPAttribute_EmptyScopeReturnsEmtpyScope() {
+ final IdPAttribute attribute = new IdPAttribute(id);
+ attribute.setValues(List.of(new StringAttributeValue("openid"), new StringAttributeValue("profile")));
+ final Scope scope = ScopeUtil.buildIntersectedScope(attribute, new Scope());
+ assertScopeValues(scope);
+ }
+
+ @Test
+ public void buildIntersectedScope_ScriptedIdPAttribute_nullAttributeReturnsEmptyScope()
+ throws ResolutionException {
+ final Scope scope = ScopeUtil.buildIntersectedScope((ScriptedIdPAttribute)null, Scope.parse("openid profile"));
+ assertScopeValues(scope);
+ }
+
+ @Test
+ public void buildIntersectedScope_ScriptedIdPAttribute_EmptyAttributeReturnsEmtpyScope()
+ throws ResolutionException {
+ final Scope scope = ScopeUtil.buildIntersectedScope(new MockScriptedIdPAttribute(id),
+ Scope.parse("openid profile"));
+ assertScopeValues(scope);
+ }
+
+ @Test
+ public void buildIntersectedScope_ScriptedIdPAttribute_sameAttributeValuesKeepScope()
+ throws ResolutionException {
+ final ScriptedIdPAttribute attribute = new MockScriptedIdPAttribute(id, "openid", "profile");
+ final Scope scope = ScopeUtil.buildIntersectedScope(attribute, Scope.parse("openid profile"));
+ assertScopeValues(scope, "openid", "profile");
+ }
+
+ @Test
+ public void buildIntersectedScope_ScriptedIdPAttribute_sameAttributeValuesKeptInScope()
+ throws ResolutionException {
+ final ScriptedIdPAttribute attribute = new MockScriptedIdPAttribute(id, "openid");
+ final Scope scope = ScopeUtil.buildIntersectedScope(attribute, Scope.parse("openid profile"));
+ assertScopeValues(scope, "openid");
+ }
+
+ @Test
+ public void buildIntersectedScope_ScriptedIdPAttribute_sameScopeValuesKeptInScope() throws ResolutionException {
+ final ScriptedIdPAttribute attribute = new MockScriptedIdPAttribute(id, "openid", "profile");
+ final Scope scope = ScopeUtil.buildIntersectedScope(attribute, Scope.parse("openid"));
+ assertScopeValues(scope, "openid");
+ }
+
+ @Test
+ public void buildIntersectedScope_ScriptedIdPAttribute_nullScopeKeepsAttributeValues() throws ResolutionException {
+ final ScriptedIdPAttribute attribute = new MockScriptedIdPAttribute(id, "openid", "profile");
+ final Scope scope = ScopeUtil.buildIntersectedScope(attribute, null);
+ assertScopeValues(scope, "openid", "profile");
+ }
+
+ @Test
+ public void buildIntersectedScope_ScriptedIdPAttribute_EmptyScopeReturnsEmtpyScope() throws ResolutionException {
+ final ScriptedIdPAttribute attribute = new MockScriptedIdPAttribute(id, "openid", "profile");
+ final Scope scope = ScopeUtil.buildIntersectedScope(attribute, new Scope());
+ assertScopeValues(scope);
+ }
+
+ @Test
+ public void removeValue_existingValueRemoved() {
+ final Scope scope = Scope.parse("openid profile");
+ ScopeUtil.removeValue(scope, "profile");
+ assertScopeValues(scope, "openid");
+ }
+
+ @Test
+ public void removeValue_nonExistingValueKeepsOriginal() {
+ final Scope scope = Scope.parse("openid profile");
+ ScopeUtil.removeValue(scope, "email");
+ assertScopeValues(scope, "openid", "profile");
+ }
+
+ protected void assertStringValues(final List<IdPAttributeValue> values, final String... strings) {
+ Assert.assertNotNull(values);
+ Assert.assertEquals(values.size(), strings.length);
+ final List<String> list = List.of(strings);
+ for (final IdPAttributeValue value : values) {
+ Assert.assertTrue(value instanceof StringAttributeValue);
+ Assert.assertTrue(list.contains(((StringAttributeValue) value).getValue()));
+ }
+ }
+
+ protected void assertStringValues(final ScriptedIdPAttribute attribute, final String... strings) {
+ try {
+ final Collection<Object> values = attribute.getValues();
+ Assert.assertEquals(values.size(), strings.length);
+ final List<String> list = List.of(strings);
+ for (final Object value : values) {
+ Assert.assertTrue(value instanceof String);
+ Assert.assertTrue(list.contains((String) value));
+ }
+ } catch (final ResolutionException e) {
+ Assert.fail();
+ }
+ }
+
+ protected void assertScopeValues(final Scope scope, final String... strings) {
+ Assert.assertNotNull(scope);
+ Assert.assertEquals(scope.size(), strings.length);
+ final List<String> list = List.of(strings);
+ for (final String value : scope.toStringList()) {
+ Assert.assertTrue(list.contains(value));
+ }
+ }
+
+ class MockScriptedIdPAttribute implements ScriptedIdPAttribute {
+
+ private final String id;
+ private final List<Object> values;
+
+ public MockScriptedIdPAttribute(final String attributeId, final Object... objects) {
+ id = attributeId;
+ values = new ArrayList<>(List.of(objects));
+ }
+
+ @Override
+ public Collection<Object> getValues() throws ResolutionException {
+ return values;
+ }
+
+ @Override
+ public IdPAttribute getNativeAttribute() throws ResolutionException {
+ return null;
+ }
+
+ @Override
+ public String getId() {
+ return id;
+ }
+
+ @Override
+ public void addValue(final Object what) throws ResolutionException {
+ values.add(what);
+ }
+
+ }
+}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list