Skip to content

Commit

Permalink
Merge branch 'master' into SHIBUI-619
Browse files Browse the repository at this point in the history
  • Loading branch information
dima767 committed Jul 13, 2018
2 parents d7f54a5 + 354747b commit a4d6d65
Show file tree
Hide file tree
Showing 45 changed files with 644 additions and 223 deletions.
13 changes: 13 additions & 0 deletions backend/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ plugins {
}

apply plugin: 'io.spring.dependency-management'
apply plugin: 'jacoco'

sourceCompatibility = 1.8
targetCompatibility = 1.8
Expand Down Expand Up @@ -194,3 +195,15 @@ tasks.withType(JavaExec) {
compileJava {
dependsOn generateSources
}

jacoco {
toolVersion = '0.8.1'
}

jacocoTestReport {
reports {
xml.enabled = false
csv.enabled = false
html.destination = file("${buildDir}/jacocoHtml")
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package edu.internet2.tier.shibboleth.admin.ui.service

import com.google.common.base.Predicate
import edu.internet2.tier.shibboleth.admin.ui.domain.filters.*
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.filters.EntityRoleWhiteListFilter
import edu.internet2.tier.shibboleth.admin.ui.domain.filters.RequiredValidUntilFilter
import edu.internet2.tier.shibboleth.admin.ui.domain.filters.SignatureValidationFilter
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.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.opensaml.OpenSamlObjects
Expand Down Expand Up @@ -157,6 +162,30 @@ class JPAMetadataResolverServiceImpl implements MetadataResolverService {
)
}

void constructXmlNodeForResolver(FilesystemMetadataResolver resolver, def markupBuilderDelegate, Closure childNodes) {
markupBuilderDelegate.MetadataProvider(id: resolver.name,
'xsi:type': 'FilesystemMetadataProvider',
metadataFile: resolver.metadataFile,

requireValidMetadata: !resolver.requireValidMetadata ?: null,
failFastInitialization: !resolver.failFastInitialization ?: null,
sortKey: resolver.sortKey,
criterionPredicateRegistryRef: resolver.criterionPredicateRegistryRef,
useDefaultPredicateRegistry: !resolver.useDefaultPredicateRegistry ?: null,
satisfyAnyPredicates: resolver.satisfyAnyPredicates ?: null,

parserPoolRef: resolver.reloadableMetadataResolverAttributes?.parserPoolRef,
minRefreshDelay: resolver.reloadableMetadataResolverAttributes?.minRefreshDelay,
maxRefreshDelay: resolver.reloadableMetadataResolverAttributes?.maxRefreshDelay,
refreshDelayFactor: resolver.reloadableMetadataResolverAttributes?.refreshDelayFactor,
indexesRef: resolver.reloadableMetadataResolverAttributes?.indexesRef,
resolveViaPredicatesOnly: resolver.reloadableMetadataResolverAttributes?.resolveViaPredicatesOnly ?: null,
expirationWarningThreshold: resolver.reloadableMetadataResolverAttributes?.expirationWarningThreshold) {

childNodes()
}
}

void constructXmlNodeForResolver(DynamicHttpMetadataResolver resolver, def markupBuilderDelegate, Closure childNodes) {
markupBuilderDelegate.MetadataProvider(id: resolver.name,
'xsi:type': 'DynamicHttpMetadataProvider',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package edu.internet2.tier.shibboleth.admin.ui.domain.resolvers;

import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

import javax.persistence.Embedded;
import javax.persistence.Entity;

/**
* @author Bill Smith (wsmith@unicon.net)
*/
@Entity
@EqualsAndHashCode(callSuper = true)
@Getter
@Setter
@ToString
public class FilesystemMetadataResolver extends MetadataResolver {

public FilesystemMetadataResolver() {
type = "FilesystemMetadataResolver";
}

private String metadataFile;

@Embedded
private ReloadableMetadataResolverAttributes reloadableMetadataResolverAttributes;
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "@type", visible = true)
@JsonSubTypes({@JsonSubTypes.Type(value = LocalDynamicMetadataResolver.class, name = "LocalDynamicMetadataResolver"),
@JsonSubTypes.Type(value = FileBackedHttpMetadataResolver.class, name = "FileBackedHttpMetadataResolver"),
@JsonSubTypes.Type(value = DynamicHttpMetadataResolver.class, name = "DynamicHttpMetadataResolver")})
@JsonSubTypes.Type(value = DynamicHttpMetadataResolver.class, name = "DynamicHttpMetadataResolver"),
@JsonSubTypes.Type(value = FilesystemMetadataResolver.class, name = "FilesystemMetadataResolver"),
@JsonSubTypes.Type(value = ResourceBackedMetadataResolver.class, name = "ResourceBackedMetadataResolver")})
public class MetadataResolver extends AbstractAuditable {

@JsonProperty("@type")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
@ToString
public class ResourceBackedMetadataResolver extends MetadataResolver {

public ResourceBackedMetadataResolver() {
type = "ResourceBackedMetadataResolver";
}

@Embedded
private ReloadableMetadataResolverAttributes reloadableMetadataResolverAttributes;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package edu.internet2.tier.shibboleth.admin.ui.controller

import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.SerializationFeature
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.repository.MetadataResolverRepository
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.MetadataResolver
Expand All @@ -18,6 +22,7 @@ import org.springframework.http.HttpHeaders
import org.springframework.test.context.ActiveProfiles

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

import static org.springframework.http.HttpMethod.PUT

Expand All @@ -34,10 +39,22 @@ class MetadataResolversControllerIntegrationTests extends Specification {
@Autowired
MetadataResolverRepository metadataResolverRepository

@Autowired
AttributeUtility attributeUtility

ObjectMapper mapper
TestObjectGenerator generator

JsonSlurper jsonSlurper = new JsonSlurper()

static BASE_URI = '/api/MetadataResolvers'

def setup() {
generator = new TestObjectGenerator(attributeUtility)
mapper = new ObjectMapper()
mapper.enable(SerializationFeature.INDENT_OUTPUT)
}

def cleanup() {
metadataResolverRepository.deleteAll()
}
Expand Down Expand Up @@ -130,24 +147,31 @@ class MetadataResolversControllerIntegrationTests extends Specification {
result.statusCodeValue == 404
}

def "POST new DynamicHttpMetadataResolver -> /api/MetadataResolvers"() {
@Unroll
def "POST new DynamicHttpMetadataResolver of type #resolverType -> /api/MetadataResolvers"(String resolverType) {
given: 'New MetadataResolver JSON representation'
def resolver = [name: 'Test DynamicHttpMetadataResolver', '@type': 'DynamicHttpMetadataResolver']
def resolver = generator.buildRandomMetadataResolverOfType(resolverType)

when: 'POST request is made with new DynamicHttpMetadataResolver JSON representation'
def result = this.restTemplate.postForEntity(BASE_URI, createRequestHttpEntityFor { JsonOutput.toJson(resolver) }, String)
def result = this.restTemplate.postForEntity(BASE_URI, createRequestHttpEntityFor { mapper.writeValueAsString(resolver) }, String)

then:
result.statusCodeValue == 201
result.headers.Location[0].contains(BASE_URI)

where:
resolverType | _
'DynamicHttp' | _
'FileBacked' | _
'LocalDynamic' | _
'ResourceBacked' | _
'Filesystem' | _
}

def "PUT concrete MetadataResolver with updated changes -> /api/MetadataResolvers/{resourceId}"() {
@Unroll
def "PUT concrete MetadataResolver of type #resolverType with updated changes -> /api/MetadataResolvers/{resourceId}"(String resolverType) {
given: 'One resolver is available in data store'
def resolver = new DynamicHttpMetadataResolver().with {
it.name = 'Test DynamicHttpMetadataResolver'
it
}
def resolver = generator.buildRandomMetadataResolverOfType(resolverType)
def resolverResourceId = resolver.resourceId
metadataResolverRepository.save(resolver)

Expand All @@ -171,6 +195,13 @@ class MetadataResolversControllerIntegrationTests extends Specification {
then:
updatedResolverMap.name == 'Updated DynamicHttpMetadataResolver'

where:
resolverType | _
'DynamicHttp' | _
'FileBacked' | _
'LocalDynamic' | _
'ResourceBacked' | _
'Filesystem' | _
}

def "PUT concrete MetadataResolver with version conflict -> /api/MetadataResolvers/{resourceId}"() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,19 @@ class JPAMetadataResolverServiceImplTests extends Specification {
generatedXmlIsTheSameAsExpectedXml('/conf/546-classpath.xml', domBuilder.parseText(writer.toString()))
}

def 'test generating FilesystemMetadataResolver xml snippet'() {
given:
def resolver = testObjectGenerator.filesystemMetadataResolver()

when:
genXmlSnippet(markupBuilder) {
JPAMetadataResolverServiceImpl.cast(metadataResolverService).constructXmlNodeForResolver(resolver, it) {}
}

then:
generatedXmlIsTheSameAsExpectedXml('/conf/520.xml', domBuilder.parseText(writer.toString()))
}

static genXmlSnippet(MarkupBuilder xml, Closure xmlNodeGenerator) {
xml.MetadataProvider('id': 'ShibbolethMetadata',
'xmlns': 'urn:mace:shibboleth:2.0:metadata',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,45 @@ class TestObjectGenerator {
return contactPerson
}

MetadataResolver buildRandomMetadataResolverOfType(String metadataResolverType) {
def randomResolver
switch (metadataResolverType) {
case 'DynamicHttp':
randomResolver = dynamicHttpMetadataResolver()
break
case 'FileBacked':
randomResolver = fileBackedHttpMetadataResolver()
break
case 'LocalDynamic':
randomResolver = localDynamicMetadataResolver()
break
case 'ResourceBacked':
randomResolver = resourceBackedMetadataResolverForSVN()
break
case 'Filesystem':
randomResolver = filesystemMetadataResolver()
break;
default:
throw new RuntimeException("Did you forget to create a TestObjectGenerator.<type>MetadataResolver method for resolverType: ${metadataResolverType} ?");
}
randomResolver
}

FilesystemMetadataResolver filesystemMetadataResolver() {
new FilesystemMetadataResolver().with {
it.name = 'FilesystemMetadata'
it.metadataFile = 'some metadata filename'

it.reloadableMetadataResolverAttributes = new ReloadableMetadataResolverAttributes().with {
it.minRefreshDelay = 'PT5M'
it.maxRefreshDelay = 'PT1H'
it.refreshDelayFactor = 0.75
it
}
it
}
}

FileBackedHttpMetadataResolver fileBackedHttpMetadataResolver() {
new FileBackedHttpMetadataResolver().with {
it.name = 'HTTPMetadata'
Expand Down
14 changes: 14 additions & 0 deletions backend/src/test/resources/conf/520.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- This file is an EXAMPLE metadata configuration file. -->
<MetadataProvider xmlns="urn:mace:shibboleth:2.0:metadata"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
id="ShibbolethMetadata"
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"
xsi:type="ChainingMetadataProvider">
<MetadataProvider id="FilesystemMetadata"
maxRefreshDelay="PT1H"
metadataFile="some metadata filename"
minRefreshDelay="PT5M"
refreshDelayFactor="0.75"
xsi:type="FilesystemMetadataProvider"/>
</MetadataProvider>
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<form [formGroup]="searchForm">
<label for="search" class="sr-only" i18n="@@action--search">Search</label>
<div class="input-group">
<div class="input-group input-group-sm">
<input
id="search"
type="text"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<section class="section">
<div class="section-body border border-top-0 border-primary">
<div class="section-header bg-primary p-2 text-light">
<div class="row justify-content-between">
<div class="col-12">
<span class="lead" i18n="@@label--current-metadata-sources">Current Metadata Providers</span>
</div>
</div>
</div>
<div class="p-3">
<code><pre>{{ providers$ | async | json }}</pre></code>
</div>
</div>
</section>



Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Component } from '@angular/core';
import { MetadataProvider } from '../../domain/model';
import { Observable } from '../../../../../node_modules/rxjs';
import { Store } from '@ngrx/store';
import { ProviderState, getAllProviders } from '../../provider/reducer';

@Component({
selector: 'dashboard-providers-list',
templateUrl: './dashboard-providers-list.component.html'
})

export class DashboardProvidersListComponent {

providers$: Observable<MetadataProvider[]>;

constructor(
private store: Store<ProviderState>
) {
this.providers$ = this.store.select(getAllProviders);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<section class="section">
<div class="section-body border border-top-0 border-primary">
<div class="section-header bg-primary p-2 text-light">
<div class="row justify-content-between">
<div class="col-md-8">
<span class="lead" i18n="@@label--current-metadata-sources">Current Metadata Sources</span>
</div>
<div class="col-md-4">
<provider-search
[query]="searchQuery$ | async"
[searching]="loading$ | async"
(search)="search($event)">
</provider-search>
</div>
</div>
</div>
<div class="p-3">
<ul class="list-unstyled m-0">
<li *ngFor="let entity of limited$ | async; index as i"
[ngClass]="{'mt-2': i > 0}"
aria-label="Provider Item Accordion. Press Spacebar to open">
<entity-item
[entity]="entity"
[isOpen]="(entitiesOpen$ | async)[entity.getId()]"
(select)="edit(entity)"
(toggle)="toggleEntity(entity)"
(preview)="openPreviewDialog(entity)"
(delete)="deleteResolver(entity)">
</entity-item>
</li>
</ul>
<div class="mt-3 clearfix" *ngIf="(total$ | async) > limit">
<ngb-pagination
class="float-right"
[collectionSize]="total$ | async"
[page]="page"
[pageSize]="limit"
(pageChange)="changePage($event)"
aria-label="Pages">
</ngb-pagination>
</div>
</div>
</div>
</section>
Loading

0 comments on commit a4d6d65

Please sign in to comment.