diff --git a/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAMetadataResolverServiceImpl.groovy b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAMetadataResolverServiceImpl.groovy
index f8eb32a38..ec11c9e43 100644
--- a/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAMetadataResolverServiceImpl.groovy
+++ b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAMetadataResolverServiceImpl.groovy
@@ -128,11 +128,6 @@ class JPAMetadataResolverServiceImpl implements MetadataResolverService {
//TODO: We do not currently marshall the internal incommon chaining resolver (with BaseMetadataResolver type)
if ((mr.type != 'BaseMetadataResolver') && (mr.enabled)) {
constructXmlNodeForResolver(mr, delegate) {
- MetadataFilter(
- 'xsi:type': 'SignatureValidation',
- 'requireSignedRoot': 'true',
- 'certificateFile': '%{idp.home}/credentials/inc-md-cert.pem'
- )
//TODO: enhance
mr.metadataFilters.each { edu.internet2.tier.shibboleth.admin.ui.domain.filters.MetadataFilter filter ->
constructXmlNodeForFilter(filter, delegate)
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 3cb37ee1b..a63c3da6e 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
@@ -6,6 +6,7 @@
import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolverRepository;
import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolversPositionOrderContainerRepository;
import edu.internet2.tier.shibboleth.admin.ui.scheduled.EntityDescriptorFilesScheduledTasks;
+import edu.internet2.tier.shibboleth.admin.ui.scheduled.MetadataProvidersScheduledTasks;
import edu.internet2.tier.shibboleth.admin.ui.service.DefaultMetadataResolversPositionOrderContainerService;
import edu.internet2.tier.shibboleth.admin.ui.service.DirectoryService;
import edu.internet2.tier.shibboleth.admin.ui.service.DirectoryServiceImpl;
@@ -34,6 +35,7 @@
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;
+import org.springframework.core.io.Resource;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
@@ -95,6 +97,12 @@ public EntityDescriptorFilesScheduledTasks entityDescriptorFilesScheduledTasks(E
return new EntityDescriptorFilesScheduledTasks(metadataDir, entityDescriptorRepository, openSamlObjects());
}
+ @Bean
+ @ConditionalOnProperty(name = "shibui.metadataProviders.target")
+ public MetadataProvidersScheduledTasks metadataProvidersScheduledTasks(@Value("${shibui.metadataProviders.target}") final Resource resource, final MetadataResolverService metadataResolverService) {
+ return new MetadataProvidersScheduledTasks(resource, metadataResolverService);
+ }
+
@Bean
public EntityIdsSearchService entityIdsSearchService(LuceneUtility luceneUtility, Analyzer fullTokenAnalyzer) {
return new EntityIdsSearchServiceImpl(luceneUtility, fullTokenAnalyzer);
diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/scheduled/MetadataProvidersScheduledTasks.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/scheduled/MetadataProvidersScheduledTasks.java
new file mode 100644
index 000000000..49048f39b
--- /dev/null
+++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/scheduled/MetadataProvidersScheduledTasks.java
@@ -0,0 +1,49 @@
+package edu.internet2.tier.shibboleth.admin.ui.scheduled;
+
+import edu.internet2.tier.shibboleth.admin.ui.service.MetadataResolverService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.WritableResource;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import java.io.IOException;
+import java.io.OutputStream;
+
+@Configuration
+@ConditionalOnProperty("shibui.metadataProviders.target")
+public class MetadataProvidersScheduledTasks {
+ private static final Logger logger = LoggerFactory.getLogger(MetadataProvidersScheduledTasks.class);
+
+ private final Resource target;
+ private final MetadataResolverService metadataResolverService;
+
+ public MetadataProvidersScheduledTasks(Resource target, MetadataResolverService metadataResolverService) {
+ this.target = target;
+ this.metadataResolverService = metadataResolverService;
+ }
+
+ @Scheduled(fixedRateString = "${shibui.metadataProviders.taskRunRate:30000}")
+ @Transactional(readOnly = true)
+ public void generateMetadataProvidersFile() {
+ try (OutputStream os = ((WritableResource)target).getOutputStream()) {
+ Transformer transformer = TransformerFactory.newInstance().newTransformer();
+ transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+ transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
+
+
+ transformer.transform(new DOMSource(metadataResolverService.generateConfiguration()), new StreamResult(os));
+ } catch (IOException | TransformerException e) {
+ logger.error(e.getLocalizedMessage(), e);
+ }
+ }
+}
diff --git a/backend/src/main/resources/application.properties b/backend/src/main/resources/application.properties
index 634d32c5b..7b290d0d4 100644
--- a/backend/src/main/resources/application.properties
+++ b/backend/src/main/resources/application.properties
@@ -52,3 +52,9 @@ spring.profiles.active=default
#Actuator endpoints (info)
# Un-comment to get full git details exposed like author, abbreviated SHA-1, commit message
#management.info.git.mode=full
+
+###
+# metadata-providers.xml write configuration
+
+# shibui.metadataProviders.target=file:/opt/shibboleth-idp/conf/shibui-metadata-providers.xml
+# shibui.metadataProviders.taskRunRate=30000
diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/IncommonJPAMetadataResolverServiceImplTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/IncommonJPAMetadataResolverServiceImplTests.groovy
index 279f4a6ba..003e8c167 100644
--- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/IncommonJPAMetadataResolverServiceImplTests.groovy
+++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/IncommonJPAMetadataResolverServiceImplTests.groovy
@@ -7,6 +7,7 @@ import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFil
import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilterTarget
import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityRoleWhiteListFilter
import edu.internet2.tier.shibboleth.admin.ui.domain.filters.RequiredValidUntilFilter
+import edu.internet2.tier.shibboleth.admin.ui.domain.filters.SignatureValidationFilter
import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects
import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolverRepository
import edu.internet2.tier.shibboleth.admin.ui.util.TestObjectGenerator
@@ -48,6 +49,7 @@ class IncommonJPAMetadataResolverServiceImplTests extends Specification {
def 'simple test generation of metadata-providers.xml'() {
when:
def mr = metadataResolverRepository.findAll().iterator().next()
+ mr.metadataFilters << new SignatureValidationFilter(requireSignedRoot: true, certificateFile: '%{idp.home}/credentials/inc-md-cert.pem')
mr.metadataFilters << requiredValidUntilFilterForXmlGenerationTests()
mr.metadataFilters << entityRoleWhiteListFilterForXmlGenerationTests()
metadataResolverRepository.save(mr)
@@ -63,6 +65,7 @@ class IncommonJPAMetadataResolverServiceImplTests extends Specification {
when:
//TODO: this might break later
def mr = metadataResolverRepository.findAll().iterator().next()
+ mr.metadataFilters << new SignatureValidationFilter(requireSignedRoot: true, certificateFile: '%{idp.home}/credentials/inc-md-cert.pem')
mr.metadataFilters << requiredValidUntilFilterForXmlGenerationTests()
mr.metadataFilters.add(new EntityAttributesFilter().with {
it.entityAttributesFilterTarget = new EntityAttributesFilterTarget().with {
diff --git a/backend/src/test/resources/conf/278.2.xml b/backend/src/test/resources/conf/278.2.xml
index 34bf7ae16..20b513e1f 100644
--- a/backend/src/test/resources/conf/278.2.xml
+++ b/backend/src/test/resources/conf/278.2.xml
@@ -23,7 +23,7 @@
socketTimeout="PT5S"
supportedContentTypes="[]"
xsi:type="DynamicHttpMetadataProvider">
-
+
-
-
-
\ No newline at end of file
diff --git a/backend/src/test/resources/conf/278.xml b/backend/src/test/resources/conf/278.xml
index e47fbd838..3bebc347b 100644
--- a/backend/src/test/resources/conf/278.xml
+++ b/backend/src/test/resources/conf/278.xml
@@ -23,7 +23,7 @@
socketTimeout="PT5S"
supportedContentTypes="[]"
xsi:type="DynamicHttpMetadataProvider">
-
+
md:SPSSODescriptor
@@ -35,8 +35,6 @@
metadataURL="https://idp.unicon.net/idp/shibboleth"
minRefreshDelay='PT0M'
maxRefreshDelay='P1D'>
-
-
-
\ No newline at end of file