fixed moodle and proctoring

This commit is contained in:
anhefti 2020-09-29 17:48:50 +02:00
parent 257b400e1a
commit 1da749a473
9 changed files with 81 additions and 74 deletions

View file

@ -104,8 +104,12 @@ public class ClientHttpRequestFactoryService {
/** A ClientHttpRequestFactory for development profile with no TSL SSL protocol and /** A ClientHttpRequestFactory for development profile with no TSL SSL protocol and
* not following redirects on redirect responses. * not following redirects on redirect responses.
* *
* @return ClientHttpRequestFactory bean for development profiles */ * @return ClientHttpRequestFactory bean for development profiles
private ClientHttpRequestFactory clientHttpRequestFactory(final ProxyData proxy) { * @throws KeyStoreException
* @throws NoSuchAlgorithmException
* @throws KeyManagementException */
private ClientHttpRequestFactory clientHttpRequestFactory(final ProxyData proxy)
throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException {
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("Initialize ClientHttpRequestFactory with insecure ClientHttpRequestFactory for development"); log.debug("Initialize ClientHttpRequestFactory with insecure ClientHttpRequestFactory for development");

View file

@ -43,11 +43,17 @@ public class GuiServiceInfo {
this.externalPort = externalPort; this.externalPort = externalPort;
this.entryPoint = entryPoint; this.entryPoint = entryPoint;
this.internalServerURIBuilder = UriComponentsBuilder this.internalServerURIBuilder = UriComponentsBuilder
.fromHttpUrl("http://" + this.internalServer) .fromHttpUrl("http://" + this.internalServer);
.port(this.internalPort); if (StringUtils.isNotBlank(internalPort)) {
this.internalServerURIBuilder.port(this.internalPort);
}
this.externalServerURIBuilder = UriComponentsBuilder this.externalServerURIBuilder = UriComponentsBuilder
.fromHttpUrl(this.externalScheme + "://" + this.externalServer) .fromHttpUrl(this.externalScheme + "://" + this.externalServer);
.port(this.externalPort); if (StringUtils.isNotBlank(externalPort)) {
this.externalServerURIBuilder.port(this.externalPort);
} else if (StringUtils.isNotBlank(internalPort)) {
this.externalServerURIBuilder.port(this.internalPort);
}
} }
public String getExternalScheme() { public String getExternalScheme() {

View file

@ -52,6 +52,8 @@ public class ExamProctoringSettings {
new LocTextKey("sebserver.exam.proctoring.form.title"); new LocTextKey("sebserver.exam.proctoring.form.title");
private final static LocTextKey SEB_PROCTORING_FORM_INFO = private final static LocTextKey SEB_PROCTORING_FORM_INFO =
new LocTextKey("sebserver.exam.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 = private final static LocTextKey SEB_PROCTORING_FORM_ENABLE =
new LocTextKey("sebserver.exam.proctoring.form.enabled"); new LocTextKey("sebserver.exam.proctoring.form.enabled");
private final static LocTextKey SEB_PROCTORING_FORM_TYPE = private final static LocTextKey SEB_PROCTORING_FORM_TYPE =
@ -200,7 +202,7 @@ public class ExamProctoringSettings {
.addField(FormBuilder.text( .addField(FormBuilder.text(
"Info", "Info",
SEB_PROCTORING_FORM_INFO, SEB_PROCTORING_FORM_INFO_TITLE,
this.pageService.getI18nSupport().getText(SEB_PROCTORING_FORM_INFO)) this.pageService.getI18nSupport().getText(SEB_PROCTORING_FORM_INFO))
.asArea(50) .asArea(50)
.asHTML() .asHTML()

View file

@ -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;
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup.LmsType; 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;
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.UserInfo;
import ch.ethz.seb.sebserver.gbl.model.user.UserRole; import ch.ethz.seb.sebserver.gbl.model.user.UserRole;
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile; import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
@ -395,7 +396,10 @@ public class LmsSetupForm implements TemplateComposer {
return handleTestResult( return handleTestResult(
action, action,
Function.identity(), info -> {
action.pageContext().publishInfo(info);
return action;
},
result.getOrThrow()); result.getOrThrow());
} }
@ -423,10 +427,8 @@ public class LmsSetupForm implements TemplateComposer {
return handleTestResult( return handleTestResult(
action, action,
a -> { info -> {
action.pageContext().publishInfo( action.pageContext().publishInfo(info);
new LocTextKey("sebserver.lmssetup.action.test.ok"));
return action; return action;
}, },
result.getOrThrow()); result.getOrThrow());
@ -434,44 +436,52 @@ public class LmsSetupForm implements TemplateComposer {
private static PageAction handleTestResult( private static PageAction handleTestResult(
final PageAction action, final PageAction action,
final Function<PageAction, PageAction> onOK, final Function<LocTextKey, PageAction> onOK,
final LmsSetupTestResult testResult) { final LmsSetupTestResult testResult) {
if (testResult.isOk()) { 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() .stream()
.findFirst() .findFirst()
.ifPresent(error -> { .orElse(null);
switch (error.errorType) { if (error != null) {
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: {
throw new PageMessageException(new LocTextKey( switch (error.errorType) {
"sebserver.lmssetup.action.test.features.error", case TOKEN_REQUEST: {
"OK", throw new PageMessageException(new LocTextKey(
Utils.formatHTMLLinesForceEscaped(Utils.escapeHTML_XML_EcmaScript(error.message)))); "sebserver.lmssetup.action.test.tokenRequestError",
} Utils.formatHTMLLinesForceEscaped(Utils.escapeHTML_XML_EcmaScript(error.message))));
default: { }
throw new PageMessageException(new LocTextKey( case QUIZ_ACCESS_API_REQUEST: {
"sebserver.lmssetup.action.test.unknownError", throw new PageMessageException(new LocTextKey(
Utils.formatHTMLLinesForceEscaped(Utils.escapeHTML_XML_EcmaScript(error.message)))); "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"));
}
} }
} }

View file

@ -125,7 +125,6 @@ public class ExamJITSIProctoringService implements ExamProctoringService {
final ProctoringSettings examProctoring, final ProctoringSettings examProctoring,
final String connectionToken) { final String connectionToken) {
// TODO Auto-generated method stub
return Result.tryCatch(() -> { return Result.tryCatch(() -> {
final ClientConnectionData clientConnection = this.examSessionService.getConnectionData(connectionToken) final ClientConnectionData clientConnection = this.examSessionService.getConnectionData(connectionToken)
.getOrThrow(); .getOrThrow();
@ -188,7 +187,6 @@ public class ExamJITSIProctoringService implements ExamProctoringService {
return Result.tryCatch(() -> { return Result.tryCatch(() -> {
final String roomUrl = createServerConnectionURL(url, roomName);
final String host = UriComponentsBuilder.fromHttpUrl(url) final String host = UriComponentsBuilder.fromHttpUrl(url)
.build() .build()
.getHost(); .getHost();
@ -206,27 +204,13 @@ public class ExamJITSIProctoringService implements ExamProctoringService {
return new SEBProctoringConnectionData( return new SEBProctoringConnectionData(
connectionToken, connectionToken,
host, host,
roomUrl, url,
roomName, roomName,
subject, subject,
token); 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( private String createAccessToken(
final String appKey, final String appKey,
final CharSequence appSecret, final CharSequence appSecret,

View file

@ -225,7 +225,7 @@ class MoodleRestTemplateFactory {
MoodleRestTemplateFactory.this.jsonMapper.readValue(apiInfo, WebserviceInfo.class); MoodleRestTemplateFactory.this.jsonMapper.readValue(apiInfo, WebserviceInfo.class);
if (StringUtils.isBlank(webserviceInfo.username) || StringUtils.isBlank(webserviceInfo.userid)) { if (StringUtils.isBlank(webserviceInfo.username) || StringUtils.isBlank(webserviceInfo.userid)) {
throw new RuntimeException("Ivalid WebserviceInfo: " + webserviceInfo); throw new RuntimeException("Invalid WebserviceInfo: " + webserviceInfo);
} }
final List<String> missingAPIFunctions = Arrays.stream(functions) final List<String> missingAPIFunctions = Arrays.stream(functions)

View file

@ -86,19 +86,19 @@ public class APIExceptionHandler extends ResponseEntityExceptionHandler {
Utils.createJsonContentHeader(), Utils.createJsonContentHeader(),
HttpStatus.BAD_REQUEST); HttpStatus.BAD_REQUEST);
} }
//
// @ExceptionHandler(RuntimeException.class) @ExceptionHandler(RuntimeException.class)
// public ResponseEntity<Object> handleRuntimeException( public ResponseEntity<Object> handleRuntimeException(
// final RuntimeException ex, final RuntimeException ex,
// final WebRequest request) { final WebRequest request) {
//
// log.error("Unexpected generic error catched at the API endpoint: ", ex); log.error("Unexpected generic error catched at the API endpoint: ", ex);
// final List<APIMessage> errors = Arrays.asList(APIMessage.ErrorMessage.GENERIC.of(ex.getMessage())); final List<APIMessage> errors = Arrays.asList(APIMessage.ErrorMessage.GENERIC.of(ex.getMessage()));
// return new ResponseEntity<>( return new ResponseEntity<>(
// errors, errors,
// Utils.createJsonContentHeader(), Utils.createJsonContentHeader(),
// HttpStatus.INTERNAL_SERVER_ERROR); HttpStatus.INTERNAL_SERVER_ERROR);
// } }
@ExceptionHandler(OnlyMessageLogExceptionWrapper.class) @ExceptionHandler(OnlyMessageLogExceptionWrapper.class)
public ResponseEntity<Object> onlyMessageLogExceptionWrapper( public ResponseEntity<Object> onlyMessageLogExceptionWrapper(

View file

@ -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.actions.open=Set Proctoring
sebserver.exam.proctoring.form.title=Exam Proctoring Settings 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=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.enabled.tooltip=Indicates whether the exam proctoring feature is enabled for this exam or not.
sebserver.exam.proctoring.form.type=Type sebserver.exam.proctoring.form.type=Type

View file

@ -39,7 +39,7 @@ public class ExamJITSIProctoringServiceTest {
assertNotNull(data); assertNotNull(data);
assertEquals( assertEquals(
"https://seb-jitsi.example.ch/SomeRoom", "https://seb-jitsi.example.ch",
data.serverURL); data.serverURL);
assertEquals( assertEquals(
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjb250ZXh0Ijp7InVzZXIiOnsibmFtZSI6IlRlc3QgTmFtZSJ9fSwiaXNzIjoidGVzdC1hcHAiLCJhdWQiOiJ0ZXN0LWNsaWVudCIsInN1YiI6InNlYi1qaXRzaS5leGFtcGxlLmNoIiwicm9vbSI6IlNvbWVSb29tIiwiZXhwIjoxNjA5NDU5MjAwfQ.4ovqUkG6jrLvkDEZNdhbtFI_DFLDFsM2eBJHhcYq7a4", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjb250ZXh0Ijp7InVzZXIiOnsibmFtZSI6IlRlc3QgTmFtZSJ9fSwiaXNzIjoidGVzdC1hcHAiLCJhdWQiOiJ0ZXN0LWNsaWVudCIsInN1YiI6InNlYi1qaXRzaS5leGFtcGxlLmNoIiwicm9vbSI6IlNvbWVSb29tIiwiZXhwIjoxNjA5NDU5MjAwfQ.4ovqUkG6jrLvkDEZNdhbtFI_DFLDFsM2eBJHhcYq7a4",