diff --git a/backend/build.gradle b/backend/build.gradle index 167bd3994..e8ec167ce 100644 --- a/backend/build.gradle +++ b/backend/build.gradle @@ -112,6 +112,10 @@ dependencies { //JSON schema generator testCompile 'com.kjetland:mbknor-jackson-jsonschema_2.12:1.0.29' testCompile 'javax.validation:validation-api:2.0.1.Final' + + //Configuration Annotation Processor + //This could go in the spring boot section above, but I wasn't sure about the compileOnly vs compile + compileOnly "org.springframework.boot:spring-boot-configuration-processor" } def generatedSrcDir = new File(buildDir, 'generated/src/main/java') @@ -217,4 +221,4 @@ docker { noCache true files tasks.bootWar.outputs buildArgs(['JAR_FILE': 'shibui.war']) -} \ No newline at end of file +} diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/ShibbolethUiApplication.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/ShibbolethUiApplication.java index 1fc74cf9d..1a55dea6f 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/ShibbolethUiApplication.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/ShibbolethUiApplication.java @@ -1,5 +1,6 @@ package edu.internet2.tier.shibboleth.admin.ui; +import edu.internet2.tier.shibboleth.admin.ui.configuration.CustomAttributesConfiguration; import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolverRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/CoreShibUiConfiguration.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/CoreShibUiConfiguration.java index c9b6493fa..8e87d9434 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/CoreShibUiConfiguration.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/CoreShibUiConfiguration.java @@ -28,6 +28,7 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.support.ResourceBundleMessageSource; @@ -41,6 +42,7 @@ import javax.servlet.http.HttpServletRequest; @Configuration +@EnableConfigurationProperties(CustomAttributesConfiguration.class) public class CoreShibUiConfiguration { private static final Logger logger = LoggerFactory.getLogger(CoreShibUiConfiguration.class); @@ -168,4 +170,9 @@ public DirectoryService directoryService() { public LuceneUtility luceneUtility(DirectoryService directoryService) { return new LuceneUtility(directoryService); } + + @Bean + public CustomAttributesConfiguration customAttributesConfiguration() { + return new CustomAttributesConfiguration(); + } } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/CustomAttributesConfiguration.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/CustomAttributesConfiguration.java new file mode 100644 index 000000000..de15bd815 --- /dev/null +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/CustomAttributesConfiguration.java @@ -0,0 +1,26 @@ +package edu.internet2.tier.shibboleth.admin.ui.configuration; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +/** + * @author Bill Smith (wsmith@unicon.net) + */ +@Configuration +@ConfigurationProperties(prefix="custom") +public class CustomAttributesConfiguration { + + private List> attributes = new ArrayList<>(); + + public List> getAttributes() { + return attributes; + } + + public void setAttributes(List> attributes) { + this.attributes = attributes; + } +} diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/ConfigurationController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/ConfigurationController.java new file mode 100644 index 000000000..4a0388428 --- /dev/null +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/ConfigurationController.java @@ -0,0 +1,24 @@ +package edu.internet2.tier.shibboleth.admin.ui.controller; + +import edu.internet2.tier.shibboleth.admin.ui.configuration.CustomAttributesConfiguration; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +/** + * @author Bill Smith (wsmith@unicon.net) + */ +@Controller +@RequestMapping(value = "/api") +public class ConfigurationController { + + @Autowired + CustomAttributesConfiguration customAttributesConfiguration; + + @GetMapping(value = "/customAttributes") + public ResponseEntity getCustomAttributes() { + return ResponseEntity.ok(customAttributesConfiguration.getAttributes()); + } +} diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/util/ModelRepresentationConversions.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/util/ModelRepresentationConversions.java index 27fd92445..e68225b5a 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/util/ModelRepresentationConversions.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/util/ModelRepresentationConversions.java @@ -47,14 +47,11 @@ public static List getAttributeReleaseListFromAttributeList(List attribute.getName().equals(MDDCConstants.RELEASE_ATTRIBUTES)) .collect(Collectors.toList()); - if (releaseAttributes.size() != 1) { - // TODO: What do we do if there is more than one? - } - if (releaseAttributes.size() == 0) { - return new ArrayList<>(); - } else { - return getStringListOfAttributeValues(releaseAttributes.get(0).getAttributeValues()); + List attributeValues = new ArrayList<>(); + for (Attribute attribute : releaseAttributes) { + attributeValues.addAll(getStringListOfAttributeValues(attribute.getAttributeValues())); } + return attributeValues; } public static boolean getBooleanValueOfAttribute(Attribute attribute) { diff --git a/backend/src/main/resources/application.yml b/backend/src/main/resources/application.yml new file mode 100644 index 000000000..b7ee1eabd --- /dev/null +++ b/backend/src/main/resources/application.yml @@ -0,0 +1,28 @@ +custom: + attributes: + # Default attributes + - name: eduPersonPrincipalName + displayName: eduPersonPrincipalName (EPPN) + - name: uid + displayName: uid + - name: mail + displayName: mail + - name: surname + displayName: surname + - name: givenName + displayName: givenName + - name: eduPersonAffiliation + displayName: eduPersonAffiliation + - name: eduPersonScopedAffiliation + displayName: eduPersonScopedAffiliation + - name: eduPersonPrimaryAffiliation + displayName: eduPersonPrimaryAffiliation + - name: eduPersonEntitlement + displayName: eduPersonEntitlement + - name: eduPersonAssurance + displayName: eduPersonAssurance + - name: eduPersonUniqueId + displayName: eduPersonUniqueId + - name: employeeNumber + displayName: employeeNumber + # Custom attributes diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/util/TestObjectGenerator.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/util/TestObjectGenerator.groovy index 13dc8a554..8cace3792 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/util/TestObjectGenerator.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/util/TestObjectGenerator.groovy @@ -475,6 +475,8 @@ class TestObjectGenerator { it.metadataURL = 'https://idp.unicon.net/idp/shibboleth' it.reloadableMetadataResolverAttributes = new ReloadableMetadataResolverAttributes().with { + it.minRefreshDelay = 'PT0M' + it.maxRefreshDelay = 'P1D' it } it diff --git a/backend/src/test/resources/conf/278.2.xml b/backend/src/test/resources/conf/278.2.xml index 5a34f756b..200e8ab9f 100644 --- a/backend/src/test/resources/conf/278.2.xml +++ b/backend/src/test/resources/conf/278.2.xml @@ -39,7 +39,9 @@ + metadataURL="https://idp.unicon.net/idp/shibboleth" + minRefreshDelay='PT0M' + maxRefreshDelay='P1D'> diff --git a/backend/src/test/resources/conf/278.xml b/backend/src/test/resources/conf/278.xml index a337f72d7..deec8e9bf 100644 --- a/backend/src/test/resources/conf/278.xml +++ b/backend/src/test/resources/conf/278.xml @@ -32,7 +32,9 @@ + metadataURL="https://idp.unicon.net/idp/shibboleth" + minRefreshDelay='PT0M' + maxRefreshDelay='P1D'> diff --git a/backend/src/test/resources/conf/532.xml b/backend/src/test/resources/conf/532.xml index 85fead908..360a4c832 100644 --- a/backend/src/test/resources/conf/532.xml +++ b/backend/src/test/resources/conf/532.xml @@ -8,5 +8,7 @@ + metadataURL="https://idp.unicon.net/idp/shibboleth" + minRefreshDelay='PT0M' + maxRefreshDelay='P1D' />