diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/AbstractDescriptor.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/AbstractDescriptor.java index d1cf5a4ea..1f6075f24 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/AbstractDescriptor.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/AbstractDescriptor.java @@ -1,5 +1,6 @@ package edu.internet2.tier.shibboleth.admin.ui.domain; +import lombok.EqualsAndHashCode; import org.hibernate.annotations.Type; import org.joda.time.DateTime; import org.opensaml.core.xml.XMLObject; @@ -16,6 +17,7 @@ @MappedSuperclass +@EqualsAndHashCode(callSuper = true) public abstract class AbstractDescriptor extends AbstractAttributeExtensibleXMLObject implements CacheableSAMLObject, TimeBoundSAMLObject, SignableXMLObject { private Long cacheDuration; diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/AbstractElementExtensibleXMLObject.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/AbstractElementExtensibleXMLObject.java index 605cf718d..d406e8256 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/AbstractElementExtensibleXMLObject.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/AbstractElementExtensibleXMLObject.java @@ -1,5 +1,6 @@ package edu.internet2.tier.shibboleth.admin.ui.domain; +import lombok.EqualsAndHashCode; import org.opensaml.core.xml.ElementExtensibleXMLObject; import org.opensaml.core.xml.XMLObject; @@ -18,6 +19,7 @@ @Entity @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) +@EqualsAndHashCode(callSuper = true) public abstract class AbstractElementExtensibleXMLObject extends AbstractXMLObject implements ElementExtensibleXMLObject { @OneToMany(cascade = CascadeType.ALL) @OrderColumn diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/UIInfo.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/UIInfo.java index 77b0dbd79..f7912aa65 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/UIInfo.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/UIInfo.java @@ -60,7 +60,7 @@ public List getLogos() { return this.xmlObjects.stream().filter(p -> p instanceof Logo).map(p -> (Logo) p).collect(Collectors.toList()); } - public void addLog(edu.internet2.tier.shibboleth.admin.ui.domain.Logo logo) { + public void addLogo(edu.internet2.tier.shibboleth.admin.ui.domain.Logo logo) { this.xmlObjects.add(logo); } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/opensaml/OpenSamlObjects.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/opensaml/OpenSamlObjects.java index 3a7114eb0..8a25b0855 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/opensaml/OpenSamlObjects.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/opensaml/OpenSamlObjects.java @@ -5,6 +5,7 @@ import net.shibboleth.utilities.java.support.component.ComponentInitializationException; import net.shibboleth.utilities.java.support.xml.BasicParserPool; import net.shibboleth.utilities.java.support.xml.ParserPool; +import net.shibboleth.utilities.java.support.xml.XMLParserException; import org.opensaml.core.config.ConfigurationService; import org.opensaml.core.config.InitializationException; import org.opensaml.core.xml.XMLObject; @@ -15,6 +16,7 @@ import org.opensaml.core.xml.io.MarshallingException; import org.opensaml.core.xml.io.Unmarshaller; import org.opensaml.core.xml.io.UnmarshallerFactory; +import org.opensaml.core.xml.io.UnmarshallingException; import org.opensaml.saml.saml2.metadata.EntityDescriptor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -130,6 +132,17 @@ public EntityDescriptor unmarshalFromXml(byte[] entityDescriptorXml) throws Exce } } + public T unmarshallFromXml(byte[] xml, Class type) throws IOException, XMLParserException, UnmarshallingException { + try (InputStream is = ByteSource.wrap(xml).openBufferedStream()) { + Document d = this.parserPool.parse(is); + Unmarshaller unmarshaller = this.unmarshallerFactory.getUnmarshaller(d.getDocumentElement()); + if (unmarshaller != null) { + return type.cast(unmarshaller.unmarshall(d.getDocumentElement())); + } + return null; + } + } + // TODO: yeah, I'm not happy with this... public T buildDefaultInstanceOfType(Class type) { try { diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImpl.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImpl.java index 78dec7d12..168e977a5 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImpl.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/JPAEntityDescriptorServiceImpl.java @@ -43,7 +43,6 @@ import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.SecurityInfoRepresentation; import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.ServiceProviderSsoDescriptorRepresentation; import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects; -import edu.internet2.tier.shibboleth.admin.ui.security.model.User; import edu.internet2.tier.shibboleth.admin.ui.security.service.UserService; import edu.internet2.tier.shibboleth.admin.util.MDDCConstants; import edu.internet2.tier.shibboleth.admin.util.ModelRepresentationConversions; @@ -59,6 +58,7 @@ import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -178,6 +178,8 @@ void setupSecurity(EntityDescriptor ed, EntityDescriptorRepresentation represent if (securityInfoRepresentation.isWantAssertionsSigned()) { getSPSSODescriptorFromEntityDescriptor(ed).setWantAssertionsSigned(true); } + // TODO: review if we need more than a naive implementation + ed.getOptionalSPSSODescriptor().ifPresent( i -> i.getKeyDescriptors().clear()); if (securityInfoRepresentation.isX509CertificateAvailable()) { for (SecurityInfoRepresentation.X509CertificateRepresentation x509CertificateRepresentation : securityInfoRepresentation.getX509Certificates()) { KeyDescriptor keyDescriptor = createKeyDescriptor(x509CertificateRepresentation.getName(), x509CertificateRepresentation.getType(), x509CertificateRepresentation.getValue()); @@ -196,6 +198,8 @@ void setupSecurity(EntityDescriptor ed, EntityDescriptorRepresentation represent void setupUIInfo(EntityDescriptor ed, EntityDescriptorRepresentation representation) { // set up mdui if (representation.getMdui() != null) { + // TODO: check if we need more than a naive implementation + removeUIInfo(ed); MduiRepresentation mduiRepresentation = representation.getMdui(); if (!Strings.isNullOrEmpty(mduiRepresentation.getDisplayName())) { @@ -248,7 +252,7 @@ void setupUIInfo(EntityDescriptor ed, EntityDescriptorRepresentation representat if (!Strings.isNullOrEmpty(mduiRepresentation.getLogoUrl())) { Logo logo = openSamlObjects.buildDefaultInstanceOfType(Logo.class); - getUIInfo(ed).addLog(logo); + getUIInfo(ed).addLogo(logo); logo.setURL(mduiRepresentation.getLogoUrl()); logo.setHeight(mduiRepresentation.getLogoHeight()); logo.setWidth(mduiRepresentation.getLogoWidth()); @@ -320,6 +324,7 @@ void setupSPSSODescriptor(EntityDescriptor ed, EntityDescriptorRepresentation re if (representation.getServiceProviderSsoDescriptor() != null) { SPSSODescriptor spssoDescriptor = getSPSSODescriptorFromEntityDescriptor(ed); + spssoDescriptor.setSupportedProtocols(Collections.EMPTY_LIST); if (!Strings.isNullOrEmpty(representation.getServiceProviderSsoDescriptor().getProtocolSupportEnum())) { spssoDescriptor.setSupportedProtocols( Arrays.stream(representation.getServiceProviderSsoDescriptor().getProtocolSupportEnum().split(",")).map(p -> MDDCConstants.PROTOCOL_BINDINGS.get(p.trim())).collect(Collectors.toList()) @@ -388,7 +393,7 @@ private Attribute createAttributeWithArbitraryValues(String name, String friendl return createAttributeWithArbitraryValues(name, friendlyName, values.toArray(new String[]{})); } - private KeyDescriptor createKeyDescriptor(String name, String type, String value) { + KeyDescriptor createKeyDescriptor(String name, String type, String value) { KeyDescriptor keyDescriptor = openSamlObjects.buildDefaultInstanceOfType(KeyDescriptor.class); if (!Strings.isNullOrEmpty(name)) { diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/AuxiliaryJPAEntityDescriptorServiceImplTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/AuxiliaryJPAEntityDescriptorServiceImplTests.groovy index 85f1202c6..f78f8d354 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/AuxiliaryJPAEntityDescriptorServiceImplTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/AuxiliaryJPAEntityDescriptorServiceImplTests.groovy @@ -1,18 +1,36 @@ package edu.internet2.tier.shibboleth.admin.ui.service +import edu.internet2.tier.shibboleth.admin.ui.domain.ContactPerson +import edu.internet2.tier.shibboleth.admin.ui.domain.Description +import edu.internet2.tier.shibboleth.admin.ui.domain.DisplayName +import edu.internet2.tier.shibboleth.admin.ui.domain.EmailAddress import edu.internet2.tier.shibboleth.admin.ui.domain.EntityDescriptor +import edu.internet2.tier.shibboleth.admin.ui.domain.Extensions +import edu.internet2.tier.shibboleth.admin.ui.domain.GivenName +import edu.internet2.tier.shibboleth.admin.ui.domain.InformationURL +import edu.internet2.tier.shibboleth.admin.ui.domain.KeyDescriptor +import edu.internet2.tier.shibboleth.admin.ui.domain.Logo +import edu.internet2.tier.shibboleth.admin.ui.domain.NameIDFormat +import edu.internet2.tier.shibboleth.admin.ui.domain.PrivacyStatementURL import edu.internet2.tier.shibboleth.admin.ui.domain.SPSSODescriptor import edu.internet2.tier.shibboleth.admin.ui.domain.SingleLogoutService +import edu.internet2.tier.shibboleth.admin.ui.domain.UIInfo +import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.ContactRepresentation import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.EntityDescriptorRepresentation import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.LogoutEndpointRepresentation +import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.MduiRepresentation +import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.SecurityInfoRepresentation +import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.ServiceProviderSsoDescriptorRepresentation import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects +import org.opensaml.saml.common.xml.SAMLConstants +import org.opensaml.saml.saml2.metadata.ContactPersonTypeEnumeration import spock.lang.Shared import spock.lang.Specification import spock.lang.Unroll class AuxiliaryJPAEntityDescriptorServiceImplTests extends Specification { @Shared - def openSAMLObjects = new OpenSamlObjects().with { + OpenSamlObjects openSAMLObjects = new OpenSamlObjects().with { it.init() it } @@ -28,6 +46,26 @@ class AuxiliaryJPAEntityDescriptorServiceImplTests extends Specification { assert true } + // this is a stub to build out the DataFields + def "pretest"() { + given: + def dataField = new Data.DataField( + method: 'setupLogout', + description: 'no change', + representation: new EntityDescriptorRepresentation(), + starter: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class), + expected: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class) + ) + + when: + def (expected, starter) = [dataField.expected, dataField.starter] + expected.setResourceId(starter.getResourceId()) + entityDescriptorService."${dataField.method}"(starter, dataField.representation) + + then: + assert expected == starter + } + @Unroll def "test #method(#description)"() { setup: @@ -38,11 +76,59 @@ class AuxiliaryJPAEntityDescriptorServiceImplTests extends Specification { assert starter == expected where: - [method, description, representation, starter, expected] << Data.getData(openSAMLObjects) + [method, description, representation, starter, expected] << Data.getData(openSAMLObjects) + } + + def "test createKeyDescriptor, single type"() { + given: + def expectedXml = ''' + + + testValue + + +''' + def expected = openSAMLObjects.unmarshallFromXml(expectedXml.bytes, KeyDescriptor) + expected.name = 'testName' + + when: + def keyDescriptor = entityDescriptorService.createKeyDescriptor('testName', 'signing', 'testValue') + + then: + assert keyDescriptor == expected + } + + def "test createKeyDescriptor, both type"() { + given: + def expectedXml = ''' + + + testValue + + +''' + def expected = openSAMLObjects.unmarshallFromXml(expectedXml.bytes, KeyDescriptor) + expected.name = 'testName' + + when: + def keyDescriptor = entityDescriptorService.createKeyDescriptor('testName', 'both', 'testValue') + def x = openSAMLObjects.marshalToXmlString(keyDescriptor) + then: + assert keyDescriptor == expected + } + + def 'test createKeyDescriptor equality'() { + when: + def key1 = entityDescriptorService.createKeyDescriptor('test', 'signing', 'test') + def key2 = entityDescriptorService.createKeyDescriptor('test', 'signing', 'test') + + then: + assert key1.equals(key2) } static class Data { static def getData(OpenSamlObjects openSAMLObjects) { + JPAEntityDescriptorServiceImpl entityDescriptorService = new JPAEntityDescriptorServiceImpl(openSAMLObjects, null, null) def data = [] data << new DataField( @@ -138,10 +224,895 @@ class AuxiliaryJPAEntityDescriptorServiceImplTests extends Specification { it }, ) + data << new DataField( + method: 'setupContacts', + description: 'add contact to empty descriptor', + representation: new EntityDescriptorRepresentation().with { + it.contacts = [new ContactRepresentation(type: 'administrative', name: 'name', emailAddress: 'test@test', displayName: 'displayName', url: 'http://url')] + it + }, + starter: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class), + expected: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class).with { + it.contactPersons = [openSAMLObjects.buildDefaultInstanceOfType(ContactPerson.class).with { + it.type = ContactPersonTypeEnumeration.ADMINISTRATIVE + it.givenName = openSAMLObjects.buildDefaultInstanceOfType(GivenName.class).with { + it.name = 'name' + it + } + it.emailAddresses.add(openSAMLObjects.buildDefaultInstanceOfType(EmailAddress.class).with { + it.address = 'test@test' + it + }) + it + }] + it + } + ) + data << new DataField( + method: 'setupContacts', + description: 'add contant to non-empty descriptor', + representation: new EntityDescriptorRepresentation().with { + it.contacts = [ + new ContactRepresentation(type: 'administrative', name: 'name', emailAddress: 'test@test', displayName: 'displayName', url: 'http://url'), + new ContactRepresentation(type: 'technical', name: 'name2', emailAddress: 'test2@test', displayName: 'displayName2', url: 'http://url2') + ] + it + }, + starter: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class).with { + it.contactPersons = [openSAMLObjects.buildDefaultInstanceOfType(ContactPerson.class).with { + it.type = ContactPersonTypeEnumeration.ADMINISTRATIVE + it.givenName = openSAMLObjects.buildDefaultInstanceOfType(GivenName.class).with { + it.name = 'name' + it + } + it.emailAddresses.add(openSAMLObjects.buildDefaultInstanceOfType(EmailAddress.class).with { + it.address = 'test@test' + it + }) + it + }] + it + }, + expected: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class).with { + it.contactPersons = [ + openSAMLObjects.buildDefaultInstanceOfType(ContactPerson.class).with { + it.type = ContactPersonTypeEnumeration.ADMINISTRATIVE + it.givenName = openSAMLObjects.buildDefaultInstanceOfType(GivenName.class).with { + it.name = 'name' + it + } + it.emailAddresses.add(openSAMLObjects.buildDefaultInstanceOfType(EmailAddress.class).with { + it.address = 'test@test' + it + }) + it + }, + openSAMLObjects.buildDefaultInstanceOfType(ContactPerson.class).with { + it.type = ContactPersonTypeEnumeration.TECHNICAL + it.givenName = openSAMLObjects.buildDefaultInstanceOfType(GivenName.class).with { + it.name = 'name2' + it + } + it.emailAddresses.add(openSAMLObjects.buildDefaultInstanceOfType(EmailAddress.class).with { + it.address = 'test2@test' + it + }) + it + }] + it + } + ) + data << new DataField( + method: 'setupContacts', + description: 'update contact', + representation: new EntityDescriptorRepresentation().with { + it.contacts = [new ContactRepresentation(type: 'technical', name: 'name2', emailAddress: 'test2@test', displayName: 'displayName', url: 'http://url')] + it + }, + starter: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class).with { + it.contactPersons = [openSAMLObjects.buildDefaultInstanceOfType(ContactPerson.class).with { + it.type = ContactPersonTypeEnumeration.ADMINISTRATIVE + it.givenName = openSAMLObjects.buildDefaultInstanceOfType(GivenName.class).with { + it.name = 'name' + it + } + it.emailAddresses.add(openSAMLObjects.buildDefaultInstanceOfType(EmailAddress.class).with { + it.address = 'test@test' + it + }) + it + }] + it + }, + expected: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class).with { + it.contactPersons = [openSAMLObjects.buildDefaultInstanceOfType(ContactPerson.class).with { + it.type = ContactPersonTypeEnumeration.TECHNICAL + it.givenName = openSAMLObjects.buildDefaultInstanceOfType(GivenName.class).with { + it.name = 'name2' + it + } + it.emailAddresses.add(openSAMLObjects.buildDefaultInstanceOfType(EmailAddress.class).with { + it.address = 'test2@test' + it + }) + it + }] + it + } + ) + data << new DataField( + method: 'setupContacts', + description: 'delete contacts', + representation: new EntityDescriptorRepresentation(), + starter: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class).with { + it.contactPersons = [openSAMLObjects.buildDefaultInstanceOfType(ContactPerson.class).with { + it.type = ContactPersonTypeEnumeration.ADMINISTRATIVE + it.givenName = openSAMLObjects.buildDefaultInstanceOfType(GivenName.class).with { + it.name = 'name' + it + } + it.emailAddresses.add(openSAMLObjects.buildDefaultInstanceOfType(EmailAddress.class).with { + it.address = 'test@test' + it + }) + it + }] + it + }, + expected: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class) + ) + data << new DataField( + method: 'setupSPSSODescriptor', + description: 'set SPSSODescriptor protocol support', + representation: new EntityDescriptorRepresentation().with { + it.serviceProviderSsoDescriptor = new ServiceProviderSsoDescriptorRepresentation().with { + it.protocolSupportEnum = 'SAML 2' + it + } + it + }, + starter: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class), + expected: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class).with { + it.getRoleDescriptors().add( + openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor.class).with { + it.supportedProtocols = [SAMLConstants.SAML20P_NS] + it + } + ) + it + } + ) + data << new DataField( + method: 'setupSPSSODescriptor', + description: 'add SPSSODescriptor protocol support', + representation: new EntityDescriptorRepresentation().with { + it.serviceProviderSsoDescriptor = new ServiceProviderSsoDescriptorRepresentation().with { + it.protocolSupportEnum = 'SAML 1.1,SAML 2' + it + } + it + }, + starter: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class).with { + it.getRoleDescriptors().add( + openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor.class).with { + it.supportedProtocols = [SAMLConstants.SAML20P_NS] + it + } + ) + it + }, + expected: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class).with { + it.getRoleDescriptors().add( + openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor.class).with { + it.supportedProtocols = [SAMLConstants.SAML11P_NS, SAMLConstants.SAML20P_NS] + it + } + ) + it + } + ) + data << new DataField( + method: 'setupSPSSODescriptor', + description: 'remove SPSSODescriptor', + representation: new EntityDescriptorRepresentation(), + starter: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class).with { + it.getRoleDescriptors().add( + openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor.class).with { + it.supportedProtocols = [SAMLConstants.SAML20P_NS] + it + } + ) + it + }, + expected: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class) + ) + data << new DataField( + method: 'setupSPSSODescriptor', + description: 'set nameid formats', + representation: new EntityDescriptorRepresentation().with { + it.serviceProviderSsoDescriptor = new ServiceProviderSsoDescriptorRepresentation().with { + it.nameIdFormats = ['testformat'] + it + } + it + }, + starter: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class), + expected: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class).with { + it.getRoleDescriptors().add( + openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor.class).with { + it.nameIDFormats.add(openSAMLObjects.buildDefaultInstanceOfType(NameIDFormat.class).with { + it.format = 'testformat' + it + }) + it + } + ) + it + } + ) + data << new DataField( + method: 'setupSPSSODescriptor', + description: 'add nameid formats', + representation: new EntityDescriptorRepresentation().with { + it.serviceProviderSsoDescriptor = new ServiceProviderSsoDescriptorRepresentation().with { + it.nameIdFormats = ['testformat', 'anotherformat'] + it + } + it + }, + starter: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class).with { + it.getRoleDescriptors().add( + openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor.class).with { + it.nameIDFormats.add(openSAMLObjects.buildDefaultInstanceOfType(NameIDFormat.class).with { + it.format = 'testformat' + it + }) + it + } + ) + it + }, + expected: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class).with { + it.getRoleDescriptors().add( + openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor.class).with { + it.nameIDFormats.add(openSAMLObjects.buildDefaultInstanceOfType(NameIDFormat.class).with { + it.format = 'testformat' + it + }) + it.nameIDFormats.add(openSAMLObjects.buildDefaultInstanceOfType(NameIDFormat.class).with { + it.format = 'anotherformat' + it + }) + it + } + ) + it + } + ) + data << new DataField( + method: 'setupSPSSODescriptor', + description: 'remove nameid format', + representation: new EntityDescriptorRepresentation().with { + it.serviceProviderSsoDescriptor = new ServiceProviderSsoDescriptorRepresentation().with { + it.nameIdFormats = ['anotherformat'] + it + } + it + }, + starter: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class).with { + it.getRoleDescriptors().add( + openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor.class).with { + it.nameIDFormats.add(openSAMLObjects.buildDefaultInstanceOfType(NameIDFormat.class).with { + it.format = 'testformat' + it + }) + it.nameIDFormats.add(openSAMLObjects.buildDefaultInstanceOfType(NameIDFormat.class).with { + it.format = 'anotherformat' + it + }) + it + } + ) + it + }, + expected: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class).with { + it.getRoleDescriptors().add( + openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor.class).with { + it.nameIDFormats.add(openSAMLObjects.buildDefaultInstanceOfType(NameIDFormat.class).with { + it.format = 'anotherformat' + it + }) + it + } + ) + it + } + ) + data << new DataField( + method: 'setupSecurity', + description: 'set authentication requests signed to true', + representation: new EntityDescriptorRepresentation().with { + it.securityInfo = new SecurityInfoRepresentation(authenticationRequestsSigned: true) + it + }, + starter: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class), + expected: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class).with { + it.getRoleDescriptors().add( + openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor.class).with { + it.authnRequestsSigned = true + it + } + ) + it + } + ) + data << new DataField( + method: 'setupSecurity', + description: 'unset authentication requests signed to true', + representation: new EntityDescriptorRepresentation(), + starter: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class).with { + it.getRoleDescriptors().add( + openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor.class).with { + it.authnRequestsSigned = true + it + } + ) + it + }, + expected: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class).with { + it.getRoleDescriptors().add( + openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor.class) + ) + it + } + ) + data << new DataField( + method: 'setupSecurity', + description: 'set want assertions signed to true', + representation: new EntityDescriptorRepresentation().with { + it.securityInfo = new SecurityInfoRepresentation(wantAssertionsSigned: true) + it + }, + starter: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class), + expected: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class).with { + it.getRoleDescriptors().add( + openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor.class).with { + it.wantAssertionsSigned = true + it + } + ) + it + } + ) + data << new DataField( + method: 'setupSecurity', + description: 'unset want assertions signed', + representation: new EntityDescriptorRepresentation(), + starter: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class).with { + it.getRoleDescriptors().add( + openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor.class).with { + it.wantAssertionsSigned = true + it + } + ) + it + }, + expected: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class).with { + it.getRoleDescriptors().add( + openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor.class) + ) + it + } + ) + data << new DataField( + method: 'setupSecurity', + description: 'add signing certificate', + representation: new EntityDescriptorRepresentation().with { + it.securityInfo = new SecurityInfoRepresentation().with { + it.x509CertificateAvailable = true + it.x509Certificates = [ + new SecurityInfoRepresentation.X509CertificateRepresentation(name: 'test', type: 'signing', value: 'test') + ] + it + } + it + }, + starter: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class), + expected: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class).with { + it.getRoleDescriptors().add( + openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor.class).with { + it.addKeyDescriptor(entityDescriptorService.createKeyDescriptor('test', 'signing', 'test')) + it + } + ) + it + } + ) + data << new DataField( + method: 'setupSecurity', + description: 'add another certificate', + representation: new EntityDescriptorRepresentation().with { + it.securityInfo = new SecurityInfoRepresentation().with { + it.x509CertificateAvailable = true + it.x509Certificates = [ + new SecurityInfoRepresentation.X509CertificateRepresentation(name: 'test', type: 'signing', value: 'test'), + new SecurityInfoRepresentation.X509CertificateRepresentation(name: 'test2', type: 'encryption', value: 'test2') + ] + it + } + it + }, + starter: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class).with { + it.getRoleDescriptors().add( + openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor.class).with { + it.addKeyDescriptor(entityDescriptorService.createKeyDescriptor('test', 'signing', 'test')) + it + } + ) + it + }, + expected: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class).with { + it.getRoleDescriptors().add( + openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor.class).with { + it.addKeyDescriptor(entityDescriptorService.createKeyDescriptor('test', 'signing', 'test')) + it.addKeyDescriptor(entityDescriptorService.createKeyDescriptor('test2', 'encryption', 'test2')) + it + } + ) + it + } + ) + data << new DataField( + method: 'setupSecurity', + description: 'remove a certificate', + representation: new EntityDescriptorRepresentation().with { + it.securityInfo = new SecurityInfoRepresentation().with { + it.x509CertificateAvailable = true + it.x509Certificates = [ + new SecurityInfoRepresentation.X509CertificateRepresentation(name: 'test2', type: 'encryption', value: 'test2') + ] + it + } + it + }, + starter: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class).with { + it.getRoleDescriptors().add( + openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor.class).with { + it.addKeyDescriptor(entityDescriptorService.createKeyDescriptor('test', 'signing', 'test')) + it.addKeyDescriptor(entityDescriptorService.createKeyDescriptor('test2', 'encryption', 'test2')) + it + } + ) + it + }, + expected: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class).with { + it.getRoleDescriptors().add( + openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor.class).with { + it.addKeyDescriptor(entityDescriptorService.createKeyDescriptor('test2', 'encryption', 'test2')) + it + } + ) + it + } + ) + data << new DataField( + method: 'setupSecurity', + description: 'remove all certificates', + representation: new EntityDescriptorRepresentation().with { + it.securityInfo = new SecurityInfoRepresentation().with { + it.x509CertificateAvailable = false + it + } + it + }, + starter: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class).with { + it.getRoleDescriptors().add( + openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor.class).with { + it.addKeyDescriptor(entityDescriptorService.createKeyDescriptor('test', 'signing', 'test')) + it.addKeyDescriptor(entityDescriptorService.createKeyDescriptor('test', 'encryption', 'test')) + it + } + ) + it + }, + expected: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class).with { + it.getRoleDescriptors().add( + openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor.class) + ) + it + } + ) + data << new DataField( + method: 'setupSecurity', + description: 'remove all certificates', + representation: new EntityDescriptorRepresentation(), + starter: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class).with { + it.getRoleDescriptors().add( + openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor.class).with { + it.addKeyDescriptor(entityDescriptorService.createKeyDescriptor('test', 'signing', 'test')) + it.addKeyDescriptor(entityDescriptorService.createKeyDescriptor('test', 'encryption', 'test')) + it + } + ) + it + }, + expected: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor.class).with { + it.getRoleDescriptors().add( + openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor.class) + ) + it + } + ) + data << new DataField( + method: 'setupUIInfo', + description: 'set display name', + representation: new EntityDescriptorRepresentation().with { + it.mdui = new MduiRepresentation().with { + it.displayName = 'test name' + it + } + it + }, + starter: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor), + expected: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor).with { + it.roleDescriptors.add(openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor).with { + it.extensions = openSAMLObjects.buildDefaultInstanceOfType(Extensions).with { + it.unknownXMLObjects.add(openSAMLObjects.buildDefaultInstanceOfType(UIInfo).with { + it.XMLObjects.add(openSAMLObjects.buildDefaultInstanceOfType(DisplayName).with { + it.value = 'test name' + it.XMLLang = 'en' + it + }) + it + }) + it + } + it + }) + it + } + ) + data << new DataField( + method: 'setupUIInfo', + description: 'remove display name', + representation: new EntityDescriptorRepresentation().with { + it.mdui = new MduiRepresentation().with { + it + } + it + }, + starter: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor).with { + it.roleDescriptors.add(openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor).with { + it.extensions = openSAMLObjects.buildDefaultInstanceOfType(Extensions).with { + it.unknownXMLObjects.add(openSAMLObjects.buildDefaultInstanceOfType(UIInfo).with { + it.XMLObjects.add(openSAMLObjects.buildDefaultInstanceOfType(DisplayName).with { + it.value = 'test name' + it.XMLLang = 'en' + it + }) + it + }) + it + } + it + }) + it + }, + expected: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor).with { + it.roleDescriptors.add(openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor).with { + it.extensions = openSAMLObjects.buildDefaultInstanceOfType(Extensions).with { + it + } + it + }) + it + } + ) + data << new DataField( + method: 'setupUIInfo', + description: 'set information URL', + representation: new EntityDescriptorRepresentation().with { + it.mdui = new MduiRepresentation().with { + it.informationUrl = 'http://test' + it + } + it + }, + starter: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor), + expected: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor).with { + it.roleDescriptors.add(openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor).with { + it.extensions = openSAMLObjects.buildDefaultInstanceOfType(Extensions).with { + it.unknownXMLObjects.add(openSAMLObjects.buildDefaultInstanceOfType(UIInfo).with { + it.XMLObjects.add(openSAMLObjects.buildDefaultInstanceOfType(InformationURL).with { + it.value = 'http://test' + it.XMLLang = 'en' + it + }) + it + }) + it + } + it + }) + it + } + ) + data << new DataField( + method: 'setupUIInfo', + description: 'remove information url', + representation: new EntityDescriptorRepresentation().with { + it.mdui = new MduiRepresentation().with { + it + } + it + }, + starter: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor).with { + it.roleDescriptors.add(openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor).with { + it.extensions = openSAMLObjects.buildDefaultInstanceOfType(Extensions).with { + it.unknownXMLObjects.add(openSAMLObjects.buildDefaultInstanceOfType(UIInfo).with { + it.XMLObjects.add(openSAMLObjects.buildDefaultInstanceOfType(InformationURL).with { + it.value = 'http://test' + it.XMLLang = 'en' + it + }) + it + }) + it + } + it + }) + it + }, + expected: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor).with { + it.roleDescriptors.add(openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor).with { + it.extensions = openSAMLObjects.buildDefaultInstanceOfType(Extensions).with { + it + } + it + }) + it + } + ) + data << new DataField( + method: 'setupUIInfo', + description: 'set privacy statement URL', + representation: new EntityDescriptorRepresentation().with { + it.mdui = new MduiRepresentation().with { + it.privacyStatementUrl = 'http://test' + it + } + it + }, + starter: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor), + expected: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor).with { + it.roleDescriptors.add(openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor).with { + it.extensions = openSAMLObjects.buildDefaultInstanceOfType(Extensions).with { + it.unknownXMLObjects.add(openSAMLObjects.buildDefaultInstanceOfType(UIInfo).with { + it.XMLObjects.add(openSAMLObjects.buildDefaultInstanceOfType(PrivacyStatementURL).with { + it.value = 'http://test' + it.XMLLang = 'en' + it + }) + it + }) + it + } + it + }) + it + } + ) + data << new DataField( + method: 'setupUIInfo', + description: 'remove information url', + representation: new EntityDescriptorRepresentation().with { + it.mdui = new MduiRepresentation().with { + it + } + it + }, + starter: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor).with { + it.roleDescriptors.add(openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor).with { + it.extensions = openSAMLObjects.buildDefaultInstanceOfType(Extensions).with { + it.unknownXMLObjects.add(openSAMLObjects.buildDefaultInstanceOfType(UIInfo).with { + it.XMLObjects.add(openSAMLObjects.buildDefaultInstanceOfType(PrivacyStatementURL).with { + it.value = 'http://test' + it.XMLLang = 'en' + it + }) + it + }) + it + } + it + }) + it + }, + expected: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor).with { + it.roleDescriptors.add(openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor).with { + it.extensions = openSAMLObjects.buildDefaultInstanceOfType(Extensions).with { + it + } + it + }) + it + } + ) + data << new DataField( + method: 'setupUIInfo', + description: 'set description', + representation: new EntityDescriptorRepresentation().with { + it.mdui = new MduiRepresentation().with { + it.description = 'test description' + it + } + it + }, + starter: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor), + expected: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor).with { + it.roleDescriptors.add(openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor).with { + it.extensions = openSAMLObjects.buildDefaultInstanceOfType(Extensions).with { + it.unknownXMLObjects.add(openSAMLObjects.buildDefaultInstanceOfType(UIInfo).with { + it.XMLObjects.add(openSAMLObjects.buildDefaultInstanceOfType(Description).with { + it.value = 'test description' + it.XMLLang = 'en' + it + }) + it + }) + it + } + it + }) + it + } + ) + data << new DataField( + method: 'setupUIInfo', + description: 'remove description', + representation: new EntityDescriptorRepresentation().with { + it.mdui = new MduiRepresentation().with { + it + } + it + }, + starter: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor).with { + it.roleDescriptors.add(openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor).with { + it.extensions = openSAMLObjects.buildDefaultInstanceOfType(Extensions).with { + it.unknownXMLObjects.add(openSAMLObjects.buildDefaultInstanceOfType(UIInfo).with { + it.XMLObjects.add(openSAMLObjects.buildDefaultInstanceOfType(Description).with { + it.value = 'test description' + it.XMLLang = 'en' + it + }) + it + }) + it + } + it + }) + it + }, + expected: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor).with { + it.roleDescriptors.add(openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor).with { + it.extensions = openSAMLObjects.buildDefaultInstanceOfType(Extensions).with { + it + } + it + }) + it + } + ) + data << new DataField( + method: 'setupUIInfo', + description: 'set logo', + representation: new EntityDescriptorRepresentation().with { + it.mdui = new MduiRepresentation().with { + it.logoUrl = 'http://test' + it.logoHeight = 5 + it.logoWidth = 25 + it + } + it + }, + starter: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor), + expected: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor).with { + it.roleDescriptors.add(openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor).with { + it.extensions = openSAMLObjects.buildDefaultInstanceOfType(Extensions).with { + it.unknownXMLObjects.add(openSAMLObjects.buildDefaultInstanceOfType(UIInfo).with { + it.XMLObjects.add(openSAMLObjects.buildDefaultInstanceOfType(Logo).with { + it.url = 'http://test' + it.height = 5 + it.width = 25 + it.XMLLang = 'en' + it + }) + it + }) + it + } + it + }) + it + } + ) + data << new DataField( + method: 'setupUIInfo', + description: 'remove logo', + representation: new EntityDescriptorRepresentation().with { + it.mdui = new MduiRepresentation().with { + it + } + it + }, + starter: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor).with { + it.roleDescriptors.add(openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor).with { + it.extensions = openSAMLObjects.buildDefaultInstanceOfType(Extensions).with { + it.unknownXMLObjects.add(openSAMLObjects.buildDefaultInstanceOfType(UIInfo).with { + it.XMLObjects.add(openSAMLObjects.buildDefaultInstanceOfType(Logo).with { + it.url = 'http://test' + it.height = 5 + it.width = 25 + it.XMLLang = 'en' + it + }) + it + }) + it + } + it + }) + it + }, + expected: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor).with { + it.roleDescriptors.add(openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor).with { + it.extensions = openSAMLObjects.buildDefaultInstanceOfType(Extensions).with { + it + } + it + }) + it + } + ) + data << new DataField( + method: 'setupUIInfo', + description: 'remove ui info', + representation: new EntityDescriptorRepresentation().with { + it.serviceProviderSsoDescriptor = new ServiceProviderSsoDescriptorRepresentation() + it + }, + starter: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor).with { + it.roleDescriptors.add(openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor).with { + it.extensions = openSAMLObjects.buildDefaultInstanceOfType(Extensions).with { + it.unknownXMLObjects.add(openSAMLObjects.buildDefaultInstanceOfType(UIInfo).with { + it.XMLObjects.add(openSAMLObjects.buildDefaultInstanceOfType(Logo).with { + it.url = 'http://test' + it.height = 5 + it.width = 25 + it.XMLLang = 'en' + it + }) + it + }) + it + } + it + }) + it + }, + expected: openSAMLObjects.buildDefaultInstanceOfType(EntityDescriptor).with { + it.roleDescriptors.add(openSAMLObjects.buildDefaultInstanceOfType(SPSSODescriptor).with { + it.extensions = openSAMLObjects.buildDefaultInstanceOfType(Extensions) + it + }) + it + } + ) return data } + static class DataField implements Iterable { String method String description