fixed some list mismatches due to read access + code cleanup
This commit is contained in:
parent
6cc2f7b84b
commit
66b2eebf1d
11 changed files with 49 additions and 14 deletions
|
@ -322,7 +322,7 @@ public final class Exam implements GrantEntity {
|
||||||
return this.institutionId;
|
return this.institutionId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isOwner(final String userId) {
|
public boolean isOwnerOrSupporter(final String userId) {
|
||||||
if (StringUtils.isBlank(userId)) {
|
if (StringUtils.isBlank(userId)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,7 +131,7 @@ public final class InstitutionalAuthenticationEntryPoint implements Authenticati
|
||||||
SEBServerAuthorizationContext authorizationContext = authorizationContextHolder
|
SEBServerAuthorizationContext authorizationContext = authorizationContextHolder
|
||||||
.getAuthorizationContext(request.getSession());
|
.getAuthorizationContext(request.getSession());
|
||||||
|
|
||||||
// check first if we already have an active session if so, invalidate ir
|
// check first if we already have an active session if so, invalidate it first
|
||||||
if (authorizationContext.isLoggedIn()) {
|
if (authorizationContext.isLoggedIn()) {
|
||||||
authorizationContext.logout();
|
authorizationContext.logout();
|
||||||
authorizationContext = authorizationContextHolder.getAuthorizationContext(request.getSession());
|
authorizationContext = authorizationContextHolder.getAuthorizationContext(request.getSession());
|
||||||
|
|
|
@ -15,7 +15,6 @@ import java.nio.charset.StandardCharsets;
|
||||||
import javax.servlet.http.HttpSession;
|
import javax.servlet.http.HttpSession;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
|
||||||
import ch.ethz.seb.sebserver.gbl.model.user.LoginForward;
|
import ch.ethz.seb.sebserver.gbl.model.user.LoginForward;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.user.TokenLoginInfo;
|
import ch.ethz.seb.sebserver.gbl.model.user.TokenLoginInfo;
|
||||||
import org.apache.commons.lang3.BooleanUtils;
|
import org.apache.commons.lang3.BooleanUtils;
|
||||||
|
|
|
@ -135,7 +135,6 @@ public class PaginationServiceImpl implements PaginationService {
|
||||||
final Supplier<Result<Collection<T>>> delegate) {
|
final Supplier<Result<Collection<T>>> delegate) {
|
||||||
|
|
||||||
return Result.tryCatch(() -> {
|
return Result.tryCatch(() -> {
|
||||||
//final SqlTable table = SqlTable.of(tableName);
|
|
||||||
final com.github.pagehelper.Page<Object> page =
|
final com.github.pagehelper.Page<Object> page =
|
||||||
setPagination(pageNumber, pageSize, sort, tableName);
|
setPagination(pageNumber, pageSize, sort, tableName);
|
||||||
|
|
||||||
|
|
|
@ -8,11 +8,7 @@
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.webservice.servicelayer.authorization;
|
package ch.ethz.seb.sebserver.webservice.servicelayer.authorization;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.*;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.authorization.Privilege;
|
import ch.ethz.seb.sebserver.gbl.api.authorization.Privilege;
|
||||||
|
@ -302,4 +298,26 @@ public interface AuthorizationService {
|
||||||
currentUser.getUserInfo());
|
currentUser.getUserInfo());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** This will throw access exception when current user has only teacher role */
|
||||||
|
default void checkNotOnlyTeacher(final EntityType type) {
|
||||||
|
final UserInfo userInfo = this.getUserService().getCurrentUser().getUserInfo();
|
||||||
|
final EnumSet<UserRole> userRoles = userInfo.getUserRoles();
|
||||||
|
if (userRoles.contains(UserRole.TEACHER) && userRoles.size() == 1) {
|
||||||
|
throw new PermissionDeniedException(type, PrivilegeType.READ, userInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** If current user has only Supporter or Teacher role, this will get the UUID of the user back
|
||||||
|
* or null otherwise (of user has other privileges too.
|
||||||
|
* @return current user UUID if it is Supporter or Teacher only */
|
||||||
|
default String getSupporterOnlyUUID() {
|
||||||
|
final UserInfo userInfo = this.getUserService().getCurrentUser().getUserInfo();
|
||||||
|
final EnumSet<UserRole> userRoles = userInfo.getUserRoles();
|
||||||
|
userRoles.removeAll(Arrays.asList(UserRole.TEACHER, UserRole.EXAM_SUPPORTER));
|
||||||
|
if (userRoles.isEmpty()) {
|
||||||
|
return userInfo.uuid;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,8 @@ public class FilterMap extends POSTMapper {
|
||||||
public static final String ATTR_ADD_INSITUTION_JOIN = "ADD_INSITUTION_JOIN";
|
public static final String ATTR_ADD_INSITUTION_JOIN = "ADD_INSITUTION_JOIN";
|
||||||
public static final String ATTR_ADD_LMS_SETUP_JOIN = "ADD_LMS_SETUP_JOIN";
|
public static final String ATTR_ADD_LMS_SETUP_JOIN = "ADD_LMS_SETUP_JOIN";
|
||||||
|
|
||||||
|
public static final String ATTR_SUPPORTER_USER_ID = "SUPPORTER_USER_UUID";
|
||||||
|
|
||||||
public FilterMap() {
|
public FilterMap() {
|
||||||
super(new LinkedMultiValueMap<>(), null);
|
super(new LinkedMultiValueMap<>(), null);
|
||||||
}
|
}
|
||||||
|
@ -123,7 +125,6 @@ public class FilterMap extends POSTMapper {
|
||||||
public DateTime getSEBClientConfigFromTime() {
|
public DateTime getSEBClientConfigFromTime() {
|
||||||
return Utils.toDateTime(getString(SEBClientConfig.FILTER_ATTR_CREATION_DATE));
|
return Utils.toDateTime(getString(SEBClientConfig.FILTER_ATTR_CREATION_DATE));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getLmsSetupId() {
|
public Long getLmsSetupId() {
|
||||||
return getLong(LmsSetup.FILTER_ATTR_LMS_SETUP);
|
return getLong(LmsSetup.FILTER_ATTR_LMS_SETUP);
|
||||||
}
|
}
|
||||||
|
@ -334,6 +335,7 @@ public class FilterMap extends POSTMapper {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static final class Builder {
|
public static final class Builder {
|
||||||
|
|
||||||
private final FilterMap filterMap = new FilterMap();
|
private final FilterMap filterMap = new FilterMap();
|
||||||
|
|
|
@ -189,6 +189,13 @@ public class ExamRecordDAO {
|
||||||
ExamRecordDynamicSqlSupport.type,
|
ExamRecordDynamicSqlSupport.type,
|
||||||
isEqualToWhenPresent(filterMap.getExamType()));
|
isEqualToWhenPresent(filterMap.getExamType()));
|
||||||
|
|
||||||
|
final String supporterUUID = filterMap.getSQLWildcard(FilterMap.ATTR_SUPPORTER_USER_ID);
|
||||||
|
if (StringUtils.isNotBlank(supporterUUID)) {
|
||||||
|
whereClause = whereClause.and(
|
||||||
|
supporter,
|
||||||
|
SqlBuilder.isLike(supporterUUID));
|
||||||
|
}
|
||||||
|
|
||||||
// SEBSERV-298
|
// SEBSERV-298
|
||||||
if (filterMap.getBoolean(Exam.FILTER_ATTR_HIDE_MISSING)) {
|
if (filterMap.getBoolean(Exam.FILTER_ATTR_HIDE_MISSING)) {
|
||||||
whereClause = whereClause.and(
|
whereClause = whereClause.and(
|
||||||
|
|
|
@ -182,7 +182,7 @@ public class SEBClientEventAdminServiceImpl implements SEBClientEventAdminServic
|
||||||
|
|
||||||
final Exam exam = getExam(rec.getClientConnectionId());
|
final Exam exam = getExam(rec.getClientConnectionId());
|
||||||
|
|
||||||
if (!isSupporterOnly || exam.isOwner(currentUser.uuid())) {
|
if (!isSupporterOnly || exam.isOwnerOrSupporter(currentUser.uuid())) {
|
||||||
this.exporter.streamData(
|
this.exporter.streamData(
|
||||||
this.output,
|
this.output,
|
||||||
rec,
|
rec,
|
||||||
|
|
|
@ -14,8 +14,6 @@ import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.model.Activatable;
|
|
||||||
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
|
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Cryptor;
|
import ch.ethz.seb.sebserver.gbl.util.Cryptor;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.exam.ExamImportService;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.exam.ExamImportService;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.exam.ExamUtils;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.exam.ExamUtils;
|
||||||
|
@ -134,6 +132,17 @@ public class ExamAdministrationController extends EntityController<Exam, Exam> {
|
||||||
this.cryptor = cryptor;
|
this.cryptor = cryptor;
|
||||||
this.fullLmsIntegrationService = fullLmsIntegrationService;
|
this.fullLmsIntegrationService = fullLmsIntegrationService;
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
protected Result<Collection<Exam>> getAll(final FilterMap filterMap) {
|
||||||
|
// If current user has only supporter role, put user UUID to filter to get correct page result from DB
|
||||||
|
final String supporterId = authorization.getSupporterOnlyUUID();
|
||||||
|
if (StringUtils.isNotBlank(supporterId)) {
|
||||||
|
filterMap.putIfAbsent(FilterMap.ATTR_SUPPORTER_USER_ID, supporterId);
|
||||||
|
}
|
||||||
|
return this.entityDAO.allMatching(
|
||||||
|
filterMap,
|
||||||
|
this::hasReadAccess);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected SqlTable getSQLTableOfEntity() {
|
protected SqlTable getSQLTableOfEntity() {
|
||||||
|
|
|
@ -539,7 +539,7 @@ public class ExamMonitoringController {
|
||||||
final UserInfo userInfo = this.authorization.getUserService().getCurrentUser().getUserInfo();
|
final UserInfo userInfo = this.authorization.getUserService().getCurrentUser().getUserInfo();
|
||||||
final String userId = userInfo.uuid;
|
final String userId = userInfo.uuid;
|
||||||
return exam.institutionId.equals(institution)
|
return exam.institutionId.equals(institution)
|
||||||
&& (exam.isOwner(userId) || userInfo.hasRole(UserRole.EXAM_ADMIN));
|
&& (exam.isOwnerOrSupporter(userId) || userInfo.hasRole(UserRole.EXAM_ADMIN));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Predicate<ClientConnectionData> noneActiveFilter(final EnumSet<ConnectionStatus> filterStates) {
|
private Predicate<ClientConnectionData> noneActiveFilter(final EnumSet<ConnectionStatus> filterStates) {
|
||||||
|
|
|
@ -85,6 +85,7 @@ public class QuizController {
|
||||||
@RequestParam final MultiValueMap<String, String> allRequestParams,
|
@RequestParam final MultiValueMap<String, String> allRequestParams,
|
||||||
final HttpServletRequest request) {
|
final HttpServletRequest request) {
|
||||||
|
|
||||||
|
this.authorization.checkNotOnlyTeacher(EntityType.EXAM);
|
||||||
this.authorization.check(
|
this.authorization.check(
|
||||||
PrivilegeType.READ,
|
PrivilegeType.READ,
|
||||||
EntityType.EXAM,
|
EntityType.EXAM,
|
||||||
|
|
Loading…
Reference in a new issue