diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/exam/Exam.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/exam/Exam.java index 465a258b..8127b9a2 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gbl/model/exam/Exam.java +++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/exam/Exam.java @@ -363,7 +363,7 @@ public final class Exam implements GrantEntity { @JsonIgnore public boolean isLmsAvailable() { - return BooleanUtils.isTrue(this.lmsAvailable); + return BooleanUtils.isNotFalse(this.lmsAvailable); } public String getExternalId() { diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/exam/ExamList.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/exam/ExamList.java index 7ceb339a..f7edff85 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/exam/ExamList.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/exam/ExamList.java @@ -336,7 +336,7 @@ public class ExamList implements TemplateComposer { final Exam exam, final PageService pageService) { - if (BooleanUtils.isFalse(exam.isLmsAvailable())) { + if (exam.lmsSetupId != null && BooleanUtils.isFalse(exam.isLmsAvailable())) { item.setData(RWT.CUSTOM_VARIANT, CustomVariant.DISABLED.key); return; } diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/session/proctoring/MonitoringProctoringService.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/session/proctoring/MonitoringProctoringService.java index 7e428a2b..ffc2006c 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/session/proctoring/MonitoringProctoringService.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/session/proctoring/MonitoringProctoringService.java @@ -12,6 +12,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.Map; +import ch.ethz.seb.sebserver.gbl.model.user.UserRole; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; @@ -29,6 +30,7 @@ import org.springframework.context.annotation.Lazy; import org.springframework.core.io.Resource; import org.springframework.http.*; import org.springframework.stereotype.Component; +import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.RestTemplate; import com.fasterxml.jackson.core.type.TypeReference; @@ -348,6 +350,12 @@ public class MonitoringProctoringService { httpEntity, String.class); + if (tokenRequest.getStatusCode() == HttpStatus.UNAUTHORIZED && + currentUser.get().hasAnyRole(UserRole.EXAM_SUPPORTER, UserRole.INSTITUTIONAL_ADMIN)) { + notifyUnauthorized(_action, currentUser); + return _action; + } + // Open SPS Gui redirect URL with login token (jwt token) in new browser tab final String redirectLocation = redirect.getBody() + "/jwt?token=" + tokenRequest.getBody(); // final String script = "var win = window.open('', 'seb_screen_proctoring'); win.location.href = '"+ redirectLocation + "';"; @@ -357,13 +365,28 @@ public class MonitoringProctoringService { // .getService(JavaScriptExecutor.class) // .execute(script); } catch (final Exception e) { + if (e instanceof HttpClientErrorException) { + if (((HttpClientErrorException) e).getRawStatusCode() == HttpStatus.UNAUTHORIZED.value()) { + notifyUnauthorized(_action, this.pageService.getCurrentUser()); + return _action; + } + } log.error("Failed to open screen proctoring service group gallery view: ", e); _action.pageContext() - .notifyError(new LocTextKey("Failed to open screen proctoring service group gallery view"), e); + .notifyError(new LocTextKey("sebserver.monitoring.sps.opengallery.fail"), e); } return _action; } + private static void notifyUnauthorized(final PageAction _action, final CurrentUser currentUser) { + log.warn("No Access to Screen Proctoring for user: {}", currentUser.get().username); + _action + .pageContext() + .notifyError( + new LocTextKey("sebserver.monitoring.sps.noaccess"), + new RuntimeException("No access to Screen Proctoring. Please make sure you are assigned as Exam Supporter for this exam.")); + } + private PageAction openExamProctoringRoom( final ProctoringGUIService proctoringGUIService, final ProctoringServiceSettings proctoringSettings, diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/LmsTestServiceImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/LmsTestServiceImpl.java index 0cc67b27..5ea1cbe7 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/LmsTestServiceImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/LmsTestServiceImpl.java @@ -101,6 +101,9 @@ public class LmsTestServiceImpl implements LmsTestService { } private LmsSetupTestResult fullIntegrationTest(final LmsAPITemplate template) { + if (template.lmsSetup().lmsType != LmsSetup.LmsType.MOODLE_PLUGIN) { + return null; + } if (!template.fullIntegrationActive()) { return null; } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/ScreenProctoringService.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/ScreenProctoringService.java index b4612e5b..3a738eae 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/ScreenProctoringService.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/ScreenProctoringService.java @@ -100,7 +100,7 @@ public interface ScreenProctoringService extends SessionUpdateTask { void updateClientConnections(); /** This goes through all running exams with screen proctoring enabled and updates the group attributes - * (mainly the number of active clients in the group) by call ing SPS API and store newest data. */ + * (mainly the number of active clients in the group) by calling SPS API and store newest data. */ void updateActiveGroups(); @Async(AsyncServiceSpringConfig.EXECUTOR_BEAN_NAME) diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamUpdateHandler.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamUpdateHandler.java index 208109f0..0fd16c53 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamUpdateHandler.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamUpdateHandler.java @@ -146,7 +146,7 @@ class ExamUpdateHandler implements ExamUpdateTask { .forEach(quizId -> { try { final Exam exam = exams.get(quizId); - if (exam.lmsAvailable == null || exam.isLmsAvailable()) { + if (exam.lmsSetupId != null && (exam.lmsAvailable == null || exam.isLmsAvailable())) { this.examDAO.markLMSAvailability(quizId, false, updateId); } } catch (final Exception ee) { diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/proctoring/ScreenProctoringServiceImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/proctoring/ScreenProctoringServiceImpl.java index f7d3d549..3c170d9c 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/proctoring/ScreenProctoringServiceImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/proctoring/ScreenProctoringServiceImpl.java @@ -577,6 +577,7 @@ public class ScreenProctoringServiceImpl implements ScreenProctoringService { log.debug("Register JOIN instruction for client "); } + final boolean checkActive = exam.lmsSetupId != null; final SPSData spsData = this.screenProctoringAPIBinding.getSPSData(exam.id); final String url = screenProctoringServiceBundle.bundled ? screenProctoringServiceBundle.serviceURL @@ -597,7 +598,7 @@ public class ScreenProctoringServiceImpl implements ScreenProctoringService { InstructionType.SEB_PROCTORING, attributes, ccRecord.getConnectionToken(), - true, + checkActive, true) .onError(error -> log.error( "Failed to register screen proctoring join instruction for SEB connection: {}", diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties index 963d9937..6ae273b9 100644 --- a/src/main/resources/messages.properties +++ b/src/main/resources/messages.properties @@ -1039,7 +1039,7 @@ sebserver.clientconfig.form.sebServerFallbackPasswordHash=Fallback Password sebserver.clientconfig.form.sebServerFallbackPasswordHash.tooltip=A password if set a SEB Client user must provide before SEB starts the fallback procedure sebserver.clientconfig.form.sebServerFallbackPasswordHash.confirm=Confirm Password sebserver.clientconfig.form.sebServerFallbackPasswordHash.tooltip.confirm=Please confirm the fallback password - +sebserver.clientconfig.form.hashedQuitPassword=Quit Password sebserver.clientconfig.form.hashedQuitPassword.tooltip=A password if set a SEB user must provide to be able to quit SEB sebserver.clientconfig.form.hashedQuitPassword.confirm=Confirm Password sebserver.clientconfig.form.hashedQuitPassword.tooltip.confirm=Please confirm the quit password @@ -2423,6 +2423,9 @@ sebserver.monitoring.signaturegrant.signature=App Signature Key Hash sebserver.monitoring.signaturegrant.tag=Tag sebserver.monitoring.signaturegrant.message.granted=This App Signature Key is already granted for this exam +sebserver.monitoring.sps.opengallery.fail=Failed to open screen proctoring service group gallery view +sebserver.monitoring.sps.noaccess=No Access to Screen Proctoring + ################################ # Finished Exams ################################