Skip to content

Commit

Permalink
master merge to 1743 test fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
chasegawa committed Sep 5, 2021
1 parent 052e8c5 commit 2dd1775
Show file tree
Hide file tree
Showing 25 changed files with 195 additions and 535 deletions.
19 changes: 18 additions & 1 deletion backend/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,23 @@ configurations {

def generatedSrcDir = new File(buildDir, 'generated/src/main/java')

//test {
// exclude 'edu/internet2/tier/shibboleth/admin/ui/configuration/*.class'
// exclude 'edu/internet2/tier/shibboleth/admin/ui/controller/*.class'
// exclude 'edu/internet2/tier/shibboleth/admin/ui/domain/*.class'
// exclude 'edu/internet2/tier/shibboleth/admin/ui/domain/filters/*.class'
// exclude 'edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/*.class'
// exclude 'edu/internet2/tier/shibboleth/admin/ui/domain/versioning/*.class'
// exclude 'edu/internet2/tier/shibboleth/admin/ui/repository/*.class'
// exclude 'edu/internet2/tier/shibboleth/admin/ui/scheduled/*.class'
// exclude 'edu/internet2/tier/shibboleth/admin/ui/security/controller/*.class'
// exclude 'edu/internet2/tier/shibboleth/admin/ui/security/repository/*.class'
//// exclude 'edu/internet2/tier/shibboleth/admin/ui/security/service/*.class'
//// exclude 'edu/internet2/tier/shibboleth/admin/ui/security/springsecurity/*.class'
// exclude 'edu/internet2/tier/shibboleth/admin/ui/service/*.class'
// exclude 'edu/internet2/tier/shibboleth/admin/ui/util/*.class'
//}

sourceSets {
main {
groovy {
Expand Down Expand Up @@ -353,4 +370,4 @@ dockerRun {
daemonize true
command '--spring.profiles.include=very-dangerous,dev', '--shibui.default-password={noop}password'
clean true
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,150 +77,6 @@ class JPAMetadataResolverServiceImpl implements MetadataResolverService {
private UserService userService

// TODO: enhance
@Override
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()

List<MetadataFilter> metadataFilters = new ArrayList<>()

// set up namespace protection
if (shibUIConfiguration.protectedAttributeNamespaces && shibUIConfiguration.protectedAttributeNamespaces.size() > 0 && targetMetadataResolver && jpaMetadataResolver.type in ['FileBackedHttpMetadataResolver', 'DynamicHttpMetadataResolver']) {
def target = new org.opensaml.saml.metadata.resolver.filter.impl.EntityAttributesFilter()
target.attributeFilter = new ScriptedPredicate(new EvaluableScript(protectedNamespaceScript()))
metadataFilters.add(target)
}

for (edu.internet2.tier.shibboleth.admin.ui.domain.filters.MetadataFilter metadataFilter : jpaMetadataResolver.getMetadataFilters()) {
if (metadataFilter instanceof EntityAttributesFilter) {
EntityAttributesFilter entityAttributesFilter = (EntityAttributesFilter) metadataFilter

org.opensaml.saml.metadata.resolver.filter.impl.EntityAttributesFilter target = new org.opensaml.saml.metadata.resolver.filter.impl.EntityAttributesFilter()
Map<Predicate<EntityDescriptor>, Collection<Attribute>> rules = new HashMap<>()
switch (entityAttributesFilter.getEntityAttributesFilterTarget().getEntityAttributesFilterTargetType()) {
case EntityAttributesFilterTarget.EntityAttributesFilterTargetType.ENTITY:
rules.put(
new EntityIdPredicate(entityAttributesFilter.getEntityAttributesFilterTarget().getValue()),
(List<Attribute>) (List<? extends Attribute>) entityAttributesFilter.getAttributes()
)
break
case EntityAttributesFilterTarget.EntityAttributesFilterTargetType.CONDITION_SCRIPT:
rules.put(new ScriptedPredicate(new EvaluableScript(entityAttributesFilter.entityAttributesFilterTarget.value[0])),
(List<Attribute>) (List<? extends Attribute>) entityAttributesFilter.getAttributes())
break
case EntityAttributesFilterTarget.EntityAttributesFilterTargetType.REGEX:
rules.put(new ScriptedPredicate(new EvaluableScript(generateJavaScriptRegexScript(entityAttributesFilter.entityAttributesFilterTarget.value[0]))),
(List<Attribute>) (List<? extends Attribute>) entityAttributesFilter.getAttributes())
break
default:
// do nothing, we'd have exploded elsewhere previously.
break
}
target.setRules(rules)
metadataFilters.add(target)
}
if (metadataFilter instanceof NameIdFormatFilter) {
NameIdFormatFilter nameIdFormatFilter = NameIdFormatFilter.cast(metadataFilter)
NameIDFormatFilter openSamlTargetFilter = new OpenSamlNameIdFormatFilter()
openSamlTargetFilter.removeExistingFormats = nameIdFormatFilter.removeExistingFormats == null ? false : nameIdFormatFilter.removeExistingFormats
Map<Predicate<EntityDescriptor>, Collection<String>> predicateRules = [:]
def type = nameIdFormatFilter.nameIdFormatFilterTarget.nameIdFormatFilterTargetType
def values = nameIdFormatFilter.nameIdFormatFilterTarget.value
switch (type) {
case ENTITY:
predicateRules[new EntityIdPredicate(values)] = nameIdFormatFilter.formats
break
case CONDITION_SCRIPT:
predicateRules[new ScriptedPredicate(new EvaluableScript(values[0]))] = nameIdFormatFilter.formats
break
case REGEX:
predicateRules[new ScriptedPredicate(new EvaluableScript(generateJavaScriptRegexScript(values[0])))] = nameIdFormatFilter.formats
break
default:
// do nothing, we'd have exploded elsewhere previously.
break
}
openSamlTargetFilter.rules = predicateRules
metadataFilters << openSamlTargetFilter
}
}
metadataFilterChain.setFilters(metadataFilters)
}

if (targetMetadataResolver != null && targetMetadataResolver instanceof Refilterable) {
(Refilterable) targetMetadataResolver.refilter()
} else {
//TODO: Do something here if we need to refilter other non-Batch resolvers
log.warn("Target resolver is not a Refilterable resolver. Skipping refilter()")
}
}

private String protectedNamespaceScript() {
return """(function (attribute) {
"use strict";
var namespaces = [${shibUIConfiguration.protectedAttributeNamespaces.collect({"\"${it}\""}).join(', ')}];
// check the parameter
if (attribute === null) { return true; }
for (var i in namespaces) {
if (attribute.getName().startsWith(namespaces[i])) {
return false;
}
}
return true;
}(input));"""
}

// TODO: enhance
@Override
Document generateConfiguration() {
// TODO: this can probably be a better writer
new StringWriter().withCloseable { writer ->
def xml = new MarkupBuilder(writer)
xml.omitEmptyAttributes = true
xml.omitNullAttributes = true

xml.MetadataProvider(id: 'ShibbolethMetadata',
xmlns: 'urn:mace:shibboleth:2.0:metadata',
'xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance',
'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'
) {


resolversPositionOrderContainerService.allMetadataResolversInDefinedOrderOrUnordered.each {
edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolver mr ->
//TODO: We do not currently marshall the internal incommon chaining resolver (with BaseMetadataResolver type)
if ((mr.type != 'BaseMetadataResolver') && (mr.enabled)) {
constructXmlNodeForResolver(mr, delegate) {
//TODO: enhance
def didNamespaceProtectionFilter = !(shibUIConfiguration.protectedAttributeNamespaces && shibUIConfiguration.protectedAttributeNamespaces.size() > 0)
def doNamespaceProtectionFilter = { def filter ->
if (mr.type in ['FileBackedMetadataResolver', 'DynamicHttpMetadataResolver'] && (filter == null || filter instanceof EntityAttributesFilter) && !didNamespaceProtectionFilter) {
constructXmlNodeForEntityAttributeNamespaceProtection(delegate)
didNamespaceProtectionFilter = true
}
}
mr.metadataFilters.each { edu.internet2.tier.shibboleth.admin.ui.domain.filters.MetadataFilter filter ->
doNamespaceProtectionFilter()
constructXmlNodeForFilter(filter, delegate)
}
doNamespaceProtectionFilter()
}
}
}
}
return DOMBuilder.newInstance().parseText(writer.toString())
}
}
@Autowired
private UserService userService

void constructXmlNodeForEntityAttributeNamespaceProtection(def markupBuilderDelegate) {
markupBuilderDelegate.MetadataFilter('xsi:type': 'EntityAttributes') {
AttributeFilterScript() {
Expand Down Expand Up @@ -269,6 +125,7 @@ class JPAMetadataResolverServiceImpl implements MetadataResolverService {
}
}

// TODO: enhance
void constructXmlNodeForFilter(EntityRoleWhiteListFilter filter, def markupBuilderDelegate) {
if (!filter.retainedRoles?.isEmpty()) {
markupBuilderDelegate.MetadataFilter(
Expand All @@ -283,7 +140,6 @@ class JPAMetadataResolverServiceImpl implements MetadataResolverService {
}
}


void constructXmlNodeForFilter(NameIdFormatFilter filter, def markupBuilderDelegate) {
def type = filter.nameIdFormatFilterTarget.nameIdFormatFilterTargetType
markupBuilderDelegate.MetadataFilter(
Expand Down Expand Up @@ -346,6 +202,7 @@ class JPAMetadataResolverServiceImpl implements MetadataResolverService {
}
}


void constructXmlNodeForResolver(DynamicHttpMetadataResolver resolver, def markupBuilderDelegate, Closure childNodes) {
markupBuilderDelegate.MetadataProvider(id: resolver.xmlId,
'xsi:type': 'DynamicHTTPMetadataProvider',
Expand Down Expand Up @@ -685,7 +542,7 @@ class JPAMetadataResolverServiceImpl implements MetadataResolverService {
if (metadataFilter instanceof NameIdFormatFilter) {
NameIdFormatFilter nameIdFormatFilter = NameIdFormatFilter.cast(metadataFilter)
NameIDFormatFilter openSamlTargetFilter = new OpenSamlNameIdFormatFilter()
openSamlTargetFilter.removeExistingFormats = nameIdFormatFilter.removeExistingFormats
openSamlTargetFilter.removeExistingFormats = nameIdFormatFilter.removeExistingFormats == null ? false : nameIdFormatFilter.removeExistingFormats
Map<Predicate<EntityDescriptor>, Collection<String>> predicateRules = [:]
def type = nameIdFormatFilter.nameIdFormatFilterTarget.nameIdFormatFilterTargetType
def values = nameIdFormatFilter.nameIdFormatFilterTarget.value
Expand Down Expand Up @@ -733,7 +590,7 @@ class JPAMetadataResolverServiceImpl implements MetadataResolverService {
throw new MetadataFileNotFoundException("message.file-doesnt-exist")
}
try {
OpenSamlChainingMetadataResolverUtil.updateChainingMetadataResolver((OpenSamlChainingMetadataResolver) chainingMetadataResolver, openSamlRepresentation);
OpenSamlChainingMetadataResolverUtil.updateChainingMetadataResolver((OpenSamlChainingMetadataResolver) chainingMetadataResolver, openSamlRepresentation)
}
catch (Throwable e) {
throw new InitializationException(e);
Expand All @@ -748,5 +605,4 @@ class JPAMetadataResolverServiceImpl implements MetadataResolverService {
}
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
@EntityListeners(GroupUpdatedEntityListener.class)
@Entity(name = "user_groups")
public class Group implements Owner {
public static final String DEFAULT_REGEX = "/(?:)/"; //non-capturing
public static final String DEFAULT_REGEX = "^.+$"; //everything

@Transient
@JsonIgnore
Expand Down Expand Up @@ -78,7 +78,6 @@ public void registerLoader(ILazyLoaderHelper lazyLoaderHelper) {
public Set<Ownership> getOwnedItems() {
if (lazyLoaderHelper != null) {
lazyLoaderHelper.loadOwnedItems(this);
lazyLoaderHelper = null;
}
return ownedItems;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,6 @@ public String getRole() {
public Set<Group> getUserGroups() {
if (lazyLoaderHelper != null) {
lazyLoaderHelper.loadGroups(this);
lazyLoaderHelper = null;
}
return userGroups;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public class GroupUpdatedEntityListener implements ILazyLoaderHelper {
* @see https://stackoverflow.com/questions/12155632/injecting-a-spring-dependency-into-a-jpa-entitylistener
*/
@Autowired
public void init(OwnershipRepository repo) {
public static void init(OwnershipRepository repo) {
GroupUpdatedEntityListener.ownershipRepository = repo;
}

Expand All @@ -36,7 +36,6 @@ public synchronized void groupSavedOrFetched(Group group) {
public void loadOwnedItems(Group group) {
Set<Ownership> ownedItems = ownershipRepository.findAllByOwner(group);
group.setOwnedItems(ownedItems);
group.registerLoader(null); // once loaded, remove the helper from the group
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public class UserUpdatedEntityListener implements ILazyLoaderHelper {
* @see https://stackoverflow.com/questions/12155632/injecting-a-spring-dependency-into-a-jpa-entitylistener
*/
@Autowired
public void init(OwnershipRepository repo, GroupsRepository groupRepo) {
public static void init(OwnershipRepository repo, GroupsRepository groupRepo) {
UserUpdatedEntityListener.ownershipRepository = repo;
UserUpdatedEntityListener.groupRepository = groupRepo;
}
Expand Down Expand Up @@ -51,6 +51,5 @@ public void loadGroups(User user) {
groups.add(userGroup);
});
user.setGroups(groups);
user.setLazyLoaderHelper(null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ public void deleteDefinition(String resourceId) throws EntityNotFoundException,
@Override
public boolean doesStringMatchGroupPattern(String groupId, String uri) {
Group group = find(groupId);
//@TODO change matching to rhino
return Pattern.matches(group.getValidationRegex(), uri);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ package edu.internet2.tier.shibboleth.admin.ui

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.model.listener.GroupUpdatedEntityListener
import edu.internet2.tier.shibboleth.admin.ui.security.model.listener.UserUpdatedEntityListener
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
Expand All @@ -17,6 +20,9 @@ import spock.lang.Specification

import javax.persistence.EntityManager

// The commented out lines show how to run the JPA tests using a file back h2 db - typically you'd switch if you want
// to access the db during testing to see what is happening in the db. Additionally, you have to use the file version of h2
// if you want to use the reset, as the in mem version won't allow multiple different access connections to be created.
//@DataJpaTest (properties = ["spring.datasource.url=jdbc:h2:file:/tmp/myApplicationDb;AUTO_SERVER=TRUE",
// "spring.datasource.username=sa",
// "spring.datasource.password=",
Expand All @@ -26,10 +32,13 @@ import javax.persistence.EntityManager
@ContextConfiguration(classes = [BaseDataJpaTestConfiguration])
@EnableJpaRepositories(basePackages = ["edu.internet2.tier.shibboleth.admin.ui"])
@EntityScan("edu.internet2.tier.shibboleth.admin.ui")
abstract class AbstractBaseDataJpaTest extends Specification implements ResetsDatabase {
abstract class AbstractBaseDataJpaTest extends Specification implements ResetsDatabaseTrait {
@Autowired
EntityManager entityManager

@Autowired
GroupsRepository groupRepository

@Autowired
GroupServiceForTesting groupService

Expand Down Expand Up @@ -74,6 +83,8 @@ abstract class AbstractBaseDataJpaTest extends Specification implements ResetsDa
}

createAdminUser()
GroupUpdatedEntityListener.init(ownershipRepository)
UserUpdatedEntityListener.init(ownershipRepository, groupRepository)
}

def cleanup() {
Expand Down
Loading

0 comments on commit 2dd1775

Please sign in to comment.