SEBSERV-8 #more fixes and tests
This commit is contained in:
parent
58881bf763
commit
02ca751748
17 changed files with 219 additions and 93 deletions
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gbl.model;
|
package ch.ethz.seb.sebserver.gbl.model;
|
||||||
|
|
||||||
public interface Entity {
|
public interface Entity extends ModelIdAware {
|
||||||
|
|
||||||
EntityType entityType();
|
EntityType entityType();
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,8 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserActivityLogDAO.Acti
|
||||||
|
|
||||||
public class UserActivityLog implements Entity {
|
public class UserActivityLog implements Entity {
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
public final Long id;
|
||||||
@JsonProperty("userId")
|
@JsonProperty("userId")
|
||||||
public final String userId;
|
public final String userId;
|
||||||
@JsonProperty("timestamp")
|
@JsonProperty("timestamp")
|
||||||
|
@ -31,13 +33,15 @@ public class UserActivityLog implements Entity {
|
||||||
public final String message;
|
public final String message;
|
||||||
|
|
||||||
public UserActivityLog(
|
public UserActivityLog(
|
||||||
@JsonProperty("userId") final String userId,
|
final Long id,
|
||||||
@JsonProperty("timestamp") final Long timestamp,
|
final String userId,
|
||||||
@JsonProperty("actionType") final ActionType actionType,
|
final Long timestamp,
|
||||||
@JsonProperty("entityType") final EntityType entityType,
|
final ActionType actionType,
|
||||||
@JsonProperty("entityId") final String entityId,
|
final EntityType entityType,
|
||||||
@JsonProperty("message") final String message) {
|
final String entityId,
|
||||||
|
final String message) {
|
||||||
|
|
||||||
|
this.id = id;
|
||||||
this.userId = userId;
|
this.userId = userId;
|
||||||
this.timestamp = timestamp;
|
this.timestamp = timestamp;
|
||||||
this.actionType = actionType;
|
this.actionType = actionType;
|
||||||
|
@ -52,6 +56,12 @@ public class UserActivityLog implements Entity {
|
||||||
return EntityType.USER_LOG;
|
return EntityType.USER_LOG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
@Override
|
||||||
|
public String getId() {
|
||||||
|
return String.valueOf(this.id);
|
||||||
|
}
|
||||||
|
|
||||||
public String getUserId() {
|
public String getUserId() {
|
||||||
return this.userId;
|
return this.userId;
|
||||||
}
|
}
|
||||||
|
@ -78,9 +88,10 @@ public class UserActivityLog implements Entity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "UserActivityLog [userId=" + this.userId + ", timestamp=" + this.timestamp + ", actionType="
|
return "UserActivityLog [id=" + this.id + ", userId=" + this.userId + ", timestamp=" + this.timestamp
|
||||||
+ this.actionType
|
+ ", actionType="
|
||||||
+ ", entityType=" + this.entityType + ", entityId=" + this.entityId + ", message=" + this.message + "]";
|
+ this.actionType + ", entityType=" + this.entityType + ", entityId=" + this.entityId + ", message="
|
||||||
|
+ this.message + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,6 @@ package ch.ethz.seb.sebserver.gbl.model.user;
|
||||||
|
|
||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
import org.apache.commons.lang3.BooleanUtils;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
import com.fasterxml.jackson.annotation.JsonInclude.Include;
|
import com.fasterxml.jackson.annotation.JsonInclude.Include;
|
||||||
|
@ -47,7 +45,7 @@ public final class UserFilter {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.userName = userName;
|
this.userName = userName;
|
||||||
this.email = email;
|
this.email = email;
|
||||||
this.active = BooleanUtils.isFalse(active);
|
this.active = (active != null) ? active : true;
|
||||||
this.locale = locale;
|
this.locale = locale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -118,6 +118,12 @@ public final class UserInfo implements GrantEntity, Serializable {
|
||||||
return EntityType.USER;
|
return EntityType.USER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
@Override
|
||||||
|
public String getId() {
|
||||||
|
return this.uuid;
|
||||||
|
}
|
||||||
|
|
||||||
public String getUuid() {
|
public String getUuid() {
|
||||||
return this.uuid;
|
return this.uuid;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,4 +22,9 @@ public enum UserRole implements Entity {
|
||||||
public EntityType entityType() {
|
public EntityType entityType() {
|
||||||
return EntityType.USER_ROLE;
|
return EntityType.USER_ROLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getId() {
|
||||||
|
return name();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,19 +21,30 @@ import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||||
* has write, modify or even read-only rights on an entity instance or on an entity type. */
|
* has write, modify or even read-only rights on an entity instance or on an entity type. */
|
||||||
public interface AuthorizationGrantService {
|
public interface AuthorizationGrantService {
|
||||||
|
|
||||||
/** Check a specified GrantType for a given GrantEntity for given user-principal and
|
/** Check a specified GrantType for a given GrantEntity and for a given user-principal.
|
||||||
* returns a with a Result of the granted entity instance or with a Result of a
|
* Use this to check a grant for a given entity instance by passing also the user-principal to check for.
|
||||||
* NoGrantException.
|
|
||||||
*
|
*
|
||||||
* @param entity The GrantEntity to check specified GrantType for
|
* @param entity The GrantEntity to check specified GrantType for
|
||||||
* @param grantType The GrantType
|
* @param grantType The GrantType
|
||||||
* @param principal the user principal
|
* @param principal the user principal
|
||||||
* @return a with a Result of the granted entity instance or with a Result of a NoGrantException */
|
* @return a with a Result of the granted entity instance or with a Result of a PermissionDeniedException */
|
||||||
<E extends GrantEntity> Result<E> checkGrantForEntity(
|
<E extends GrantEntity> Result<E> checkGrantForEntity(
|
||||||
final E entity,
|
final E entity,
|
||||||
final GrantType grantType,
|
final GrantType grantType,
|
||||||
final Principal principal);
|
final Principal principal);
|
||||||
|
|
||||||
|
/** Check a specified GrantType for a given entity type and for a given user-principal.
|
||||||
|
* Use this to check a base-grant for a given entity type by passing also the user-principal to check for.
|
||||||
|
*
|
||||||
|
* @param entityType The EntityType to check specified GrantType for
|
||||||
|
* @param grantType The GrantType
|
||||||
|
* @param principal the user principal
|
||||||
|
* @return a with a Result of the granted entity-type or with a Result of a PermissionDeniedException */
|
||||||
|
Result<EntityType> checkGrantForType(
|
||||||
|
final EntityType entityType,
|
||||||
|
final GrantType grantType,
|
||||||
|
final Principal principal);
|
||||||
|
|
||||||
/** Checks if a given user has a specified grant for a given entity-type
|
/** Checks if a given user has a specified grant for a given entity-type
|
||||||
*
|
*
|
||||||
* NOTE: within this method only base-privileges for a given entity-type are checked
|
* NOTE: within this method only base-privileges for a given entity-type are checked
|
||||||
|
|
|
@ -117,6 +117,19 @@ public class AuthorizationGrantServiceImpl implements AuthorizationGrantService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Result<EntityType> checkGrantForType(
|
||||||
|
final EntityType entityType,
|
||||||
|
final GrantType grantType,
|
||||||
|
final Principal principal) {
|
||||||
|
|
||||||
|
if (hasBaseGrant(entityType, grantType, principal)) {
|
||||||
|
return Result.of(entityType);
|
||||||
|
} else {
|
||||||
|
return Result.ofError(new PermissionDeniedException(entityType, grantType, principal.getName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasBaseGrant(
|
public boolean hasBaseGrant(
|
||||||
final EntityType entityType,
|
final EntityType entityType,
|
||||||
|
|
|
@ -11,7 +11,7 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.dao;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.model.EntityType;
|
import ch.ethz.seb.sebserver.gbl.model.Entity;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.user.UserActivityLog;
|
import ch.ethz.seb.sebserver.gbl.model.user.UserActivityLog;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||||
import ch.ethz.seb.sebserver.webservice.datalayer.batis.model.UserLogRecord;
|
import ch.ethz.seb.sebserver.webservice.datalayer.batis.model.UserLogRecord;
|
||||||
|
@ -32,14 +32,12 @@ public interface UserActivityLogDAO extends UserRelatedEntityDAO<UserActivityLog
|
||||||
*
|
*
|
||||||
* @param user for specified SEBServerUser instance
|
* @param user for specified SEBServerUser instance
|
||||||
* @param actionType the action type
|
* @param actionType the action type
|
||||||
* @param entityType the entity type
|
* @param entity the Entity
|
||||||
* @param entityId the entity id (primary key or UUID)
|
|
||||||
* @param message an optional message */
|
* @param message an optional message */
|
||||||
void logUserActivity(
|
<E extends Entity> Result<E> logUserActivity(
|
||||||
SEBServerUser user,
|
SEBServerUser user,
|
||||||
ActionType actionType,
|
ActionType actionType,
|
||||||
EntityType entityType,
|
E entity,
|
||||||
String entityId,
|
|
||||||
String message);
|
String message);
|
||||||
|
|
||||||
/** Creates a user activity log entry.
|
/** Creates a user activity log entry.
|
||||||
|
@ -48,13 +46,12 @@ public interface UserActivityLogDAO extends UserRelatedEntityDAO<UserActivityLog
|
||||||
* @param actionType the action type
|
* @param actionType the action type
|
||||||
* @param entityType the entity type
|
* @param entityType the entity type
|
||||||
* @param entityId the entity id (primary key or UUID) */
|
* @param entityId the entity id (primary key or UUID) */
|
||||||
default void logUserActivity(
|
default <E extends Entity> Result<E> logUserActivity(
|
||||||
final SEBServerUser user,
|
final SEBServerUser user,
|
||||||
final ActionType actionType,
|
final ActionType actionType,
|
||||||
final EntityType entityType,
|
final E entity) {
|
||||||
final String entityId) {
|
|
||||||
|
|
||||||
logUserActivity(user, actionType, entityType, entityId);
|
return logUserActivity(user, actionType, entity, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<Collection<UserActivityLog>> allForUser(
|
Result<Collection<UserActivityLog>> allForUser(
|
||||||
|
|
|
@ -17,9 +17,13 @@ import java.util.stream.Collectors;
|
||||||
import org.mybatis.dynamic.sql.SqlBuilder;
|
import org.mybatis.dynamic.sql.SqlBuilder;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.transaction.interceptor.TransactionInterceptor;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.Entity;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.EntityType;
|
import ch.ethz.seb.sebserver.gbl.model.EntityType;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.user.UserActivityLog;
|
import ch.ethz.seb.sebserver.gbl.model.user.UserActivityLog;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||||
|
@ -30,6 +34,8 @@ 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.authorization.UserService;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserActivityLogDAO;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserActivityLogDAO;
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
@Component
|
||||||
public class UserActivityLogDAOImpl implements UserActivityLogDAO {
|
public class UserActivityLogDAOImpl implements UserActivityLogDAO {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(UserActivityLogDAOImpl.class);
|
private static final Logger log = LoggerFactory.getLogger(UserActivityLogDAOImpl.class);
|
||||||
|
@ -52,11 +58,10 @@ public class UserActivityLogDAOImpl implements UserActivityLogDAO {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public void logUserActivity(
|
public <E extends Entity> Result<E> logUserActivity(
|
||||||
final SEBServerUser user,
|
final SEBServerUser user,
|
||||||
final ActionType actionType,
|
final ActionType actionType,
|
||||||
final EntityType entityType,
|
final E entity,
|
||||||
final String entityId,
|
|
||||||
final String message) {
|
final String message) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -66,18 +71,26 @@ public class UserActivityLogDAOImpl implements UserActivityLogDAO {
|
||||||
user.getUserInfo().uuid,
|
user.getUserInfo().uuid,
|
||||||
System.currentTimeMillis(),
|
System.currentTimeMillis(),
|
||||||
actionType.name(),
|
actionType.name(),
|
||||||
entityType.name(),
|
entity.entityType().name(),
|
||||||
entityId,
|
entity.getId(),
|
||||||
message));
|
message));
|
||||||
|
|
||||||
|
return Result.of(entity);
|
||||||
|
|
||||||
} catch (final Throwable t) {
|
} catch (final Throwable t) {
|
||||||
|
|
||||||
log.error(
|
log.error(
|
||||||
"Unexpected error while trying to log user activity for user {}, action-type: {} entity-type: {} entity-id: {}",
|
"Unexpected error while trying to log user activity for user {}, action-type: {} entity-type: {} entity-id: {}",
|
||||||
user.getUserInfo().uuid,
|
user.getUserInfo().uuid,
|
||||||
actionType,
|
actionType,
|
||||||
entityType,
|
entity.entityType().name(),
|
||||||
entityId,
|
entity.getId(),
|
||||||
t);
|
t);
|
||||||
|
TransactionInterceptor
|
||||||
|
.currentTransactionStatus()
|
||||||
|
.setRollbackOnly();
|
||||||
|
return Result.ofError(t);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,6 +227,7 @@ public class UserActivityLogDAOImpl implements UserActivityLogDAO {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
return Result.of(new UserActivityLog(
|
return Result.of(new UserActivityLog(
|
||||||
|
record.getId(),
|
||||||
record.getUserUuid(),
|
record.getUserUuid(),
|
||||||
record.getTimestamp(),
|
record.getTimestamp(),
|
||||||
ActionType.valueOf(record.getActionType()),
|
ActionType.valueOf(record.getActionType()),
|
||||||
|
|
|
@ -234,7 +234,7 @@ public class UserDaoImpl implements UserDAO {
|
||||||
return Result.ofError(new IllegalArgumentException("The users institution cannot be null"));
|
return Result.ofError(new IllegalArgumentException("The users institution cannot be null"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (userMod.newPasswordMatch()) {
|
if (!userMod.newPasswordMatch()) {
|
||||||
return Result.ofError(new APIMessageException(ErrorMessage.PASSWORD_MISSMATCH));
|
return Result.ofError(new APIMessageException(ErrorMessage.PASSWORD_MISSMATCH));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018 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;
|
|
||||||
|
|
||||||
import org.springframework.core.Ordered;
|
|
||||||
import org.springframework.core.annotation.Order;
|
|
||||||
import org.springframework.http.HttpHeaders;
|
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
import org.springframework.http.ResponseEntity;
|
|
||||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
|
||||||
import org.springframework.web.context.request.WebRequest;
|
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
|
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
|
||||||
|
|
||||||
@Order(Ordered.HIGHEST_PRECEDENCE)
|
|
||||||
@ControllerAdvice
|
|
||||||
@WebServiceProfile
|
|
||||||
public class WebExceptionHandler extends ResponseEntityExceptionHandler {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ResponseEntity<Object> handleExceptionInternal(
|
|
||||||
final Exception ex,
|
|
||||||
final Object body,
|
|
||||||
final HttpHeaders headers,
|
|
||||||
final HttpStatus status, final WebRequest request) {
|
|
||||||
|
|
||||||
// TODO here we can handle exception within the Rest API
|
|
||||||
ex.printStackTrace();
|
|
||||||
return super.handleExceptionInternal(ex, body, headers, status, request);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -82,4 +82,14 @@ public class APIExceptionHandler extends ResponseEntityExceptionHandler {
|
||||||
.createErrorResponse(ex.getMessage());
|
.createErrorResponse(ex.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(Exception.class)
|
||||||
|
public ResponseEntity<Object> handleUnexpected(
|
||||||
|
final Exception ex,
|
||||||
|
final WebRequest request) {
|
||||||
|
|
||||||
|
log.error("Unexpected internal error catched at the API endpoint: ", ex);
|
||||||
|
return APIMessage.ErrorMessage.UNEXPECTED
|
||||||
|
.createErrorResponse(ex.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,11 +23,17 @@ import org.springframework.web.bind.annotation.RestController;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.EntityType;
|
import ch.ethz.seb.sebserver.gbl.model.EntityType;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.user.UserFilter;
|
import ch.ethz.seb.sebserver.gbl.model.user.UserFilter;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
|
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.user.UserMod;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.AuthorizationGrantService;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.AuthorizationGrantService;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.GrantType;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.GrantType;
|
||||||
|
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.authorization.UserService;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserActivityLogDAO;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserActivityLogDAO.ActionType;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserDAO;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserDAO;
|
||||||
|
|
||||||
|
@WebServiceProfile
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/${sebserver.webservice.api.admin.endpoint}/useraccount")
|
@RequestMapping("/${sebserver.webservice.api.admin.endpoint}/useraccount")
|
||||||
public class UserAccountController {
|
public class UserAccountController {
|
||||||
|
@ -35,15 +41,18 @@ public class UserAccountController {
|
||||||
private final UserDAO userDao;
|
private final UserDAO userDao;
|
||||||
private final AuthorizationGrantService authorizationGrantService;
|
private final AuthorizationGrantService authorizationGrantService;
|
||||||
private final UserService userService;
|
private final UserService userService;
|
||||||
|
private final UserActivityLogDAO userActivityLogDAO;
|
||||||
|
|
||||||
public UserAccountController(
|
public UserAccountController(
|
||||||
final UserDAO userDao,
|
final UserDAO userDao,
|
||||||
final AuthorizationGrantService authorizationGrantService,
|
final AuthorizationGrantService authorizationGrantService,
|
||||||
final UserService userService) {
|
final UserService userService,
|
||||||
|
final UserActivityLogDAO userActivityLogDAO) {
|
||||||
|
|
||||||
this.userDao = userDao;
|
this.userDao = userDao;
|
||||||
this.authorizationGrantService = authorizationGrantService;
|
this.authorizationGrantService = authorizationGrantService;
|
||||||
this.userService = userService;
|
this.userService = userService;
|
||||||
|
this.userActivityLogDAO = userActivityLogDAO;
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.GET)
|
@RequestMapping(method = RequestMethod.GET)
|
||||||
|
@ -71,8 +80,9 @@ public class UserAccountController {
|
||||||
if (filter == null) {
|
if (filter == null) {
|
||||||
|
|
||||||
return this.userDao
|
return this.userDao
|
||||||
.all(grantFilter)
|
.all(userInfo -> userInfo.active && grantFilter.test(userInfo))
|
||||||
.getOrThrow();
|
.getOrThrow();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
return this.userDao
|
return this.userDao
|
||||||
|
@ -104,12 +114,45 @@ public class UserAccountController {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// @RequestMapping(value = "/", method = RequestMethod.POST)
|
@RequestMapping(value = "/create", method = RequestMethod.PUT)
|
||||||
// public UserInfo save(
|
public UserInfo createUser(
|
||||||
// @PathVariable final Long institutionId,
|
@RequestBody final UserMod userData,
|
||||||
// @RequestBody final UserFilter filter,
|
final Principal principal) {
|
||||||
// final Principal principal) {
|
|
||||||
//
|
return _saveUser(userData, principal, GrantType.WRITE);
|
||||||
// }
|
}
|
||||||
|
|
||||||
|
@RequestMapping(value = "/save", method = RequestMethod.POST)
|
||||||
|
public UserInfo saveUser(
|
||||||
|
@RequestBody final UserMod userData,
|
||||||
|
final Principal principal) {
|
||||||
|
|
||||||
|
return _saveUser(userData, principal, GrantType.MODIFY);
|
||||||
|
}
|
||||||
|
|
||||||
|
private UserInfo _saveUser(
|
||||||
|
final UserMod userData,
|
||||||
|
final Principal principal,
|
||||||
|
final GrantType grantType) {
|
||||||
|
|
||||||
|
this.authorizationGrantService.checkGrantForType(
|
||||||
|
EntityType.USER,
|
||||||
|
grantType,
|
||||||
|
principal)
|
||||||
|
.getOrThrow();
|
||||||
|
|
||||||
|
final SEBServerUser admin = this.userService.extractFromPrincipal(principal);
|
||||||
|
final ActionType actionType = (userData.getUserInfo().uuid == null)
|
||||||
|
? ActionType.CREATE
|
||||||
|
: ActionType.MODIFY;
|
||||||
|
|
||||||
|
return this.userDao
|
||||||
|
.save(admin, userData)
|
||||||
|
.flatMap(userInfo -> this.userActivityLogDAO.logUserActivity(
|
||||||
|
admin,
|
||||||
|
actionType,
|
||||||
|
userInfo))
|
||||||
|
.getOrThrow();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018 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.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
||||||
|
|
||||||
|
@WebServiceProfile
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/${sebserver.webservice.api.admin.endpoint}/useraccount")
|
||||||
|
public class UserActionLogController {
|
||||||
|
|
||||||
|
public UserActionLogController() {
|
||||||
|
System.out.println("UserActionLogController");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -9,7 +9,6 @@
|
||||||
package ch.ethz.seb.sebserver.gbl.model.user;
|
package ch.ethz.seb.sebserver.gbl.model.user;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertNotNull;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@ -26,6 +25,7 @@ public class UserActivityLogTest {
|
||||||
@Test
|
@Test
|
||||||
public void testFromToJson() throws IOException {
|
public void testFromToJson() throws IOException {
|
||||||
final UserActivityLog testModel = new UserActivityLog(
|
final UserActivityLog testModel = new UserActivityLog(
|
||||||
|
1L,
|
||||||
"testUser",
|
"testUser",
|
||||||
123l,
|
123l,
|
||||||
ActionType.CREATE,
|
ActionType.CREATE,
|
||||||
|
@ -43,15 +43,6 @@ public class UserActivityLogTest {
|
||||||
+ "\"entityId\":\"321\","
|
+ "\"entityId\":\"321\","
|
||||||
+ "\"message\":\"noComment\"}",
|
+ "\"message\":\"noComment\"}",
|
||||||
jsonValue);
|
jsonValue);
|
||||||
|
|
||||||
final UserActivityLog deserialized = this.jsonMapper.readValue(jsonValue, UserActivityLog.class);
|
|
||||||
assertNotNull(deserialized);
|
|
||||||
assertEquals(testModel.userId, deserialized.userId);
|
|
||||||
assertEquals(testModel.timestamp, deserialized.timestamp);
|
|
||||||
assertEquals(testModel.actionType, deserialized.actionType);
|
|
||||||
assertEquals(testModel.entityType, deserialized.entityType);
|
|
||||||
assertEquals(testModel.entityId, deserialized.entityId);
|
|
||||||
assertEquals(testModel.message, deserialized.message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,12 +10,17 @@ package ch.ethz.seb.sebserver.webservice.integration.api;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
|
import org.joda.time.DateTimeZone;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
|
|
||||||
|
@ -23,6 +28,8 @@ import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.model.user.UserFilter;
|
import ch.ethz.seb.sebserver.gbl.model.user.UserFilter;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
|
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.user.UserMod;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.user.UserRole;
|
||||||
|
|
||||||
public class UserAPITest extends AdministrationAPIIntegrationTest {
|
public class UserAPITest extends AdministrationAPIIntegrationTest {
|
||||||
|
|
||||||
|
@ -182,6 +189,35 @@ public class UserAPITest extends AdministrationAPIIntegrationTest {
|
||||||
assertNotNull(getUserInfo("examSupporter", userInfos));
|
assertNotNull(getUserInfo("examSupporter", userInfos));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void createUserTest() throws Exception {
|
||||||
|
final UserInfo userInfo = new UserInfo(
|
||||||
|
null, 1L, "NewTestUser", "NewTestUser",
|
||||||
|
"", true, Locale.CANADA, DateTimeZone.UTC,
|
||||||
|
new HashSet<>(Arrays.asList(UserRole.EXAM_ADMIN.name())));
|
||||||
|
final UserMod newUser = new UserMod(userInfo, "123", "123");
|
||||||
|
final String newUserJson = this.jsonMapper.writeValueAsString(newUser);
|
||||||
|
|
||||||
|
final String token = getSebAdminAccess();
|
||||||
|
final UserInfo createdUser = this.jsonMapper.readValue(
|
||||||
|
this.mockMvc.perform(put(this.endpoint + "/useraccount/create")
|
||||||
|
.header("Authorization", "Bearer " + token)
|
||||||
|
.contentType(MediaType.APPLICATION_JSON_UTF8)
|
||||||
|
.content(newUserJson))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andReturn().getResponse().getContentAsString(),
|
||||||
|
new TypeReference<UserInfo>() {
|
||||||
|
});
|
||||||
|
|
||||||
|
assertNotNull(createdUser);
|
||||||
|
assertEquals("NewTestUser", createdUser.name);
|
||||||
|
|
||||||
|
// TODO get newly created user and check equality
|
||||||
|
|
||||||
|
// TODO get user activity log for newly created user
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private UserInfo getUserInfo(final String name, final Collection<UserInfo> infos) {
|
private UserInfo getUserInfo(final String name, final Collection<UserInfo> infos) {
|
||||||
return infos
|
return infos
|
||||||
.stream()
|
.stream()
|
||||||
|
|
|
@ -95,6 +95,11 @@ public class AuthorizationGrantServiceTest {
|
||||||
return owner;
|
return owner;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getId() {
|
||||||
|
return "1";
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue