fixed some list mismatches due to read access + code cleanup

This commit is contained in:
anhefti 2024-06-26 14:14:24 +02:00
parent 6cc2f7b84b
commit 66b2eebf1d
11 changed files with 49 additions and 14 deletions

View file

@ -322,7 +322,7 @@ public final class Exam implements GrantEntity {
return this.institutionId;
}
public boolean isOwner(final String userId) {
public boolean isOwnerOrSupporter(final String userId) {
if (StringUtils.isBlank(userId)) {
return false;
}

View file

@ -131,7 +131,7 @@ public final class InstitutionalAuthenticationEntryPoint implements Authenticati
SEBServerAuthorizationContext authorizationContext = authorizationContextHolder
.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()) {
authorizationContext.logout();
authorizationContext = authorizationContextHolder.getAuthorizationContext(request.getSession());

View file

@ -15,7 +15,6 @@ import java.nio.charset.StandardCharsets;
import javax.servlet.http.HttpSession;
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.TokenLoginInfo;
import org.apache.commons.lang3.BooleanUtils;

View file

@ -135,7 +135,6 @@ public class PaginationServiceImpl implements PaginationService {
final Supplier<Result<Collection<T>>> delegate) {
return Result.tryCatch(() -> {
//final SqlTable table = SqlTable.of(tableName);
final com.github.pagehelper.Page<Object> page =
setPagination(pageNumber, pageSize, sort, tableName);

View file

@ -8,11 +8,7 @@
package ch.ethz.seb.sebserver.webservice.servicelayer.authorization;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.*;
import ch.ethz.seb.sebserver.gbl.api.EntityType;
import ch.ethz.seb.sebserver.gbl.api.authorization.Privilege;
@ -302,4 +298,26 @@ public interface AuthorizationService {
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;
}
}

View file

@ -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_LMS_SETUP_JOIN = "ADD_LMS_SETUP_JOIN";
public static final String ATTR_SUPPORTER_USER_ID = "SUPPORTER_USER_UUID";
public FilterMap() {
super(new LinkedMultiValueMap<>(), null);
}
@ -123,7 +125,6 @@ public class FilterMap extends POSTMapper {
public DateTime getSEBClientConfigFromTime() {
return Utils.toDateTime(getString(SEBClientConfig.FILTER_ATTR_CREATION_DATE));
}
public Long getLmsSetupId() {
return getLong(LmsSetup.FILTER_ATTR_LMS_SETUP);
}
@ -334,6 +335,7 @@ public class FilterMap extends POSTMapper {
return null;
}
public static final class Builder {
private final FilterMap filterMap = new FilterMap();

View file

@ -189,6 +189,13 @@ public class ExamRecordDAO {
ExamRecordDynamicSqlSupport.type,
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
if (filterMap.getBoolean(Exam.FILTER_ATTR_HIDE_MISSING)) {
whereClause = whereClause.and(

View file

@ -182,7 +182,7 @@ public class SEBClientEventAdminServiceImpl implements SEBClientEventAdminServic
final Exam exam = getExam(rec.getClientConnectionId());
if (!isSupporterOnly || exam.isOwner(currentUser.uuid())) {
if (!isSupporterOnly || exam.isOwnerOrSupporter(currentUser.uuid())) {
this.exporter.streamData(
this.output,
rec,

View file

@ -14,8 +14,6 @@ import java.util.stream.Collectors;
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.webservice.servicelayer.exam.ExamImportService;
import ch.ethz.seb.sebserver.webservice.servicelayer.exam.ExamUtils;
@ -134,6 +132,17 @@ public class ExamAdministrationController extends EntityController<Exam, Exam> {
this.cryptor = cryptor;
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
protected SqlTable getSQLTableOfEntity() {

View file

@ -539,7 +539,7 @@ public class ExamMonitoringController {
final UserInfo userInfo = this.authorization.getUserService().getCurrentUser().getUserInfo();
final String userId = userInfo.uuid;
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) {

View file

@ -85,6 +85,7 @@ public class QuizController {
@RequestParam final MultiValueMap<String, String> allRequestParams,
final HttpServletRequest request) {
this.authorization.checkNotOnlyTeacher(EntityType.EXAM);
this.authorization.check(
PrivilegeType.READ,
EntityType.EXAM,