created controller abstraction for Entity and ActivatableEntity
This commit is contained in:
parent
2f8b796b86
commit
ca20785400
39 changed files with 1376 additions and 572 deletions
|
@ -10,6 +10,9 @@ package ch.ethz.seb.sebserver.gbl.model;
|
|||
|
||||
public interface Entity extends ModelIdAware {
|
||||
|
||||
public static final String ATTR_ID = "id";
|
||||
public static final String ATTR_INSTITUTION = "institution";
|
||||
|
||||
EntityType entityType();
|
||||
|
||||
String getName();
|
||||
|
|
|
@ -8,35 +8,40 @@
|
|||
|
||||
package ch.ethz.seb.sebserver.gbl.model;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
public class EntityKey {
|
||||
|
||||
public final String entityId;
|
||||
@JsonProperty(value = "modelId", required = true)
|
||||
public final String modelId;
|
||||
@JsonProperty(value = "entityType", required = true)
|
||||
public final EntityType entityType;
|
||||
@JsonIgnore
|
||||
public final boolean isIdPK;
|
||||
|
||||
@JsonCreator
|
||||
public EntityKey(
|
||||
@NotNull final Long entityId,
|
||||
@NotNull final EntityType entityType) {
|
||||
@JsonProperty(value = "modelId", required = true) final String modelId,
|
||||
@JsonProperty(value = "entityType", required = true) final EntityType entityType) {
|
||||
|
||||
this.entityId = String.valueOf(entityId);
|
||||
this.modelId = modelId;
|
||||
this.entityType = entityType;
|
||||
this.isIdPK = entityType != EntityType.USER;
|
||||
}
|
||||
|
||||
public EntityKey(
|
||||
final Long pk,
|
||||
final EntityType entityType) {
|
||||
|
||||
this.modelId = String.valueOf(pk);
|
||||
this.entityType = entityType;
|
||||
this.isIdPK = true;
|
||||
}
|
||||
|
||||
public EntityKey(
|
||||
@NotNull final String entityId,
|
||||
@NotNull final EntityType entityType,
|
||||
final boolean isIdPK) {
|
||||
|
||||
this.entityId = entityId;
|
||||
this.entityType = entityType;
|
||||
this.isIdPK = isIdPK;
|
||||
}
|
||||
|
||||
public String getEntityId() {
|
||||
return this.entityId;
|
||||
public String getModelId() {
|
||||
return this.modelId;
|
||||
}
|
||||
|
||||
public EntityType getEntityType() {
|
||||
|
@ -47,8 +52,8 @@ public class EntityKey {
|
|||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((this.entityId == null) ? 0 : this.entityId.hashCode());
|
||||
result = prime * result + ((this.entityType == null) ? 0 : this.entityType.hashCode());
|
||||
result = prime * result + ((this.modelId == null) ? 0 : this.modelId.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -61,19 +66,19 @@ public class EntityKey {
|
|||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
final EntityKey other = (EntityKey) obj;
|
||||
if (this.entityId == null) {
|
||||
if (other.entityId != null)
|
||||
return false;
|
||||
} else if (!this.entityId.equals(other.entityId))
|
||||
return false;
|
||||
if (this.entityType != other.entityType)
|
||||
return false;
|
||||
if (this.modelId == null) {
|
||||
if (other.modelId != null)
|
||||
return false;
|
||||
} else if (!this.modelId.equals(other.modelId))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "EntityKey [entityId=" + this.entityId + ", entityType=" + this.entityType + "]";
|
||||
return "EntityKey [modelId=" + this.modelId + ", entityType=" + this.entityType + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ public class EntityKeyAndName implements ModelIdAware, ModelNameAware {
|
|||
@JsonProperty(value = "entityType", required = true)
|
||||
public final EntityType entityType;
|
||||
@JsonProperty(value = Domain.ATTR_ID, required = true)
|
||||
public final String id;
|
||||
public final String modelId;
|
||||
@JsonProperty(value = "name", required = true)
|
||||
public final String name;
|
||||
|
||||
|
@ -30,14 +30,14 @@ public class EntityKeyAndName implements ModelIdAware, ModelNameAware {
|
|||
@JsonProperty(value = "name", required = true) final String name) {
|
||||
|
||||
this.entityType = entityType;
|
||||
this.id = id;
|
||||
this.modelId = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public EntityKeyAndName(final EntityKey entityKey, final String name) {
|
||||
|
||||
this.entityType = entityKey.entityType;
|
||||
this.id = entityKey.entityId;
|
||||
this.modelId = entityKey.modelId;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
|
@ -45,10 +45,6 @@ public class EntityKeyAndName implements ModelIdAware, ModelNameAware {
|
|||
return this.entityType;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return this.name;
|
||||
|
@ -57,7 +53,7 @@ public class EntityKeyAndName implements ModelIdAware, ModelNameAware {
|
|||
@Override
|
||||
@JsonIgnore
|
||||
public String getModelId() {
|
||||
return this.id;
|
||||
return this.modelId;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -65,7 +61,7 @@ public class EntityKeyAndName implements ModelIdAware, ModelNameAware {
|
|||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((this.entityType == null) ? 0 : this.entityType.hashCode());
|
||||
result = prime * result + ((this.id == null) ? 0 : this.id.hashCode());
|
||||
result = prime * result + ((this.modelId == null) ? 0 : this.modelId.hashCode());
|
||||
result = prime * result + ((this.name == null) ? 0 : this.name.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
@ -81,10 +77,10 @@ public class EntityKeyAndName implements ModelIdAware, ModelNameAware {
|
|||
final EntityKeyAndName other = (EntityKeyAndName) obj;
|
||||
if (this.entityType != other.entityType)
|
||||
return false;
|
||||
if (this.id == null) {
|
||||
if (other.id != null)
|
||||
if (this.modelId == null) {
|
||||
if (other.modelId != null)
|
||||
return false;
|
||||
} else if (!this.id.equals(other.id))
|
||||
} else if (!this.modelId.equals(other.modelId))
|
||||
return false;
|
||||
if (this.name == null) {
|
||||
if (other.name != null)
|
||||
|
@ -96,7 +92,7 @@ public class EntityKeyAndName implements ModelIdAware, ModelNameAware {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "EntityIdAndName [entityType=" + this.entityType + ", id=" + this.id + ", name=" + this.name + "]";
|
||||
return "EntityIdAndName [entityType=" + this.entityType + ", id=" + this.modelId + ", name=" + this.name + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -9,30 +9,46 @@
|
|||
package ch.ethz.seb.sebserver.gbl.model;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||
|
||||
public class EntityProcessingReport {
|
||||
|
||||
@JsonProperty(value = "source", required = true)
|
||||
public final Collection<Entity> source;
|
||||
public final Collection<EntityKey> source;
|
||||
@JsonProperty(value = "dependencies", required = true)
|
||||
public final Collection<EntityKeyAndName> dependencies;
|
||||
public final Collection<EntityKey> dependencies;
|
||||
@JsonProperty(value = "errors", required = true)
|
||||
public final Map<EntityKeyAndName, String> errors;
|
||||
public final Collection<ErrorEntry> errors;
|
||||
|
||||
@JsonCreator
|
||||
public EntityProcessingReport(
|
||||
@JsonProperty(value = "source", required = true) final Collection<Entity> source,
|
||||
@JsonProperty(value = "dependencies", required = true) final Collection<EntityKeyAndName> dependencies,
|
||||
@JsonProperty(value = "errors", required = true) final Map<EntityKeyAndName, String> errors) {
|
||||
@JsonProperty(value = "source", required = true) final Collection<EntityKey> source,
|
||||
@JsonProperty(value = "dependencies", required = true) final Collection<EntityKey> dependencies,
|
||||
@JsonProperty(value = "errors", required = true) final Collection<ErrorEntry> errors) {
|
||||
|
||||
this.source = Utils.immutableCollectionOf(source);
|
||||
this.dependencies = Utils.immutableCollectionOf(dependencies);
|
||||
this.errors = Utils.immutableCollectionOf(errors);
|
||||
}
|
||||
|
||||
public static final class ErrorEntry {
|
||||
|
||||
public final EntityKey entityKey;
|
||||
public final APIMessage errorMessage;
|
||||
|
||||
@JsonCreator
|
||||
public ErrorEntry(
|
||||
@JsonProperty(value = "entity_key", required = true) final EntityKey entityKey,
|
||||
@JsonProperty(value = "error_message", required = true) final APIMessage errorMessage) {
|
||||
|
||||
this.entityKey = entityKey;
|
||||
this.errorMessage = errorMessage;
|
||||
}
|
||||
|
||||
this.source = Collections.unmodifiableCollection(source);
|
||||
this.dependencies = Collections.unmodifiableCollection(dependencies);
|
||||
this.errors = Collections.unmodifiableMap(errors);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,11 +22,11 @@ public final class Page<T> {
|
|||
DESCENDING
|
||||
}
|
||||
|
||||
public static final String ATTR_NUMBER_OF_PAGES = "numberOfPages";
|
||||
public static final String ATTR_PAGE_NUMBER = "pageNumber";
|
||||
public static final String ATTR_PAGE_SIZE = "pageSize";
|
||||
public static final String ATTR_SORT_BY = "sortBy";
|
||||
public static final String ATTR_SORT_ORDER = "sortOrder";
|
||||
public static final String ATTR_NUMBER_OF_PAGES = "number_of_pages";
|
||||
public static final String ATTR_PAGE_NUMBER = "page_number";
|
||||
public static final String ATTR_PAGE_SIZE = "page_size";
|
||||
public static final String ATTR_SORT_BY = "sort_by";
|
||||
public static final String ATTR_SORT_ORDER = "sort_order";
|
||||
public static final String ATTR_CONTENT = "content";
|
||||
|
||||
@JsonProperty(ATTR_NUMBER_OF_PAGES)
|
||||
|
|
|
@ -26,7 +26,7 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.GrantEntity;
|
|||
|
||||
public final class Exam implements GrantEntity, Activatable {
|
||||
|
||||
public static final String FILTER_ATTR_INSTITUTION = "institution";
|
||||
public static final String FILTER_ATTR_INSTITUTION = ATTR_INSTITUTION;
|
||||
public static final String FILTER_ATTR_LMS_SETUP = "lms_setup";
|
||||
public static final String FILTER_ATTR_NAME = "name_like";
|
||||
public static final String FILTER_ATTR_STATUS = "status";
|
||||
|
|
|
@ -22,11 +22,6 @@ public final class QuizData {
|
|||
public static final String FILTER_ATTR_NAME = "name_like";
|
||||
public static final String FILTER_ATTR_START_TIME = "start_timestamp";
|
||||
|
||||
public static final String PAGE_ATTR_NUMBER = "page_number";
|
||||
public static final String PAGE_ATTR_SIZE = "page_size";
|
||||
public static final String PAGE_ATTR_SORT_BY = "sort_by";
|
||||
public static final String PAGE_ATTR_SORT_ORDER = "sort_order";
|
||||
|
||||
public static final String QUIZ_ATTR_ID = "quiz_id";
|
||||
public static final String QUIZ_ATTR_NAME = "quiz_name";
|
||||
public static final String QUIZ_ATTR_DESCRIPTION = "quiz_description";
|
||||
|
|
|
@ -19,6 +19,12 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserActivityLogDAO.Acti
|
|||
|
||||
public class UserActivityLog implements Entity {
|
||||
|
||||
public static final String FILTER_ATTR_INSTITUTION = ATTR_INSTITUTION;
|
||||
public static final String FILTER_ATTR_FROM = "from";
|
||||
public static final String FILTER_ATTR_TO = "to";
|
||||
public static final String FILTER_ATTR_ACTIVITY_TYPES = "activity_types";
|
||||
public static final String FILTER_ATTR_ENTITY_TYPES = "entity_types";
|
||||
|
||||
@JsonIgnore
|
||||
public final Long id;
|
||||
@JsonProperty(USER_ACTIVITY_LOG.ATTR_USER_UUID)
|
||||
|
|
|
@ -18,6 +18,7 @@ import java.util.Map;
|
|||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||
|
@ -105,4 +106,24 @@ public final class Utils {
|
|||
return map;
|
||||
}
|
||||
|
||||
public static DateTime toDateTime(final String dateString) {
|
||||
if (StringUtils.isBlank(dateString)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (dateString.contains(".")) {
|
||||
return DateTime.parse(dateString, Constants.DATE_TIME_PATTERN_UTC_MILLIS);
|
||||
} else {
|
||||
return DateTime.parse(dateString, Constants.DATE_TIME_PATTERN_UTC_NO_MILLIS);
|
||||
}
|
||||
}
|
||||
|
||||
public static Long toMilliSeconds(final String dateString) {
|
||||
if (StringUtils.isBlank(dateString)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return toDateTime(dateString).getMillis();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import ch.ethz.seb.sebserver.gbl.model.Domain;
|
|||
import ch.ethz.seb.sebserver.gbl.model.Entity;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Page;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
||||
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ExamRecordDynamicSqlSupport;
|
||||
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.UserActivityLogRecordDynamicSqlSupport;
|
||||
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.UserRecordDynamicSqlSupport;
|
||||
|
||||
|
@ -50,6 +51,25 @@ public class PaginationService {
|
|||
initSortColumnMapping();
|
||||
}
|
||||
|
||||
/** Use this to verify whether native sorting (on SQL level) is supported for a given orderBy column
|
||||
* and a given SqlTable or not.
|
||||
*
|
||||
* @param table SqlTable the SQL table (MyBatis)
|
||||
* @param orderBy the orderBy columnName
|
||||
* @return true if there is native sorting support for the given attributes */
|
||||
public boolean isNativeSortingSupported(final SqlTable table, final String orderBy) {
|
||||
if (StringUtils.isBlank(orderBy)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final Map<String, String> tableMap = this.sortColumnMapping.get(table.name());
|
||||
if (tableMap == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return tableMap.containsKey(orderBy);
|
||||
}
|
||||
|
||||
public void setDefaultLimitOfNotSet(final SqlTable table) {
|
||||
if (PageHelper.getLocalPage() != null) {
|
||||
return;
|
||||
|
@ -69,6 +89,20 @@ public class PaginationService {
|
|||
setPagination(1, this.maxPageSize, sortBy, sortOrder, table);
|
||||
}
|
||||
|
||||
public int getPageNumber(final Integer pageNumber) {
|
||||
return (pageNumber == null)
|
||||
? 1
|
||||
: pageNumber;
|
||||
}
|
||||
|
||||
public int getPageSize(final Integer pageSize) {
|
||||
return (pageSize == null || pageSize < 0)
|
||||
? this.defaultPageSize
|
||||
: (pageSize > this.maxPageSize)
|
||||
? this.maxPageSize
|
||||
: pageSize;
|
||||
}
|
||||
|
||||
public com.github.pagehelper.Page<Object> setPagination(
|
||||
final Integer pageNumber,
|
||||
final Integer pageSize,
|
||||
|
@ -76,18 +110,8 @@ public class PaginationService {
|
|||
final Page.SortOrder sortOrder,
|
||||
final SqlTable table) {
|
||||
|
||||
final int _pageNumber = (pageNumber == null)
|
||||
? 1
|
||||
: pageNumber;
|
||||
|
||||
final int _pageSize = (pageSize == null || pageSize < 0)
|
||||
? this.defaultPageSize
|
||||
: (pageSize > this.maxPageSize)
|
||||
? this.maxPageSize
|
||||
: pageSize;
|
||||
|
||||
final com.github.pagehelper.Page<Object> startPage =
|
||||
PageHelper.startPage(_pageNumber, _pageSize, true, true, false);
|
||||
PageHelper.startPage(getPageNumber(pageNumber), getPageSize(pageSize), true, true, false);
|
||||
|
||||
final String sortColumnName = verifySortColumnName(sortBy, table);
|
||||
if (StringUtils.isNoneBlank(sortColumnName)) {
|
||||
|
@ -111,7 +135,7 @@ public class PaginationService {
|
|||
|
||||
final com.github.pagehelper.Page<Object> page = setPagination(pageNumber, pageSize, sortBy, sortOrder, table);
|
||||
final Collection<T> pageList = delegate.get();
|
||||
return new Page<>(page.getPages(), pageNumber, sortBy, sortOrder, pageList);
|
||||
return new Page<>(page.getPages(), page.getPageNum(), sortBy, sortOrder, pageList);
|
||||
}
|
||||
|
||||
private String verifySortColumnName(final String sortBy, final SqlTable table) {
|
||||
|
@ -130,6 +154,7 @@ public class PaginationService {
|
|||
|
||||
// TODO is it possible to generate this within MyBatis generator?
|
||||
private void initSortColumnMapping() {
|
||||
|
||||
// User Table
|
||||
final Map<String, String> userTableMap = new HashMap<>();
|
||||
userTableMap.put(Domain.USER.ATTR_NAME, UserRecordDynamicSqlSupport.name.name());
|
||||
|
@ -163,6 +188,21 @@ public class PaginationService {
|
|||
UserActivityLogRecordDynamicSqlSupport.userActivityLogRecord.name(),
|
||||
Domain.USER_ACTIVITY_LOG.ATTR_ID);
|
||||
|
||||
// Exam Table
|
||||
final Map<String, String> examTableMap = new HashMap<>();
|
||||
examTableMap.put(
|
||||
Domain.EXAM.ATTR_INSTITUTION_ID,
|
||||
ExamRecordDynamicSqlSupport.institutionId.name());
|
||||
examTableMap.put(
|
||||
Domain.EXAM.ATTR_LMS_SETUP_ID,
|
||||
ExamRecordDynamicSqlSupport.lmsSetupId.name());
|
||||
examTableMap.put(
|
||||
Domain.EXAM.ATTR_TYPE,
|
||||
ExamRecordDynamicSqlSupport.type.name());
|
||||
examTableMap.put(
|
||||
Domain.EXAM.ATTR_STATUS,
|
||||
ExamRecordDynamicSqlSupport.status.name());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ import ch.ethz.seb.sebserver.gbl.util.Result;
|
|||
public interface AuthorizationGrantService {
|
||||
|
||||
/** Gets the UserService that is bundled within the AuthorizationGrantService
|
||||
*
|
||||
*
|
||||
* @return the UserService that is bundled within the AuthorizationGrantService */
|
||||
UserService getUserService();
|
||||
|
||||
|
@ -33,6 +33,10 @@ public interface AuthorizationGrantService {
|
|||
* @param privilegeType the PrivilegeType to check on EntityType */
|
||||
void checkHasAnyPrivilege(EntityType entityType, PrivilegeType privilegeType);
|
||||
|
||||
void checkPrivilege(EntityType entityType, PrivilegeType privilegeType, Long institutionId);
|
||||
|
||||
void checkPrivilege(EntityType entityType, PrivilegeType privilegeType, Long institutionId, Long ownerId);
|
||||
|
||||
/** Check if current user has grant on a given GrantEntity instance for specified PrivilegeType
|
||||
*
|
||||
* @param entity The GrantEntity to check specified PrivilegeType for
|
||||
|
|
|
@ -120,49 +120,86 @@ public class AuthorizationGrantServiceImpl implements AuthorizationGrantService
|
|||
}
|
||||
|
||||
@Override
|
||||
public void checkHasAnyPrivilege(final EntityType entityType, final PrivilegeType grantType) {
|
||||
public void checkHasAnyPrivilege(final EntityType entityType, final PrivilegeType privilegeType) {
|
||||
final SEBServerUser currentUser = this.userService.getCurrentUser();
|
||||
if (hasBasePrivilege(entityType, grantType, currentUser) ||
|
||||
hasInstitutionalPrivilege(entityType, grantType, currentUser)) {
|
||||
if (hasBasePrivilege(entityType, privilegeType, currentUser) ||
|
||||
hasInstitutionalPrivilege(entityType, privilegeType, currentUser)) {
|
||||
return;
|
||||
}
|
||||
|
||||
throw new PermissionDeniedException(entityType, grantType, currentUser.getUserInfo().uuid);
|
||||
throw new PermissionDeniedException(entityType, privilegeType, currentUser.getUserInfo().uuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <E extends GrantEntity> Result<E> checkGrantOnEntity(final E entity, final PrivilegeType grantType) {
|
||||
public void checkPrivilege(
|
||||
final EntityType entityType,
|
||||
final PrivilegeType privilegeType,
|
||||
final Long institutionId) {
|
||||
|
||||
final SEBServerUser currentUser = this.userService.getCurrentUser();
|
||||
if (hasGrant(entity, grantType, currentUser)) {
|
||||
if (hasBasePrivilege(entityType, privilegeType, currentUser)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (institutionId == null) {
|
||||
throw new PermissionDeniedException(entityType, privilegeType, currentUser.getUserInfo().uuid);
|
||||
}
|
||||
|
||||
if (hasInstitutionalPrivilege(entityType, privilegeType, currentUser) &&
|
||||
currentUser.institutionId().longValue() == institutionId.longValue()) {
|
||||
return;
|
||||
}
|
||||
|
||||
throw new PermissionDeniedException(entityType, privilegeType, currentUser.getUserInfo().uuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkPrivilege(
|
||||
final EntityType entityType,
|
||||
final PrivilegeType privilegeType,
|
||||
final Long institutionId,
|
||||
final Long ownerId) {
|
||||
|
||||
final SEBServerUser currentUser = this.userService.getCurrentUser();
|
||||
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
throw new PermissionDeniedException(entityType, privilegeType, currentUser.getUserInfo().uuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <E extends GrantEntity> Result<E> checkGrantOnEntity(final E entity, final PrivilegeType privilegeType) {
|
||||
|
||||
final SEBServerUser currentUser = this.userService.getCurrentUser();
|
||||
if (hasGrant(entity, privilegeType, currentUser)) {
|
||||
return Result.of(entity);
|
||||
} else {
|
||||
return Result.ofError(new PermissionDeniedException(entity, grantType, currentUser.getUserInfo().uuid));
|
||||
return Result.ofError(new PermissionDeniedException(entity, privilegeType, currentUser.getUserInfo().uuid));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasBasePrivilege(final EntityType entityType, final PrivilegeType grantType) {
|
||||
return hasBasePrivilege(entityType, grantType, this.userService.getCurrentUser());
|
||||
public boolean hasBasePrivilege(final EntityType entityType, final PrivilegeType privilegeType) {
|
||||
return hasBasePrivilege(entityType, privilegeType, this.userService.getCurrentUser());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasBasePrivilege(
|
||||
final EntityType entityType,
|
||||
final PrivilegeType grantType,
|
||||
final PrivilegeType privilegeType,
|
||||
final Principal principal) {
|
||||
|
||||
return hasBasePrivilege(entityType, grantType, this.userService.extractFromPrincipal(principal));
|
||||
return hasBasePrivilege(entityType, privilegeType, this.userService.extractFromPrincipal(principal));
|
||||
}
|
||||
|
||||
private boolean hasBasePrivilege(
|
||||
final EntityType entityType,
|
||||
final PrivilegeType grantType,
|
||||
final PrivilegeType privilegeType,
|
||||
final SEBServerUser user) {
|
||||
|
||||
for (final UserRole role : user.getUserRoles()) {
|
||||
final Privilege roleTypeGrant = this.grants.get(new RoleTypeKey(entityType, role));
|
||||
if (roleTypeGrant != null && roleTypeGrant.hasBasePrivilege(grantType)) {
|
||||
if (roleTypeGrant != null && roleTypeGrant.hasBasePrivilege(privilegeType)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -171,27 +208,36 @@ public class AuthorizationGrantServiceImpl implements AuthorizationGrantService
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean hasInstitutionalPrivilege(final EntityType entityType, final PrivilegeType grantType) {
|
||||
return hasInstitutionalPrivilege(entityType, grantType, this.userService.getCurrentUser());
|
||||
public boolean hasInstitutionalPrivilege(
|
||||
final EntityType entityType,
|
||||
final PrivilegeType privilegeType) {
|
||||
|
||||
return hasInstitutionalPrivilege(
|
||||
entityType,
|
||||
privilegeType,
|
||||
this.userService.getCurrentUser());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasInstitutionalPrivilege(
|
||||
final EntityType entityType,
|
||||
final PrivilegeType grantType,
|
||||
final PrivilegeType privilegeType,
|
||||
final Principal principal) {
|
||||
|
||||
return hasInstitutionalPrivilege(entityType, grantType, this.userService.extractFromPrincipal(principal));
|
||||
return hasInstitutionalPrivilege(
|
||||
entityType,
|
||||
privilegeType,
|
||||
this.userService.extractFromPrincipal(principal));
|
||||
}
|
||||
|
||||
private boolean hasInstitutionalPrivilege(
|
||||
final EntityType entityType,
|
||||
final PrivilegeType grantType,
|
||||
final PrivilegeType privilegeType,
|
||||
final SEBServerUser user) {
|
||||
|
||||
for (final UserRole role : user.getUserRoles()) {
|
||||
final Privilege roleTypeGrant = this.grants.get(new RoleTypeKey(entityType, role));
|
||||
if (roleTypeGrant != null && roleTypeGrant.hasInstitutionalPrivilege(grantType)) {
|
||||
if (roleTypeGrant != null && roleTypeGrant.hasInstitutionalPrivilege(privilegeType)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,9 +10,13 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.authorization;
|
|||
|
||||
import java.security.Principal;
|
||||
|
||||
import org.springframework.web.bind.WebDataBinder;
|
||||
|
||||
/** A service to get the authenticated user from current request */
|
||||
public interface UserService {
|
||||
|
||||
String USERS_INSTITUTION_AS_DEFAULT = "USERS_INSTITUTION_AS_DEFAULT";
|
||||
|
||||
/** Use this to get the current User within a request-response thread cycle.
|
||||
*
|
||||
* @return the SEBServerUser instance of the current request
|
||||
|
@ -46,4 +50,6 @@ public interface UserService {
|
|||
* @return an overall super user with all rights */
|
||||
SEBServerUser getSuperUser();
|
||||
|
||||
void addUsersInstitutionDefaultPropertySupport(final WebDataBinder binder);
|
||||
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
package ch.ethz.seb.sebserver.webservice.servicelayer.authorization;
|
||||
|
||||
import java.beans.PropertyEditorSupport;
|
||||
import java.security.Principal;
|
||||
import java.util.Collection;
|
||||
|
||||
|
@ -20,6 +21,7 @@ import org.springframework.security.core.context.SecurityContextHolder;
|
|||
import org.springframework.security.oauth2.provider.OAuth2Authentication;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.bind.WebDataBinder;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
||||
|
@ -78,6 +80,22 @@ public class UserServiceImpl implements UserService {
|
|||
return SUPER_USER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addUsersInstitutionDefaultPropertySupport(final WebDataBinder binder) {
|
||||
final PropertyEditorSupport usersInstitutionDefaultEditor = new PropertyEditorSupport() {
|
||||
@Override
|
||||
public void setAsText(final String text) throws IllegalArgumentException {
|
||||
if (UserService.USERS_INSTITUTION_AS_DEFAULT.equals(text)) {
|
||||
setValue(getCurrentUser().institutionId());
|
||||
} else {
|
||||
setValue((text == null) ? null : Long.decode(text));
|
||||
}
|
||||
}
|
||||
};
|
||||
binder.registerCustomEditor(Long.class, usersInstitutionDefaultEditor);
|
||||
|
||||
}
|
||||
|
||||
// 1. OAuth2Authentication strategy
|
||||
@Lazy
|
||||
@Component
|
||||
|
|
|
@ -21,6 +21,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.profile.WebServiceProfile;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserActivityLogDAO;
|
||||
|
||||
@Service
|
||||
|
@ -49,44 +50,56 @@ public class BulkActionService {
|
|||
action.alreadyProcessed = true;
|
||||
}
|
||||
|
||||
public void doBulkAction(final BulkAction action) {
|
||||
checkProcessing(action);
|
||||
public Result<BulkAction> doBulkAction(final BulkAction action) {
|
||||
return Result.tryCatch(() -> {
|
||||
|
||||
final BulkActionSupportDAO<?> supportForSource = this.supporter.get(action.sourceType);
|
||||
if (supportForSource == null) {
|
||||
action.alreadyProcessed = true;
|
||||
return;
|
||||
}
|
||||
checkProcessing(action);
|
||||
|
||||
collectDependencies(action);
|
||||
|
||||
if (!action.dependencies.isEmpty()) {
|
||||
// process dependencies first...
|
||||
final List<BulkActionSupportDAO<?>> dependancySupporter =
|
||||
getDependancySupporter(action);
|
||||
|
||||
for (final BulkActionSupportDAO<?> support : dependancySupporter) {
|
||||
action.result.addAll(support.processBulkAction(action));
|
||||
final BulkActionSupportDAO<?> supportForSource = this.supporter
|
||||
.get(action.sourceType);
|
||||
if (supportForSource == null) {
|
||||
action.alreadyProcessed = true;
|
||||
throw new IllegalArgumentException("No bulk action support for: " + action);
|
||||
}
|
||||
}
|
||||
|
||||
action.result.addAll(supportForSource.processBulkAction(action));
|
||||
collectDependencies(action);
|
||||
|
||||
processUserActivityLog(action);
|
||||
action.alreadyProcessed = true;
|
||||
if (!action.dependencies.isEmpty()) {
|
||||
// process dependencies first...
|
||||
final List<BulkActionSupportDAO<?>> dependancySupporter =
|
||||
getDependancySupporter(action);
|
||||
|
||||
for (final BulkActionSupportDAO<?> support : dependancySupporter) {
|
||||
action.result.addAll(support.processBulkAction(action));
|
||||
}
|
||||
}
|
||||
|
||||
action.result.addAll(supportForSource.processBulkAction(action));
|
||||
|
||||
processUserActivityLog(action);
|
||||
action.alreadyProcessed = true;
|
||||
return action;
|
||||
});
|
||||
}
|
||||
|
||||
public EntityProcessingReport createReport(final BulkAction action) {
|
||||
public Result<EntityProcessingReport> createReport(final BulkAction action) {
|
||||
if (!action.alreadyProcessed) {
|
||||
doBulkAction(action);
|
||||
return doBulkAction(action)
|
||||
.flatMap(this::createFullReport);
|
||||
} else {
|
||||
return createFullReport(action);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO
|
||||
private Result<EntityProcessingReport> createFullReport(final BulkAction action) {
|
||||
return Result.tryCatch(() -> {
|
||||
|
||||
return new EntityProcessingReport(
|
||||
Collections.emptyList(),
|
||||
Collections.emptyList(),
|
||||
Collections.emptyMap());
|
||||
// TODO
|
||||
return new EntityProcessingReport(
|
||||
action.sources,
|
||||
Collections.emptyList(),
|
||||
Collections.emptyList());
|
||||
});
|
||||
}
|
||||
|
||||
private void processUserActivityLog(final BulkAction action) {
|
||||
|
@ -98,7 +111,7 @@ public class BulkActionService {
|
|||
this.userActivityLogDAO.log(
|
||||
action.type.activityType,
|
||||
key.entityType,
|
||||
key.entityId,
|
||||
key.modelId,
|
||||
"bulk action dependency");
|
||||
}
|
||||
|
||||
|
@ -106,7 +119,7 @@ public class BulkActionService {
|
|||
this.userActivityLogDAO.log(
|
||||
action.type.activityType,
|
||||
key.entityType,
|
||||
key.entityId,
|
||||
key.modelId,
|
||||
"bulk action source");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,21 @@ public interface EntityDAO<T extends Entity> {
|
|||
* @param id the data base identifier of the entity
|
||||
* @return Result refer the Entity instance with the specified database identifier or refer to an error if
|
||||
* happened */
|
||||
Result<T> byId(Long id);
|
||||
Result<T> byPK(Long id);
|
||||
|
||||
/** Use this to get an Entity instance of concrete type by model identifier
|
||||
*
|
||||
* NOTE: A model identifier may differ from the string representation of the database identifier
|
||||
* but usually they are the same.
|
||||
*
|
||||
* @param id the model identifier
|
||||
* @return Result refer the Entity instance with the specified model identifier or refer to an error if
|
||||
* happened */
|
||||
default Result<T> byModelId(final String id) {
|
||||
return Result.tryCatch(() -> {
|
||||
return Long.parseLong(id);
|
||||
}).flatMap(this::byPK);
|
||||
}
|
||||
|
||||
/** Use this to get a Collection of all entities of concrete type that matches a given predicate.
|
||||
*
|
||||
|
@ -104,7 +118,7 @@ public interface EntityDAO<T extends Entity> {
|
|||
*
|
||||
* @param keys Collection of EntityKey of various types
|
||||
* @return List of id's (PK's) from the given key collection that match the concrete EntityType */
|
||||
default List<Long> extractIdsFromKeys(final Collection<EntityKey> keys) {
|
||||
default List<Long> extractPKsFromKeys(final Collection<EntityKey> keys) {
|
||||
|
||||
if (keys == null) {
|
||||
return Collections.emptyList();
|
||||
|
@ -114,7 +128,7 @@ public interface EntityDAO<T extends Entity> {
|
|||
return keys
|
||||
.stream()
|
||||
.filter(key -> key.entityType == entityType)
|
||||
.map(key -> Long.valueOf(key.entityId))
|
||||
.map(key -> Long.valueOf(key.modelId))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,8 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.dao;
|
|||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.Exam;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.QuizData;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||
|
@ -27,8 +29,10 @@ public interface ExamDAO extends ActivatableEntityDAO<Exam>, BulkActionSupportDA
|
|||
String name,
|
||||
Exam.ExamStatus status,
|
||||
Exam.ExamType type,
|
||||
Long startTime,
|
||||
DateTime from,
|
||||
String owner,
|
||||
Boolean active);
|
||||
|
||||
Result<Exam> save(Exam exam);
|
||||
|
||||
}
|
||||
|
|
|
@ -84,6 +84,7 @@ public interface UserActivityLogDAO extends UserRelatedEntityDAO<UserActivityLog
|
|||
}
|
||||
|
||||
Result<Collection<UserActivityLog>> all(
|
||||
Long InstitutionId,
|
||||
String userId,
|
||||
Long from,
|
||||
Long to,
|
||||
|
|
|
@ -26,17 +26,11 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.BulkActionSuppor
|
|||
* within SEBServerUser. */
|
||||
public interface UserDAO extends ActivatableEntityDAO<UserInfo>, BulkActionSupportDAO<UserInfo> {
|
||||
|
||||
/** Use this to get UserInfo by users UUID
|
||||
*
|
||||
* @param uuid The UUID of the user to get UserInfo from
|
||||
* @return a Result of UserInfo data from user with the specified UUID. Or an exception result on error case */
|
||||
Result<UserInfo> byUuid(String uuid);
|
||||
|
||||
/** Use this to get the user id (PK) from a given UUID.
|
||||
*
|
||||
* @param uuid The UUID of the user
|
||||
* @return the user id (PK) from a given UUID. */
|
||||
Result<Long> pkForUUID(String uuid);
|
||||
Result<Long> pkForModelId(String uuid);
|
||||
|
||||
/** Use this to get UserInfo by users username
|
||||
*
|
||||
|
|
|
@ -22,6 +22,7 @@ import java.util.stream.Collectors;
|
|||
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.joda.time.DateTime;
|
||||
import org.mybatis.dynamic.sql.select.MyBatis3SelectModelAdapter;
|
||||
import org.mybatis.dynamic.sql.select.QueryExpressionDSL;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
|
@ -67,7 +68,7 @@ public class ExamDAOImpl implements ExamDAO {
|
|||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public Result<Exam> byId(final Long id) {
|
||||
public Result<Exam> byPK(final Long id) {
|
||||
return recordById(id)
|
||||
.flatMap(this::toDomainModel);
|
||||
}
|
||||
|
@ -108,7 +109,7 @@ public class ExamDAOImpl implements ExamDAO {
|
|||
final String name,
|
||||
final ExamStatus status,
|
||||
final ExamType type,
|
||||
final Long startTime,
|
||||
final DateTime from,
|
||||
final String owner,
|
||||
final Boolean active) {
|
||||
|
||||
|
@ -121,8 +122,8 @@ public class ExamDAOImpl implements ExamDAO {
|
|||
}
|
||||
}
|
||||
|
||||
if (startTime != null) {
|
||||
if (exam.startTime.getMillis() < startTime.longValue()) {
|
||||
if (from != null) {
|
||||
if (exam.startTime.isAfter(from)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -167,10 +168,40 @@ public class ExamDAOImpl implements ExamDAO {
|
|||
return Result.ofTODO();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<Exam> save(final Exam exam) {
|
||||
if (exam == null) {
|
||||
return Result.ofError(new NullPointerException("exam has null-reference"));
|
||||
}
|
||||
if (exam.id == null) {
|
||||
return Result.ofError(new IllegalArgumentException("exam.id has null-reference"));
|
||||
}
|
||||
|
||||
return update(exam)
|
||||
.flatMap(this::toDomainModel);
|
||||
}
|
||||
|
||||
private Result<ExamRecord> update(final Exam exam) {
|
||||
return Result.tryCatch(() -> {
|
||||
final ExamRecord examRecord = new ExamRecord(
|
||||
exam.id,
|
||||
null, null, null, null,
|
||||
(exam.supporter != null)
|
||||
? StringUtils.join(exam.supporter, Constants.LIST_SEPARATOR_CHAR)
|
||||
: null,
|
||||
(exam.type != null) ? exam.type.name() : null,
|
||||
(exam.status != null) ? exam.status.name() : null,
|
||||
BooleanUtils.toIntegerObject(exam.active));
|
||||
|
||||
this.examRecordMapper.updateByPrimaryKeySelective(examRecord);
|
||||
return this.examRecordMapper.selectByPrimaryKey(exam.id);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Collection<Result<EntityKey>> setActive(final Set<EntityKey> all, final boolean active) {
|
||||
final List<Long> ids = extractIdsFromKeys(all);
|
||||
final List<Long> ids = extractPKsFromKeys(all);
|
||||
final ExamRecord examRecord = new ExamRecord(null, null, null, null, null,
|
||||
null, null, null, BooleanUtils.toInteger(active));
|
||||
|
||||
|
@ -196,7 +227,7 @@ public class ExamDAOImpl implements ExamDAO {
|
|||
@Override
|
||||
@Transactional
|
||||
public Collection<Result<EntityKey>> delete(final Set<EntityKey> all) {
|
||||
final List<Long> ids = extractIdsFromKeys(all);
|
||||
final List<Long> ids = extractPKsFromKeys(all);
|
||||
|
||||
try {
|
||||
|
||||
|
@ -235,7 +266,7 @@ public class ExamDAOImpl implements ExamDAO {
|
|||
@Transactional(readOnly = true)
|
||||
public Result<Collection<Exam>> bulkLoadEntities(final Collection<EntityKey> keys) {
|
||||
return Result.tryCatch(() -> {
|
||||
final List<Long> ids = extractIdsFromKeys(keys);
|
||||
final List<Long> ids = extractPKsFromKeys(keys);
|
||||
return this.examRecordMapper.selectByExample()
|
||||
.where(ExamRecordDynamicSqlSupport.id, isIn(ids))
|
||||
.build()
|
||||
|
@ -247,7 +278,7 @@ public class ExamDAOImpl implements ExamDAO {
|
|||
return Result.tryCatch(() -> {
|
||||
return this.examRecordMapper.selectIdsByExample()
|
||||
.where(ExamRecordDynamicSqlSupport.institutionId,
|
||||
isEqualTo(Long.valueOf(institutionKey.entityId)))
|
||||
isEqualTo(Long.valueOf(institutionKey.modelId)))
|
||||
.build()
|
||||
.execute()
|
||||
.stream()
|
||||
|
@ -260,7 +291,7 @@ public class ExamDAOImpl implements ExamDAO {
|
|||
return Result.tryCatch(() -> {
|
||||
return this.examRecordMapper.selectIdsByExample()
|
||||
.where(ExamRecordDynamicSqlSupport.lmsSetupId,
|
||||
isEqualTo(Long.valueOf(lmsSetupKey.entityId)))
|
||||
isEqualTo(Long.valueOf(lmsSetupKey.modelId)))
|
||||
.build()
|
||||
.execute()
|
||||
.stream()
|
||||
|
|
|
@ -56,7 +56,7 @@ public class InstitutionDAOImpl implements InstitutionDAO {
|
|||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public Result<Institution> byId(final Long id) {
|
||||
public Result<Institution> byPK(final Long id) {
|
||||
return recordById(id)
|
||||
.flatMap(InstitutionDAOImpl::toDomainModel);
|
||||
}
|
||||
|
@ -123,7 +123,7 @@ public class InstitutionDAOImpl implements InstitutionDAO {
|
|||
@Override
|
||||
@Transactional
|
||||
public Collection<Result<EntityKey>> setActive(final Set<EntityKey> all, final boolean active) {
|
||||
final List<Long> ids = extractIdsFromKeys(all);
|
||||
final List<Long> ids = extractPKsFromKeys(all);
|
||||
final InstitutionRecord institutionRecord = new InstitutionRecord(
|
||||
null, null, null, BooleanUtils.toInteger(active), null);
|
||||
|
||||
|
@ -147,7 +147,7 @@ public class InstitutionDAOImpl implements InstitutionDAO {
|
|||
@Override
|
||||
@Transactional
|
||||
public Collection<Result<EntityKey>> delete(final Set<EntityKey> all) {
|
||||
final List<Long> ids = extractIdsFromKeys(all);
|
||||
final List<Long> ids = extractPKsFromKeys(all);
|
||||
|
||||
try {
|
||||
this.institutionRecordMapper.deleteByExample()
|
||||
|
@ -177,7 +177,7 @@ public class InstitutionDAOImpl implements InstitutionDAO {
|
|||
@Transactional(readOnly = true)
|
||||
public Result<Collection<Institution>> bulkLoadEntities(final Collection<EntityKey> keys) {
|
||||
return Result.tryCatch(() -> {
|
||||
final List<Long> ids = extractIdsFromKeys(keys);
|
||||
final List<Long> ids = extractPKsFromKeys(keys);
|
||||
|
||||
return this.institutionRecordMapper.selectByExample()
|
||||
.where(InstitutionRecordDynamicSqlSupport.id, isIn(ids))
|
||||
|
@ -217,19 +217,18 @@ public class InstitutionDAOImpl implements InstitutionDAO {
|
|||
}
|
||||
|
||||
private Result<InstitutionRecord> update(final Institution institution) {
|
||||
return recordById(institution.id)
|
||||
.map(record -> {
|
||||
return Result.tryCatch(() -> {
|
||||
|
||||
final InstitutionRecord newRecord = new InstitutionRecord(
|
||||
institution.id,
|
||||
institution.name,
|
||||
institution.urlSuffix,
|
||||
null,
|
||||
institution.logoImage);
|
||||
final InstitutionRecord newRecord = new InstitutionRecord(
|
||||
institution.id,
|
||||
institution.name,
|
||||
institution.urlSuffix,
|
||||
null,
|
||||
institution.logoImage);
|
||||
|
||||
this.institutionRecordMapper.updateByPrimaryKeySelective(newRecord);
|
||||
return this.institutionRecordMapper.selectByPrimaryKey(institution.id);
|
||||
});
|
||||
this.institutionRecordMapper.updateByPrimaryKeySelective(newRecord);
|
||||
return this.institutionRecordMapper.selectByPrimaryKey(institution.id);
|
||||
});
|
||||
}
|
||||
|
||||
private static Result<Institution> toDomainModel(final InstitutionRecord record) {
|
||||
|
|
|
@ -55,7 +55,7 @@ public class LmsSetupDAOImpl implements LmsSetupDAO {
|
|||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public Result<LmsSetup> byId(final Long id) {
|
||||
public Result<LmsSetup> byPK(final Long id) {
|
||||
return recordById(id)
|
||||
.flatMap(LmsSetupDAOImpl::toDomainModel);
|
||||
}
|
||||
|
@ -137,7 +137,7 @@ public class LmsSetupDAOImpl implements LmsSetupDAO {
|
|||
@Override
|
||||
@Transactional
|
||||
public Collection<Result<EntityKey>> setActive(final Set<EntityKey> all, final boolean active) {
|
||||
final List<Long> ids = extractIdsFromKeys(all);
|
||||
final List<Long> ids = extractPKsFromKeys(all);
|
||||
final LmsSetupRecord lmsSetupRecord = new LmsSetupRecord(
|
||||
null, null, null, null, null, null, null, null, null, null,
|
||||
BooleanUtils.toIntegerObject(active));
|
||||
|
@ -162,7 +162,7 @@ public class LmsSetupDAOImpl implements LmsSetupDAO {
|
|||
@Override
|
||||
@Transactional
|
||||
public Collection<Result<EntityKey>> delete(final Set<EntityKey> all) {
|
||||
final List<Long> ids = extractIdsFromKeys(all);
|
||||
final List<Long> ids = extractPKsFromKeys(all);
|
||||
|
||||
try {
|
||||
this.lmsSetupRecordMapper.deleteByExample()
|
||||
|
@ -196,7 +196,7 @@ public class LmsSetupDAOImpl implements LmsSetupDAO {
|
|||
@Transactional(readOnly = true)
|
||||
public Result<Collection<LmsSetup>> bulkLoadEntities(final Collection<EntityKey> keys) {
|
||||
return Result.tryCatch(() -> {
|
||||
final List<Long> ids = extractIdsFromKeys(keys);
|
||||
final List<Long> ids = extractPKsFromKeys(keys);
|
||||
|
||||
return this.lmsSetupRecordMapper.selectByExample()
|
||||
.where(LmsSetupRecordDynamicSqlSupport.id, isIn(ids))
|
||||
|
@ -213,7 +213,7 @@ public class LmsSetupDAOImpl implements LmsSetupDAO {
|
|||
return Result.tryCatch(() -> {
|
||||
return this.lmsSetupRecordMapper.selectIdsByExample()
|
||||
.where(LmsSetupRecordDynamicSqlSupport.institutionId,
|
||||
isEqualTo(Long.valueOf(institutionKey.entityId)))
|
||||
isEqualTo(Long.valueOf(institutionKey.modelId)))
|
||||
.build()
|
||||
.execute()
|
||||
.stream()
|
||||
|
@ -271,25 +271,24 @@ public class LmsSetupDAOImpl implements LmsSetupDAO {
|
|||
}
|
||||
|
||||
private Result<LmsSetupRecord> update(final LmsSetup lmsSetup) {
|
||||
return recordById(lmsSetup.id)
|
||||
.map(record -> {
|
||||
return Result.tryCatch(() -> {
|
||||
|
||||
final LmsSetupRecord newRecord = new LmsSetupRecord(
|
||||
lmsSetup.id,
|
||||
lmsSetup.institutionId,
|
||||
lmsSetup.name,
|
||||
(lmsSetup.lmsType != null) ? lmsSetup.lmsType.name() : null,
|
||||
lmsSetup.lmsApiUrl,
|
||||
lmsSetup.lmsAuthName,
|
||||
lmsSetup.lmsAuthSecret,
|
||||
lmsSetup.lmsRestApiToken,
|
||||
lmsSetup.sebAuthName,
|
||||
lmsSetup.sebAuthSecret,
|
||||
null);
|
||||
final LmsSetupRecord newRecord = new LmsSetupRecord(
|
||||
lmsSetup.id,
|
||||
lmsSetup.institutionId,
|
||||
lmsSetup.name,
|
||||
(lmsSetup.lmsType != null) ? lmsSetup.lmsType.name() : null,
|
||||
lmsSetup.lmsApiUrl,
|
||||
lmsSetup.lmsAuthName,
|
||||
lmsSetup.lmsAuthSecret,
|
||||
lmsSetup.lmsRestApiToken,
|
||||
lmsSetup.sebAuthName,
|
||||
lmsSetup.sebAuthSecret,
|
||||
null);
|
||||
|
||||
this.lmsSetupRecordMapper.updateByPrimaryKeySelective(newRecord);
|
||||
return this.lmsSetupRecordMapper.selectByPrimaryKey(lmsSetup.id);
|
||||
});
|
||||
this.lmsSetupRecordMapper.updateByPrimaryKeySelective(newRecord);
|
||||
return this.lmsSetupRecordMapper.selectByPrimaryKey(lmsSetup.id);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -34,8 +34,6 @@ import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.UserActivityLogRe
|
|||
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.UserRecordDynamicSqlSupport;
|
||||
import ch.ethz.seb.sebserver.webservice.datalayer.batis.model.UserActivityLogRecord;
|
||||
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.authorization.UserService;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.TransactionHandler;
|
||||
|
@ -49,18 +47,15 @@ public class UserActivityLogDAOImpl implements UserActivityLogDAO {
|
|||
|
||||
private final UserActivityLogRecordMapper userLogRecordMapper;
|
||||
private final UserService userService;
|
||||
private final AuthorizationGrantService authorizationGrantService;
|
||||
private final PaginationService paginationService;
|
||||
|
||||
public UserActivityLogDAOImpl(
|
||||
final UserActivityLogRecordMapper userLogRecordMapper,
|
||||
final UserService userService,
|
||||
final AuthorizationGrantService authorizationGrantService,
|
||||
final PaginationService paginationService) {
|
||||
|
||||
this.userLogRecordMapper = userLogRecordMapper;
|
||||
this.userService = userService;
|
||||
this.authorizationGrantService = authorizationGrantService;
|
||||
this.paginationService = paginationService;
|
||||
}
|
||||
|
||||
|
@ -172,7 +167,7 @@ public class UserActivityLogDAOImpl implements UserActivityLogDAO {
|
|||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public Result<UserActivityLog> byId(final Long id) {
|
||||
public Result<UserActivityLog> byPK(final Long id) {
|
||||
return Result.tryCatch(() -> this.userLogRecordMapper.selectByPrimaryKey(id))
|
||||
.flatMap(UserActivityLogDAOImpl::toDomainModel);
|
||||
}
|
||||
|
@ -180,7 +175,7 @@ public class UserActivityLogDAOImpl implements UserActivityLogDAO {
|
|||
@Override
|
||||
@Transactional
|
||||
public Collection<Result<EntityKey>> delete(final Set<EntityKey> all) {
|
||||
final List<Long> ids = extractIdsFromKeys(all);
|
||||
final List<Long> ids = extractPKsFromKeys(all);
|
||||
|
||||
try {
|
||||
this.userLogRecordMapper.deleteByExample()
|
||||
|
@ -202,12 +197,24 @@ public class UserActivityLogDAOImpl implements UserActivityLogDAO {
|
|||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public Result<Collection<UserActivityLog>> getAllForUser(final String userUuid) {
|
||||
return all(userUuid, null, null, model -> true);
|
||||
return Result.tryCatch(() -> {
|
||||
return this.userLogRecordMapper.selectByExample()
|
||||
.where(
|
||||
UserActivityLogRecordDynamicSqlSupport.userUuid,
|
||||
SqlBuilder.isEqualTo(userUuid))
|
||||
.build()
|
||||
.execute()
|
||||
.stream()
|
||||
.map(UserActivityLogDAOImpl::toDomainModel)
|
||||
.flatMap(Result::skipOnError)
|
||||
.collect(Collectors.toList());
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public Result<Collection<UserActivityLog>> all(
|
||||
final Long institutionId,
|
||||
final String userId,
|
||||
final Long from,
|
||||
final Long to,
|
||||
|
@ -218,57 +225,30 @@ public class UserActivityLogDAOImpl implements UserActivityLogDAO {
|
|||
? predicate
|
||||
: model -> true;
|
||||
|
||||
final boolean basePrivilege = this.authorizationGrantService.hasBasePrivilege(
|
||||
EntityType.USER_ACTIVITY_LOG,
|
||||
PrivilegeType.READ_ONLY);
|
||||
|
||||
final Long institutionId = (basePrivilege)
|
||||
? null
|
||||
: this.userService.getCurrentUser().institutionId();
|
||||
|
||||
return (institutionId == null)
|
||||
? this.userLogRecordMapper.selectByExample()
|
||||
.where(
|
||||
UserActivityLogRecordDynamicSqlSupport.userUuid,
|
||||
SqlBuilder.isEqualToWhenPresent(userId))
|
||||
.and(
|
||||
UserActivityLogRecordDynamicSqlSupport.timestamp,
|
||||
SqlBuilder.isGreaterThanOrEqualToWhenPresent(from))
|
||||
.and(
|
||||
UserActivityLogRecordDynamicSqlSupport.timestamp,
|
||||
SqlBuilder.isLessThanWhenPresent(to))
|
||||
.build()
|
||||
.execute()
|
||||
.stream()
|
||||
.filter(_predicate)
|
||||
.map(UserActivityLogDAOImpl::toDomainModel)
|
||||
.flatMap(Result::skipOnError)
|
||||
.collect(Collectors.toList())
|
||||
|
||||
: this.userLogRecordMapper.selectByExample()
|
||||
.join(UserRecordDynamicSqlSupport.userRecord)
|
||||
.on(
|
||||
UserRecordDynamicSqlSupport.uuid,
|
||||
SqlBuilder.equalTo(UserActivityLogRecordDynamicSqlSupport.userUuid))
|
||||
.where(
|
||||
UserActivityLogRecordDynamicSqlSupport.userUuid,
|
||||
SqlBuilder.isEqualToWhenPresent(userId))
|
||||
.and(
|
||||
UserRecordDynamicSqlSupport.institutionId,
|
||||
SqlBuilder.isEqualToWhenPresent(institutionId))
|
||||
.and(
|
||||
UserActivityLogRecordDynamicSqlSupport.timestamp,
|
||||
SqlBuilder.isGreaterThanOrEqualToWhenPresent(from))
|
||||
.and(
|
||||
UserActivityLogRecordDynamicSqlSupport.timestamp,
|
||||
SqlBuilder.isLessThanWhenPresent(to))
|
||||
.build()
|
||||
.execute()
|
||||
.stream()
|
||||
.filter(_predicate)
|
||||
.map(UserActivityLogDAOImpl::toDomainModel)
|
||||
.flatMap(Result::skipOnError)
|
||||
.collect(Collectors.toList());
|
||||
return this.userLogRecordMapper.selectByExample()
|
||||
.join(UserRecordDynamicSqlSupport.userRecord)
|
||||
.on(
|
||||
UserRecordDynamicSqlSupport.uuid,
|
||||
SqlBuilder.equalTo(UserActivityLogRecordDynamicSqlSupport.userUuid))
|
||||
.where(
|
||||
UserRecordDynamicSqlSupport.institutionId,
|
||||
SqlBuilder.isEqualTo(institutionId))
|
||||
.and(
|
||||
UserActivityLogRecordDynamicSqlSupport.userUuid,
|
||||
SqlBuilder.isEqualToWhenPresent(userId))
|
||||
.and(
|
||||
UserActivityLogRecordDynamicSqlSupport.timestamp,
|
||||
SqlBuilder.isGreaterThanOrEqualToWhenPresent(from))
|
||||
.and(
|
||||
UserActivityLogRecordDynamicSqlSupport.timestamp,
|
||||
SqlBuilder.isLessThanWhenPresent(to))
|
||||
.build()
|
||||
.execute()
|
||||
.stream()
|
||||
.filter(_predicate)
|
||||
.map(UserActivityLogDAOImpl::toDomainModel)
|
||||
.flatMap(Result::skipOnError)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
});
|
||||
}
|
||||
|
|
|
@ -83,22 +83,22 @@ public class UserDaoImpl implements UserDAO {
|
|||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public Result<UserInfo> byId(final Long id) {
|
||||
public Result<UserInfo> byPK(final Long id) {
|
||||
return Result.tryCatch(() -> this.userRecordMapper.selectByPrimaryKey(id))
|
||||
.flatMap(this::toDomainModel);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public Result<UserInfo> byUuid(final String uuid) {
|
||||
return recordByUUID(uuid)
|
||||
public Result<UserInfo> byModelId(final String modelId) {
|
||||
return recordByUUID(modelId)
|
||||
.flatMap(this::toDomainModel);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public Result<Long> pkForUUID(final String uuid) {
|
||||
return recordByUUID(uuid)
|
||||
public Result<Long> pkForModelId(final String modelId) {
|
||||
return recordByUUID(modelId)
|
||||
.map(r -> r.getId());
|
||||
}
|
||||
|
||||
|
@ -191,7 +191,7 @@ public class UserDaoImpl implements UserDAO {
|
|||
@Override
|
||||
@Transactional
|
||||
public Collection<Result<EntityKey>> setActive(final Set<EntityKey> all, final boolean active) {
|
||||
final List<Long> ids = extractIdsFromKeys(all);
|
||||
final List<Long> ids = extractPKsFromKeys(all);
|
||||
final UserRecord userRecord = new UserRecord(
|
||||
null, null, null, null, null, null, null, null, null,
|
||||
BooleanUtils.toIntegerObject(active));
|
||||
|
@ -216,7 +216,7 @@ public class UserDaoImpl implements UserDAO {
|
|||
@Override
|
||||
@Transactional
|
||||
public Collection<Result<EntityKey>> delete(final Set<EntityKey> all) {
|
||||
final List<Long> ids = extractIdsFromKeys(all);
|
||||
final List<Long> ids = extractPKsFromKeys(all);
|
||||
|
||||
try {
|
||||
this.userRecordMapper.deleteByExample()
|
||||
|
@ -259,7 +259,7 @@ public class UserDaoImpl implements UserDAO {
|
|||
@Transactional(readOnly = true)
|
||||
public Result<Collection<UserInfo>> bulkLoadEntities(final Collection<EntityKey> keys) {
|
||||
return Result.tryCatch(() -> {
|
||||
final List<Long> ids = extractIdsFromKeys(keys);
|
||||
final List<Long> ids = extractPKsFromKeys(keys);
|
||||
|
||||
return this.userRecordMapper.selectByExample()
|
||||
.where(InstitutionRecordDynamicSqlSupport.id, isIn(ids))
|
||||
|
@ -273,12 +273,12 @@ public class UserDaoImpl implements UserDAO {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<Long> extractIdsFromKeys(final Collection<EntityKey> keys) {
|
||||
public List<Long> extractPKsFromKeys(final Collection<EntityKey> keys) {
|
||||
if (keys == null || keys.isEmpty() || keys.iterator().next().isIdPK) {
|
||||
return UserDAO.super.extractIdsFromKeys(keys);
|
||||
return UserDAO.super.extractPKsFromKeys(keys);
|
||||
} else {
|
||||
final List<String> uuids = keys.stream()
|
||||
.map(key -> key.entityId)
|
||||
.map(key -> key.modelId)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
try {
|
||||
|
@ -299,7 +299,7 @@ public class UserDaoImpl implements UserDAO {
|
|||
return Result.tryCatch(() -> {
|
||||
return this.userRecordMapper.selectIdsByExample()
|
||||
.where(UserRecordDynamicSqlSupport.institutionId,
|
||||
isEqualTo(Long.valueOf(institutionKey.entityId)))
|
||||
isEqualTo(Long.valueOf(institutionKey.modelId)))
|
||||
.build()
|
||||
.execute()
|
||||
.stream()
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
package ch.ethz.seb.sebserver.webservice.servicelayer.lms;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||
|
||||
|
@ -17,8 +19,8 @@ public interface LmsAPIService {
|
|||
|
||||
Result<LmsAPITemplate> createLmsAPITemplate(LmsSetup lmsSetup);
|
||||
|
||||
Result<byte[]> createSEBStartConfiguration(Long lmsSetupId);
|
||||
Result<InputStream> createSEBStartConfiguration(Long lmsSetupId);
|
||||
|
||||
Result<byte[]> createSEBStartConfiguration(LmsSetup lmsSetup);
|
||||
Result<InputStream> createSEBStartConfiguration(LmsSetup lmsSetup);
|
||||
|
||||
}
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
package ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup;
|
||||
|
@ -30,7 +32,7 @@ public class LmsAPIServiceImpl implements LmsAPIService {
|
|||
@Override
|
||||
public Result<LmsAPITemplate> createLmsAPITemplate(final Long lmsSetupId) {
|
||||
return this.lmsSetupDAO
|
||||
.byId(lmsSetupId)
|
||||
.byPK(lmsSetupId)
|
||||
.flatMap(this::createLmsAPITemplate);
|
||||
}
|
||||
|
||||
|
@ -46,14 +48,14 @@ public class LmsAPIServiceImpl implements LmsAPIService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Result<byte[]> createSEBStartConfiguration(final Long lmsSetupId) {
|
||||
public Result<InputStream> createSEBStartConfiguration(final Long lmsSetupId) {
|
||||
return this.lmsSetupDAO
|
||||
.byId(lmsSetupId)
|
||||
.byPK(lmsSetupId)
|
||||
.flatMap(this::createSEBStartConfiguration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<byte[]> createSEBStartConfiguration(final LmsSetup lmsSetup) {
|
||||
public Result<InputStream> createSEBStartConfiguration(final LmsSetup lmsSetup) {
|
||||
|
||||
// TODO implementation of creation of SEB start configuration for specified LmsSetup
|
||||
// A SEB start configuration should at least contain the SEB-Client-Credentials to access the SEB Server API
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package ch.ethz.seb.sebserver.webservice.weblayer.api;
|
||||
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
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.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.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;
|
||||
|
||||
public abstract class ActivatableEntityController<T extends GrantEntity> extends EntityController<T> {
|
||||
|
||||
public ActivatableEntityController(
|
||||
final AuthorizationGrantService authorizationGrantService,
|
||||
final BulkActionService bulkActionService,
|
||||
final EntityDAO<T> entityDAO) {
|
||||
|
||||
super(authorizationGrantService, bulkActionService, entityDAO);
|
||||
}
|
||||
|
||||
@RequestMapping(path = "/{id}/activate", method = RequestMethod.POST)
|
||||
public EntityProcessingReport activate(@PathVariable final String id) {
|
||||
return setActive(id, true)
|
||||
.getOrThrow();
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/{id}/deactivate", method = RequestMethod.POST)
|
||||
public EntityProcessingReport deactivate(@PathVariable final String id) {
|
||||
return setActive(id, false)
|
||||
.getOrThrow();
|
||||
}
|
||||
|
||||
@RequestMapping(path = "/{id}/delete", method = RequestMethod.DELETE)
|
||||
public EntityProcessingReport delete(@PathVariable final String id) {
|
||||
return deactivate(id);
|
||||
}
|
||||
|
||||
private Result<EntityProcessingReport> setActive(final String id, final boolean active) {
|
||||
final EntityType entityType = this.entityDAO.entityType();
|
||||
final BulkAction bulkAction = new BulkAction(
|
||||
(active) ? Type.ACTIVATE : Type.DEACTIVATE,
|
||||
entityType,
|
||||
new EntityKey(id, entityType));
|
||||
|
||||
return this.entityDAO.byModelId(id)
|
||||
.flatMap(entity -> this.authorizationGrantService.checkGrantOnEntity(
|
||||
entity,
|
||||
PrivilegeType.WRITE))
|
||||
.flatMap(entity -> this.bulkActionService.createReport(bulkAction));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package ch.ethz.seb.sebserver.webservice.weblayer.api;
|
||||
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
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.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.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;
|
||||
|
||||
public abstract class EntityController<T extends GrantEntity> {
|
||||
|
||||
protected final AuthorizationGrantService authorizationGrantService;
|
||||
protected final BulkActionService bulkActionService;
|
||||
protected final EntityDAO<T> entityDAO;
|
||||
|
||||
protected EntityController(
|
||||
final AuthorizationGrantService authorizationGrantService,
|
||||
final BulkActionService bulkActionService,
|
||||
final EntityDAO<T> entityDAO) {
|
||||
|
||||
this.authorizationGrantService = authorizationGrantService;
|
||||
this.bulkActionService = bulkActionService;
|
||||
this.entityDAO = entityDAO;
|
||||
}
|
||||
|
||||
@RequestMapping(path = "/{id}", method = RequestMethod.GET)
|
||||
public T accountInfo(@PathVariable final String id) {
|
||||
return this.entityDAO
|
||||
.byModelId(id)
|
||||
.flatMap(entity -> this.authorizationGrantService.checkGrantOnEntity(
|
||||
entity,
|
||||
PrivilegeType.READ_ONLY))
|
||||
.getOrThrow();
|
||||
}
|
||||
|
||||
@RequestMapping(path = "/{id}/hard-delete", method = RequestMethod.DELETE)
|
||||
public EntityProcessingReport hardDeleteUser(@PathVariable final String id) {
|
||||
final EntityType entityType = this.entityDAO.entityType();
|
||||
final BulkAction bulkAction = new BulkAction(
|
||||
Type.HARD_DELETE,
|
||||
entityType,
|
||||
new EntityKey(id, entityType));
|
||||
|
||||
return this.entityDAO.byModelId(id)
|
||||
.flatMap(entity -> this.authorizationGrantService.checkGrantOnEntity(
|
||||
entity,
|
||||
PrivilegeType.WRITE))
|
||||
.flatMap(entity -> this.bulkActionService.createReport(bulkAction))
|
||||
.getOrThrow();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,246 @@
|
|||
/*
|
||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package ch.ethz.seb.sebserver.webservice.weblayer.api;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.joda.time.DateTime;
|
||||
import org.springframework.web.bind.WebDataBinder;
|
||||
import org.springframework.web.bind.annotation.InitBinder;
|
||||
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.Constants;
|
||||
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.model.Page;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Page.SortOrder;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.Exam;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.Exam.ExamStatus;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.Exam.ExamType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.QuizData;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ExamRecordDynamicSqlSupport;
|
||||
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.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.ExamDAO;
|
||||
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_EXAM_ADMINISTRATION)
|
||||
public class ExamAdministrationController {
|
||||
|
||||
private final AuthorizationGrantService authorizationGrantService;
|
||||
private final UserActivityLogDAO userActivityLogDAO;
|
||||
private final ExamDAO examDAO;
|
||||
private final PaginationService paginationService;
|
||||
private final BulkActionService bulkActionService;
|
||||
|
||||
public ExamAdministrationController(
|
||||
final AuthorizationGrantService authorizationGrantService,
|
||||
final UserActivityLogDAO userActivityLogDAO,
|
||||
final ExamDAO examDAO,
|
||||
final PaginationService paginationService,
|
||||
final BulkActionService bulkActionService) {
|
||||
|
||||
this.authorizationGrantService = authorizationGrantService;
|
||||
this.userActivityLogDAO = userActivityLogDAO;
|
||||
this.examDAO = examDAO;
|
||||
this.paginationService = paginationService;
|
||||
this.bulkActionService = bulkActionService;
|
||||
}
|
||||
|
||||
@InitBinder
|
||||
public void initBinder(final WebDataBinder binder) throws Exception {
|
||||
this.authorizationGrantService
|
||||
.getUserService()
|
||||
.addUsersInstitutionDefaultPropertySupport(binder);
|
||||
}
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET)
|
||||
public Collection<Exam> getAll(
|
||||
@RequestParam(
|
||||
name = Exam.FILTER_ATTR_INSTITUTION,
|
||||
required = true,
|
||||
defaultValue = UserService.USERS_INSTITUTION_AS_DEFAULT) final Long institutionId,
|
||||
@RequestParam(name = Exam.FILTER_ATTR_LMS_SETUP, required = false) final Long lmsSetupId,
|
||||
@RequestParam(name = Exam.FILTER_ATTR_ACTIVE, required = false) final Boolean active,
|
||||
@RequestParam(name = Exam.FILTER_ATTR_NAME, required = false) final String name,
|
||||
@RequestParam(name = Exam.FILTER_ATTR_FROM, required = false) final String from,
|
||||
@RequestParam(name = Exam.FILTER_ATTR_STATUS, required = false) final ExamStatus status,
|
||||
@RequestParam(name = Exam.FILTER_ATTR_TYPE, required = false) final ExamType type,
|
||||
@RequestParam(name = Exam.FILTER_ATTR_OWNER, required = false) final String owner) {
|
||||
|
||||
checkBaseReadPrivilege(institutionId);
|
||||
|
||||
this.paginationService.setDefaultLimit(ExamRecordDynamicSqlSupport.examRecord);
|
||||
return getExams(institutionId, lmsSetupId, active, name, from, status, type, owner);
|
||||
}
|
||||
|
||||
@RequestMapping(path = "/page", method = RequestMethod.GET)
|
||||
public Page<Exam> getPage(
|
||||
@RequestParam(
|
||||
name = Exam.FILTER_ATTR_INSTITUTION,
|
||||
required = true,
|
||||
defaultValue = UserService.USERS_INSTITUTION_AS_DEFAULT) final Long institutionId,
|
||||
@RequestParam(name = Exam.FILTER_ATTR_LMS_SETUP, required = false) final Long lmsSetupId,
|
||||
@RequestParam(name = Exam.FILTER_ATTR_ACTIVE, required = false) final Boolean active,
|
||||
@RequestParam(name = Exam.FILTER_ATTR_NAME, required = false) final String name,
|
||||
@RequestParam(name = Exam.FILTER_ATTR_FROM, required = false) final String from,
|
||||
@RequestParam(name = Exam.FILTER_ATTR_STATUS, required = false) final ExamStatus status,
|
||||
@RequestParam(name = Exam.FILTER_ATTR_TYPE, required = false) final ExamType type,
|
||||
@RequestParam(name = Exam.FILTER_ATTR_OWNER, required = false) final String owner,
|
||||
@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) {
|
||||
|
||||
checkBaseReadPrivilege(institutionId);
|
||||
|
||||
// NOTE: several attributes for sorting may be originated by the QuizData from LMS not by the database
|
||||
// of the SEB Server. Therefore in the case we have no or the default sorting we can use the
|
||||
// native PaginationService within MyBatis and SQL. For the other cases we need an in-line sorting and paging
|
||||
if (StringUtils.isBlank(sortBy) ||
|
||||
this.paginationService.isNativeSortingSupported(ExamRecordDynamicSqlSupport.examRecord, sortBy)) {
|
||||
|
||||
return this.paginationService.getPage(
|
||||
pageNumber,
|
||||
pageSize,
|
||||
sortBy,
|
||||
sortOrder,
|
||||
ExamRecordDynamicSqlSupport.examRecord,
|
||||
() -> getExams(institutionId, lmsSetupId, active, name, from, status, type, owner));
|
||||
|
||||
} else {
|
||||
|
||||
final int pageNum = this.paginationService.getPageNumber(pageNumber);
|
||||
final int pSize = this.paginationService.getPageSize(pageSize);
|
||||
|
||||
final List<Exam> exams = new ArrayList<>(
|
||||
getExams(institutionId, lmsSetupId, active, name, from, status, type, owner));
|
||||
|
||||
if (!StringUtils.isBlank(sortBy)) {
|
||||
if (sortBy.equals(QuizData.QUIZ_ATTR_NAME)) {
|
||||
Collections.sort(exams, (exam1, exam2) -> exam1.name.compareTo(exam2.name));
|
||||
}
|
||||
if (sortBy.equals(QuizData.FILTER_ATTR_START_TIME)) {
|
||||
Collections.sort(exams, (exam1, exam2) -> exam1.startTime.compareTo(exam2.startTime));
|
||||
}
|
||||
}
|
||||
|
||||
if (SortOrder.DESCENDING == sortOrder) {
|
||||
Collections.reverse(exams);
|
||||
}
|
||||
|
||||
return new Page<>(
|
||||
exams.size() / pSize,
|
||||
pageNum,
|
||||
sortBy,
|
||||
sortOrder,
|
||||
exams.subList(pageNum * pSize, pageNum * pSize + pSize));
|
||||
}
|
||||
}
|
||||
|
||||
@RequestMapping(path = "/{id}", method = RequestMethod.GET)
|
||||
public Exam byId(@PathVariable final Long id) {
|
||||
return this.examDAO
|
||||
.byPK(id)
|
||||
.flatMap(exam -> this.authorizationGrantService.checkGrantOnEntity(
|
||||
exam,
|
||||
PrivilegeType.READ_ONLY))
|
||||
.getOrThrow();
|
||||
}
|
||||
|
||||
@RequestMapping(path = "/save", method = RequestMethod.POST)
|
||||
public Exam save(@Valid @RequestBody final Exam exam) {
|
||||
return this.authorizationGrantService
|
||||
.checkGrantOnEntity(exam, PrivilegeType.MODIFY)
|
||||
.flatMap(this.examDAO::save)
|
||||
.flatMap(entity -> this.userActivityLogDAO.log(ActivityType.MODIFY, entity))
|
||||
.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();
|
||||
}
|
||||
|
||||
private Result<EntityProcessingReport> setActive(final Long id, final boolean active) {
|
||||
|
||||
return this.bulkActionService.createReport(new BulkAction(
|
||||
(active) ? Type.ACTIVATE : Type.DEACTIVATE,
|
||||
EntityType.LMS_SETUP,
|
||||
new EntityKey(id, EntityType.LMS_SETUP)));
|
||||
|
||||
}
|
||||
|
||||
private Collection<Exam> getExams(
|
||||
final Long institutionId,
|
||||
final Long lmsSetupId,
|
||||
final Boolean active,
|
||||
final String name,
|
||||
final String from,
|
||||
final ExamStatus status,
|
||||
final ExamType type,
|
||||
final String owner) {
|
||||
|
||||
this.authorizationGrantService.checkPrivilege(
|
||||
EntityType.EXAM,
|
||||
PrivilegeType.READ_ONLY,
|
||||
institutionId);
|
||||
|
||||
final DateTime _from = (from != null)
|
||||
? DateTime.parse(from, Constants.DATE_TIME_PATTERN_UTC_NO_MILLIS)
|
||||
: null;
|
||||
|
||||
return this.examDAO.allMatching(
|
||||
institutionId,
|
||||
lmsSetupId,
|
||||
name,
|
||||
status,
|
||||
type,
|
||||
_from,
|
||||
owner,
|
||||
active).getOrThrow();
|
||||
}
|
||||
|
||||
private void checkBaseReadPrivilege(final Long institutionId) {
|
||||
this.authorizationGrantService.checkPrivilege(
|
||||
EntityType.EXAM,
|
||||
PrivilegeType.READ_ONLY,
|
||||
institutionId);
|
||||
}
|
||||
|
||||
}
|
|
@ -21,8 +21,8 @@ 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.EntityKeyAndName;
|
||||
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;
|
||||
|
@ -62,24 +62,18 @@ public class InstitutionController {
|
|||
|
||||
@RequestMapping(path = "/self", method = RequestMethod.GET)
|
||||
public Institution getOwn() {
|
||||
|
||||
checkBaseReadPrivilege();
|
||||
|
||||
final SEBServerUser currentUser = this.authorizationGrantService
|
||||
.getUserService()
|
||||
.getCurrentUser();
|
||||
final Long institutionId = currentUser.institutionId();
|
||||
return this.institutionDAO.byId(institutionId).getOrThrow();
|
||||
|
||||
final Long institutionId = currentUser.institutionId();
|
||||
return this.institutionDAO.byPK(institutionId).getOrThrow();
|
||||
}
|
||||
|
||||
@RequestMapping(path = "/{id}", method = RequestMethod.GET)
|
||||
public Institution getById(@PathVariable final Long id) {
|
||||
|
||||
checkBaseReadPrivilege();
|
||||
|
||||
return this.institutionDAO
|
||||
.byId(id)
|
||||
.byPK(id)
|
||||
.flatMap(inst -> this.authorizationGrantService.checkGrantOnEntity(
|
||||
inst,
|
||||
PrivilegeType.READ_ONLY))
|
||||
|
@ -90,8 +84,6 @@ public class InstitutionController {
|
|||
public Collection<Institution> getAll(
|
||||
@RequestParam(name = Institution.FILTER_ATTR_ACTIVE, required = false) final Boolean active) {
|
||||
|
||||
checkBaseReadPrivilege();
|
||||
|
||||
if (!this.authorizationGrantService.hasBasePrivilege(
|
||||
EntityType.INSTITUTION,
|
||||
PrivilegeType.READ_ONLY)) {
|
||||
|
@ -126,13 +118,15 @@ public class InstitutionController {
|
|||
}
|
||||
|
||||
@RequestMapping(path = "/{id}/activate", method = RequestMethod.POST)
|
||||
public Institution activate(@PathVariable final Long id) {
|
||||
return setActive(id, true);
|
||||
public EntityProcessingReport activate(@PathVariable final Long id) {
|
||||
return setActive(id, true)
|
||||
.getOrThrow();
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/{id}/deactivate", method = RequestMethod.POST)
|
||||
public Institution deactivate(@PathVariable final Long id) {
|
||||
return setActive(id, false);
|
||||
public EntityProcessingReport deactivate(@PathVariable final Long id) {
|
||||
return setActive(id, false)
|
||||
.getOrThrow();
|
||||
}
|
||||
|
||||
@RequestMapping(path = "/{id}/delete", method = RequestMethod.DELETE)
|
||||
|
@ -142,7 +136,8 @@ public class InstitutionController {
|
|||
return this.bulkActionService.createReport(new BulkAction(
|
||||
Type.DEACTIVATE,
|
||||
EntityType.INSTITUTION,
|
||||
new EntityKey(id, EntityType.INSTITUTION)));
|
||||
new EntityKey(id, EntityType.INSTITUTION)))
|
||||
.getOrThrow();
|
||||
}
|
||||
|
||||
@RequestMapping(path = "/{id}/hard-delete", method = RequestMethod.DELETE)
|
||||
|
@ -152,7 +147,8 @@ public class InstitutionController {
|
|||
return this.bulkActionService.createReport(new BulkAction(
|
||||
Type.HARD_DELETE,
|
||||
EntityType.INSTITUTION,
|
||||
new EntityKey(id, EntityType.INSTITUTION)));
|
||||
new EntityKey(id, EntityType.INSTITUTION)))
|
||||
.getOrThrow();
|
||||
}
|
||||
|
||||
private void checkPrivilegeForInstitution(final Long id, final PrivilegeType type) {
|
||||
|
@ -160,24 +156,21 @@ public class InstitutionController {
|
|||
EntityType.INSTITUTION,
|
||||
type);
|
||||
|
||||
this.institutionDAO.byId(id)
|
||||
this.institutionDAO.byPK(id)
|
||||
.flatMap(institution -> this.authorizationGrantService.checkGrantOnEntity(
|
||||
institution,
|
||||
type))
|
||||
.getOrThrow();
|
||||
}
|
||||
|
||||
private Institution setActive(final Long id, final boolean active) {
|
||||
private Result<EntityProcessingReport> setActive(final Long id, final boolean active) {
|
||||
checkPrivilegeForInstitution(id, PrivilegeType.MODIFY);
|
||||
|
||||
this.bulkActionService.doBulkAction(new BulkAction(
|
||||
return this.bulkActionService.createReport(new BulkAction(
|
||||
(active) ? Type.ACTIVATE : Type.DEACTIVATE,
|
||||
EntityType.INSTITUTION,
|
||||
new EntityKey(id, EntityType.INSTITUTION)));
|
||||
|
||||
return this.institutionDAO
|
||||
.byId(id)
|
||||
.getOrThrow();
|
||||
}
|
||||
|
||||
private Result<Institution> save(final Institution institution, final PrivilegeType privilegeType) {
|
||||
|
@ -192,10 +185,4 @@ public class InstitutionController {
|
|||
.flatMap(inst -> this.userActivityLogDAO.log(activityType, inst));
|
||||
}
|
||||
|
||||
private void checkBaseReadPrivilege() {
|
||||
this.authorizationGrantService.checkHasAnyPrivilege(
|
||||
EntityType.INSTITUTION,
|
||||
PrivilegeType.READ_ONLY);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,12 +8,18 @@
|
|||
|
||||
package ch.ethz.seb.sebserver.webservice.weblayer.api;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.Collection;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
|
||||
import org.apache.tomcat.util.http.fileupload.IOUtils;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.bind.WebDataBinder;
|
||||
import org.springframework.web.bind.annotation.InitBinder;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
@ -30,9 +36,8 @@ import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup.LmsType;
|
|||
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.AuthorizationGrantService;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.PermissionDeniedException;
|
||||
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.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;
|
||||
|
@ -66,44 +71,42 @@ public class LmsSetupController {
|
|||
this.lmsAPIService = lmsAPIService;
|
||||
}
|
||||
|
||||
@InitBinder
|
||||
public void initBinder(final WebDataBinder binder) throws Exception {
|
||||
this.authorizationGrantService
|
||||
.getUserService()
|
||||
.addUsersInstitutionDefaultPropertySupport(binder);
|
||||
}
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET)
|
||||
public Collection<LmsSetup> getAll(
|
||||
@RequestParam(name = LmsSetup.FILTER_ATTR_INSTITUTION, required = false) final Long institutionId,
|
||||
@RequestParam(
|
||||
name = LmsSetup.FILTER_ATTR_INSTITUTION,
|
||||
required = true,
|
||||
defaultValue = UserService.USERS_INSTITUTION_AS_DEFAULT) final Long institutionId,
|
||||
@RequestParam(name = LmsSetup.FILTER_ATTR_NAME, required = false) final String name,
|
||||
@RequestParam(name = LmsSetup.FILTER_ATTR_LMS_TYPE, required = false) final LmsType lmsType,
|
||||
@RequestParam(name = LmsSetup.FILTER_ATTR_ACTIVE, required = false) final Boolean active) {
|
||||
|
||||
checkBaseReadPrivilege();
|
||||
|
||||
final SEBServerUser currentUser = this.authorizationGrantService
|
||||
.getUserService()
|
||||
.getCurrentUser();
|
||||
final Long usersInstitution = currentUser.institutionId();
|
||||
final Long instId = (institutionId != null) ? institutionId : usersInstitution;
|
||||
|
||||
if (!this.authorizationGrantService.hasBasePrivilege(
|
||||
EntityType.LMS_SETUP,
|
||||
PrivilegeType.READ_ONLY) &&
|
||||
!instId.equals(usersInstitution)) {
|
||||
|
||||
throw new PermissionDeniedException(
|
||||
EntityType.LMS_SETUP,
|
||||
PrivilegeType.READ_ONLY,
|
||||
currentUser.getUserInfo().uuid);
|
||||
}
|
||||
checkReadPrivilege(institutionId);
|
||||
|
||||
return this.lmsSetupDAO
|
||||
.allMatching(instId, name, lmsType, active)
|
||||
.allMatching(institutionId, name, lmsType, active)
|
||||
.getOrThrow();
|
||||
}
|
||||
|
||||
@RequestMapping(path = "/names", method = RequestMethod.GET)
|
||||
public Collection<EntityKeyAndName> getNames(
|
||||
@RequestParam(name = LmsSetup.FILTER_ATTR_INSTITUTION, required = false) final Long institutionId,
|
||||
@RequestParam(
|
||||
name = LmsSetup.FILTER_ATTR_INSTITUTION,
|
||||
required = true,
|
||||
defaultValue = UserService.USERS_INSTITUTION_AS_DEFAULT) final Long institutionId,
|
||||
@RequestParam(name = LmsSetup.FILTER_ATTR_NAME, required = false) final String name,
|
||||
@RequestParam(name = LmsSetup.FILTER_ATTR_LMS_TYPE, required = false) final LmsType lmsType,
|
||||
@RequestParam(name = LmsSetup.FILTER_ATTR_ACTIVE, required = false) final Boolean active) {
|
||||
|
||||
checkReadPrivilege(institutionId);
|
||||
|
||||
return getAll(institutionId, name, lmsType, active)
|
||||
.stream()
|
||||
.map(LmsSetup::toName)
|
||||
|
@ -112,13 +115,10 @@ public class LmsSetupController {
|
|||
|
||||
@RequestMapping(path = "/{id}", method = RequestMethod.GET)
|
||||
public LmsSetup getById(@PathVariable final Long id) {
|
||||
|
||||
checkBaseReadPrivilege();
|
||||
|
||||
return this.lmsSetupDAO
|
||||
.byId(id)
|
||||
.flatMap(inst -> this.authorizationGrantService.checkGrantOnEntity(
|
||||
inst,
|
||||
.byPK(id)
|
||||
.flatMap(lmsSetup -> this.authorizationGrantService.checkGrantOnEntity(
|
||||
lmsSetup,
|
||||
PrivilegeType.READ_ONLY))
|
||||
.getOrThrow();
|
||||
}
|
||||
|
@ -127,15 +127,28 @@ public class LmsSetupController {
|
|||
path = "/create_seb_config/{id}",
|
||||
method = RequestMethod.GET,
|
||||
produces = MediaType.APPLICATION_OCTET_STREAM_VALUE) // TODO check if this is the right format
|
||||
public byte[] createSEBConfig(@PathVariable final Long id) {
|
||||
public void downloadSEBConfig(
|
||||
@PathVariable final Long id,
|
||||
final HttpServletResponse response) {
|
||||
|
||||
this.authorizationGrantService.checkHasAnyPrivilege(
|
||||
EntityType.LMS_SETUP,
|
||||
PrivilegeType.WRITE);
|
||||
|
||||
return this.lmsAPIService
|
||||
.createSEBStartConfiguration(id)
|
||||
.getOrThrow();
|
||||
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
|
||||
response.setStatus(HttpStatus.OK.value());
|
||||
|
||||
try {
|
||||
final InputStream sebConfigFileIn = this.lmsAPIService
|
||||
.createSEBStartConfiguration(id)
|
||||
.getOrThrow();
|
||||
|
||||
IOUtils.copyLarge(sebConfigFileIn, response.getOutputStream());
|
||||
response.flushBuffer();
|
||||
|
||||
} catch (final Exception e) {
|
||||
throw new RuntimeException("Unexpected error while trying to creae SEB start config: ", e);
|
||||
}
|
||||
}
|
||||
|
||||
@RequestMapping(path = "/create", method = RequestMethod.PUT)
|
||||
|
@ -151,12 +164,12 @@ public class LmsSetupController {
|
|||
}
|
||||
|
||||
@RequestMapping(path = "/{id}/activate", method = RequestMethod.POST)
|
||||
public LmsSetup activate(@PathVariable final Long id) {
|
||||
public EntityProcessingReport activate(@PathVariable final Long id) {
|
||||
return setActive(id, true);
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/{id}/deactivate", method = RequestMethod.POST)
|
||||
public LmsSetup deactivate(@PathVariable final Long id) {
|
||||
public EntityProcessingReport deactivate(@PathVariable final Long id) {
|
||||
return setActive(id, false);
|
||||
}
|
||||
|
||||
|
@ -167,7 +180,8 @@ public class LmsSetupController {
|
|||
return this.bulkActionService.createReport(new BulkAction(
|
||||
Type.DEACTIVATE,
|
||||
EntityType.LMS_SETUP,
|
||||
new EntityKey(id, EntityType.LMS_SETUP)));
|
||||
new EntityKey(id, EntityType.LMS_SETUP)))
|
||||
.getOrThrow();
|
||||
}
|
||||
|
||||
@RequestMapping(path = "/{id}/hard-delete", method = RequestMethod.DELETE)
|
||||
|
@ -177,31 +191,29 @@ public class LmsSetupController {
|
|||
return this.bulkActionService.createReport(new BulkAction(
|
||||
Type.HARD_DELETE,
|
||||
EntityType.LMS_SETUP,
|
||||
new EntityKey(id, EntityType.LMS_SETUP)));
|
||||
new EntityKey(id, EntityType.LMS_SETUP)))
|
||||
.getOrThrow();
|
||||
}
|
||||
|
||||
private void checkPrivilegeForInstitution(final Long id, final PrivilegeType type) {
|
||||
private void checkPrivilegeForInstitution(final Long lmsSetupId, final PrivilegeType type) {
|
||||
this.authorizationGrantService.checkHasAnyPrivilege(
|
||||
EntityType.LMS_SETUP,
|
||||
type);
|
||||
|
||||
this.lmsSetupDAO.byId(id)
|
||||
this.lmsSetupDAO.byPK(lmsSetupId)
|
||||
.flatMap(institution -> this.authorizationGrantService.checkGrantOnEntity(
|
||||
institution,
|
||||
type))
|
||||
.getOrThrow();
|
||||
}
|
||||
|
||||
private LmsSetup setActive(final Long id, final boolean active) {
|
||||
private EntityProcessingReport setActive(final Long id, final boolean active) {
|
||||
checkPrivilegeForInstitution(id, PrivilegeType.MODIFY);
|
||||
|
||||
this.bulkActionService.doBulkAction(new BulkAction(
|
||||
return this.bulkActionService.createReport(new BulkAction(
|
||||
(active) ? Type.ACTIVATE : Type.DEACTIVATE,
|
||||
EntityType.LMS_SETUP,
|
||||
new EntityKey(id, EntityType.LMS_SETUP)));
|
||||
|
||||
return this.lmsSetupDAO
|
||||
.byId(id)
|
||||
new EntityKey(id, EntityType.LMS_SETUP)))
|
||||
.getOrThrow();
|
||||
}
|
||||
|
||||
|
@ -214,13 +226,14 @@ public class LmsSetupController {
|
|||
return this.authorizationGrantService
|
||||
.checkGrantOnEntity(lmsSetup, privilegeType)
|
||||
.flatMap(this.lmsSetupDAO::save)
|
||||
.flatMap(inst -> this.userActivityLogDAO.log(activityType, inst));
|
||||
.flatMap(exam -> this.userActivityLogDAO.log(activityType, exam));
|
||||
}
|
||||
|
||||
private void checkBaseReadPrivilege() {
|
||||
this.authorizationGrantService.checkHasAnyPrivilege(
|
||||
private void checkReadPrivilege(final Long institutionId) {
|
||||
this.authorizationGrantService.checkPrivilege(
|
||||
EntityType.LMS_SETUP,
|
||||
PrivilegeType.READ_ONLY);
|
||||
PrivilegeType.READ_ONLY,
|
||||
institutionId);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -74,19 +74,20 @@ public class QuizImportController {
|
|||
@RequestParam(name = LMS_SETUP.ATTR_ID, required = true) final Long lmsSetupId,
|
||||
@RequestParam(name = QuizData.FILTER_ATTR_NAME, required = false) final String nameLike,
|
||||
@RequestParam(name = QuizData.FILTER_ATTR_START_TIME, required = false) final String startTime,
|
||||
@RequestParam(name = QuizData.PAGE_ATTR_NUMBER, required = false) final Integer pageNumber,
|
||||
@RequestParam(name = QuizData.PAGE_ATTR_SIZE, required = false) final Integer pageSize,
|
||||
@RequestParam(name = QuizData.PAGE_ATTR_SORT_BY, required = false) final String orderBy,
|
||||
@RequestParam(name = QuizData.PAGE_ATTR_SORT_ORDER, required = false) final String sortOrder) {
|
||||
|
||||
this.authorizationGrantService.checkHasAnyPrivilege(
|
||||
EntityType.EXAM,
|
||||
PrivilegeType.READ_ONLY);
|
||||
@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 orderBy,
|
||||
@RequestParam(name = Page.ATTR_SORT_ORDER, required = false) final String sortOrder) {
|
||||
|
||||
final LmsAPITemplate lmsAPITemplate = this.lmsAPIService
|
||||
.createLmsAPITemplate(lmsSetupId)
|
||||
.getOrThrow();
|
||||
|
||||
this.authorizationGrantService.checkPrivilege(
|
||||
EntityType.EXAM,
|
||||
PrivilegeType.READ_ONLY,
|
||||
lmsAPITemplate.lmsSetup().institutionId);
|
||||
|
||||
return lmsAPITemplate.getQuizzesPage(
|
||||
nameLike,
|
||||
Utils.dateTimeStringToTimestamp(startTime, null),
|
||||
|
|
|
@ -18,6 +18,8 @@ public class RestAPI {
|
|||
|
||||
public static final String ENDPOINT_QUIZ_IMPORT = "/quiz";
|
||||
|
||||
public static final String ENDPOINT_EXAM_ADMINISTRATION = "/exam";
|
||||
|
||||
public static final String ENDPOINT_USER_ACTIVITY_LOG = "/useractivity";
|
||||
|
||||
}
|
||||
|
|
|
@ -13,15 +13,14 @@ import java.util.Collection;
|
|||
import javax.validation.Valid;
|
||||
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
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;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
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.model.Page;
|
||||
import ch.ethz.seb.sebserver.gbl.model.user.UserFilter;
|
||||
|
@ -34,8 +33,6 @@ 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.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.UserActivityLogDAO;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserActivityLogDAO.ActivityType;
|
||||
|
@ -45,11 +42,10 @@ import ch.ethz.seb.sebserver.webservice.weblayer.oauth.RevokeTokenEndpoint;
|
|||
@WebServiceProfile
|
||||
@RestController
|
||||
@RequestMapping("/${sebserver.webservice.api.admin.endpoint}" + RestAPI.ENDPOINT_USER_ACCOUNT)
|
||||
public class UserAccountController {
|
||||
public class UserAccountController extends ActivatableEntityController<UserInfo> {
|
||||
|
||||
private final UserDAO userDao;
|
||||
private final AuthorizationGrantService authorizationGrantService;
|
||||
private final UserService userService;
|
||||
private final UserActivityLogDAO userActivityLogDAO;
|
||||
private final PaginationService paginationService;
|
||||
private final BulkActionService bulkActionService;
|
||||
|
@ -58,34 +54,40 @@ public class UserAccountController {
|
|||
public UserAccountController(
|
||||
final UserDAO userDao,
|
||||
final AuthorizationGrantService authorizationGrantService,
|
||||
final UserService userService,
|
||||
final UserActivityLogDAO userActivityLogDAO,
|
||||
final PaginationService paginationService,
|
||||
final BulkActionService bulkActionService,
|
||||
final ApplicationEventPublisher applicationEventPublisher) {
|
||||
|
||||
super(authorizationGrantService, bulkActionService, userDao);
|
||||
this.userDao = userDao;
|
||||
this.authorizationGrantService = authorizationGrantService;
|
||||
this.userService = userService;
|
||||
this.userActivityLogDAO = userActivityLogDAO;
|
||||
this.paginationService = paginationService;
|
||||
this.bulkActionService = bulkActionService;
|
||||
this.applicationEventPublisher = applicationEventPublisher;
|
||||
}
|
||||
|
||||
@InitBinder
|
||||
public void initBinder(final WebDataBinder binder) throws Exception {
|
||||
this.authorizationGrantService
|
||||
.getUserService()
|
||||
.addUsersInstitutionDefaultPropertySupport(binder);
|
||||
}
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET)
|
||||
public Collection<UserInfo> getAll(
|
||||
@RequestParam(name = UserFilter.FILTER_ATTR_INSTITUTION, required = false) final Long institutionId,
|
||||
@RequestParam(
|
||||
name = UserFilter.FILTER_ATTR_INSTITUTION,
|
||||
required = true,
|
||||
defaultValue = UserService.USERS_INSTITUTION_AS_DEFAULT) final Long institutionId,
|
||||
@RequestParam(name = UserFilter.FILTER_ATTR_ACTIVE, required = false) final Boolean active,
|
||||
@RequestParam(name = UserFilter.FILTER_ATTR_NAME, required = false) final String name,
|
||||
@RequestParam(name = UserFilter.FILTER_ATTR_USER_NAME, required = false) final String username,
|
||||
@RequestParam(name = UserFilter.FILTER_ATTR_EMAIL, required = false) final String email,
|
||||
@RequestParam(name = UserFilter.FILTER_ATTR_LOCALE, required = false) final String locale) {
|
||||
|
||||
// fist check if current user has any privileges for this action
|
||||
this.authorizationGrantService.checkHasAnyPrivilege(
|
||||
EntityType.USER,
|
||||
PrivilegeType.READ_ONLY);
|
||||
checkReadPrivilege(institutionId);
|
||||
|
||||
this.paginationService.setDefaultLimit(UserRecordDynamicSqlSupport.userRecord);
|
||||
return getAll(createUserFilter(institutionId, active, name, username, email, locale));
|
||||
|
@ -93,7 +95,10 @@ public class UserAccountController {
|
|||
|
||||
@RequestMapping(path = "/page", method = RequestMethod.GET)
|
||||
public Page<UserInfo> getPage(
|
||||
@RequestParam(name = UserFilter.FILTER_ATTR_INSTITUTION, required = false) final Long institutionId,
|
||||
@RequestParam(
|
||||
name = UserFilter.FILTER_ATTR_INSTITUTION,
|
||||
required = true,
|
||||
defaultValue = UserService.USERS_INSTITUTION_AS_DEFAULT) final Long institutionId,
|
||||
@RequestParam(name = UserFilter.FILTER_ATTR_ACTIVE, required = false) final Boolean active,
|
||||
@RequestParam(name = UserFilter.FILTER_ATTR_NAME, required = false) final String name,
|
||||
@RequestParam(name = UserFilter.FILTER_ATTR_USER_NAME, required = false) final String username,
|
||||
|
@ -104,10 +109,7 @@ public class UserAccountController {
|
|||
@RequestParam(name = Page.ATTR_SORT_BY, required = false) final String sortBy,
|
||||
@RequestParam(name = Page.ATTR_SORT_ORDER, required = false) final Page.SortOrder sortOrder) {
|
||||
|
||||
// fist check if current user has any privileges for this action
|
||||
this.authorizationGrantService.checkHasAnyPrivilege(
|
||||
EntityType.USER,
|
||||
PrivilegeType.READ_ONLY);
|
||||
checkReadPrivilege(institutionId);
|
||||
|
||||
return this.paginationService.getPage(
|
||||
pageNumber,
|
||||
|
@ -121,21 +123,22 @@ public class UserAccountController {
|
|||
|
||||
@RequestMapping(path = "/me", method = RequestMethod.GET)
|
||||
public UserInfo loggedInUser() {
|
||||
return this.userService
|
||||
return this.authorizationGrantService
|
||||
.getUserService()
|
||||
.getCurrentUser()
|
||||
.getUserInfo();
|
||||
}
|
||||
|
||||
@RequestMapping(path = "/{uuid}", method = RequestMethod.GET)
|
||||
public UserInfo accountInfo(@PathVariable final String uuid) {
|
||||
return this.userDao
|
||||
.byUuid(uuid)
|
||||
.flatMap(userInfo -> this.authorizationGrantService.checkGrantOnEntity(
|
||||
userInfo,
|
||||
PrivilegeType.READ_ONLY))
|
||||
.getOrThrow();
|
||||
|
||||
}
|
||||
// @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) {
|
||||
|
@ -150,60 +153,52 @@ public class UserAccountController {
|
|||
|
||||
}
|
||||
|
||||
@RequestMapping(path = "/{uuid}/activate", method = RequestMethod.POST)
|
||||
public UserInfo activateUser(@PathVariable final String uuid) {
|
||||
return setActive(uuid, true);
|
||||
}
|
||||
// @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();
|
||||
// }
|
||||
|
||||
@RequestMapping(value = "/{uuid}/deactivate", method = RequestMethod.POST)
|
||||
public UserInfo deactivateUser(@PathVariable final String uuid) {
|
||||
return setActive(uuid, false);
|
||||
}
|
||||
// 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();
|
||||
// }
|
||||
|
||||
@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)));
|
||||
}
|
||||
|
||||
@RequestMapping(path = "/{uuid}/hard-delete", method = RequestMethod.DELETE)
|
||||
public EntityProcessingReport hardDeleteUser(@PathVariable final String uuid) {
|
||||
checkPrivilegeForUser(uuid, PrivilegeType.WRITE);
|
||||
|
||||
return this.bulkActionService.createReport(new BulkAction(
|
||||
Type.HARD_DELETE,
|
||||
EntityType.USER,
|
||||
new EntityKey(uuid, EntityType.USER, false)));
|
||||
}
|
||||
|
||||
private void checkPrivilegeForUser(final String uuid, final PrivilegeType type) {
|
||||
this.authorizationGrantService.checkHasAnyPrivilege(
|
||||
EntityType.USER,
|
||||
type);
|
||||
|
||||
this.userDao.byUuid(uuid)
|
||||
.flatMap(userInfo -> this.authorizationGrantService.checkGrantOnEntity(
|
||||
userInfo,
|
||||
type))
|
||||
.getOrThrow();
|
||||
}
|
||||
|
||||
private UserInfo setActive(final String uuid, final boolean active) {
|
||||
this.checkPrivilegeForUser(uuid, PrivilegeType.MODIFY);
|
||||
|
||||
this.bulkActionService.doBulkAction(new BulkAction(
|
||||
(active) ? Type.ACTIVATE : Type.DEACTIVATE,
|
||||
EntityType.USER,
|
||||
new EntityKey(uuid, EntityType.USER, false)));
|
||||
|
||||
return this.userDao
|
||||
.byUuid(uuid)
|
||||
.getOrThrow();
|
||||
}
|
||||
// private Result<EntityProcessingReport> 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<UserInfo> _saveUser(final UserMod userData, final PrivilegeType privilegeType) {
|
||||
|
||||
|
@ -261,4 +256,11 @@ public class UserAccountController {
|
|||
: null;
|
||||
}
|
||||
|
||||
private void checkReadPrivilege(final Long institutionId) {
|
||||
this.authorizationGrantService.checkPrivilege(
|
||||
EntityType.USER,
|
||||
PrivilegeType.READ_ONLY,
|
||||
institutionId);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -13,8 +13,11 @@ import java.util.Collection;
|
|||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.web.bind.WebDataBinder;
|
||||
import org.springframework.web.bind.annotation.InitBinder;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
@ -26,11 +29,14 @@ import ch.ethz.seb.sebserver.gbl.model.EntityType;
|
|||
import ch.ethz.seb.sebserver.gbl.model.Page;
|
||||
import ch.ethz.seb.sebserver.gbl.model.user.UserActivityLog;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.UserActivityLogRecordDynamicSqlSupport;
|
||||
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.UserRecordDynamicSqlSupport;
|
||||
import ch.ethz.seb.sebserver.webservice.datalayer.batis.model.UserActivityLogRecord;
|
||||
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.UserService;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserActivityLogDAO;
|
||||
|
||||
@WebServiceProfile
|
||||
|
@ -52,84 +58,113 @@ public class UserActivityLogController {
|
|||
this.paginationService = paginationService;
|
||||
}
|
||||
|
||||
@InitBinder
|
||||
public void initBinder(final WebDataBinder binder) throws Exception {
|
||||
this.authorizationGrantService
|
||||
.getUserService()
|
||||
.addUsersInstitutionDefaultPropertySupport(binder);
|
||||
}
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET)
|
||||
public Collection<UserActivityLog> getAll(
|
||||
@RequestParam(required = false) final Long from,
|
||||
@RequestParam(required = false) final Long to,
|
||||
@RequestParam(required = false) final String activityTypes,
|
||||
@RequestParam(required = false) final String entityTypes) {
|
||||
@RequestParam(
|
||||
name = UserActivityLog.FILTER_ATTR_INSTITUTION,
|
||||
required = true,
|
||||
defaultValue = UserService.USERS_INSTITUTION_AS_DEFAULT) final Long institutionId,
|
||||
@RequestParam(
|
||||
name = UserActivityLog.FILTER_ATTR_FROM,
|
||||
required = false) final String from,
|
||||
@RequestParam(
|
||||
name = UserActivityLog.FILTER_ATTR_TO,
|
||||
required = false) final String to,
|
||||
@RequestParam(
|
||||
name = UserActivityLog.FILTER_ATTR_ACTIVITY_TYPES,
|
||||
required = false) final String activityTypes,
|
||||
@RequestParam(
|
||||
name = UserActivityLog.FILTER_ATTR_ENTITY_TYPES,
|
||||
required = false) final String entityTypes) {
|
||||
|
||||
checkBaseReadPrivilege();
|
||||
checkBaseReadPrivilege(institutionId);
|
||||
this.paginationService.setDefaultLimit(UserActivityLogRecordDynamicSqlSupport.userActivityLogRecord);
|
||||
return _getAll(null, from, to, activityTypes, entityTypes);
|
||||
return _getAll(institutionId, null, from, to, activityTypes, entityTypes);
|
||||
}
|
||||
|
||||
@RequestMapping(path = "/{userId}", method = RequestMethod.GET)
|
||||
public Collection<UserActivityLog> getAllForUser(
|
||||
@PathVariable final String userId,
|
||||
@RequestParam(required = false) final Long from,
|
||||
@RequestParam(required = false) final Long to,
|
||||
@RequestParam(required = false) final String activityTypes,
|
||||
@RequestParam(required = false) final String entityTypes) {
|
||||
@RequestParam(
|
||||
name = UserActivityLog.FILTER_ATTR_INSTITUTION,
|
||||
required = true,
|
||||
defaultValue = UserService.USERS_INSTITUTION_AS_DEFAULT) final Long institutionId,
|
||||
@RequestParam(name = UserActivityLog.FILTER_ATTR_FROM, required = false) final String from,
|
||||
@RequestParam(name = UserActivityLog.FILTER_ATTR_TO, required = false) final String to,
|
||||
@RequestParam(name = UserActivityLog.FILTER_ATTR_ACTIVITY_TYPES,
|
||||
required = false) final String activityTypes,
|
||||
@RequestParam(name = UserActivityLog.FILTER_ATTR_ENTITY_TYPES, required = false) final String entityTypes) {
|
||||
|
||||
checkBaseReadPrivilege();
|
||||
checkBaseReadPrivilege(institutionId);
|
||||
this.paginationService.setDefaultLimit(UserActivityLogRecordDynamicSqlSupport.userActivityLogRecord);
|
||||
return _getAll(userId, from, to, activityTypes, entityTypes);
|
||||
return _getAll(institutionId, userId, from, to, activityTypes, entityTypes);
|
||||
}
|
||||
|
||||
@RequestMapping(path = "/page", method = RequestMethod.GET)
|
||||
public Page<UserActivityLog> getPage(
|
||||
@RequestParam(required = false) final Long from,
|
||||
@RequestParam(required = false) final Long to,
|
||||
@RequestParam(required = false) final String activityTypes,
|
||||
@RequestParam(required = false) final String entityTypes,
|
||||
@RequestParam(
|
||||
name = UserActivityLog.FILTER_ATTR_INSTITUTION,
|
||||
required = true,
|
||||
defaultValue = UserService.USERS_INSTITUTION_AS_DEFAULT) final Long institutionId,
|
||||
@RequestParam(name = UserActivityLog.FILTER_ATTR_FROM, required = false) final String from,
|
||||
@RequestParam(name = UserActivityLog.FILTER_ATTR_TO, required = false) final String to,
|
||||
@RequestParam(name = UserActivityLog.FILTER_ATTR_ACTIVITY_TYPES,
|
||||
required = false) final String activityTypes,
|
||||
@RequestParam(name = UserActivityLog.FILTER_ATTR_ENTITY_TYPES, required = false) final String entityTypes,
|
||||
@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) {
|
||||
|
||||
checkBaseReadPrivilege();
|
||||
checkBaseReadPrivilege(institutionId);
|
||||
return this.paginationService.getPage(
|
||||
pageNumber,
|
||||
pageSize,
|
||||
sortBy,
|
||||
sortOrder,
|
||||
UserRecordDynamicSqlSupport.userRecord,
|
||||
() -> _getAll(null, from, to, activityTypes, entityTypes));
|
||||
() -> _getAll(institutionId, null, from, to, activityTypes, entityTypes));
|
||||
}
|
||||
|
||||
@RequestMapping(path = "/page/{userId}", method = RequestMethod.GET)
|
||||
public Page<UserActivityLog> getPageForUser(
|
||||
@PathVariable final String userId,
|
||||
@RequestParam(required = false) final Long from,
|
||||
@RequestParam(required = false) final Long to,
|
||||
@RequestParam(required = false) final String activityTypes,
|
||||
@RequestParam(required = false) final String entityTypes,
|
||||
@RequestParam(
|
||||
name = UserActivityLog.FILTER_ATTR_INSTITUTION,
|
||||
required = true,
|
||||
defaultValue = UserService.USERS_INSTITUTION_AS_DEFAULT) final Long institutionId,
|
||||
@RequestParam(name = UserActivityLog.FILTER_ATTR_FROM, required = false) final String from,
|
||||
@RequestParam(name = UserActivityLog.FILTER_ATTR_TO, required = false) final String to,
|
||||
@RequestParam(name = UserActivityLog.FILTER_ATTR_ACTIVITY_TYPES,
|
||||
required = false) final String activityTypes,
|
||||
@RequestParam(name = UserActivityLog.FILTER_ATTR_ENTITY_TYPES, required = false) final String entityTypes,
|
||||
@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) {
|
||||
|
||||
checkBaseReadPrivilege();
|
||||
checkBaseReadPrivilege(institutionId);
|
||||
return this.paginationService.getPage(
|
||||
pageNumber,
|
||||
pageSize,
|
||||
sortBy,
|
||||
sortOrder,
|
||||
UserRecordDynamicSqlSupport.userRecord,
|
||||
() -> _getAll(userId, from, to, activityTypes, entityTypes));
|
||||
}
|
||||
|
||||
private void checkBaseReadPrivilege() {
|
||||
this.authorizationGrantService.checkHasAnyPrivilege(
|
||||
EntityType.USER_ACTIVITY_LOG,
|
||||
PrivilegeType.READ_ONLY);
|
||||
() -> _getAll(institutionId, userId, from, to, activityTypes, entityTypes));
|
||||
}
|
||||
|
||||
private Collection<UserActivityLog> _getAll(
|
||||
final Long institutionId,
|
||||
final String userId,
|
||||
final Long from,
|
||||
final Long to,
|
||||
final String from,
|
||||
final String to,
|
||||
final String activityTypes,
|
||||
final String entityTypes) {
|
||||
|
||||
|
@ -142,24 +177,32 @@ public class UserActivityLogController {
|
|||
Arrays.asList(StringUtils.split(entityTypes, Constants.LIST_SEPARATOR))))
|
||||
: null;
|
||||
|
||||
if (_activityTypes != null || _entityTypes != null) {
|
||||
final Predicate<UserActivityLogRecord> filter = (_activityTypes != null || _entityTypes != null)
|
||||
? record -> {
|
||||
if (_activityTypes != null && !_activityTypes.contains(record.getActivityType())) {
|
||||
return false;
|
||||
}
|
||||
if (_entityTypes != null && !_entityTypes.contains(record.getEntityType())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.userActivityLogDAO.all(userId, from, to, record -> {
|
||||
if (_activityTypes != null && !_activityTypes.contains(record.getActivityType())) {
|
||||
return false;
|
||||
}
|
||||
if (_entityTypes != null && !_entityTypes.contains(record.getEntityType())) {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
: record -> true;
|
||||
|
||||
return true;
|
||||
}).getOrThrow();
|
||||
return this.userActivityLogDAO.all(
|
||||
institutionId,
|
||||
userId,
|
||||
Utils.toMilliSeconds(from),
|
||||
Utils.toMilliSeconds(to),
|
||||
filter).getOrThrow();
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
return this.userActivityLogDAO.all(userId, from, to, record -> true)
|
||||
.getOrThrow();
|
||||
}
|
||||
private void checkBaseReadPrivilege(final Long institutionId) {
|
||||
this.authorizationGrantService.checkPrivilege(
|
||||
EntityType.USER_ACTIVITY_LOG,
|
||||
PrivilegeType.READ_ONLY,
|
||||
institutionId);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -99,4 +99,12 @@ public abstract class AdministrationAPIIntegrationTest {
|
|||
return obtainAccessToken("examAdmin1", "admin");
|
||||
}
|
||||
|
||||
// protected static class TestHelper {
|
||||
//
|
||||
// private Supplier<String> accessTokenSuplier;
|
||||
// private String query;
|
||||
// private String endpoint;
|
||||
// private Object
|
||||
// }
|
||||
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ import java.util.NoSuchElementException;
|
|||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.DateTimeZone;
|
||||
import org.junit.Test;
|
||||
import org.springframework.http.MediaType;
|
||||
|
@ -28,7 +29,10 @@ import org.springframework.test.context.jdbc.Sql;
|
|||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||
import ch.ethz.seb.sebserver.gbl.model.APIMessage;
|
||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||
import ch.ethz.seb.sebserver.gbl.model.EntityProcessingReport;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Page;
|
||||
import ch.ethz.seb.sebserver.gbl.model.user.UserActivityLog;
|
||||
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
|
||||
|
@ -113,6 +117,15 @@ public class UserAPITest extends AdministrationAPIIntegrationTest {
|
|||
contentAsString);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void institutionalAdminNotAllowedToSeeUsersOfOtherInstitution() throws Exception {
|
||||
final String token = getAdminInstitution1Access();
|
||||
this.mockMvc.perform(get(this.endpoint + RestAPI.ENDPOINT_USER_ACCOUNT + "?institution=2")
|
||||
.header("Authorization", "Bearer " + token))
|
||||
.andExpect(status().isForbidden())
|
||||
.andReturn().getResponse().getContentAsString();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAllUserInfoNoFilter() throws Exception {
|
||||
String token = getSebAdminAccess();
|
||||
|
@ -126,34 +139,65 @@ public class UserAPITest extends AdministrationAPIIntegrationTest {
|
|||
|
||||
// expecting all users for a SEBAdmin except inactive.
|
||||
assertNotNull(userInfos);
|
||||
assertTrue(userInfos.size() == 7);
|
||||
assertTrue(userInfos.size() == 3);
|
||||
assertNotNull(getUserInfo("admin", userInfos));
|
||||
assertNotNull(getUserInfo("inst1Admin", userInfos));
|
||||
assertNotNull(getUserInfo("examSupporter", userInfos));
|
||||
assertNotNull(getUserInfo("inst2Admin", userInfos));
|
||||
assertNotNull(getUserInfo("examAdmin1", userInfos));
|
||||
assertNotNull(getUserInfo("user1", userInfos));
|
||||
assertNotNull(getUserInfo("deactivatedUser", userInfos));
|
||||
|
||||
token = getAdminInstitution1Access();
|
||||
token = getAdminInstitution2Access();
|
||||
userInfos = this.jsonMapper.readValue(
|
||||
this.mockMvc.perform(get(this.endpoint + RestAPI.ENDPOINT_USER_ACCOUNT)
|
||||
this.mockMvc.perform(get(this.endpoint + RestAPI.ENDPOINT_USER_ACCOUNT + "?institution=2")
|
||||
.header("Authorization", "Bearer " + token))
|
||||
.andExpect(status().isOk())
|
||||
.andReturn().getResponse().getContentAsString(),
|
||||
new TypeReference<List<UserInfo>>() {
|
||||
});
|
||||
|
||||
// expecting all users of institution 2 also inactive when active flag is not set
|
||||
assertNotNull(userInfos);
|
||||
assertTrue(userInfos.size() == 4);
|
||||
assertNotNull(getUserInfo("inst2Admin", userInfos));
|
||||
assertNotNull(getUserInfo("examAdmin1", userInfos));
|
||||
assertNotNull(getUserInfo("deactivatedUser", userInfos));
|
||||
assertNotNull(getUserInfo("user1", userInfos));
|
||||
|
||||
//.. and without inactive, if active flag is set to true
|
||||
token = getAdminInstitution2Access();
|
||||
userInfos = this.jsonMapper.readValue(
|
||||
this.mockMvc.perform(get(this.endpoint + RestAPI.ENDPOINT_USER_ACCOUNT + "?institution=2&active=true")
|
||||
.header("Authorization", "Bearer " + token))
|
||||
.andExpect(status().isOk())
|
||||
.andReturn().getResponse().getContentAsString(),
|
||||
new TypeReference<List<UserInfo>>() {
|
||||
});
|
||||
|
||||
// expecting all users of institution 1 for Institutional Admin of institution 1
|
||||
assertNotNull(userInfos);
|
||||
assertTrue(userInfos.size() == 3);
|
||||
assertNotNull(getUserInfo("admin", userInfos));
|
||||
assertNotNull(getUserInfo("inst1Admin", userInfos));
|
||||
assertNotNull(getUserInfo("examSupporter", userInfos));
|
||||
assertNotNull(getUserInfo("inst2Admin", userInfos));
|
||||
assertNotNull(getUserInfo("examAdmin1", userInfos));
|
||||
assertNotNull(getUserInfo("user1", userInfos));
|
||||
|
||||
//.. and only inactive, if active flag is set to false
|
||||
token = getAdminInstitution2Access();
|
||||
userInfos = this.jsonMapper.readValue(
|
||||
this.mockMvc.perform(get(this.endpoint + RestAPI.ENDPOINT_USER_ACCOUNT + "?institution=2&active=false")
|
||||
.header("Authorization", "Bearer " + token))
|
||||
.andExpect(status().isOk())
|
||||
.andReturn().getResponse().getContentAsString(),
|
||||
new TypeReference<List<UserInfo>>() {
|
||||
});
|
||||
|
||||
assertNotNull(userInfos);
|
||||
assertTrue(userInfos.size() == 1);
|
||||
assertNotNull(getUserInfo("deactivatedUser", userInfos));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getPageNoFilterNoPageAttributes() throws Exception {
|
||||
|
||||
// expecting all user accounts of the institution of SEBAdmin
|
||||
|
||||
final String token = getSebAdminAccess();
|
||||
final Page<UserInfo> userInfos = this.jsonMapper.readValue(
|
||||
this.mockMvc.perform(get(this.endpoint + RestAPI.ENDPOINT_USER_ACCOUNT + "/page")
|
||||
|
@ -166,15 +210,18 @@ public class UserAPITest extends AdministrationAPIIntegrationTest {
|
|||
assertNotNull(userInfos);
|
||||
assertTrue(userInfos.numberOfPages == 1);
|
||||
assertNotNull(userInfos.content);
|
||||
assertTrue(userInfos.content.size() == 7);
|
||||
assertEquals("[user1, user2, user3, user4, user5, user6, user7]", getOrderedUUIDs(userInfos.content));
|
||||
assertTrue(userInfos.content.size() == 3);
|
||||
assertEquals("[user1, user2, user5]", getOrderedUUIDs(userInfos.content));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getPageNoFilterNoPageAttributesDescendingOrder() throws Exception {
|
||||
public void getPageNoFilterNoPageAttributesFromOtherInstitution() throws Exception {
|
||||
|
||||
// expecting all user accounts of institution 2
|
||||
|
||||
final String token = getSebAdminAccess();
|
||||
final Page<UserInfo> userInfos = this.jsonMapper.readValue(
|
||||
this.mockMvc.perform(get(this.endpoint + RestAPI.ENDPOINT_USER_ACCOUNT + "/page?sortOrder=DESCENDING")
|
||||
this.mockMvc.perform(get(this.endpoint + RestAPI.ENDPOINT_USER_ACCOUNT + "/page?institution=2")
|
||||
.header("Authorization", "Bearer " + token))
|
||||
.andExpect(status().isOk())
|
||||
.andReturn().getResponse().getContentAsString(),
|
||||
|
@ -184,8 +231,26 @@ public class UserAPITest extends AdministrationAPIIntegrationTest {
|
|||
assertNotNull(userInfos);
|
||||
assertTrue(userInfos.numberOfPages == 1);
|
||||
assertNotNull(userInfos.content);
|
||||
assertTrue(userInfos.content.size() == 7);
|
||||
assertEquals("[user7, user6, user5, user4, user3, user2, user1]", getOrderedUUIDs(userInfos.content));
|
||||
assertTrue(userInfos.content.size() == 4);
|
||||
assertEquals("[user3, user4, user6, user7]", getOrderedUUIDs(userInfos.content));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getPageNoFilterNoPageAttributesDescendingOrder() throws Exception {
|
||||
final String token = getSebAdminAccess();
|
||||
final Page<UserInfo> userInfos = this.jsonMapper.readValue(
|
||||
this.mockMvc.perform(get(this.endpoint + RestAPI.ENDPOINT_USER_ACCOUNT + "/page?sort_order=DESCENDING")
|
||||
.header("Authorization", "Bearer " + token))
|
||||
.andExpect(status().isOk())
|
||||
.andReturn().getResponse().getContentAsString(),
|
||||
new TypeReference<Page<UserInfo>>() {
|
||||
});
|
||||
|
||||
assertNotNull(userInfos);
|
||||
assertTrue(userInfos.numberOfPages == 1);
|
||||
assertNotNull(userInfos.content);
|
||||
assertTrue(userInfos.content.size() == 3);
|
||||
assertEquals("[user5, user2, user1]", getOrderedUUIDs(userInfos.content));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -195,24 +260,25 @@ public class UserAPITest extends AdministrationAPIIntegrationTest {
|
|||
// first page default sort order
|
||||
Page<UserInfo> userInfos = this.jsonMapper.readValue(
|
||||
this.mockMvc
|
||||
.perform(get(this.endpoint + RestAPI.ENDPOINT_USER_ACCOUNT + "/page?pageNumber=1&pageSize=3")
|
||||
.header("Authorization", "Bearer " + token))
|
||||
.perform(get(this.endpoint + RestAPI.ENDPOINT_USER_ACCOUNT
|
||||
+ "/page?page_number=1&page_size=3&institution=2")
|
||||
.header("Authorization", "Bearer " + token))
|
||||
.andExpect(status().isOk())
|
||||
.andReturn().getResponse().getContentAsString(),
|
||||
new TypeReference<Page<UserInfo>>() {
|
||||
});
|
||||
|
||||
assertNotNull(userInfos);
|
||||
assertTrue(userInfos.numberOfPages == 3);
|
||||
assertTrue(userInfos.numberOfPages == 2);
|
||||
assertNotNull(userInfos.content);
|
||||
assertTrue(userInfos.content.size() == 3);
|
||||
assertEquals("[user1, user2, user3]", getOrderedUUIDs(userInfos.content));
|
||||
assertEquals("[user3, user4, user6]", getOrderedUUIDs(userInfos.content));
|
||||
|
||||
// second page default sort order
|
||||
userInfos = this.jsonMapper.readValue(
|
||||
this.mockMvc
|
||||
.perform(get(this.endpoint + RestAPI.ENDPOINT_USER_ACCOUNT
|
||||
+ "/page?pageNumber=2&pageSize=3")
|
||||
+ "/page?page_number=2&page_size=3&institution=2")
|
||||
.header("Authorization", "Bearer " + token))
|
||||
.andExpect(status().isOk())
|
||||
.andReturn().getResponse().getContentAsString(),
|
||||
|
@ -220,16 +286,17 @@ public class UserAPITest extends AdministrationAPIIntegrationTest {
|
|||
});
|
||||
|
||||
assertNotNull(userInfos);
|
||||
assertTrue(userInfos.numberOfPages == 3);
|
||||
assertTrue(userInfos.numberOfPages == 2);
|
||||
assertNotNull(userInfos.content);
|
||||
assertTrue(userInfos.content.size() == 3);
|
||||
assertEquals("[user4, user5, user6]", getOrderedUUIDs(userInfos.content));
|
||||
assertTrue(userInfos.pageSize == 1);
|
||||
assertTrue(userInfos.content.size() == 1);
|
||||
assertEquals("[user7]", getOrderedUUIDs(userInfos.content));
|
||||
|
||||
// third page default sort order
|
||||
// invalid page number should refer to last page
|
||||
userInfos = this.jsonMapper.readValue(
|
||||
this.mockMvc
|
||||
.perform(get(this.endpoint + RestAPI.ENDPOINT_USER_ACCOUNT
|
||||
+ "/page?pageNumber=3&pageSize=3")
|
||||
+ "/page?page_number=3&page_size=3&institution=2")
|
||||
.header("Authorization", "Bearer " + token))
|
||||
.andExpect(status().isOk())
|
||||
.andReturn().getResponse().getContentAsString(),
|
||||
|
@ -237,7 +304,8 @@ public class UserAPITest extends AdministrationAPIIntegrationTest {
|
|||
});
|
||||
|
||||
assertNotNull(userInfos);
|
||||
assertTrue(userInfos.numberOfPages == 3);
|
||||
assertTrue(userInfos.numberOfPages == 2);
|
||||
assertTrue(userInfos.pageNumber == 2);
|
||||
assertNotNull(userInfos.content);
|
||||
assertTrue(userInfos.content.size() == 1);
|
||||
assertEquals("[user7]", getOrderedUUIDs(userInfos.content));
|
||||
|
@ -246,7 +314,7 @@ public class UserAPITest extends AdministrationAPIIntegrationTest {
|
|||
userInfos = this.jsonMapper.readValue(
|
||||
this.mockMvc
|
||||
.perform(get(this.endpoint + RestAPI.ENDPOINT_USER_ACCOUNT
|
||||
+ "/page?pageNumber=1&pageSize=3&sortOrder=DESCENDING")
|
||||
+ "/page?page_number=1&page_size=3&sort_order=DESCENDING&institution=2")
|
||||
.header("Authorization", "Bearer " + token))
|
||||
.andExpect(status().isOk())
|
||||
.andReturn().getResponse().getContentAsString(),
|
||||
|
@ -254,10 +322,10 @@ public class UserAPITest extends AdministrationAPIIntegrationTest {
|
|||
});
|
||||
|
||||
assertNotNull(userInfos);
|
||||
assertTrue(userInfos.numberOfPages == 3);
|
||||
assertTrue(userInfos.numberOfPages == 2);
|
||||
assertNotNull(userInfos.content);
|
||||
assertTrue(userInfos.content.size() == 3);
|
||||
assertEquals("[user7, user6, user5]", getOrderedUUIDs(userInfos.content));
|
||||
assertEquals("[user7, user6, user4]", getOrderedUUIDs(userInfos.content));
|
||||
}
|
||||
|
||||
private String getOrderedUUIDs(final Collection<UserInfo> list) {
|
||||
|
@ -280,15 +348,14 @@ public class UserAPITest extends AdministrationAPIIntegrationTest {
|
|||
});
|
||||
|
||||
assertNotNull(userInfos);
|
||||
assertTrue(userInfos.size() == 7);
|
||||
assertNotNull(getUserInfo("deactivatedUser", userInfos));
|
||||
assertTrue(userInfos.size() == 3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAllUserInfoWithOnlyActice() throws Exception {
|
||||
public void getAllUserInfoWithOnlyActive() throws Exception {
|
||||
final String token = getSebAdminAccess();
|
||||
final List<UserInfo> userInfos = this.jsonMapper.readValue(
|
||||
this.mockMvc.perform(get(this.endpoint + RestAPI.ENDPOINT_USER_ACCOUNT + "?active=true")
|
||||
this.mockMvc.perform(get(this.endpoint + RestAPI.ENDPOINT_USER_ACCOUNT + "?active=true&institution=2")
|
||||
.header("Authorization", "Bearer " + token))
|
||||
.andExpect(status().isOk())
|
||||
.andReturn().getResponse().getContentAsString(),
|
||||
|
@ -296,14 +363,16 @@ public class UserAPITest extends AdministrationAPIIntegrationTest {
|
|||
});
|
||||
|
||||
assertNotNull(userInfos);
|
||||
assertTrue(userInfos.size() == 6);
|
||||
assertTrue(userInfos.size() == 3);
|
||||
assertNull(getUserInfo("deactivatedUser", userInfos));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAllUserInfoOnlyInactive() throws Exception {
|
||||
|
||||
// expecting none for SEBAdmins institution
|
||||
final String token = getSebAdminAccess();
|
||||
final List<UserInfo> userInfos = this.jsonMapper.readValue(
|
||||
List<UserInfo> userInfos = this.jsonMapper.readValue(
|
||||
this.mockMvc.perform(get(this.endpoint + RestAPI.ENDPOINT_USER_ACCOUNT + "?active=false")
|
||||
.header("Authorization", "Bearer " + token))
|
||||
.andExpect(status().isOk())
|
||||
|
@ -311,6 +380,18 @@ public class UserAPITest extends AdministrationAPIIntegrationTest {
|
|||
new TypeReference<List<UserInfo>>() {
|
||||
});
|
||||
|
||||
assertNotNull(userInfos);
|
||||
assertTrue(userInfos.size() == 0);
|
||||
|
||||
// expecting one for institution 2
|
||||
userInfos = this.jsonMapper.readValue(
|
||||
this.mockMvc.perform(get(this.endpoint + RestAPI.ENDPOINT_USER_ACCOUNT + "?active=false&institution=2")
|
||||
.header("Authorization", "Bearer " + token))
|
||||
.andExpect(status().isOk())
|
||||
.andReturn().getResponse().getContentAsString(),
|
||||
new TypeReference<List<UserInfo>>() {
|
||||
});
|
||||
|
||||
assertNotNull(userInfos);
|
||||
assertTrue(userInfos.size() == 1);
|
||||
assertNotNull(getUserInfo("deactivatedUser", userInfos));
|
||||
|
@ -328,8 +409,7 @@ public class UserAPITest extends AdministrationAPIIntegrationTest {
|
|||
});
|
||||
|
||||
assertNotNull(userInfos);
|
||||
assertTrue(userInfos.size() == 2);
|
||||
assertNotNull(getUserInfo("examAdmin1", userInfos));
|
||||
assertTrue(userInfos.size() == 1);
|
||||
assertNotNull(getUserInfo("examSupporter", userInfos));
|
||||
}
|
||||
|
||||
|
@ -381,8 +461,9 @@ public class UserAPITest extends AdministrationAPIIntegrationTest {
|
|||
// check user activity log for newly created user
|
||||
final List<UserActivityLog> logs = this.jsonMapper.readValue(
|
||||
this.mockMvc
|
||||
.perform(get(this.endpoint + RestAPI.ENDPOINT_USER_ACTIVITY_LOG + "/user1?activityTypes=CREATE")
|
||||
.header("Authorization", "Bearer " + token))
|
||||
.perform(
|
||||
get(this.endpoint + RestAPI.ENDPOINT_USER_ACTIVITY_LOG + "/user1?activity_types=CREATE")
|
||||
.header("Authorization", "Bearer " + token))
|
||||
.andExpect(status().isOk())
|
||||
.andReturn().getResponse().getContentAsString(),
|
||||
new TypeReference<List<UserActivityLog>>() {
|
||||
|
@ -700,7 +781,7 @@ public class UserAPITest extends AdministrationAPIIntegrationTest {
|
|||
|
||||
@Test
|
||||
public void deactivateUserAccount() throws Exception {
|
||||
final long timeNow = System.currentTimeMillis();
|
||||
final String timeNow = DateTime.now(DateTimeZone.UTC).toString(Constants.DATE_TIME_PATTERN_UTC_NO_MILLIS);
|
||||
// only a SEB Administrator or an Institutional administrator should be able to deactivate a user-account
|
||||
final String examAdminToken = getExamAdmin1();
|
||||
this.mockMvc.perform(post(this.endpoint + RestAPI.ENDPOINT_USER_ACCOUNT + "/user4/deactivate")
|
||||
|
@ -709,16 +790,32 @@ public class UserAPITest extends AdministrationAPIIntegrationTest {
|
|||
|
||||
// With SEB Administrator it should work
|
||||
final String sebAdminToken = getSebAdminAccess();
|
||||
final UserInfo deactivatedUser = this.jsonMapper.readValue(
|
||||
final EntityProcessingReport report = this.jsonMapper.readValue(
|
||||
this.mockMvc.perform(post(this.endpoint + RestAPI.ENDPOINT_USER_ACCOUNT + "/user4/deactivate")
|
||||
.header("Authorization", "Bearer " + sebAdminToken))
|
||||
.andExpect(status().isOk())
|
||||
.andReturn().getResponse().getContentAsString(),
|
||||
new TypeReference<EntityProcessingReport>() {
|
||||
});
|
||||
|
||||
assertNotNull(report);
|
||||
assertNotNull(report.source);
|
||||
assertTrue(report.dependencies.isEmpty()); // TODO
|
||||
assertTrue(report.errors.isEmpty());
|
||||
assertTrue(report.source.size() == 1);
|
||||
|
||||
// get user and check activity
|
||||
final EntityKey key = report.source.iterator().next();
|
||||
final UserInfo user = this.jsonMapper.readValue(
|
||||
this.mockMvc.perform(get(this.endpoint + RestAPI.ENDPOINT_USER_ACCOUNT + "/" + key.modelId)
|
||||
.header("Authorization", "Bearer " + sebAdminToken))
|
||||
.andExpect(status().isOk())
|
||||
.andReturn().getResponse().getContentAsString(),
|
||||
new TypeReference<UserInfo>() {
|
||||
});
|
||||
|
||||
assertNotNull(deactivatedUser);
|
||||
assertFalse(deactivatedUser.isActive());
|
||||
assertNotNull(user);
|
||||
assertFalse(user.isActive());
|
||||
|
||||
// check also user activity log
|
||||
final Collection<UserActivityLog> userLogs = this.jsonMapper.readValue(
|
||||
|
@ -738,7 +835,7 @@ public class UserAPITest extends AdministrationAPIIntegrationTest {
|
|||
|
||||
@Test
|
||||
public void activateUserAccount() throws Exception {
|
||||
final long timeNow = System.currentTimeMillis();
|
||||
final String timeNow = DateTime.now(DateTimeZone.UTC).toString(Constants.DATE_TIME_PATTERN_UTC_NO_MILLIS);
|
||||
// only a SEB Administrator or an Institutional administrator should be able to deactivate a user-account
|
||||
final String examAdminToken = getExamAdmin1();
|
||||
this.mockMvc.perform(post(this.endpoint + RestAPI.ENDPOINT_USER_ACCOUNT + "/user6/activate")
|
||||
|
@ -747,16 +844,32 @@ public class UserAPITest extends AdministrationAPIIntegrationTest {
|
|||
|
||||
// With SEB Administrator it should work
|
||||
final String sebAdminToken = getSebAdminAccess();
|
||||
final UserInfo activatedUser = this.jsonMapper.readValue(
|
||||
final EntityProcessingReport report = this.jsonMapper.readValue(
|
||||
this.mockMvc.perform(post(this.endpoint + RestAPI.ENDPOINT_USER_ACCOUNT + "/user6/activate")
|
||||
.header("Authorization", "Bearer " + sebAdminToken))
|
||||
.andExpect(status().isOk())
|
||||
.andReturn().getResponse().getContentAsString(),
|
||||
new TypeReference<EntityProcessingReport>() {
|
||||
});
|
||||
|
||||
assertNotNull(report);
|
||||
assertNotNull(report.source);
|
||||
assertTrue(report.dependencies.isEmpty()); // TODO
|
||||
assertTrue(report.errors.isEmpty());
|
||||
assertTrue(report.source.size() == 1);
|
||||
|
||||
// get user and check activity
|
||||
final EntityKey key = report.source.iterator().next();
|
||||
final UserInfo user = this.jsonMapper.readValue(
|
||||
this.mockMvc.perform(get(this.endpoint + RestAPI.ENDPOINT_USER_ACCOUNT + "/" + key.modelId)
|
||||
.header("Authorization", "Bearer " + sebAdminToken))
|
||||
.andExpect(status().isOk())
|
||||
.andReturn().getResponse().getContentAsString(),
|
||||
new TypeReference<UserInfo>() {
|
||||
});
|
||||
|
||||
assertNotNull(activatedUser);
|
||||
assertTrue(activatedUser.isActive());
|
||||
assertNotNull(user);
|
||||
assertTrue(user.isActive());
|
||||
|
||||
// check also user activity log
|
||||
final Collection<UserActivityLog> userLogs = this.jsonMapper.readValue(
|
||||
|
|
|
@ -8,18 +8,19 @@
|
|||
|
||||
package ch.ethz.seb.sebserver.webservice.integration.api;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.Test;
|
||||
import org.springframework.test.context.jdbc.Sql;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||
import ch.ethz.seb.sebserver.gbl.model.user.UserActivityLog;
|
||||
import ch.ethz.seb.sebserver.webservice.weblayer.api.RestAPI;
|
||||
|
||||
|
@ -38,14 +39,15 @@ public class UserActivityLogAPITest extends AdministrationAPIIntegrationTest {
|
|||
});
|
||||
|
||||
assertNotNull(logs);
|
||||
assertTrue(5 == logs.size());
|
||||
assertTrue(2 == logs.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAllAsSEBAdminForUser() throws Exception {
|
||||
final String token = getSebAdminAccess();
|
||||
// for a user in another institution, the institution has to be defined
|
||||
List<UserActivityLog> logs = this.jsonMapper.readValue(
|
||||
this.mockMvc.perform(get(this.endpoint + RestAPI.ENDPOINT_USER_ACTIVITY_LOG + "/user4")
|
||||
this.mockMvc.perform(get(this.endpoint + RestAPI.ENDPOINT_USER_ACTIVITY_LOG + "/user4?institution=2")
|
||||
.header("Authorization", "Bearer " + token))
|
||||
.andExpect(status().isOk())
|
||||
.andReturn().getResponse().getContentAsString(),
|
||||
|
@ -55,6 +57,7 @@ public class UserActivityLogAPITest extends AdministrationAPIIntegrationTest {
|
|||
assertNotNull(logs);
|
||||
assertTrue(2 == logs.size());
|
||||
|
||||
// for a user in the same institution no institution is needed
|
||||
logs = this.jsonMapper.readValue(
|
||||
this.mockMvc.perform(get(this.endpoint + RestAPI.ENDPOINT_USER_ACTIVITY_LOG + "/user2")
|
||||
.header("Authorization", "Bearer " + token))
|
||||
|
@ -69,47 +72,18 @@ public class UserActivityLogAPITest extends AdministrationAPIIntegrationTest {
|
|||
|
||||
@Test
|
||||
public void getAllAsSEBAdminInTimeRange() throws Exception {
|
||||
final DateTime zeroDate = DateTime.parse("1970-01-01 00:00:00", Constants.DATE_TIME_PATTERN_UTC_NO_MILLIS);
|
||||
assertEquals("0", String.valueOf(zeroDate.getMillis()));
|
||||
final String sec2 = zeroDate.plus(1000).toString(Constants.DATE_TIME_PATTERN_UTC_NO_MILLIS);
|
||||
final String sec4 = zeroDate.plus(4000).toString(Constants.DATE_TIME_PATTERN_UTC_NO_MILLIS);
|
||||
final String sec5 = zeroDate.plus(5000).toString(Constants.DATE_TIME_PATTERN_UTC_NO_MILLIS);
|
||||
final String sec6 = zeroDate.plus(6000).toString(Constants.DATE_TIME_PATTERN_UTC_NO_MILLIS);
|
||||
|
||||
final String token = getSebAdminAccess();
|
||||
List<UserActivityLog> logs = this.jsonMapper.readValue(
|
||||
this.mockMvc.perform(get(this.endpoint + RestAPI.ENDPOINT_USER_ACTIVITY_LOG + "?from=2")
|
||||
.header("Authorization", "Bearer " + token))
|
||||
.andExpect(status().isOk())
|
||||
.andReturn().getResponse().getContentAsString(),
|
||||
new TypeReference<List<UserActivityLog>>() {
|
||||
});
|
||||
|
||||
assertNotNull(logs);
|
||||
assertTrue(4 == logs.size());
|
||||
|
||||
logs = this.jsonMapper.readValue(
|
||||
this.mockMvc.perform(get(this.endpoint + RestAPI.ENDPOINT_USER_ACTIVITY_LOG + "?from=2&to=3")
|
||||
.header("Authorization", "Bearer " + token))
|
||||
.andExpect(status().isOk())
|
||||
.andReturn().getResponse().getContentAsString(),
|
||||
new TypeReference<List<UserActivityLog>>() {
|
||||
});
|
||||
|
||||
assertNotNull(logs);
|
||||
assertTrue(1 == logs.size());
|
||||
|
||||
logs = this.jsonMapper.readValue(
|
||||
this.mockMvc.perform(get(this.endpoint + RestAPI.ENDPOINT_USER_ACTIVITY_LOG + "?from=2&to=4")
|
||||
.header("Authorization", "Bearer " + token))
|
||||
.andExpect(status().isOk())
|
||||
.andReturn().getResponse().getContentAsString(),
|
||||
new TypeReference<List<UserActivityLog>>() {
|
||||
});
|
||||
|
||||
assertNotNull(logs);
|
||||
assertTrue(2 == logs.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAllAsSEBAdminForActivityType() throws Exception {
|
||||
final String token = getSebAdminAccess();
|
||||
List<UserActivityLog> logs = this.jsonMapper.readValue(
|
||||
this.mockMvc.perform(get(this.endpoint + RestAPI.ENDPOINT_USER_ACTIVITY_LOG + "?activityTypes=CREATE")
|
||||
.header("Authorization", "Bearer " + token))
|
||||
this.mockMvc.perform(
|
||||
get(this.endpoint + RestAPI.ENDPOINT_USER_ACTIVITY_LOG + "?institution=2&from=" + sec2)
|
||||
.header("Authorization", "Bearer " + token))
|
||||
.andExpect(status().isOk())
|
||||
.andReturn().getResponse().getContentAsString(),
|
||||
new TypeReference<List<UserActivityLog>>() {
|
||||
|
@ -120,8 +94,8 @@ public class UserActivityLogAPITest extends AdministrationAPIIntegrationTest {
|
|||
|
||||
logs = this.jsonMapper.readValue(
|
||||
this.mockMvc
|
||||
.perform(
|
||||
get(this.endpoint + RestAPI.ENDPOINT_USER_ACTIVITY_LOG + "?activityTypes=CREATE,MODIFY")
|
||||
.perform(get(this.endpoint + RestAPI.ENDPOINT_USER_ACTIVITY_LOG + "?institution=2&from="
|
||||
+ sec2 + "&to=" + sec4)
|
||||
.header("Authorization", "Bearer " + token))
|
||||
.andExpect(status().isOk())
|
||||
.andReturn().getResponse().getContentAsString(),
|
||||
|
@ -129,7 +103,77 @@ public class UserActivityLogAPITest extends AdministrationAPIIntegrationTest {
|
|||
});
|
||||
|
||||
assertNotNull(logs);
|
||||
assertTrue(5 == logs.size());
|
||||
assertTrue(1 == logs.size());
|
||||
|
||||
logs = this.jsonMapper.readValue(
|
||||
this.mockMvc
|
||||
.perform(get(this.endpoint + RestAPI.ENDPOINT_USER_ACTIVITY_LOG + "?institution=2&from=" + sec2
|
||||
+ "&to=" + sec5)
|
||||
.header("Authorization", "Bearer " + token))
|
||||
.andExpect(status().isOk())
|
||||
.andReturn().getResponse().getContentAsString(),
|
||||
new TypeReference<List<UserActivityLog>>() {
|
||||
});
|
||||
|
||||
assertNotNull(logs);
|
||||
assertTrue(2 == logs.size());
|
||||
|
||||
logs = this.jsonMapper.readValue(
|
||||
this.mockMvc
|
||||
.perform(get(this.endpoint + RestAPI.ENDPOINT_USER_ACTIVITY_LOG + "?institution=2&from=" + sec2
|
||||
+ "&to=" + sec6)
|
||||
.header("Authorization", "Bearer " + token))
|
||||
.andExpect(status().isOk())
|
||||
.andReturn().getResponse().getContentAsString(),
|
||||
new TypeReference<List<UserActivityLog>>() {
|
||||
});
|
||||
|
||||
assertNotNull(logs);
|
||||
assertTrue(3 == logs.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAllAsSEBAdminForActivityType() throws Exception {
|
||||
final String token = getSebAdminAccess();
|
||||
List<UserActivityLog> logs = this.jsonMapper.readValue(
|
||||
this.mockMvc.perform(get(this.endpoint + RestAPI.ENDPOINT_USER_ACTIVITY_LOG + "?activity_types=CREATE")
|
||||
.header("Authorization", "Bearer " + token))
|
||||
.andExpect(status().isOk())
|
||||
.andReturn().getResponse().getContentAsString(),
|
||||
new TypeReference<List<UserActivityLog>>() {
|
||||
});
|
||||
|
||||
assertNotNull(logs);
|
||||
assertTrue(1 == logs.size());
|
||||
|
||||
logs = this.jsonMapper.readValue(
|
||||
this.mockMvc
|
||||
.perform(
|
||||
get(this.endpoint + RestAPI.ENDPOINT_USER_ACTIVITY_LOG
|
||||
+ "?activity_types=CREATE,MODIFY")
|
||||
.header("Authorization", "Bearer " + token))
|
||||
.andExpect(status().isOk())
|
||||
.andReturn().getResponse().getContentAsString(),
|
||||
new TypeReference<List<UserActivityLog>>() {
|
||||
});
|
||||
|
||||
assertNotNull(logs);
|
||||
assertTrue(2 == logs.size());
|
||||
|
||||
// for other institution (2)
|
||||
logs = this.jsonMapper.readValue(
|
||||
this.mockMvc
|
||||
.perform(
|
||||
get(this.endpoint + RestAPI.ENDPOINT_USER_ACTIVITY_LOG
|
||||
+ "?institution=2&activity_types=CREATE,MODIFY")
|
||||
.header("Authorization", "Bearer " + token))
|
||||
.andExpect(status().isOk())
|
||||
.andReturn().getResponse().getContentAsString(),
|
||||
new TypeReference<List<UserActivityLog>>() {
|
||||
});
|
||||
|
||||
assertNotNull(logs);
|
||||
assertTrue(3 == logs.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -137,7 +181,7 @@ public class UserActivityLogAPITest extends AdministrationAPIIntegrationTest {
|
|||
final String token = getSebAdminAccess();
|
||||
List<UserActivityLog> logs = this.jsonMapper.readValue(
|
||||
this.mockMvc
|
||||
.perform(get(this.endpoint + RestAPI.ENDPOINT_USER_ACTIVITY_LOG + "?entityTypes=INSTITUTION")
|
||||
.perform(get(this.endpoint + RestAPI.ENDPOINT_USER_ACTIVITY_LOG + "?entity_types=INSTITUTION")
|
||||
.header("Authorization", "Bearer " + token))
|
||||
.andExpect(status().isOk())
|
||||
.andReturn().getResponse().getContentAsString(),
|
||||
|
@ -151,7 +195,7 @@ public class UserActivityLogAPITest extends AdministrationAPIIntegrationTest {
|
|||
this.mockMvc
|
||||
.perform(
|
||||
get(this.endpoint + RestAPI.ENDPOINT_USER_ACTIVITY_LOG
|
||||
+ "?entityTypes=INSTITUTION,EXAM")
|
||||
+ "?entity_types=INSTITUTION,EXAM")
|
||||
.header("Authorization", "Bearer " + token))
|
||||
.andExpect(status().isOk())
|
||||
.andReturn().getResponse().getContentAsString(),
|
||||
|
@ -159,7 +203,21 @@ public class UserActivityLogAPITest extends AdministrationAPIIntegrationTest {
|
|||
});
|
||||
|
||||
assertNotNull(logs);
|
||||
assertTrue(5 == logs.size());
|
||||
assertTrue(2 == logs.size());
|
||||
|
||||
logs = this.jsonMapper.readValue(
|
||||
this.mockMvc
|
||||
.perform(
|
||||
get(this.endpoint + RestAPI.ENDPOINT_USER_ACTIVITY_LOG
|
||||
+ "?entity_types=INSTITUTION,EXAM&institution=2")
|
||||
.header("Authorization", "Bearer " + token))
|
||||
.andExpect(status().isOk())
|
||||
.andReturn().getResponse().getContentAsString(),
|
||||
new TypeReference<List<UserActivityLog>>() {
|
||||
});
|
||||
|
||||
assertNotNull(logs);
|
||||
assertTrue(3 == logs.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -24,10 +24,10 @@ INSERT INTO user_role VALUES
|
|||
;
|
||||
|
||||
INSERT INTO user_activity_log VALUES
|
||||
(1, 'user1', 1, 'MODIFY', 'INSTITUTION', '1', 'some message'),
|
||||
(2, 'user2', 2, 'CREATE', 'EXAM', '1', 'some message'),
|
||||
(3, 'user3', 3, 'CREATE', 'EXAM', '2', 'some message'),
|
||||
(4, 'user4', 4, 'CREATE', 'EXAM', '33', 'some message'),
|
||||
(5, 'user4', 5, 'MODIFY', 'EXAM', '33', 'some message')
|
||||
(1, 'user1', 1000, 'MODIFY', 'INSTITUTION', '1', 'some message'),
|
||||
(2, 'user2', 2000, 'CREATE', 'EXAM', '1', 'some message'),
|
||||
(3, 'user3', 3000, 'CREATE', 'EXAM', '2', 'some message'),
|
||||
(4, 'user4', 4000, 'CREATE', 'EXAM', '33', 'some message'),
|
||||
(5, 'user4', 5000, 'MODIFY', 'EXAM', '33', 'some message')
|
||||
;
|
||||
|
||||
|
|
Loading…
Reference in a new issue