Skip to content

Commit

Permalink
SHIBUI-814 resolved conflict
Browse files Browse the repository at this point in the history
  • Loading branch information
rmathis committed Sep 21, 2018
2 parents 9a47fef + 3899e35 commit a3c4e40
Show file tree
Hide file tree
Showing 32 changed files with 585 additions and 115 deletions.
52 changes: 52 additions & 0 deletions Jenkinsfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
pipeline {
agent any
options {
disableConcurrentBuilds()
buildDiscarder(logRotator(numToKeepStr: '10', artifactNumToKeepStr: '10'))
}
stages {
stage('Build') {
steps {
sh './gradlew clean build'
}
post {
always {
junit 'backend/build/test-results/**/*.xml'
jacoco execPattern: '**/build/jacoco/test.exec'
}
}
}
stage('Build Docker images') {
when {
expression {
return GIT_BRANCH in ['master']
}
}
steps {
sh '''./gradlew docker
'''
}
}
stage('Deploy') {
when {
expression {
return GIT_BRANCH in ['master']
}
}
steps {
sh '''
docker stop shibui || true && docker rm shibui || true
docker run -d --restart always --name shibui -p 8080:8080 -v /etc/shibui/application.properties:/application.properties unicon/shibui:latest
'''
}
}
}
post {
failure {
step([$class: 'Mailer', notifyEveryUnstableBuild: true, recipients: emailextrecipients([[$class: 'CulpritsRecipientProvider'], [$class: 'RequesterRecipientProvider']])])
}
success {
emailext body: '''${SCRIPT, template="groovy-text.template"}''', recipientProviders: [[$class: 'DevelopersRecipientProvider'], [$class: 'RequesterRecipientProvider']], subject: '[SHIBUI] Build Success'
}
}
}
9 changes: 9 additions & 0 deletions backend/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FROM gcr.io/distroless/java

ARG JAR_FILE

COPY ${JAR_FILE} app.jar

EXPOSE 8080

CMD ["app.jar"]
11 changes: 11 additions & 0 deletions backend/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ plugins {
id 'com.gorylenko.gradle-git-properties' version '1.4.21'
id 'net.researchgate.release' version '2.6.0'
id 'io.franzbecker.gradle-lombok' version '1.13'
id 'com.palantir.docker' version '0.20.1'
}

apply plugin: 'io.spring.dependency-management'
Expand Down Expand Up @@ -208,3 +209,13 @@ jacocoTestReport {
html.destination = file("${buildDir}/jacocoHtml")
}
}

tasks.docker.dependsOn tasks.build
docker {
name 'unicon/shibui'
tags 'latest'
pull true
noCache true
files tasks.bootWar.outputs
buildArgs(['JAR_FILE': 'shibui.war'])
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,16 @@ 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.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.logic.ScriptedPredicate
import net.shibboleth.utilities.java.support.resolver.ResolverException
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.RefreshableMetadataResolver
import org.opensaml.saml.metadata.resolver.filter.MetadataFilter
import org.opensaml.saml.metadata.resolver.filter.MetadataFilterChain
import org.opensaml.saml.saml2.core.Attribute
Expand Down Expand Up @@ -52,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.findByName(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 @@ -94,12 +92,11 @@ class JPAMetadataResolverServiceImpl implements MetadataResolverService {
metadataFilterChain.setFilters(metadataFilters)
}

if (metadataResolver instanceof RefreshableMetadataResolver) {
try {
((RefreshableMetadataResolver) metadataResolver).refresh()
} catch (ResolverException e) {
log.warn("error refreshing metadataResolver " + metadataResolverName, e)
}
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()")
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package edu.internet2.tier.shibboleth.admin.ui.configuration;

import com.fasterxml.jackson.databind.Module;
import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects;
import edu.internet2.tier.shibboleth.admin.ui.repository.EntityDescriptorRepository;
import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolverRepository;
Expand Down Expand Up @@ -168,4 +169,9 @@ public DirectoryService directoryService() {
public LuceneUtility luceneUtility(DirectoryService directoryService) {
return new LuceneUtility(directoryService);
}

@Bean
public Module stringTrimModule() {
return new StringTrimModule();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package edu.internet2.tier.shibboleth.admin.ui.configuration;

import edu.internet2.tier.shibboleth.admin.ui.service.MetadataResolverConverterService;
import edu.internet2.tier.shibboleth.admin.ui.service.MetadataResolverConverterServiceImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
* @author Bill Smith (wsmith@unicon.net)
*/
@Configuration
public class MetadataResolverConverterConfiguration {
@Bean
public MetadataResolverConverterService metadataResolverConverterService() {
return new MetadataResolverConverterServiceImpl();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package edu.internet2.tier.shibboleth.admin.ui.configuration;

import edu.internet2.tier.shibboleth.admin.ui.service.TokenPlaceholderValueResolvingService;
import edu.internet2.tier.shibboleth.admin.util.TokenPlaceholderResolvers;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.ConfigurableEnvironment;

@Configuration
public class PlaceholderResolverComponentsConfiguration {

@Bean
public TokenPlaceholderValueResolvingService tokenPlaceholderValueResolvingService(ConfigurableEnvironment env) {
return TokenPlaceholderValueResolvingService.shibbolethPlaceholderPrefixAware(env.getPropertySources());
}

@Bean
public TokenPlaceholderResolvers tokenPlaceholderResolvers(TokenPlaceholderValueResolvingService service) {
return new TokenPlaceholderResolvers(service);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package edu.internet2.tier.shibboleth.admin.ui.configuration;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.deser.std.StdScalarDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;

import java.io.IOException;

/**
* @author Bill Smith (wsmith@unicon.net)
*
* Adapted from Maciej Marczuk's answer on Stack Overflow here:
* https://stackoverflow.com/questions/6852213/can-jackson-be-configured-to-trim-leading-trailing-whitespace-from-all-string-pr/33765854#33765854
*/
public class StringTrimModule extends SimpleModule {

public StringTrimModule() {
addDeserializer(String.class, new StdScalarDeserializer<String>(String.class) {
@Override
public String deserialize(JsonParser jsonParser, DeserializationContext ctx) throws IOException {
return jsonParser.getValueAsString().trim();
}
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package edu.internet2.tier.shibboleth.admin.ui.configuration.postprocessors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MapPropertySource;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

/**
* Spring Boot Environment Post Processor setting the value for idp.home property to a temp directory
* if no IDP_HOME environment variable has been set already.
*
* @author Dmitriy Kopylenko
*/
public class IdpHomeValueSettingEnvironmentPostProcessor implements EnvironmentPostProcessor {

private static final String IDP_HOME_PROP = "idp.home";

private static final String METADATA_DIR = "metadata";

private static final Logger LOGGER = LoggerFactory.getLogger(IdpHomeValueSettingEnvironmentPostProcessor.class);

@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
if(environment.getProperty(IDP_HOME_PROP) == null) {
Map<String, Object> map = new HashMap<>(1);
try {
Path tempDir = Files.createTempDirectory(null);
tempDir.toFile().deleteOnExit();
String tempDirName = tempDir.toAbsolutePath().toString();
Path tempMetadataSubDir = Paths.get(tempDirName, METADATA_DIR);
Files.createDirectories(tempMetadataSubDir);
map.put(IDP_HOME_PROP, tempDirName);
} catch (IOException e) {
LOGGER.error(e.getMessage());
throw new RuntimeException(e);
}
environment.getPropertySources().addLast(new MapPropertySource("idp.home.propertysource", map));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,7 @@ public ResponseEntity<?> create(@PathVariable String metadataResolverId, @Reques
MetadataResolver persistedMr = repository.save(metadataResolver);

// we reload the filters here after save
metadataResolverService.reloadFilters(persistedMr.getName());
refreshOrInitResolver(metadataResolver);
metadataResolverService.reloadFilters(persistedMr.getResourceId());

MetadataFilter persistedFilter = newlyPersistedFilter(persistedMr.getMetadataFilters().stream(), createdFilter.getResourceId());

Expand All @@ -98,33 +97,6 @@ public ResponseEntity<?> create(@PathVariable String metadataResolverId, @Reques
.body(persistedFilter);
}

private void refreshOrInitResolver(MetadataResolver resolver) {
List<org.opensaml.saml.metadata.resolver.MetadataResolver> resolvers = ((ChainingMetadataResolver) chainingMetadataResolver).getResolvers();
resolvers.stream().filter(it -> it.getId().equals(resolver.getResourceId())).forEach(it -> {
if (it instanceof RefreshableMetadataResolver) {
try {
((RefreshableMetadataResolver) it).refresh();
} catch (ResolverException e) {
//TODO what should we do if we can't refresh?
}
} else if (it instanceof OpenSamlFunctionDrivenDynamicHTTPMetadataResolver) {
try {
((OpenSamlFunctionDrivenDynamicHTTPMetadataResolver) it).refresh();
} catch (ComponentInitializationException e) {
//TODO what should we do if we can't refresh?
}
} else if (it instanceof OpenSamlLocalDynamicMetadataResolver) {
try {
((OpenSamlLocalDynamicMetadataResolver) it).refresh();
} catch (ComponentInitializationException e) {
//TODO what should we do if we can't refresh?
}
} else {
//TODO we shouldn't get here, but if we do... throw exception?
}
});
}

@PutMapping("/Filters/{resourceId}")
public ResponseEntity<?> update(@PathVariable String metadataResolverId,
@PathVariable String resourceId,
Expand Down Expand Up @@ -158,8 +130,7 @@ public ResponseEntity<?> update(@PathVariable String metadataResolverId,
MetadataFilter persistedFilter = filterRepository.save(filterTobeUpdated);

// TODO: this is wrong
metadataResolverService.reloadFilters(metadataResolver.getName());
refreshOrInitResolver(metadataResolver);
metadataResolverService.reloadFilters(metadataResolver.getResourceId());

return ResponseEntity.ok().body(persistedFilter);
}
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 @@ -118,19 +118,14 @@ public ResponseEntity<?> create(@RequestBody MetadataResolver newResolver) throw
MetadataResolver persistedResolver = resolverRepository.save(newResolver);
positionOrderContainerService.appendPositionOrderForNew(persistedResolver);

updateChainingMetadataResolver(persistedResolver);
//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?
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 @@ -153,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
Loading

0 comments on commit a3c4e40

Please sign in to comment.