Skip to content

Commit

Permalink
Merge branch 'master' into SHIBUI-660
Browse files Browse the repository at this point in the history
  • Loading branch information
Bill Smith committed Aug 16, 2018
2 parents 85bd3c1 + 9449d07 commit 3551b54
Show file tree
Hide file tree
Showing 27 changed files with 358 additions and 160 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -126,16 +126,18 @@ class JPAMetadataResolverServiceImpl implements MetadataResolverService {
}

void constructXmlNodeForFilter(SignatureValidationFilter filter, def markupBuilderDelegate) {
markupBuilderDelegate.MetadataFilter(id: filter.name,
'xsi:type': 'SignatureValidation',
'xmlns:md': 'urn:oasis:names:tc:SAML:2.0:metadata',
'requireSignedRoot': !filter.requireSignedRoot ?: null,
'certificateFile': filter.certificateFile,
'defaultCriteriaRef': filter.defaultCriteriaRef,
'signaturePrevalidatorRef': filter.signaturePrevalidatorRef,
'dynamicTrustedNamesStrategyRef': filter.dynamicTrustedNamesStrategyRef,
'trustEngineRef': filter.trustEngineRef,
'publicKey': filter.publicKey)
if(filter.xmlShouldBeGenerated()) {
markupBuilderDelegate.MetadataFilter(id: filter.name,
'xsi:type': 'SignatureValidation',
'xmlns:md': 'urn:oasis:names:tc:SAML:2.0:metadata',
'requireSignedRoot': !filter.requireSignedRoot ?: null,
'certificateFile': filter.certificateFile,
'defaultCriteriaRef': filter.defaultCriteriaRef,
'signaturePrevalidatorRef': filter.signaturePrevalidatorRef,
'dynamicTrustedNamesStrategyRef': filter.dynamicTrustedNamesStrategyRef,
'trustEngineRef': filter.trustEngineRef,
'publicKey': filter.publicKey)
}
}

void constructXmlNodeForFilter(EntityAttributesFilter filter, def markupBuilderDelegate) {
Expand Down Expand Up @@ -165,10 +167,12 @@ class JPAMetadataResolverServiceImpl implements MetadataResolverService {
}

void constructXmlNodeForFilter(RequiredValidUntilFilter filter, def markupBuilderDelegate) {
markupBuilderDelegate.MetadataFilter(
'xsi:type': 'RequiredValidUntil',
maxValidityInterval: filter.maxValidityInterval
)
if(filter.xmlShouldBeGenerated()) {
markupBuilderDelegate.MetadataFilter(
'xsi:type': 'RequiredValidUntil',
maxValidityInterval: filter.maxValidityInterval
)
}
}

void constructXmlNodeForResolver(FilesystemMetadataResolver resolver, def markupBuilderDelegate, Closure childNodes) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
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.MetadataResolver;
import edu.internet2.tier.shibboleth.admin.ui.repository.FilterRepository;
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.http.HttpStatus;
import org.springframework.http.ResponseEntity;
Expand All @@ -24,22 +24,22 @@
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;

import java.net.URI;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@RestController
@RequestMapping("/api/MetadataResolvers/{metadataResolverId}")
public class MetadataFiltersController {

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

@Autowired
private MetadataResolverRepository repository;

@Autowired
private MetadataResolverService metadataResolverService;

@Autowired
private FilterRepository filterRepository;

@GetMapping("/Filters")
@Transactional(readOnly = true)
public ResponseEntity<?> getAll(@PathVariable String metadataResolverId) {
Expand Down Expand Up @@ -68,18 +68,12 @@ public ResponseEntity<?> create(@PathVariable String metadataResolverId, @Reques
return ResponseEntity.notFound().build();
}
metadataResolver.getMetadataFilters().add(createdFilter);

//convert before saving into database
if(createdFilter instanceof EntityAttributesFilter) {
EntityAttributesFilter.class.cast(createdFilter).fromTransientRepresentation();
}
MetadataResolver persistedMr = repository.save(metadataResolver);

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

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

return ResponseEntity
.created(getResourceUriFor(persistedMr, createdFilter.getResourceId()))
Expand All @@ -91,63 +85,48 @@ public ResponseEntity<?> create(@PathVariable String metadataResolverId, @Reques
public ResponseEntity<?> update(@PathVariable String metadataResolverId,
@PathVariable String resourceId,
@RequestBody MetadataFilter updatedFilter) {
MetadataFilter filterTobeUpdated = filterRepository.findByResourceId(resourceId);
if (filterTobeUpdated == null) {
return ResponseEntity.notFound().build();
}

MetadataResolver metadataResolver = repository.findByResourceId(metadataResolverId);
if(metadataResolver == null) {
return ResponseEntity.notFound().build();
}

if (!resourceId.equals(updatedFilter.getResourceId())) {
return new ResponseEntity<Void>(HttpStatus.CONFLICT);
// check to make sure that the relationship exists
if (!metadataResolver.getMetadataFilters().contains(filterTobeUpdated)) {
// TODO: find a better response
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}

List<MetadataFilter> filters =
metadataResolver.getMetadataFilters().stream()
.filter(f -> f.getResourceId().equals(updatedFilter.getResourceId()))
.collect(Collectors.toList());
if (filters.size() > 1) {
// TODO: I don't think this should ever happen, but... if it does...
// do something? throw exception, return error?
LOGGER.warn("More than one filter was found for id {}! This is probably a bad thing.\n" +
"We're going to go ahead and use the first one, but .. look in to this!", updatedFilter.getResourceId());
if (!resourceId.equals(updatedFilter.getResourceId())) {
return new ResponseEntity<Void>(HttpStatus.CONFLICT);
}

MetadataFilter filterTobeUpdated = filters.get(0);
// Verify we're the only one attempting to update the filter
if (updatedFilter.getVersion() != filterTobeUpdated.hashCode()) {
if (updatedFilter.getVersion() != filterTobeUpdated.getVersion()) {
return new ResponseEntity<Void>(HttpStatus.CONFLICT);
}

filterTobeUpdated.setName(updatedFilter.getName());
filterTobeUpdated.setFilterEnabled(updatedFilter.isFilterEnabled());
updateConcreteFilterTypeData(filterTobeUpdated, updatedFilter);

//convert before saving into database
if(filterTobeUpdated instanceof EntityAttributesFilter) {
EntityAttributesFilter.class.cast(filterTobeUpdated).fromTransientRepresentation();
}
MetadataFilter persistedFilter = filterRepository.save(filterTobeUpdated);

MetadataResolver persistedMr = repository.save(metadataResolver);

metadataResolverService.reloadFilters(persistedMr.getName());

MetadataFilter persistedFilter =
convertIntoTransientRepresentationIfNecessary(persistedMr.getMetadataFilters().stream(), updatedFilter.getResourceId());

persistedFilter.setVersion(persistedFilter.hashCode());
// TODO: this is wrong
metadataResolverService.reloadFilters(metadataResolver.getName());

return ResponseEntity.ok().body(persistedFilter);
}

private MetadataFilter convertIntoTransientRepresentationIfNecessary(Stream<MetadataFilter> filters, final String filterResourceId) {
private MetadataFilter newlyPersistedFilter(Stream<MetadataFilter> filters, final String filterResourceId) {
MetadataFilter persistedFilter = filters
.filter(f -> f.getResourceId().equals(filterResourceId))
.collect(Collectors.toList()).get(0);

//convert before saving into database
if(persistedFilter instanceof EntityAttributesFilter) {
EntityAttributesFilter.class.cast(persistedFilter).intoTransientRepresentation();
}
return persistedFilter;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ public ResponseEntity<?> unableToParseJson(Exception ex) {
@Transactional(readOnly = true)
public ResponseEntity<?> getAll() {
List<MetadataResolver> resolvers = positionOrderContainerService.getAllMetadataResolversInDefinedOrderOrUnordered();
resolvers.forEach(MetadataResolver::updateVersion);
return ResponseEntity.ok(resolvers);
}

Expand All @@ -95,7 +94,6 @@ public ResponseEntity<?> getOne(@PathVariable String resourceId) {
if (resolver == null) {
return ResponseEntity.notFound().build();
}
resolver.updateVersion();
return ResponseEntity.ok(resolver);
}

Expand All @@ -111,12 +109,9 @@ public ResponseEntity<?> create(@RequestBody MetadataResolver newResolver) {
return validationErrorResponse;
}

newResolver.convertFiltersFromTransientRepresentationIfNecessary();
MetadataResolver persistedResolver = resolverRepository.save(newResolver);
positionOrderContainerService.appendPositionOrderForNew(persistedResolver);
persistedResolver.updateVersion();

persistedResolver.convertFiltersIntoTransientRepresentationIfNecessary();
return ResponseEntity.created(getResourceUriFor(persistedResolver)).body(persistedResolver);
}

Expand All @@ -127,9 +122,9 @@ public ResponseEntity<?> update(@PathVariable String resourceId, @RequestBody Me
if (existingResolver == null) {
return ResponseEntity.notFound().build();
}
if (existingResolver.hashCode() != updatedResolver.getVersion()) {
if (existingResolver.getVersion() != updatedResolver.getVersion()) {
log.info("Metadata Resolver version conflict. Latest resolver in database version: {}. Resolver version sent from UI: {}",
existingResolver.hashCode(), updatedResolver.getVersion());
existingResolver.getVersion(), updatedResolver.getVersion());
return ResponseEntity.status(HttpStatus.CONFLICT).build();
}

Expand All @@ -140,11 +135,7 @@ public ResponseEntity<?> update(@PathVariable String resourceId, @RequestBody Me

updatedResolver.setAudId(existingResolver.getAudId());

//If one needs to update filters, it should be dealt with via filters endpoints
updatedResolver.setMetadataFilters(existingResolver.getMetadataFilters());

MetadataResolver persistedResolver = resolverRepository.save(updatedResolver);
persistedResolver.updateVersion();

return ResponseEntity.ok(persistedResolver);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
import javax.persistence.OneToOne;
import javax.persistence.OrderColumn;
import javax.persistence.PostLoad;
import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
import javax.persistence.Transient;
import java.util.ArrayList;

Expand Down Expand Up @@ -48,25 +46,29 @@ public EntityAttributesFilter() {
@Transient
private List<String> attributeRelease = new ArrayList<>();

public void setAttributeRelease(List<String> attributeRelease) {
this.attributeRelease = attributeRelease;
this.rebuildAttributes();
}

@Transient
private RelyingPartyOverridesRepresentation relyingPartyOverrides;

public void setRelyingPartyOverrides(RelyingPartyOverridesRepresentation relyingPartyOverridesRepresentation) {
this.relyingPartyOverrides = relyingPartyOverridesRepresentation;
this.rebuildAttributes();
}

//TODO: yeah, I'm not too happy, either
private void rebuildAttributes() {
this.attributes.clear();
this.attributes.addAll((List<edu.internet2.tier.shibboleth.admin.ui.domain.Attribute>) (List<? extends org.opensaml.saml.saml2.core.Attribute>)getAttributeListFromAttributeReleaseList(this.attributeRelease));
this.attributes.addAll((List<edu.internet2.tier.shibboleth.admin.ui.domain.Attribute>) (List<? extends org.opensaml.saml.saml2.core.Attribute>)getAttributeListFromRelyingPartyOverridesRepresentation(this.relyingPartyOverrides));
}

@PostLoad
public void intoTransientRepresentation() {
this.attributeRelease = getAttributeReleaseListFromAttributeList(this.attributes);
this.relyingPartyOverrides = getRelyingPartyOverridesRepresentationFromAttributeList(attributes);
updateVersion();
}

@PrePersist
@PreUpdate
public void fromTransientRepresentation() {
List<org.opensaml.saml.saml2.core.Attribute> attributeList = new ArrayList<>();
attributeList.addAll(getAttributeListFromAttributeReleaseList(this.attributeRelease));
attributeList.addAll(getAttributeListFromRelyingPartyOverridesRepresentation(this.relyingPartyOverrides));

if(!attributeList.isEmpty()) {
this.attributes = (List<edu.internet2.tier.shibboleth.admin.ui.domain.Attribute>) (List<? extends org.opensaml.saml.saml2.core.Attribute>) attributeList;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package edu.internet2.tier.shibboleth.admin.ui.domain.filters;

import com.fasterxml.jackson.annotation.JsonGetter;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
Expand Down Expand Up @@ -46,9 +47,13 @@ public class MetadataFilter extends AbstractAuditable {
private boolean filterEnabled;

@Transient
private int version;

public void updateVersion() {
this.version = hashCode();
private transient Integer version;

@JsonGetter("version")
public int getVersion() {
if (version != null && version != 0) {
return this.version;
}
return this.hashCode();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,8 @@ public RequiredValidUntilFilter() {
}

private String maxValidityInterval;

public boolean xmlShouldBeGenerated() {
return (maxValidityInterval != null) && (!maxValidityInterval.equals("PT0S"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,7 @@
import lombok.Setter;
import lombok.ToString;

import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.OrderColumn;
import java.util.ArrayList;
import java.util.List;

@Entity
@EqualsAndHashCode(callSuper = true)
Expand All @@ -38,4 +31,8 @@ public SignatureValidationFilter() {
private String trustEngineRef;

private String publicKey;

public boolean xmlShouldBeGenerated() {
return requireSignedRoot;
}
}
Loading

0 comments on commit 3551b54

Please sign in to comment.