From bf45576610ad9b82b99f64379998607e362e37ae Mon Sep 17 00:00:00 2001 From: anhefti Date: Sun, 20 Jan 2019 21:05:33 +0100 Subject: [PATCH] more generalized controller endpoints --- .../ethz/seb/sebserver/gbl/model/Entity.java | 8 ++ .../gbl/model/institution/Institution.java | 8 -- .../bulkaction/BulkActionSupportDAO.java | 23 +--- .../dao/ActivatableEntityDAO.java | 3 +- .../servicelayer/dao/EntityDAO.java | 32 ++++- .../webservice/servicelayer/dao/ExamDAO.java | 4 +- .../servicelayer/dao/InstitutionDAO.java | 5 +- .../servicelayer/dao/LmsSetupDAO.java | 4 +- .../servicelayer/dao/UserActivityLogDAO.java | 3 +- .../webservice/servicelayer/dao/UserDAO.java | 12 +- .../dao/UserRelatedEntityDAO.java | 2 +- .../servicelayer/dao/impl/ExamDAOImpl.java | 2 +- .../dao/impl/InstitutionDAOImpl.java | 2 +- .../dao/impl/LmsSetupDAOImpl.java | 2 +- .../dao/impl/UserActivityLogDAOImpl.java | 14 ++ .../servicelayer/dao/impl/UserDaoImpl.java | 2 +- .../api/ActivatableEntityController.java | 11 +- .../weblayer/api/EntityController.java | 113 +++++++++++++++- .../weblayer/api/InstitutionController.java | 124 +----------------- .../weblayer/api/UserAccountController.java | 106 +-------------- 20 files changed, 197 insertions(+), 283 deletions(-) diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/Entity.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/Entity.java index caf5c045..ea942b3d 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gbl/model/Entity.java +++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/Entity.java @@ -12,9 +12,17 @@ public interface Entity extends ModelIdAware { public static final String ATTR_ID = "id"; public static final String ATTR_INSTITUTION = "institution"; + public static final String ATTR_ACTIVE = "active"; EntityType entityType(); String getName(); + public static EntityKeyAndName toName(final Entity entity) { + return new EntityKeyAndName( + entity.entityType(), + entity.getModelId(), + entity.getName()); + } + } diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/institution/Institution.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/institution/Institution.java index 9739e386..d174b7e1 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gbl/model/institution/Institution.java +++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/institution/Institution.java @@ -17,7 +17,6 @@ import com.fasterxml.jackson.annotation.JsonProperty; import ch.ethz.seb.sebserver.gbl.model.Activatable; import ch.ethz.seb.sebserver.gbl.model.Domain; import ch.ethz.seb.sebserver.gbl.model.Domain.INSTITUTION; -import ch.ethz.seb.sebserver.gbl.model.EntityKeyAndName; import ch.ethz.seb.sebserver.gbl.model.EntityType; import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.GrantEntity; @@ -110,11 +109,4 @@ public final class Institution implements GrantEntity, Activatable { + ", active=" + this.active + "]"; } - public static EntityKeyAndName toName(final Institution institution) { - return new EntityKeyAndName( - EntityType.INSTITUTION, - String.valueOf(institution.id), - institution.name); - } - } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/bulkaction/BulkActionSupportDAO.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/bulkaction/BulkActionSupportDAO.java index 89628b10..31b421e4 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/bulkaction/BulkActionSupportDAO.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/bulkaction/BulkActionSupportDAO.java @@ -20,7 +20,6 @@ import org.springframework.transaction.annotation.Transactional; import ch.ethz.seb.sebserver.gbl.model.Entity; import ch.ethz.seb.sebserver.gbl.model.EntityKey; -import ch.ethz.seb.sebserver.gbl.model.EntityKeyAndName; import ch.ethz.seb.sebserver.gbl.model.EntityType; import ch.ethz.seb.sebserver.gbl.util.Result; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ActivatableEntityDAO; @@ -37,22 +36,6 @@ public interface BulkActionSupportDAO { Set getDependencies(BulkAction bulkAction); - Result> bulkLoadEntities(Collection keys); - - @Transactional(readOnly = true) - default Result> bulkLoadEntityNames(final Collection keys) { - return Result.tryCatch(() -> { - return bulkLoadEntities(keys) - .getOrThrow() - .stream() - .map(entity -> new EntityKeyAndName( - EntityType.INSTITUTION, - entity.getModelId(), - entity.getName())) - .collect(Collectors.toList()); - }); - } - @Transactional default Collection> processBulkAction(final BulkAction bulkAction) { final Set all = bulkAction.extractKeys(entityType()); @@ -60,15 +43,15 @@ public interface BulkActionSupportDAO { switch (bulkAction.type) { case ACTIVATE: return (this instanceof ActivatableEntityDAO) - ? ((ActivatableEntityDAO) this).setActive(all, true) + ? ((ActivatableEntityDAO) this).setActive(all, true) : Collections.emptyList(); case DEACTIVATE: return (this instanceof ActivatableEntityDAO) - ? ((ActivatableEntityDAO) this).setActive(all, false) + ? ((ActivatableEntityDAO) this).setActive(all, false) : Collections.emptyList(); case HARD_DELETE: return (this instanceof EntityDAO) - ? ((EntityDAO) this).delete(all) + ? ((EntityDAO) this).delete(all) : Collections.emptyList(); } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/ActivatableEntityDAO.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/ActivatableEntityDAO.java index bb03f6be..6729879f 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/ActivatableEntityDAO.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/ActivatableEntityDAO.java @@ -15,12 +15,13 @@ import org.springframework.transaction.annotation.Transactional; import ch.ethz.seb.sebserver.gbl.model.Entity; import ch.ethz.seb.sebserver.gbl.model.EntityKey; +import ch.ethz.seb.sebserver.gbl.model.ModelIdAware; import ch.ethz.seb.sebserver.gbl.util.Result; /** Interface of a DAO for an Entity that has activation feature. * * @param the concrete Entity type */ -public interface ActivatableEntityDAO extends EntityDAO { +public interface ActivatableEntityDAO extends EntityDAO { /** Get a Collection of all active Entity instances for a concrete entity-domain. * diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/EntityDAO.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/EntityDAO.java index 58fd7295..b28b7bf2 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/EntityDAO.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/EntityDAO.java @@ -15,12 +15,16 @@ import java.util.Set; import java.util.function.Predicate; import java.util.stream.Collectors; +import org.springframework.transaction.annotation.Transactional; + import ch.ethz.seb.sebserver.gbl.model.Entity; import ch.ethz.seb.sebserver.gbl.model.EntityKey; +import ch.ethz.seb.sebserver.gbl.model.EntityKeyAndName; import ch.ethz.seb.sebserver.gbl.model.EntityType; +import ch.ethz.seb.sebserver.gbl.model.ModelIdAware; import ch.ethz.seb.sebserver.gbl.util.Result; -public interface EntityDAO { +public interface EntityDAO { /** Get the entity type for a concrete EntityDAO implementation. * @@ -80,6 +84,32 @@ public interface EntityDAO { return all(entity -> true); } + Result> loadEntities(Collection keys); + + @Transactional(readOnly = true) + default Result> loadEntityNames(final Collection keys) { + return Result.tryCatch(() -> { + return loadEntities(keys) + .getOrThrow() + .stream() + .map(entity -> new EntityKeyAndName( + entity.entityType(), + entity.getModelId(), + entity.getName())) + .collect(Collectors.toList()); + }); + } + + /** Use this to save/modify an entity. + * If the model identifier from given modified entity data is null or not exists already, a new entity is created. + * If the model identifier is available and matches an existing entity, all entity data that are + * not null on modified entity data instance are updated within the existing entity. + * + * @param modified modified data instance containing all data that should be modified + * @return A Result of the entity instance where the successfully saved/modified entity data is available or a + * reported exception on error case */ + Result save(M modified); + /** Use this to delete a set Entity by a Collection of EntityKey * * @param all The Collection of EntityKey to delete diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/ExamDAO.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/ExamDAO.java index 569678bb..0f6d72c8 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/ExamDAO.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/ExamDAO.java @@ -17,7 +17,7 @@ import ch.ethz.seb.sebserver.gbl.model.exam.QuizData; import ch.ethz.seb.sebserver.gbl.util.Result; import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.BulkActionSupportDAO; -public interface ExamDAO extends ActivatableEntityDAO, BulkActionSupportDAO { +public interface ExamDAO extends ActivatableEntityDAO, BulkActionSupportDAO { Result importFromQuizData(QuizData quizData); @@ -33,6 +33,4 @@ public interface ExamDAO extends ActivatableEntityDAO, BulkActionSupportDA String owner, Boolean active); - Result save(Exam exam); - } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/InstitutionDAO.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/InstitutionDAO.java index 5893be5f..46cde571 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/InstitutionDAO.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/InstitutionDAO.java @@ -14,10 +14,9 @@ import ch.ethz.seb.sebserver.gbl.model.institution.Institution; import ch.ethz.seb.sebserver.gbl.util.Result; import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.BulkActionSupportDAO; -public interface InstitutionDAO extends ActivatableEntityDAO, BulkActionSupportDAO { +public interface InstitutionDAO + extends ActivatableEntityDAO, BulkActionSupportDAO { Result> allMatching(String name, Boolean active); - Result save(Institution institution); - } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/LmsSetupDAO.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/LmsSetupDAO.java index 18e8f1b0..26eb35cc 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/LmsSetupDAO.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/LmsSetupDAO.java @@ -17,7 +17,7 @@ import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup.LmsType; import ch.ethz.seb.sebserver.gbl.util.Result; import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.BulkActionSupportDAO; -public interface LmsSetupDAO extends ActivatableEntityDAO, BulkActionSupportDAO { +public interface LmsSetupDAO extends ActivatableEntityDAO, BulkActionSupportDAO { @Transactional(readOnly = true) default Result> allOfInstitution(final Long institutionId, final Boolean active) { @@ -26,6 +26,4 @@ public interface LmsSetupDAO extends ActivatableEntityDAO, BulkActionS Result> allMatching(Long institutionId, String name, LmsType lmsType, Boolean active); - Result save(LmsSetup lmsSetup); - } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/UserActivityLogDAO.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/UserActivityLogDAO.java index 1deff9b3..ab1d0ab7 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/UserActivityLogDAO.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/UserActivityLogDAO.java @@ -18,7 +18,8 @@ import ch.ethz.seb.sebserver.gbl.util.Result; import ch.ethz.seb.sebserver.webservice.datalayer.batis.model.UserActivityLogRecord; import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.SEBServerUser; -public interface UserActivityLogDAO extends UserRelatedEntityDAO { +public interface UserActivityLogDAO + extends EntityDAO, UserRelatedEntityDAO { enum ActivityType { CREATE, diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/UserDAO.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/UserDAO.java index 8b31aa39..a2deff8b 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/UserDAO.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/UserDAO.java @@ -24,7 +24,7 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.BulkActionSuppor /** The Data Access Object for all User related data like get user data within UserInfo, * save and modify user related data within UserMod and get internal user principal data * within SEBServerUser. */ -public interface UserDAO extends ActivatableEntityDAO, BulkActionSupportDAO { +public interface UserDAO extends ActivatableEntityDAO, BulkActionSupportDAO { /** Use this to get the user id (PK) from a given UUID. * @@ -68,16 +68,6 @@ public interface UserDAO extends ActivatableEntityDAO, BulkActionSuppo * @return a Result of Collection of filtered UserInfo. Or an exception result on error case */ Result> all(UserFilter filter, Predicate predicate); - /** Use this to save/modify user data. - * If the UUID from given UserMod is null or not exists already, a new user is created. - * If the UUID is available and matches an existing user record, all user data that are - * not null on UserMod instance are updated within the existing user record. - * - * @param userMod UserMod instance containing new user record data - * @return A Result of UserInfo where the successfully saved/modified user data is available or a reported - * exception on error case */ - Result save(UserMod userMod); - /** Use this to get a Collection containing EntityKey's of all entities that belongs to a given User. * * @param uuid The UUID of the user diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/UserRelatedEntityDAO.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/UserRelatedEntityDAO.java index e97175bb..01c101cc 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/UserRelatedEntityDAO.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/UserRelatedEntityDAO.java @@ -17,7 +17,7 @@ import ch.ethz.seb.sebserver.gbl.util.Result; * * * @param the concrete type of the Entity */ -public interface UserRelatedEntityDAO extends EntityDAO { +public interface UserRelatedEntityDAO { /** Get all Entity instances that has a relation to the user-account * of a given user identity (UUID) diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ExamDAOImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ExamDAOImpl.java index df0ce7f4..f0d7c6d6 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ExamDAOImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ExamDAOImpl.java @@ -264,7 +264,7 @@ public class ExamDAOImpl implements ExamDAO { @Override @Transactional(readOnly = true) - public Result> bulkLoadEntities(final Collection keys) { + public Result> loadEntities(final Collection keys) { return Result.tryCatch(() -> { final List ids = extractPKsFromKeys(keys); return this.examRecordMapper.selectByExample() diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/InstitutionDAOImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/InstitutionDAOImpl.java index fc6e60ce..789345af 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/InstitutionDAOImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/InstitutionDAOImpl.java @@ -175,7 +175,7 @@ public class InstitutionDAOImpl implements InstitutionDAO { @Override @Transactional(readOnly = true) - public Result> bulkLoadEntities(final Collection keys) { + public Result> loadEntities(final Collection keys) { return Result.tryCatch(() -> { final List ids = extractPKsFromKeys(keys); diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/LmsSetupDAOImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/LmsSetupDAOImpl.java index 53ad58e4..314b4883 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/LmsSetupDAOImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/LmsSetupDAOImpl.java @@ -194,7 +194,7 @@ public class LmsSetupDAOImpl implements LmsSetupDAO { @Override @Transactional(readOnly = true) - public Result> bulkLoadEntities(final Collection keys) { + public Result> loadEntities(final Collection keys) { return Result.tryCatch(() -> { final List ids = extractPKsFromKeys(keys); 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 495980af..fe2eb704 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 @@ -277,6 +277,20 @@ public class UserActivityLogDAOImpl implements UserActivityLogDAO { @Override @Transactional(readOnly = true) + public Result> loadEntities(final Collection keys) { + // TODO Auto-generated method stub + return null; + } + + @Override + @Transactional + public Result save(final UserActivityLog modified) { + // TODO Auto-generated method stub + return null; + } + + @Override + @Transactional public Result overwriteUserReferences(final String userUuid, final boolean deactivate) { return Result.tryCatch(() -> { final List records = this.userLogRecordMapper.selectByExample() diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/UserDaoImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/UserDaoImpl.java index 4f837778..b682b924 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/UserDaoImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/UserDaoImpl.java @@ -257,7 +257,7 @@ public class UserDaoImpl implements UserDAO { @Override @Transactional(readOnly = true) - public Result> bulkLoadEntities(final Collection keys) { + public Result> loadEntities(final Collection keys) { return Result.tryCatch(() -> { final List ids = extractPKsFromKeys(keys); 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 b25a6f81..6aa0b676 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 @@ -16,6 +16,7 @@ import ch.ethz.seb.sebserver.gbl.model.EntityKey; import ch.ethz.seb.sebserver.gbl.model.EntityProcessingReport; import ch.ethz.seb.sebserver.gbl.model.EntityType; import ch.ethz.seb.sebserver.gbl.util.Result; +import ch.ethz.seb.sebserver.webservice.servicelayer.PaginationService; import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.AuthorizationGrantService; import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.GrantEntity; import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.PrivilegeType; @@ -23,15 +24,19 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.BulkAction; import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.BulkAction.Type; import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.BulkActionService; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.EntityDAO; +import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserActivityLogDAO; -public abstract class ActivatableEntityController extends EntityController { +public abstract class ActivatableEntityController + extends EntityController { public ActivatableEntityController( final AuthorizationGrantService authorizationGrantService, final BulkActionService bulkActionService, - final EntityDAO entityDAO) { + final EntityDAO entityDAO, + final UserActivityLogDAO userActivityLogDAO, + final PaginationService paginationService) { - super(authorizationGrantService, bulkActionService, entityDAO); + super(authorizationGrantService, bulkActionService, entityDAO, userActivityLogDAO, paginationService); } @RequestMapping(path = "/{id}/activate", method = RequestMethod.POST) diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/EntityController.java b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/EntityController.java index ad9f6644..649bb1ea 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/EntityController.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/EntityController.java @@ -8,39 +8,64 @@ package ch.ethz.seb.sebserver.webservice.weblayer.api; +import java.util.Arrays; +import java.util.Collection; +import java.util.stream.Collectors; + +import javax.validation.Valid; + +import org.apache.commons.lang3.StringUtils; import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import ch.ethz.seb.sebserver.gbl.Constants; +import ch.ethz.seb.sebserver.gbl.model.Entity; import ch.ethz.seb.sebserver.gbl.model.EntityKey; +import ch.ethz.seb.sebserver.gbl.model.EntityKeyAndName; import ch.ethz.seb.sebserver.gbl.model.EntityProcessingReport; import ch.ethz.seb.sebserver.gbl.model.EntityType; +import ch.ethz.seb.sebserver.gbl.model.Page; +import ch.ethz.seb.sebserver.gbl.util.Result; +import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.UserRecordDynamicSqlSupport; +import ch.ethz.seb.sebserver.webservice.servicelayer.PaginationService; import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.AuthorizationGrantService; import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.GrantEntity; import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.PrivilegeType; +import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.UserService; import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.BulkAction; import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.BulkAction.Type; import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.BulkActionService; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.EntityDAO; +import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserActivityLogDAO; +import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserActivityLogDAO.ActivityType; -public abstract class EntityController { +public abstract class EntityController { protected final AuthorizationGrantService authorizationGrantService; protected final BulkActionService bulkActionService; - protected final EntityDAO entityDAO; + protected final EntityDAO entityDAO; + protected final UserActivityLogDAO userActivityLogDAO; + protected final PaginationService paginationService; protected EntityController( final AuthorizationGrantService authorizationGrantService, final BulkActionService bulkActionService, - final EntityDAO entityDAO) { + final EntityDAO entityDAO, + final UserActivityLogDAO userActivityLogDAO, + final PaginationService paginationService) { this.authorizationGrantService = authorizationGrantService; this.bulkActionService = bulkActionService; this.entityDAO = entityDAO; + this.userActivityLogDAO = userActivityLogDAO; + this.paginationService = paginationService; } @RequestMapping(path = "/{id}", method = RequestMethod.GET) - public T accountInfo(@PathVariable final String id) { + public T byId(@PathVariable final String id) { return this.entityDAO .byModelId(id) .flatMap(entity -> this.authorizationGrantService.checkGrantOnEntity( @@ -49,6 +74,58 @@ public abstract class EntityController { .getOrThrow(); } + @RequestMapping(path = "/all", method = RequestMethod.GET) + public Page allActive( + @RequestParam( + name = Entity.ATTR_INSTITUTION, + required = true, + defaultValue = UserService.USERS_INSTITUTION_AS_DEFAULT) final Long institutionId, + @RequestParam(name = Page.ATTR_PAGE_NUMBER, required = false) final Integer pageNumber, + @RequestParam(name = Page.ATTR_PAGE_SIZE, required = false) final Integer pageSize, + @RequestParam(name = Page.ATTR_SORT_BY, required = false) final String sortBy, + @RequestParam(name = Page.ATTR_SORT_ORDER, required = false) final Page.SortOrder sortOrder) { + + checkReadPrivilege(institutionId); + return this.paginationService.getPage( + pageNumber, + pageSize, + sortBy, + sortOrder, + UserRecordDynamicSqlSupport.userRecord, + () -> this.entityDAO.all(entity -> true, true).getOrThrow()); + } + + @RequestMapping(path = "/all/in", method = RequestMethod.GET) + public Collection getForIds( + @RequestParam( + name = Entity.ATTR_INSTITUTION, + required = true, + defaultValue = UserService.USERS_INSTITUTION_AS_DEFAULT) final Long institutionId, + @RequestParam(name = "ids", required = true) final String ids) { + + checkReadPrivilege(institutionId); + + return Result.tryCatch(() -> { + return Arrays.asList(StringUtils.split(ids, Constants.LIST_SEPARATOR_CHAR)) + .stream() + .map(modelId -> new EntityKey(modelId, this.entityDAO.entityType())) + .collect(Collectors.toList()); + }) + .flatMap(this.entityDAO::loadEntities) + .getOrThrow(); + } + + @RequestMapping(path = "/names", method = RequestMethod.GET) + public Collection getNames( + @RequestParam(name = Entity.ATTR_ACTIVE, required = false) final Boolean active) { + + return this.entityDAO.all(entity -> true, true) + .getOrThrow() + .stream() + .map(Entity::toName) + .collect(Collectors.toList()); + } + @RequestMapping(path = "/{id}/hard-delete", method = RequestMethod.DELETE) public EntityProcessingReport hardDeleteUser(@PathVariable final String id) { final EntityType entityType = this.entityDAO.entityType(); @@ -65,4 +142,32 @@ public abstract class EntityController { .getOrThrow(); } + @RequestMapping(path = "/create", method = RequestMethod.PUT) + public T create(@Valid @RequestBody final M modifyData) { + return this.authorizationGrantService.checkGrantOnEntity(modifyData, PrivilegeType.WRITE) + .flatMap(entity -> this.entityDAO.save(modifyData)) + .flatMap(entity -> this.userActivityLogDAO.log(ActivityType.CREATE, entity)) + .flatMap(entity -> notifySave(modifyData, entity)) + .getOrThrow(); + } + + @RequestMapping(path = "/save", method = RequestMethod.POST) + public T save(@Valid @RequestBody final M modifyData) { + return this.authorizationGrantService.checkGrantOnEntity(modifyData, PrivilegeType.MODIFY) + .flatMap(entity -> this.entityDAO.save(modifyData)) + .flatMap(entity -> this.userActivityLogDAO.log(ActivityType.MODIFY, entity)) + .flatMap(entity -> notifySave(modifyData, entity)) + .getOrThrow(); + } + + protected Result notifySave(final M modifyData, final T entity) { + return Result.of(entity); + } + + protected void checkReadPrivilege(final Long institutionId) { + this.authorizationGrantService.checkPrivilege( + this.entityDAO.entityType(), + PrivilegeType.READ_ONLY, + institutionId); + } } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/InstitutionController.java b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/InstitutionController.java index e533cbbb..b79f6977 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/InstitutionController.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/InstitutionController.java @@ -10,54 +10,42 @@ package ch.ethz.seb.sebserver.webservice.weblayer.api; import java.util.Arrays; import java.util.Collection; -import java.util.stream.Collectors; -import javax.validation.Valid; - -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import ch.ethz.seb.sebserver.gbl.model.EntityKey; -import ch.ethz.seb.sebserver.gbl.model.EntityKeyAndName; -import ch.ethz.seb.sebserver.gbl.model.EntityProcessingReport; import ch.ethz.seb.sebserver.gbl.model.EntityType; import ch.ethz.seb.sebserver.gbl.model.institution.Institution; import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile; -import ch.ethz.seb.sebserver.gbl.util.Result; +import ch.ethz.seb.sebserver.webservice.servicelayer.PaginationService; import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.AuthorizationGrantService; import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.PrivilegeType; import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.SEBServerUser; -import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.BulkAction; -import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.BulkAction.Type; import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.BulkActionService; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.InstitutionDAO; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserActivityLogDAO; -import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserActivityLogDAO.ActivityType; @WebServiceProfile @RestController @RequestMapping("/${sebserver.webservice.api.admin.endpoint}" + RestAPI.ENDPOINT_INSTITUTION) -public class InstitutionController { +public class InstitutionController extends ActivatableEntityController { private final InstitutionDAO institutionDAO; private final AuthorizationGrantService authorizationGrantService; - private final UserActivityLogDAO userActivityLogDAO; - private final BulkActionService bulkActionService; public InstitutionController( final InstitutionDAO institutionDAO, final AuthorizationGrantService authorizationGrantService, final UserActivityLogDAO userActivityLogDAO, - final BulkActionService bulkActionService) { + final BulkActionService bulkActionService, + final PaginationService paginationService) { + + super(authorizationGrantService, bulkActionService, institutionDAO, userActivityLogDAO, paginationService); this.institutionDAO = institutionDAO; this.authorizationGrantService = authorizationGrantService; - this.userActivityLogDAO = userActivityLogDAO; - this.bulkActionService = bulkActionService; } @RequestMapping(path = "/self", method = RequestMethod.GET) @@ -70,16 +58,6 @@ public class InstitutionController { return this.institutionDAO.byPK(institutionId).getOrThrow(); } - @RequestMapping(path = "/{id}", method = RequestMethod.GET) - public Institution getById(@PathVariable final Long id) { - return this.institutionDAO - .byPK(id) - .flatMap(inst -> this.authorizationGrantService.checkGrantOnEntity( - inst, - PrivilegeType.READ_ONLY)) - .getOrThrow(); - } - @RequestMapping(method = RequestMethod.GET) public Collection getAll( @RequestParam(name = Institution.FILTER_ATTR_ACTIVE, required = false) final Boolean active) { @@ -95,94 +73,4 @@ public class InstitutionController { } } - @RequestMapping(path = "/names", method = RequestMethod.GET) - public Collection getNames( - @RequestParam(name = Institution.FILTER_ATTR_ACTIVE, required = false) final Boolean active) { - - return getAll(active) - .stream() - .map(Institution::toName) - .collect(Collectors.toList()); - } - - @RequestMapping(path = "/create", method = RequestMethod.PUT) - public Institution create(@Valid @RequestBody final Institution institution) { - return save(institution, PrivilegeType.WRITE) - .getOrThrow(); - } - - @RequestMapping(path = "/save", method = RequestMethod.POST) - public Institution save(@Valid @RequestBody final Institution institution) { - return save(institution, PrivilegeType.MODIFY) - .getOrThrow(); - } - - @RequestMapping(path = "/{id}/activate", method = RequestMethod.POST) - public EntityProcessingReport activate(@PathVariable final Long id) { - return setActive(id, true) - .getOrThrow(); - } - - @RequestMapping(value = "/{id}/deactivate", method = RequestMethod.POST) - public EntityProcessingReport deactivate(@PathVariable final Long id) { - return setActive(id, false) - .getOrThrow(); - } - - @RequestMapping(path = "/{id}/delete", method = RequestMethod.DELETE) - public EntityProcessingReport deleteUser(@PathVariable final Long id) { - checkPrivilegeForInstitution(id, PrivilegeType.WRITE); - - return this.bulkActionService.createReport(new BulkAction( - Type.DEACTIVATE, - EntityType.INSTITUTION, - new EntityKey(id, EntityType.INSTITUTION))) - .getOrThrow(); - } - - @RequestMapping(path = "/{id}/hard-delete", method = RequestMethod.DELETE) - public EntityProcessingReport hardDeleteUser(@PathVariable final Long id) { - checkPrivilegeForInstitution(id, PrivilegeType.WRITE); - - return this.bulkActionService.createReport(new BulkAction( - Type.HARD_DELETE, - EntityType.INSTITUTION, - new EntityKey(id, EntityType.INSTITUTION))) - .getOrThrow(); - } - - private void checkPrivilegeForInstitution(final Long id, final PrivilegeType type) { - this.authorizationGrantService.checkHasAnyPrivilege( - EntityType.INSTITUTION, - type); - - this.institutionDAO.byPK(id) - .flatMap(institution -> this.authorizationGrantService.checkGrantOnEntity( - institution, - type)) - .getOrThrow(); - } - - private Result setActive(final Long id, final boolean active) { - checkPrivilegeForInstitution(id, PrivilegeType.MODIFY); - - return this.bulkActionService.createReport(new BulkAction( - (active) ? Type.ACTIVATE : Type.DEACTIVATE, - EntityType.INSTITUTION, - new EntityKey(id, EntityType.INSTITUTION))); - - } - - private Result save(final Institution institution, final PrivilegeType privilegeType) { - - final ActivityType activityType = (institution.id == null) - ? ActivityType.CREATE - : ActivityType.MODIFY; - - return this.authorizationGrantService - .checkGrantOnEntity(institution, privilegeType) - .flatMap(this.institutionDAO::save) - .flatMap(inst -> this.userActivityLogDAO.log(activityType, inst)); - } - } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/UserAccountController.java b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/UserAccountController.java index 6c3d3236..3701d304 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/UserAccountController.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/UserAccountController.java @@ -10,12 +10,9 @@ package ch.ethz.seb.sebserver.webservice.weblayer.api; import java.util.Collection; -import javax.validation.Valid; - import org.springframework.context.ApplicationEventPublisher; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.annotation.InitBinder; -import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; @@ -35,20 +32,17 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.PrivilegeType import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.UserService; import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.BulkActionService; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserActivityLogDAO; -import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserActivityLogDAO.ActivityType; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserDAO; import ch.ethz.seb.sebserver.webservice.weblayer.oauth.RevokeTokenEndpoint; @WebServiceProfile @RestController @RequestMapping("/${sebserver.webservice.api.admin.endpoint}" + RestAPI.ENDPOINT_USER_ACCOUNT) -public class UserAccountController extends ActivatableEntityController { +public class UserAccountController extends ActivatableEntityController { private final UserDAO userDao; private final AuthorizationGrantService authorizationGrantService; - private final UserActivityLogDAO userActivityLogDAO; private final PaginationService paginationService; - private final BulkActionService bulkActionService; private final ApplicationEventPublisher applicationEventPublisher; public UserAccountController( @@ -59,12 +53,10 @@ public class UserAccountController extends ActivatableEntityController final BulkActionService bulkActionService, final ApplicationEventPublisher applicationEventPublisher) { - super(authorizationGrantService, bulkActionService, userDao); + super(authorizationGrantService, bulkActionService, userDao, userActivityLogDAO, paginationService); this.userDao = userDao; this.authorizationGrantService = authorizationGrantService; - this.userActivityLogDAO = userActivityLogDAO; this.paginationService = paginationService; - this.bulkActionService = bulkActionService; this.applicationEventPublisher = applicationEventPublisher; } @@ -129,91 +121,8 @@ public class UserAccountController extends ActivatableEntityController .getUserInfo(); } -// @Override -// @RequestMapping(path = "/{uuid}", method = RequestMethod.GET) -// public UserInfo accountInfo(@PathVariable final String uuid) { -// return this.userDao -// .byModelId(uuid) -// .flatMap(userInfo -> this.authorizationGrantService.checkGrantOnEntity( -// userInfo, -// PrivilegeType.READ_ONLY)) -// .getOrThrow(); -// } - - @RequestMapping(path = "/create", method = RequestMethod.PUT) - public UserInfo createUser(@Valid @RequestBody final UserMod userData) { - return _saveUser(userData, PrivilegeType.WRITE) - .getOrThrow(); - } - - @RequestMapping(path = "/save", method = RequestMethod.POST) - public UserInfo saveUser(@Valid @RequestBody final UserMod userData) { - return _saveUser(userData, PrivilegeType.MODIFY) - .getOrThrow(); - - } - -// @Override -// @RequestMapping(path = "/{uuid}/activate", method = RequestMethod.POST) -// public EntityProcessingReport activateUser(@PathVariable final String uuid) { -// return setActive(uuid, true) -// .getOrThrow(); -// } -// -// @Override -// @RequestMapping(value = "/{uuid}/deactivate", method = RequestMethod.POST) -// public EntityProcessingReport deactivateUser(@PathVariable final String uuid) { -// return setActive(uuid, false) -// .getOrThrow(); -// } -// -// @Override -// @RequestMapping(path = "/{uuid}/delete", method = RequestMethod.DELETE) -// public EntityProcessingReport deleteUser(@PathVariable final String uuid) { -// checkPrivilegeForUser(uuid, PrivilegeType.WRITE); -// -// return this.bulkActionService.createReport(new BulkAction( -// Type.DEACTIVATE, -// EntityType.USER, -// new EntityKey(uuid, EntityType.USER, false))) -// .getOrThrow(); -// } - -// private void checkPrivilegeForUser(final String uuid, final PrivilegeType type) { -// this.authorizationGrantService.checkHasAnyPrivilege( -// EntityType.USER, -// type); -// -// this.userDao.byModelId(uuid) -// .flatMap(userInfo -> this.authorizationGrantService.checkGrantOnEntity( -// userInfo, -// type)) -// .getOrThrow(); -// } - -// private Result setActive(final String uuid, final boolean active) { -// this.checkPrivilegeForUser(uuid, PrivilegeType.MODIFY); -// -// return this.bulkActionService.createReport(new BulkAction( -// (active) ? Type.ACTIVATE : Type.DEACTIVATE, -// EntityType.USER, -// new EntityKey(uuid, EntityType.USER, false))); -// } - - private Result _saveUser(final UserMod userData, final PrivilegeType privilegeType) { - - final ActivityType activityType = (userData.uuid == null) - ? ActivityType.CREATE - : ActivityType.MODIFY; - - return this.authorizationGrantService - .checkGrantOnEntity(userData, privilegeType) - .flatMap(this.userDao::save) - .flatMap(userInfo -> this.userActivityLogDAO.log(activityType, userInfo)) - .flatMap(userInfo -> revokePassword(userData, userInfo)); - } - - private Result revokePassword(final UserMod userData, final UserInfo userInfo) { + @Override + protected Result notifySave(final UserMod userData, final UserInfo userInfo) { // handle password change; revoke access tokens if password has changed if (userData.passwordChangeRequest() && userData.newPasswordMatch()) { this.applicationEventPublisher.publishEvent( @@ -256,11 +165,4 @@ public class UserAccountController extends ActivatableEntityController : null; } - private void checkReadPrivilege(final Long institutionId) { - this.authorizationGrantService.checkPrivilege( - EntityType.USER, - PrivilegeType.READ_ONLY, - institutionId); - } - }