some changes

This commit is contained in:
anhefti 2018-12-20 22:16:28 +01:00
parent b684654efd
commit 53572431fc
3 changed files with 113 additions and 58 deletions

View file

@ -12,6 +12,7 @@ import java.util.Collection;
import java.util.function.Predicate; import java.util.function.Predicate;
import ch.ethz.seb.sebserver.gbl.model.Entity; import ch.ethz.seb.sebserver.gbl.model.Entity;
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;
import ch.ethz.seb.sebserver.webservice.datalayer.batis.model.UserActivityLogRecord; import ch.ethz.seb.sebserver.webservice.datalayer.batis.model.UserActivityLogRecord;
@ -30,41 +31,48 @@ public interface UserActivityLogDAO extends UserRelatedEntityDAO<UserActivityLog
/** Creates a user activity log entry for the current user. /** Creates a user activity log entry for the current user.
* *
* @param actionType the action type * @param activityType the activity type
* @param entity the Entity * @param entity the Entity
* @param message an optional message */ * @param message an optional message */
<E extends Entity> Result<E> logUserActivity(ActivityType actionType, E entity, String message); <E extends Entity> Result<E> log(ActivityType activityType, E entity, String message);
/** Creates a user activity log entry for the current user. /** Creates a user activity log entry for the current user.
* *
* @param actionType the action type * @param actionType the action type
* @param entity the Entity */ * @param entity the Entity */
<E extends Entity> Result<E> logUserActivity(ActivityType actionType, E entity); <E extends Entity> Result<E> log(ActivityType activityType, E entity);
/** Creates a user activity log entry for the current user.
*
* @param activityType the activity type
* @param entityType the EntityType
* @param message the message */
void log(ActivityType activityType, EntityType entityType, String entityId, String message);
/** Creates a user activity log entry. /** Creates a user activity log entry.
* *
* @param user for specified SEBServerUser instance * @param user for specified SEBServerUser instance
* @param actionType the action type * @param activityType the activity type
* @param entity the Entity * @param entity the Entity
* @param message an optional message */ * @param message an optional message */
<E extends Entity> Result<E> logUserActivity( <E extends Entity> Result<E> log(
SEBServerUser user, SEBServerUser user,
ActivityType actionType, ActivityType activityType,
E entity, E entity,
String message); String message);
/** Creates a user activity log entry. /** Creates a user activity log entry.
* *
* @param user for specified SEBServerUser instance * @param user for specified SEBServerUser instance
* @param actionType the action type * @param activityType the activity 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 <E extends Entity> Result<E> logUserActivity( default <E extends Entity> Result<E> log(
final SEBServerUser user, final SEBServerUser user,
final ActivityType actionType, final ActivityType activityType,
final E entity) { final E entity) {
return logUserActivity(user, actionType, entity, null); return log(user, activityType, entity, null);
} }
Result<Collection<UserActivityLog>> all( Result<Collection<UserActivityLog>> all(

View file

@ -19,11 +19,10 @@ import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component; 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.EntityProcessingReport;
import ch.ethz.seb.sebserver.gbl.model.Entity; import ch.ethz.seb.sebserver.gbl.model.Entity;
import ch.ethz.seb.sebserver.gbl.model.EntityProcessingReport;
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;
@ -64,55 +63,85 @@ public class UserActivityLogDAOImpl implements UserActivityLogDAO {
} }
@Override @Override
public <E extends Entity> Result<E> logUserActivity( @Transactional
final ActivityType actionType, public <E extends Entity> Result<E> log(
final ActivityType activityType,
final E entity, final E entity,
final String message) { final String message) {
return logUserActivity(this.userService.getCurrentUser(), actionType, entity, message); return log(this.userService.getCurrentUser(), activityType, entity, message);
}
@Override
public <E extends Entity> Result<E> logUserActivity(final ActivityType actionType, final E entity) {
return logUserActivity(this.userService.getCurrentUser(), actionType, entity, null);
} }
@Override @Override
@Transactional @Transactional
public <E extends Entity> Result<E> logUserActivity( public <E extends Entity> Result<E> log(final ActivityType activityType, final E entity) {
return log(this.userService.getCurrentUser(), activityType, entity, null);
}
@Override
@Transactional
public void log(
final ActivityType activityType,
final EntityType entityType,
final String entityId,
final String message) {
try {
log(
this.userService.getCurrentUser(),
activityType,
entityType,
entityId,
message);
} catch (final Exception e) {
log.error(
"Unexpected error while trying to log user activity for user {}, action-type: {} entity-type: {} entity-id: {}",
this.userService.getCurrentUser(),
activityType,
entityType,
entityId,
e);
TransactionHandler.rollback();
}
}
@Override
@Transactional
public <E extends Entity> Result<E> log(
final SEBServerUser user, final SEBServerUser user,
final ActivityType activityType, final ActivityType activityType,
final E entity, final E entity,
final String message) { final String message) {
try { return Result.tryCatch(() -> {
log(user, activityType, entity.entityType(), entity.getModelId(), message);
return entity;
})
.onErrorDo(TransactionHandler::rollback)
.onErrorDo(t -> log.error(
"Unexpected error while trying to log user activity for user {}, action-type: {} entity-type: {} entity-id: {}",
user.getUserInfo().uuid,
activityType,
entity.entityType().name(),
entity.getModelId(),
t));
}
this.userLogRecordMapper.insertSelective(new UserActivityLogRecord( private void log(
null, final SEBServerUser user,
user.getUserInfo().uuid, final ActivityType activityType,
System.currentTimeMillis(), final EntityType entityType,
activityType.name(), final String entityId,
entity.entityType().name(), final String message) {
entity.getModelId(),
message));
return Result.of(entity); this.userLogRecordMapper.insertSelective(new UserActivityLogRecord(
null,
} catch (final Throwable t) { user.getUserInfo().uuid,
System.currentTimeMillis(),
log.error( activityType.name(),
"Unexpected error while trying to log user activity for user {}, action-type: {} entity-type: {} entity-id: {}", entityType.name(),
user.getUserInfo().uuid, entityId,
activityType, message));
entity.entityType().name(),
entity.getModelId(),
t);
TransactionInterceptor
.currentTransactionStatus()
.setRollbackOnly();
return Result.ofError(t);
}
} }
@Override @Override
@ -169,7 +198,8 @@ public class UserActivityLogDAOImpl implements UserActivityLogDAO {
SqlBuilder.isEqualToWhenPresent(userId)) SqlBuilder.isEqualToWhenPresent(userId))
.and(UserActivityLogRecordDynamicSqlSupport.timestamp, .and(UserActivityLogRecordDynamicSqlSupport.timestamp,
SqlBuilder.isGreaterThanOrEqualToWhenPresent(from)) SqlBuilder.isGreaterThanOrEqualToWhenPresent(from))
.and(UserActivityLogRecordDynamicSqlSupport.timestamp, SqlBuilder.isLessThanWhenPresent(to)) .and(UserActivityLogRecordDynamicSqlSupport.timestamp,
SqlBuilder.isLessThanWhenPresent(to))
.build() .build()
.execute() .execute()
.stream() .stream()
@ -188,7 +218,8 @@ public class UserActivityLogDAOImpl implements UserActivityLogDAO {
SqlBuilder.isEqualToWhenPresent(institutionId)) SqlBuilder.isEqualToWhenPresent(institutionId))
.and(UserActivityLogRecordDynamicSqlSupport.timestamp, .and(UserActivityLogRecordDynamicSqlSupport.timestamp,
SqlBuilder.isGreaterThanOrEqualToWhenPresent(from)) SqlBuilder.isGreaterThanOrEqualToWhenPresent(from))
.and(UserActivityLogRecordDynamicSqlSupport.timestamp, SqlBuilder.isLessThanWhenPresent(to)) .and(UserActivityLogRecordDynamicSqlSupport.timestamp,
SqlBuilder.isLessThanWhenPresent(to))
.build() .build()
.execute() .execute()
.stream() .stream()
@ -215,7 +246,8 @@ public class UserActivityLogDAOImpl implements UserActivityLogDAO {
public Result<Integer> overwriteUserReferences(final String userUuid, final boolean deactivate) { public Result<Integer> overwriteUserReferences(final String userUuid, final boolean deactivate) {
return Result.tryCatch(() -> { return Result.tryCatch(() -> {
final List<UserActivityLogRecord> records = this.userLogRecordMapper.selectByExample() final List<UserActivityLogRecord> records = this.userLogRecordMapper.selectByExample()
.where(UserActivityLogRecordDynamicSqlSupport.userUuid, SqlBuilder.isEqualTo(userUuid)) .where(UserActivityLogRecordDynamicSqlSupport.userUuid,
SqlBuilder.isEqualTo(userUuid))
.build() .build()
.execute(); .execute();
@ -236,7 +268,8 @@ public class UserActivityLogDAOImpl implements UserActivityLogDAO {
public Result<Integer> deleteUserEnities(final String userUuid) { public Result<Integer> deleteUserEnities(final String userUuid) {
return Result.tryCatch(() -> { return Result.tryCatch(() -> {
return this.userLogRecordMapper.deleteByExample() return this.userLogRecordMapper.deleteByExample()
.where(UserActivityLogRecordDynamicSqlSupport.userUuid, SqlBuilder.isEqualToWhenPresent(userUuid)) .where(UserActivityLogRecordDynamicSqlSupport.userUuid,
SqlBuilder.isEqualToWhenPresent(userUuid))
.build() .build()
.execute(); .execute();
}); });

View file

@ -148,18 +148,22 @@ public class UserAccountController {
@RequestMapping(value = "/{uuid}/activate", method = RequestMethod.POST) @RequestMapping(value = "/{uuid}/activate", method = RequestMethod.POST)
public UserInfo activateUser(@PathVariable final String uuid) { public UserInfo activateUser(@PathVariable final String uuid) {
return setActivity(uuid, true); return setActive(uuid, true);
} }
@RequestMapping(value = "/{uuid}/deactivate", method = RequestMethod.POST) @RequestMapping(value = "/{uuid}/deactivate", method = RequestMethod.POST)
public UserInfo deactivateUser(@PathVariable final String uuid) { public UserInfo deactivateUser(@PathVariable final String uuid) {
return setActivity(uuid, false); return setActive(uuid, false);
} }
@RequestMapping(value = "/{uuid}/delete", method = RequestMethod.DELETE) @RequestMapping(value = "/{uuid}/delete", method = RequestMethod.DELETE)
public EntityProcessingReport deleteUser(@PathVariable final String uuid) { public EntityProcessingReport deleteUser(@PathVariable final String uuid) {
return this.userDao.pkForUUID(uuid) return this.userDao.pkForUUID(uuid)
.flatMap(pk -> this.userDao.delete(pk, true)) .flatMap(pk -> this.userDao.delete(pk, true))
.map(report -> {
this.userActivityLogDAO.log(ActivityType.DELETE, EntityType.USER, uuid, "soft");
return report;
})
.getOrThrow(); .getOrThrow();
} }
@ -167,6 +171,10 @@ public class UserAccountController {
public EntityProcessingReport hardDeleteUser(@PathVariable final String uuid) { public EntityProcessingReport hardDeleteUser(@PathVariable final String uuid) {
return this.userDao.pkForUUID(uuid) return this.userDao.pkForUUID(uuid)
.flatMap(pk -> this.userDao.delete(pk, false)) .flatMap(pk -> this.userDao.delete(pk, false))
.map(report -> {
this.userActivityLogDAO.log(ActivityType.DELETE, EntityType.USER, uuid, "hard");
return report;
})
.getOrThrow(); .getOrThrow();
} }
@ -176,27 +184,33 @@ public class UserAccountController {
.getOrThrow(); .getOrThrow();
} }
private UserInfo setActivity(final String uuid, final boolean activity) { private UserInfo setActive(final String uuid, final boolean active) {
final ActivityType activityType = (active)
? ActivityType.ACTIVATE
: ActivityType.DEACTIVATE;
return this.userDao.byUuid(uuid) return this.userDao.byUuid(uuid)
.flatMap(userInfo -> this.authorizationGrantService.checkGrantOnEntity(userInfo, PrivilegeType.WRITE)) .flatMap(userInfo -> this.authorizationGrantService.checkGrantOnEntity(userInfo, PrivilegeType.WRITE))
.flatMap(userInfo -> this.userDao.setActive(userInfo.uuid, activity)) .flatMap(userInfo -> this.userDao.setActive(userInfo.uuid, active))
.map(userInfo -> { .map(userInfo -> {
this.applicationEventPublisher.publishEvent(new EntityActivationEvent(userInfo, activity)); this.applicationEventPublisher.publishEvent(new EntityActivationEvent(userInfo, active));
return userInfo; return userInfo;
}) })
.flatMap(userInfo -> this.userActivityLogDAO.log(activityType, userInfo))
.getOrThrow(); .getOrThrow();
} }
private Result<UserInfo> _saveUser(final UserMod userData, final PrivilegeType privilegeType) { private Result<UserInfo> _saveUser(final UserMod userData, final PrivilegeType privilegeType) {
final ActivityType actionType = (userData.uuid == null) final ActivityType activityType = (userData.uuid == null)
? ActivityType.CREATE ? ActivityType.CREATE
: ActivityType.MODIFY; : ActivityType.MODIFY;
return this.authorizationGrantService return this.authorizationGrantService
.checkGrantOnEntity(userData, privilegeType) .checkGrantOnEntity(userData, privilegeType)
.flatMap(this.userDao::save) .flatMap(this.userDao::save)
.flatMap(userInfo -> this.userActivityLogDAO.logUserActivity(actionType, userInfo)) .flatMap(userInfo -> this.userActivityLogDAO.log(activityType, userInfo))
.flatMap(userInfo -> { .flatMap(userInfo -> {
// handle password change; revoke access tokens if password has changed // handle password change; revoke access tokens if password has changed
if (userData.passwordChangeRequest() && userData.newPasswordMatch()) { if (userData.passwordChangeRequest() && userData.newPasswordMatch()) {