diff --git a/backend/build.gradle b/backend/build.gradle index ca484d6cb..bc6167e38 100644 --- a/backend/build.gradle +++ b/backend/build.gradle @@ -106,7 +106,7 @@ dependencies { testCompile "org.xmlunit:xmlunit-core:2.5.1" testRuntime 'cglib:cglib-nodep:3.2.5' - testCompile "net.shibboleth.ext:spring-extensions:5.4.0-SNAPSHOT" + compile "net.shibboleth.ext:spring-extensions:5.4.0-SNAPSHOT" //JSON schema generator testCompile 'com.kjetland:mbknor-jackson-jsonschema_2.12:1.0.29' diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/MetadataResolverConfiguration.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/MetadataResolverConfiguration.java index cdcd54f02..3b2eab911 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/MetadataResolverConfiguration.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/MetadataResolverConfiguration.java @@ -3,27 +3,17 @@ 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.service.IndexWriterService; +import edu.internet2.tier.shibboleth.admin.ui.service.MetadataResolverConverterService; import net.shibboleth.utilities.java.support.component.ComponentInitializationException; import net.shibboleth.utilities.java.support.resolver.ResolverException; -import org.apache.http.HttpResponse; -import org.apache.http.impl.client.HttpClients; -import org.apache.lucene.document.Document; -import org.apache.lucene.document.Field; -import org.apache.lucene.document.StringField; -import org.apache.lucene.document.TextField; -import org.apache.lucene.index.IndexWriter; -import org.joda.time.DateTime; import org.opensaml.saml.metadata.resolver.ChainingMetadataResolver; import org.opensaml.saml.metadata.resolver.MetadataResolver; -import org.opensaml.saml.metadata.resolver.filter.MetadataFilterChain; -import org.opensaml.saml.metadata.resolver.impl.FileBackedHTTPMetadataResolver; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import javax.annotation.Nullable; import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -44,6 +34,9 @@ public class MetadataResolverConfiguration { @Autowired MetadataResolverRepository metadataResolverRepository; + @Autowired + MetadataResolverConverterService metadataResolverConverterService; + @Bean public MetadataResolver metadataResolver() throws ResolverException, ComponentInitializationException { ChainingMetadataResolver metadataResolver = new ChainingMetadataResolver(); @@ -51,63 +44,14 @@ public MetadataResolver metadataResolver() throws ResolverException, ComponentIn List resolvers = new ArrayList<>(); - String incommonMRId = "incommonmd"; - // TODO: remove this later when we allow for creation of arbitrary metadata resolvers - FileBackedHTTPMetadataResolver incommonMR = new FileBackedHTTPMetadataResolver(HttpClients.createMinimal(), "http://md.incommon.org/InCommon/InCommon-metadata.xml", "/tmp/incommonmd.xml"){ - @Override - protected void initMetadataResolver() throws ComponentInitializationException { - super.initMetadataResolver(); - - IndexWriter indexWriter; - try { - indexWriter = indexWriterService.getIndexWriter(incommonMRId); - } catch (IOException e) { - throw new ComponentInitializationException(e); - } - - for (String entityId: this.getBackingStore().getIndexedDescriptors().keySet()) { - - Document document = new Document(); - document.add(new StringField("id", entityId, Field.Store.YES)); - document.add(new TextField("content", entityId, Field.Store.YES)); // TODO: change entityId to be content of entity descriptor block - try { - indexWriter.addDocument(document); - } catch (IOException e) { - logger.error(e.getMessage(), e); - } - } - try { - indexWriter.commit(); - } catch (IOException e) { - throw new ComponentInitializationException(e); - } - } - - // TODO: this is probably not the best way to do this - @Nullable - @Override - public DateTime getLastRefresh() { - return null; - } - - // TODO: this is probably not the best way to do this - @Override - protected void processConditionalRetrievalHeaders(HttpResponse response) { - // let's do nothing 'cause we want to allow a refresh + Iterable persistedResolvers = metadataResolverRepository.findAll(); + for (edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolver resolver : persistedResolvers) { + try { + MetadataResolver openSamlResolver = metadataResolverConverterService.convertToOpenSamlRepresentation(resolver); + resolvers.add(openSamlResolver); + } catch (IOException e) { + //TODO: do something interesting here? } - }; - incommonMR.setId(incommonMRId); - incommonMR.setParserPool(openSamlObjects.getParserPool()); - incommonMR.setMetadataFilter(new MetadataFilterChain()); - incommonMR.initialize(); - - - resolvers.add(incommonMR); - - if (!metadataResolverRepository.findAll().iterator().hasNext()) { - edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolver mr = new edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolver(); - mr.setName("incommonmd"); - metadataResolverRepository.save(mr); } metadataResolver.setResolvers(resolvers); diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversController.java index b6e1f0538..c76ccb89e 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversController.java @@ -5,14 +5,17 @@ import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolverValidationService; import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolverRepository; import edu.internet2.tier.shibboleth.admin.ui.service.IndexWriterService; +import edu.internet2.tier.shibboleth.admin.ui.service.MetadataResolverConverterService; import edu.internet2.tier.shibboleth.admin.ui.service.MetadataResolverService; import edu.internet2.tier.shibboleth.admin.ui.service.MetadataResolversPositionOrderContainerService; import lombok.extern.slf4j.Slf4j; import net.shibboleth.utilities.java.support.component.ComponentInitializationException; +import net.shibboleth.utilities.java.support.resolver.ResolverException; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.document.StringField; import org.apache.lucene.index.IndexWriter; +import org.opensaml.saml.metadata.resolver.ChainingMetadataResolver; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -37,6 +40,7 @@ import java.io.IOException; import java.io.StringWriter; import java.net.URI; +import java.util.ArrayList; import java.util.List; import static edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolverValidator.ValidationResult; @@ -61,6 +65,12 @@ public class MetadataResolversController { @Autowired IndexWriterService indexWriterService; + @Autowired + org.opensaml.saml.metadata.resolver.MetadataResolver chainingMetadataResolver; + + @Autowired + MetadataResolverConverterService metadataResolverConverterService; + @ExceptionHandler({InvalidTypeIdException.class, IOException.class, HttpMessageNotReadableException.class}) public ResponseEntity unableToParseJson(Exception ex) { return ResponseEntity.badRequest().body(new ErrorResponse(HttpStatus.BAD_REQUEST.toString(), ex.getMessage())); @@ -99,7 +109,7 @@ public ResponseEntity getOne(@PathVariable String resourceId) { @PostMapping("/MetadataResolvers") @Transactional - public ResponseEntity create(@RequestBody MetadataResolver newResolver) { + public ResponseEntity create(@RequestBody MetadataResolver newResolver) throws IOException, ResolverException { if (resolverRepository.findByName(newResolver.getName()) != null) { return ResponseEntity.status(HttpStatus.CONFLICT).build(); } @@ -112,12 +122,26 @@ public ResponseEntity create(@RequestBody MetadataResolver newResolver) { MetadataResolver persistedResolver = resolverRepository.save(newResolver); positionOrderContainerService.appendPositionOrderForNew(persistedResolver); + updateChainingMetadataResolver(persistedResolver); + return ResponseEntity.created(getResourceUriFor(persistedResolver)).body(persistedResolver); } + private void updateChainingMetadataResolver(MetadataResolver persistedResolver) throws IOException, ResolverException { + org.opensaml.saml.metadata.resolver.MetadataResolver openSamlResolver = metadataResolverConverterService.convertToOpenSamlRepresentation(persistedResolver); + List resolverList = new ArrayList<>(((ChainingMetadataResolver) chainingMetadataResolver).getResolvers()); + for (org.opensaml.saml.metadata.resolver.MetadataResolver resolver : resolverList) { + if (resolver.getId().equals(persistedResolver.getResourceId())) { + resolverList.remove(resolver); + } + } + resolverList.add(openSamlResolver); + ((ChainingMetadataResolver) chainingMetadataResolver).setResolvers(resolverList); + } + @PutMapping("/MetadataResolvers/{resourceId}") @Transactional - public ResponseEntity update(@PathVariable String resourceId, @RequestBody MetadataResolver updatedResolver) { + public ResponseEntity update(@PathVariable String resourceId, @RequestBody MetadataResolver updatedResolver) throws IOException, ResolverException { MetadataResolver existingResolver = resolverRepository.findByResourceId(resourceId); if (existingResolver == null) { return ResponseEntity.notFound().build(); @@ -137,6 +161,8 @@ public ResponseEntity update(@PathVariable String resourceId, @RequestBody Me MetadataResolver persistedResolver = resolverRepository.save(updatedResolver); + updateChainingMetadataResolver(persistedResolver); + return ResponseEntity.ok(persistedResolver); } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/DynamicHttpMetadataResolver.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/DynamicHttpMetadataResolver.java index e1c9ddc6b..d1b3692d2 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/DynamicHttpMetadataResolver.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/DynamicHttpMetadataResolver.java @@ -20,9 +20,6 @@ @Setter @ToString public class DynamicHttpMetadataResolver extends MetadataResolver { - - - public static final String DEFAULT_TIMEOUT = "PT5S"; @Embedded diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/FileBackedHttpMetadataResolver.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/FileBackedHttpMetadataResolver.java index f659a412b..b6d303fb3 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/FileBackedHttpMetadataResolver.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/FileBackedHttpMetadataResolver.java @@ -2,7 +2,6 @@ import lombok.EqualsAndHashCode; import lombok.Getter; -import lombok.NoArgsConstructor; import lombok.Setter; import lombok.ToString; @@ -15,7 +14,6 @@ @Setter @ToString public class FileBackedHttpMetadataResolver extends MetadataResolver { - public FileBackedHttpMetadataResolver() { type = "FileBackedHttpMetadataResolver"; } @@ -34,5 +32,4 @@ public FileBackedHttpMetadataResolver() { @Embedded private HttpMetadataResolverAttributes httpMetadataResolverAttributes; - } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/FilesystemMetadataResolver.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/FilesystemMetadataResolver.java index 0e16c8353..1370f0881 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/FilesystemMetadataResolver.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/FilesystemMetadataResolver.java @@ -17,7 +17,6 @@ @Setter @ToString public class FilesystemMetadataResolver extends MetadataResolver { - public FilesystemMetadataResolver() { type = "FilesystemMetadataResolver"; } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/LocalDynamicMetadataResolver.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/LocalDynamicMetadataResolver.java index 2bdb67d1f..20ca36251 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/LocalDynamicMetadataResolver.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/LocalDynamicMetadataResolver.java @@ -14,7 +14,6 @@ @Setter @ToString public class LocalDynamicMetadataResolver extends MetadataResolver { - public LocalDynamicMetadataResolver() { type = "LocalDynamicMetadataResolver"; } @@ -27,5 +26,4 @@ public LocalDynamicMetadataResolver() { @Embedded private DynamicMetadataResolverAttributes dynamicMetadataResolverAttributes; - } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/ResourceBackedMetadataResolver.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/ResourceBackedMetadataResolver.java index 5737d0162..55c833f2d 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/ResourceBackedMetadataResolver.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/ResourceBackedMetadataResolver.java @@ -17,7 +17,6 @@ @Setter @ToString public class ResourceBackedMetadataResolver extends MetadataResolver { - public ResourceBackedMetadataResolver() { type = "ResourceBackedMetadataResolver"; } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/opensaml/OpenSamlFileBackedHTTPMetadataResolver.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/opensaml/OpenSamlFileBackedHTTPMetadataResolver.java new file mode 100644 index 000000000..76d3d9384 --- /dev/null +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/opensaml/OpenSamlFileBackedHTTPMetadataResolver.java @@ -0,0 +1,68 @@ +package edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.opensaml; + +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.FileBackedHttpMetadataResolver; +import net.shibboleth.utilities.java.support.component.ComponentInitializationException; +import net.shibboleth.utilities.java.support.resolver.ResolverException; +import org.apache.http.HttpResponse; +import org.apache.http.impl.client.HttpClients; +import org.apache.lucene.index.IndexWriter; +import org.joda.time.DateTime; +import org.opensaml.saml.metadata.resolver.impl.FileBackedHTTPMetadataResolver; + +import javax.annotation.Nullable; + +import static edu.internet2.tier.shibboleth.admin.util.DurationUtility.toMillis; + +/** + * @author Bill Smith (wsmith@unicon.net) + */ +public class OpenSamlFileBackedHTTPMetadataResolver extends FileBackedHTTPMetadataResolver { + private IndexWriter indexWriter; + private FileBackedHttpMetadataResolver sourceResolver; + + private OpenSamlMetadataResolverDelegate delegate; + + public OpenSamlFileBackedHTTPMetadataResolver(IndexWriter indexWriter, + FileBackedHttpMetadataResolver sourceResolver) throws ResolverException { + super(HttpClients.createMinimal(), sourceResolver.getMetadataURL(), sourceResolver.getBackingFile()); + this.indexWriter = indexWriter; + this.sourceResolver = sourceResolver; + this.delegate = new OpenSamlMetadataResolverDelegate(); + + this.setId(sourceResolver.getResourceId()); + + OpenSamlMetadataResolverConstructorHelper.updateOpenSamlMetadataResolverFromHttpMetadataResolverAttributes( + this, sourceResolver.getHttpMetadataResolverAttributes()); + OpenSamlMetadataResolverConstructorHelper.updateOpenSamlMetadataResolverFromReloadableMetadataResolverAttributes( + this, sourceResolver.getReloadableMetadataResolverAttributes()); + + this.setBackupFile(sourceResolver.getBackingFile()); + this.setBackupFileInitNextRefreshDelay(toMillis(sourceResolver.getBackupFileInitNextRefreshDelay())); + this.setInitializeFromBackupFile(sourceResolver.getInitializeFromBackupFile()); + + //TODO: Where does this get set in OpenSAML land? + // sourceResolver.getMetadataURL(); + } + + // TODO: this is still probably not the best way to do this? + @Nullable + @Override + public DateTime getLastRefresh() { + return null; + } + + // TODO: this is still probably not the best way to do this? + @Override + protected void processConditionalRetrievalHeaders(HttpResponse response) { + // let's do nothing 'cause we want to allow a refresh + } + + @Override + protected void initMetadataResolver() throws ComponentInitializationException { + super.initMetadataResolver(); + + delegate.addIndexedDescriptorsFromBackingStore(this.getBackingStore(), + this.sourceResolver.getResourceId(), + indexWriter); + } +} diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/opensaml/OpenSamlFilesystemMetadataResolver.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/opensaml/OpenSamlFilesystemMetadataResolver.java new file mode 100644 index 000000000..94ded9133 --- /dev/null +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/opensaml/OpenSamlFilesystemMetadataResolver.java @@ -0,0 +1,49 @@ +package edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.opensaml; + +import net.shibboleth.utilities.java.support.component.ComponentInitializationException; +import net.shibboleth.utilities.java.support.resolver.ResolverException; +import org.apache.lucene.index.IndexWriter; +import org.joda.time.DateTime; +import org.opensaml.saml.metadata.resolver.impl.FilesystemMetadataResolver; + +import javax.annotation.Nullable; +import java.io.File; + +/** + * @author Bill Smith (wsmith@unicon.net) + */ +public class OpenSamlFilesystemMetadataResolver extends FilesystemMetadataResolver { + private IndexWriter indexWriter; + private edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.FilesystemMetadataResolver sourceResolver; + private OpenSamlMetadataResolverDelegate delegate; + + public OpenSamlFilesystemMetadataResolver(File metadataFile, + IndexWriter indexWriter, + edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.FilesystemMetadataResolver sourceResolver) throws ResolverException { + super(metadataFile); + this.indexWriter = indexWriter; + this.sourceResolver = sourceResolver; + this.delegate = new OpenSamlMetadataResolverDelegate(); + + this.setId(sourceResolver.getResourceId()); + + OpenSamlMetadataResolverConstructorHelper.updateOpenSamlMetadataResolverFromReloadableMetadataResolverAttributes( + this, sourceResolver.getReloadableMetadataResolverAttributes()); + } + + // TODO: this is still probably not the best way to do this? + @Nullable + @Override + public DateTime getLastRefresh() { + return null; + } + + @Override + protected void initMetadataResolver() throws ComponentInitializationException { + super.initMetadataResolver(); + + delegate.addIndexedDescriptorsFromBackingStore(this.getBackingStore(), + this.sourceResolver.getResourceId(), + indexWriter); + } +} diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/opensaml/OpenSamlFunctionDrivenDynamicHTTPMetadataResolver.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/opensaml/OpenSamlFunctionDrivenDynamicHTTPMetadataResolver.java new file mode 100644 index 000000000..2887fa85a --- /dev/null +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/opensaml/OpenSamlFunctionDrivenDynamicHTTPMetadataResolver.java @@ -0,0 +1,48 @@ +package edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.opensaml; + +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.DynamicHttpMetadataResolver; +import net.shibboleth.utilities.java.support.component.ComponentInitializationException; +import org.apache.http.impl.client.HttpClients; +import org.apache.lucene.index.IndexWriter; +import org.opensaml.saml.metadata.resolver.impl.FunctionDrivenDynamicHTTPMetadataResolver; + +/** + * @author Bill Smith (wsmith@unicon.net) + */ +public class OpenSamlFunctionDrivenDynamicHTTPMetadataResolver extends FunctionDrivenDynamicHTTPMetadataResolver { + private IndexWriter indexWriter; + private DynamicHttpMetadataResolver sourceResolver; + private OpenSamlMetadataResolverDelegate delegate; + + public OpenSamlFunctionDrivenDynamicHTTPMetadataResolver(IndexWriter indexWriter, + DynamicHttpMetadataResolver sourceResolver) { + super(HttpClients.createMinimal()); + this.indexWriter = indexWriter; + this.sourceResolver = sourceResolver; + this.delegate = new OpenSamlMetadataResolverDelegate(); + + this.setId(sourceResolver.getResourceId()); + + OpenSamlMetadataResolverConstructorHelper.updateOpenSamlMetadataResolverFromDynamicMetadataResolverAttributes( + this, sourceResolver.getDynamicMetadataResolverAttributes()); + + OpenSamlMetadataResolverConstructorHelper.updateOpenSamlMetadataResolverFromHttpMetadataResolverAttributes( + this, sourceResolver.getHttpMetadataResolverAttributes()); + + this.setSupportedContentTypes(sourceResolver.getSupportedContentTypes()); + + //TODO: These don't seem to be used anywhere. + // In the parser, if not null, a warning is logged .. but nothing else happens with them. + // sourceResolver.getMaxConnectionsPerRoute(); + // sourceResolver.getMaxConnectionsTotal(); + } + + @Override + protected void initMetadataResolver() throws ComponentInitializationException { + super.initMetadataResolver(); + + delegate.addIndexedDescriptorsFromBackingStore(this.getBackingStore(), + this.sourceResolver.getResourceId(), + indexWriter); + } +} diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/opensaml/OpenSamlLocalDynamicMetadataResolver.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/opensaml/OpenSamlLocalDynamicMetadataResolver.java new file mode 100644 index 000000000..abbfbd26b --- /dev/null +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/opensaml/OpenSamlLocalDynamicMetadataResolver.java @@ -0,0 +1,45 @@ +package edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.opensaml; + +import net.shibboleth.utilities.java.support.component.ComponentInitializationException; +import org.apache.lucene.index.IndexWriter; +import org.opensaml.core.xml.XMLObject; +import org.opensaml.core.xml.persist.XMLObjectLoadSaveManager; +import org.opensaml.saml.metadata.resolver.impl.LocalDynamicMetadataResolver; + +import javax.annotation.Nonnull; + +/** + * @author Bill Smith (wsmith@unicon.net) + */ +public class OpenSamlLocalDynamicMetadataResolver extends LocalDynamicMetadataResolver { + private IndexWriter indexWriter; + private edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.LocalDynamicMetadataResolver sourceResolver; + private OpenSamlMetadataResolverDelegate delegate; + + public OpenSamlLocalDynamicMetadataResolver(@Nonnull XMLObjectLoadSaveManager manager, + IndexWriter indexWriter, + edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.LocalDynamicMetadataResolver sourceResolver) { + super(manager); + this.indexWriter = indexWriter; + this.sourceResolver = sourceResolver; + this.delegate = new OpenSamlMetadataResolverDelegate(); + + this.setId(sourceResolver.getResourceId()); + + OpenSamlMetadataResolverConstructorHelper.updateOpenSamlMetadataResolverFromDynamicMetadataResolverAttributes( + this, sourceResolver.getDynamicMetadataResolverAttributes()); + + //TODO: Where do these refs get used in OpenSAML land? + // sourceResolver.getSourceKeyGeneratorRef(); + // sourceResolver.getSourceManagerRef(); + } + + @Override + protected void initMetadataResolver() throws ComponentInitializationException { + super.initMetadataResolver(); + + delegate.addIndexedDescriptorsFromBackingStore(this.getBackingStore(), + this.sourceResolver.getResourceId(), + indexWriter); + } +} diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/opensaml/OpenSamlMetadataResolverConstructorHelper.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/opensaml/OpenSamlMetadataResolverConstructorHelper.java new file mode 100644 index 000000000..7e674ab2b --- /dev/null +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/opensaml/OpenSamlMetadataResolverConstructorHelper.java @@ -0,0 +1,75 @@ +package edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.opensaml; + +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.DynamicMetadataResolverAttributes; +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.HttpMetadataResolverAttributes; +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.ReloadableMetadataResolverAttributes; +import org.opensaml.saml.metadata.resolver.MetadataResolver; +import org.opensaml.saml.metadata.resolver.impl.AbstractDynamicMetadataResolver; +import org.opensaml.saml.metadata.resolver.impl.AbstractReloadingMetadataResolver; + +import static edu.internet2.tier.shibboleth.admin.util.DurationUtility.toMillis; + +/** + * @author Bill Smith (wsmith@unicon.net) + */ +public class OpenSamlMetadataResolverConstructorHelper { + + public static void updateOpenSamlMetadataResolverFromDynamicMetadataResolverAttributes(MetadataResolver metadataResolver, DynamicMetadataResolverAttributes attributes) { + AbstractDynamicMetadataResolver dynamicMetadataResolver = (AbstractDynamicMetadataResolver) metadataResolver; + + dynamicMetadataResolver.setBackgroundInitializationFromCacheDelay(toMillis(attributes.getBackgroundInitializationFromCacheDelay())); + dynamicMetadataResolver.setCleanupTaskInterval(toMillis(attributes.getCleanupTaskInterval())); + dynamicMetadataResolver.setInitializeFromPersistentCacheInBackground(attributes.getInitializeFromPersistentCacheInBackground()); + dynamicMetadataResolver.setMaxCacheDuration(toMillis(attributes.getMaxCacheDuration())); + dynamicMetadataResolver.setMaxIdleEntityData(toMillis(attributes.getMaxIdleEntityData())); + dynamicMetadataResolver.setMinCacheDuration(toMillis(attributes.getMinCacheDuration())); + dynamicMetadataResolver.setBackgroundInitializationFromCacheDelay(toMillis(attributes.getBackgroundInitializationFromCacheDelay())); + dynamicMetadataResolver.setRefreshDelayFactor(attributes.getRefreshDelayFactor().floatValue()); + + //TODO: What should we do here if this data is null/empty? + dynamicMetadataResolver.setRemoveIdleEntityData(attributes.getRemoveIdleEntityData() == null ? false : attributes.getRemoveIdleEntityData()); + + //TODO: This takes a XMLObjectLoadSaveManager. Do we have what we need to create one? + // dynamicMetadataResolver.setPersistentCacheManager(); attributes.getPersistentCacheManagerDirectory(); + // attributes.getPersistentCacheManagerRef(); + + //TODO: This takes a Function. We've got a ref. How to convert? + // dynamicMetadataResolver.setPersistentCacheKeyGenerator(); attributes.getPersistentCacheKeyGeneratorRef(); + + //TODO: This takes a Predicate. We've got a predicate ref. How to convert? + // dynamicMetadataResolver.setInitializationFromCachePredicate(); attributes.getInitializationFromCachePredicateRef(); + + //TODO: This takes a ParserPool. We've got a ParserPoolRef. How to convert? + // dynamicMetadataResolver.setParserPool(); attributes.getParserPoolRef(); + + //TODO: Where does this get used in OpenSAML land? + // attributes.getTaskTimerRef(); + } + + public static void updateOpenSamlMetadataResolverFromHttpMetadataResolverAttributes(MetadataResolver metadataResolver, HttpMetadataResolverAttributes attributes) { + //TODO: Implement once we figure out what needs to happen here. + } + + public static void updateOpenSamlMetadataResolverFromReloadableMetadataResolverAttributes(MetadataResolver metadataResolver, ReloadableMetadataResolverAttributes attributes) { + AbstractReloadingMetadataResolver reloadingMetadataResolver = (AbstractReloadingMetadataResolver) metadataResolver; + + reloadingMetadataResolver.setExpirationWarningThreshold(toMillis(attributes.getExpirationWarningThreshold())); + reloadingMetadataResolver.setMaxRefreshDelay(toMillis(attributes.getMaxRefreshDelay())); + reloadingMetadataResolver.setMinRefreshDelay(toMillis(attributes.getMinRefreshDelay())); + + //TODO: I think we may need to take another look at setting the defaults properly on our attributes. + reloadingMetadataResolver.setRefreshDelayFactor(attributes.getRefreshDelayFactor() == null ? 0.75f : attributes.getRefreshDelayFactor().floatValue()); + + //TODO: What should we do here if this data is null/empty? + reloadingMetadataResolver.setResolveViaPredicatesOnly(attributes.getResolveViaPredicatesOnly() == null ? false : attributes.getResolveViaPredicatesOnly()); + + //TODO: This takes a set of MetadataIndex's. We've got an IndexesRef. How to convert? + // reloadingMetadataResolver.setIndexes(); attributes.getIndexesRef(); + + //TODO: This takes a ParserPool. We've got a ParserPoolRef. How to convert? + // reloadingMetadataResolver.setParserPool(); attributes.getParserPoolRef(); + + //TODO: Where does this get used in OpenSAML land? + // attributes.getTaskTimerRef(); + } +} diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/opensaml/OpenSamlMetadataResolverDelegate.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/opensaml/OpenSamlMetadataResolverDelegate.java new file mode 100644 index 000000000..ab4cfd8aa --- /dev/null +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/opensaml/OpenSamlMetadataResolverDelegate.java @@ -0,0 +1,49 @@ +package edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.opensaml; + +import net.shibboleth.utilities.java.support.component.ComponentInitializationException; +import net.shibboleth.utilities.java.support.resolver.CriteriaSet; +import org.apache.lucene.document.Document; +import org.apache.lucene.document.Field; +import org.apache.lucene.document.StringField; +import org.apache.lucene.document.TextField; +import org.apache.lucene.index.IndexWriter; +import org.opensaml.saml.metadata.resolver.impl.AbstractMetadataResolver; +import org.opensaml.saml.saml2.metadata.EntityDescriptor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.io.IOException; + +/** + * @author Bill Smith (wsmith@unicon.net) + */ +public class OpenSamlMetadataResolverDelegate extends AbstractMetadataResolver { + private static final Logger logger = LoggerFactory.getLogger(OpenSamlMetadataResolverDelegate.class); + + @Nonnull + @Override + public Iterable resolve(@Nullable CriteriaSet criteria) { + throw new UnsupportedOperationException("This method should not be called."); + } + + void addIndexedDescriptorsFromBackingStore(AbstractMetadataResolver.EntityBackingStore backingStore, String resourceId, IndexWriter indexWriter) throws ComponentInitializationException { + for (String entityId : backingStore.getIndexedDescriptors().keySet()) { + Document document = new Document(); + document.add(new StringField("id", entityId, Field.Store.YES)); + document.add(new TextField("content", entityId, Field.Store.YES)); // TODO: change entityId to be content of entity descriptor block + document.add(new StringField("tag", resourceId, Field.Store.YES)); + try { + indexWriter.addDocument(document); + } catch (IOException e) { + logger.error(e.getMessage(), e); + } + } + try { + indexWriter.commit(); + } catch (IOException e) { + throw new ComponentInitializationException(e); + } + } +} diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/opensaml/OpenSamlResourceBackedMetadataResolver.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/opensaml/OpenSamlResourceBackedMetadataResolver.java new file mode 100644 index 000000000..addbdf9c7 --- /dev/null +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/opensaml/OpenSamlResourceBackedMetadataResolver.java @@ -0,0 +1,49 @@ +package edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.opensaml; + +import net.shibboleth.utilities.java.support.component.ComponentInitializationException; +import net.shibboleth.utilities.java.support.resource.Resource; +import org.apache.lucene.index.IndexWriter; +import org.joda.time.DateTime; +import org.opensaml.saml.metadata.resolver.impl.ResourceBackedMetadataResolver; + +import javax.annotation.Nullable; +import java.io.IOException; + +/** + * @author Bill Smith (wsmith@unicon.net) + */ +public class OpenSamlResourceBackedMetadataResolver extends ResourceBackedMetadataResolver { + private IndexWriter indexWriter; + private edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.ResourceBackedMetadataResolver sourceResolver; + private OpenSamlMetadataResolverDelegate delegate; + + public OpenSamlResourceBackedMetadataResolver(Resource resource, + IndexWriter indexWriter, + edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.ResourceBackedMetadataResolver sourceResolver) throws IOException { + super(resource); + this.indexWriter = indexWriter; + this.sourceResolver = sourceResolver; + this.delegate = new OpenSamlMetadataResolverDelegate(); + + this.setId(sourceResolver.getResourceId()); + + OpenSamlMetadataResolverConstructorHelper.updateOpenSamlMetadataResolverFromReloadableMetadataResolverAttributes( + this, sourceResolver.getReloadableMetadataResolverAttributes()); + } + + // TODO: this is still probably not the best way to do this? + @Nullable + @Override + public DateTime getLastRefresh() { + return null; + } + + @Override + protected void initMetadataResolver() throws ComponentInitializationException { + super.initMetadataResolver(); + + delegate.addIndexedDescriptorsFromBackingStore(this.getBackingStore(), + this.sourceResolver.getResourceId(), + indexWriter); + } +} diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/MetadataResolverConverterService.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/MetadataResolverConverterService.java new file mode 100644 index 000000000..8ac04c154 --- /dev/null +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/MetadataResolverConverterService.java @@ -0,0 +1,13 @@ +package edu.internet2.tier.shibboleth.admin.ui.service; + +import net.shibboleth.utilities.java.support.resolver.ResolverException; +import org.opensaml.saml.metadata.resolver.MetadataResolver; + +import java.io.IOException; + +/** + * @author Bill Smith (wsmith@unicon.net) + */ +public interface MetadataResolverConverterService { + MetadataResolver convertToOpenSamlRepresentation(edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolver resolver) throws IOException, ResolverException; +} diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/MetadataResolverConverterServiceImpl.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/MetadataResolverConverterServiceImpl.java new file mode 100644 index 000000000..fcd66cd35 --- /dev/null +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/MetadataResolverConverterServiceImpl.java @@ -0,0 +1,110 @@ +package edu.internet2.tier.shibboleth.admin.ui.service; + +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.DynamicHttpMetadataResolver; +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.FileBackedHttpMetadataResolver; +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.FilesystemMetadataResolver; +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.LocalDynamicMetadataResolver; +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.ResourceBackedMetadataResolver; +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.opensaml.OpenSamlFileBackedHTTPMetadataResolver; +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.opensaml.OpenSamlFilesystemMetadataResolver; +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.opensaml.OpenSamlFunctionDrivenDynamicHTTPMetadataResolver; +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.opensaml.OpenSamlLocalDynamicMetadataResolver; +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.opensaml.OpenSamlResourceBackedMetadataResolver; +import net.shibboleth.ext.spring.resource.ResourceHelper; +import net.shibboleth.utilities.java.support.resolver.ResolverException; +import net.shibboleth.utilities.java.support.resource.Resource; +import org.apache.lucene.index.IndexWriter; +import org.opensaml.core.xml.persist.FilesystemLoadSaveManager; +import org.opensaml.core.xml.persist.XMLObjectLoadSaveManager; +import org.opensaml.saml.metadata.resolver.MetadataResolver; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.ClassPathResource; +import org.springframework.stereotype.Service; + +import javax.validation.ConstraintViolationException; +import java.io.File; +import java.io.IOException; + +/** + * @author Bill Smith (wsmith@unicon.net) + */ +@Service +public class MetadataResolverConverterServiceImpl implements MetadataResolverConverterService { + + @Autowired + IndexWriterService indexWriterService; + + private OpenSamlFunctionDrivenDynamicHTTPMetadataResolver convertToOpenSamlRepresentation(DynamicHttpMetadataResolver resolver) throws IOException { + IndexWriter indexWriter = indexWriterService.getIndexWriter(resolver.getResourceId()); + + return new OpenSamlFunctionDrivenDynamicHTTPMetadataResolver(indexWriter, + resolver); + } + + private OpenSamlFileBackedHTTPMetadataResolver convertToOpenSamlRepresentation(FileBackedHttpMetadataResolver resolver) throws IOException, ResolverException { + IndexWriter indexWriter = indexWriterService.getIndexWriter(resolver.getResourceId()); + + return new OpenSamlFileBackedHTTPMetadataResolver(indexWriter, resolver); + } + + private OpenSamlFilesystemMetadataResolver convertToOpenSamlRepresentation(FilesystemMetadataResolver resolver) throws IOException, ResolverException { + IndexWriter indexWriter = indexWriterService.getIndexWriter(resolver.getResourceId()); + File metadataFile = new File(resolver.getMetadataFile()); + + return new OpenSamlFilesystemMetadataResolver(metadataFile, + indexWriter, + resolver); + } + + private OpenSamlLocalDynamicMetadataResolver convertToOpenSamlRepresentation(LocalDynamicMetadataResolver resolver) throws IOException { + IndexWriter indexWriter = indexWriterService.getIndexWriter(resolver.getResourceId()); + + XMLObjectLoadSaveManager manager = null; + try { + manager = new FilesystemLoadSaveManager(resolver.getSourceDirectory()); + } catch (ConstraintViolationException e) { + // the base directory string instance was null or empty + //TODO: What should we do here? Currently, this causes a test to fail. + } + + return new OpenSamlLocalDynamicMetadataResolver(manager, indexWriter, resolver); + } + + private OpenSamlResourceBackedMetadataResolver convertToOpenSamlRepresentation(ResourceBackedMetadataResolver resolver) throws IOException { + IndexWriter indexWriter = indexWriterService.getIndexWriter(resolver.getResourceId()); + ResourceBackedMetadataResolver.ResourceType resourceType = resolver.validateAndDetermineResourceType(); + Resource resource = null; + switch (resourceType) { + case SVN: + //TODO: What sort of resource type should be created here? URL? + break; + case CLASSPATH: + resource = ResourceHelper.of(new ClassPathResource(resolver.getClasspathMetadataResource().getFile())); + break; + default: + throw new RuntimeException("Unsupported resource type!"); + } + + return new OpenSamlResourceBackedMetadataResolver(resource, + indexWriter, + resolver); + } + + @Override + public MetadataResolver convertToOpenSamlRepresentation(edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolver resolver) throws IOException, ResolverException { + switch (resolver.getType()) { + case "LocalDynamicMetadataResolver": + return convertToOpenSamlRepresentation((LocalDynamicMetadataResolver) resolver); + case "FileBackedHttpMetadataResolver": + return convertToOpenSamlRepresentation((FileBackedHttpMetadataResolver) resolver); + case "DynamicHttpMetadataResolver": + return convertToOpenSamlRepresentation((DynamicHttpMetadataResolver) resolver); + case "FilesystemMetadataResolver": + return convertToOpenSamlRepresentation((FilesystemMetadataResolver) resolver); + case "ResourceBackedMetadataResolver": + return convertToOpenSamlRepresentation((ResourceBackedMetadataResolver) resolver); + default: + throw new RuntimeException("Unsupported metadata resolver type!"); + } + } +} diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/util/DurationUtility.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/util/DurationUtility.java new file mode 100644 index 000000000..b19328e27 --- /dev/null +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/util/DurationUtility.java @@ -0,0 +1,39 @@ +package edu.internet2.tier.shibboleth.admin.util; + +import org.apache.commons.lang3.StringUtils; + +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.datatype.DatatypeFactory; +import javax.xml.datatype.Duration; +import java.util.Date; + +/** + * @author Bill Smith (wsmith@unicon.net) + */ +public class DurationUtility { + private static final DatatypeFactory datatypeFactory; + + static { + DatatypeFactory factory; + try { + factory = DatatypeFactory.newInstance(); + } catch (DatatypeConfigurationException e) { + factory = null; + } + datatypeFactory = factory; + } + + public static Long toMillis(String xmlDuration) { + if (datatypeFactory == null) { + throw new RuntimeException("DatatypeFactory was never initialized!"); + } + if (StringUtils.isBlank(xmlDuration)) { + return 0L; + } + Duration duration = datatypeFactory.newDuration(xmlDuration); + + Date zero = new Date(0); + duration.addTo(zero); // potentially can return undesired results for large xmlDurations + return zero.getTime(); + } +} diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversControllerIntegrationTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversControllerIntegrationTests.groovy index 3ceb55417..f90b85146 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversControllerIntegrationTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversControllerIntegrationTests.groovy @@ -11,8 +11,8 @@ import edu.internet2.tier.shibboleth.admin.ui.util.TestObjectGenerator import edu.internet2.tier.shibboleth.admin.util.AttributeUtility import groovy.json.JsonOutput import groovy.json.JsonSlurper +import org.opensaml.saml.metadata.resolver.ChainingMetadataResolver import org.opensaml.saml.metadata.resolver.MetadataResolver -import org.opensaml.saml.metadata.resolver.impl.FilesystemMetadataResolver import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest import org.springframework.boot.test.context.TestConfiguration @@ -20,9 +20,7 @@ import org.springframework.boot.test.web.client.TestRestTemplate import org.springframework.context.annotation.Bean import org.springframework.http.HttpEntity import org.springframework.http.HttpHeaders - import org.springframework.test.context.ActiveProfiles - import spock.lang.Specification import spock.lang.Unroll @@ -290,7 +288,7 @@ class MetadataResolversControllerIntegrationTests extends Specification { static class Config { @Bean MetadataResolver metadataResolver() { - new FilesystemMetadataResolver(new File('fake')) + new ChainingMetadataResolver() } } } 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 b158c83d0..279f4a6ba 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 @@ -140,7 +140,7 @@ class IncommonJPAMetadataResolverServiceImplTests extends Specification { metadataResolverRepository.save(new TestObjectGenerator(attributeUtility).localDynamicMetadataResolver()) // Generate and test edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.ResourceBackedMetadataResolver - metadataResolverRepository.save(new TestObjectGenerator(attributeUtility).resourceBackedMetadataResolverForSVN()) + metadataResolverRepository.save(new TestObjectGenerator(attributeUtility).resourceBackedMetadataResolverForClasspath()) } return resolver 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 4469e1b36..8e4cf2ed4 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 @@ -389,7 +389,7 @@ class TestObjectGenerator { randomResolver = localDynamicMetadataResolver() break case 'ResourceBacked': - randomResolver = resourceBackedMetadataResolverForSVN() + randomResolver = resourceBackedMetadataResolverForClasspath() break case 'Filesystem': randomResolver = filesystemMetadataResolver() @@ -437,6 +437,9 @@ class TestObjectGenerator { new DynamicHttpMetadataResolver().with { it.name = 'DynamicHTTP' it.xmlId = 'DynamicHTTP' + it.dynamicMetadataResolverAttributes = new DynamicMetadataResolverAttributes().with { + it + } it } } @@ -445,6 +448,10 @@ class TestObjectGenerator { new LocalDynamicMetadataResolver().with { it.name = 'LocalDynamic' it.xmlId = 'LocalDynamic' + it.sourceDirectory = '/tmp' + it.dynamicMetadataResolverAttributes = new DynamicMetadataResolverAttributes().with { + it + } it } } @@ -459,6 +466,25 @@ class TestObjectGenerator { it.workingCopyDirectory = '%{idp.home}/metadata/svn' it } + it.reloadableMetadataResolverAttributes = new ReloadableMetadataResolverAttributes().with { + it + } + it + } + } + + ResourceBackedMetadataResolver resourceBackedMetadataResolverForClasspath() { + new ResourceBackedMetadataResolver().with { + it.name = 'ClasspathResourceMetadata' + it.xmlId = 'ClasspathResourceMetadata' + it.classpathMetadataResource = new ClasspathMetadataResource().with { + it.file = 'metadata/metadata.xml' + it + } + it.reloadableMetadataResolverAttributes = new ReloadableMetadataResolverAttributes().with { + it.refreshDelayFactor = 0.3 + it + } it } } diff --git a/backend/src/test/resources/conf/278.2.xml b/backend/src/test/resources/conf/278.2.xml index 216f9626c..42c21c122 100644 --- a/backend/src/test/resources/conf/278.2.xml +++ b/backend/src/test/resources/conf/278.2.xml @@ -47,17 +47,23 @@ certificateFile="%{idp.home}/credentials/inc-md-cert.pem" /> - + + xsi:type="resource:ClasspathResource" + file="metadata/metadata.xml" /> diff --git a/backend/src/test/resources/conf/278.xml b/backend/src/test/resources/conf/278.xml index 6f845bf59..856244654 100644 --- a/backend/src/test/resources/conf/278.xml +++ b/backend/src/test/resources/conf/278.xml @@ -40,17 +40,23 @@ certificateFile="%{idp.home}/credentials/inc-md-cert.pem" /> - + + xsi:type="resource:ClasspathResource" + file="metadata/metadata.xml" /> \ No newline at end of file