[java-oidc-common] branch main updated: JCOMOIDC-40 - Complete OIDCAttributeTranscoder decode values function
Phil Smart
philip.smart at jisc.ac.uk
Fri Feb 25 14:40:53 UTC 2022
This is an automated email from the git hooks/post-receive script.
philsmart pushed a commit to branch main
in repository java-oidc-common.
View the commit online:
http://git.shibboleth.net/view/?p=java-oidc-common.git;a=commit;h=d4155614eab8baa256c7c860d837d52c833f0692
The following commit(s) were added to refs/heads/main by this push:
new d415561 JCOMOIDC-40 - Complete OIDCAttributeTranscoder decode values function
d415561 is described below
commit d4155614eab8baa256c7c860d837d52c833f0692
Author: Phil Smart <philip.smart at jisc.ac.uk>
AuthorDate: Fri Feb 25 14:40:41 2022 +0000
JCOMOIDC-40 - Complete OIDCAttributeTranscoder decode values function
- Completed (subject to review) the decode method in the String OIDC
attribute transcoder.
- Changed the logic in the Abstract OIDC encoder to pull out the claim
values from the claim object without using the getEncodedName method.
https://shibboleth.atlassian.net/browse/JCOMOIDC-40
---
.../AbstractOIDCAttributeTranscoder.java | 30 +-
.../transcoding/OIDCAttributeTranscoder.java | 9 +
.../impl/OIDCStringAttributeTranscoder.java | 66 ++-
.../impl/OIDCStringAttributeTranscoderTest.java | 478 ++++++++++++++++++++-
4 files changed, 564 insertions(+), 19 deletions(-)
diff --git a/oidc-common-attribute-api/src/main/java/net/shibboleth/oidc/attribute/transcoding/AbstractOIDCAttributeTranscoder.java b/oidc-common-attribute-api/src/main/java/net/shibboleth/oidc/attribute/transcoding/AbstractOIDCAttributeTranscoder.java
index acc7379..c26d4e1 100644
--- a/oidc-common-attribute-api/src/main/java/net/shibboleth/oidc/attribute/transcoding/AbstractOIDCAttributeTranscoder.java
+++ b/oidc-common-attribute-api/src/main/java/net/shibboleth/oidc/attribute/transcoding/AbstractOIDCAttributeTranscoder.java
@@ -17,6 +17,7 @@
package net.shibboleth.oidc.attribute.transcoding;
+import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
@@ -29,7 +30,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Strings;
-import com.nimbusds.openid.connect.sdk.OIDCClaimsRequest;
import com.nimbusds.openid.connect.sdk.claims.ClaimRequirement;
import com.nimbusds.openid.connect.sdk.claims.ClaimsSetRequest;
@@ -55,11 +55,13 @@ public abstract class AbstractOIDCAttributeTranscoder
@Nonnull private final Logger log = LoggerFactory.getLogger(AbstractOIDCAttributeTranscoder.class);
/** {@inheritDoc} */
+ @Override
public Class<JSONObject> getEncodedType() {
return JSONObject.class;
}
/** {@inheritDoc} */
+ @Override
@Nullable public String getEncodedName(@Nonnull final TranscodingRule rule) {
final String name = rule.getOrDefault(PROP_NAME, String.class,
@@ -140,15 +142,24 @@ public abstract class AbstractOIDCAttributeTranscoder
@Nonnull final JSONObject input, @Nonnull final TranscodingRule rule)
throws AttributeDecodingException {
- final String attributeName = getEncodedName(rule);
+ final String attributeName = rule.getOrDefault(PROP_NAME, String.class,
+ rule.get(AttributeTranscoderRegistry.PROP_ID, String.class));
- log.trace("Beginning to decode claim {}", attributeName);
-
- final List<IdPAttributeValue> idpAttributeValues =
- decodeValues(profileRequestContext, input.get(attributeName), rule);
-
- log.trace("Decoded {} values for claim {}", idpAttributeValues.size(), attributeName);
- return buildIdPAttribute(profileRequestContext, input, rule, idpAttributeValues);
+ log.trace("Beginning to decode claim '{}'", attributeName);
+
+ final Object inputToDecode = input.get(attributeName);
+ if (inputToDecode == null) {
+ log.debug("Skipping null value(s) of attribute '{}'", attributeName);
+ } else {
+ final List<IdPAttributeValue> decodedValues = decodeValues(profileRequestContext,inputToDecode, rule);
+ if (decodedValues.isEmpty()) {
+ log.trace("Unable to decode value(s) of attribute '{}'", attributeName);
+ } else {
+ log.trace("Decoded {} value(s) for attribute '{}'", decodedValues.size(), attributeName);
+ return buildIdPAttribute(profileRequestContext, input, rule, decodedValues);
+ }
+ }
+ return buildIdPAttribute(profileRequestContext, input, rule, Collections.emptyList());
}
/**
@@ -212,6 +223,7 @@ public abstract class AbstractOIDCAttributeTranscoder
public static class NamingFunction implements Function<JSONObject,String> {
/** {@inheritDoc} */
+ @Override
@Nullable public String apply(@Nullable final JSONObject input) {
if (input == null) {
diff --git a/oidc-common-attribute-api/src/main/java/net/shibboleth/oidc/attribute/transcoding/OIDCAttributeTranscoder.java b/oidc-common-attribute-api/src/main/java/net/shibboleth/oidc/attribute/transcoding/OIDCAttributeTranscoder.java
index 672d487..1d8c06f 100644
--- a/oidc-common-attribute-api/src/main/java/net/shibboleth/oidc/attribute/transcoding/OIDCAttributeTranscoder.java
+++ b/oidc-common-attribute-api/src/main/java/net/shibboleth/oidc/attribute/transcoding/OIDCAttributeTranscoder.java
@@ -42,5 +42,14 @@ public interface OIDCAttributeTranscoder extends AttributeTranscoder<JSONObject>
/** Separator to use when not encoding multiple values to array. */
@Nonnull @NotEmpty static final String PROP_STRING_DELIMITER = "oidc.stringDelimiter";
+
+ /** Whether to decode JSON Numbers to IdP Attribute Strings. */
+ @Nonnull @NotEmpty static final String PROP_NUMBER_AS_STRING = "oidc.numberAsString";
+
+ /** Whether to decode JSON Booleans to IdP Attribute Strings. */
+ @Nonnull @NotEmpty static final String PROP_BOOLEAN_AS_STRING = "oidc.booleanAsString";
+
+ /** Whether to decode a JSON Array into a serialized JSON string. */
+ @Nonnull @NotEmpty static final String PROP_ARRAY_AS_STRING = "oidc.arrayAsString";
}
\ No newline at end of file
diff --git a/oidc-common-attribute-impl/src/main/java/net/shibboleth/oidc/attribute/transcoding/impl/OIDCStringAttributeTranscoder.java b/oidc-common-attribute-impl/src/main/java/net/shibboleth/oidc/attribute/transcoding/impl/OIDCStringAttributeTranscoder.java
index 47d3fbd..595a249 100644
--- a/oidc-common-attribute-impl/src/main/java/net/shibboleth/oidc/attribute/transcoding/impl/OIDCStringAttributeTranscoder.java
+++ b/oidc-common-attribute-impl/src/main/java/net/shibboleth/oidc/attribute/transcoding/impl/OIDCStringAttributeTranscoder.java
@@ -17,6 +17,7 @@
package net.shibboleth.oidc.attribute.transcoding.impl;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
@@ -33,6 +34,7 @@ import org.slf4j.LoggerFactory;
import com.google.common.base.Predicates;
import net.minidev.json.JSONArray;
+import net.minidev.json.JSONObject;
import net.minidev.json.parser.JSONParser;
import net.minidev.json.parser.ParseException;
import net.shibboleth.idp.attribute.AttributeDecodingException;
@@ -40,6 +42,7 @@ import net.shibboleth.idp.attribute.AttributeEncodingException;
import net.shibboleth.idp.attribute.IdPAttribute;
import net.shibboleth.idp.attribute.IdPAttributeValue;
import net.shibboleth.idp.attribute.StringAttributeValue;
+import net.shibboleth.idp.attribute.transcoding.AttributeTranscoderRegistry;
import net.shibboleth.idp.attribute.transcoding.TranscodingRule;
import net.shibboleth.oidc.attribute.transcoding.AbstractOIDCAttributeTranscoder;
import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElements;
@@ -55,6 +58,24 @@ import net.shibboleth.utilities.java.support.annotation.constraint.Unmodifiable;
* interpreted as boolean the value is true if string value equals to "true" ignoring the case. If boolean values are
* not set to array the first string value is considered to be the result. Finally, the result may be placed to json
* Object.
+ *
+ * <p>For decoding, attempt to convert the input JSON type into a {@link StringAttributeValue} in the following way for
+ * the following JSON types:</p>
+ * <ul>
+ * <li>If a String, convert directly to a string attribute value.</li>
+ * <li>If an Integer or Double (a number type) and PROP_NUMBER_AS_STRING is true, convert to string,
+ * else return an empty values list.</li>
+ * <li>If a Boolean and PROP_BOOLEAN_AS_STRING is true, convert boolean to 'true' or 'false' string,
+ * else return an empty values list.</li>
+ * <li>If a JSON Array and PROP_ARRAY_AS_STRING is true, convert to a string by serializing the array to a
+ * JSON string.</li>
+ * <li>If a JSON Array and PROP_ARRAY_AS_STRING is false, attempt to recursively convert elements of the array
+ * to string attribute values using the same set of rules. If any element fails to convert it will be excluded
+ * from the result.</li>
+ * <li>If a JSON Object and PROP_ASOBJECT is true, convert the object to a string by serializing into JSON. Else,
+ * return an empty values list.</li>
+ * <li>For any other unknown type, return an empty values list.</li>
+ * </ul>
*/
public class OIDCStringAttributeTranscoder extends AbstractOIDCAttributeTranscoder {
@@ -149,10 +170,51 @@ public class OIDCStringAttributeTranscoder extends AbstractOIDCAttributeTranscod
@Nullable final ProfileRequestContext profileRequestContext, @Nonnull final Object input,
@Nonnull final TranscodingRule rule) throws AttributeDecodingException {
- // TODO: implement value decoding
- return Collections.emptyList();
+ // Input could be any JSON data type e.g. String, Number, JSONObject, Array, Boolean.
+
+ if (input instanceof String) {
+ return List.of(StringAttributeValue.valueOf((String)input));
+
+ } else if (input instanceof Integer && rule.getOrDefault(PROP_NUMBER_AS_STRING, Boolean.class, false)) {
+ return List.of(StringAttributeValue.valueOf(Integer.toString((Integer)input)));
+
+ } else if (input instanceof Double && rule.getOrDefault(PROP_NUMBER_AS_STRING, Boolean.class, false)) {
+ return List.of(StringAttributeValue.valueOf(Double.toString((Double)input)));
+
+ } else if (input instanceof Boolean && rule.getOrDefault(PROP_BOOLEAN_AS_STRING, Boolean.class, false)) {
+ return List.of(StringAttributeValue.valueOf(Boolean.toString((Boolean)input)));
+
+ } else if (input instanceof JSONArray) {
+ if (rule.getOrDefault(PROP_ARRAY_AS_STRING, Boolean.class, false)) {
+ // Serialize JSON Array to JSON string
+ return List.of(StringAttributeValue.valueOf(((JSONArray)input).toJSONString()));
+ } else {
+ // Deal with array recursively, if any nested element can not be converted to a string
+ // the entire attribute will fail to be decoded.
+ final JSONArray array = (JSONArray)input;
+ final List<IdPAttributeValue> arrayValuesDecoded = new ArrayList<>();
+ for (final Object element : array) {
+ arrayValuesDecoded.addAll(decodeValues(profileRequestContext, element, rule));
+ }
+ return arrayValuesDecoded;
+ }
+
+ } else if (input instanceof JSONObject && rule.getOrDefault(PROP_ASOBJECT, Boolean.class, false)) {
+ // Serialize JSONObject to a JSON string.
+ return List.of(StringAttributeValue.valueOf(((JSONObject)input).toJSONString()));
+
+ } else {
+ log.trace("Could not convert values of type {} for the claim '{}' to a string attribute using "
+ + "transcoding rule '{} -> {}'",
+ input.getClass().getName(), input, rule.getOrDefault(PROP_NAME, String.class, "unknown"),
+ rule.getOrDefault(AttributeTranscoderRegistry.PROP_ID, String.class, "unknown"));
+
+ return Collections.emptyList();
+ }
+
}
+
/**
* Parses string as JSONObject.
*
diff --git a/oidc-common-attribute-impl/src/test/java/net/shibboleth/oidc/attribute/transcoding/impl/OIDCStringAttributeTranscoderTest.java b/oidc-common-attribute-impl/src/test/java/net/shibboleth/oidc/attribute/transcoding/impl/OIDCStringAttributeTranscoderTest.java
index 00c78cb..0d77420 100644
--- a/oidc-common-attribute-impl/src/test/java/net/shibboleth/oidc/attribute/transcoding/impl/OIDCStringAttributeTranscoderTest.java
+++ b/oidc-common-attribute-impl/src/test/java/net/shibboleth/oidc/attribute/transcoding/impl/OIDCStringAttributeTranscoderTest.java
@@ -24,20 +24,22 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.nimbusds.openid.connect.sdk.claims.ClaimsSetRequest;
+
import net.minidev.json.JSONArray;
import net.minidev.json.JSONObject;
import net.shibboleth.ext.spring.testing.MockApplicationContext;
+import net.shibboleth.idp.attribute.AttributeDecodingException;
import net.shibboleth.idp.attribute.AttributeEncodingException;
import net.shibboleth.idp.attribute.ByteAttributeValue;
import net.shibboleth.idp.attribute.IdPAttribute;
import net.shibboleth.idp.attribute.IdPAttributeValue;
-import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
-
-import org.testng.Assert;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
+import net.shibboleth.idp.attribute.IdPRequestedAttribute;
import net.shibboleth.idp.attribute.StringAttributeValue;
import net.shibboleth.idp.attribute.transcoding.AttributeTranscoderRegistry;
import net.shibboleth.idp.attribute.transcoding.BasicNamingFunction;
@@ -46,7 +48,7 @@ import net.shibboleth.idp.attribute.transcoding.TranscodingRule;
import net.shibboleth.idp.attribute.transcoding.impl.AttributeTranscoderRegistryImpl;
import net.shibboleth.oidc.attribute.transcoding.AbstractOIDCAttributeTranscoder;
import net.shibboleth.oidc.attribute.transcoding.OIDCAttributeTranscoder;
-import net.shibboleth.oidc.attribute.transcoding.impl.OIDCStringAttributeTranscoder;
+import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
public class OIDCStringAttributeTranscoderTest {
@@ -253,5 +255,465 @@ public class OIDCStringAttributeTranscoderTest {
TranscoderSupport.<JSONObject>getTranscoder(tr).encode(null, inputAttribute, JSONObject.class, tr);
}
+
+ @Test
+ public void testDecodingString() throws ComponentInitializationException, AttributeDecodingException {
+
+ registry.setTranscoderRegistry(Collections.singletonList(new TranscodingRule(ruleset)));
+ registry.setApplicationContext(new MockApplicationContext());
+ registry.initialize();
+
+ // Map from oidc claim.name 'bar' to shib attribute id 'foo'.
+ final JSONObject inputAttribute = new JSONObject();
+ inputAttribute.put(ATTR_NAME, "The bar value");
+
+ final Collection<TranscodingRule> rulesets = registry.getTranscodingRules(inputAttribute);
+ Assert.assertEquals(rulesets.size(), 1);
+ final TranscodingRule tr = rulesets.iterator().next();
+
+ final IdPAttribute decodedAttribute = TranscoderSupport.<JSONObject>getTranscoder(tr)
+ .decode(null, inputAttribute, tr);
+
+ Assert.assertNotNull(decodedAttribute);
+ Assert.assertEquals(decodedAttribute.getId(), ATTR_ID);
+ Assert.assertEquals(decodedAttribute.getValues().size(), 1);
+ Assert.assertNotNull(decodedAttribute.getValues().get(0).getNativeValue());
+ Assert.assertEquals(decodedAttribute.getValues().get(0).getNativeValue(), "The bar value");
+ }
+
+ @Test
+ public void testDecodingNoValues() throws ComponentInitializationException, AttributeDecodingException {
+
+ registry.setTranscoderRegistry(Collections.singletonList(new TranscodingRule(ruleset)));
+ registry.setApplicationContext(new MockApplicationContext());
+ registry.initialize();
+
+ // Map from oidc claim.name 'bar' to shib attribute id 'foo'.
+ final JSONObject inputAttribute = new JSONObject();
+ inputAttribute.put(ATTR_NAME, null);
+
+ final Collection<TranscodingRule> rulesets = registry.getTranscodingRules(inputAttribute);
+ Assert.assertEquals(rulesets.size(), 1);
+ final TranscodingRule tr = rulesets.iterator().next();
+
+ final IdPAttribute decodedAttribute = TranscoderSupport.<JSONObject>getTranscoder(tr)
+ .decode(null, inputAttribute, tr);
+
+ Assert.assertNotNull(decodedAttribute);
+ Assert.assertEquals(decodedAttribute.getId(), ATTR_ID);
+ Assert.assertEquals(decodedAttribute.getValues().size(), 0);
+ }
+
+ /* Specifically test the ClaimsSetRequested type for the OP's SetRequiredClaimsToResponseContext.*/
+ @Test
+ public void testDecodingWrongType_ClaimsRequest() throws ComponentInitializationException, AttributeDecodingException {
+
+ registry.setTranscoderRegistry(Collections.singletonList(new TranscodingRule(ruleset)));
+ registry.setApplicationContext(new MockApplicationContext());
+ registry.initialize();
+
+
+ final ClaimsSetRequest.Entry entry = new ClaimsSetRequest.Entry("test");
+ // Map from oidc claim.name 'bar' to shib attribute id 'foo'.
+ final JSONObject inputAttribute = new JSONObject();
+ inputAttribute.put(ATTR_NAME, entry);
+
+ final Collection<TranscodingRule> rulesets = registry.getTranscodingRules(inputAttribute);
+ Assert.assertEquals(rulesets.size(), 1);
+ final TranscodingRule tr = rulesets.iterator().next();
+
+ final IdPAttribute decodedAttribute = TranscoderSupport.<JSONObject>getTranscoder(tr)
+ .decode(null, inputAttribute, tr);
+
+ Assert.assertNotNull(decodedAttribute);
+ Assert.assertTrue(decodedAttribute instanceof IdPRequestedAttribute);
+ Assert.assertEquals(decodedAttribute.getId(), ATTR_ID);
+ Assert.assertEquals(decodedAttribute.getValues().size(), 0);
+
+ }
+
+ @Test
+ public void testDecodingStringArray() throws ComponentInitializationException, AttributeDecodingException {
+
+ registry.setTranscoderRegistry(Collections.singletonList(new TranscodingRule(ruleset)));
+ registry.setApplicationContext(new MockApplicationContext());
+ registry.initialize();
+
+ // Map from oidc claim.name 'bar' to shib attribute id 'foo'.
+ final JSONObject inputAttribute = new JSONObject();
+ final JSONArray array = new JSONArray();
+ array.add("First");
+ array.add("Second");
+ inputAttribute.put(ATTR_NAME, array);
+
+ final Collection<TranscodingRule> rulesets = registry.getTranscodingRules(inputAttribute);
+ Assert.assertEquals(rulesets.size(), 1);
+ final TranscodingRule tr = rulesets.iterator().next();
+
+ final IdPAttribute decodedAttribute = TranscoderSupport.<JSONObject>getTranscoder(tr)
+ .decode(null, inputAttribute, tr);
+
+ Assert.assertNotNull(decodedAttribute);
+ Assert.assertEquals(decodedAttribute.getId(), ATTR_ID);
+ Assert.assertEquals(decodedAttribute.getValues().size(), 2);
+ Assert.assertEquals(decodedAttribute.getValues().get(0).getNativeValue(), "First");
+ Assert.assertEquals(decodedAttribute.getValues().get(1).getNativeValue(), "Second");
+ }
+
+ @Test
+ public void testDecodingStringArrayAsString() throws ComponentInitializationException, AttributeDecodingException {
+
+ ruleset.put(OIDCStringAttributeTranscoder.PROP_ARRAY_AS_STRING, true);
+
+ registry.setTranscoderRegistry(Collections.singletonList(new TranscodingRule(ruleset)));
+ registry.setApplicationContext(new MockApplicationContext());
+ registry.initialize();
+
+ // Map from oidc claim.name 'bar' to shib attribute id 'foo'.
+ final JSONObject inputAttribute = new JSONObject();
+ final JSONArray array = new JSONArray();
+ array.add("First");
+ array.add("Second");
+ inputAttribute.put(ATTR_NAME, array);
+
+ final Collection<TranscodingRule> rulesets = registry.getTranscodingRules(inputAttribute);
+ Assert.assertEquals(rulesets.size(), 1);
+ final TranscodingRule tr = rulesets.iterator().next();
+
+ final IdPAttribute decodedAttribute = TranscoderSupport.<JSONObject>getTranscoder(tr)
+ .decode(null, inputAttribute, tr);
+
+ Assert.assertNotNull(decodedAttribute);
+ Assert.assertEquals(decodedAttribute.getId(), ATTR_ID);
+ Assert.assertEquals(decodedAttribute.getValues().size(), 1);
+ Assert.assertEquals(decodedAttribute.getValues().get(0).getNativeValue(), "[\"First\",\"Second\"]");
+ }
+
+ @Test
+ public void testDecodingComplexArray() throws ComponentInitializationException, AttributeDecodingException {
+
+ // Convert all types below to strings
+ ruleset.put(OIDCStringAttributeTranscoder.PROP_ASOBJECT, true);
+ ruleset.put(OIDCStringAttributeTranscoder.PROP_NUMBER_AS_STRING, true);
+ ruleset.put(OIDCStringAttributeTranscoder.PROP_BOOLEAN_AS_STRING, true);
+
+ registry.setTranscoderRegistry(Collections.singletonList(new TranscodingRule(ruleset)));
+ registry.setApplicationContext(new MockApplicationContext());
+ registry.initialize();
+
+ // Map from oidc claim.name 'bar' to shib attribute id 'foo'.
+ final JSONObject inputAttribute = new JSONObject();
+ final JSONArray firstArray = new JSONArray();
+ firstArray.add("First");
+
+ final JSONArray secondArray = new JSONArray();
+ secondArray.add("Second");
+ secondArray.add(true);
+ secondArray.add(1);
+
+ firstArray.add(secondArray);
+
+ final JSONArray thirdArray = new JSONArray();
+ thirdArray.add(3.14);
+
+ final JSONObject nestedObject = new JSONObject();
+ nestedObject.put("name","John");
+ nestedObject.put("age","30");
+
+ thirdArray.add(nestedObject);
+ secondArray.add(thirdArray);
+
+ inputAttribute.put(ATTR_NAME, firstArray);
+
+ final Collection<TranscodingRule> rulesets = registry.getTranscodingRules(inputAttribute);
+ Assert.assertEquals(rulesets.size(), 1);
+ final TranscodingRule tr = rulesets.iterator().next();
+
+ final IdPAttribute decodedAttribute = TranscoderSupport.<JSONObject>getTranscoder(tr)
+ .decode(null, inputAttribute, tr);
+
+ Assert.assertNotNull(decodedAttribute);
+ Assert.assertEquals(decodedAttribute.getId(), ATTR_ID);
+ Assert.assertEquals(decodedAttribute.getValues().size(), 6);
+ Assert.assertEquals(decodedAttribute.getValues().get(0).getNativeValue(), "First");
+ Assert.assertEquals(decodedAttribute.getValues().get(1).getNativeValue(), "Second");
+ Assert.assertEquals(decodedAttribute.getValues().get(2).getNativeValue(), "true");
+ Assert.assertEquals(decodedAttribute.getValues().get(3).getNativeValue(), "1");
+ Assert.assertEquals(decodedAttribute.getValues().get(4).getNativeValue(), "3.14");
+ Assert.assertEquals(decodedAttribute.getValues().get(5).getNativeValue(), "{\"name\":\"John\",\"age\":\"30\"}");
+ }
+
+ @Test
+ public void testDecodingComplexArray_NumberNotSupported()
+ throws ComponentInitializationException, AttributeDecodingException {
+
+ // Do not convert numbers to string, any in the input will trigger an exception
+ ruleset.put(OIDCStringAttributeTranscoder.PROP_ASOBJECT, true);
+ // Do not convert numbers
+ ruleset.put(OIDCStringAttributeTranscoder.PROP_NUMBER_AS_STRING, false);
+ // convert boolean
+ ruleset.put(OIDCStringAttributeTranscoder.PROP_BOOLEAN_AS_STRING, true);
+
+ registry.setTranscoderRegistry(Collections.singletonList(new TranscodingRule(ruleset)));
+ registry.setApplicationContext(new MockApplicationContext());
+ registry.initialize();
+
+ // Map from oidc claim.name 'bar' to shib attribute id 'foo'.
+ final JSONObject inputAttribute = new JSONObject();
+ final JSONArray firstArray = new JSONArray();
+ firstArray.add("First");
+
+ final JSONArray secondArray = new JSONArray();
+ secondArray.add("Second");
+ secondArray.add(true);
+ secondArray.add(1);
+
+ firstArray.add(secondArray);
+
+ final JSONArray thirdArray = new JSONArray();
+ thirdArray.add(3.14);
+
+ final JSONObject nestedObject = new JSONObject();
+ nestedObject.put("name","John");
+ nestedObject.put("age","30");
+
+ thirdArray.add(nestedObject);
+ secondArray.add(thirdArray);
+
+ inputAttribute.put(ATTR_NAME, firstArray);
+
+ final Collection<TranscodingRule> rulesets = registry.getTranscodingRules(inputAttribute);
+ Assert.assertEquals(rulesets.size(), 1);
+ final TranscodingRule tr = rulesets.iterator().next();
+
+ final IdPAttribute decodedAttribute = TranscoderSupport.<JSONObject>getTranscoder(tr)
+ .decode(null, inputAttribute, tr);
+
+ Assert.assertNotNull(decodedAttribute);
+ Assert.assertEquals(decodedAttribute.getId(), ATTR_ID);
+ Assert.assertEquals(decodedAttribute.getValues().size(), 4);
+ Assert.assertEquals(decodedAttribute.getValues().get(0).getNativeValue(), "First");
+ Assert.assertEquals(decodedAttribute.getValues().get(1).getNativeValue(), "Second");
+ Assert.assertEquals(decodedAttribute.getValues().get(2).getNativeValue(), "true");
+ Assert.assertEquals(decodedAttribute.getValues().get(3).getNativeValue(), "{\"name\":\"John\",\"age\":\"30\"}");
+ }
+
+ @Test
+ public void testDecodingInteger() throws ComponentInitializationException, AttributeDecodingException {
+
+ ruleset.put(OIDCStringAttributeTranscoder.PROP_NUMBER_AS_STRING, true);
+
+ registry.setTranscoderRegistry(Collections.singletonList(new TranscodingRule(ruleset)));
+ registry.setApplicationContext(new MockApplicationContext());
+ registry.initialize();
+
+ // Map from oidc claim.name 'bar' to shib attribute id 'foo'.
+ final JSONObject inputAttribute = new JSONObject();
+ inputAttribute.put(ATTR_NAME, 1);
+
+ final Collection<TranscodingRule> rulesets = registry.getTranscodingRules(inputAttribute);
+ Assert.assertEquals(rulesets.size(), 1);
+ final TranscodingRule tr = rulesets.iterator().next();
+
+ final IdPAttribute decodedAttribute = TranscoderSupport.<JSONObject>getTranscoder(tr)
+ .decode(null, inputAttribute, tr);
+
+ Assert.assertNotNull(decodedAttribute);
+ Assert.assertEquals(decodedAttribute.getId(), ATTR_ID);
+ Assert.assertEquals(decodedAttribute.getValues().size(), 1);
+ Assert.assertNotNull(decodedAttribute.getValues().get(0).getNativeValue());
+ Assert.assertEquals(decodedAttribute.getValues().get(0).getNativeValue(), "1");
+ }
+
+ @Test
+ public void testDecodingInteger_NotSupported() throws ComponentInitializationException, AttributeDecodingException {
+
+ ruleset.put(OIDCStringAttributeTranscoder.PROP_NUMBER_AS_STRING, false);
+
+ registry.setTranscoderRegistry(Collections.singletonList(new TranscodingRule(ruleset)));
+ registry.setApplicationContext(new MockApplicationContext());
+ registry.initialize();
+
+ // Map from oidc claim.name 'bar' to shib attribute id 'foo'.
+ final JSONObject inputAttribute = new JSONObject();
+ inputAttribute.put(ATTR_NAME, 1);
+
+ final Collection<TranscodingRule> rulesets = registry.getTranscodingRules(inputAttribute);
+ Assert.assertEquals(rulesets.size(), 1);
+ final TranscodingRule tr = rulesets.iterator().next();
+
+ final IdPAttribute decodedAttribute = TranscoderSupport.<JSONObject>getTranscoder(tr)
+ .decode(null, inputAttribute, tr);
+
+ Assert.assertNotNull(decodedAttribute);
+ Assert.assertEquals(decodedAttribute.getId(), ATTR_ID);
+ Assert.assertEquals(decodedAttribute.getValues().size(), 0);
+ }
+
+ @Test
+ public void testDecodingDouble() throws ComponentInitializationException, AttributeDecodingException {
+
+ ruleset.put(OIDCStringAttributeTranscoder.PROP_NUMBER_AS_STRING, true);
+
+ registry.setTranscoderRegistry(Collections.singletonList(new TranscodingRule(ruleset)));
+ registry.setApplicationContext(new MockApplicationContext());
+ registry.initialize();
+
+ // Map from oidc claim.name 'bar' to shib attribute id 'foo'.
+ final JSONObject inputAttribute = new JSONObject();
+ inputAttribute.put(ATTR_NAME, 3.14);
+
+ final Collection<TranscodingRule> rulesets = registry.getTranscodingRules(inputAttribute);
+ Assert.assertEquals(rulesets.size(), 1);
+ final TranscodingRule tr = rulesets.iterator().next();
+
+ final IdPAttribute decodedAttribute = TranscoderSupport.<JSONObject>getTranscoder(tr)
+ .decode(null, inputAttribute, tr);
+
+ Assert.assertNotNull(decodedAttribute);
+ Assert.assertEquals(decodedAttribute.getId(), ATTR_ID);
+ Assert.assertEquals(decodedAttribute.getValues().size(), 1);
+ Assert.assertNotNull(decodedAttribute.getValues().get(0).getNativeValue());
+ Assert.assertEquals(decodedAttribute.getValues().get(0).getNativeValue(), "3.14");
+ }
+
+
+ @Test
+ public void testDecodingBoolean() throws ComponentInitializationException, AttributeDecodingException {
+
+ ruleset.put(OIDCStringAttributeTranscoder.PROP_BOOLEAN_AS_STRING, true);
+
+ registry.setTranscoderRegistry(Collections.singletonList(new TranscodingRule(ruleset)));
+ registry.setApplicationContext(new MockApplicationContext());
+ registry.initialize();
+
+ // Map from oidc claim.name 'bar' to shib attribute id 'foo'.
+ final JSONObject inputAttribute = new JSONObject();
+ inputAttribute.put(ATTR_NAME, true);
+
+ final Collection<TranscodingRule> rulesets = registry.getTranscodingRules(inputAttribute);
+ Assert.assertEquals(rulesets.size(), 1);
+ final TranscodingRule tr = rulesets.iterator().next();
+
+ final IdPAttribute decodedAttribute = TranscoderSupport.<JSONObject>getTranscoder(tr)
+ .decode(null, inputAttribute, tr);
+
+ Assert.assertNotNull(decodedAttribute);
+ Assert.assertEquals(decodedAttribute.getId(), ATTR_ID);
+ Assert.assertEquals(decodedAttribute.getValues().size(), 1);
+ Assert.assertNotNull(decodedAttribute.getValues().get(0).getNativeValue());
+ Assert.assertEquals(decodedAttribute.getValues().get(0).getNativeValue(), "true");
+ }
+
+ @Test
+ public void testDecodingBoolean_NotSupported()
+ throws ComponentInitializationException, AttributeDecodingException {
+
+ ruleset.put(OIDCStringAttributeTranscoder.PROP_BOOLEAN_AS_STRING, false);
+
+ registry.setTranscoderRegistry(Collections.singletonList(new TranscodingRule(ruleset)));
+ registry.setApplicationContext(new MockApplicationContext());
+ registry.initialize();
+
+ // Map from oidc claim.name 'bar' to shib attribute id 'foo'.
+ final JSONObject inputAttribute = new JSONObject();
+ inputAttribute.put(ATTR_NAME, true);
+
+ final Collection<TranscodingRule> rulesets = registry.getTranscodingRules(inputAttribute);
+ Assert.assertEquals(rulesets.size(), 1);
+ final TranscodingRule tr = rulesets.iterator().next();
+
+ final IdPAttribute decodedAttribute = TranscoderSupport.<JSONObject>getTranscoder(tr)
+ .decode(null, inputAttribute, tr);
+
+ Assert.assertNotNull(decodedAttribute);
+ Assert.assertEquals(decodedAttribute.getId(), ATTR_ID);
+ Assert.assertEquals(decodedAttribute.getValues().size(), 0);
+ }
+
+ @Test
+ public void testDecodingJSONObject() throws ComponentInitializationException, AttributeDecodingException {
+
+ ruleset.put(OIDCStringAttributeTranscoder.PROP_ASOBJECT, true);
+
+ registry.setTranscoderRegistry(Collections.singletonList(new TranscodingRule(ruleset)));
+ registry.setApplicationContext(new MockApplicationContext());
+ registry.initialize();
+
+ // Map from oidc claim.name 'bar' to shib attribute id 'foo'.
+ final JSONObject inputAttribute = new JSONObject();
+ final JSONObject nested = new JSONObject();
+ nested.put("name","John");
+ nested.put("age","30");
+ inputAttribute.put(ATTR_NAME, nested);
+
+ final Collection<TranscodingRule> rulesets = registry.getTranscodingRules(inputAttribute);
+ Assert.assertEquals(rulesets.size(), 1);
+ final TranscodingRule tr = rulesets.iterator().next();
+
+ final IdPAttribute decodedAttribute = TranscoderSupport.<JSONObject>getTranscoder(tr)
+ .decode(null, inputAttribute, tr);
+
+ Assert.assertNotNull(decodedAttribute);
+ Assert.assertEquals(decodedAttribute.getId(), ATTR_ID);
+ Assert.assertEquals(decodedAttribute.getValues().size(), 1);
+ Assert.assertNotNull(decodedAttribute.getValues().get(0).getNativeValue());
+ Assert.assertEquals(decodedAttribute.getValues().get(0)
+ .getNativeValue(), "{\"name\":\"John\",\"age\":\"30\"}");
+ }
+
+ @Test
+ public void testDecodingJSONObjectDisabledByRule() throws ComponentInitializationException, AttributeDecodingException {
+
+
+ ruleset.put(OIDCStringAttributeTranscoder.PROP_ASOBJECT, false);
+
+ registry.setTranscoderRegistry(Collections.singletonList(new TranscodingRule(ruleset)));
+ registry.setApplicationContext(new MockApplicationContext());
+ registry.initialize();
+
+ // Map from oidc claim.name 'bar' to shib attribute id 'foo'.
+ final JSONObject inputAttribute = new JSONObject();
+ final JSONObject nested = new JSONObject();
+ nested.put("name","John");
+ nested.put("age","30");
+ inputAttribute.put(ATTR_NAME, nested);
+
+ final Collection<TranscodingRule> rulesets = registry.getTranscodingRules(inputAttribute);
+ Assert.assertEquals(rulesets.size(), 1);
+ final TranscodingRule tr = rulesets.iterator().next();
+
+ final IdPAttribute decodedAttribute = TranscoderSupport.<JSONObject>getTranscoder(tr)
+ .decode(null, inputAttribute, tr);
+
+ Assert.assertNotNull(decodedAttribute);
+ Assert.assertEquals(decodedAttribute.getId(), ATTR_ID);
+ Assert.assertEquals(decodedAttribute.getValues().size(), 0);
+
+ }
+
+ @Test
+ public void testDecodingWrongType() throws ComponentInitializationException, AttributeDecodingException {
+
+ registry.setTranscoderRegistry(Collections.singletonList(new TranscodingRule(ruleset)));
+ registry.setApplicationContext(new MockApplicationContext());
+ registry.initialize();
+
+ // Map from oidc claim.name 'bar' to shib attribute id 'foo'.
+ final JSONObject inputAttribute = new JSONObject();
+ inputAttribute.put(ATTR_NAME, new byte[1]);
+
+ final Collection<TranscodingRule> rulesets = registry.getTranscodingRules(inputAttribute);
+ Assert.assertEquals(rulesets.size(), 1);
+ final TranscodingRule tr = rulesets.iterator().next();
+
+ final IdPAttribute decodedAttribute = TranscoderSupport.<JSONObject>getTranscoder(tr)
+ .decode(null, inputAttribute, tr);
+
+ Assert.assertNotNull(decodedAttribute);
+ Assert.assertEquals(decodedAttribute.getId(), ATTR_ID);
+ Assert.assertEquals(decodedAttribute.getValues().size(), 0);
+
+ }
}
\ 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