refactoring EntityController
This commit is contained in:
parent
2b3d4aa27d
commit
201e37914e
6 changed files with 107 additions and 46 deletions
|
@ -104,7 +104,7 @@ public class AuthorizationServiceImpl implements AuthorizationService {
|
|||
.andForRole(UserRole.INSTITUTIONAL_ADMIN)
|
||||
.withInstitutionalPrivilege(PrivilegeType.READ)
|
||||
.andForRole(UserRole.EXAM_ADMIN)
|
||||
.withInstitutionalPrivilege(PrivilegeType.MODIFY)
|
||||
.withInstitutionalPrivilege(PrivilegeType.WRITE)
|
||||
.withOwnerPrivilege(PrivilegeType.WRITE)
|
||||
.andForRole(UserRole.EXAM_SUPPORTER)
|
||||
.withInstitutionalPrivilege(PrivilegeType.READ)
|
||||
|
@ -117,7 +117,7 @@ public class AuthorizationServiceImpl implements AuthorizationService {
|
|||
.andForRole(UserRole.INSTITUTIONAL_ADMIN)
|
||||
.withInstitutionalPrivilege(PrivilegeType.READ)
|
||||
.andForRole(UserRole.EXAM_ADMIN)
|
||||
.withInstitutionalPrivilege(PrivilegeType.MODIFY)
|
||||
.withInstitutionalPrivilege(PrivilegeType.WRITE)
|
||||
.withOwnerPrivilege(PrivilegeType.WRITE)
|
||||
.andForRole(UserRole.EXAM_SUPPORTER)
|
||||
.withInstitutionalPrivilege(PrivilegeType.READ)
|
||||
|
|
|
@ -11,12 +11,49 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction;
|
|||
import ch.ethz.seb.sebserver.gbl.model.EntityProcessingReport;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||
|
||||
/** Service to address bulk actions like activation or deletion where the action
|
||||
* or state-change of one Entity has an effect on other entities that that has
|
||||
* a relation to the source entity.
|
||||
* <p>
|
||||
* A bulk action for a specified entity instance will be first applied to all its dependent
|
||||
* child-entities. For example if one is going to delete/deactivate a particular LMS Setup, all
|
||||
* Exams imported from this LMSSetup are first deactivated and all Exam Config Mapping and
|
||||
* all Client Connection are of all the Exams are deactivated first.
|
||||
* <p>
|
||||
* below is the relation-tree of known node-entities of the SEB Server application
|
||||
* <code>
|
||||
* Institution
|
||||
* ____________ / | \______________
|
||||
* / | \
|
||||
* LMS Setup | User-Account
|
||||
* | |
|
||||
* Exam Configuration
|
||||
* |\ /
|
||||
* | Exam Config Mapping
|
||||
* |
|
||||
* Client Connection
|
||||
* </code> */
|
||||
public interface BulkActionService {
|
||||
|
||||
/** Use this to collect all EntityKey's of all dependent entities for a given BulkAction.
|
||||
*
|
||||
* @param action the BulkAction defining the source entity keys and acts also as the
|
||||
* dependency collector */
|
||||
void collectDependencies(BulkAction action);
|
||||
|
||||
/** This executes a given BulkAction by first getting all dependencies and applying
|
||||
* the action to that first and then applying the action to the source entities of
|
||||
* the BulkAction.
|
||||
*
|
||||
* @param action the BulkAction that defines at least the type and the source entity keys
|
||||
* @return The BulkAction containing the result of the execution */
|
||||
Result<BulkAction> doBulkAction(BulkAction action);
|
||||
|
||||
/** Creates a EntityProcessingReport from a given BulkAction result.
|
||||
* If the given BulkAction has not already been executed, it will be executed first
|
||||
*
|
||||
* @param action the BulkAction of a concrete type
|
||||
* @return EntityProcessingReport extracted form an executed BulkAxtion */
|
||||
Result<EntityProcessingReport> createReport(BulkAction action);
|
||||
|
||||
}
|
|
@ -336,14 +336,17 @@ public class UserActivityLogDAOImpl implements UserActivityLogDAO {
|
|||
@Override
|
||||
@Transactional
|
||||
public Result<UserActivityLog> save(final UserActivityLog modified) {
|
||||
// TODO Auto-generated method stub
|
||||
return Result.ofTODO();
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<UserActivityLog> createNew(final UserActivityLog data) {
|
||||
// TODO Auto-generated method stub
|
||||
return Result.ofTODO();
|
||||
return log(
|
||||
data.activityType,
|
||||
data.entityType,
|
||||
data.entityId,
|
||||
data.message,
|
||||
data);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -40,7 +40,7 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.validation.BeanValidationSe
|
|||
* @param <T> The concrete Entity domain-model type used on all GET, PUT
|
||||
* @param <M> The concrete Entity domain-model type used for POST methods (new) */
|
||||
public abstract class ActivatableEntityController<T extends GrantEntity, M extends GrantEntity>
|
||||
extends GrantEntityController<T, M> {
|
||||
extends EntityController<T, M> {
|
||||
|
||||
public ActivatableEntityController(
|
||||
final AuthorizationService authorizationGrantService,
|
||||
|
|
|
@ -55,7 +55,7 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.validation.BeanValidationSe
|
|||
*
|
||||
* @param <T> The concrete Entity domain-model type used on all GET, PUT
|
||||
* @param <M> The concrete Entity domain-model type used for POST methods (new) */
|
||||
public abstract class GrantEntityController<T extends GrantEntity, M extends GrantEntity> {
|
||||
public abstract class EntityController<T extends Entity, M extends Entity> {
|
||||
|
||||
protected final AuthorizationService authorization;
|
||||
protected final BulkActionService bulkActionService;
|
||||
|
@ -64,7 +64,7 @@ public abstract class GrantEntityController<T extends GrantEntity, M extends Gra
|
|||
protected final PaginationService paginationService;
|
||||
protected final BeanValidationService beanValidationService;
|
||||
|
||||
protected GrantEntityController(
|
||||
protected EntityController(
|
||||
final AuthorizationService authorization,
|
||||
final BulkActionService bulkActionService,
|
||||
final EntityDAO<T, M> entityDAO,
|
||||
|
@ -196,7 +196,7 @@ public abstract class GrantEntityController<T extends GrantEntity, M extends Gra
|
|||
|
||||
this.entityDAO
|
||||
.byModelId(modelId)
|
||||
.flatMap(this.authorization::checkRead);
|
||||
.map(this::checkReadAccess);
|
||||
|
||||
final BulkAction bulkAction = new BulkAction(
|
||||
bulkActionType,
|
||||
|
@ -220,7 +220,7 @@ public abstract class GrantEntityController<T extends GrantEntity, M extends Gra
|
|||
|
||||
return this.entityDAO
|
||||
.byModelId(modelId)
|
||||
.flatMap(this.authorization::checkRead)
|
||||
.flatMap(this::checkReadAccess)
|
||||
.getOrThrow();
|
||||
}
|
||||
|
||||
|
@ -246,7 +246,7 @@ public abstract class GrantEntityController<T extends GrantEntity, M extends Gra
|
|||
.flatMap(this.entityDAO::byEntityKeys)
|
||||
.getOrThrow()
|
||||
.stream()
|
||||
.filter(this.authorization::hasReadonlyGrant)
|
||||
.filter(this::hasReadAccess)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
@ -276,7 +276,7 @@ public abstract class GrantEntityController<T extends GrantEntity, M extends Gra
|
|||
|
||||
final M requestModel = this.createNew(postMap);
|
||||
|
||||
return this.authorization.checkWrite(requestModel)
|
||||
return this.checkCreateAccess(requestModel)
|
||||
.flatMap(this::validForCreate)
|
||||
.flatMap(this.entityDAO::createNew)
|
||||
.flatMap(this.userActivityLogDAO::logCreate)
|
||||
|
@ -294,7 +294,7 @@ public abstract class GrantEntityController<T extends GrantEntity, M extends Gra
|
|||
produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
public T savePut(@Valid @RequestBody final T modifyData) {
|
||||
|
||||
return this.authorization.checkModify(modifyData)
|
||||
return this.checkModifyAccess(modifyData)
|
||||
.flatMap(this::validForSave)
|
||||
.flatMap(this.entityDAO::save)
|
||||
.flatMap(this.userActivityLogDAO::logModify)
|
||||
|
@ -302,35 +302,6 @@ public abstract class GrantEntityController<T extends GrantEntity, M extends Gra
|
|||
.getOrThrow();
|
||||
}
|
||||
|
||||
// ******************
|
||||
// * PATCH (save)
|
||||
// ******************
|
||||
|
||||
// NOTE: not supported yet because of difficulties on conversion of params-map to json object
|
||||
// @RequestMapping(
|
||||
// path = "/{id}",
|
||||
// method = RequestMethod.PATCH,
|
||||
// consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
|
||||
// produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
// public T savePost(
|
||||
// @PathVariable final String id,
|
||||
// @RequestParam final MultiValueMap<String, String> allRequestParams,
|
||||
// @RequestParam(
|
||||
// name = Entity.FILTER_ATTR_INSTITUTION,
|
||||
// required = true,
|
||||
// defaultValue = UserService.USERS_INSTITUTION_AS_DEFAULT) final Long institutionId) {
|
||||
//
|
||||
// allRequestParams.putIfAbsent(
|
||||
// Domain.ATTR_INSTITUTION_ID,
|
||||
// Arrays.asList(String.valueOf(institutionId)));
|
||||
// final M requestModel = this.toRequestModel(null, allRequestParams);
|
||||
//
|
||||
// return this.entityDAO.save(id, requestModel)
|
||||
// .flatMap(entity -> this.userActivityLogDAO.log(ActivityType.MODIFY, entity))
|
||||
// .flatMap(entity -> notifySaved(requestModel, entity))
|
||||
// .getOrThrow();
|
||||
// }
|
||||
|
||||
// ******************
|
||||
// * DELETE (delete)
|
||||
// ******************
|
||||
|
@ -347,7 +318,7 @@ public abstract class GrantEntityController<T extends GrantEntity, M extends Gra
|
|||
new EntityKey(modelId, entityType));
|
||||
|
||||
return this.entityDAO.byModelId(modelId)
|
||||
.flatMap(this.authorization::checkWrite)
|
||||
.flatMap(this::checkWriteAccess)
|
||||
.flatMap(entity -> this.bulkActionService.createReport(bulkAction))
|
||||
.getOrThrow();
|
||||
}
|
||||
|
@ -362,7 +333,7 @@ public abstract class GrantEntityController<T extends GrantEntity, M extends Gra
|
|||
protected Result<Collection<T>> getAll(final FilterMap filterMap) {
|
||||
return this.entityDAO.allMatching(
|
||||
filterMap,
|
||||
this.authorization::hasReadonlyGrant);
|
||||
this::hasReadAccess);
|
||||
}
|
||||
|
||||
protected Result<T> notifyCreated(final T entity) {
|
||||
|
@ -390,6 +361,56 @@ public abstract class GrantEntityController<T extends GrantEntity, M extends Gra
|
|||
return Result.of(entity);
|
||||
}
|
||||
|
||||
private Result<T> checkReadAccess(final T entity) {
|
||||
final GrantEntity grantEntity = toGrantEntity(entity);
|
||||
if (grantEntity != null) {
|
||||
this.authorization.checkRead(grantEntity);
|
||||
}
|
||||
return Result.of(entity);
|
||||
}
|
||||
|
||||
private boolean hasReadAccess(final T entity) {
|
||||
final GrantEntity grantEntity = toGrantEntity(entity);
|
||||
if (grantEntity != null) {
|
||||
return this.authorization.hasReadonlyGrant(grantEntity);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private Result<T> checkModifyAccess(final T entity) {
|
||||
final GrantEntity grantEntity = toGrantEntity(entity);
|
||||
if (grantEntity != null) {
|
||||
this.authorization.checkModify(grantEntity);
|
||||
}
|
||||
return Result.of(entity);
|
||||
}
|
||||
|
||||
private Result<T> checkWriteAccess(final T entity) {
|
||||
final GrantEntity grantEntity = toGrantEntity(entity);
|
||||
if (grantEntity != null) {
|
||||
this.authorization.checkWrite(grantEntity);
|
||||
}
|
||||
return Result.of(entity);
|
||||
}
|
||||
|
||||
private Result<M> checkCreateAccess(final M entity) {
|
||||
final GrantEntity grantEntity = toGrantEntity(entity);
|
||||
if (grantEntity != null) {
|
||||
this.authorization.checkWrite(grantEntity);
|
||||
}
|
||||
return Result.of(entity);
|
||||
}
|
||||
|
||||
protected GrantEntity toGrantEntity(final Entity entity) {
|
||||
if (entity instanceof GrantEntity) {
|
||||
return (GrantEntity) entity;
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Entity instance is not of type GrantEntity. "
|
||||
+ "Do override the toGrantEntity method from EntityController within the specific -Controller implementation");
|
||||
}
|
||||
|
||||
protected abstract M createNew(POSTMapper postParams);
|
||||
|
||||
protected abstract SqlTable getSQLTableOfEntity();
|
|
@ -29,7 +29,7 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.validation.BeanValidationSe
|
|||
@WebServiceProfile
|
||||
@RestController
|
||||
@RequestMapping("/${sebserver.webservice.api.admin.endpoint}" + API.EXAM_INDICATOR_ENDPOINT)
|
||||
public class IndicatorController extends GrantEntityController<Indicator, Indicator> {
|
||||
public class IndicatorController extends EntityController<Indicator, Indicator> {
|
||||
|
||||
private final ExamDAO examDao;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue