Skip to content

Commit

Permalink
Merge branch 'master' into bugfix/SHIBUI-985
Browse files Browse the repository at this point in the history
  • Loading branch information
rmathis committed Nov 30, 2018
2 parents 4a3ae5f + 46526ab commit 50f92c5
Show file tree
Hide file tree
Showing 80 changed files with 3,238 additions and 685 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -382,3 +382,6 @@ gradle-app.setting

# Do not ignore typescript config
!tsconfig.json

# pac4j
pac4j-module/out/
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ The easiest way to do this in a servlet container is through the use of system p

## Authentication

Currently, the application is wired with very simple authentication. A password for the user `user`
Currently, the application is wired with very simple authentication. A password for the user `root`
can be set with the `shibui.default-password` property. If none is set, a default password
will be generated and logged:

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

import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilter
import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilterTarget
import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.DynamicHttpMetadataResolver
import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.FileBackedHttpMetadataResolver
import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.HttpMetadataResolverAttributes
import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataQueryProtocolScheme
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.ui.repository.MetadataResolverRepository
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.UserRepository
import edu.internet2.tier.shibboleth.admin.util.ModelRepresentationConversions
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Profile
import org.springframework.stereotype.Component
import org.springframework.transaction.annotation.Transactional

import javax.annotation.PostConstruct

@Component
@Profile('dev')
class DevConfig {
private final UserRepository adminUserRepository

private final MetadataResolverRepository metadataResolverRepository

DevConfig(UserRepository adminUserRepository, MetadataResolverRepository metadataResolverRepository) {
this.adminUserRepository = adminUserRepository
this.metadataResolverRepository = metadataResolverRepository
}

@Transactional
@PostConstruct
void createDevAdminUsers() {
if (adminUserRepository.count() == 0) {
def user = new User().with {
username = 'admin'
password = '{noop}adminpass'
roles.add(new Role(name: 'ROLE_ADMIN'))
it
}

adminUserRepository.save(user)
}
}

@Transactional
@Profile('fbhmr')
@Bean
MetadataResolver fbhmr(ModelRepresentationConversions modelRepresentationConversions) {
return this.metadataResolverRepository.save(new FileBackedHttpMetadataResolver().with {
enabled = true
xmlId = 'test-fbhmr'
name = 'test-fbhmr'
metadataURL = 'http://md.incommon.org/InCommon/InCommon-metadata.xml'
backingFile = '%{idp.home}/test-fbhmr.xml'
reloadableMetadataResolverAttributes = new ReloadableMetadataResolverAttributes()
httpMetadataResolverAttributes = new HttpMetadataResolverAttributes()
it.metadataFilters.add(new EntityAttributesFilter().with {
it.name = 'test'
it.filterEnabled = true
it.entityAttributesFilterTarget = new EntityAttributesFilterTarget().with {
it.entityAttributesFilterTargetType = EntityAttributesFilterTarget.EntityAttributesFilterTargetType.ENTITY
it.value = ["https://carmenwiki.osu.edu/shibboleth"]
return it
}
it.attributeRelease = ['eduPersonPrincipalName', 'givenName', 'surname', 'mail']
it.relyingPartyOverrides = null
return it
})
return it
})
}

@Profile('dhmr')
@Transactional
@Bean
MetadataResolver dhmr(ModelRepresentationConversions modelRepresentationConversions) {
return this.metadataResolverRepository.save(new DynamicHttpMetadataResolver().with {
it.enabled = true
it.xmlId = 'test-dhmr'
it.name = 'test-dhmr'
it.metadataRequestURLConstructionScheme = new MetadataQueryProtocolScheme(content: 'http://mdq-beta.incommon.org/global')
it.metadataFilters.add(new EntityAttributesFilter().with {
it.name = 'test'
it.filterEnabled = true
it.entityAttributesFilterTarget = new EntityAttributesFilterTarget().with {
it.entityAttributesFilterTargetType = EntityAttributesFilterTarget.EntityAttributesFilterTargetType.ENTITY
it.value = ["https://issues.shibboleth.net/shibboleth"]
return it
}
it.attributeRelease = ['eduPersonPrincipalName', 'givenName', 'surname', 'mail']
it.relyingPartyOverrides = null
return it
})
return it
})
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController

import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaLocationLookup.filesystemMetadataProviderSchema
//import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaLocationLookup.localDynamicMetadataProviderSchema
//import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaLocationLookup.dynamicHttpMetadataProviderSchema
import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaLocationLookup.localDynamicMetadataProviderSchema
import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaLocationLookup.dynamicHttpMetadataProviderSchema
import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR
import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.SchemaType

Expand Down Expand Up @@ -41,12 +41,12 @@ class MetadataResolverUiDefinitionController {
case SchemaType.FILESYSTEM_METADATA_RESOLVER:
jsonSchemaLocation = filesystemMetadataProviderSchema(this.jsonSchemaResourceLocationRegistry)
break
/* case SchemaType.LOCAL_DYNAMIC_METADATA_RESOLVER:
case SchemaType.LOCAL_DYNAMIC_METADATA_RESOLVER:
jsonSchemaLocation = localDynamicMetadataProviderSchema(this.jsonSchemaResourceLocationRegistry)
break*/
/* case SchemaType.DYNAMIC_HTTP_METADATA_RESOLVER:
break
case SchemaType.DYNAMIC_HTTP_METADATA_RESOLVER:
jsonSchemaLocation = dynamicHttpMetadataProviderSchema(this.jsonSchemaResourceLocationRegistry)
break*/
break
default:
throw new UnsupportedOperationException("Json schema for an unsupported metadata resolver (" + resolverType + ") was requested")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,21 @@ class RelyingPartyOverridesJsonSchemaValidatingControllerAdvice extends RequestB
}

@Override
Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
def relyingPartyOverrides = EntityDescriptorRepresentation.cast(body).relyingPartyOverrides
def relyingPartyOverridesJson = Json.make([relyingPartyOverrides: relyingPartyOverrides])
HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter,
Type targetType, Class<? extends HttpMessageConverter<?>> converterType)
throws IOException {
def bytes = inputMessage.body.bytes
def schema = Json.schema(this.jsonSchemaLocation.uri)
def validationResult = schema.validate(relyingPartyOverridesJson)

def stream = new ByteArrayInputStream(bytes)
def validationResult = schema.validate(Json.read(stream.getText()))
if (!validationResult.at('ok')) {
throw new JsonSchemaValidationFailedException(validationResult.at('errors').asList())
}
body
return [
getBody: { new ByteArrayInputStream(bytes) },
getHeaders: { inputMessage.headers }
] as HttpInputMessage
}

@ExceptionHandler(JsonSchemaValidationFailedException)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.DynamicHttpMetada
import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.FileBackedHttpMetadataResolver
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.MetadataQueryProtocolScheme
import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataRequestURLConstructionScheme
import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.RegexScheme
import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.ResourceBackedMetadataResolver
import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.TemplateScheme
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
Expand Down Expand Up @@ -287,6 +291,36 @@ class JPAMetadataResolverServiceImpl implements MetadataResolverService {
httpMaxCacheEntries: resolver.httpMetadataResolverAttributes?.httpMaxCacheEntries,
httpMaxCacheEntrySize: resolver.httpMetadataResolverAttributes?.httpMaxCacheEntrySize) {

switch (MetadataRequestURLConstructionScheme.SchemeType.get(resolver.metadataRequestURLConstructionScheme.type)) {
case MetadataRequestURLConstructionScheme.SchemeType.METADATA_QUERY_PROTOCOL:
MetadataQueryProtocolScheme scheme = (MetadataQueryProtocolScheme) resolver.metadataRequestURLConstructionScheme
MetadataQueryProtocol(transformRef: scheme.transformRef) {
if (scheme.content != null) {
mkp.yield(scheme.content)
}
}
break
case MetadataRequestURLConstructionScheme.SchemeType.TEMPLATE:
TemplateScheme scheme = (TemplateScheme) resolver.metadataRequestURLConstructionScheme
Template(encodingStyle: scheme.encodingStyle,
transformRef: scheme.transformRef,
velocityEngine: scheme.velocityEngine) {
if (scheme.content != null) {
mkp.yield(scheme.content)
}
}
break
case MetadataRequestURLConstructionScheme.SchemeType.REGEX:
RegexScheme scheme = (RegexScheme) resolver.metadataRequestURLConstructionScheme
Regex(match: scheme.match) {
if (scheme.content != null) {
mkp.yield(scheme.content)
}
}
break
default:
break
}
childNodes()
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,36 @@
package edu.internet2.tier.shibboleth.admin.ui;

import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolverRepository;
import edu.internet2.tier.shibboleth.admin.ui.service.MetadataResolverService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.Profile;
import org.springframework.context.event.EventListener;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

@SpringBootApplication
@ComponentScan(excludeFilters = @ComponentScan.Filter(type = FilterType.REGEX, pattern = "edu.internet2.tier.shibboleth.admin.ui.configuration.auto.*"))
@EntityScan(basePackages = "edu.internet2.tier.shibboleth.admin.ui.domain")
@EntityScan(basePackages = {"edu.internet2.tier.shibboleth.admin.ui.domain", "edu.internet2.tier.shibboleth.admin.ui.security.model"})
@EnableJpaAuditing
@EnableScheduling
@EnableWebSecurity
public class ShibbolethUiApplication extends SpringBootServletInitializer {

private static final Logger logger = LoggerFactory.getLogger(ShibbolethUiApplication.class);

@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(ShibbolethUiApplication.class);
Expand All @@ -44,10 +48,29 @@ public static class MetadataResolversResourceIdEmitter {
MetadataResolverRepository metadataResolverRepository;

@EventListener
void showMetadataResolversResourceIds(ApplicationStartedEvent e) {
public void showMetadataResolversResourceIds(ApplicationStartedEvent e) {
metadataResolverRepository.findAll()
.forEach(it -> System.out.println(String.format("MetadataResolver [%s: %s]", it.getName(), it.getResourceId())));
.forEach(it -> logger.info(String.format("MetadataResolver [%s: %s]", it.getName(), it.getResourceId())));
}
}

@Component
public static class MetadataResolverInitializingApplicationStartupListener {

@Autowired
MetadataResolverService metadataResolverService;

@Autowired
MetadataResolverRepository metadataResolverRepository;

@Transactional
@EventListener
public void initializeResolvers(ApplicationStartedEvent e) {
metadataResolverRepository.findAll()
.forEach(it -> {
logger.info(String.format("Reloading filters for resolver [%s: %s]", it.getName(), it.getResourceId()));
metadataResolverService.reloadFilters(it.getResourceId());
});
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.SchemaType.ENTITY_ATTRIBUTES_FILTERS;
import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.SchemaType.METADATA_SOURCES;
import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.SchemaType.FILESYSTEM_METADATA_RESOLVER;
//import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.SchemaType.LOCAL_DYNAMIC_METADATA_RESOLVER;
//import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.SchemaType.DYNAMIC_HTTP_METADATA_RESOLVER;
import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.SchemaType.LOCAL_DYNAMIC_METADATA_RESOLVER;
import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResourceLocation.SchemaType.DYNAMIC_HTTP_METADATA_RESOLVER;

/**
* @author Dmitriy Kopylenko
Expand All @@ -38,15 +38,15 @@ public class JsonSchemaComponentsConfiguration {
@Setter
private String filesystemMetadataResolverUiSchemaLocation = "classpath:file-system-metadata-provider.schema.json";

/* TODO: Will be added as part of SHIBUI-703
//Configured via @ConfigurationProperties (using setter method) with 'shibui.local-dynamic-metadata-provider-ui-schema-location' property and
// default value set here if that property is not explicitly set in application.properties
@Setter
private String localDynamicMetadataResolverUiSchemaLocation = "classpath:local-dynamic-metadata-provider.schema.json";
*/

/* TODO: Will be added as part of SHIBUI-704
//Configured via @ConfigurationProperties (using setter method) with 'shibui.dynamic-http-metadata-provider-ui-schema-location' property and
// default value set here if that property is not explicitly set in application.properties
@Setter
private String dynamicHttpMetadataResolverUiSchemaLocation = "classpath:dynamic-http-metadata-provider.schema.json";
*/

@Bean
public JsonSchemaResourceLocationRegistry jsonSchemaResourceLocationRegistry(ResourceLoader resourceLoader, ObjectMapper jacksonMapper) {
Expand All @@ -68,20 +68,19 @@ public JsonSchemaResourceLocationRegistry jsonSchemaResourceLocationRegistry(Res
.resourceLoader(resourceLoader)
.jacksonMapper(jacksonMapper)
.detectMalformedJson(true)
.build());
/*.register(DYNAMIC_HTTP_METADATA_RESOLVER, JsonSchemaLocationBuilder.with()
.jsonSchemaLocation(dynamicHttpMetadataResolverUiSchemaLocation)
.build())
.register(LOCAL_DYNAMIC_METADATA_RESOLVER, JsonSchemaLocationBuilder.with()
.jsonSchemaLocation(localDynamicMetadataResolverUiSchemaLocation)
.resourceLoader(resourceLoader)
.jacksonMapper(jacksonMapper)
.detectMalformedJson(true)
.build())
.register(LOCAL_DYNAMIC_METADATA_RESOLVER, JsonSchemaLocationBuilder.with()
.jsonSchemaLocation(localDynamicMetadataResolverUiSchemaLocation)
.register(DYNAMIC_HTTP_METADATA_RESOLVER, JsonSchemaLocationBuilder.with()
.jsonSchemaLocation(dynamicHttpMetadataResolverUiSchemaLocation)
.resourceLoader(resourceLoader)
.jacksonMapper(jacksonMapper)
.detectMalformedJson(true)
.build());*/

.build());
}

@Bean
Expand Down
Loading

0 comments on commit 50f92c5

Please sign in to comment.