Skip to content

Commit

Permalink
Merged in SHIBUI-526 (pull request #90)
Browse files Browse the repository at this point in the history
SHIBUI-526

Approved-by: Shibui Jenkins <shibui.jenkins@gmail.com>
Approved-by: Bill Smith <wsmith@unicon.net>
Approved-by: Dmitriy Kopylenko <dkopylenko@unicon.net>
  • Loading branch information
dima767 authored and Jonathan Johnson committed Jun 22, 2018
2 parents c75fe2d + dbfe084 commit debfc00
Show file tree
Hide file tree
Showing 12 changed files with 146 additions and 31 deletions.
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
package edu.internet2.tier.shibboleth.admin.ui.service;

import com.google.common.base.Predicate;
import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilter;
import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilterTarget
import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.DynamicHttpMetadataResolver
import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.LocalDynamicMetadataResolver
import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects;

import com.google.common.base.Predicate

import com.google.common.base.Predicate
import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilter
import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilterTarget
import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityRoleWhiteListFilter

import edu.internet2.tier.shibboleth.admin.ui.domain.filters.RequiredValidUntilFilter

import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.FileBackedHttpMetadataResolver

Expand Down Expand Up @@ -111,10 +106,6 @@ class JPAMetadataResolverServiceImpl implements MetadataResolverService {
'requireSignedRoot': 'true',
'certificateFile': '%{idp.home}/credentials/inc-md-cert.pem'
)
MetadataFilter(
'xsi:type': 'RequiredValidUntil',
'maxValidityInterval': 'P14D'
)
//TODO: enhance
mr.metadataFilters.each { edu.internet2.tier.shibboleth.admin.ui.domain.filters.MetadataFilter filter ->
constructXmlNodeForFilter(filter, delegate)
Expand Down Expand Up @@ -199,6 +190,13 @@ class JPAMetadataResolverServiceImpl implements MetadataResolverService {
}
}

void constructXmlNodeForFilter(RequiredValidUntilFilter filter, def markupBuilderDelegate) {
markupBuilderDelegate.MetadataFilter(
'xsi:type': 'RequiredValidUntil',
maxValidityInterval: filter.maxValidityInterval
)
}

void constructXmlNodeForResolver(FileBackedHttpMetadataResolver resolver, def markupBuilderDelegate, Closure childNodes) {
markupBuilderDelegate.MetadataProvider(id: resolver.name,
'xsi:type': 'FileBackedHTTPMetadataProvider',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilter;
import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityRoleWhiteListFilter;
import edu.internet2.tier.shibboleth.admin.ui.domain.filters.MetadataFilter;
import edu.internet2.tier.shibboleth.admin.ui.domain.filters.RequiredValidUntilFilter;
import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.FilterRepresentation;
import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolver;
import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolverRepository;
Expand Down Expand Up @@ -168,6 +169,11 @@ else if(filterWithUpdatedData instanceof EntityRoleWhiteListFilter) {
toFilter.setRemoveRolelessEntityDescriptors(fromFilter.getRemoveRolelessEntityDescriptors());
toFilter.setRetainedRoles(fromFilter.getRetainedRoles());
}
else if(filterWithUpdatedData instanceof RequiredValidUntilFilter) {
RequiredValidUntilFilter toFilter = RequiredValidUntilFilter.class.cast(filterToBeUpdated);
RequiredValidUntilFilter fromFilter = RequiredValidUntilFilter.class.cast(filterWithUpdatedData);
toFilter.setMaxValidityInterval(fromFilter.getMaxValidityInterval());
}
//TODO: add other types of concrete filters update here
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@
@ToString
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "@type", visible = true)
@JsonSubTypes({@JsonSubTypes.Type(value=EntityRoleWhiteListFilter.class, name="EntityRoleWhiteList"),
@JsonSubTypes.Type(value=EntityAttributesFilter.class, name="EntityAttributes")})
@JsonSubTypes.Type(value=EntityAttributesFilter.class, name="EntityAttributes"),
@JsonSubTypes.Type(value=RequiredValidUntilFilter.class, name="RequiredValidUntil")})
public class MetadataFilter extends AbstractAuditable {

@JsonProperty("@type")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package edu.internet2.tier.shibboleth.admin.ui.domain.filters;

import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

import javax.persistence.Entity;

@Entity
@EqualsAndHashCode(callSuper = true)
@Getter
@Setter
@ToString
public class RequiredValidUntilFilter extends MetadataFilter {

public RequiredValidUntilFilter() {
type = "RequiredValidUntil";
}

private String maxValidityInterval;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.fasterxml.jackson.databind.SerializationFeature
import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilter
import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityRoleWhiteListFilter
import edu.internet2.tier.shibboleth.admin.ui.domain.filters.MetadataFilter
import edu.internet2.tier.shibboleth.admin.ui.domain.filters.RequiredValidUntilFilter
import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects
import edu.internet2.tier.shibboleth.admin.ui.util.TestObjectGenerator
import edu.internet2.tier.shibboleth.admin.util.AttributeUtility
Expand Down Expand Up @@ -74,28 +75,54 @@ class PolymorphicFiltersJacksonHandlingTests extends Specification {
simulatedPrePersistentFilter.relyingPartyOverrides = simulatedPersistentFilter.relyingPartyOverrides
simulatedPrePersistentFilter.fromTransientRepresentation()

expect:
simulatedPersistentFilter.attributes.size() == simulatedPrePersistentFilter.attributes.size()
}

def "Correct polymorphic serialization of RequiredValidUntilFilter"() {
given:
def givenFilterJson = """
{
"@type" : "RequiredValidUntil",
"createdDate" : null,
"modifiedDate" : null,
"createdBy" : null,
"modifiedBy" : null,
"name" : null,
"resourceId" : "9667ae04-8c36-4741-be62-dd325e7d6790",
"filterEnabled" : true,
"version" : 0,
"maxValidityInterval" : "P14D"
}
"""

when:
def jsonFromPersistentFilter = mapper.writeValueAsString(simulatedPersistentFilter)
def jsonFromPrePersistentFilter = mapper.writeValueAsString(simulatedPrePersistentFilter)
println("JSON from persistent filter -> $jsonFromPersistentFilter")
println("JSON from PRE persistent filter -> $jsonFromPrePersistentFilter")
println("Attributes from persistent filter -> $simulatedPersistentFilter.attributes")
println("Attributes from PRE persistent filter -> $simulatedPrePersistentFilter.attributes")
def deSerializedFilter = mapper.readValue(givenFilterJson, MetadataFilter)
def json = mapper.writeValueAsString(deSerializedFilter)
println(json)
def roundTripFilter = mapper.readValue(json, MetadataFilter)

then:
simulatedPersistentFilter.attributes.size() == simulatedPrePersistentFilter.attributes.size()
roundTripFilter == deSerializedFilter

and:
deSerializedFilter instanceof RequiredValidUntilFilter
roundTripFilter instanceof RequiredValidUntilFilter
}

def "List of filters with correct types"() {
given:
def filters = testObjectGenerator.buildAllTypesOfFilterList();
def filters = testObjectGenerator.buildAllTypesOfFilterList()

when:
def json = mapper.writeValueAsString(filters)
println(json)

then:
json
json.contains('EntityAttributes')
json.contains('RequiredValidUntil')
json.contains('EntityAttributes')

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import edu.internet2.tier.shibboleth.admin.ui.configuration.CoreShibUiConfigurat
import edu.internet2.tier.shibboleth.admin.ui.configuration.SearchConfiguration
import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilter
import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilterTarget
import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityRoleWhiteListFilter
import edu.internet2.tier.shibboleth.admin.ui.domain.filters.RequiredValidUntilFilter
import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects
import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolverRepository
import edu.internet2.tier.shibboleth.admin.ui.util.TestObjectGenerator
Expand All @@ -19,8 +21,7 @@ import org.springframework.context.annotation.Bean
import org.springframework.data.jpa.repository.config.EnableJpaRepositories
import org.springframework.test.annotation.DirtiesContext
import org.springframework.test.context.ContextConfiguration
import org.xmlunit.builder.DiffBuilder
import org.xmlunit.builder.Input

import spock.lang.Specification

import static edu.internet2.tier.shibboleth.admin.ui.util.TestHelpers.*
Expand All @@ -43,6 +44,10 @@ class IncommonJPAMetadataResolverServiceImplTests extends Specification {

def 'simple test generation of metadata-providers.xml'() {
when:
def mr = metadataResolverRepository.findAll().iterator().next()
mr.metadataFilters << requiredValidUntilFilterForXmlGenerationTests()
mr.metadataFilters << entityRoleWhiteListFilterForXmlGenerationTests()
metadataResolverRepository.save(mr)
def output = metadataResolverService.generateConfiguration()

println(output.documentElement)
Expand All @@ -55,6 +60,7 @@ class IncommonJPAMetadataResolverServiceImplTests extends Specification {
when:
//TODO: this might break later
def mr = metadataResolverRepository.findAll().iterator().next()
mr.metadataFilters << requiredValidUntilFilterForXmlGenerationTests()
mr.metadataFilters.add(new EntityAttributesFilter().with {
it.entityAttributesFilterTarget = new EntityAttributesFilterTarget().with {
it.entityAttributesFilterTargetType = EntityAttributesFilterTarget.EntityAttributesFilterTargetType.ENTITY
Expand All @@ -70,6 +76,7 @@ class IncommonJPAMetadataResolverServiceImplTests extends Specification {
it.attributes = [attribute]
it
})
mr.metadataFilters << entityRoleWhiteListFilterForXmlGenerationTests()
metadataResolverRepository.save(mr)

def output = metadataResolverService.generateConfiguration()
Expand All @@ -78,6 +85,20 @@ class IncommonJPAMetadataResolverServiceImplTests extends Specification {
generatedXmlIsTheSameAsExpectedXml('/conf/278.2.xml', output)
}

EntityRoleWhiteListFilter entityRoleWhiteListFilterForXmlGenerationTests() {
new EntityRoleWhiteListFilter().with {
it.retainedRoles = ['md:SPSSODescriptor']
it
}
}

RequiredValidUntilFilter requiredValidUntilFilterForXmlGenerationTests() {
new RequiredValidUntilFilter().with {
it.maxValidityInterval = 'P14D'
it
}
}

//TODO: check that this configuration is sufficient
@TestConfiguration
static class TestConfig {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import edu.internet2.tier.shibboleth.admin.ui.configuration.CoreShibUiConfigurat
import edu.internet2.tier.shibboleth.admin.ui.configuration.SearchConfiguration
import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilter
import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilterTarget
import edu.internet2.tier.shibboleth.admin.ui.domain.filters.RequiredValidUntilFilter
import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects
import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolverRepository

Expand Down Expand Up @@ -139,6 +140,21 @@ class JPAMetadataResolverServiceImplTests extends Specification {

then:
generatedXmlIsTheSameAsExpectedXml('/conf/533.xml', domBuilder.parseText(writer.toString()))

}

def 'test generating RequiredValidUntilFilter xml snippet'() {
given:
def filter = new RequiredValidUntilFilter().with {
it.maxValidityInterval = 'P14D'
it
}

when:
genXmlSnippet(markupBuilder) { JPAMetadataResolverServiceImpl.cast(metadataResolverService).constructXmlNodeForFilter(filter, it) }

then:
generatedXmlIsTheSameAsExpectedXml('/conf/552.xml', domBuilder.parseText(writer.toString()))
}

def 'test generating FileBackedHttMetadataResolver xml snippet'() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,11 @@ class TestHelpers {
}

static void generatedXmlIsTheSameAsExpectedXml(String expectedXmlResource, Document generatedXml) {
assert !DiffBuilder.compare(Input.fromStream(TestHelpers.getResourceAsStream(expectedXmlResource))).withTest(Input.fromDocument(generatedXml))
.ignoreComments().ignoreWhitespace().build().hasDifferences()

assert !DiffBuilder.compare(Input.fromStream(TestHelpers.getResourceAsStream(expectedXmlResource)))
.withTest(Input.fromDocument(generatedXml))
.ignoreComments()
.ignoreWhitespace()
.build()
.hasDifferences()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFil
import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilterTarget
import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityRoleWhiteListFilter
import edu.internet2.tier.shibboleth.admin.ui.domain.filters.MetadataFilter
import edu.internet2.tier.shibboleth.admin.ui.domain.filters.RequiredValidUntilFilter
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.*
import edu.internet2.tier.shibboleth.admin.util.AttributeUtility
import edu.internet2.tier.shibboleth.admin.util.MDDCConstants

import org.opensaml.saml.saml2.metadata.Organization

import java.util.function.Supplier
Expand Down Expand Up @@ -119,6 +121,7 @@ class TestObjectGenerator {
(1..generator.randomInt(4, 10)).each {
filterList.add(buildFilter { entityAttributesFilter() })
filterList.add(buildFilter { entityRoleWhitelistFilter() })
filterList.add(buildFilter { requiredValidUntilFilter() })
}
return filterList
}
Expand All @@ -142,6 +145,13 @@ class TestObjectGenerator {
}
}

RequiredValidUntilFilter requiredValidUntilFilter() {
return new RequiredValidUntilFilter().with {
it.maxValidityInterval = 'P14D'
it
}
}

EntityAttributesFilter copyOf(EntityAttributesFilter entityAttributesFilter) {
new EntityAttributesFilter().with {
it.name = entityAttributesFilter.name
Expand Down
7 changes: 4 additions & 3 deletions backend/src/test/resources/conf/278.2.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@
</saml:Attribute>
<Entity>https://sp1.example.org</Entity>
</MetadataFilter>
<MetadataFilter xsi:type="EntityRoleWhiteList" xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata">
<RetainedRole>md:SPSSODescriptor</RetainedRole>
</MetadataFilter>
</MetadataProvider>
<MetadataProvider id="HTTPMetadata"
xsi:type="FileBackedHTTPMetadataProvider"
Expand All @@ -42,14 +45,12 @@
refreshDelayFactor="0.75">
<MetadataFilter xsi:type="SignatureValidation" requireSignedRoot="true"
certificateFile="%{idp.home}/credentials/inc-md-cert.pem" />
<MetadataFilter xsi:type="RequiredValidUntil" maxValidityInterval="P14D" />
</MetadataProvider>
<MetadataProvider id="LocalDynamic"
initializeFromPersistentCacheInBackground="true"
removeIdleEntityData="true"
xsi:type="DynamicHttpMetadataProvider">
<MetadataFilter certificateFile="%{idp.home}/credentials/inc-md-cert.pem" requireSignedRoot="true" xsi:type="SignatureValidation"/>
<MetadataFilter maxValidityInterval="P14D" xsi:type="RequiredValidUntil"/>
</MetadataProvider>

</MetadataProvider>
</MetadataProvider>
7 changes: 4 additions & 3 deletions backend/src/test/resources/conf/278.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
xsi:type="DynamicHttpMetadataProvider">
<MetadataFilter certificateFile="%{idp.home}/credentials/inc-md-cert.pem" requireSignedRoot="true" xsi:type="SignatureValidation"/>
<MetadataFilter maxValidityInterval="P14D" xsi:type="RequiredValidUntil"/>
<MetadataFilter xsi:type="EntityRoleWhiteList" xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata">
<RetainedRole>md:SPSSODescriptor</RetainedRole>
</MetadataFilter>
</MetadataProvider>
<MetadataProvider id="HTTPMetadata"
xsi:type="FileBackedHTTPMetadataProvider"
Expand All @@ -35,13 +38,11 @@
refreshDelayFactor="0.75">
<MetadataFilter xsi:type="SignatureValidation" requireSignedRoot="true"
certificateFile="%{idp.home}/credentials/inc-md-cert.pem" />
<MetadataFilter xsi:type="RequiredValidUntil" maxValidityInterval="P14D" />
</MetadataProvider>
<MetadataProvider id="LocalDynamic"
initializeFromPersistentCacheInBackground="true"
removeIdleEntityData="true"
xsi:type="DynamicHttpMetadataProvider">
<MetadataFilter certificateFile="%{idp.home}/credentials/inc-md-cert.pem" requireSignedRoot="true" xsi:type="SignatureValidation"/>
<MetadataFilter maxValidityInterval="P14D" xsi:type="RequiredValidUntil"/>
</MetadataProvider>
</MetadataProvider>
</MetadataProvider>
9 changes: 9 additions & 0 deletions backend/src/test/resources/conf/552.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- This file is an EXAMPLE metadata configuration file. -->
<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">
<MetadataFilter xsi:type="RequiredValidUntil" maxValidityInterval="P14D" />
</MetadataProvider>

0 comments on commit debfc00

Please sign in to comment.