From f96a45d21ac49f7ea99e50168e788cafdaaf6544 Mon Sep 17 00:00:00 2001 From: Dmitriy Kopylenko Date: Fri, 8 Jun 2018 13:51:05 -0400 Subject: [PATCH 1/7] SHIBUI-517[532] work in progress --- .../JPAMetadataResolverServiceImpl.groovy | 88 +++++++++++-------- .../FileBackedHttpMetadataResolver.java | 9 ++ ...HttpMetadataResolverRepositoryTests.groovy | 6 +- ...JPAMetadataResolverServiceImplTests.groovy | 53 +++++++++++ .../admin/ui/util/TestHelpers.groovy | 12 +++ .../admin/ui/util/TestObjectGenerator.groovy | 22 +++++ backend/src/test/resources/conf/532.xml | 15 ++++ 7 files changed, 165 insertions(+), 40 deletions(-) create mode 100644 backend/src/test/resources/conf/532.xml 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 f28480e73..fdf84927d 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 @@ -1,28 +1,29 @@ package edu.internet2.tier.shibboleth.admin.ui.service; -import com.google.common.base.Predicate; -import edu.internet2.tier.shibboleth.admin.ui.domain.EntityAttributesFilter; +import com.google.common.base.Predicate +import edu.internet2.tier.shibboleth.admin.ui.domain.EntityAttributesFilter import edu.internet2.tier.shibboleth.admin.ui.domain.EntityAttributesFilterTarget -import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects; +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.FileBackedHttpMetadataResolver +import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolverRepository +import groovy.util.logging.Slf4j import groovy.xml.DOMBuilder -import groovy.xml.MarkupBuilder; -import net.shibboleth.utilities.java.support.resolver.ResolverException; -import org.opensaml.saml.common.profile.logic.EntityIdPredicate; -import org.opensaml.saml.metadata.resolver.ChainingMetadataResolver; -import org.opensaml.saml.metadata.resolver.MetadataResolver; -import org.opensaml.saml.metadata.resolver.RefreshableMetadataResolver; -import org.opensaml.saml.metadata.resolver.filter.MetadataFilter; -import org.opensaml.saml.metadata.resolver.filter.MetadataFilterChain; -import org.opensaml.saml.saml2.core.Attribute; -import org.opensaml.saml.saml2.metadata.EntityDescriptor; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.w3c.dom.Document; - -public class JPAMetadataResolverServiceImpl implements MetadataResolverService { - private static final Logger logger = LoggerFactory.getLogger(JPAMetadataResolverServiceImpl.class); +import groovy.xml.MarkupBuilder +import net.shibboleth.utilities.java.support.resolver.ResolverException +import org.opensaml.saml.common.profile.logic.EntityIdPredicate +import org.opensaml.saml.metadata.resolver.ChainingMetadataResolver +import org.opensaml.saml.metadata.resolver.MetadataResolver +import org.opensaml.saml.metadata.resolver.RefreshableMetadataResolver +import org.opensaml.saml.metadata.resolver.filter.MetadataFilter +import org.opensaml.saml.metadata.resolver.filter.MetadataFilterChain +import org.opensaml.saml.saml2.core.Attribute +import org.opensaml.saml.saml2.metadata.EntityDescriptor + +import org.springframework.beans.factory.annotation.Autowired +import org.w3c.dom.Document + +@Slf4j +class JPAMetadataResolverServiceImpl implements MetadataResolverService { @Autowired private MetadataResolver metadataResolver @@ -35,52 +36,52 @@ public class JPAMetadataResolverServiceImpl implements MetadataResolverService { // TODO: enhance @Override - public void reloadFilters(String metadataResolverName) { - ChainingMetadataResolver chainingMetadataResolver = (ChainingMetadataResolver)metadataResolver; - - // MetadataResolver targetMetadataResolver = chainingMetadataResolver.getResolvers().stream().filter(r -> r.getId().equals(metadataResolverName)).findFirst().get(); + void reloadFilters(String metadataResolverName) { + ChainingMetadataResolver chainingMetadataResolver = (ChainingMetadataResolver)metadataResolver MetadataResolver targetMetadataResolver = chainingMetadataResolver.getResolvers().find { it.id == metadataResolverName } - edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolver jpaMetadataResolver = metadataResolverRepository.findByName(metadataResolverName); + edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolver jpaMetadataResolver = metadataResolverRepository.findByName(metadataResolverName) if (targetMetadataResolver && targetMetadataResolver.getMetadataFilter() instanceof MetadataFilterChain) { - MetadataFilterChain metadataFilterChain = (MetadataFilterChain)targetMetadataResolver.getMetadataFilter(); + MetadataFilterChain metadataFilterChain = (MetadataFilterChain)targetMetadataResolver.getMetadataFilter() - List metadataFilters = new ArrayList<>(); + List metadataFilters = new ArrayList<>() for (edu.internet2.tier.shibboleth.admin.ui.domain.MetadataFilter metadataFilter : jpaMetadataResolver.getMetadataFilters()) { if (metadataFilter instanceof EntityAttributesFilter) { - EntityAttributesFilter entityAttributesFilter = (EntityAttributesFilter) metadataFilter; + EntityAttributesFilter entityAttributesFilter = (EntityAttributesFilter) metadataFilter - org.opensaml.saml.metadata.resolver.filter.impl.EntityAttributesFilter target = new org.opensaml.saml.metadata.resolver.filter.impl.EntityAttributesFilter(); - Map, Collection> rules = new HashMap<>(); + org.opensaml.saml.metadata.resolver.filter.impl.EntityAttributesFilter target = new org.opensaml.saml.metadata.resolver.filter.impl.EntityAttributesFilter() + Map, Collection> rules = new HashMap<>() if (entityAttributesFilter.getEntityAttributesFilterTarget().getEntityAttributesFilterTargetType() == EntityAttributesFilterTarget.EntityAttributesFilterTargetType.ENTITY) { rules.put( new EntityIdPredicate(entityAttributesFilter.getEntityAttributesFilterTarget().getValue()), (List)(List)entityAttributesFilter.getAttributes() - ); + ) } - target.setRules(rules); - metadataFilters.add(target); + target.setRules(rules) + metadataFilters.add(target) } } - metadataFilterChain.setFilters(metadataFilters); + metadataFilterChain.setFilters(metadataFilters) } if (metadataResolver instanceof RefreshableMetadataResolver) { try { - ((RefreshableMetadataResolver)metadataResolver).refresh(); + ((RefreshableMetadataResolver)metadataResolver).refresh() } catch (ResolverException e) { - logger.warn("error refreshing metadataResolver " + metadataResolverName, e); + log.warn("error refreshing metadataResolver " + metadataResolverName, e) } } } // TODO: enhance @Override - public Document generateConfiguration() { + Document generateConfiguration() { // TODO: this can probably be a better writer new StringWriter().withCloseable { writer -> def xml = new MarkupBuilder(writer) + xml.omitEmptyAttributes = true + xml.omitNullAttributes = true xml.MetadataProvider(id: 'ShibbolethMetadata', xmlns: 'urn:mace:shibboleth:2.0:metadata', @@ -135,4 +136,17 @@ public class JPAMetadataResolverServiceImpl implements MetadataResolverService { return DOMBuilder.newInstance().parseText(writer.toString()) } } + + void constructXmlNodeFor(FileBackedHttpMetadataResolver resolver, def markupBuilderDelegate) { + def attributes = [id: "${resolver.name}", + 'xsi:type': 'FileBackedHTTPMetadataProvider', + backingFile: resolver.backingFile, + metadataURL: resolver.metadataURL, + minRefreshDelay: resolver.reloadableMetadataResolverAttributes?.minRefreshDelay, + maxRefreshDelay: resolver.reloadableMetadataResolverAttributes?.maxRefreshDelay, + refreshDelayFactor: resolver.reloadableMetadataResolverAttributes?.refreshDelayFactor] + + markupBuilderDelegate.MetadataProvider(attributes) + } + } 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 c9850ecc6..4678dca1d 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 @@ -17,6 +17,15 @@ @ToString public class FileBackedHttpMetadataResolver extends MetadataResolver { + private String metadataURL; + + private String backingFile; + + private Boolean initializeFromBackupFile; + + private String backupFileInitNextRefreshDelay; + + @Embedded private ReloadableMetadataResolverAttributes reloadableMetadataResolverAttributes; diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/FileBackedHttpMetadataResolverRepositoryTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/FileBackedHttpMetadataResolverRepositoryTests.groovy index d0beb24d2..5074750ea 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/FileBackedHttpMetadataResolverRepositoryTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/FileBackedHttpMetadataResolverRepositoryTests.groovy @@ -30,7 +30,7 @@ import static edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.HttpMetada class FileBackedHttpMetadataResolverRepositoryTests extends Specification { @Autowired - FileBackedHttpMetadataResolverRepository repositoryUnderTest + MetadataResolverRepository repositoryUnderTest @Autowired EntityManager entityManager @@ -119,9 +119,9 @@ class FileBackedHttpMetadataResolverRepositoryTests extends Specification { entityManager.flush() then: - def item1 = repositoryUnderTest.findByResourceId(persistedResolver.resourceId) + def item1 = repositoryUnderTest.findByName(persistedResolver.name) entityManager.clear() - def item2 = repositoryUnderTest.findByResourceId(persistedResolver.resourceId) + def item2 = repositoryUnderTest.findByName(persistedResolver.name) item1.hashCode() == item2.hashCode() } diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAMetadataResolverServiceImplTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAMetadataResolverServiceImplTests.groovy index afc93df62..a20ce8eb9 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAMetadataResolverServiceImplTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAMetadataResolverServiceImplTests.groovy @@ -6,6 +6,11 @@ import edu.internet2.tier.shibboleth.admin.ui.domain.EntityAttributesFilter import edu.internet2.tier.shibboleth.admin.ui.domain.EntityAttributesFilterTarget 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 +import edu.internet2.tier.shibboleth.admin.util.AttributeUtility +import groovy.xml.DOMBuilder +import groovy.xml.MarkupBuilder import net.shibboleth.ext.spring.resource.ResourceHelper import net.shibboleth.utilities.java.support.resolver.CriteriaSet import org.joda.time.DateTime @@ -28,6 +33,8 @@ import org.xmlunit.builder.DiffBuilder import org.xmlunit.builder.Input import spock.lang.Specification +import static edu.internet2.tier.shibboleth.admin.ui.util.TestHelpers.generatedXmlIsTheSameAsExpectedXml + @SpringBootTest @DataJpaTest @ContextConfiguration(classes=[CoreShibUiConfiguration, SearchConfiguration]) @@ -50,6 +57,30 @@ class JPAMetadataResolverServiceImplTests extends Specification { @Autowired OpenSamlObjects openSamlObjects + @Autowired + AttributeUtility attributeUtility + + TestObjectGenerator testObjectGenerator + + DOMBuilder domBuilder + + StringWriter writer + + MarkupBuilder markupBuilder + + def setup() { + testObjectGenerator = new TestObjectGenerator(attributeUtility) + domBuilder = DOMBuilder.newInstance() + writer = new StringWriter() + markupBuilder = new MarkupBuilder(writer) + markupBuilder.omitNullAttributes = true + markupBuilder.omitEmptyAttributes = true + } + + def cleanup() { + writer.close() + } + def 'test adding a filter'() { given: def expectedXML = ''' @@ -98,6 +129,28 @@ class JPAMetadataResolverServiceImplTests extends Specification { !diff.hasDifferences() } + def 'test generating FileBackedHttMetadataResolver xml snippet'() { + given: + def resolver = testObjectGenerator.fileBackedHttpMetadataResolver() + + when: + genXmlSnippet(markupBuilder) { JPAMetadataResolverServiceImpl.cast(metadataResolverService).constructXmlNodeFor(resolver, it) } + + then: + assert generatedXmlIsTheSameAsExpectedXml('/conf/532.xml', domBuilder.parseText(writer.toString())) + } + + static genXmlSnippet(MarkupBuilder xml, Closure xmlNodeGenerator) { + xml.MetadataProvider('id': 'ShibbolethMetadata', + 'xmlns': 'urn:mace:shibboleth:2.0:metadata', + 'xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance', + 'xsi:type': 'ChainingMetadataProvider', + 'xsi:schemaLocation': 'urn:mace:shibboleth:2.0:metadata http://shibboleth.net/schema/idp/shibboleth-metadata.xsd urn:mace:shibboleth:2.0:resource http://shibboleth.net/schema/idp/shibboleth-resource.xsd urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd urn:oasis:names:tc:SAML:2.0:metadata http://docs.oasis-open.org/security/saml/v2.0/saml-schema-metadata-2.0.xsd urn:oasis:names:tc:SAML:2.0:assertion http://docs.oasis-open.org/security/saml/v2.0/saml-schema-assertion-2.0.xsd' + ) { + xmlNodeGenerator(delegate) + } + } + @TestConfiguration static class Config { @Autowired diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/util/TestHelpers.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/util/TestHelpers.groovy index 1a6a085e2..3d8b834e8 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/util/TestHelpers.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/util/TestHelpers.groovy @@ -2,6 +2,9 @@ package edu.internet2.tier.shibboleth.admin.ui.util import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.RelyingPartyOverridesRepresentation import org.apache.commons.lang.StringUtils +import org.w3c.dom.Document +import org.xmlunit.builder.DiffBuilder +import org.xmlunit.builder.Input /** * @author Bill Smith (wsmith@unicon.net) @@ -22,4 +25,13 @@ class TestHelpers { return count } + + static generatedXmlIsTheSameAsExpectedXml(String expectedXmlResource, Document generatedXml) { + def diffs = DiffBuilder.compare(Input.fromStream(this.getResourceAsStream(expectedXmlResource))).withTest(Input.fromDocument + (generatedXml)) + .ignoreComments().ignoreWhitespace().build().differences + + !DiffBuilder.compare(Input.fromStream(this.getResourceAsStream(expectedXmlResource))).withTest(Input.fromDocument(generatedXml)) + .ignoreComments().ignoreWhitespace().build().hasDifferences() + } } 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 302bdac95..b8adc23d0 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 @@ -12,10 +12,16 @@ import edu.internet2.tier.shibboleth.admin.ui.domain.OrganizationURL import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.FilterRepresentation import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.FilterTargetRepresentation import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.RelyingPartyOverridesRepresentation +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.FileBackedHttpMetadataResolver +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.HttpMetadataResolverAttributes +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.ReloadableMetadataResolverAttributes import edu.internet2.tier.shibboleth.admin.util.AttributeUtility import edu.internet2.tier.shibboleth.admin.util.MDDCConstants import org.opensaml.saml.saml2.metadata.Organization +import static edu.internet2.tier.shibboleth.admin.ui.domain.EntityAttributesFilterTarget.EntityAttributesFilterTargetType.ENTITY +import static edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.HttpMetadataResolverAttributes.HttpCachingType.memory + /** * @author Bill Smith (wsmith@unicon.net) */ @@ -190,6 +196,22 @@ class TestObjectGenerator { return contactPerson } + FileBackedHttpMetadataResolver fileBackedHttpMetadataResolver() { + new FileBackedHttpMetadataResolver().with { + it.name = 'HTTPMetadata' + it.backingFile = '%{idp.home}/metadata/incommonmd.xml' + it.metadataURL = 'http://md.incommon.org/InCommon/InCommon-metadata.xml' + + it.reloadableMetadataResolverAttributes = new ReloadableMetadataResolverAttributes().with { + it.minRefreshDelay = 'PT5M' + it.maxRefreshDelay = 'PT1H' + it.refreshDelayFactor = 0.75 + it + } + it + } + } + /** * This method takes a type and a size and builds a List of that size containing objects of that type. This is * intended to be used with things that extend LocalizedName such as {@link OrganizationName}, {@link OrganizationDisplayName}, diff --git a/backend/src/test/resources/conf/532.xml b/backend/src/test/resources/conf/532.xml new file mode 100644 index 000000000..cdfd93301 --- /dev/null +++ b/backend/src/test/resources/conf/532.xml @@ -0,0 +1,15 @@ + + + + + From 546daeb50978ebfb9fe714d27c87f9e48e4ad509 Mon Sep 17 00:00:00 2001 From: Dmitriy Kopylenko Date: Fri, 8 Jun 2018 13:54:07 -0400 Subject: [PATCH 2/7] Polishing --- .../tier/shibboleth/admin/ui/util/TestHelpers.groovy | 4 ---- 1 file changed, 4 deletions(-) diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/util/TestHelpers.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/util/TestHelpers.groovy index 3d8b834e8..bbac2be5f 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/util/TestHelpers.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/util/TestHelpers.groovy @@ -27,10 +27,6 @@ class TestHelpers { } static generatedXmlIsTheSameAsExpectedXml(String expectedXmlResource, Document generatedXml) { - def diffs = DiffBuilder.compare(Input.fromStream(this.getResourceAsStream(expectedXmlResource))).withTest(Input.fromDocument - (generatedXml)) - .ignoreComments().ignoreWhitespace().build().differences - !DiffBuilder.compare(Input.fromStream(this.getResourceAsStream(expectedXmlResource))).withTest(Input.fromDocument(generatedXml)) .ignoreComments().ignoreWhitespace().build().hasDifferences() } From 478c23e0176c2d015bccde9843c3405ce186bf02 Mon Sep 17 00:00:00 2001 From: Dmitriy Kopylenko Date: Fri, 8 Jun 2018 14:44:12 -0400 Subject: [PATCH 3/7] SHIBUI-517[532] --- .../JPAMetadataResolverServiceImpl.groovy | 44 +++++++++++++++---- .../FileBackedHttpMetadataResolver.java | 2 +- .../HttpMetadataResolverAttributes.java | 2 +- .../ui/domain/resolvers/MetadataResolver.java | 6 +-- 4 files changed, 40 insertions(+), 14 deletions(-) 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 fdf84927d..610aa2181 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 @@ -138,15 +138,41 @@ class JPAMetadataResolverServiceImpl implements MetadataResolverService { } void constructXmlNodeFor(FileBackedHttpMetadataResolver resolver, def markupBuilderDelegate) { - def attributes = [id: "${resolver.name}", - 'xsi:type': 'FileBackedHTTPMetadataProvider', - backingFile: resolver.backingFile, - metadataURL: resolver.metadataURL, - minRefreshDelay: resolver.reloadableMetadataResolverAttributes?.minRefreshDelay, - maxRefreshDelay: resolver.reloadableMetadataResolverAttributes?.maxRefreshDelay, - refreshDelayFactor: resolver.reloadableMetadataResolverAttributes?.refreshDelayFactor] - - markupBuilderDelegate.MetadataProvider(attributes) + markupBuilderDelegate.MetadataProvider(id: resolver.name, + 'xsi:type': 'FileBackedHTTPMetadataProvider', + backingFile: resolver.backingFile, + metadataURL: resolver.metadataURL, + initializeFromBackupFile: !resolver.initializeFromBackupFile ?: null, + backupFileInitNextRefreshDelay: resolver.backupFileInitNextRefreshDelay, + requireValidMetadata: !resolver.requireValidMetadata ?: null, + failFastInitialization: !resolver.failFastInitialization ?: null, + sortKey: resolver.sortKey, + criterionPredicateRegistryRef: resolver.criterionPredicateRegistryRef, + useDefaultPredicateRegistry: !resolver.useDefaultPredicateRegistry ?: null, + satisfyAnyPredicates: resolver.satisfyAnyPredicates ?: null, + + parserPoolRef: resolver.reloadableMetadataResolverAttributes?.parserPoolRef, + minRefreshDelay: resolver.reloadableMetadataResolverAttributes?.minRefreshDelay, + maxRefreshDelay: resolver.reloadableMetadataResolverAttributes?.maxRefreshDelay, + refreshDelayFactor: resolver.reloadableMetadataResolverAttributes?.refreshDelayFactor, + indexesRef: resolver.reloadableMetadataResolverAttributes?.indexesRef, + resolveViaPredicatesOnly: resolver.reloadableMetadataResolverAttributes?.resolveViaPredicatesOnly ?: null, + expirationWarningThreshold: resolver.reloadableMetadataResolverAttributes?.expirationWarningThreshold, + + httpClientRef: resolver.httpMetadataResolverAttributes?.httpClientRef, + connectionRequestTimeout: resolver.httpMetadataResolverAttributes?.connectionRequestTimeout, + connectionTimeout: resolver.httpMetadataResolverAttributes?.connectionTimeout, + socketTimeout: resolver.httpMetadataResolverAttributes?.socketTimeout, + disregardTLSCertificate: resolver.httpMetadataResolverAttributes?.disregardTLSCertificate ?: null, + httpClientSecurityParametersRef: resolver.httpMetadataResolverAttributes?.httpClientSecurityParametersRef, + proxyHost: resolver.httpMetadataResolverAttributes?.proxyHost, + proxyPort: resolver.httpMetadataResolverAttributes?.proxyHost, + proxyUser: resolver.httpMetadataResolverAttributes?.proxyUser, + proxyPassword: resolver.httpMetadataResolverAttributes?.proxyPassword, + httpCaching: resolver.httpMetadataResolverAttributes?.httpCaching, + httpCacheDirectory: resolver.httpMetadataResolverAttributes?.httpCacheDirectory, + httpMaxCacheEntries: resolver.httpMetadataResolverAttributes?.httpMaxCacheEntries, + httpMaxCacheEntrySize: resolver.httpMetadataResolverAttributes?.httpMaxCacheEntrySize) } } 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 4678dca1d..37748e6c0 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 @@ -21,7 +21,7 @@ public class FileBackedHttpMetadataResolver extends MetadataResolver { private String backingFile; - private Boolean initializeFromBackupFile; + private Boolean initializeFromBackupFile = true; private String backupFileInitNextRefreshDelay; diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/HttpMetadataResolverAttributes.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/HttpMetadataResolverAttributes.java index 437516ffd..f286fca01 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/HttpMetadataResolverAttributes.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/HttpMetadataResolverAttributes.java @@ -24,7 +24,7 @@ public class HttpMetadataResolverAttributes { private String connectionRequestTimeout; - private String requestTimeout; + private String connectionTimeout; private String socketTimeout; diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/MetadataResolver.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/MetadataResolver.java index 4deebcbcb..5efd6f5d2 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/MetadataResolver.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/MetadataResolver.java @@ -36,15 +36,15 @@ public class MetadataResolver extends AbstractAuditable { @Column(unique=true) private String resourceId = UUID.randomUUID().toString(); - private Boolean requireValidMetadata; + private Boolean requireValidMetadata = true; - private Boolean failFastInitialization; + private Boolean failFastInitialization = true; private Integer sortKey; private String criterionPredicateRegistryRef; - private Boolean useDefaultPredicateRegistry; + private Boolean useDefaultPredicateRegistry = true; private Boolean satisfyAnyPredicates; From f940fc07f9e8b1fc5d3759e6cbf8eea494d7c11b Mon Sep 17 00:00:00 2001 From: Dmitriy Kopylenko Date: Mon, 11 Jun 2018 11:41:33 -0400 Subject: [PATCH 4/7] SHIBUI-532 --- .../JPAMetadataResolverServiceImpl.groovy | 19 +++++++------------ ...JPAMetadataResolverServiceImplTests.groovy | 10 ++++++++-- ...JPAMetadataResolverServiceImplTests.groovy | 4 +++- 3 files changed, 18 insertions(+), 15 deletions(-) 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 610aa2181..72fd0b2e6 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 @@ -90,14 +90,7 @@ class JPAMetadataResolverServiceImpl implements MetadataResolverService { 'xsi:schemaLocation': 'urn:mace:shibboleth:2.0:metadata http://shibboleth.net/schema/idp/shibboleth-metadata.xsd urn:mace:shibboleth:2.0:resource http://shibboleth.net/schema/idp/shibboleth-resource.xsd urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd urn:oasis:names:tc:SAML:2.0:metadata http://docs.oasis-open.org/security/saml/v2.0/saml-schema-metadata-2.0.xsd urn:oasis:names:tc:SAML:2.0:assertion http://docs.oasis-open.org/security/saml/v2.0/saml-schema-assertion-2.0.xsd' ) { metadataResolverRepository.findAll().each { edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolver mr -> - MetadataProvider(id: 'HTTPMetadata', - 'xsi:type': 'FileBackedHTTPMetadataProvider', - backingFile: '%{idp.home}/metadata/incommonmd.xml', - metadataURL: 'http://md.incommon.org/InCommon/InCommon-metadata.xml', - minRefreshDelay: 'PT5M', - maxRefreshDelay: 'PT1H', - refreshDelayFactor: '0.75' - ) { + constructXmlNodeForResolver(mr, delegate) { MetadataFilter( 'xsi:type': 'SignatureValidation', 'requireSignedRoot': 'true', @@ -115,7 +108,7 @@ class JPAMetadataResolverServiceImpl implements MetadataResolverService { //TODO: enhance mr.metadataFilters.each { edu.internet2.tier.shibboleth.admin.ui.domain.MetadataFilter filter -> if (filter instanceof EntityAttributesFilter) { - EntityAttributesFilter entityAttributesFilter = (EntityAttributesFilter)filter + EntityAttributesFilter entityAttributesFilter = (EntityAttributesFilter) filter MetadataFilter('xsi:type': 'EntityAttributes') { // TODO: enhance. currently this does weird things with namespaces entityAttributesFilter.attributes.each { attribute -> @@ -132,12 +125,11 @@ class JPAMetadataResolverServiceImpl implements MetadataResolverService { } } } - return DOMBuilder.newInstance().parseText(writer.toString()) } } - void constructXmlNodeFor(FileBackedHttpMetadataResolver resolver, def markupBuilderDelegate) { + void constructXmlNodeForResolver(FileBackedHttpMetadataResolver resolver, def markupBuilderDelegate, Closure childNodes) { markupBuilderDelegate.MetadataProvider(id: resolver.name, 'xsi:type': 'FileBackedHTTPMetadataProvider', backingFile: resolver.backingFile, @@ -172,7 +164,10 @@ class JPAMetadataResolverServiceImpl implements MetadataResolverService { httpCaching: resolver.httpMetadataResolverAttributes?.httpCaching, httpCacheDirectory: resolver.httpMetadataResolverAttributes?.httpCacheDirectory, httpMaxCacheEntries: resolver.httpMetadataResolverAttributes?.httpMaxCacheEntries, - httpMaxCacheEntrySize: resolver.httpMetadataResolverAttributes?.httpMaxCacheEntrySize) + httpMaxCacheEntrySize: resolver.httpMetadataResolverAttributes?.httpMaxCacheEntrySize) { + + childNodes() + } } } 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 7628f30de..ce88779f7 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 @@ -6,6 +6,7 @@ import edu.internet2.tier.shibboleth.admin.ui.domain.EntityAttributesFilter import edu.internet2.tier.shibboleth.admin.ui.domain.EntityAttributesFilterTarget 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 import edu.internet2.tier.shibboleth.admin.util.AttributeUtility import org.opensaml.saml.metadata.resolver.ChainingMetadataResolver import org.opensaml.saml.metadata.resolver.MetadataResolver @@ -82,6 +83,9 @@ class IncommonJPAMetadataResolverServiceImplTests extends Specification { @Autowired MetadataResolverRepository metadataResolverRepository + @Autowired + AttributeUtility attributeUtility + @Bean MetadataResolver metadataResolver() { def resolver = new ChainingMetadataResolver().with { @@ -97,8 +101,10 @@ class IncommonJPAMetadataResolverServiceImplTests extends Specification { } 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") + //Generate and test edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.FileBackedHttpMetadataResolver. Add more as + // we implement them + def mr = new TestObjectGenerator(attributeUtility).fileBackedHttpMetadataResolver() + mr.setName("HTTPMetadata") metadataResolverRepository.save(mr) } diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAMetadataResolverServiceImplTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAMetadataResolverServiceImplTests.groovy index a20ce8eb9..c6ee49871 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAMetadataResolverServiceImplTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAMetadataResolverServiceImplTests.groovy @@ -134,7 +134,9 @@ class JPAMetadataResolverServiceImplTests extends Specification { def resolver = testObjectGenerator.fileBackedHttpMetadataResolver() when: - genXmlSnippet(markupBuilder) { JPAMetadataResolverServiceImpl.cast(metadataResolverService).constructXmlNodeFor(resolver, it) } + genXmlSnippet(markupBuilder) { + JPAMetadataResolverServiceImpl.cast(metadataResolverService).constructXmlNodeForResolver(resolver, it) {} + } then: assert generatedXmlIsTheSameAsExpectedXml('/conf/532.xml', domBuilder.parseText(writer.toString())) From 8c4221c0ce916f35ca22ba13ea5f27ca33decbf0 Mon Sep 17 00:00:00 2001 From: Bill Smith Date: Mon, 11 Jun 2018 10:17:13 -0700 Subject: [PATCH 5/7] [SHIBUI-517] Updated/fixed tests WIP. --- ...HttpMetadataProviderControllerTests.groovy | 8 +++ .../admin/ui/util/TestObjectGenerator.groovy | 50 +++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/FileBackedHttpMetadataProviderControllerTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/FileBackedHttpMetadataProviderControllerTests.groovy index 1cf30ab69..f70b69e5b 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/FileBackedHttpMetadataProviderControllerTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/FileBackedHttpMetadataProviderControllerTests.groovy @@ -7,8 +7,11 @@ import edu.internet2.tier.shibboleth.admin.ui.configuration.SearchConfiguration import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.FileBackedHttpMetadataResolver import edu.internet2.tier.shibboleth.admin.ui.repository.FileBackedHttpMetadataResolverRepository import edu.internet2.tier.shibboleth.admin.ui.util.RandomGenerator +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.springframework.beans.factory.annotation.Autowired import org.springframework.boot.autoconfigure.domain.EntityScan import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest import org.springframework.data.jpa.repository.config.EnableJpaRepositories @@ -30,14 +33,19 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. @EntityScan("edu.internet2.tier.shibboleth.admin.ui") class FileBackedHttpMetadataProviderControllerTests extends Specification { RandomGenerator randomGenerator + TestObjectGenerator testObjectGenerator ObjectMapper mapper + @Autowired + AttributeUtility attributeUtility + def repository = Mock(FileBackedHttpMetadataResolverRepository) def controller def mockMvc def setup() { randomGenerator = new RandomGenerator() + testObjectGenerator = new TestObjectGenerator(attributeUtility) mapper = new ObjectMapper() controller = new FileBackedHttpMetadataProviderController ( 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 b8adc23d0..54d771f5b 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 @@ -35,6 +35,28 @@ class TestObjectGenerator { this.attributeUtility = attributeUtility } + HttpMetadataResolverAttributes buildHttpMetadataResolverAttributes() { + def attributes = new HttpMetadataResolverAttributes().with { + it.disregardTLSCertificate = generator.randomBoolean() + it.connectionRequestTimeout = generator.randomString(10) + it.httpClientRef = generator.randomString(10) + it.httpCacheDirectory = generator.randomString(10) + it.httpCaching = randomHttpCachingType() + it.httpClientSecurityParametersRef = generator.randomString(10) + it.httpMaxCacheEntries = generator.randomInt(1, 10) + it.httpMaxCacheEntrySize = generator.randomInt(100, 10000) + it.proxyHost = generator.randomString(10) + it.proxyPassword = generator.randomString(10) + it.proxyPort = generator.randomString(5) + it.proxyUser = generator.randomString(10) + it.requestTimeout = generator.randomString(10) + it.socketTimeout = generator.randomString(10) + it.tlsTrustEngineRef = generator.randomString(10) + it + } + return attributes + } + List buildFilterList() { List filterList = new ArrayList<>() (1..generator.randomInt(4, 10)).each { @@ -212,6 +234,34 @@ class TestObjectGenerator { } } + FileBackedHttpMetadataResolver buildFileBackedHttpMetadataResolver() { + def resolver = new FileBackedHttpMetadataResolver() + resolver.name = generator.randomString(10) + resolver.requireValidMetadata = generator.randomBoolean() + resolver.failFastInitialization = generator.randomBoolean() + resolver.sortKey = generator.randomInt(0, 10) + resolver.criterionPredicateRegistryRef = generator.randomString(10) + resolver.useDefaultPredicateRegistry = generator.randomBoolean() + resolver.satisfyAnyPredicates = generator.randomBoolean() + resolver.metadataFilters = buildFilterList() + resolver.reloadableMetadataResolverAttributes = buildReloadableMetadataResolverAttributes() + resolver.httpMetadataResolverAttributes = buildHttpMetadataResolverAttributes() + return resolver + } + + ReloadableMetadataResolverAttributes buildReloadableMetadataResolverAttributes() { + def attributes = new ReloadableMetadataResolverAttributes() + attributes.parserPoolRef = generator.randomString(10) + attributes.taskTimerRef = generator.randomString(10) + attributes.minRefreshDelay = generator.randomString(5) + attributes.maxRefreshDelay = generator.randomString(5) + attributes.refreshDelayFactor = generator.randomInt(0, 5) + attributes.indexesRef = generator.randomString(10) + attributes.resolveViaPredicatesOnly = generator.randomBoolean() + attributes.expirationWarningThreshold = generator.randomString(10) + return attributes + } + /** * This method takes a type and a size and builds a List of that size containing objects of that type. This is * intended to be used with things that extend LocalizedName such as {@link OrganizationName}, {@link OrganizationDisplayName}, From cccd2220ab9e521c792f0df57139a256729cf94f Mon Sep 17 00:00:00 2001 From: Bill Smith Date: Mon, 11 Jun 2018 10:31:51 -0700 Subject: [PATCH 6/7] [SHIBUI-517] Continuing unit tests WIP. Investigating recursion. --- .../HttpMetadataResolverAttributes.java | 2 +- ...HttpMetadataProviderControllerTests.groovy | 45 ++----------------- .../admin/ui/util/TestObjectGenerator.groovy | 6 ++- 3 files changed, 10 insertions(+), 43 deletions(-) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/HttpMetadataResolverAttributes.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/HttpMetadataResolverAttributes.java index f286fca01..706c34e08 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/HttpMetadataResolverAttributes.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/HttpMetadataResolverAttributes.java @@ -52,7 +52,7 @@ public class HttpMetadataResolverAttributes { private Integer httpMaxCacheEntrySize; - private enum HttpCachingType { + public enum HttpCachingType { none,file,memory } } diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/FileBackedHttpMetadataProviderControllerTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/FileBackedHttpMetadataProviderControllerTests.groovy index f70b69e5b..fe7686402 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/FileBackedHttpMetadataProviderControllerTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/FileBackedHttpMetadataProviderControllerTests.groovy @@ -272,48 +272,11 @@ class FileBackedHttpMetadataProviderControllerTests extends Specification { def "GET by resolver name returns the desired persisted resolver"() { given: - def randomResolverName = randomGenerator.randomString(10) - def resolverJson = """{ - "name": "$randomResolverName", - "requireValidMetadata": true, - "failFastInitialization": true, - "sortKey": 7, - "criterionPredicateRegistryRef": "criterionPredicateRegistryRef", - "useDefaultPredicateRegistry": true, - "satisfyAnyPredicates": true, - "metadataFilters": [], - "reloadableMetadataResolverAttributes": { - "parserPoolRef": "parserPoolRef", - "taskTimerRef": "taskTimerRef", - "minRefreshDelay": "minRefreshDelay", - "maxRefreshDelay": "maxRefreshDelay", - "refreshDelayFactor": 1.0, - "indexesRef": "indexesRef", - "resolveViaPredicatesOnly": true, - "expirationWarningThreshold": "expirationWarningThreshold" - }, - "httpMetadataResolverAttributes": { - "httpClientRef": "httpClientRef", - "connectionRequestTimeout": "connectionRequestTimeout", - "requestTimeout": "requestTimeout", - "socketTimeout": "socketTimeout", - "disregardTLSCertificate": true, - "tlsTrustEngineRef": "tlsTrustEngineRef", - "httpClientSecurityParametersRef": "httpClientSecurityParametersRef", - "proxyHost": "proxyHost", - "proxyPort": "proxyPort", - "proxyUser": "proxyUser", - "proxyPassword": "proxyPassword", - "httpCaching": "none", - "httpCacheDirectory": "httpCacheDirectory", - "httpMaxCacheEntries": 1, - "httpMaxCacheEntrySize": 2 - } -}""" + def randomResolver = testObjectGenerator.buildFileBackedHttpMetadataResolver() + def randomResolverName = randomResolver.name + def resolverJson = mapper.writeValueAsString(randomResolver) - def resolver = new ObjectMapper().readValue(resolverJson.bytes, FileBackedHttpMetadataResolver) - - 1 * repository.findByName(randomResolverName) >> resolver + 1 * repository.findByName(randomResolverName) >> randomResolver def expectedResponseContentType = APPLICATION_JSON_UTF8 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 54d771f5b..3a3605a90 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 @@ -49,9 +49,9 @@ class TestObjectGenerator { it.proxyPassword = generator.randomString(10) it.proxyPort = generator.randomString(5) it.proxyUser = generator.randomString(10) - it.requestTimeout = generator.randomString(10) it.socketTimeout = generator.randomString(10) it.tlsTrustEngineRef = generator.randomString(10) + it.connectionTimeout = generator.randomString(10) it } return attributes @@ -262,6 +262,10 @@ class TestObjectGenerator { return attributes } + HttpMetadataResolverAttributes.HttpCachingType randomHttpCachingType() { + HttpMetadataResolverAttributes.HttpCachingType.values()[generator.randomInt(0, 2)] + } + /** * This method takes a type and a size and builds a List of that size containing objects of that type. This is * intended to be used with things that extend LocalizedName such as {@link OrganizationName}, {@link OrganizationDisplayName}, From 61a524a49ca0bdfcb058ea154cfb9e0d3ff28bbf Mon Sep 17 00:00:00 2001 From: Bill Smith Date: Mon, 11 Jun 2018 11:12:45 -0700 Subject: [PATCH 7/7] [SHIBUI-517] Fixed all tests. --- ...HttpMetadataProviderControllerTests.groovy | 369 ++---------------- ...HttpMetadataResolverRepositoryTests.groovy | 2 +- .../admin/ui/util/TestObjectGenerator.groovy | 2 +- 3 files changed, 43 insertions(+), 330 deletions(-) diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/FileBackedHttpMetadataProviderControllerTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/FileBackedHttpMetadataProviderControllerTests.groovy index fe7686402..19975e843 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/FileBackedHttpMetadataProviderControllerTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/FileBackedHttpMetadataProviderControllerTests.groovy @@ -85,44 +85,10 @@ class FileBackedHttpMetadataProviderControllerTests extends Specification { def "POST a new resolver properly persists and returns the new persisted resolver"() { given: - def postedJsonBody = '''{ - "name": "name", - "requireValidMetadata": true, - "failFastInitialization": true, - "sortKey": 7, - "criterionPredicateRegistryRef": "criterionPredicateRegistryRef", - "useDefaultPredicateRegistry": true, - "satisfyAnyPredicates": true, - "metadataFilters": [], - "reloadableMetadataResolverAttributes": { - "parserPoolRef": "parserPoolRef", - "taskTimerRef": "taskTimerRef", - "minRefreshDelay": "minRefreshDelay", - "maxRefreshDelay": "maxRefreshDelay", - "refreshDelayFactor": 1.0, - "indexesRef": "indexesRef", - "resolveViaPredicatesOnly": true, - "expirationWarningThreshold": "expirationWarningThreshold" - }, - "httpMetadataResolverAttributes": { - "httpClientRef": "httpClientRef", - "connectionRequestTimeout": "connectionRequestTimeout", - "requestTimeout": "requestTimeout", - "socketTimeout": "socketTimeout", - "disregardTLSCertificate": true, - "tlsTrustEngineRef": "tlsTrustEngineRef", - "httpClientSecurityParametersRef": "httpClientSecurityParametersRef", - "proxyHost": "proxyHost", - "proxyPort": "proxyPort", - "proxyUser": "proxyUser", - "proxyPassword": "proxyPassword", - "httpCaching": "none", - "httpCacheDirectory": "httpCacheDirectory", - "httpMaxCacheEntries": 1, - "httpMaxCacheEntrySize": 2 - } -}''' - def resolver = new ObjectMapper().readValue(postedJsonBody.bytes, FileBackedHttpMetadataResolver) + def resolver = testObjectGenerator.buildFileBackedHttpMetadataResolver() + resolver.version = resolver.hashCode() + def postedJsonBody = mapper.writeValueAsString(resolver) + 1 * repository.findByName(resolver.getName()) >> null 1 * repository.save(_) >> resolver @@ -145,46 +111,13 @@ class FileBackedHttpMetadataProviderControllerTests extends Specification { def "POST a new resolver that has a name of a persisted resolver returns conflict"() { given: - def randomResolverName = randomGenerator.randomString(10) - def postedJsonBody = """{ - "name": "$randomResolverName", - "requireValidMetadata": true, - "failFastInitialization": true, - "sortKey": 7, - "criterionPredicateRegistryRef": "criterionPredicateRegistryRef", - "useDefaultPredicateRegistry": true, - "satisfyAnyPredicates": true, - "metadataFilters": [], - "reloadableMetadataResolverAttributes": { - "parserPoolRef": "parserPoolRef", - "taskTimerRef": "taskTimerRef", - "minRefreshDelay": "minRefreshDelay", - "maxRefreshDelay": "maxRefreshDelay", - "refreshDelayFactor": 1.0, - "indexesRef": "indexesRef", - "resolveViaPredicatesOnly": true, - "expirationWarningThreshold": "expirationWarningThreshold" - }, - "httpMetadataResolverAttributes": { - "httpClientRef": "httpClientRef", - "connectionRequestTimeout": "connectionRequestTimeout", - "requestTimeout": "requestTimeout", - "socketTimeout": "socketTimeout", - "disregardTLSCertificate": true, - "tlsTrustEngineRef": "tlsTrustEngineRef", - "httpClientSecurityParametersRef": "httpClientSecurityParametersRef", - "proxyHost": "proxyHost", - "proxyPort": "proxyPort", - "proxyUser": "proxyUser", - "proxyPassword": "proxyPassword", - "httpCaching": "none", - "httpCacheDirectory": "httpCacheDirectory", - "httpMaxCacheEntries": 1, - "httpMaxCacheEntrySize": 2 - } -}""" - def resolver = new ObjectMapper().readValue(postedJsonBody.bytes, FileBackedHttpMetadataResolver) - 1 * repository.findByName(randomResolverName) >> resolver + def existingResolver = testObjectGenerator.buildFileBackedHttpMetadataResolver() + def randomResolverName = existingResolver.name + def newResolver = testObjectGenerator.buildFileBackedHttpMetadataResolver() + newResolver.name = randomResolverName + def postedJsonBody = mapper.writeValueAsString(newResolver) + + 1 * repository.findByName(randomResolverName) >> existingResolver 0 * repository.save(_) when: @@ -199,56 +132,18 @@ class FileBackedHttpMetadataProviderControllerTests extends Specification { def "GET by resourceId returns the desired persisted resolver"() { given: - def randomUUID = randomGenerator.randomId() - def resolverJson = """{ - "name": "name", - "resourceId": "$randomUUID", - "requireValidMetadata": true, - "failFastInitialization": true, - "sortKey": 7, - "criterionPredicateRegistryRef": "criterionPredicateRegistryRef", - "useDefaultPredicateRegistry": true, - "satisfyAnyPredicates": true, - "metadataFilters": [], - "reloadableMetadataResolverAttributes": { - "parserPoolRef": "parserPoolRef", - "taskTimerRef": "taskTimerRef", - "minRefreshDelay": "minRefreshDelay", - "maxRefreshDelay": "maxRefreshDelay", - "refreshDelayFactor": 1.0, - "indexesRef": "indexesRef", - "resolveViaPredicatesOnly": true, - "expirationWarningThreshold": "expirationWarningThreshold" - }, - "httpMetadataResolverAttributes": { - "httpClientRef": "httpClientRef", - "connectionRequestTimeout": "connectionRequestTimeout", - "requestTimeout": "requestTimeout", - "socketTimeout": "socketTimeout", - "disregardTLSCertificate": true, - "tlsTrustEngineRef": "tlsTrustEngineRef", - "httpClientSecurityParametersRef": "httpClientSecurityParametersRef", - "proxyHost": "proxyHost", - "proxyPort": "proxyPort", - "proxyUser": "proxyUser", - "proxyPassword": "proxyPassword", - "httpCaching": "none", - "httpCacheDirectory": "httpCacheDirectory", - "httpMaxCacheEntries": 1, - "httpMaxCacheEntrySize": 2 - } -}""" - - def resolver = new ObjectMapper().readValue(resolverJson.bytes, FileBackedHttpMetadataResolver) - resolver.setResourceId(randomUUID) - - 1 * repository.findByResourceId(randomUUID) >> resolver + def existingResolver = testObjectGenerator.buildFileBackedHttpMetadataResolver() + existingResolver.version = existingResolver.hashCode() + def randomResourceId = existingResolver.resourceId + def resolverJson = mapper.writeValueAsString(existingResolver) + + 1 * repository.findByResourceId(randomResourceId) >> existingResolver def expectedResponseContentType = APPLICATION_JSON_UTF8 when: def result = mockMvc.perform( - get("/api/MetadataProvider/FileBackedHttp/$randomUUID")) + get("/api/MetadataProvider/FileBackedHttp/$randomResourceId")) then: result.andExpect(status().isOk()) @@ -273,6 +168,7 @@ class FileBackedHttpMetadataProviderControllerTests extends Specification { def "GET by resolver name returns the desired persisted resolver"() { given: def randomResolver = testObjectGenerator.buildFileBackedHttpMetadataResolver() + randomResolver.version = randomResolver.hashCode() def randomResolverName = randomResolver.name def resolverJson = mapper.writeValueAsString(randomResolver) @@ -306,89 +202,15 @@ class FileBackedHttpMetadataProviderControllerTests extends Specification { def "PUT allows for a successful update of an already-persisted resolver"() { given: - def randomResourceId = "resourceId" - def existingResolverJson = """{ - "name": "name", - "resourceId": "$randomResourceId", - "requireValidMetadata": true, - "failFastInitialization": true, - "sortKey": 7, - "criterionPredicateRegistryRef": "criterionPredicateRegistryRef", - "useDefaultPredicateRegistry": true, - "satisfyAnyPredicates": true, - "metadataFilters": [], - "reloadableMetadataResolverAttributes": { - "parserPoolRef": "parserPoolRef", - "taskTimerRef": "taskTimerRef", - "minRefreshDelay": "minRefreshDelay", - "maxRefreshDelay": "maxRefreshDelay", - "refreshDelayFactor": 1.0, - "indexesRef": "indexesRef", - "resolveViaPredicatesOnly": true, - "expirationWarningThreshold": "expirationWarningThreshold" - }, - "httpMetadataResolverAttributes": { - "httpClientRef": "httpClientRef", - "connectionRequestTimeout": "connectionRequestTimeout", - "requestTimeout": "requestTimeout", - "socketTimeout": "socketTimeout", - "disregardTLSCertificate": true, - "tlsTrustEngineRef": "tlsTrustEngineRef", - "httpClientSecurityParametersRef": "httpClientSecurityParametersRef", - "proxyHost": "proxyHost", - "proxyPort": "proxyPort", - "proxyUser": "proxyUser", - "proxyPassword": "proxyPassword", - "httpCaching": "none", - "httpCacheDirectory": "httpCacheDirectory", - "httpMaxCacheEntries": 1, - "httpMaxCacheEntrySize": 2 - } -}""" - def existingResolver = new ObjectMapper().readValue(existingResolverJson.bytes, FileBackedHttpMetadataResolver) - def existingResolverVersion = existingResolver.hashCode() - - def randomName = randomGenerator.randomString(10) - def postedJsonBody = """{ - "name": "$randomName", - "resourceId": "$randomResourceId", - "version": "$existingResolverVersion", - "requireValidMetadata": true, - "failFastInitialization": true, - "sortKey": 7, - "criterionPredicateRegistryRef": "criterionPredicateRegistryRef", - "useDefaultPredicateRegistry": true, - "satisfyAnyPredicates": true, - "metadataFilters": [], - "reloadableMetadataResolverAttributes": { - "parserPoolRef": "parserPoolRef", - "taskTimerRef": "taskTimerRef", - "minRefreshDelay": "minRefreshDelay", - "maxRefreshDelay": "maxRefreshDelay", - "refreshDelayFactor": 1.0, - "indexesRef": "indexesRef", - "resolveViaPredicatesOnly": true, - "expirationWarningThreshold": "expirationWarningThreshold" - }, - "httpMetadataResolverAttributes": { - "httpClientRef": "httpClientRef", - "connectionRequestTimeout": "connectionRequestTimeout", - "requestTimeout": "requestTimeout", - "socketTimeout": "socketTimeout", - "disregardTLSCertificate": true, - "tlsTrustEngineRef": "tlsTrustEngineRef", - "httpClientSecurityParametersRef": "httpClientSecurityParametersRef", - "proxyHost": "proxyHost", - "proxyPort": "proxyPort", - "proxyUser": "proxyUser", - "proxyPassword": "proxyPassword", - "httpCaching": "none", - "httpCacheDirectory": "httpCacheDirectory", - "httpMaxCacheEntries": 1, - "httpMaxCacheEntrySize": 2 - } -}""" - def updatedResolver = new ObjectMapper().readValue(postedJsonBody.bytes, FileBackedHttpMetadataResolver) + def existingResolver = testObjectGenerator.buildFileBackedHttpMetadataResolver() + existingResolver.version = existingResolver.hashCode() + def randomResourceId = existingResolver.resourceId + def updatedResolver = testObjectGenerator.buildFileBackedHttpMetadataResolver() + updatedResolver.version = existingResolver.version + updatedResolver.resourceId = existingResolver.resourceId + def postedJsonBody = mapper.writeValueAsString(updatedResolver) + + 1 * repository.findByResourceId(randomResourceId) >> existingResolver 1 * repository.save(_) >> updatedResolver @@ -410,89 +232,14 @@ class FileBackedHttpMetadataProviderControllerTests extends Specification { def "PUT of an updated resolver with an incorrect version returns a conflict"() { given: - def randomResourceId = "resourceId" - def existingResolverJson = """{ - "name": "name", - "resourceId": "$randomResourceId", - "requireValidMetadata": true, - "failFastInitialization": true, - "sortKey": 7, - "criterionPredicateRegistryRef": "criterionPredicateRegistryRef", - "useDefaultPredicateRegistry": true, - "satisfyAnyPredicates": true, - "metadataFilters": [], - "reloadableMetadataResolverAttributes": { - "parserPoolRef": "parserPoolRef", - "taskTimerRef": "taskTimerRef", - "minRefreshDelay": "minRefreshDelay", - "maxRefreshDelay": "maxRefreshDelay", - "refreshDelayFactor": 1.0, - "indexesRef": "indexesRef", - "resolveViaPredicatesOnly": true, - "expirationWarningThreshold": "expirationWarningThreshold" - }, - "httpMetadataResolverAttributes": { - "httpClientRef": "httpClientRef", - "connectionRequestTimeout": "connectionRequestTimeout", - "requestTimeout": "requestTimeout", - "socketTimeout": "socketTimeout", - "disregardTLSCertificate": true, - "tlsTrustEngineRef": "tlsTrustEngineRef", - "httpClientSecurityParametersRef": "httpClientSecurityParametersRef", - "proxyHost": "proxyHost", - "proxyPort": "proxyPort", - "proxyUser": "proxyUser", - "proxyPassword": "proxyPassword", - "httpCaching": "none", - "httpCacheDirectory": "httpCacheDirectory", - "httpMaxCacheEntries": 1, - "httpMaxCacheEntrySize": 2 - } -}""" - def existingResolver = new ObjectMapper().readValue(existingResolverJson.bytes, FileBackedHttpMetadataResolver) - def existingResolverVersion = existingResolver.hashCode() - - def randomName = randomGenerator.randomString(10) - def randomVersion = randomGenerator.randomInt() - def postedJsonBody = """{ - "name": "$randomName", - "resourceId": "$randomResourceId", - "version": "$randomVersion", - "requireValidMetadata": true, - "failFastInitialization": true, - "sortKey": 7, - "criterionPredicateRegistryRef": "criterionPredicateRegistryRef", - "useDefaultPredicateRegistry": true, - "satisfyAnyPredicates": true, - "metadataFilters": [], - "reloadableMetadataResolverAttributes": { - "parserPoolRef": "parserPoolRef", - "taskTimerRef": "taskTimerRef", - "minRefreshDelay": "minRefreshDelay", - "maxRefreshDelay": "maxRefreshDelay", - "refreshDelayFactor": 1.0, - "indexesRef": "indexesRef", - "resolveViaPredicatesOnly": true, - "expirationWarningThreshold": "expirationWarningThreshold" - }, - "httpMetadataResolverAttributes": { - "httpClientRef": "httpClientRef", - "connectionRequestTimeout": "connectionRequestTimeout", - "requestTimeout": "requestTimeout", - "socketTimeout": "socketTimeout", - "disregardTLSCertificate": true, - "tlsTrustEngineRef": "tlsTrustEngineRef", - "httpClientSecurityParametersRef": "httpClientSecurityParametersRef", - "proxyHost": "proxyHost", - "proxyPort": "proxyPort", - "proxyUser": "proxyUser", - "proxyPassword": "proxyPassword", - "httpCaching": "none", - "httpCacheDirectory": "httpCacheDirectory", - "httpMaxCacheEntries": 1, - "httpMaxCacheEntrySize": 2 - } -}""" + def existingResolver = testObjectGenerator.buildFileBackedHttpMetadataResolver() + existingResolver.version = existingResolver.hashCode() + def randomResourceId = existingResolver.resourceId + def updatedResolver = testObjectGenerator.buildFileBackedHttpMetadataResolver() + updatedResolver.version = updatedResolver.hashCode() + updatedResolver.resourceId = existingResolver.resourceId + def postedJsonBody = mapper.writeValueAsString(updatedResolver) + 1 * repository.findByResourceId(randomResourceId) >> existingResolver 0 * repository.save(_) @@ -508,45 +255,11 @@ class FileBackedHttpMetadataProviderControllerTests extends Specification { def "PUT of a resolver that is not persisted returns not found"() { given: - def randomResourceId = randomGenerator.randomId() - def postedJsonBody = """{ - "name": "name", - "resourceId": "$randomResourceId", - "requireValidMetadata": true, - "failFastInitialization": true, - "sortKey": 7, - "criterionPredicateRegistryRef": "criterionPredicateRegistryRef", - "useDefaultPredicateRegistry": true, - "satisfyAnyPredicates": true, - "metadataFilters": [], - "reloadableMetadataResolverAttributes": { - "parserPoolRef": "parserPoolRef", - "taskTimerRef": "taskTimerRef", - "minRefreshDelay": "minRefreshDelay", - "maxRefreshDelay": "maxRefreshDelay", - "refreshDelayFactor": 1.0, - "indexesRef": "indexesRef", - "resolveViaPredicatesOnly": true, - "expirationWarningThreshold": "expirationWarningThreshold" - }, - "httpMetadataResolverAttributes": { - "httpClientRef": "httpClientRef", - "connectionRequestTimeout": "connectionRequestTimeout", - "requestTimeout": "requestTimeout", - "socketTimeout": "socketTimeout", - "disregardTLSCertificate": true, - "tlsTrustEngineRef": "tlsTrustEngineRef", - "httpClientSecurityParametersRef": "httpClientSecurityParametersRef", - "proxyHost": "proxyHost", - "proxyPort": "proxyPort", - "proxyUser": "proxyUser", - "proxyPassword": "proxyPassword", - "httpCaching": "none", - "httpCacheDirectory": "httpCacheDirectory", - "httpMaxCacheEntries": 1, - "httpMaxCacheEntrySize": 2 - } -}""" + def randomResolver = testObjectGenerator.buildFileBackedHttpMetadataResolver() + randomResolver.version = randomResolver.hashCode() + def randomResourceId = randomResolver.resourceId + def postedJsonBody = mapper.writeValueAsString(randomResolver) + 1 * repository.findByResourceId(randomResourceId) >> null 0 * repository.save(_) diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/FileBackedHttpMetadataResolverRepositoryTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/FileBackedHttpMetadataResolverRepositoryTests.groovy index 5074750ea..c68667042 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/FileBackedHttpMetadataResolverRepositoryTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/repository/FileBackedHttpMetadataResolverRepositoryTests.groovy @@ -97,7 +97,7 @@ class FileBackedHttpMetadataResolverRepositoryTests extends Specification { "httpMetadataResolverAttributes": { "httpClientRef": "httpClientRef", "connectionRequestTimeout": "connectionRequestTimeout", - "requestTimeout": "requestTimeout", + "connectionTimeout": "connectionTimeout", "socketTimeout": "socketTimeout", "disregardTLSCertificate": true, "tlsTrustEngineRef": "tlsTrustEngineRef", 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 3a3605a90..da541f5ed 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 @@ -243,7 +243,7 @@ class TestObjectGenerator { resolver.criterionPredicateRegistryRef = generator.randomString(10) resolver.useDefaultPredicateRegistry = generator.randomBoolean() resolver.satisfyAnyPredicates = generator.randomBoolean() - resolver.metadataFilters = buildFilterList() + resolver.metadataFilters = [] resolver.reloadableMetadataResolverAttributes = buildReloadableMetadataResolverAttributes() resolver.httpMetadataResolverAttributes = buildHttpMetadataResolverAttributes() return resolver