Skip to content

Commit

Permalink
Metadata Resolvers schema validation
Browse files Browse the repository at this point in the history
  • Loading branch information
dima767 committed Aug 23, 2019
1 parent bdf8e93 commit ffffc0b
Show file tree
Hide file tree
Showing 9 changed files with 75 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,16 @@ import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaLocati
class LowLevelJsonSchemaValidator {

static HttpInputMessage validatePayloadAgainstSchema(HttpInputMessage inputMessage, URI schemaUri) {
def json = extractJsonPayload(inputMessage)
def origInput = [inputMessage.body.bytes, inputMessage.headers]
def json = extractJsonPayload(origInput)
def schema = Json.schema(schemaUri)
doValidate(schema, json)
doValidate(origInput, schema, json)
}

static HttpInputMessage validateMetadataResolverTypePayloadAgainstSchema(HttpInputMessage inputMessage,
JsonSchemaResourceLocationRegistry schemaRegistry) {
def json = extractJsonPayload(inputMessage)
def origInput = [inputMessage.body.bytes, inputMessage.headers]
def json = extractJsonPayload(origInput)
def schemaUri = null
switch (json.asMap()['@type']) {
case 'LocalDynamicMetadataResolver':
Expand All @@ -36,23 +38,27 @@ class LowLevelJsonSchemaValidator {
break
}
if(!schemaUri) {
return inputMessage
return newInputMessage(origInput)
}
doValidate(Json.schema(schemaUri), json)
doValidate(origInput, Json.schema(schemaUri), json)
}

private static Json extractJsonPayload(HttpInputMessage inputMessage) {
Json.read(new ByteArrayInputStream(inputMessage.body.bytes).getText())
private static Json extractJsonPayload(List origInput) {
Json.read(new ByteArrayInputStream(origInput[0]).getText())
}

private static HttpInputMessage doValidate(Json.Schema schema, Json json) {
private static HttpInputMessage doValidate(List origInput, Json.Schema schema, Json json) {
def validationResult = schema.validate(json)
if (!validationResult.at('ok')) {
throw new JsonSchemaValidationFailedException(validationResult.at('errors').asList())
}
return [
getBody : { new ByteArrayInputStream(bytes) },
getHeaders: { inputMessage.headers }
newInputMessage(origInput)
}

private static newInputMessage(origInput) {
[
getBody : { new ByteArrayInputStream(origInput[0]) },
getHeaders: { origInput[1] }
] as HttpInputMessage
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ public class DynamicHttpMetadataResolver extends MetadataResolver {

private Integer maxConnectionsPerRoute = 100;

private String metadataURL;

@ElementCollection
@OrderColumn
private List<String> supportedContentTypes;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public class DynamicMetadataResolverAttributes {

private String taskTimerRef;

private Double refreshDelayFactor = 0.75;
private Float refreshDelayFactor = 0.75F;

private String minCacheDuration = "PT10M";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public static void updateOpenSamlMetadataResolverFromDynamicMetadataResolverAttr
}

if (attributes.getRefreshDelayFactor() != null) {
dynamicMetadataResolver.setRefreshDelayFactor(attributes.getRefreshDelayFactor().floatValue());
dynamicMetadataResolver.setRefreshDelayFactor(attributes.getRefreshDelayFactor());
}

if (attributes.getRemoveIdleEntityData() != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@
"refreshDelayFactor": {
"title": "label.refresh-delay-factor",
"description": "tooltip.refresh-delay-factor",
"type": "string",
"type": "number",
"widget": {
"id": "string",
"help": "message.real-number"
Expand Down Expand Up @@ -578,7 +578,7 @@
"metadataFilters": {
"title": "",
"description": "",
"type": "object",
"type": "array",
"properties": {
"RequiredValidUntil": {
"title": "label.required-valid-until",
Expand Down Expand Up @@ -703,4 +703,4 @@
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
"refreshDelayFactor": {
"title": "label.refresh-delay-factor",
"description": "tooltip.refresh-delay-factor",
"type": "string",
"type": "number",
"widget": {
"id": "string",
"help": "message.real-number"
Expand Down Expand Up @@ -188,4 +188,4 @@
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@ class MetadataResolverControllerSchemaValidationIntegrationTests extends Specifi

static RESOURCE_URI = '/api/MetadataResolvers'

private HTTP_POST = { body ->
this.restTemplate.postForEntity(RESOURCE_URI, createRequestHttpEntityFor(body), Map)
}

private static checkJsonValidationIsPerformed = {
assert it.statusCodeValue == 400
assert it.body.errorMessage.count('Type mistmatch for null') > 0
true
}

def 'POST for LocalDynamicMetadataResolver with invalid payload according to schema validation'() {
given:
def postedJsonBody = """
Expand Down Expand Up @@ -87,14 +97,36 @@ class MetadataResolverControllerSchemaValidationIntegrationTests extends Specifi
"""

when:
def result = this.restTemplate.postForEntity(RESOURCE_URI, createRequestHttpEntityFor { postedJsonBody }, Map)
def result = HTTP_POST(postedJsonBody)

then:
checkJsonValidationIsPerformed(result)

}

def 'POST for DynamicHttpMetadataResolver with invalid payload according to schema validation'() {
given:
def postedJsonBody = """
{
"name" : null,
"xmlId": "123",
"metadataURL": "http://metadata",
"metadataRequestURLConstructionScheme": {"@type": "MetadataQueryProtocol", "content": "scheme"},
"@type" : "DynamicHttpMetadataResolver"
}
"""

when:
def result = HTTP_POST(postedJsonBody)

then:
result.statusCodeValue == 400
result.body.errorMessage.count('Type mistmatch for null') > 0
checkJsonValidationIsPerformed(result)

}

private static HttpEntity<String> createRequestHttpEntityFor(Closure jsonBodySupplier) {
new HttpEntity<String>(jsonBodySupplier(), ['Content-Type': 'application/json'] as HttpHeaders)
private static HttpEntity<String> createRequestHttpEntityFor(String jsonBody) {
new HttpEntity<String>(jsonBody, ['Content-Type': 'application/json'] as HttpHeaders)
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFil
import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.DynamicHttpMetadataResolver
import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.FileBackedHttpMetadataResolver
import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.LocalDynamicMetadataResolver
import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataQueryProtocolScheme
import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.opensaml.OpenSamlChainingMetadataResolver
import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolverRepository
import edu.internet2.tier.shibboleth.admin.ui.util.TestObjectGenerator
Expand All @@ -27,6 +28,7 @@ import org.springframework.test.context.ActiveProfiles
import spock.lang.Specification
import spock.lang.Unroll

import static com.fasterxml.jackson.annotation.JsonInclude.Include.*
import static org.springframework.http.HttpMethod.PUT

/**
Expand Down Expand Up @@ -59,6 +61,7 @@ class MetadataResolversControllerIntegrationTests extends Specification {
generator = new TestObjectGenerator(attributeUtility, customPropertiesConfiguration)
mapper = new ObjectMapper()
mapper.enable(SerializationFeature.INDENT_OUTPUT)
mapper.setSerializationInclusion(NON_NULL)
mapper.registerModule(new JavaTimeModule())
}

Expand Down Expand Up @@ -254,7 +257,14 @@ class MetadataResolversControllerIntegrationTests extends Specification {
def "PUT concrete MetadataResolver with version conflict -> /api/MetadataResolvers/{resourceId}"() {
given: 'One resolver is available in data store'
def resolver = new DynamicHttpMetadataResolver().with {
it.name = 'Test DynamicHttpMetadataResolver'
it.name = 'DynamicHTTP'
it.xmlId = 'DynamicHTTP'
it.metadataURL = 'http://metadata'
it.metadataRequestURLConstructionScheme = new MetadataQueryProtocolScheme().with {
it.transformRef = 'transformRef'
it.content = 'content'
it
}
it
}
def resolverResourceId = resolver.resourceId
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,7 @@ class TestObjectGenerator {
new DynamicHttpMetadataResolver().with {
it.name = 'DynamicHTTP'
it.xmlId = 'DynamicHTTP'
it.metadataURL = 'http://metadata'
it.dynamicMetadataResolverAttributes = new DynamicMetadataResolverAttributes().with {
it
}
Expand Down

0 comments on commit ffffc0b

Please sign in to comment.