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;