From 1da749a473e535ac6fe0ed368b74bcec142be5df Mon Sep 17 00:00:00 2001 From: anhefti Date: Tue, 29 Sep 2020 17:48:50 +0200 Subject: [PATCH] fixed moodle and proctoring --- .../ClientHttpRequestFactoryService.java | 8 +- .../seb/sebserver/gui/GuiServiceInfo.java | 14 +++- .../gui/content/ExamProctoringSettings.java | 4 +- .../sebserver/gui/content/LmsSetupForm.java | 78 +++++++++++-------- .../exam/impl/ExamJITSIProctoringService.java | 18 +---- .../moodle/MoodleRestTemplateFactory.java | 2 +- .../weblayer/api/APIExceptionHandler.java | 26 +++---- src/main/resources/messages.properties | 3 +- .../impl/ExamJITSIProctoringServiceTest.java | 2 +- 9 files changed, 81 insertions(+), 74 deletions(-) diff --git a/src/main/java/ch/ethz/seb/sebserver/ClientHttpRequestFactoryService.java b/src/main/java/ch/ethz/seb/sebserver/ClientHttpRequestFactoryService.java index 6e69a81e..f3ea00d9 100644 --- a/src/main/java/ch/ethz/seb/sebserver/ClientHttpRequestFactoryService.java +++ b/src/main/java/ch/ethz/seb/sebserver/ClientHttpRequestFactoryService.java @@ -104,8 +104,12 @@ public class ClientHttpRequestFactoryService { /** A ClientHttpRequestFactory for development profile with no TSL SSL protocol and * not following redirects on redirect responses. * - * @return ClientHttpRequestFactory bean for development profiles */ - private ClientHttpRequestFactory clientHttpRequestFactory(final ProxyData proxy) { + * @return ClientHttpRequestFactory bean for development profiles + * @throws KeyStoreException + * @throws NoSuchAlgorithmException + * @throws KeyManagementException */ + private ClientHttpRequestFactory clientHttpRequestFactory(final ProxyData proxy) + throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException { if (log.isDebugEnabled()) { log.debug("Initialize ClientHttpRequestFactory with insecure ClientHttpRequestFactory for development"); diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/GuiServiceInfo.java b/src/main/java/ch/ethz/seb/sebserver/gui/GuiServiceInfo.java index 14b602c9..03f06be4 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/GuiServiceInfo.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/GuiServiceInfo.java @@ -43,11 +43,17 @@ public class GuiServiceInfo { this.externalPort = externalPort; this.entryPoint = entryPoint; this.internalServerURIBuilder = UriComponentsBuilder - .fromHttpUrl("http://" + this.internalServer) - .port(this.internalPort); + .fromHttpUrl("http://" + this.internalServer); + if (StringUtils.isNotBlank(internalPort)) { + this.internalServerURIBuilder.port(this.internalPort); + } this.externalServerURIBuilder = UriComponentsBuilder - .fromHttpUrl(this.externalScheme + "://" + this.externalServer) - .port(this.externalPort); + .fromHttpUrl(this.externalScheme + "://" + this.externalServer); + if (StringUtils.isNotBlank(externalPort)) { + this.externalServerURIBuilder.port(this.externalPort); + } else if (StringUtils.isNotBlank(internalPort)) { + this.externalServerURIBuilder.port(this.internalPort); + } } public String getExternalScheme() { diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/ExamProctoringSettings.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/ExamProctoringSettings.java index 7f0c5caa..df5f7f43 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/ExamProctoringSettings.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/ExamProctoringSettings.java @@ -52,6 +52,8 @@ public class ExamProctoringSettings { new LocTextKey("sebserver.exam.proctoring.form.title"); private final static LocTextKey SEB_PROCTORING_FORM_INFO = new LocTextKey("sebserver.exam.proctoring.form.info"); + private final static LocTextKey SEB_PROCTORING_FORM_INFO_TITLE = + new LocTextKey("sebserver.exam.proctoring.form.info.title"); private final static LocTextKey SEB_PROCTORING_FORM_ENABLE = new LocTextKey("sebserver.exam.proctoring.form.enabled"); private final static LocTextKey SEB_PROCTORING_FORM_TYPE = @@ -200,7 +202,7 @@ public class ExamProctoringSettings { .addField(FormBuilder.text( "Info", - SEB_PROCTORING_FORM_INFO, + SEB_PROCTORING_FORM_INFO_TITLE, this.pageService.getI18nSupport().getText(SEB_PROCTORING_FORM_INFO)) .asArea(50) .asHTML() diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/LmsSetupForm.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/LmsSetupForm.java index bcb9d82b..6d448937 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/LmsSetupForm.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/LmsSetupForm.java @@ -29,6 +29,7 @@ import ch.ethz.seb.sebserver.gbl.model.EntityKey; import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup; import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup.LmsType; import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetupTestResult; +import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetupTestResult.Error; 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; @@ -395,7 +396,10 @@ public class LmsSetupForm implements TemplateComposer { return handleTestResult( action, - Function.identity(), + info -> { + action.pageContext().publishInfo(info); + return action; + }, result.getOrThrow()); } @@ -423,10 +427,8 @@ public class LmsSetupForm implements TemplateComposer { return handleTestResult( action, - a -> { - action.pageContext().publishInfo( - new LocTextKey("sebserver.lmssetup.action.test.ok")); - + info -> { + action.pageContext().publishInfo(info); return action; }, result.getOrThrow()); @@ -434,44 +436,52 @@ public class LmsSetupForm implements TemplateComposer { private static PageAction handleTestResult( final PageAction action, - final Function onOK, + final Function onOK, final LmsSetupTestResult testResult) { if (testResult.isOk()) { - return onOK.apply(action); + return onOK.apply(new LocTextKey("sebserver.lmssetup.action.test.ok")); } - testResult.errors + final Error error = testResult.errors .stream() .findFirst() - .ifPresent(error -> { - switch (error.errorType) { - case TOKEN_REQUEST: { - throw new PageMessageException(new LocTextKey( - "sebserver.lmssetup.action.test.tokenRequestError", - Utils.formatHTMLLinesForceEscaped(Utils.escapeHTML_XML_EcmaScript(error.message)))); - } - case QUIZ_ACCESS_API_REQUEST: { - throw new PageMessageException(new LocTextKey( - "sebserver.lmssetup.action.test.quizRequestError", - Utils.formatHTMLLinesForceEscaped(Utils.escapeHTML_XML_EcmaScript(error.message)))); - } - case QUIZ_RESTRICTION_API_REQUEST: { + .orElse(null); + if (error != null) { - throw new PageMessageException(new LocTextKey( - "sebserver.lmssetup.action.test.features.error", - "OK", - Utils.formatHTMLLinesForceEscaped(Utils.escapeHTML_XML_EcmaScript(error.message)))); - } - default: { - throw new PageMessageException(new LocTextKey( - "sebserver.lmssetup.action.test.unknownError", - Utils.formatHTMLLinesForceEscaped(Utils.escapeHTML_XML_EcmaScript(error.message)))); - } - } - }); + switch (error.errorType) { + case TOKEN_REQUEST: { + throw new PageMessageException(new LocTextKey( + "sebserver.lmssetup.action.test.tokenRequestError", + Utils.formatHTMLLinesForceEscaped(Utils.escapeHTML_XML_EcmaScript(error.message)))); + } + case QUIZ_ACCESS_API_REQUEST: { + throw new PageMessageException(new LocTextKey( + "sebserver.lmssetup.action.test.quizRequestError", + Utils.formatHTMLLinesForceEscaped(Utils.escapeHTML_XML_EcmaScript(error.message)))); + } + case QUIZ_RESTRICTION_API_REQUEST: { + final LocTextKey locTextKey = new LocTextKey( + "sebserver.lmssetup.action.test.features.error", + "OK", + Utils.formatHTMLLinesForceEscaped( + Utils.escapeHTML_XML_EcmaScript(error.message))); + return onOK.apply(locTextKey); +// throw new PageMessageException(new LocTextKey( +// "sebserver.lmssetup.action.test.features.error", +// "OK", +// Utils.formatHTMLLinesForceEscaped(Utils.escapeHTML_XML_EcmaScript(error.message)))); - return onOK.apply(action); + } + default: { + throw new PageMessageException(new LocTextKey( + "sebserver.lmssetup.action.test.unknownError", + Utils.formatHTMLLinesForceEscaped(Utils.escapeHTML_XML_EcmaScript(error.message)))); + } + } + } else { + return onOK.apply(new LocTextKey("sebserver.lmssetup.action.test.ok")); + } } } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/exam/impl/ExamJITSIProctoringService.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/exam/impl/ExamJITSIProctoringService.java index 08181616..541e9e28 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/exam/impl/ExamJITSIProctoringService.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/exam/impl/ExamJITSIProctoringService.java @@ -125,7 +125,6 @@ public class ExamJITSIProctoringService implements ExamProctoringService { final ProctoringSettings examProctoring, final String connectionToken) { - // TODO Auto-generated method stub return Result.tryCatch(() -> { final ClientConnectionData clientConnection = this.examSessionService.getConnectionData(connectionToken) .getOrThrow(); @@ -188,7 +187,6 @@ public class ExamJITSIProctoringService implements ExamProctoringService { return Result.tryCatch(() -> { - final String roomUrl = createServerConnectionURL(url, roomName); final String host = UriComponentsBuilder.fromHttpUrl(url) .build() .getHost(); @@ -206,27 +204,13 @@ public class ExamJITSIProctoringService implements ExamProctoringService { return new SEBProctoringConnectionData( connectionToken, host, - roomUrl, + url, roomName, subject, token); }); } - private String createServerConnectionURL( - final String url, - final String roomName) { - - final StringBuilder builder = new StringBuilder(); - builder.append(url); - if (!url.endsWith(Constants.URL_PATH_SEPARATOR)) { - builder.append(Constants.URL_PATH_SEPARATOR); - } - - return builder.append(roomName) - .toString(); - } - private String createAccessToken( final String appKey, final CharSequence appSecret, diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/MoodleRestTemplateFactory.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/MoodleRestTemplateFactory.java index 08c76ff7..e9b6c339 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/MoodleRestTemplateFactory.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/MoodleRestTemplateFactory.java @@ -225,7 +225,7 @@ class MoodleRestTemplateFactory { MoodleRestTemplateFactory.this.jsonMapper.readValue(apiInfo, WebserviceInfo.class); if (StringUtils.isBlank(webserviceInfo.username) || StringUtils.isBlank(webserviceInfo.userid)) { - throw new RuntimeException("Ivalid WebserviceInfo: " + webserviceInfo); + throw new RuntimeException("Invalid WebserviceInfo: " + webserviceInfo); } final List missingAPIFunctions = Arrays.stream(functions) diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/APIExceptionHandler.java b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/APIExceptionHandler.java index dcf3da84..2b56b838 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/APIExceptionHandler.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/APIExceptionHandler.java @@ -86,19 +86,19 @@ public class APIExceptionHandler extends ResponseEntityExceptionHandler { Utils.createJsonContentHeader(), HttpStatus.BAD_REQUEST); } -// -// @ExceptionHandler(RuntimeException.class) -// public ResponseEntity handleRuntimeException( -// final RuntimeException ex, -// final WebRequest request) { -// -// log.error("Unexpected generic error catched at the API endpoint: ", ex); -// final List errors = Arrays.asList(APIMessage.ErrorMessage.GENERIC.of(ex.getMessage())); -// return new ResponseEntity<>( -// errors, -// Utils.createJsonContentHeader(), -// HttpStatus.INTERNAL_SERVER_ERROR); -// } + + @ExceptionHandler(RuntimeException.class) + public ResponseEntity handleRuntimeException( + final RuntimeException ex, + final WebRequest request) { + + log.error("Unexpected generic error catched at the API endpoint: ", ex); + final List errors = Arrays.asList(APIMessage.ErrorMessage.GENERIC.of(ex.getMessage())); + return new ResponseEntity<>( + errors, + Utils.createJsonContentHeader(), + HttpStatus.INTERNAL_SERVER_ERROR); + } @ExceptionHandler(OnlyMessageLogExceptionWrapper.class) public ResponseEntity onlyMessageLogExceptionWrapper( diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties index a4cc2ade..1e8ebb32 100644 --- a/src/main/resources/messages.properties +++ b/src/main/resources/messages.properties @@ -624,7 +624,8 @@ sebserver.exam.delete.report.list.empty=No dependencies will be deleted. sebserver.exam.proctoring.actions.open=Set Proctoring sebserver.exam.proctoring.form.title=Exam Proctoring Settings -sebserver.exam.proctoring.form.info=This allows to integrate a supported external proctoring service. +sebserver.exam.proctoring.form.info.title=Remote Proctoring +sebserver.exam.proctoring.form.info=This allows you to integrate a supported external proctoring service. sebserver.exam.proctoring.form.enabled=Proctoring enabled sebserver.exam.proctoring.form.enabled.tooltip=Indicates whether the exam proctoring feature is enabled for this exam or not. sebserver.exam.proctoring.form.type=Type diff --git a/src/test/java/ch/ethz/seb/sebserver/webservice/servicelayer/exam/impl/ExamJITSIProctoringServiceTest.java b/src/test/java/ch/ethz/seb/sebserver/webservice/servicelayer/exam/impl/ExamJITSIProctoringServiceTest.java index f1a5943f..f8c3eba8 100644 --- a/src/test/java/ch/ethz/seb/sebserver/webservice/servicelayer/exam/impl/ExamJITSIProctoringServiceTest.java +++ b/src/test/java/ch/ethz/seb/sebserver/webservice/servicelayer/exam/impl/ExamJITSIProctoringServiceTest.java @@ -39,7 +39,7 @@ public class ExamJITSIProctoringServiceTest { assertNotNull(data); assertEquals( - "https://seb-jitsi.example.ch/SomeRoom", + "https://seb-jitsi.example.ch", data.serverURL); assertEquals( "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjb250ZXh0Ijp7InVzZXIiOnsibmFtZSI6IlRlc3QgTmFtZSJ9fSwiaXNzIjoidGVzdC1hcHAiLCJhdWQiOiJ0ZXN0LWNsaWVudCIsInN1YiI6InNlYi1qaXRzaS5leGFtcGxlLmNoIiwicm9vbSI6IlNvbWVSb29tIiwiZXhwIjoxNjA5NDU5MjAwfQ.4ovqUkG6jrLvkDEZNdhbtFI_DFLDFsM2eBJHhcYq7a4",