Skip to content

Commit

Permalink
[SHIBUI-723]
Browse files Browse the repository at this point in the history
Added DurationUtility.
Updated all duration-related code.
Updated tests to mostly not break.

Still need to address TODOs.
  • Loading branch information
Bill Smith committed Aug 16, 2018
1 parent c969919 commit 3d160aa
Show file tree
Hide file tree
Showing 11 changed files with 103 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
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 @@ -133,13 +134,14 @@ public ResponseEntity<?> create(@RequestBody MetadataResolver newResolver) throw

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

@PutMapping("/MetadataResolvers/{resourceId}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

import javax.annotation.Nullable;

import static edu.internet2.tier.shibboleth.admin.util.DurationUtility.toMillis;

/**
* @author Bill Smith (wsmith@unicon.net)
*/
Expand All @@ -27,13 +29,15 @@ public OpenSamlFileBackedHTTPMetadataResolver(IndexWriter indexWriter,
this.sourceResolver = sourceResolver;
this.delegate = new OpenSamlMetadataResolverDelegate();

this.setId(sourceResolver.getResourceId());

OpenSamlMetadataResolverConstructorHelper.updateOpenSamlMetadataResolverFromHttpMetadataResolverAttributes(
this, sourceResolver.getHttpMetadataResolverAttributes());
OpenSamlMetadataResolverConstructorHelper.updateOpenSamlMetadataResolverFromReloadableMetadataResolverAttributes(
this, sourceResolver.getReloadableMetadataResolverAttributes());

this.setBackupFile(sourceResolver.getBackingFile());
this.setBackupFileInitNextRefreshDelay(Long.parseLong(sourceResolver.getBackupFileInitNextRefreshDelay()));
this.setBackupFileInitNextRefreshDelay(toMillis(sourceResolver.getBackupFileInitNextRefreshDelay()));
this.setInitializeFromBackupFile(sourceResolver.getInitializeFromBackupFile());

//TODO: Where does this get set in OpenSAML land?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ public OpenSamlFilesystemMetadataResolver(File metadataFile,
this.sourceResolver = sourceResolver;
this.delegate = new OpenSamlMetadataResolverDelegate();

this.setId(sourceResolver.getResourceId());

OpenSamlMetadataResolverConstructorHelper.updateOpenSamlMetadataResolverFromReloadableMetadataResolverAttributes(
this, sourceResolver.getReloadableMetadataResolverAttributes());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ public OpenSamlFunctionDrivenDynamicHTTPMetadataResolver(IndexWriter indexWriter
this.sourceResolver = sourceResolver;
this.delegate = new OpenSamlMetadataResolverDelegate();

this.setId(sourceResolver.getResourceId());

OpenSamlMetadataResolverConstructorHelper.updateOpenSamlMetadataResolverFromDynamicMetadataResolverAttributes(
this, sourceResolver.getDynamicMetadataResolverAttributes());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ public OpenSamlLocalDynamicMetadataResolver(@Nonnull XMLObjectLoadSaveManager<XM
this.sourceResolver = sourceResolver;
this.delegate = new OpenSamlMetadataResolverDelegate();

this.setId(sourceResolver.getResourceId());

OpenSamlMetadataResolverConstructorHelper.updateOpenSamlMetadataResolverFromDynamicMetadataResolverAttributes(
this, sourceResolver.getDynamicMetadataResolverAttributes());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,27 @@
import org.opensaml.saml.metadata.resolver.impl.AbstractDynamicMetadataResolver;
import org.opensaml.saml.metadata.resolver.impl.AbstractReloadingMetadataResolver;

import static edu.internet2.tier.shibboleth.admin.util.DurationUtility.toMillis;

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

public static void updateOpenSamlMetadataResolverFromDynamicMetadataResolverAttributes(MetadataResolver metadataResolver, DynamicMetadataResolverAttributes attributes) {

AbstractDynamicMetadataResolver dynamicMetadataResolver = (AbstractDynamicMetadataResolver) metadataResolver;

// from DynamicMetadataResolverAttributes
dynamicMetadataResolver.setBackgroundInitializationFromCacheDelay(Long.valueOf(attributes.getBackgroundInitializationFromCacheDelay()));
dynamicMetadataResolver.setCleanupTaskInterval(Long.valueOf(attributes.getCleanupTaskInterval()));
dynamicMetadataResolver.setBackgroundInitializationFromCacheDelay(toMillis(attributes.getBackgroundInitializationFromCacheDelay()));
dynamicMetadataResolver.setCleanupTaskInterval(toMillis(attributes.getCleanupTaskInterval()));
dynamicMetadataResolver.setInitializeFromPersistentCacheInBackground(attributes.getInitializeFromPersistentCacheInBackground());
dynamicMetadataResolver.setMaxCacheDuration(Long.valueOf(attributes.getMaxCacheDuration()));
dynamicMetadataResolver.setMaxIdleEntityData(Long.valueOf(attributes.getMaxIdleEntityData()));
dynamicMetadataResolver.setMinCacheDuration(Long.valueOf(attributes.getMinCacheDuration()));
dynamicMetadataResolver.setBackgroundInitializationFromCacheDelay(Long.valueOf(attributes.getBackgroundInitializationFromCacheDelay()));
dynamicMetadataResolver.setMaxCacheDuration(toMillis(attributes.getMaxCacheDuration()));
dynamicMetadataResolver.setMaxIdleEntityData(toMillis(attributes.getMaxIdleEntityData()));
dynamicMetadataResolver.setMinCacheDuration(toMillis(attributes.getMinCacheDuration()));
dynamicMetadataResolver.setBackgroundInitializationFromCacheDelay(toMillis(attributes.getBackgroundInitializationFromCacheDelay()));
dynamicMetadataResolver.setRefreshDelayFactor(attributes.getRefreshDelayFactor().floatValue());
dynamicMetadataResolver.setRemoveIdleEntityData(attributes.getRemoveIdleEntityData());

//TODO: What should we do here if this data is null/empty?
dynamicMetadataResolver.setRemoveIdleEntityData(attributes.getRemoveIdleEntityData() == null ? false : attributes.getRemoveIdleEntityData());

//TODO: This takes a XMLObjectLoadSaveManager. Do we have what we need to create one?
// dynamicMetadataResolver.setPersistentCacheManager(); attributes.getPersistentCacheManagerDirectory();
Expand All @@ -51,11 +53,13 @@ public static void updateOpenSamlMetadataResolverFromHttpMetadataResolverAttribu
public static void updateOpenSamlMetadataResolverFromReloadableMetadataResolverAttributes(MetadataResolver metadataResolver, ReloadableMetadataResolverAttributes attributes) {
AbstractReloadingMetadataResolver reloadingMetadataResolver = (AbstractReloadingMetadataResolver) metadataResolver;

reloadingMetadataResolver.setExpirationWarningThreshold(Long.parseLong(attributes.getExpirationWarningThreshold()));
reloadingMetadataResolver.setMaxRefreshDelay(Long.parseLong(attributes.getMaxRefreshDelay()));
reloadingMetadataResolver.setMinRefreshDelay(Long.parseLong(attributes.getMinRefreshDelay()));
reloadingMetadataResolver.setExpirationWarningThreshold(toMillis(attributes.getExpirationWarningThreshold()));
reloadingMetadataResolver.setMaxRefreshDelay(toMillis(attributes.getMaxRefreshDelay()));
reloadingMetadataResolver.setMinRefreshDelay(toMillis(attributes.getMinRefreshDelay()));
reloadingMetadataResolver.setRefreshDelayFactor(attributes.getRefreshDelayFactor().floatValue());
reloadingMetadataResolver.setResolveViaPredicatesOnly(attributes.getResolveViaPredicatesOnly());

//TODO: What should we do here if this data is null/empty?
reloadingMetadataResolver.setResolveViaPredicatesOnly(attributes.getResolveViaPredicatesOnly() == null ? false : attributes.getResolveViaPredicatesOnly());

//TODO: This takes a set of MetadataIndex's. We've got an IndexesRef. How to convert?
// reloadingMetadataResolver.setIndexes(); attributes.getIndexesRef();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ public OpenSamlResourceBackedMetadataResolver(Resource resource,
this.sourceResolver = sourceResolver;
this.delegate = new OpenSamlMetadataResolverDelegate();

this.setId(sourceResolver.getResourceId());

OpenSamlMetadataResolverConstructorHelper.updateOpenSamlMetadataResolverFromReloadableMetadataResolverAttributes(
this, sourceResolver.getReloadableMetadataResolverAttributes());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;

import javax.validation.ConstraintViolationException;
import java.io.File;
import java.io.IOException;

Expand Down Expand Up @@ -57,8 +58,13 @@ private OpenSamlFilesystemMetadataResolver convertToOpenSamlRepresentation(Files
private OpenSamlLocalDynamicMetadataResolver convertToOpenSamlRepresentation(LocalDynamicMetadataResolver resolver) throws IOException {
IndexWriter indexWriter = indexWriterService.getIndexWriter(resolver.getResourceId());

//TODO: This is an educated guess.
XMLObjectLoadSaveManager manager = new FilesystemLoadSaveManager(resolver.getSourceDirectory());
XMLObjectLoadSaveManager manager = null;
try {
manager = new FilesystemLoadSaveManager(resolver.getSourceDirectory());
} catch (ConstraintViolationException e) {
// the base directory string instance was null or empty
//TODO: What should we do here? Currently, this causes a test to fail.
}

return new OpenSamlLocalDynamicMetadataResolver(manager, indexWriter, resolver);
}
Expand All @@ -72,7 +78,8 @@ private OpenSamlResourceBackedMetadataResolver convertToOpenSamlRepresentation(R
//TODO: What sort of resource type should be created here? URL?
break;
case CLASSPATH:
resource = (Resource) new ClassPathResource(resolver.getClasspathMetadataResource().getFile());
//TODO: Not sure what kind of resource class to use here.
// resource = (Resource) new ClassPathResource(resolver.getClasspathMetadataResource().getFile()); // this doesn't work.
break;
default:
throw new RuntimeException("Unsupported resource type!");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package edu.internet2.tier.shibboleth.admin.util;

import org.apache.commons.lang3.StringUtils;

import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.Duration;
import java.util.Date;

/**
* @author Bill Smith (wsmith@unicon.net)
*/
public class DurationUtility {
private static final DatatypeFactory datatypeFactory;

static {
DatatypeFactory factory;
try {
factory = DatatypeFactory.newInstance();
} catch (DatatypeConfigurationException e) {
factory = null;
}
datatypeFactory = factory;
}

public static Long toMillis(String xmlDuration) {
if (datatypeFactory == null) {
throw new RuntimeException("DatatypeFactory was never initialized!");
}
if (StringUtils.isBlank(xmlDuration)) {
return 0L;
}
Duration duration = datatypeFactory.newDuration(xmlDuration);

Date zero = new Date(0);
duration.addTo(zero); // potentially can return undesired results for large xmlDurations
return zero.getTime();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,16 @@ import edu.internet2.tier.shibboleth.admin.ui.util.TestObjectGenerator
import edu.internet2.tier.shibboleth.admin.util.AttributeUtility
import groovy.json.JsonOutput
import groovy.json.JsonSlurper
import org.opensaml.saml.metadata.resolver.ChainingMetadataResolver
import org.opensaml.saml.metadata.resolver.MetadataResolver
import org.opensaml.saml.metadata.resolver.impl.FilesystemMetadataResolver
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.boot.test.context.TestConfiguration
import org.springframework.boot.test.web.client.TestRestTemplate
import org.springframework.context.annotation.Bean
import org.springframework.http.HttpEntity
import org.springframework.http.HttpHeaders

import org.springframework.test.context.ActiveProfiles

import spock.lang.Specification
import spock.lang.Unroll

Expand Down Expand Up @@ -162,6 +160,10 @@ class MetadataResolversControllerIntegrationTests extends Specification {
result.statusCodeValue == 201
result.headers.Location[0].contains(BASE_URI)

cleanup:
def file = new File('/tmp/foo.txt')
file.delete()

where:
resolverType | _
'DynamicHttp' | _
Expand Down Expand Up @@ -263,7 +265,7 @@ class MetadataResolversControllerIntegrationTests extends Specification {
static class Config {
@Bean
MetadataResolver metadataResolver() {
new FilesystemMetadataResolver(new File('fake'))
new ChainingMetadataResolver()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ class TestObjectGenerator {
randomResolver = localDynamicMetadataResolver()
break
case 'ResourceBacked':
randomResolver = resourceBackedMetadataResolverForSVN()
randomResolver = resourceBackedMetadataResolverForClasspath()
break
case 'Filesystem':
randomResolver = filesystemMetadataResolver()
Expand Down Expand Up @@ -463,6 +463,20 @@ class TestObjectGenerator {
}
}

ResourceBackedMetadataResolver resourceBackedMetadataResolverForClasspath() {
def file = new File('/tmp/foo.txt') // should we really do this?
file.write 'This is a temp file for a groovy test.'
new ResourceBackedMetadataResolver().with {
it.name = 'ClasspathResourceMetadata'
it.xmlId = 'ClasspathResourceMetadata'
it.classpathMetadataResource = new ClasspathMetadataResource().with {
it.file = '/tmp/foo.txt'
it
}
it
}
}

FileBackedHttpMetadataResolver buildFileBackedHttpMetadataResolver() {
def resolver = new FileBackedHttpMetadataResolver()
resolver.name = generator.randomString(10)
Expand Down

0 comments on commit 3d160aa

Please sign in to comment.