SEBSERV-155 implementation

This commit is contained in:
anhefti 2021-09-29 16:06:35 +02:00
parent 7817ed48c4
commit 69c9de6d64
5 changed files with 51 additions and 39 deletions

View file

@ -301,6 +301,9 @@ public class ActivitiesPane implements TemplateComposer {
.newAction(ActionDefinition.EXAM_VIEW_LIST)
.create());
}
if (this.currentUser.hasInstitutionalPrivilege(PrivilegeType.READ, EntityType.EXAM_TEMPLATE)) {
// Exam Template
final TreeItem examTemplate = this.widgetFactory.treeItemLocalized(
examAdmin,
@ -310,7 +313,6 @@ public class ActivitiesPane implements TemplateComposer {
actionBuilder
.newAction(ActionDefinition.EXAM_TEMPLATE_VIEW_LIST)
.create());
}
examAdmin.setExpanded(this.currentUser.get().hasAnyRole(UserRole.EXAM_ADMIN));
@ -322,7 +324,8 @@ public class ActivitiesPane implements TemplateComposer {
//--------------------------------------------------------------------------------------
// ---- MONITORING ---------------------------------------------------------------------
final boolean isSupporter = this.currentUser.get().hasAnyRole(UserRole.EXAM_SUPPORTER);
final boolean isSupporter = this.currentUser.get().hasAnyRole(UserRole.EXAM_SUPPORTER) ||
this.currentUser.get().hasAnyRole(UserRole.EXAM_ADMIN);
final boolean viewSEBClientLogs = this.currentUser.hasInstitutionalPrivilege(
PrivilegeType.READ,
EntityType.EXAM) ||

View file

@ -9,6 +9,7 @@
package ch.ethz.seb.sebserver.gui.content.monitoring;
import java.util.Collection;
import java.util.function.BooleanSupplier;
import java.util.function.Supplier;
import org.eclipse.swt.widgets.Composite;
@ -32,6 +33,7 @@ import ch.ethz.seb.sebserver.gbl.model.session.ClientConnectionData;
import ch.ethz.seb.sebserver.gbl.model.session.ClientEvent;
import ch.ethz.seb.sebserver.gbl.model.session.ClientNotification;
import ch.ethz.seb.sebserver.gbl.model.session.ExtendedClientEvent;
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
import ch.ethz.seb.sebserver.gbl.model.user.UserRole;
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
import ch.ethz.seb.sebserver.gbl.util.Utils;
@ -171,6 +173,10 @@ public class MonitoringClientConnection implements TemplateComposer {
.call()
.onError(error -> pageContext.notifyLoadError(EntityType.EXAM, error))
.getOrThrow();
final UserInfo user = currentUser.get();
final boolean supporting = user.hasRole(UserRole.EXAM_SUPPORTER) &&
exam.supporter.contains(user.uuid);
final BooleanSupplier isExamSupporter = () -> supporting || user.hasRole(UserRole.EXAM_ADMIN);
final Collection<Indicator> indicators = restService.getBuilder(GetIndicators.class)
.withQueryParam(Indicator.FILTER_ATTR_EXAM_ID, parentEntityKey.modelId)
@ -260,7 +266,7 @@ public class MonitoringClientConnection implements TemplateComposer {
NOTIFICATION_LIST_NO_SELECTION_KEY)
.noEventPropagation()
.publishIf(() -> currentUser.get().hasRole(UserRole.EXAM_SUPPORTER), false);
.publishIf(isExamSupporter, false);
_notificationTableSupplier = () -> notificationTable;
}
@ -353,7 +359,7 @@ public class MonitoringClientConnection implements TemplateComposer {
actionBuilder
.newAction(ActionDefinition.MONITOR_EXAM_BACK_TO_OVERVIEW)
.withEntityKey(parentEntityKey)
.publishIf(() -> currentUser.get().hasRole(UserRole.EXAM_SUPPORTER))
.publishIf(isExamSupporter)
.newAction(ActionDefinition.MONITOR_EXAM_CLIENT_CONNECTION_QUIT)
.withConfirm(() -> CONFIRM_QUIT)
@ -365,7 +371,7 @@ public class MonitoringClientConnection implements TemplateComposer {
return action;
})
.noEventPropagation()
.publishIf(() -> currentUser.get().hasRole(UserRole.EXAM_SUPPORTER) &&
.publishIf(() -> isExamSupporter.getAsBoolean() &&
connectionData.clientConnection.status.clientActiveStatus);
if (connectionData.clientConnection.status == ConnectionStatus.ACTIVE) {

View file

@ -37,6 +37,7 @@ import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringServiceSettings;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringServiceSettings.ProctoringFeature;
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnection.ConnectionStatus;
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnectionData;
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
import ch.ethz.seb.sebserver.gbl.model.user.UserRole;
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
import ch.ethz.seb.sebserver.gbl.util.Tuple;
@ -130,6 +131,10 @@ public class MonitoringRunningExam implements TemplateComposer {
.withURIVariable(API.PARAM_MODEL_ID, entityKey.modelId)
.call()
.getOrThrow();
final UserInfo user = currentUser.get();
final boolean supporting = user.hasRole(UserRole.EXAM_SUPPORTER) &&
exam.supporter.contains(user.uuid);
final BooleanSupplier isExamSupporter = () -> supporting || user.hasRole(UserRole.EXAM_ADMIN);
final Collection<Indicator> indicators = restService.getBuilder(GetIndicators.class)
.withQueryParam(Indicator.FILTER_ATTR_EXAM_ID, entityKey.modelId)
@ -191,8 +196,6 @@ public class MonitoringRunningExam implements TemplateComposer {
context -> clientTable.updateValues(),
updateTableGUI(clientTable));
final BooleanSupplier isExamSupporter = () -> currentUser.get().hasRole(UserRole.EXAM_SUPPORTER);
actionBuilder
.newAction(ActionDefinition.MONITOR_EXAM_CLIENT_CONNECTION)

View file

@ -132,8 +132,6 @@ public class AuthorizationServiceImpl implements AuthorizationService {
.withInstitutionalPrivilege(PrivilegeType.READ)
.andForRole(UserRole.EXAM_ADMIN)
.withInstitutionalPrivilege(PrivilegeType.WRITE)
.andForRole(UserRole.EXAM_SUPPORTER)
.withOwnerPrivilege(PrivilegeType.MODIFY)
.create();
// grants for configuration node

View file

@ -41,6 +41,7 @@ import ch.ethz.seb.sebserver.gbl.model.session.ClientConnection.ConnectionStatus
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnectionData;
import ch.ethz.seb.sebserver.gbl.model.session.ClientInstruction;
import ch.ethz.seb.sebserver.gbl.model.session.ClientNotification;
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
import ch.ethz.seb.sebserver.gbl.model.user.UserRole;
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
import ch.ethz.seb.sebserver.webservice.servicelayer.PaginationService;
@ -129,7 +130,8 @@ public class ExamMonitoringController {
this.authorization.checkRole(
institutionId,
EntityType.EXAM,
UserRole.EXAM_SUPPORTER);
UserRole.EXAM_SUPPORTER,
UserRole.EXAM_ADMIN);
final FilterMap filterMap = new FilterMap(allRequestParams, request.getQueryString());
@ -166,19 +168,7 @@ public class ExamMonitoringController {
@PathVariable(name = API.PARAM_PARENT_MODEL_ID, required = true) final Long examId,
@RequestHeader(name = API.EXAM_MONITORING_STATE_FILTER, required = false) final String hiddenStates) {
// check overall privilege
this.authorization.checkRole(
institutionId,
EntityType.EXAM,
UserRole.EXAM_SUPPORTER);
// check running exam privilege for specified exam
if (!hasRunningExamPrivilege(examId, institutionId)) {
throw new PermissionDeniedException(
EntityType.EXAM,
PrivilegeType.READ,
this.authorization.getUserService().getCurrentUser().getUserInfo());
}
checkPrivileges(institutionId, examId);
final EnumSet<ConnectionStatus> filterStates = EnumSet.noneOf(ConnectionStatus.class);
if (StringUtils.isNoneBlank(hiddenStates)) {
@ -211,20 +201,7 @@ public class ExamMonitoringController {
@PathVariable(name = API.PARAM_PARENT_MODEL_ID, required = true) final Long examId,
@PathVariable(name = API.EXAM_API_SEB_CONNECTION_TOKEN, required = true) final String connectionToken) {
// check overall privilege
this.authorization.checkRole(
institutionId,
EntityType.EXAM,
UserRole.EXAM_SUPPORTER);
// check running exam privilege for specified exam
if (!hasRunningExamPrivilege(examId, institutionId)) {
throw new PermissionDeniedException(
EntityType.EXAM,
PrivilegeType.READ,
this.authorization.getUserService().getCurrentUser().getUserInfo());
}
checkPrivileges(institutionId, examId);
return this.examSessionService
.getConnectionData(connectionToken)
.getOrThrow();
@ -243,6 +220,7 @@ public class ExamMonitoringController {
@PathVariable(name = API.PARAM_PARENT_MODEL_ID, required = true) final Long examId,
@Valid @RequestBody final ClientInstruction clientInstruction) {
checkPrivileges(institutionId, examId);
this.sebClientInstructionService.registerInstruction(clientInstruction);
}
@ -261,6 +239,8 @@ public class ExamMonitoringController {
@PathVariable(name = API.PARAM_PARENT_MODEL_ID, required = true) final Long examId,
@PathVariable(name = API.EXAM_API_SEB_CONNECTION_TOKEN, required = true) final String connectionToken) {
checkPrivileges(institutionId, examId);
final ClientConnectionData connection = getConnectionDataForSingleConnection(
institutionId,
examId,
@ -286,6 +266,7 @@ public class ExamMonitoringController {
@PathVariable(name = API.PARAM_MODEL_ID, required = true) final Long notificationId,
@PathVariable(name = API.EXAM_API_SEB_CONNECTION_TOKEN, required = true) final String connectionToken) {
checkPrivileges(institutionId, examId);
this.sebClientNotificationService.confirmPendingNotification(
notificationId,
examId,
@ -308,6 +289,8 @@ public class ExamMonitoringController {
name = Domain.CLIENT_CONNECTION.ATTR_CONNECTION_TOKEN,
required = true) final String connectionToken) {
checkPrivileges(institutionId, examId);
if (connectionToken.contains(Constants.LIST_SEPARATOR)) {
final String[] tokens = StringUtils.split(connectionToken, Constants.LIST_SEPARATOR);
for (int i = 0; i < tokens.length; i++) {
@ -322,6 +305,23 @@ public class ExamMonitoringController {
}
}
private void checkPrivileges(final Long institutionId, final Long examId) {
// check overall privilege
this.authorization.checkRole(
institutionId,
EntityType.EXAM,
UserRole.EXAM_SUPPORTER,
UserRole.EXAM_ADMIN);
// check running exam privilege for specified exam
if (!hasRunningExamPrivilege(examId, institutionId)) {
throw new PermissionDeniedException(
EntityType.EXAM,
PrivilegeType.READ,
this.authorization.getUserService().getCurrentUser().getUserInfo());
}
}
private boolean hasRunningExamPrivilege(final Long examId, final Long institution) {
return hasRunningExamPrivilege(
this.examSessionService.getRunningExam(examId).getOr(null),
@ -333,8 +333,10 @@ public class ExamMonitoringController {
return false;
}
final String userId = this.authorization.getUserService().getCurrentUser().getUserInfo().uuid;
return exam.institutionId.equals(institution) && exam.isOwner(userId);
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));
}
}