[java-identity-provider] 03/04: IdP-1206 Resolver Config: Optional filtering of null values after resolution
Rod Widdowson
rdw at steadingsoftware.com
Tue Apr 17 11:14:35 EDT 2018
This is an automated email from the git hooks/post-receive script.
rdw pushed a commit to branch master
in repository java-identity-provider.
View the commit online:
http://git.shibboleth.net/view/?p=java-identity-provider.git;a=commit;h=bd719f4ddaaaadb516567f58e8dd5f8763345144
commit bd719f4ddaaaadb516567f58e8dd5f8763345144
Author: Rod Widdowson <rdw at steadingsoftware.com>
AuthorDate: Tue Apr 17 14:25:28 2018 +0100
IdP-1206 Resolver Config: Optional filtering of null values after resolution
https://issues.shibboleth.net/jira/browse/IDP-1206
Make the AttributeResolverServiceStrategy configurable as whether to strip
nulls from the output of the service.
---
.../impl/AttributeResolverServiceStrategy.java | 31 +++++--
.../resolver/spring/AttributeResolverTest.java | 101 ++++++++++++---------
.../spring/dc/StaticDataConnectorParserTest.java | 8 +-
.../resolver/spring/dc/staticAttributesNative.xml | 5 +-
.../attribute/resolver/spring/serviceNullStrip.xml | 51 +++++++++++
5 files changed, 144 insertions(+), 52 deletions(-)
diff --git a/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/impl/AttributeResolverServiceStrategy.java b/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/impl/AttributeResolverServiceStrategy.java
index ed42783..9ea9af3 100644
--- a/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/impl/AttributeResolverServiceStrategy.java
+++ b/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/impl/AttributeResolverServiceStrategy.java
@@ -22,6 +22,12 @@ import java.util.Collection;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.ApplicationContext;
+
+import com.google.common.base.Function;
+
import net.shibboleth.idp.attribute.resolver.AttributeDefinition;
import net.shibboleth.idp.attribute.resolver.AttributeResolver;
import net.shibboleth.idp.attribute.resolver.DataConnector;
@@ -33,12 +39,6 @@ import net.shibboleth.utilities.java.support.component.ComponentInitializationEx
import net.shibboleth.utilities.java.support.service.ServiceException;
import net.shibboleth.utilities.java.support.service.ServiceableComponent;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.context.ApplicationContext;
-
-import com.google.common.base.Function;
-
/**
* Strategy for summoning up an {@link AttributeResolverImpl} from a populated {@link ApplicationContext}. We do this by
* finding all the configured {@link AttributeDefinition}, {@link DataConnector} and {@link PrincipalConnector} beans
@@ -49,6 +49,24 @@ public class AttributeResolverServiceStrategy extends AbstractIdentifiableInitia
/** Class logger. */
@Nonnull private final Logger log = LoggerFactory.getLogger(AttributeResolverServiceStrategy.class);
+
+ /** Whether to strip null attribute values. */
+ private boolean stripNulls;
+
+ /** Do we strip nulls from attribute values.
+ * @return Returns whether to strip nulls from attribute values
+ */
+ public boolean isStripNulls() {
+ return stripNulls;
+ }
+
+ /**
+ * Sets whether to strip nulls from attribute values.
+ * @param doStripNulls what to set
+ */
+ public void setStripNulls(final Boolean doStripNulls) {
+ stripNulls = doStripNulls;
+ }
/** {@inheritDoc} */
@Override @Nullable public ServiceableComponent<AttributeResolver> apply(
@@ -71,6 +89,7 @@ public class AttributeResolverServiceStrategy extends AbstractIdentifiableInitia
resolver.setDataConnectors(connectors);
resolver.setPrincipalDecoder(pcc);
resolver.setId(getId());
+ resolver.setStripNulls(isStripNulls());
resolver.setApplicationContext(appContext);
try {
diff --git a/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/AttributeResolverTest.java b/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/AttributeResolverTest.java
index 050107d..4b56df1 100644
--- a/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/AttributeResolverTest.java
+++ b/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/AttributeResolverTest.java
@@ -24,25 +24,6 @@ import javax.annotation.Nullable;
import javax.security.auth.Subject;
import javax.sql.DataSource;
-import net.shibboleth.ext.spring.config.IdentifiableBeanPostProcessor;
-import net.shibboleth.ext.spring.util.SchemaTypeAwareXMLBeanDefinitionReader;
-import net.shibboleth.idp.attribute.IdPAttribute;
-import net.shibboleth.idp.attribute.IdPAttributeValue;
-import net.shibboleth.idp.attribute.StringAttributeValue;
-import net.shibboleth.idp.attribute.resolver.AttributeResolver;
-import net.shibboleth.idp.attribute.resolver.LegacyPrincipalDecoder;
-import net.shibboleth.idp.attribute.resolver.ResolutionException;
-import net.shibboleth.idp.attribute.resolver.context.AttributeResolutionContext;
-import net.shibboleth.idp.authn.context.SubjectCanonicalizationContext;
-import net.shibboleth.idp.saml.authn.principal.NameIDPrincipal;
-import net.shibboleth.idp.saml.impl.TestSources;
-import net.shibboleth.idp.testing.DatabaseTestingSupport;
-import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
-import net.shibboleth.utilities.java.support.logic.Constraint;
-import net.shibboleth.utilities.java.support.service.ReloadableService;
-import net.shibboleth.utilities.java.support.service.ServiceException;
-import net.shibboleth.utilities.java.support.service.ServiceableComponent;
-
import org.opensaml.core.OpenSAMLInitBaseTestCase;
import org.opensaml.profile.context.ProfileRequestContext;
import org.opensaml.saml.saml2.core.NameID;
@@ -64,6 +45,25 @@ import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig;
import com.unboundid.ldap.listener.InMemoryListenerConfig;
import com.unboundid.ldap.sdk.LDAPException;
+import net.shibboleth.ext.spring.config.IdentifiableBeanPostProcessor;
+import net.shibboleth.ext.spring.util.SchemaTypeAwareXMLBeanDefinitionReader;
+import net.shibboleth.idp.attribute.IdPAttribute;
+import net.shibboleth.idp.attribute.IdPAttributeValue;
+import net.shibboleth.idp.attribute.StringAttributeValue;
+import net.shibboleth.idp.attribute.resolver.AttributeResolver;
+import net.shibboleth.idp.attribute.resolver.LegacyPrincipalDecoder;
+import net.shibboleth.idp.attribute.resolver.ResolutionException;
+import net.shibboleth.idp.attribute.resolver.context.AttributeResolutionContext;
+import net.shibboleth.idp.authn.context.SubjectCanonicalizationContext;
+import net.shibboleth.idp.saml.authn.principal.NameIDPrincipal;
+import net.shibboleth.idp.saml.impl.TestSources;
+import net.shibboleth.idp.testing.DatabaseTestingSupport;
+import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
+import net.shibboleth.utilities.java.support.logic.Constraint;
+import net.shibboleth.utilities.java.support.service.ReloadableService;
+import net.shibboleth.utilities.java.support.service.ServiceException;
+import net.shibboleth.utilities.java.support.service.ServiceableComponent;
+
/** A work in progress to test the attribute resolver service. */
public class AttributeResolverTest extends OpenSAMLInitBaseTestCase {
@@ -95,7 +95,7 @@ public class AttributeResolverTest extends OpenSAMLInitBaseTestCase {
pendingTeardownContext = null;
}
- protected void setTestContext(GenericApplicationContext context) {
+ protected void setTestContext(final GenericApplicationContext context) {
tearDownTestContext();
pendingTeardownContext = context;
}
@@ -103,7 +103,7 @@ public class AttributeResolverTest extends OpenSAMLInitBaseTestCase {
@BeforeTest public void setupDataConnectors() throws LDAPException {
// LDAP
- InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig("dc=shibboleth,dc=net");
+ final InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig("dc=shibboleth,dc=net");
config.setListenerConfigs(InMemoryListenerConfig.createLDAPConfig("default", 10391));
config.addAdditionalBindCredentials("cn=Directory Manager", "password");
directoryServer = new InMemoryDirectoryServer(config);
@@ -123,13 +123,13 @@ public class AttributeResolverTest extends OpenSAMLInitBaseTestCase {
directoryServer.shutDown(true);
}
- private ReloadableService<AttributeResolver> getResolver(String file) {
- GenericApplicationContext context = new GenericApplicationContext();
+ private ReloadableService<AttributeResolver> getResolver(final String file) {
+ final GenericApplicationContext context = new GenericApplicationContext();
context.getBeanFactory().addBeanPostProcessor(new IdentifiableBeanPostProcessor());
setTestContext(context);
context.setDisplayName("ApplicationContext: " + AttributeResolverTest.class);
- SchemaTypeAwareXMLBeanDefinitionReader beanDefinitionReader =
+ final SchemaTypeAwareXMLBeanDefinitionReader beanDefinitionReader =
new SchemaTypeAwareXMLBeanDefinitionReader(context);
beanDefinitionReader.loadBeanDefinitions(file);
@@ -139,10 +139,28 @@ public class AttributeResolverTest extends OpenSAMLInitBaseTestCase {
}
+
+ @Test public void service() throws ComponentInitializationException, ServiceException, ResolutionException {
+ helper(true);
+ }
+
+ @Test public void serviceNullStrip() throws ComponentInitializationException, ServiceException, ResolutionException {
+ helper(false);
+ }
+
+ private void helper(final boolean stripNulls) throws ComponentInitializationException, ServiceException, ResolutionException {
- @Test public void one() throws ComponentInitializationException, ServiceException, ResolutionException {
+ final String inputFile;
+ final int expectedEPAValues;
+ if (stripNulls) {
+ inputFile = "net/shibboleth/idp/attribute/resolver/spring/serviceNullStrip.xml";
+ expectedEPAValues = 1;
+ } else {
+ inputFile ="net/shibboleth/idp/attribute/resolver/spring/service.xml";
+ expectedEPAValues = 2;
+ }
- final ReloadableService<AttributeResolver> attributeResolverService = getResolver("net/shibboleth/idp/attribute/resolver/spring/service.xml");
+ final ReloadableService<AttributeResolver> attributeResolverService = getResolver(inputFile);
attributeResolverService.initialize();
@@ -162,7 +180,7 @@ public class AttributeResolverTest extends OpenSAMLInitBaseTestCase {
}
}
- Map<String, IdPAttribute> resolvedAttributes = resolutionContext.getResolvedIdPAttributes();
+ final Map<String, IdPAttribute> resolvedAttributes = resolutionContext.getResolvedIdPAttributes();
log.debug("resolved attributes '{}'", resolvedAttributes);
Assert.assertEquals(resolvedAttributes.size(), 15);
@@ -171,14 +189,15 @@ public class AttributeResolverTest extends OpenSAMLInitBaseTestCase {
IdPAttribute attribute = resolvedAttributes.get("eduPersonAffiliation");
Assert.assertNotNull(attribute);
List<IdPAttributeValue<?>> values = attribute.getValues();
- Assert.assertEquals(values.size(), 1);
+
+ Assert.assertEquals(values.size(), expectedEPAValues);
Assert.assertTrue(values.contains(new StringAttributeValue("member")));
// Broken (case 665)
attribute = resolvedAttributes.get("broken");
- Assert.assertEquals(attribute.getValues().size(), 3);
+ Assert.assertEquals(attribute.getValues().size(), 2+expectedEPAValues);
attribute = resolvedAttributes.get("broken2");
- Assert.assertEquals(attribute.getValues().size(), 3);
+ Assert.assertEquals(attribute.getValues().size(), 2+expectedEPAValues);
// LDAP
@@ -257,7 +276,7 @@ public class AttributeResolverTest extends OpenSAMLInitBaseTestCase {
final Subject subject = new Subject();
subject.getPrincipals().add(new NameIDPrincipal(nameId));
- SubjectCanonicalizationContext ctx = new SubjectCanonicalizationContext();
+ final SubjectCanonicalizationContext ctx = new SubjectCanonicalizationContext();
ctx.setSubject(subject);
ctx.setRequesterId("REQ");
ctx.setResponderId("RES");
@@ -266,7 +285,7 @@ public class AttributeResolverTest extends OpenSAMLInitBaseTestCase {
serviceableComponent = attributeResolverService.getServiceableComponent();
final AttributeResolver resolver = serviceableComponent.getComponent();
- LegacyPrincipalDecoder decoder = (LegacyPrincipalDecoder) resolver;
+ final LegacyPrincipalDecoder decoder = (LegacyPrincipalDecoder) resolver;
Assert.assertTrue(decoder.hasValidConnectors());
Assert.assertEquals(decoder.canonicalize(ctx), "MyHovercraftIsFullOfEels");
@@ -299,7 +318,7 @@ public class AttributeResolverTest extends OpenSAMLInitBaseTestCase {
}
}
- Map<String, IdPAttribute> resolvedAttributes = resolutionContext.getResolvedIdPAttributes();
+ final Map<String, IdPAttribute> resolvedAttributes = resolutionContext.getResolvedIdPAttributes();
log.debug("output {}", resolvedAttributes);
Assert.assertEquals(resolvedAttributes.get("testing").getValues().size(), 2);
}
@@ -329,7 +348,7 @@ public class AttributeResolverTest extends OpenSAMLInitBaseTestCase {
final Subject subject = new Subject();
subject.getPrincipals().add(new NameIDPrincipal(nameId));
- SubjectCanonicalizationContext ctx = new SubjectCanonicalizationContext();
+ final SubjectCanonicalizationContext ctx = new SubjectCanonicalizationContext();
ctx.setSubject(subject);
ctx.setRequesterId("REQ");
ctx.setResponderId("RES");
@@ -338,7 +357,7 @@ public class AttributeResolverTest extends OpenSAMLInitBaseTestCase {
serviceableComponent = attributeResolverService.getServiceableComponent();
final AttributeResolver resolver = serviceableComponent.getComponent();
- LegacyPrincipalDecoder decoder = (LegacyPrincipalDecoder) resolver;
+ final LegacyPrincipalDecoder decoder = (LegacyPrincipalDecoder) resolver;
Assert.assertFalse(decoder.hasValidConnectors());
Assert.assertNull(decoder.canonicalize(ctx));
@@ -350,11 +369,11 @@ public class AttributeResolverTest extends OpenSAMLInitBaseTestCase {
}
@Test public void selective() throws ResolutionException {
- GenericApplicationContext context = new GenericApplicationContext();
+ final GenericApplicationContext context = new GenericApplicationContext();
setTestContext(context);
context.setDisplayName("ApplicationContext: " + AttributeResolverTest.class);
- SchemaTypeAwareXMLBeanDefinitionReader beanDefinitionReader =
+ final SchemaTypeAwareXMLBeanDefinitionReader beanDefinitionReader =
new SchemaTypeAwareXMLBeanDefinitionReader(context);
beanDefinitionReader.loadBeanDefinitions(new ClassPathResource(
@@ -382,11 +401,11 @@ public class AttributeResolverTest extends OpenSAMLInitBaseTestCase {
}
@Test public void selectiveNavigate() throws ResolutionException {
- GenericApplicationContext context = new GenericApplicationContext();
+ final GenericApplicationContext context = new GenericApplicationContext();
setTestContext(context);
context.setDisplayName("ApplicationContext: " + AttributeResolverTest.class);
- SchemaTypeAwareXMLBeanDefinitionReader beanDefinitionReader =
+ final SchemaTypeAwareXMLBeanDefinitionReader beanDefinitionReader =
new SchemaTypeAwareXMLBeanDefinitionReader(context);
beanDefinitionReader.loadBeanDefinitions(new ClassPathResource(
@@ -449,13 +468,13 @@ public class AttributeResolverTest extends OpenSAMLInitBaseTestCase {
private final Function<ProfileRequestContext, String> navigate;
- public TestPredicate(Function<ProfileRequestContext, String> profileFinder, String compare) {
+ public TestPredicate(final Function<ProfileRequestContext, String> profileFinder, final String compare) {
value = Constraint.isNotNull(compare, "provided compare name must not be null");
navigate = Constraint.isNotNull(profileFinder, "provided prinicpal locator must not be null");
}
/** {@inheritDoc} */
- @Override public boolean apply(@Nullable ProfileRequestContext input) {
+ @Override public boolean apply(@Nullable final ProfileRequestContext input) {
return value.equals(navigate.apply(input));
}
}
diff --git a/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/dc/StaticDataConnectorParserTest.java b/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/dc/StaticDataConnectorParserTest.java
index 6407017..06f9c35 100644
--- a/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/dc/StaticDataConnectorParserTest.java
+++ b/idp-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/dc/StaticDataConnectorParserTest.java
@@ -19,6 +19,9 @@ package net.shibboleth.idp.attribute.resolver.spring.dc;
import java.util.List;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
import net.shibboleth.idp.attribute.IdPAttribute;
import net.shibboleth.idp.attribute.IdPAttributeValue;
import net.shibboleth.idp.attribute.StringAttributeValue;
@@ -26,9 +29,6 @@ import net.shibboleth.idp.attribute.resolver.dc.impl.StaticDataConnector;
import net.shibboleth.idp.attribute.resolver.spring.BaseAttributeDefinitionParserTest;
import net.shibboleth.idp.attribute.resolver.spring.dc.impl.StaticDataConnectorParser;
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
/**
* test for {@link StaticDataConnectorParser}
*/
@@ -106,7 +106,7 @@ public class StaticDataConnectorParserTest extends BaseAttributeDefinitionParser
Assert.assertTrue(values.contains(new StringAttributeValue("urn:mace:dir:entitlement:common-lib-terms")));
values = connector.getAttributes().get("staticEpA").getValues();
- Assert.assertEquals(values.size(), 1);
+ Assert.assertEquals(values.size(), 2);
Assert.assertTrue(values.contains(new StringAttributeValue("member")));
}
}
diff --git a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/dc/staticAttributesNative.xml b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/dc/staticAttributesNative.xml
index 6b09568..722b4dd 100644
--- a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/dc/staticAttributesNative.xml
+++ b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/dc/staticAttributesNative.xml
@@ -12,7 +12,10 @@
<list>
<bean class="net.shibboleth.idp.attribute.IdPAttribute" c:attributeId="staticEpA">
<property name="values">
- <bean class="net.shibboleth.idp.attribute.StringAttributeValue" c:attributeValue="member" />
+ <list>
+ <bean class="net.shibboleth.idp.attribute.StringAttributeValue" c:attributeValue="member" />
+ <bean factory-method="valueOf" class="net.shibboleth.idp.attribute.StringAttributeValue" c:value="" />
+ </list>
</property>
</bean>
<bean class="net.shibboleth.idp.attribute.IdPAttribute" c:attributeId="eduPersonEntitlement">
diff --git a/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/serviceNullStrip.xml b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/serviceNullStrip.xml
new file mode 100644
index 0000000..25fca0a
--- /dev/null
+++ b/idp-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/serviceNullStrip.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:util="http://www.springframework.org/schema/util"
+ xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:c="http://www.springframework.org/schema/c"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
+ default-init-method="initialize"
+ default-destroy-method="destroy"
+ >
+
+ <!-- This BeanPostProcessor auto-sets identifiable beans with the bean name (if not already set). -->
+ <bean id="shibboleth.IdentifiableBeanPostProcessor"
+ class="net.shibboleth.ext.spring.config.IdentifiableBeanPostProcessor" />
+
+ <bean id="shibboleth.VelocityEngine" class="org.springframework.ui.velocity.VelocityEngineFactoryBean">
+ <property name="velocityProperties">
+ <props>
+ <prop key="resource.loader">classpath, string</prop>
+ <prop key="classpath.resource.loader.class">
+ org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader
+ </prop>
+ <prop key="string.resource.loader.class">
+ org.apache.velocity.runtime.resource.loader.StringResourceLoader
+ </prop>
+ </props>
+ </property>
+ </bean>
+ <bean id="shibboleth.AttributeResolverService" class="net.shibboleth.ext.spring.service.ReloadableSpringService"
+ depends-on="shibboleth.VelocityEngine"
+ p:beanPostProcessors-ref="shibboleth.IdentifiableBeanPostProcessor"
+ p:failFast="false" p:reloadCheckDelay="0">
+
+ <constructor-arg name="claz"
+ value="net.shibboleth.idp.attribute.resolver.AttributeResolver" />
+ <constructor-arg name="strategy">
+ <bean
+ class="net.shibboleth.idp.attribute.resolver.spring.impl.AttributeResolverServiceStrategy"
+ p:id="Shibboleth.Resolver"
+ p:stripNulls="true"/>
+ </constructor-arg>
+ <property name="serviceConfigurations">
+ <util:list>
+ <value>net/shibboleth/idp/attribute/resolver/spring/externalBeans.xml</value>
+ <value>net/shibboleth/idp/attribute/resolver/spring/storageService.xml</value>
+ <value>net/shibboleth/idp/attribute/resolver/spring/attribute-resolver.xml</value>
+ <value>net/shibboleth/idp/attribute/resolver/spring/dc/staticAttributesNative.xml</value>
+ </util:list>
+ </property>
+ </bean>
+</beans>
\ 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