diff --git a/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataSourcesUiDefinitionController.groovy b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataSourcesUiDefinitionController.groovy index 74f5e6d8c..9d54e5ac0 100644 --- a/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataSourcesUiDefinitionController.groovy +++ b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataSourcesUiDefinitionController.groovy @@ -2,7 +2,7 @@ package edu.internet2.tier.shibboleth.admin.ui.controller import com.fasterxml.jackson.databind.ObjectMapper import edu.internet2.tier.shibboleth.admin.ui.configuration.CustomAttributesConfiguration - +import edu.internet2.tier.shibboleth.admin.ui.jsonschema.MetadataSourcesJsonSchemaResourceLocation import org.springframework.beans.factory.BeanInitializationException import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.context.properties.ConfigurationProperties @@ -23,17 +23,10 @@ import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR * @author Bill Smith (wsmith@unicon.net) */ @RestController('/api/ui/MetadataSources') -@ConfigurationProperties('shibui') class MetadataSourcesUiDefinitionController { - //Configured via @ConfigurationProperties with 'shibui.metadata-sources-ui-schema-location' property and default - //value set here if that property is not explicitly set in application.properties - String metadataSourcesUiSchemaLocation = 'classpath:metadata-sources-ui-schema.json' - - URL jsonSchemaUrl - @Autowired - ResourceLoader resourceLoader + MetadataSourcesJsonSchemaResourceLocation jsonSchemaLocation @Autowired ObjectMapper jacksonObjectMapper @@ -44,7 +37,7 @@ class MetadataSourcesUiDefinitionController { @GetMapping ResponseEntity getUiDefinitionJsonSchema() { try { - def parsedJson = jacksonObjectMapper.readValue(this.jsonSchemaUrl, Map) + def parsedJson = jacksonObjectMapper.readValue(this.jsonSchemaLocation.url, Map) def widget = parsedJson["properties"]["attributeRelease"]["widget"] def data = [] customAttributesConfiguration.getAttributes().each { @@ -59,24 +52,7 @@ class MetadataSourcesUiDefinitionController { catch (Exception e) { return ResponseEntity.status(INTERNAL_SERVER_ERROR) .body([jsonParseError : e.getMessage(), - sourceUiSchemaDefinitionFile: this.jsonSchemaUrl]) - } - } - - @PostConstruct - def init() { - jsonSchemaUrl = this.resourceLoader.getResource(this.metadataSourcesUiSchemaLocation).getURL() - //Detect malformed JSON schema early, during application start up and fail fast with useful exception message - try { - this.jacksonObjectMapper.readValue(this.jsonSchemaUrl, Map) - } - catch (Exception e) { - def msg = """ - An error is detected during JSON parsing => [${e.message}] - ********************************************************** - Offending resource => [${this.jsonSchemaUrl}] - """ - throw new BeanInitializationException(msg.toString(), e) + sourceUiSchemaDefinitionFile: this.jsonSchemaLocation.url]) } } } 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 ec11c9e43..4e6879d0f 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 @@ -205,7 +205,8 @@ class JPAMetadataResolverServiceImpl implements MetadataResolverService { 'xmlns:md': 'urn:oasis:names:tc:SAML:2.0:metadata' ) { filter.retainedRoles.each { - markupBuilderDelegate.RetainedRole(it) + // TODO: fix + markupBuilderDelegate.RetainedRole(it.startsWith('md:') ? it : "md:${it}") } } } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/JsonSchemaValidationComponentsConfiguration.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/JsonSchemaValidationComponentsConfiguration.java new file mode 100644 index 000000000..7e983edeb --- /dev/null +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/JsonSchemaValidationComponentsConfiguration.java @@ -0,0 +1,19 @@ +package edu.internet2.tier.shibboleth.admin.ui.configuration; + +import com.fasterxml.jackson.databind.ObjectMapper; +import edu.internet2.tier.shibboleth.admin.ui.jsonschema.MetadataSourcesJsonSchemaResourceLocation; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ResourceLoader; + +/** + * @author Dmitriy Kopylenko + */ +@Configuration +public class JsonSchemaValidationComponentsConfiguration { + + @Bean + public MetadataSourcesJsonSchemaResourceLocation metadataSourcesJsonSchemaResourceLocation(ResourceLoader resourceLoader, ObjectMapper jacksonMapper) { + return new MetadataSourcesJsonSchemaResourceLocation(resourceLoader, jacksonMapper); + } +} diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/MetadataResolverConfiguration.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/MetadataResolverConfiguration.java index 0222ba46e..ad407cfb5 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/MetadataResolverConfiguration.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/MetadataResolverConfiguration.java @@ -5,6 +5,8 @@ import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolverRepository; import edu.internet2.tier.shibboleth.admin.ui.service.IndexWriterService; import edu.internet2.tier.shibboleth.admin.ui.service.MetadataResolverConverterService; +import edu.internet2.tier.shibboleth.admin.ui.service.TokenPlaceholderValueResolvingService; +import edu.internet2.tier.shibboleth.admin.util.TokenPlaceholderResolvers; import net.shibboleth.utilities.java.support.component.ComponentInitializationException; import net.shibboleth.utilities.java.support.resolver.ResolverException; import org.opensaml.saml.metadata.resolver.ChainingMetadataResolver; @@ -39,7 +41,9 @@ public class MetadataResolverConfiguration { MetadataResolverConverterService metadataResolverConverterService; @Bean - public MetadataResolver metadataResolver() throws ResolverException, ComponentInitializationException { + //This injected dependency makes sure that this bean has been created and the wrapped placeholder resolver service + //is available via static facade accessor method to all the downstream non-Spring managed consumers + public MetadataResolver metadataResolver(TokenPlaceholderResolvers tokenPlaceholderResolvers) throws ResolverException, ComponentInitializationException { ChainingMetadataResolver metadataResolver = new OpenSamlChainingMetadataResolver(); metadataResolver.setId("chain"); diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/jsonschema/MetadataSourcesJsonSchemaResourceLocation.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/jsonschema/MetadataSourcesJsonSchemaResourceLocation.java new file mode 100644 index 000000000..d02b09ff0 --- /dev/null +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/jsonschema/MetadataSourcesJsonSchemaResourceLocation.java @@ -0,0 +1,76 @@ +package edu.internet2.tier.shibboleth.admin.ui.jsonschema; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.beans.factory.BeanCreationException; +import org.springframework.beans.factory.BeanInitializationException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.core.io.ResourceLoader; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.Map; + +/** + * Encapsulates metadata sources JSON schema location. + * + * @author Dmitriy Kopylenko + */ +@ConfigurationProperties("shibui") +public class MetadataSourcesJsonSchemaResourceLocation { + + //Configured via @ConfigurationProperties with 'shibui.metadata-sources-ui-schema-location' property and default + //value set here if that property is not explicitly set in application.properties + private String metadataSourcesUiSchemaLocation = "classpath:metadata-sources-ui-schema.json"; + + private URL jsonSchemaUrl; + + private ResourceLoader resourceLoader; + + private ObjectMapper jacksonMapper; + + + + public MetadataSourcesJsonSchemaResourceLocation(ResourceLoader resourceLoader, ObjectMapper jacksonMapper) { + this.resourceLoader = resourceLoader; + this.jacksonMapper = jacksonMapper; + } + + public void setMetadataSourcesUiSchemaLocation(String metadataSourcesUiSchemaLocation) { + this.metadataSourcesUiSchemaLocation = metadataSourcesUiSchemaLocation; + } + + public URL getUrl() { + return this.jsonSchemaUrl; + } + + public URI getUri() { + try { + return this.jsonSchemaUrl.toURI(); + } + catch (URISyntaxException ex) { + throw new RuntimeException(ex); + } + } + + @PostConstruct + public void init() { + try { + this.jsonSchemaUrl = this.resourceLoader.getResource(this.metadataSourcesUiSchemaLocation).getURL(); + //Detect malformed JSON schema early, during application start up and fail fast with useful exception message + this.jacksonMapper.readValue(this.jsonSchemaUrl, Map.class); + } + catch (Exception ex) { + StringBuilder msg = + new StringBuilder(String.format("An error is detected during JSON parsing => [%s]", ex.getMessage())); + msg.append(String.format("Offending resource => [%s]", this.metadataSourcesUiSchemaLocation)); + + throw new BeanInitializationException(msg.toString(), ex); + } + } +} diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataSourcesUiDefinitionControllerIntegrationTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataSourcesUiDefinitionControllerIntegrationTests.groovy index 2695ac803..240a08b77 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataSourcesUiDefinitionControllerIntegrationTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataSourcesUiDefinitionControllerIntegrationTests.groovy @@ -1,5 +1,6 @@ package edu.internet2.tier.shibboleth.admin.ui.controller +import edu.internet2.tier.shibboleth.admin.ui.jsonschema.MetadataSourcesJsonSchemaResourceLocation import org.springframework.beans.factory.BeanInitializationException import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest @@ -18,7 +19,7 @@ class MetadataSourcesUiDefinitionControllerIntegrationTests extends Specificatio private TestRestTemplate restTemplate @Autowired - MetadataSourcesUiDefinitionController controllerUnderTest + MetadataSourcesJsonSchemaResourceLocation schemaLocation static RESOURCE_URI = '/api/ui/MetadataSources' @@ -54,9 +55,9 @@ class MetadataSourcesUiDefinitionControllerIntegrationTests extends Specificatio } private configureMalformedJsonInput(boolean simulateApplicationStartup) { - controllerUnderTest.metadataSourcesUiSchemaLocation = 'classpath:metadata-sources-ui-schema_MALFORMED.json' + schemaLocation.metadataSourcesUiSchemaLocation = 'classpath:metadata-sources-ui-schema_MALFORMED.json' try { - controllerUnderTest.init() + schemaLocation.init() } catch (Exception e) { if (simulateApplicationStartup) { diff --git a/backend/src/test/resources/conf/533.xml b/backend/src/test/resources/conf/533.xml index 2120be543..66cc376ef 100644 --- a/backend/src/test/resources/conf/533.xml +++ b/backend/src/test/resources/conf/533.xml @@ -6,7 +6,7 @@ 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"> - role1 - role2 + md:role1 + md:role2