diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorController.java index c2d9b81a0..81d62a1ad 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorController.java @@ -9,6 +9,7 @@ import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects; import edu.internet2.tier.shibboleth.admin.ui.service.EntityDescriptorService; import edu.internet2.tier.shibboleth.admin.ui.service.EntityDescriptorVersionService; +import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tags; import lombok.extern.slf4j.Slf4j; @@ -33,6 +34,7 @@ import javax.annotation.PostConstruct; import java.net.URI; import java.util.ConcurrentModificationException; +import java.util.Optional; @RestController @RequestMapping("/api") @@ -126,9 +128,13 @@ public ResponseEntity getSpecificVersion(@PathVariable String resourceId, @Pa private ResponseEntity handleUploadingEntityDescriptorXml(byte[] rawXmlBytes, String spName) throws Exception { final EntityDescriptor ed = EntityDescriptor.class.cast(openSamlObjects.unmarshalFromXml(rawXmlBytes)); + if (entityDescriptorService.entityExists(ed.getEntityID())) { + throw new ObjectIdExistsException("Entity with ID: " + ed.getEntityID() + "exists"); + } + ed.setServiceProviderName(spName); - - EntityDescriptorRepresentation persistedEd = entityDescriptorService.createNew(ed); + + EntityDescriptorRepresentation persistedEd = entityDescriptorService.createNewEntityDescriptorFromXMLOrigin(ed); return ResponseEntity.created(getResourceUriFor(persistedEd.getId())).body(persistedEd); } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/AttributeConsumingService.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/AttributeConsumingService.java index 632bcb888..9adb45e2e 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/AttributeConsumingService.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/AttributeConsumingService.java @@ -2,6 +2,7 @@ import lombok.EqualsAndHashCode; import org.hibernate.envers.Audited; +import org.opensaml.core.xml.XMLObject; import org.opensaml.core.xml.schema.XSBooleanValue; import javax.persistence.CascadeType; @@ -17,7 +18,6 @@ @EqualsAndHashCode(callSuper = true) @Audited public class AttributeConsumingService extends AbstractXMLObject implements org.opensaml.saml.saml2.metadata.AttributeConsumingService { - private int acsIndex; private boolean isDefault; @@ -93,4 +93,13 @@ public List getRequestedAtt public void setRequestedAttributes(List requestedAttributes) { this.requestedAttributes = requestedAttributes; } + + @Override + public List getOrderedChildren() { + List childXMLObjects = new ArrayList<>(); + childXMLObjects.addAll(serviceNames); + childXMLObjects.addAll(serviceDescriptions); + childXMLObjects.addAll(requestedAttributes); + return childXMLObjects; + } } \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/Description.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/Description.java index db994740a..b86c86b1d 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/Description.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/Description.java @@ -6,6 +6,7 @@ import javax.annotation.Nullable; import javax.persistence.Column; import javax.persistence.Entity; +import javax.persistence.Lob; @Entity @EqualsAndHashCode(callSuper = true) @@ -16,6 +17,7 @@ public class Description extends AbstractXMLObject implements org.opensaml.saml. private String xmlLang; @Column(name = "descriptionValue") + @Lob private String value; @Nullable @@ -39,4 +41,4 @@ public String getValue() { public void setValue(@Nullable String value) { this.value = value; } -} +} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/SPSSODescriptor.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/SPSSODescriptor.java index e90542c5a..52d37bf1f 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/SPSSODescriptor.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/SPSSODescriptor.java @@ -95,7 +95,7 @@ public AssertionConsumerService getDefaultAssertionConsumerService() { @Override public List getAttributeConsumingServices() { - return Lists.newArrayList(attributeConsumingServices); + return (List)(List) attributeConsumingServices; } public void setAttributeConsumingServices(List attributeConsumingServices) { @@ -124,4 +124,4 @@ public List getOrderedChildren() { public Optional getOptionalExtensions() { return Optional.ofNullable(this.getExtensions()); } -} +} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/SurName.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/SurName.java index b6be50f64..031dc8eec 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/SurName.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/SurName.java @@ -18,6 +18,6 @@ public String getValue() { @Override public void setValue(String name) { - this.value = value; + this.value = name; } } \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/EntityDescriptorService.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/EntityDescriptorService.java index b2bf96ac3..6ecf9073e 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/EntityDescriptorService.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/EntityDescriptorService.java @@ -114,4 +114,8 @@ EntityDescriptorRepresentation update(EntityDescriptorRepresentation edRepresent void updateDescriptorFromRepresentation(final org.opensaml.saml.saml2.metadata.EntityDescriptor entityDescriptor, final EntityDescriptorRepresentation representation); EntityDescriptorRepresentation updateEntityDescriptorEnabledStatus(String resourceId, boolean status) throws EntityNotFoundException, ForbiddenException; + + EntityDescriptorRepresentation createNewEntityDescriptorFromXMLOrigin(EntityDescriptor ed); + + boolean entityExists(String entityID); } \ No newline at end of file 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 f6c419b31..ec5c28048 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 @@ -102,11 +102,22 @@ public EntityDescriptor createDescriptorFromRepresentation(final EntityDescripto } @Override - public EntityDescriptorRepresentation createNew(EntityDescriptor ed) - throws ForbiddenException, ObjectIdExistsException, InvalidPatternMatchException { + public EntityDescriptorRepresentation createNew(EntityDescriptor ed) throws ForbiddenException, ObjectIdExistsException, InvalidPatternMatchException { return createNew(createRepresentationFromDescriptor(ed)); } + @Override + public EntityDescriptorRepresentation createNewEntityDescriptorFromXMLOrigin(EntityDescriptor ed) { + ed.setIdOfOwner(userService.getCurrentUserGroup().getOwnerId()); + EntityDescriptor savedEntity = entityDescriptorRepository.save(ed); + return createRepresentationFromDescriptor(savedEntity); + } + + @Override + public boolean entityExists(String entityID) { + return entityDescriptorRepository.findByEntityID(entityID) != null ; + } + @Override public EntityDescriptorRepresentation createNew(EntityDescriptorRepresentation edRep) throws ForbiddenException, ObjectIdExistsException, InvalidPatternMatchException { diff --git a/backend/src/main/resources/db/changelog/changelog.sql b/backend/src/main/resources/db/changelog/changelog.sql index 0a63846a3..f1494b2ca 100644 --- a/backend/src/main/resources/db/changelog/changelog.sql +++ b/backend/src/main/resources/db/changelog/changelog.sql @@ -175,4 +175,24 @@ update file_backed_http_metadata_resolver_aud set max_refresh_delay ='PT4H'; update resource_backed_metadata_resolver set min_refresh_delay ='PT5M'; update resource_backed_metadata_resolver_aud set min_refresh_delay ='PT5M'; update resource_backed_metadata_resolver set max_refresh_delay ='PT4H'; -update resource_backed_metadata_resolver_aud set max_refresh_delay ='PT4H'; \ No newline at end of file +update resource_backed_metadata_resolver_aud set max_refresh_delay ='PT4H'; + +-- changeset liquibase:1.13.0.1 dbms:mariadb,mysql +-- preconditions onFail:MARK_RAN +-- precondition-sql-check expectedResult:1 SELECT count(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = N'users' +-- comment: /* we don't need to run this if the system is new */ + +ALTER TABLE description ALTER COLUMN descriptionValue LONGTEXT; +GO +ALTER TABLE description)aud ALTER COLUMN descriptionValue LONGTEXT; +GO + +-- changeset liquibase:1.13.0.2 dbms:postgresql,mssql +-- preconditions onFail:MARK_RAN +-- precondition-sql-check expectedResult:1 SELECT count(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = N'users' +-- comment: /* we don't need to run this if the system is new */ + +ALTER TABLE description ALTER COLUMN descriptionValue TEXT; +GO +ALTER TABLE description_aud ALTER COLUMN descriptionValue TEXT; +GO \ No newline at end of file diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorControllerTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorControllerTests.groovy index 8861d1613..35bd77ea2 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorControllerTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorControllerTests.groovy @@ -530,6 +530,11 @@ class EntityDescriptorControllerTests extends AbstractBaseDataJpaTest { urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified + + Shrink Space + Shrink Space Authenticator + + ''' @@ -552,6 +557,12 @@ class EntityDescriptorControllerTests extends AbstractBaseDataJpaTest { .andExpect(jsonPath("\$.assertionConsumerServices[0].makeDefault").value(false)) .andExpect(jsonPath("\$.assertionConsumerServices[0].locationUrl").value("https://test.scaldingspoon.org/test1/acs")) + try { + mockMvc.perform(post("/api/EntityDescriptor").contentType(APPLICATION_XML).content(postedBody).param("spName", spName)) + } + catch (Exception e) { + e instanceof ObjectIdExistsException + } } @WithMockAdmin @@ -691,4 +702,4 @@ class EntityDescriptorControllerTests extends AbstractBaseDataJpaTest { e instanceof ConcurrentModificationException } } -} +} \ No newline at end of file diff --git a/testbed/postgres/docker-compose.yml b/testbed/postgres/docker-compose.yml index c66b591a8..1a3dd4d82 100644 --- a/testbed/postgres/docker-compose.yml +++ b/testbed/postgres/docker-compose.yml @@ -18,9 +18,11 @@ services: - 8080:8080 - 5005:5005 - 8443:8443 + - 8000:8000 volumes: - ./conf:/conf - ./conf/application.yml:/application.yml + entrypoint: ["/usr/bin/java", "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:8000", "-jar", "app.war"] networks: - front depends_on: