From c4e1b63c53381b302a29f03e19d472a78f5ea847 Mon Sep 17 00:00:00 2001 From: chasegawa Date: Tue, 17 Aug 2021 13:24:46 -0700 Subject: [PATCH] SHIBUI-2024 Added validation for FileBackedHttpMetadataResolver url --- ...DurationIMetadataResolverValidator.groovy} | 9 +- .../JPAMetadataResolverServiceImpl.groovy | 6 +- ...tadataResolverValidationConfiguration.java | 30 +++-- .../MetadataResolversController.java | 6 +- ...leBackedHttpMetadataResolverValidator.java | 32 +++++ .../IMetadataResolverValidator.java} | 8 +- .../MetadataResolverValidationService.java | 16 ++- ...urceBackedIMetadataResolverValidator.java} | 9 +- ...dataResolverValidationConfiguration.groovy | 26 ++-- ...dHttpMetadataResolverValidatorTests.groovy | 124 ++++++++++++++++++ ...ValidationServiceConfigurationTests.groovy | 10 +- ...adataResolverValidationServiceTests.groovy | 19 +-- ...esourceBackedMetadataValidatorTests.groovy | 20 ++- .../security/service/GroupServiceTests.groovy | 6 - 14 files changed, 252 insertions(+), 69 deletions(-) rename backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/{DurationMetadataResolverValidator.groovy => validator/DurationIMetadataResolverValidator.groovy} (78%) create mode 100644 backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/validator/FileBackedHttpMetadataResolverValidator.java rename backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/{MetadataResolverValidator.java => validator/IMetadataResolverValidator.java} (82%) rename backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/{ => validator}/MetadataResolverValidationService.java (59%) rename backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/{ResourceBackedMetadataResolverValidator.java => validator/ResourceBackedIMetadataResolverValidator.java} (57%) create mode 100644 backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/validator/FileBackedHttpMetadataResolverValidatorTests.groovy rename backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/{ => validator}/MetadataResolverValidationServiceConfigurationTests.groovy (81%) rename backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/{ => validator}/MetadataResolverValidationServiceTests.groovy (86%) rename backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/{ => validator}/ResourceBackedMetadataValidatorTests.groovy (54%) diff --git a/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/DurationMetadataResolverValidator.groovy b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/validator/DurationIMetadataResolverValidator.groovy similarity index 78% rename from backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/DurationMetadataResolverValidator.groovy rename to backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/validator/DurationIMetadataResolverValidator.groovy index 56a2ecd77..ef7c70f23 100644 --- a/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/DurationMetadataResolverValidator.groovy +++ b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/validator/DurationIMetadataResolverValidator.groovy @@ -1,8 +1,11 @@ -package edu.internet2.tier.shibboleth.admin.ui.domain.resolvers +package edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.validator +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.DynamicMetadataResolverAttributes +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolver +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.ReloadableMetadataResolverAttributes import edu.internet2.tier.shibboleth.admin.util.DurationUtility -class DurationMetadataResolverValidator implements MetadataResolverValidator { +class DurationIMetadataResolverValidator implements IMetadataResolverValidator { boolean supports(MetadataResolver resolver) { return resolver.hasProperty('dynamicMetadataResolverAttributes') || resolver.hasProperty('reloadableMetadataResolverAttributes') } @@ -27,4 +30,4 @@ class DurationMetadataResolverValidator implements MetadataResolverValidator { } return new ValidationResult() } -} +} \ No newline at end of file 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 7ffb5b5f7..bea96989f 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 @@ -400,7 +400,7 @@ class JPAMetadataResolverServiceImpl implements MetadataResolverService { disregardTLSCertificate: resolver.httpMetadataResolverAttributes?.disregardTLSCertificate ?: null, httpClientSecurityParametersRef: resolver.httpMetadataResolverAttributes?.httpClientSecurityParametersRef, proxyHost: resolver.httpMetadataResolverAttributes?.proxyHost, - proxyPort: resolver.httpMetadataResolverAttributes?.proxyHost, + proxyPort: resolver.httpMetadataResolverAttributes?.proxyPort, proxyUser: resolver.httpMetadataResolverAttributes?.proxyUser, proxyPassword: resolver.httpMetadataResolverAttributes?.proxyPassword, httpCaching: resolver.httpMetadataResolverAttributes?.httpCaching, @@ -471,7 +471,7 @@ class JPAMetadataResolverServiceImpl implements MetadataResolverService { disregardTLSCertificate: resolver.httpMetadataResolverAttributes?.disregardTLSCertificate ?: null, httpClientSecurityParametersRef: resolver.httpMetadataResolverAttributes?.httpClientSecurityParametersRef, proxyHost: resolver.httpMetadataResolverAttributes?.proxyHost, - proxyPort: resolver.httpMetadataResolverAttributes?.proxyHost, + proxyPort: resolver.httpMetadataResolverAttributes?.proxyPort, proxyUser: resolver.httpMetadataResolverAttributes?.proxyUser, proxyPassword: resolver.httpMetadataResolverAttributes?.proxyPassword, httpCaching: resolver.httpMetadataResolverAttributes?.httpCaching, @@ -559,4 +559,4 @@ class JPAMetadataResolverServiceImpl implements MetadataResolverService { } -} +} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/MetadataResolverValidationConfiguration.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/MetadataResolverValidationConfiguration.java index 86d3f9f58..b5609f60d 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/MetadataResolverValidationConfiguration.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/MetadataResolverValidationConfiguration.java @@ -1,9 +1,12 @@ package edu.internet2.tier.shibboleth.admin.ui.configuration; -import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.DurationMetadataResolverValidator; -import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolverValidationService; -import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolverValidator; -import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.ResourceBackedMetadataResolverValidator; +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.validator.DurationIMetadataResolverValidator; +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.validator.MetadataResolverValidationService; +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.validator.FileBackedHttpMetadataResolverValidator; +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.validator.IMetadataResolverValidator; +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.validator.ResourceBackedIMetadataResolverValidator; +import edu.internet2.tier.shibboleth.admin.ui.security.service.IGroupService; +import edu.internet2.tier.shibboleth.admin.ui.security.service.UserService; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -12,19 +15,22 @@ @Configuration public class MetadataResolverValidationConfiguration { + @Bean ResourceBackedIMetadataResolverValidator resourceBackedMetadataResolverValidator() { + return new ResourceBackedIMetadataResolverValidator(); + } + @Bean - ResourceBackedMetadataResolverValidator resourceBackedMetadataResolverValidator() { - return new ResourceBackedMetadataResolverValidator(); + FileBackedHttpMetadataResolverValidator fileBackedHttpMetadataResolverValidator(IGroupService groupService, UserService userService) { + return new FileBackedHttpMetadataResolverValidator(groupService, userService); } @Bean @SuppressWarnings("Unchecked") - MetadataResolverValidationService metadataResolverValidationService(List metadataResolverValidators) { - return new MetadataResolverValidationService(metadataResolverValidators); + MetadataResolverValidationService metadataResolverValidationService(List IMetadataResolverValidators) { + return new MetadataResolverValidationService(IMetadataResolverValidators); } - @Bean - DurationMetadataResolverValidator durationMetadataResolverValidator() { - return new DurationMetadataResolverValidator(); + @Bean DurationIMetadataResolverValidator durationMetadataResolverValidator() { + return new DurationIMetadataResolverValidator(); } -} +} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversController.java index 6bce7af7b..915995d4c 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversController.java @@ -3,7 +3,7 @@ import com.fasterxml.jackson.databind.exc.InvalidTypeIdException; import edu.internet2.tier.shibboleth.admin.ui.domain.exceptions.MetadataFileNotFoundException; 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.validator.MetadataResolverValidationService; import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.opensaml.OpenSamlChainingMetadataResolver; import edu.internet2.tier.shibboleth.admin.ui.domain.versioning.Version; import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolverRepository; @@ -43,7 +43,7 @@ import java.net.URI; import java.util.List; -import static edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolverValidator.ValidationResult; +import static edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.validator.IMetadataResolverValidator.ValidationResult; @RestController @RequestMapping("/api") @@ -212,4 +212,4 @@ private void doResolverInitialization(MetadataResolver persistedResolver) throws OpenSamlChainingMetadataResolverUtil.updateChainingMetadataResolver((OpenSamlChainingMetadataResolver) chainingMetadataResolver, openSamlRepresentation); } } -} +} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/validator/FileBackedHttpMetadataResolverValidator.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/validator/FileBackedHttpMetadataResolverValidator.java new file mode 100644 index 000000000..19d165859 --- /dev/null +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/validator/FileBackedHttpMetadataResolverValidator.java @@ -0,0 +1,32 @@ +package edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.validator; + +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.FileBackedHttpMetadataResolver; +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolver; +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.ResourceBackedMetadataResolver; +import edu.internet2.tier.shibboleth.admin.ui.security.service.IGroupService; +import edu.internet2.tier.shibboleth.admin.ui.security.service.UserService; +import org.springframework.beans.factory.annotation.Autowired; + +public class FileBackedHttpMetadataResolverValidator implements IMetadataResolverValidator { + @Autowired + IGroupService groupService; + + @Autowired + UserService userService; + + public FileBackedHttpMetadataResolverValidator(IGroupService groupService, UserService userService) { + this.groupService = groupService; + this.userService = userService; + } + + @Override public boolean supports(MetadataResolver resolver) { return resolver instanceof FileBackedHttpMetadataResolver; } + + @Override public ValidationResult validate(MetadataResolver resolver) { + FileBackedHttpMetadataResolver fbhmResolver = (FileBackedHttpMetadataResolver) resolver; + String url = fbhmResolver.getMetadataURL(); + if (!groupService.doesUrlMatchGroupPattern(userService.getCurrentUser().getGroupId(), url)) { + return new ValidationResult("Metadata URL not acceptable for user's group"); + } + return new ValidationResult(); + } +} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/MetadataResolverValidator.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/validator/IMetadataResolverValidator.java similarity index 82% rename from backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/MetadataResolverValidator.java rename to backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/validator/IMetadataResolverValidator.java index a57bc6f18..33ceefa00 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/MetadataResolverValidator.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/validator/IMetadataResolverValidator.java @@ -1,4 +1,6 @@ -package edu.internet2.tier.shibboleth.admin.ui.domain.resolvers; +package edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.validator; + +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolver; import java.util.ArrayList; import java.util.List; @@ -12,7 +14,7 @@ * * @author Dmitriy Kopylenko */ -public interface MetadataResolverValidator { +public interface IMetadataResolverValidator { boolean supports(MetadataResolver resolver); @@ -38,4 +40,4 @@ public boolean isValid() { return this.errorMessages == null || this.errorMessages.isEmpty(); } } -} +} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/MetadataResolverValidationService.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/validator/MetadataResolverValidationService.java similarity index 59% rename from backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/MetadataResolverValidationService.java rename to backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/validator/MetadataResolverValidationService.java index 676755b26..3e9e3df51 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/MetadataResolverValidationService.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/validator/MetadataResolverValidationService.java @@ -1,13 +1,15 @@ -package edu.internet2.tier.shibboleth.admin.ui.domain.resolvers; +package edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.validator; -import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolverValidator.ValidationResult; +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolver; +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.validator.IMetadataResolverValidator; +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.validator.IMetadataResolverValidator.ValidationResult; import java.util.ArrayList; import java.util.List; /** - * A facade that aggregates {@link MetadataResolverValidator}s available to call just one of them supporting the type of a given resolver. - * If no {@link MetadataResolverValidator}s are configured, considers provided MetadataResolver as valid. + * A facade that aggregates {@link IMetadataResolverValidator}s available to call just one of them supporting the type of a given resolver. + * If no {@link IMetadataResolverValidator}s are configured, considers provided MetadataResolver as valid. *

* Uses chain-of-responsibility design pattern * @@ -15,9 +17,9 @@ */ public class MetadataResolverValidationService { - private List> validators; + List> validators; - public MetadataResolverValidationService(List> validators) { + public MetadataResolverValidationService(List> validators) { this.validators = validators != null ? validators : new ArrayList<>(); } @@ -36,4 +38,4 @@ public ValidationResult validateIfNecessary(T metadataResolver) { boolean noValidatorsConfigured() { return this.validators.size() == 0; } -} +} \ No newline at end of file diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/ResourceBackedMetadataResolverValidator.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/validator/ResourceBackedIMetadataResolverValidator.java similarity index 57% rename from backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/ResourceBackedMetadataResolverValidator.java rename to backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/validator/ResourceBackedIMetadataResolverValidator.java index 480491465..6b4c7ba6d 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/ResourceBackedMetadataResolverValidator.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/validator/ResourceBackedIMetadataResolverValidator.java @@ -1,6 +1,9 @@ -package edu.internet2.tier.shibboleth.admin.ui.domain.resolvers; +package edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.validator; -public class ResourceBackedMetadataResolverValidator implements MetadataResolverValidator { +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolver; +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.ResourceBackedMetadataResolver; + +public class ResourceBackedIMetadataResolverValidator implements IMetadataResolverValidator { @Override public boolean supports(MetadataResolver resolver) { @@ -17,4 +20,4 @@ public ValidationResult validate(ResourceBackedMetadataResolver resolver) { } return new ValidationResult(); } -} +} \ No newline at end of file diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/configuration/TestMetadataResolverValidationConfiguration.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/configuration/TestMetadataResolverValidationConfiguration.groovy index d5c2f4f29..37f69ff8c 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/configuration/TestMetadataResolverValidationConfiguration.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/configuration/TestMetadataResolverValidationConfiguration.groovy @@ -1,19 +1,29 @@ package edu.internet2.tier.shibboleth.admin.ui.configuration -import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolverValidationService -import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolverValidator -import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.ResourceBackedMetadataResolverValidator - +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.validator.MetadataResolverValidationService +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.validator.FileBackedHttpMetadataResolverValidator +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.validator.IMetadataResolverValidator +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.validator.ResourceBackedIMetadataResolverValidator +import edu.internet2.tier.shibboleth.admin.ui.security.service.IGroupService +import edu.internet2.tier.shibboleth.admin.ui.security.service.UserService +import org.springframework.beans.factory.annotation.Qualifier import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration +import org.springframework.context.annotation.Profile @Configuration class TestMetadataResolverValidationConfiguration { @Bean - ResourceBackedMetadataResolverValidator resourceBackedMetadataResolverValidator() { - new ResourceBackedMetadataResolverValidator() + @Profile("fbh-test") + FileBackedHttpMetadataResolverValidator fileBackedHttpMetadataResolverValidator(IGroupService groupService, UserService userService) { + new FileBackedHttpMetadataResolverValidator(groupService, userService) + } + + @Bean + ResourceBackedIMetadataResolverValidator resourceBackedMetadataResolverValidator() { + new ResourceBackedIMetadataResolverValidator() } @Bean @@ -22,8 +32,8 @@ class TestMetadataResolverValidationConfiguration { } @Bean - MetadataResolverValidationService metadataResolverValidationServiceOneValidator(List metadataResolverValidators) { + MetadataResolverValidationService metadataResolverValidationService(List metadataResolverValidators) { new MetadataResolverValidationService(metadataResolverValidators) } -} +} \ No newline at end of file diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/validator/FileBackedHttpMetadataResolverValidatorTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/validator/FileBackedHttpMetadataResolverValidatorTests.groovy new file mode 100644 index 000000000..790baec2d --- /dev/null +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/validator/FileBackedHttpMetadataResolverValidatorTests.groovy @@ -0,0 +1,124 @@ +package edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.validator + +import edu.internet2.tier.shibboleth.admin.ui.configuration.CoreShibUiConfiguration +import edu.internet2.tier.shibboleth.admin.ui.configuration.InternationalizationConfiguration +import edu.internet2.tier.shibboleth.admin.ui.configuration.SearchConfiguration +import edu.internet2.tier.shibboleth.admin.ui.configuration.TestConfiguration +import edu.internet2.tier.shibboleth.admin.ui.configuration.TestMetadataResolverValidationConfiguration +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.FileBackedHttpMetadataResolver +import edu.internet2.tier.shibboleth.admin.ui.security.model.Group +import edu.internet2.tier.shibboleth.admin.ui.security.model.Role +import edu.internet2.tier.shibboleth.admin.ui.security.model.User +import edu.internet2.tier.shibboleth.admin.ui.security.repository.GroupsRepository +import edu.internet2.tier.shibboleth.admin.ui.security.repository.OwnershipRepository +import edu.internet2.tier.shibboleth.admin.ui.security.repository.RoleRepository +import edu.internet2.tier.shibboleth.admin.ui.security.repository.UserRepository +import edu.internet2.tier.shibboleth.admin.ui.security.service.GroupServiceForTesting +import edu.internet2.tier.shibboleth.admin.ui.security.service.GroupServiceImpl +import edu.internet2.tier.shibboleth.admin.ui.security.service.UserService +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.beans.factory.annotation.Qualifier +import org.springframework.boot.autoconfigure.domain.EntityScan +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Primary +import org.springframework.context.annotation.Profile +import org.springframework.data.jpa.repository.config.EnableJpaRepositories +import org.springframework.security.test.context.support.WithMockUser +import org.springframework.test.annotation.Rollback +import org.springframework.test.context.ActiveProfiles +import org.springframework.test.context.ContextConfiguration +import org.springframework.transaction.annotation.Transactional +import spock.lang.Specification + +@DataJpaTest +@ContextConfiguration(classes=[CoreShibUiConfiguration, SearchConfiguration, TestConfiguration, InternationalizationConfiguration, TestMetadataResolverValidationConfiguration, LocalConfig]) +@EnableJpaRepositories(basePackages = ["edu.internet2.tier.shibboleth.admin.ui"]) +@EntityScan("edu.internet2.tier.shibboleth.admin.ui") +@ActiveProfiles(["fbh-test"]) +class FileBackedHttpMetadataResolverValidatorTests extends Specification { + @Autowired + GroupServiceForTesting groupServiceForTesting + + @Autowired + @Qualifier("metadataResolverValidationService") + MetadataResolverValidationService metadataResolverValidationService + + @Autowired + RoleRepository roleRepository + + @Autowired + UserRepository userRepository + + @Autowired + UserService userService + + @Transactional + def setup() { + userRepository.deleteAll() + roleRepository.deleteAll() + groupServiceForTesting.clearAllForTesting() + + Group g = new Group() + g.setResourceId("shib") + g.setName("shib") + // This is valid for a url with "shib.org" in it + g.setValidationRegex("^(?:https?:\\/\\/)?(?:[^.]+\\.)?shib\\.org(\\/.*)?\$") + g = groupServiceForTesting.createGroup(g) + + def roles = [new Role().with { + name = 'ROLE_ADMIN' + it + }, new Role().with { + name = 'ROLE_USER' + it + }, new Role().with { + name = 'ROLE_NONE' + it + }] + roles.each { + roleRepository.save(it) + } + + Optional userRole = roleRepository.findByName("ROLE_USER") + User user = new User(username: "someUser", roles:[userRole.get()], password: "foo", group: g) + userService.save(user) + } + + @WithMockUser(value = "someUser", roles = ["USER"]) + @Rollback + def "test validation by service works properly"() { + given: + FileBackedHttpMetadataResolver metadataResolver = new FileBackedHttpMetadataResolver() + metadataResolver.setMetadataURL("http://foo.shib.org/bar") + + when: + IMetadataResolverValidator.ValidationResult result = metadataResolverValidationService.validateIfNecessary(metadataResolver) + + then: + result.isValid() + + when: "using a bad url (no match)" + metadataResolver.setMetadataURL("http://foo.shib.com/bar") + result = metadataResolverValidationService.validateIfNecessary(metadataResolver) + + then: + !result.isValid() + } + + @org.springframework.boot.test.context.TestConfiguration + @Profile("fbh-test") + static class LocalConfig { + @Bean + @Primary + GroupServiceForTesting groupServiceForTesting(GroupsRepository repo, OwnershipRepository ownershipRepository) { + GroupServiceForTesting result = new GroupServiceForTesting(new GroupServiceImpl().with { + it.groupRepository = repo + it.ownershipRepository = ownershipRepository + return it + }) + result.ensureAdminGroupExists() + return result + } + } +} \ No newline at end of file diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/MetadataResolverValidationServiceConfigurationTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/validator/MetadataResolverValidationServiceConfigurationTests.groovy similarity index 81% rename from backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/MetadataResolverValidationServiceConfigurationTests.groovy rename to backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/validator/MetadataResolverValidationServiceConfigurationTests.groovy index 9007cb15e..501afe9b9 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/MetadataResolverValidationServiceConfigurationTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/validator/MetadataResolverValidationServiceConfigurationTests.groovy @@ -1,4 +1,4 @@ -package edu.internet2.tier.shibboleth.admin.ui.domain.resolvers +package edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.validator import edu.internet2.tier.shibboleth.admin.ui.configuration.TestMetadataResolverValidationConfiguration import org.springframework.beans.factory.annotation.Autowired @@ -17,8 +17,8 @@ class MetadataResolverValidationServiceConfigurationTests extends Specification MetadataResolverValidationService metadataResolverValidationServiceNoValidators @Autowired - @Qualifier("metadataResolverValidationServiceOneValidator") - MetadataResolverValidationService metadataResolverValidationServiceOneValidator + @Qualifier("metadataResolverValidationService") + MetadataResolverValidationService metadataResolverValidationService def "Validation service with no validators"() { expect: @@ -27,6 +27,6 @@ class MetadataResolverValidationServiceConfigurationTests extends Specification def "Validation service with one validator"() { expect: - !metadataResolverValidationServiceOneValidator.noValidatorsConfigured() + !metadataResolverValidationService.noValidatorsConfigured() } -} +} \ No newline at end of file diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/MetadataResolverValidationServiceTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/validator/MetadataResolverValidationServiceTests.groovy similarity index 86% rename from backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/MetadataResolverValidationServiceTests.groovy rename to backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/validator/MetadataResolverValidationServiceTests.groovy index d62f07170..f0aaf8aa4 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/MetadataResolverValidationServiceTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/validator/MetadataResolverValidationServiceTests.groovy @@ -1,9 +1,10 @@ -package edu.internet2.tier.shibboleth.admin.ui.domain.resolvers +package edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.validator +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolver import spock.lang.Specification import spock.lang.Subject -import static edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolverValidator.* +import static edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.validator.IMetadataResolverValidator.* /** * @author Dmitriy Kopylenko @@ -26,7 +27,7 @@ class MetadataResolverValidationServiceTests extends Specification { def "Validation service with one validator not supporting the type of resolver returns default valid result"() { given: 'Sample metadata resolver and validation service with one validator not supporting that type' def resolver = Mock(MetadataResolver) - def validator = Mock(MetadataResolverValidator) + def validator = Mock(IMetadataResolverValidator) validator.supports(_) >> false @Subject def validationService = new MetadataResolverValidationService([validator]) @@ -41,7 +42,7 @@ class MetadataResolverValidationServiceTests extends Specification { def "Validation service with one validator supporting the type of resolver but fails its validation"() { given: 'Sample metadata resolver and validation service with one validator supporting that type' def resolver = Mock(MetadataResolver) - def validator = Mock(MetadataResolverValidator) + def validator = Mock(IMetadataResolverValidator) validator.supports(_) >> true validator.validate(_) >> new ValidationResult('Invalid') @Subject @@ -57,10 +58,10 @@ class MetadataResolverValidationServiceTests extends Specification { def "Validation service with with two validators supporting the type of resolver, first fails, second passes validation"() { given: 'Sample metadata resolver and validation service with two validators supporting that type' def resolver = Mock(MetadataResolver) - def validator1 = Mock(MetadataResolverValidator) + def validator1 = Mock(IMetadataResolverValidator) validator1.supports(_) >> true validator1.validate(_) >> new ValidationResult('Invalid') - def validator2 = Mock(MetadataResolverValidator) + def validator2 = Mock(IMetadataResolverValidator) validator2.supports(_) >> true validator2.validate(_) >> new ValidationResult(null) @Subject @@ -76,9 +77,9 @@ class MetadataResolverValidationServiceTests extends Specification { def "Validation service with with two validators, only one supporting the type of resolver, passes validation"() { given: 'Sample metadata resolver and validation service with two validators, with one supporting that type' def resolver = Mock(MetadataResolver) - def validator1 = Mock(MetadataResolverValidator) + def validator1 = Mock(IMetadataResolverValidator) validator1.supports(_) >> false - def validator2 = Mock(MetadataResolverValidator) + def validator2 = Mock(IMetadataResolverValidator) validator2.supports(_) >> true validator2.validate(_) >> new ValidationResult(null) @Subject @@ -90,4 +91,4 @@ class MetadataResolverValidationServiceTests extends Specification { then: validationResult.valid } -} +} \ No newline at end of file diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/ResourceBackedMetadataValidatorTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/validator/ResourceBackedMetadataValidatorTests.groovy similarity index 54% rename from backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/ResourceBackedMetadataValidatorTests.groovy rename to backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/validator/ResourceBackedMetadataValidatorTests.groovy index 6447a7f1a..66102f4fe 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/ResourceBackedMetadataValidatorTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/validator/ResourceBackedMetadataValidatorTests.groovy @@ -1,12 +1,18 @@ -package edu.internet2.tier.shibboleth.admin.ui.domain.resolvers - +package edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.validator + +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.ClasspathMetadataResource +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.FileBackedHttpMetadataResolver +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.ResourceBackedMetadataResolver +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.SvnMetadataResource +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.validator.IMetadataResolverValidator +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.validator.ResourceBackedIMetadataResolverValidator import spock.lang.Specification class ResourceBackedMetadataValidatorTests extends Specification { def "Does not support foreign resolver type"() { given: - MetadataResolverValidator validator = new ResourceBackedMetadataResolverValidator() + IMetadataResolverValidator validator = new ResourceBackedIMetadataResolverValidator() FileBackedHttpMetadataResolver resolver = new FileBackedHttpMetadataResolver() expect: @@ -15,7 +21,7 @@ class ResourceBackedMetadataValidatorTests extends Specification { def "Passes validation"() { given: - MetadataResolverValidator validator = new ResourceBackedMetadataResolverValidator() + IMetadataResolverValidator validator = new ResourceBackedIMetadataResolverValidator() ResourceBackedMetadataResolver resolver = new ResourceBackedMetadataResolver().with { it.classpathMetadataResource = new ClasspathMetadataResource() it @@ -28,7 +34,7 @@ class ResourceBackedMetadataValidatorTests extends Specification { def "Does not pass validation with both resource types missing"() { given: - MetadataResolverValidator validator = new ResourceBackedMetadataResolverValidator() + IMetadataResolverValidator validator = new ResourceBackedIMetadataResolverValidator() ResourceBackedMetadataResolver resolver = new ResourceBackedMetadataResolver() expect: @@ -38,7 +44,7 @@ class ResourceBackedMetadataValidatorTests extends Specification { def "Does not pass validation with both resource types present"() { given: - MetadataResolverValidator validator = new ResourceBackedMetadataResolverValidator() + IMetadataResolverValidator validator = new ResourceBackedIMetadataResolverValidator() ResourceBackedMetadataResolver resolver = new ResourceBackedMetadataResolver().with { it.classpathMetadataResource = new ClasspathMetadataResource() it.svnMetadataResource = new SvnMetadataResource() @@ -49,4 +55,4 @@ class ResourceBackedMetadataValidatorTests extends Specification { validator.supports(resolver) !validator.validate(resolver).valid } -} +} \ No newline at end of file diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/security/service/GroupServiceTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/security/service/GroupServiceTests.groovy index 057cfb576..7673a907a 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/security/service/GroupServiceTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/security/service/GroupServiceTests.groovy @@ -48,12 +48,6 @@ class GroupServiceTests extends Specification { @Transactional def setup() { groupService.ensureAdminGroupExists() -// Group g = new Group() -// g.setResourceId("twitter") -// g.setName("twitter") -// // This is valid for a url with "twitter" in it -// g.setValidationRegex("") -// g = groupService.createGroup(g) if (roleRepository.count() == 0) { def roles = [new Role().with {