Skip to content

Commit

Permalink
[SHIBUI-570]
Browse files Browse the repository at this point in the history
Replaced references to metadataResolverName with ResourceId.
Replaced ChainingMetadataResolver with OpenSaml.
Replaced instanceof with smaller one based on Refilterable.
Moved updateChainingMetadataResolver to Util class.
Updated unit tests that create EntityAttributesFilters to create Targets
with valid values for regex and condition script.
Unit tests WIP.
  • Loading branch information
Bill Smith committed Sep 12, 2018
1 parent 78781de commit 3e8d197
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,18 @@ import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.FileBackedHttpMet
import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.FilesystemMetadataResolver
import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.LocalDynamicMetadataResolver
import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.ResourceBackedMetadataResolver
import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.opensaml.OpenSamlFileBackedHTTPMetadataResolver
import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.opensaml.OpenSamlFilesystemMetadataResolver
import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.opensaml.OpenSamlResourceBackedMetadataResolver
import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.opensaml.OpenSamlChainingMetadataResolver
import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.opensaml.Refilterable
import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects
import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolverRepository
import groovy.util.logging.Slf4j
import groovy.xml.DOMBuilder
import groovy.xml.MarkupBuilder
import net.shibboleth.utilities.java.support.scripting.EvaluableScript
import org.opensaml.saml.common.profile.logic.EntityIdPredicate
import org.opensaml.saml.metadata.resolver.ChainingMetadataResolver
import org.opensaml.saml.metadata.resolver.MetadataResolver
import org.opensaml.saml.metadata.resolver.filter.MetadataFilter
import org.opensaml.saml.metadata.resolver.filter.MetadataFilterChain
import org.opensaml.saml.metadata.resolver.impl.AbstractBatchMetadataResolver
import org.opensaml.saml.saml2.core.Attribute
import org.opensaml.saml.saml2.metadata.EntityDescriptor
import org.springframework.beans.factory.annotation.Autowired
Expand Down Expand Up @@ -53,10 +50,10 @@ class JPAMetadataResolverServiceImpl implements MetadataResolverService {

// TODO: enhance
@Override
void reloadFilters(String metadataResolverName) {
ChainingMetadataResolver chainingMetadataResolver = (ChainingMetadataResolver) metadataResolver
MetadataResolver targetMetadataResolver = chainingMetadataResolver.getResolvers().find { it.id == metadataResolverName }
edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolver jpaMetadataResolver = metadataResolverRepository.findByResourceId(metadataResolverName)
void reloadFilters(String metadataResolverResourceId) {
OpenSamlChainingMetadataResolver chainingMetadataResolver = (OpenSamlChainingMetadataResolver) metadataResolver
MetadataResolver targetMetadataResolver = chainingMetadataResolver.getResolvers().find { it.id == metadataResolverResourceId }
edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolver jpaMetadataResolver = metadataResolverRepository.findByResourceId(metadataResolverResourceId)

if (targetMetadataResolver && targetMetadataResolver.getMetadataFilter() instanceof MetadataFilterChain) {
MetadataFilterChain metadataFilterChain = (MetadataFilterChain) targetMetadataResolver.getMetadataFilter()
Expand Down Expand Up @@ -95,17 +92,11 @@ class JPAMetadataResolverServiceImpl implements MetadataResolverService {
metadataFilterChain.setFilters(metadataFilters)
}

if (targetMetadataResolver != null && targetMetadataResolver instanceof AbstractBatchMetadataResolver) {
if (targetMetadataResolver instanceof OpenSamlFileBackedHTTPMetadataResolver) {
(OpenSamlFileBackedHTTPMetadataResolver) targetMetadataResolver.refilter()
} else if (targetMetadataResolver instanceof OpenSamlFilesystemMetadataResolver) {
(OpenSamlFilesystemMetadataResolver) targetMetadataResolver.refilter()
} else if (targetMetadataResolver instanceof OpenSamlResourceBackedMetadataResolver) {
(OpenSamlResourceBackedMetadataResolver) targetMetadataResolver.refilter()
} else {
//TODO: Do something here if we need to refilter other non-Batch resolvers
println("We shouldn't be here. But we are. Why?")
}
if (targetMetadataResolver != null && targetMetadataResolver instanceof Refilterable) {
(Refilterable) targetMetadataResolver.refilter()
} else {
//TODO: Do something here if we need to refilter other non-Batch resolvers
println("We shouldn't be here. But we are. Why?")
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@
import com.fasterxml.jackson.databind.exc.InvalidTypeIdException;
import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolver;
import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolverValidationService;
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.service.IndexWriterService;
import edu.internet2.tier.shibboleth.admin.ui.service.MetadataResolverConverterService;
import edu.internet2.tier.shibboleth.admin.ui.service.MetadataResolverService;
import edu.internet2.tier.shibboleth.admin.ui.service.MetadataResolversPositionOrderContainerService;
import edu.internet2.tier.shibboleth.admin.util.OpenSamlChainingMetadataResolverUtil;
import lombok.extern.slf4j.Slf4j;
import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
import net.shibboleth.utilities.java.support.resolver.ResolverException;
import org.opensaml.saml.metadata.resolver.ChainingMetadataResolver;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
Expand All @@ -36,7 +37,6 @@
import java.io.IOException;
import java.io.StringWriter;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;

import static edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolverValidator.ValidationResult;
Expand Down Expand Up @@ -120,19 +120,12 @@ public ResponseEntity<?> create(@RequestBody MetadataResolver newResolver) throw

//TODO: currently, the update call might explode, but the save works.. in which case, the UI never gets
// n valid response. This operation is not atomic. Should we return an error here?
updateChainingMetadataResolver(persistedResolver);
org.opensaml.saml.metadata.resolver.MetadataResolver openSamlRepresentation = metadataResolverConverterService.convertToOpenSamlRepresentation(persistedResolver);
OpenSamlChainingMetadataResolverUtil.updateChainingMetadataResolver((OpenSamlChainingMetadataResolver) chainingMetadataResolver, openSamlRepresentation);

return ResponseEntity.created(getResourceUriFor(persistedResolver)).body(persistedResolver);
}

private void updateChainingMetadataResolver(MetadataResolver persistedResolver) throws IOException, ResolverException, ComponentInitializationException {
org.opensaml.saml.metadata.resolver.MetadataResolver openSamlResolver = metadataResolverConverterService.convertToOpenSamlRepresentation(persistedResolver);
List<org.opensaml.saml.metadata.resolver.MetadataResolver> resolverList = new ArrayList<>(((ChainingMetadataResolver) chainingMetadataResolver).getResolvers());
resolverList.removeIf(resolver -> resolver.getId().equals(persistedResolver.getResourceId()));
resolverList.add(openSamlResolver);
((ChainingMetadataResolver) chainingMetadataResolver).setResolvers(resolverList);
}

@PutMapping("/MetadataResolvers/{resourceId}")
@Transactional
public ResponseEntity<?> update(@PathVariable String resourceId, @RequestBody MetadataResolver updatedResolver) throws IOException, ResolverException, ComponentInitializationException {
Expand All @@ -155,7 +148,8 @@ public ResponseEntity<?> update(@PathVariable String resourceId, @RequestBody Me

MetadataResolver persistedResolver = resolverRepository.save(updatedResolver);

updateChainingMetadataResolver(persistedResolver);
org.opensaml.saml.metadata.resolver.MetadataResolver openSamlRepresentation = metadataResolverConverterService.convertToOpenSamlRepresentation(persistedResolver);
OpenSamlChainingMetadataResolverUtil.updateChainingMetadataResolver((OpenSamlChainingMetadataResolver) chainingMetadataResolver, openSamlRepresentation);

return ResponseEntity.ok(persistedResolver);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package edu.internet2.tier.shibboleth.admin.util;

import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.opensaml.OpenSamlChainingMetadataResolver;
import org.opensaml.saml.metadata.resolver.MetadataResolver;

import java.util.ArrayList;
import java.util.List;

/**
* @author Bill Smith (wsmith@unicon.net)
*/
public class OpenSamlChainingMetadataResolverUtil {

public static void updateChainingMetadataResolver(OpenSamlChainingMetadataResolver chainingMetadataResolver, MetadataResolver openSamlResolver) {
List<MetadataResolver> resolverList = new ArrayList<>(chainingMetadataResolver.getResolvers());
resolverList.removeIf(resolver -> resolver.getId().equals(openSamlResolver.getId()));
resolverList.add(openSamlResolver);
chainingMetadataResolver.setResolvers(resolverList);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ package edu.internet2.tier.shibboleth.admin.ui.controller
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.SerializationFeature
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
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.service.MetadataResolverConverterService
import edu.internet2.tier.shibboleth.admin.ui.util.TestObjectGenerator
import edu.internet2.tier.shibboleth.admin.util.AttributeUtility
import edu.internet2.tier.shibboleth.admin.util.OpenSamlChainingMetadataResolverUtil
import groovy.json.JsonOutput
import groovy.json.JsonSlurper
import org.opensaml.saml.metadata.resolver.ChainingMetadataResolver
import org.opensaml.saml.metadata.resolver.MetadataResolver
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
Expand Down Expand Up @@ -38,6 +40,12 @@ class MetadataFiltersControllerIntegrationTests extends Specification {
@Autowired
AttributeUtility attributeUtility

@Autowired
MetadataResolverConverterService metadataResolverConverterService

@Autowired
MetadataResolver chainingMetadataResolver

ObjectMapper mapper
TestObjectGenerator generator

Expand All @@ -63,7 +71,8 @@ class MetadataFiltersControllerIntegrationTests extends Specification {
def filterResourceId = resolver.metadataFilters[0].resourceId
def resolverResourceId = resolver.resourceId
metadataResolverRepository.save(resolver)

MetadataResolver openSamlRepresentation = metadataResolverConverterService.convertToOpenSamlRepresentation(resolver)
OpenSamlChainingMetadataResolverUtil.updateChainingMetadataResolver((OpenSamlChainingMetadataResolver) chainingMetadataResolver, openSamlRepresentation)

when: 'GET request is made with resource Id matching the existing filter'
def result = this.restTemplate.getForEntity("$BASE_URI/$resolverResourceId/Filters/$filterResourceId", String)
Expand All @@ -86,7 +95,8 @@ class MetadataFiltersControllerIntegrationTests extends Specification {
def filterResourceId = resolver.metadataFilters[0].resourceId
def resolverResourceId = resolver.resourceId
metadataResolverRepository.save(resolver)

MetadataResolver openSamlRepresentation = metadataResolverConverterService.convertToOpenSamlRepresentation(resolver)
OpenSamlChainingMetadataResolverUtil.updateChainingMetadataResolver((OpenSamlChainingMetadataResolver) chainingMetadataResolver, openSamlRepresentation)

when: 'GET request is made with resource Id matching the existing filter'
def result = this.restTemplate.getForEntity("$BASE_URI/$resolverResourceId/Filters/$filterResourceId", String)
Expand Down Expand Up @@ -182,7 +192,7 @@ class MetadataFiltersControllerIntegrationTests extends Specification {
static class Config {
@Bean
MetadataResolver metadataResolver() {
new ChainingMetadataResolver().with {
new OpenSamlChainingMetadataResolver().with {
it.id = 'tester'
it.initialize()
return it
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package edu.internet2.tier.shibboleth.admin.ui.util

import edu.internet2.tier.shibboleth.admin.ui.domain.*
import edu.internet2.tier.shibboleth.admin.ui.domain.filters.*
import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilterTarget.EntityAttributesFilterTargetType
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
Expand Down Expand Up @@ -321,11 +322,23 @@ class TestObjectGenerator {
return representation
}

String buildEntityAttributesFilterTargetValueByType(EntityAttributesFilterTargetType type) {
switch (type) {
case EntityAttributesFilterTargetType.ENTITY:
return generator.randomString()
case EntityAttributesFilterTargetType.CONDITION_SCRIPT:
return "eval(true);"
case EntityAttributesFilterTargetType.REGEX:
return "/foo.*/"
}
}

EntityAttributesFilterTarget buildEntityAttributesFilterTarget() {
EntityAttributesFilterTarget entityAttributesFilterTarget = new EntityAttributesFilterTarget()

entityAttributesFilterTarget.setSingleValue(generator.randomString())
entityAttributesFilterTarget.setEntityAttributesFilterTargetType(randomFilterTargetType())
entityAttributesFilterTarget.setSingleValue(
buildEntityAttributesFilterTargetValueByType(entityAttributesFilterTarget.getEntityAttributesFilterTargetType()))

return entityAttributesFilterTarget
}
Expand Down Expand Up @@ -353,8 +366,10 @@ class TestObjectGenerator {
FilterTargetRepresentation buildFilterTargetRepresentation() {
FilterTargetRepresentation representation = new FilterTargetRepresentation()

representation.setValue(generator.randomStringList())
representation.setType(randomFilterTargetType().toString())
representation.setValue([
buildEntityAttributesFilterTargetValueByType(representation.getType())
])

return representation
}
Expand Down

0 comments on commit 3e8d197

Please sign in to comment.