diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/authorization/AuthorizationServiceImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/authorization/AuthorizationServiceImpl.java index dab26f88..c4caca1d 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/authorization/AuthorizationServiceImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/authorization/AuthorizationServiceImpl.java @@ -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) diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/bulkaction/BulkActionService.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/bulkaction/BulkActionService.java index 6cbbc601..61775f69 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/bulkaction/BulkActionService.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/bulkaction/BulkActionService.java @@ -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. + *

+ * 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. + *

+ * below is the relation-tree of known node-entities of the SEB Server application + * + * Institution + * ____________ / | \______________ + * / | \ + * LMS Setup | User-Account + * | | + * Exam Configuration + * |\ / + * | Exam Config Mapping + * | + * Client Connection + * */ 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 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 createReport(BulkAction action); } \ No newline at end of file diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/UserActivityLogDAOImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/UserActivityLogDAOImpl.java index 378efa83..c6f16ac6 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/UserActivityLogDAOImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/UserActivityLogDAOImpl.java @@ -336,14 +336,17 @@ public class UserActivityLogDAOImpl implements UserActivityLogDAO { @Override @Transactional public Result save(final UserActivityLog modified) { - // TODO Auto-generated method stub - return Result.ofTODO(); + throw new UnsupportedOperationException(); } @Override public Result createNew(final UserActivityLog data) { - // TODO Auto-generated method stub - return Result.ofTODO(); + return log( + data.activityType, + data.entityType, + data.entityId, + data.message, + data); } @Override diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ActivatableEntityController.java b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ActivatableEntityController.java index aa0f18d2..defc6307 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ActivatableEntityController.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ActivatableEntityController.java @@ -40,7 +40,7 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.validation.BeanValidationSe * @param The concrete Entity domain-model type used on all GET, PUT * @param The concrete Entity domain-model type used for POST methods (new) */ public abstract class ActivatableEntityController - extends GrantEntityController { + extends EntityController { public ActivatableEntityController( final AuthorizationService authorizationGrantService, diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/GrantEntityController.java b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/EntityController.java similarity index 85% rename from src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/GrantEntityController.java rename to src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/EntityController.java index cfa4a4f8..d40f21df 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/GrantEntityController.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/EntityController.java @@ -55,7 +55,7 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.validation.BeanValidationSe * * @param The concrete Entity domain-model type used on all GET, PUT * @param The concrete Entity domain-model type used for POST methods (new) */ -public abstract class GrantEntityController { +public abstract class EntityController { protected final AuthorizationService authorization; protected final BulkActionService bulkActionService; @@ -64,7 +64,7 @@ public abstract class GrantEntityController entityDAO, @@ -196,7 +196,7 @@ public abstract class GrantEntityController 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 this.bulkActionService.createReport(bulkAction)) .getOrThrow(); } @@ -362,7 +333,7 @@ public abstract class GrantEntityController> getAll(final FilterMap filterMap) { return this.entityDAO.allMatching( filterMap, - this.authorization::hasReadonlyGrant); + this::hasReadAccess); } protected Result notifyCreated(final T entity) { @@ -390,6 +361,56 @@ public abstract class GrantEntityController 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 checkModifyAccess(final T entity) { + final GrantEntity grantEntity = toGrantEntity(entity); + if (grantEntity != null) { + this.authorization.checkModify(grantEntity); + } + return Result.of(entity); + } + + private Result checkWriteAccess(final T entity) { + final GrantEntity grantEntity = toGrantEntity(entity); + if (grantEntity != null) { + this.authorization.checkWrite(grantEntity); + } + return Result.of(entity); + } + + private Result 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(); diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/IndicatorController.java b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/IndicatorController.java index 817eb37b..62535887 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/IndicatorController.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/IndicatorController.java @@ -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 { +public class IndicatorController extends EntityController { private final ExamDAO examDao;