Skip to content

Commit

Permalink
SHIBUI-1740
Browse files Browse the repository at this point in the history
Refactoring/cleanup of EntityDescriptor Controller complete
  • Loading branch information
chasegawa committed Jul 3, 2021
1 parent b7aa821 commit 8db5ac8
Show file tree
Hide file tree
Showing 6 changed files with 203 additions and 328 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,6 @@ static URI getResourceUriFor(String resourceId) {
.toUri();
}

@Autowired
private EntityDescriptorRepository entityDescriptorRepository;

@Autowired
private EntityDescriptorService entityDescriptorService;

Expand All @@ -68,12 +65,9 @@ static URI getResourceUriFor(String resourceId) {
@Autowired
RestTemplateBuilder restTemplateBuilder;

private UserService userService;

private EntityDescriptorVersionService versionService;

public EntityDescriptorController(UserService userService, EntityDescriptorVersionService versionService) {
this.userService = userService;
public EntityDescriptorController(EntityDescriptorVersionService versionService) {
this.versionService = versionService;
}

Expand All @@ -92,20 +86,6 @@ public ResponseEntity<?> deleteOne(@PathVariable String resourceId) throws Forbi
return ResponseEntity.noContent().build();
}

private ResponseEntity<?> existingEntityDescriptorCheck(String entityId) {
final EntityDescriptor ed = entityDescriptorRepository.findByEntityID(entityId);
if (ed != null) {
HttpHeaders headers = new HttpHeaders();
headers.setLocation(getResourceUriFor(ed.getResourceId()));
return ResponseEntity
.status(HttpStatus.CONFLICT)
.headers(headers)
.body(new ErrorResponse(String.valueOf(HttpStatus.CONFLICT.value()), String.format("The entity descriptor with entity id [%s] already exists.", entityId)));
}
//No existing entity descriptor, which is an OK condition indicated by returning a null conflict response
return null;
}

@GetMapping("/EntityDescriptors")
@Transactional(readOnly = true)
public ResponseEntity<?> getAll() throws ForbiddenException {
Expand All @@ -115,90 +95,47 @@ public ResponseEntity<?> getAll() throws ForbiddenException {
@GetMapping("/EntityDescriptor/{resourceId}/Versions")
@Transactional(readOnly = true)
public ResponseEntity<?> getAllVersions(@PathVariable String resourceId) throws EntityNotFoundException, ForbiddenException {
// this verifies that both the ED exists and the user has proper access, so needs to remain
// this "get by resource id" verifies that both the ED exists and the user has proper access, so needs to remain
EntityDescriptor ed = entityDescriptorService.getEntityDescriptorByResourceId(resourceId);
return ResponseEntity.ok(versionService.findVersionsForEntityDescriptor(ed.getResourceId()));
}

@Secured("ROLE_ADMIN")
@Transactional(readOnly = true)
@GetMapping(value = "/EntityDescriptor/disabledNonAdmin")
public Iterable<EntityDescriptorRepresentation> getDisabledAndNotOwnedByAdmin() {
return entityDescriptorRepository.findAllDisabledAndNotOwnedByAdmin()
.map(ed -> entityDescriptorService.createRepresentationFromDescriptor(ed))
.collect(Collectors.toList());
public Iterable<EntityDescriptorRepresentation> getDisabledAndNotOwnedByAdmin() throws ForbiddenException {
return entityDescriptorService.getAllDisabledAndNotOwnedByAdmin();
}

@GetMapping("/EntityDescriptor/{resourceId}")
@Transactional(readOnly = true)
public ResponseEntity<?> getOne(@PathVariable String resourceId) {
User currentUser = userService.getCurrentUser();
if (currentUser != null) {
EntityDescriptor ed = entityDescriptorRepository.findByResourceId(resourceId);
if (ed == null) {
return ResponseEntity.notFound().build();
} else {
if (userService.isAuthorizedFor(ed.getCreatedBy(), ed.getGroup() == null ? null : ed.getGroup().getResourceId())) {
EntityDescriptorRepresentation edr = entityDescriptorService.createRepresentationFromDescriptor(ed);
return ResponseEntity.ok(edr);
}
}
}
return ResponseEntity.status(HttpStatus.FORBIDDEN).body(
new ErrorResponse(HttpStatus.FORBIDDEN, "You are not authorized to perform the requested operation."));

public ResponseEntity<?> getOne(@PathVariable String resourceId) throws EntityNotFoundException, ForbiddenException {
return ResponseEntity.ok(entityDescriptorService
.createRepresentationFromDescriptor(entityDescriptorService.getEntityDescriptorByResourceId(resourceId)));
}

@GetMapping(value = "/EntityDescriptor/{resourceId}", produces = "application/xml")
@Transactional(readOnly = true)
public ResponseEntity<?> getOneXml(@PathVariable String resourceId) throws MarshallingException {
User currentUser = userService.getCurrentUser();
if (currentUser != null) {
EntityDescriptor ed = entityDescriptorRepository.findByResourceId(resourceId);
if (ed == null) {
return ResponseEntity.notFound().build();
} else {
if (userService.isAuthorizedFor(ed.getCreatedBy(), ed.getGroup() == null ? null : ed.getGroup().getResourceId())) {
final String xml = this.openSamlObjects.marshalToXmlString(ed);
return ResponseEntity.ok(xml);
}
}
}
return ResponseEntity.status(HttpStatus.FORBIDDEN).build();

public ResponseEntity<?> getOneXml(@PathVariable String resourceId) throws MarshallingException, EntityNotFoundException, ForbiddenException {
EntityDescriptor ed = entityDescriptorService.getEntityDescriptorByResourceId(resourceId);
final String xml = this.openSamlObjects.marshalToXmlString(ed);
return ResponseEntity.ok(xml);
}

@GetMapping("/EntityDescriptor/{resourceId}/Versions/{versionId}")
@Transactional(readOnly = true)
public ResponseEntity<?> getSpecificVersion(@PathVariable String resourceId, @PathVariable String versionId) {
EntityDescriptorRepresentation edRepresentation = versionService.findSpecificVersionOfEntityDescriptor(resourceId, versionId);

if (edRepresentation == null) {
return ResponseEntity.notFound().build();
}
if(userService.isAuthorizedFor(edRepresentation.getCreatedBy(), edRepresentation.getGroupId())) {
return ResponseEntity.ok(edRepresentation);
}
return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
}

@ExceptionHandler({ ForbiddenException.class })
public void handleException() {
//
public ResponseEntity<?> getSpecificVersion(@PathVariable String resourceId, @PathVariable String versionId) throws EntityNotFoundException, ForbiddenException {
// this "get by resource id" verifies that both the ED exists and the user has proper access, so needs to remain
EntityDescriptor ed = entityDescriptorService.getEntityDescriptorByResourceId(resourceId);
return ResponseEntity.ok(versionService.findSpecificVersionOfEntityDescriptor(ed.getResourceId(), versionId));
}

private ResponseEntity<?> handleUploadingEntityDescriptorXml(byte[] rawXmlBytes, String spName) throws Exception {
final EntityDescriptor ed = EntityDescriptor.class.cast(openSamlObjects.unmarshalFromXml(rawXmlBytes));

ResponseEntity<?> existingEntityDescriptorConflictResponse = existingEntityDescriptorCheck(ed.getEntityID());
if (existingEntityDescriptorConflictResponse != null) {
return existingEntityDescriptorConflictResponse;
}

ed.setServiceProviderName(spName);
final EntityDescriptor persistedEd = entityDescriptorRepository.save(ed);
return ResponseEntity.created(getResourceUriFor(persistedEd.getResourceId()))
.body(entityDescriptorService.createRepresentationFromDescriptor(persistedEd));

EntityDescriptorRepresentation persistedEd = entityDescriptorService.createNew(ed);
return ResponseEntity.created(getResourceUriFor(persistedEd.getId())).body(persistedEd);
}

@PostConstruct
Expand Down Expand Up @@ -234,5 +171,4 @@ public ResponseEntity<?> upload(@RequestParam String metadataUrl, @RequestParam
.body(String.format("Error fetching XML metadata from the provided URL. Error: %s", e.getMessage()));
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
@ControllerAdvice(assignableTypes = {EntityDescriptorController.class})
public class EntityDescriptorControllerExceptionHandler extends ResponseEntityExceptionHandler {

@ExceptionHandler({ ForbiddenException.class })
public ResponseEntity<?> handleForbiddenAccess(ForbiddenException e, WebRequest request) {
return ResponseEntity.status(HttpStatus.FORBIDDEN).body(new ErrorResponse(HttpStatus.FORBIDDEN, e.getMessage()));
@ExceptionHandler({ ConcurrentModificationException.class })
public ResponseEntity<?> handleConcurrentModificationException(ConcurrentModificationException e, WebRequest request) {
return ResponseEntity.status(HttpStatus.CONFLICT).body(new ErrorResponse(HttpStatus.CONFLICT, e.getMessage()));
}

@ExceptionHandler({ EntityIdExistsException.class })
Expand All @@ -37,8 +37,8 @@ public ResponseEntity<?> handleEntityNotFoundException(EntityNotFoundException e
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ErrorResponse(HttpStatus.NOT_FOUND, e.getMessage()));
}

@ExceptionHandler({ ConcurrentModificationException.class })
public ResponseEntity<?> handleConcurrentModificationException(ConcurrentModificationException e, WebRequest request) {
return ResponseEntity.status(HttpStatus.CONFLICT).body(new ErrorResponse(HttpStatus.CONFLICT, e.getMessage()));
@ExceptionHandler({ ForbiddenException.class })
public ResponseEntity<?> handleForbiddenAccess(ForbiddenException e, WebRequest request) {
return ResponseEntity.status(HttpStatus.FORBIDDEN).body(new ErrorResponse(HttpStatus.FORBIDDEN, e.getMessage()));
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
package edu.internet2.tier.shibboleth.admin.ui.service;

import edu.internet2.tier.shibboleth.admin.ui.domain.Attribute;
import edu.internet2.tier.shibboleth.admin.ui.domain.EntityDescriptor;
import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.EntityDescriptorRepresentation;
import edu.internet2.tier.shibboleth.admin.ui.exception.EntityIdExistsException;
import edu.internet2.tier.shibboleth.admin.ui.exception.EntityNotFoundException;
import edu.internet2.tier.shibboleth.admin.ui.exception.ForbiddenException;

import org.opensaml.saml.saml2.metadata.EntityDescriptor;

import java.util.ConcurrentModificationException;
import java.util.List;
import java.util.Map;
Expand All @@ -22,17 +21,47 @@ public interface EntityDescriptorService {
* Map from front-end data representation of entity descriptor to opensaml implementation of entity descriptor model
*
* @param representation of entity descriptor coming from front end layer
* @return EntityDescriptor
* @return org.opensaml.saml.saml2.metadata.EntityDescriptor opensaml model
*/
org.opensaml.saml.saml2.metadata.EntityDescriptor createDescriptorFromRepresentation(final EntityDescriptorRepresentation representation);

/**
* @param ed - JPA EntityDescriptor to base creation on
* @return EntityDescriptorRepresentation of the created object
* @throws ForbiddenException If user is unauthorized to perform this operation
* @throws EntityIdExistsException If any EntityDescriptor already exists with the same EntityId
*/
EntityDescriptor createDescriptorFromRepresentation(final EntityDescriptorRepresentation representation);
EntityDescriptorRepresentation createNew(EntityDescriptor ed) throws ForbiddenException, EntityIdExistsException;

/**
* @param edRepresentation Incoming representation to save
* @return EntityDescriptorRepresentation
* @throws ForbiddenException If user is unauthorized to perform this operation
* @throws EntityIdExistsException If the entity already exists
*/
EntityDescriptorRepresentation createNew(EntityDescriptorRepresentation edRepresentation) throws ForbiddenException, EntityIdExistsException;

/**
* Map from opensaml implementation of entity descriptor model to front-end data representation of entity descriptor
*
* @param entityDescriptor opensaml model
* @param org.opensaml.saml.saml2.metadata.EntityDescriptor opensaml model
* @return EntityDescriptorRepresentation
*/
EntityDescriptorRepresentation createRepresentationFromDescriptor(final EntityDescriptor entityDescriptor);
EntityDescriptorRepresentation createRepresentationFromDescriptor(final org.opensaml.saml.saml2.metadata.EntityDescriptor entityDescriptor);

/**
* @param resourceId - id of the JPA EntityDescriptor
* @throws ForbiddenException If user is unauthorized to perform this operation
* @throws EntityNotFoundException If the db entity is not found
*/
void delete(String resourceId) throws ForbiddenException, EntityNotFoundException;

/**
* @return - Iterable set of EntityDescriptorRepresentations of those items which are NOT enabled and not owned by
* "admin"
* @throws ForbiddenException - If user is not an ADMIN
*/
Iterable<EntityDescriptorRepresentation> getAllDisabledAndNotOwnedByAdmin() throws ForbiddenException;

/**
* @return a list of EntityDescriptorRepresentations that a user has the rights to access
Expand All @@ -47,6 +76,14 @@ public interface EntityDescriptorService {
*/
List<String> getAttributeReleaseListFromAttributeList(List<Attribute> attributeList);

/**
* @param resourceId - id of the JPA EntityDescriptor
* @return JPA EntityDescriptor
* @throws ForbiddenException If user is unauthorized to perform this operation
* @throws EntityNotFoundException If the db entity is not found
*/
EntityDescriptor getEntityDescriptorByResourceId(String resourceId) throws EntityNotFoundException, ForbiddenException;

/**
* Given a list of attributes, generate a map of relying party overrides
*
Expand All @@ -55,20 +92,21 @@ public interface EntityDescriptorService {
*/
Map<String, Object> getRelyingPartyOverridesRepresentationFromAttributeList(List<Attribute> attributeList);

/**
* @param edRepresentation Incoming representation to save
* @return EntityDescriptorRepresentation
* @throws ForbiddenException If user is unauthorized to perform this operation
* @throws EntityIdExistsException If the entity already exists
* @throws ConcurrentModificationException If the entity was already modified by another user
*/
EntityDescriptorRepresentation update(EntityDescriptorRepresentation edRepresentation) throws ForbiddenException, EntityNotFoundException, ConcurrentModificationException;

/**
* Update an instance of entity descriptor with information from the front-end representation
*
* @param entityDescriptor opensaml model instance to update
* @param representation front end representation to use to update
* @param representation front end representation to use to update
*/
void updateDescriptorFromRepresentation(final EntityDescriptor entityDescriptor, final EntityDescriptorRepresentation representation);

EntityDescriptorRepresentation createNew(EntityDescriptorRepresentation edRepresentation) throws ForbiddenException, EntityIdExistsException;

EntityDescriptorRepresentation update(EntityDescriptorRepresentation edRepresentation) throws ForbiddenException, EntityNotFoundException, ConcurrentModificationException;

edu.internet2.tier.shibboleth.admin.ui.domain.EntityDescriptor getEntityDescriptorByResourceId(String resourceId) throws EntityNotFoundException, ForbiddenException;

void delete(String resourceId) throws ForbiddenException, EntityNotFoundException;
void updateDescriptorFromRepresentation(final org.opensaml.saml.saml2.metadata.EntityDescriptor entityDescriptor, final EntityDescriptorRepresentation representation);

}
Loading

0 comments on commit 8db5ac8

Please sign in to comment.