Skip to content

Commit

Permalink
Merge into master
Browse files Browse the repository at this point in the history
  • Loading branch information
dima767 committed Aug 15, 2018
2 parents 7bdad26 + fd1230b commit 66227ab
Show file tree
Hide file tree
Showing 59 changed files with 1,144 additions and 358 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,15 @@
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;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
Expand All @@ -27,67 +26,61 @@
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;

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

import static org.springframework.http.HttpStatus.NOT_FOUND;

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

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

@Autowired
private MetadataResolverRepository repository;

@Autowired
private MetadataResolverService metadataResolverService;

private static final Supplier<HttpClientErrorException> HTTP_404_CLIENT_ERROR_EXCEPTION = () -> new HttpClientErrorException(NOT_FOUND);
@Autowired
private FilterRepository filterRepository;

@ExceptionHandler
public ResponseEntity<?> notFoundHandler(HttpClientErrorException ex) {
if(ex.getStatusCode() == NOT_FOUND) {
return ResponseEntity.notFound().build();
}
throw ex;
}
private static final Supplier<HttpClientErrorException> HTTP_404_CLIENT_ERROR_EXCEPTION = () -> new HttpClientErrorException(NOT_FOUND);

@GetMapping("/Filters")
@Transactional(readOnly = true)
public ResponseEntity<?> getAll(@PathVariable String metadataResolverId) {
MetadataResolver resolver = findResolverOrThrowHttp404(metadataResolverId);
resolver.convertFiltersIntoTransientRepresentationIfNecessary();
MetadataResolver resolver = repository.findByResourceId(metadataResolverId);
if(resolver == null) {
return ResponseEntity.notFound().build();
}
return ResponseEntity.ok(resolver.getMetadataFilters());
}

@GetMapping("/Filters/{resourceId}")
@Transactional(readOnly = true)
public ResponseEntity<?> getOne(@PathVariable String metadataResolverId, @PathVariable String resourceId) {
MetadataResolver resolver = findResolverOrThrowHttp404(metadataResolverId);
resolver.convertFiltersIntoTransientRepresentationIfNecessary();
return ResponseEntity.ok(findFilterOrThrowHttp404(resolver, resourceId));
MetadataResolver resolver = repository.findByResourceId(metadataResolverId);
if(resolver == null) {
return ResponseEntity.notFound().build();
}
return ResponseEntity.ok(resolver.getMetadataFilters().stream()
.filter(f -> f.getResourceId().equals(resourceId))
.collect(Collectors.toList()).get(0));
}

@PostMapping("/Filters")
@Transactional
public ResponseEntity<?> create(@PathVariable String metadataResolverId, @RequestBody MetadataFilter createdFilter) {
MetadataResolver metadataResolver = findResolverOrThrowHttp404(metadataResolverId);
metadataResolver.getMetadataFilters().add(createdFilter);

//convert before saving into database
if(createdFilter instanceof EntityAttributesFilter) {
EntityAttributesFilter.class.cast(createdFilter).fromTransientRepresentation();
MetadataResolver metadataResolver = repository.findByResourceId(metadataResolverId);
if(metadataResolver == null) {
return ResponseEntity.notFound().build();
}
metadataResolver.getMetadataFilters().add(createdFilter);
MetadataResolver persistedMr = repository.save(metadataResolver);

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

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

return ResponseEntity
.created(getResourceUriFor(persistedMr, createdFilter.getResourceId()))
Expand All @@ -96,51 +89,42 @@ public ResponseEntity<?> create(@PathVariable String metadataResolverId, @Reques
}

@PutMapping("/Filters/{resourceId}")
@Transactional
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 = findResolverOrThrowHttp404(metadataResolverId);
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, updatedFilter.getResourceId());

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

return ResponseEntity.ok().body(persistedFilter);
}
Expand All @@ -156,7 +140,6 @@ public ResponseEntity<?> delete(@PathVariable String metadataResolverId,
throw HTTP_404_CLIENT_ERROR_EXCEPTION.get();
}
repository.save(resolver);
MetadataResolver persistedMr = repository.findByResourceId(metadataResolverId);

//TODO: do we need to reload filters here?!?
//metadataResolverService.reloadFilters(persistedMr.getName());
Expand All @@ -172,19 +155,11 @@ private MetadataResolver findResolverOrThrowHttp404(String resolverResourceId) {
return resolver;
}

private MetadataFilter findFilterOrThrowHttp404(MetadataResolver resolver, String filterResourceId) {
return resolver.getMetadataFilters().stream()
private MetadataFilter newlyPersistedFilter(Stream<MetadataFilter> filters, final String filterResourceId) {
MetadataFilter persistedFilter = filters
.filter(f -> f.getResourceId().equals(filterResourceId))
.findFirst()
.orElseThrow(HTTP_404_CLIENT_ERROR_EXCEPTION);
}
.collect(Collectors.toList()).get(0);

private MetadataFilter convertIntoTransientRepresentationIfNecessary(MetadataResolver resolver, final String filterResourceId) {
MetadataFilter persistedFilter = findFilterOrThrowHttp404(resolver, filterResourceId);
//convert before saving into database
if(persistedFilter instanceof EntityAttributesFilter) {
EntityAttributesFilter.class.cast(persistedFilter).intoTransientRepresentation();
}
return persistedFilter;
}

Expand Down Expand Up @@ -238,4 +213,4 @@ private static URI getResourceUriFor(MetadataResolver mr, String filterResourceI
.build()
.toUri();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,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 @@ -86,7 +85,6 @@ public ResponseEntity<?> getOne(@PathVariable String resourceId) {
if (resolver == null) {
return ResponseEntity.notFound().build();
}
resolver.updateVersion();
return ResponseEntity.ok(resolver);
}

Expand All @@ -102,13 +100,9 @@ public ResponseEntity<?> create(@RequestBody MetadataResolver newResolver) {
return validationErrorResponse;
}

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

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

Expand All @@ -119,9 +113,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 @@ -132,12 +126,8 @@ public ResponseEntity<?> update(@PathVariable String resourceId, @RequestBody Me

updatedResolver.setAudId(existingResolver.getAudId());

updatedResolver.convertFiltersFromTransientRepresentationIfNecessary();
resolverRepository.save(updatedResolver);
MetadataResolver persistedResolver = resolverRepository.findByResourceId(updatedResolver.getResourceId());
MetadataResolver persistedResolver = resolverRepository.save(updatedResolver);

persistedResolver.updateVersion();
persistedResolver.convertFiltersFromTransientRepresentationIfNecessary();
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,22 +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 intoTransientRepresentation() {
this.attributeRelease = getAttributeReleaseListFromAttributeList(this.attributes);
this.relyingPartyOverrides = getRelyingPartyOverridesRepresentationFromAttributeList(attributes);
updateVersion();
public void setRelyingPartyOverrides(RelyingPartyOverridesRepresentation relyingPartyOverridesRepresentation) {
this.relyingPartyOverrides = relyingPartyOverridesRepresentation;
this.rebuildAttributes();
}

public void fromTransientRepresentation() {
List<org.opensaml.saml.saml2.core.Attribute> attributeList = new ArrayList<>();
attributeList.addAll(getAttributeListFromAttributeReleaseList(this.attributeRelease));
attributeList.addAll(getAttributeListFromRelyingPartyOverridesRepresentation(this.relyingPartyOverrides));
//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));
}

if(!attributeList.isEmpty()) {
this.attributes = (List<edu.internet2.tier.shibboleth.admin.ui.domain.Attribute>) (List<? extends org.opensaml.saml.saml2.core.Attribute>) attributeList;
}
@PostLoad
public void intoTransientRepresentation() {
this.attributeRelease = getAttributeReleaseListFromAttributeList(this.attributes);
this.relyingPartyOverrides = getRelyingPartyOverridesRepresentationFromAttributeList(attributes);
}
}
}
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();
}
}
}
Loading

0 comments on commit 66227ab

Please sign in to comment.