[java-shib-attribute] branch main updated: IDP-2052 NPE when InputAttributeDefinition references nonexistant attribute

Rod Widdowson rdw at steadingsoftware.com
Tue Apr 1 19:17:44 UTC 2025


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

rdw pushed a commit to branch main
in repository java-shib-attribute.

View the commit online:
http://git.shibboleth.net/view/?p=java-shib-attribute.git;a=commit;h=d3e97700d22156833736d6a79bd71065197cceaa

The following commit(s) were added to refs/heads/main by this push:
     new d3e97700d IDP-2052 NPE when InputAttributeDefinition references nonexistant attribute
d3e97700d is described below

commit d3e97700d22156833736d6a79bd71065197cceaa
Author: Rod Widdowson <rdw at steadingsoftware.com>
AuthorDate: Tue Apr 1 20:15:40 2025 +0100

    IDP-2052 NPE when InputAttributeDefinition references nonexistant attribute
    
    https://shibboleth.atlassian.net/browse/IDP-2052
    
    Add regression test to try to smoke out unreproducible bug.
---
 .../resolver/spring/AttributeResolverTest.java     | 80 +++++++++++++++++++++-
 .../resolver/spring/propertyFileService.xml        | 41 +++++++++++
 2 files changed, 120 insertions(+), 1 deletion(-)

diff --git a/shib-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/AttributeResolverTest.java b/shib-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/AttributeResolverTest.java
index 49d9a000b..142d677ed 100644
--- a/shib-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/AttributeResolverTest.java
+++ b/shib-attribute-resolver-spring/src/test/java/net/shibboleth/idp/attribute/resolver/spring/AttributeResolverTest.java
@@ -14,10 +14,17 @@
 
 package net.shibboleth.idp.attribute.resolver.spring;
 
+import static org.testng.Assert.ARRAY_MISMATCH_TEMPLATE;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertTrue;
 
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.List;
@@ -36,6 +43,7 @@ import org.slf4j.Logger;
 import org.springframework.context.support.ConversionServiceFactoryBean;
 import org.springframework.context.support.GenericApplicationContext;
 import org.springframework.core.io.ClassPathResource;
+import org.springframework.mock.env.MockPropertySource;
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeClass;
@@ -47,6 +55,7 @@ import net.shibboleth.idp.attribute.StringAttributeValue;
 import net.shibboleth.idp.attribute.resolver.AttributeResolver;
 import net.shibboleth.idp.attribute.resolver.ResolutionException;
 import net.shibboleth.idp.attribute.resolver.context.AttributeResolutionContext;
+import net.shibboleth.idp.attribute.resolver.spring.dc.ldap.impl.LDAPDataConnectorParserTest;
 import net.shibboleth.idp.attribute.resolver.spring.testing.BaseAttributeDefinitionParserTest;
 import net.shibboleth.idp.attribute.resolver.testing.TestSources;
 import net.shibboleth.shared.annotation.constraint.NotEmpty;
@@ -63,6 +72,7 @@ import net.shibboleth.shared.spring.config.IdentifiableBeanPostProcessor;
 import net.shibboleth.shared.spring.config.StringToDurationConverter;
 import net.shibboleth.shared.spring.config.StringToResourceConverter;
 import net.shibboleth.shared.spring.custom.SchemaTypeAwareXMLBeanDefinitionReader;
+import net.shibboleth.shared.spring.util.ApplicationContextBuilder;
 import net.shibboleth.shared.testing.DatabaseTestingSupport;
 import net.shibboleth.shared.testing.InMemoryDirectory;
 
@@ -144,7 +154,7 @@ public class AttributeResolverTest extends OpenSAMLInitBaseTestCase {
         service.afterPropertiesSet();
 
         context.getBeanFactory().setConversionService(service.getObject());
-        
+
         final SchemaTypeAwareXMLBeanDefinitionReader beanDefinitionReader =
                 new SchemaTypeAwareXMLBeanDefinitionReader(context);
 
@@ -315,6 +325,74 @@ public class AttributeResolverTest extends OpenSAMLInitBaseTestCase {
         assertTrue(values.contains(new StringAttributeValue("#4321")));
     }
     
+    private void write2053File(final OutputStreamWriter ow, final String defname) throws IOException {
+
+        ow.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+                 + "<AttributeResolver xmlns=\"urn:mace:shibboleth:2.0:resolver\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
+                 + "  xsi:schemaLocation=\"urn:mace:shibboleth:2.0:resolver http://shibboleth.net/schema/idp/shibboleth-attribute-resolver.xsd\">\n");
+        ow.append("<DataConnector id=\"staticAttributes\" xsi:type=\"Static\">"
+                  + "<Attribute id=\"staticEpA\">"
+                  + "<Value>member</Value>"
+                  + "</Attribute></DataConnector>\n");
+        ow.append("<AttributeDefinition xsi:type=\"Simple\" id=\"");
+        ow.append(defname);
+        ow.append("\" dependencyOnly=\"true\">"
+                  + "<InputDataConnector ref=\"staticAttributes\" attributeNames=\"staticEpA\"/>"
+                  + "</AttributeDefinition>\n"
+                  + "<AttributeDefinition xsi:type=\"Simple\" id=\"setup-to-fail\">"
+                  + "<InputAttributeDefinition ref=\"undef\"/>"
+                  + "</AttributeDefinition></AttributeResolver>\n");
+        ow.flush();
+    }
+
+    @Test public void idp2052() throws IOException, ResolutionException
+    {
+        Path p = Files.createTempFile("Attr", "2052");
+
+        try (OutputStreamWriter ow = new OutputStreamWriter(new FileOutputStream(p.toFile()))) {
+            write2053File(ow, "undef");
+        }
+
+        final MockPropertySource mockEnvVars = new MockPropertySource();
+        mockEnvVars.setProperty("file.name", p.toAbsolutePath().toString());
+        final ApplicationContextBuilder builder = new ApplicationContextBuilder();
+        builder.setName("ApplicationContext: " + getClass())
+            .setPropertySources(CollectionSupport.singletonList(mockEnvVars))
+            .setServiceConfigurations(CollectionSupport.singletonList(new ClassPathResource("net/shibboleth/idp/attribute/resolver/spring/propertyFileService.xml")));
+
+        final GenericApplicationContext context = builder.build();
+
+        setTestContext(context);
+
+        final ReloadableService<AttributeResolver> service =  context.getBean(ReloadableService.class);
+
+        try (final ServiceableComponent<AttributeResolver> serviceableComponent = service.getServiceableComponent()) {
+            final AttributeResolutionContext resolutionContext = TestSources.createResolutionContext("PRINCIPAL", "ISSUER", "recipient");
+            final AttributeResolver resolver = serviceableComponent.getComponent();
+            assertEquals(resolver.getId(), "PropertyFileResolver");
+            resolver.resolveAttributes(resolutionContext);
+            assertEquals(resolutionContext.getResolvedIdPAttributes().size(), 1);
+        }
+
+        try (OutputStreamWriter ow = new OutputStreamWriter(new FileOutputStream(p.toFile()))) {
+                write2053File(ow, "redef");
+        }
+
+        try {
+                service.reload();
+        } catch (final ServiceException e) {
+                // OK
+        }
+        try (final ServiceableComponent<AttributeResolver> serviceableComponent = service.getServiceableComponent()) {
+            final AttributeResolutionContext resolutionContext = TestSources.createResolutionContext("PRINCIPAL", "ISSUER", "recipient");
+            final AttributeResolver resolver = serviceableComponent.getComponent();
+            assertEquals(resolver.getId(), "PropertyFileResolver");
+            resolver.resolveAttributes(resolutionContext);
+            assertEquals(resolutionContext.getResolvedIdPAttributes().size(), 1);
+        }
+        Files.delete(p);
+    }
+
     @Test public void mappedTemplate() throws Exception {
         final ReloadableService<AttributeResolver> attributeResolverService = getResolver("net/shibboleth/idp/attribute/resolver/spring/mappedTemplateService.xml");
 
diff --git a/shib-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/propertyFileService.xml b/shib-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/propertyFileService.xml
new file mode 100644
index 000000000..b2b8e860c
--- /dev/null
+++ b/shib-attribute-resolver-spring/src/test/resources/net/shibboleth/idp/attribute/resolver/spring/propertyFileService.xml
@@ -0,0 +1,41 @@
+<?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"
+	default-init-method="initialize" default-destroy-method="destroy"
+	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">
+                            
+	<bean id="shibboleth.VelocityEngine" destroy-method=""
+		class="net.shibboleth.shared.spring.velocity.VelocityEngineFactoryBean">
+		<property name="velocityProperties">
+			<props>
+                <prop key="resource.loaders">classpath, string</prop>
+                <prop key="resource.loader.classpath.class">
+                    org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader
+                </prop>
+                <prop key="resource.loader.string.class">
+                    org.apache.velocity.runtime.resource.loader.StringResourceLoader
+                </prop>
+			</props>
+		</property>
+	</bean>
+	
+	<bean id="shibboleth.AttributeResolverService" class="net.shibboleth.shared.spring.service.ReloadableSpringService"
+		depends-on="shibboleth.VelocityEngine" 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="PropertyFileResolver" />
+		</constructor-arg>
+		<property name="serviceConfigurations">
+			<util:list>
+				<value>%{file.name}</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