From 77857043ea67bfe92897bfea39085e9234db0e96 Mon Sep 17 00:00:00 2001 From: Bill Smith Date: Tue, 7 Aug 2018 09:48:05 -0700 Subject: [PATCH] [SHIBUI-723] OpenSaml resolver creation WIP. --- .../LuceneMetadataResolverService.groovy | 39 ++++++++++++++ .../DynamicHttpMetadataResolver.java | 36 ++++++++++++- .../FileBackedHttpMetadataResolver.java | 47 +++++++++++++++++ .../resolvers/FilesystemMetadataResolver.java | 43 +++++++++++++++ .../LocalDynamicMetadataResolver.java | 36 +++++++++++++ .../ResourceBackedMetadataResolver.java | 52 +++++++++++++++++++ 6 files changed, 252 insertions(+), 1 deletion(-) create mode 100644 backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/LuceneMetadataResolverService.groovy diff --git a/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/LuceneMetadataResolverService.groovy b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/LuceneMetadataResolverService.groovy new file mode 100644 index 000000000..dd59b669c --- /dev/null +++ b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/LuceneMetadataResolverService.groovy @@ -0,0 +1,39 @@ +package edu.internet2.tier.shibboleth.admin.ui.service + +import net.shibboleth.utilities.java.support.component.ComponentInitializationException +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.slf4j.Logger +import org.slf4j.LoggerFactory +import org.springframework.stereotype.Service + +/** + * @author Bill Smith (wsmith@unicon.net) + */ +@Service +class LuceneMetadataResolverService { + private static final Logger logger = LoggerFactory.getLogger(LuceneMetadataResolverService.class) + + void addIndexedDescriptorsFromBackingStore(AbstractMetadataResolver.EntityBackingStore backingStore, String resourceId, IndexWriter indexWriter) { + 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/DynamicHttpMetadataResolver.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/DynamicHttpMetadataResolver.java index e1c9ddc6b..2392c1ac3 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 @@ -1,14 +1,32 @@ package edu.internet2.tier.shibboleth.admin.ui.domain.resolvers; +import edu.internet2.tier.shibboleth.admin.ui.service.LuceneMetadataResolverService; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; import lombok.ToString; +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.DynamicMetadataResolver; +import org.opensaml.saml.metadata.resolver.impl.FunctionDrivenDynamicHTTPMetadataResolver; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import javax.annotation.Nullable; import javax.persistence.ElementCollection; import javax.persistence.Embedded; import javax.persistence.Entity; import javax.persistence.OrderColumn; +import java.io.IOException; import java.util.List; /** @@ -20,8 +38,10 @@ @Setter @ToString public class DynamicHttpMetadataResolver extends MetadataResolver { + private static final Logger logger = LoggerFactory.getLogger(DynamicHttpMetadataResolver.class); - + @Autowired + LuceneMetadataResolverService luceneMetadataResolverService; public static final String DEFAULT_TIMEOUT = "PT5S"; @@ -47,4 +67,18 @@ public DynamicHttpMetadataResolver() { this.httpMetadataResolverAttributes.setSocketTimeout(DEFAULT_TIMEOUT); this.dynamicMetadataResolverAttributes = new DynamicMetadataResolverAttributes(); } + + public FunctionDrivenDynamicHTTPMetadataResolver createOpenSamlResolver(IndexWriter indexWriter) throws ResolverException { + final String resourceId = this.getResourceId(); + + FunctionDrivenDynamicHTTPMetadataResolver openSamlResolver = new FunctionDrivenDynamicHTTPMetadataResolver(HttpClients.createMinimal()) { + @Override + protected void initMetadataResolver() throws ComponentInitializationException { + super.initMetadataResolver(); + + luceneMetadataResolverService.addIndexedDescriptorsFromBackingStore(this.getBackingStore(), resourceId, indexWriter); + } + }; + return openSamlResolver; + } } 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..d044800b0 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 @@ -1,13 +1,30 @@ package edu.internet2.tier.shibboleth.admin.ui.domain.resolvers; +import edu.internet2.tier.shibboleth.admin.ui.service.LuceneMetadataResolverService; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import lombok.ToString; +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.impl.FileBackedHTTPMetadataResolver; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import javax.annotation.Nullable; import javax.persistence.Embedded; import javax.persistence.Entity; +import java.io.IOException; @Entity @EqualsAndHashCode(callSuper = true) @@ -15,6 +32,10 @@ @Setter @ToString public class FileBackedHttpMetadataResolver extends MetadataResolver { + private static final Logger logger = LoggerFactory.getLogger(FileBackedHttpMetadataResolver.class); + + @Autowired + LuceneMetadataResolverService luceneMetadataResolverService; public FileBackedHttpMetadataResolver() { type = "FileBackedHttpMetadataResolver"; @@ -35,4 +56,30 @@ public FileBackedHttpMetadataResolver() { @Embedded private HttpMetadataResolverAttributes httpMetadataResolverAttributes; + public FileBackedHTTPMetadataResolver createOpenSamlResolver(IndexWriter indexWriter) throws ResolverException { + final String resourceId = this.getResourceId(); + + FileBackedHTTPMetadataResolver openSamlResolver = new FileBackedHTTPMetadataResolver(HttpClients.createMinimal(), this.metadataURL, this.backingFile) { + @Override + protected void initMetadataResolver() throws ComponentInitializationException { + super.initMetadataResolver(); + + luceneMetadataResolverService.addIndexedDescriptorsFromBackingStore(this.getBackingStore(), resourceId, indexWriter); + } + + // 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 + } + }; + return openSamlResolver; + } } 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..7a081eeae 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 @@ -1,12 +1,28 @@ package edu.internet2.tier.shibboleth.admin.ui.domain.resolvers; +import edu.internet2.tier.shibboleth.admin.ui.service.LuceneMetadataResolverService; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; import lombok.ToString; +import net.shibboleth.utilities.java.support.component.ComponentInitializationException; +import net.shibboleth.utilities.java.support.resolver.ResolverException; +import org.apache.http.HttpResponse; +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.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import javax.annotation.Nullable; import javax.persistence.Embedded; import javax.persistence.Entity; +import java.io.File; +import java.io.IOException; /** * @author Bill Smith (wsmith@unicon.net) @@ -17,6 +33,10 @@ @Setter @ToString public class FilesystemMetadataResolver extends MetadataResolver { + private static final Logger logger = LoggerFactory.getLogger(FilesystemMetadataResolver.class); + + @Autowired + LuceneMetadataResolverService luceneMetadataResolverService; public FilesystemMetadataResolver() { type = "FilesystemMetadataResolver"; @@ -26,4 +46,27 @@ public FilesystemMetadataResolver() { @Embedded private ReloadableMetadataResolverAttributes reloadableMetadataResolverAttributes; + + public org.opensaml.saml.metadata.resolver.impl.FilesystemMetadataResolver createOpenSamlResolver(IndexWriter indexWriter) throws ResolverException { + File metadataFile = new File(this.metadataFile); + + final String resourceId = this.getResourceId(); + + org.opensaml.saml.metadata.resolver.impl.FilesystemMetadataResolver openSamlResolver = new org.opensaml.saml.metadata.resolver.impl.FilesystemMetadataResolver(metadataFile) { + @Override + protected void initMetadataResolver() throws ComponentInitializationException { + super.initMetadataResolver(); + + luceneMetadataResolverService.addIndexedDescriptorsFromBackingStore(this.getBackingStore(), resourceId, indexWriter); + } + + // TODO: this is still probably not the best way to do this? + @Nullable + @Override + public DateTime getLastRefresh() { + return null; + } + }; + return openSamlResolver; + } } 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..0db3dae39 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 @@ -1,12 +1,28 @@ package edu.internet2.tier.shibboleth.admin.ui.domain.resolvers; +import edu.internet2.tier.shibboleth.admin.ui.service.LuceneMetadataResolverService; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; import lombok.ToString; +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.document.TextField; +import org.apache.lucene.index.IndexWriter; +import org.joda.time.DateTime; +import org.opensaml.core.xml.persist.FilesystemLoadSaveManager; +import org.opensaml.core.xml.persist.XMLObjectLoadSaveManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import javax.annotation.Nullable; import javax.persistence.Embedded; import javax.persistence.Entity; +import java.io.IOException; @Entity @EqualsAndHashCode(callSuper = true) @@ -14,6 +30,10 @@ @Setter @ToString public class LocalDynamicMetadataResolver extends MetadataResolver { + private static final Logger logger = LoggerFactory.getLogger(LocalDynamicMetadataResolver.class); + + @Autowired + LuceneMetadataResolverService luceneMetadataResolverService; public LocalDynamicMetadataResolver() { type = "LocalDynamicMetadataResolver"; @@ -28,4 +48,20 @@ public LocalDynamicMetadataResolver() { @Embedded private DynamicMetadataResolverAttributes dynamicMetadataResolverAttributes; + public org.opensaml.saml.metadata.resolver.impl.LocalDynamicMetadataResolver createOpenSamlResolver(IndexWriter indexWriter) throws ResolverException { + XMLObjectLoadSaveManager manager = null; + // manager = new .. what? + + final String resourceId = this.getResourceId(); + + org.opensaml.saml.metadata.resolver.impl.LocalDynamicMetadataResolver openSamlResolver = new org.opensaml.saml.metadata.resolver.impl.LocalDynamicMetadataResolver(manager) { + @Override + protected void initMetadataResolver() throws ComponentInitializationException { + super.initMetadataResolver(); + + luceneMetadataResolverService.addIndexedDescriptorsFromBackingStore(this.getBackingStore(), resourceId, indexWriter); + } + }; + return openSamlResolver; + } } 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..5c2d9f1ac 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 @@ -1,13 +1,30 @@ package edu.internet2.tier.shibboleth.admin.ui.domain.resolvers; +import edu.internet2.tier.shibboleth.admin.ui.service.LuceneMetadataResolverService; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; import lombok.ToString; +import net.shibboleth.utilities.java.support.component.ComponentInitializationException; +import net.shibboleth.utilities.java.support.resolver.ResolverException; +import net.shibboleth.utilities.java.support.resource.Resource; +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.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.ClassPathResource; +import javax.annotation.Nullable; import javax.persistence.Embedded; import javax.persistence.Entity; +import java.io.IOException; + import static edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.ResourceBackedMetadataResolver.ResourceType.CLASSPATH; import static edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.ResourceBackedMetadataResolver.ResourceType.SVN; @@ -17,11 +34,15 @@ @Setter @ToString public class ResourceBackedMetadataResolver extends MetadataResolver { + private static final Logger logger = LoggerFactory.getLogger(ResourceBackedMetadataResolver.class); public ResourceBackedMetadataResolver() { type = "ResourceBackedMetadataResolver"; } + @Autowired + private LuceneMetadataResolverService luceneMetadataResolverService; + @Embedded private ReloadableMetadataResolverAttributes reloadableMetadataResolverAttributes; @@ -51,4 +72,35 @@ public enum ResourceType { CLASSPATH, SVN } + + public org.opensaml.saml.metadata.resolver.impl.ResourceBackedMetadataResolver createOpenSamlResolver(IndexWriter indexWriter) throws ResolverException, IOException { + ResourceType resourceType = this.validateAndDetermineResourceType(); + Resource resource = null; + switch (resourceType) { + case SVN: + // resource = new ... what? + break; + case CLASSPATH: + resource = (Resource) new ClassPathResource(this.classpathMetadataResource.getFile()); + break; + } + final String resourceId = this.getResourceId(); + + org.opensaml.saml.metadata.resolver.impl.ResourceBackedMetadataResolver openSamlResolver = new org.opensaml.saml.metadata.resolver.impl.ResourceBackedMetadataResolver(resource) { + @Override + protected void initMetadataResolver() throws ComponentInitializationException { + super.initMetadataResolver(); + + luceneMetadataResolverService.addIndexedDescriptorsFromBackingStore(this.getBackingStore(), resourceId, indexWriter); + } + + // TODO: this is still probably not the best way to do this? + @Nullable + @Override + public DateTime getLastRefresh() { + return null; + } + }; + return openSamlResolver; + } }