SEBSERV-382

This commit is contained in:
anhefti 2023-02-08 13:15:17 +01:00
parent 80af47e14e
commit c26f8da944
7 changed files with 70 additions and 48 deletions

View file

@ -61,7 +61,7 @@ public class AllowedSEBVersion {
valid = false;
}
this.minor = num;
if (split.length >= 3) {
if (split.length > 3) {
try {
num = Integer.valueOf(split[3]);
} catch (final Exception e) {

View file

@ -83,11 +83,6 @@ public class ProctoringSettingsPopup {
private final static LocTextKey SEB_PROCTORING_FORM_SECRET_JITSI =
new LocTextKey("sebserver.exam.proctoring.form.secret.jitsi");
private final static LocTextKey SEB_PROCTORING_FORM_APPKEY_ZOOM =
new LocTextKey("sebserver.exam.proctoring.form.appkey.zoom");
private final static LocTextKey SEB_PROCTORING_FORM_SECRET_ZOOM =
new LocTextKey("sebserver.exam.proctoring.form.secret.zoom");
private final static LocTextKey SEB_PROCTORING_FORM_ACCOUNT_ID =
new LocTextKey("sebserver.exam.proctoring.form.accountId");
private final static LocTextKey SEB_PROCTORING_FORM_CLIENT_ID =
@ -113,6 +108,8 @@ public class ProctoringSettingsPopup {
new LocTextKey("sebserver.exam.proctoring.form.resetConfirm");
private final static LocTextKey RESET_ACTIVE_CON_KEY =
new LocTextKey("sebserver.exam.proctoring.form.resetActive");
private final static LocTextKey RESET_SUCCESS_KEY =
new LocTextKey("sebserver.exam.proctoring.form.resetOk");
Function<PageAction, PageAction> settingsFunction(final PageService pageService, final boolean modifyGrant) {
@ -144,16 +141,19 @@ public class ProctoringSettingsPopup {
}
});
final Button reset = widgetFactory.buttonLocalized(composite, RESET_TEXT_KEY);
reset.setLayoutData(new RowData());
reset.addListener(SWT.Selection, event -> {
pageContext.applyConfirmDialog(RESET_CONFIRM_KEY, apply -> {
if (apply && doResetSettings(pageService, pageContext)) {
dialog.close();
}
final EntityKey entityKey = pageContext.getEntityKey();
if (entityKey.entityType == EntityType.EXAM) {
final Button reset = widgetFactory.buttonLocalized(composite, RESET_TEXT_KEY);
reset.setLayoutData(new RowData());
reset.addListener(SWT.Selection, event -> {
pageContext.applyConfirmDialog(RESET_CONFIRM_KEY, apply -> {
if (apply && doResetSettings(pageService, pageContext)) {
dialog.close();
}
});
});
});
resetButtonHandler.set(reset);
resetButtonHandler.set(reset);
}
};
final SEBProctoringPropertiesForm bindFormContext = new SEBProctoringPropertiesForm(
@ -208,16 +208,10 @@ public class ProctoringSettingsPopup {
.getBuilder(ResetProctoringSettings.class)
.withURIVariable(API.PARAM_MODEL_ID, entityKey.modelId)
.call()
.onError(error -> {
if (error.getMessage().contains("active connections") ||
(error.getCause() != null &&
error.getCause().getMessage().contains("active connections"))) {
pageContext.publishInfo(RESET_ACTIVE_CON_KEY);
} else {
log.error("Failed to rest proctoring settings for exam: {}", entityKey, error);
pageContext.notifyUnexpectedError(error);
}
}).map(settings -> true).getOr(false);
.onError(error -> handleResetError(pageContext, entityKey, error))
.onSuccess(settings -> pageContext.publishInfo(RESET_SUCCESS_KEY))
.map(settings -> true)
.getOr(false);
}
private boolean doSaveSettings(
@ -451,19 +445,6 @@ public class ProctoringSettingsPopup {
proctoringSettings.serverURL)
.mandatory())
.addField(FormBuilder.text(
ProctoringServiceSettings.ATTR_APP_KEY,
SEB_PROCTORING_FORM_APPKEY_ZOOM,
proctoringSettings.appKey))
.withEmptyCellSeparation(false)
.addField(FormBuilder.password(
ProctoringServiceSettings.ATTR_APP_SECRET,
SEB_PROCTORING_FORM_SECRET_ZOOM,
(proctoringSettings.appSecret != null)
? String.valueOf(proctoringSettings.appSecret)
: null))
.addField(FormBuilder.text(
ProctoringServiceSettings.ATTR_ACCOUNT_ID,
SEB_PROCTORING_FORM_ACCOUNT_ID,
@ -559,11 +540,20 @@ public class ProctoringSettingsPopup {
}
}
private static final class FormHandleAnchor {
private void handleResetError(final PageContext pageContext, final EntityKey entityKey, final Exception error) {
if (error.getMessage().contains("active connections") ||
(error.getCause() != null &&
error.getCause().getMessage().contains("active connections"))) {
pageContext.publishInfo(RESET_ACTIVE_CON_KEY);
} else {
log.error("Failed to rest proctoring settings for exam: {}", entityKey, error);
pageContext.notifyUnexpectedError(error);
}
}
private static final class FormHandleAnchor {
FormHandle<ProctoringServiceSettings> formHandle;
PageContext formContext;
}
}

View file

@ -63,6 +63,8 @@ public class ClientConnectionDetails implements MonitoringEntry {
new LocTextKey("sebserver.monitoring.connection.form.info");
private final static LocTextKey CONNECTION_STATUS_TEXT_KEY =
new LocTextKey("sebserver.monitoring.connection.form.status");
private final static LocTextKey WRONG_SEB_CLIENT_TOOLTIP =
new LocTextKey("sebserver.finished.connection.form.info.wrong.client.tooltip");
private static final int NUMBER_OF_NONE_INDICATOR_ROWS = 3;
@ -130,12 +132,15 @@ public class ClientConnectionDetails implements MonitoringEntry {
CONNECTION_GROUP_TEXT_KEY,
Constants.EMPTY_NOTE)
.asMarkupLabel())
.withDefaultSpanInput(3)
.addField(FormBuilder.text(
ClientConnection.ATTR_INFO,
CONNECTION_INFO_TEXT_KEY,
Constants.EMPTY_NOTE)
.asArea(50)
.asColorBox())
.withDefaultSpanEmptyCell(2)
.withDefaultSpanInput(3)
.addField(FormBuilder.text(
Domain.CLIENT_CONNECTION.ATTR_STATUS,
@ -322,6 +327,8 @@ public class ClientConnectionDetails implements MonitoringEntry {
if (this.connectionData.clientConnection.clientVersionGranted != null &&
!this.connectionData.clientConnection.clientVersionGranted) {
form.setFieldColor(ClientConnection.ATTR_INFO, this.colorData.color2);
form.getFieldInput(ClientConnection.ATTR_INFO)
.setToolTipText(this.pageService.getI18nSupport().getText(WRONG_SEB_CLIENT_TOOLTIP));
}
}

View file

@ -195,8 +195,8 @@ public class ZoomProctoringService implements ExamProctoringService {
proctoringSettings.collectingRoomSize,
proctoringSettings.enabledFeatures,
proctoringSettings.serviceInUse,
proctoringSettings.appKey,
this.cryptor.encrypt(proctoringSettings.appSecret).getOrThrow(),
null,
null,
proctoringSettings.accountId,
proctoringSettings.clientId,
this.cryptor.encrypt(proctoringSettings.clientSecret).getOrThrow(),

View file

@ -55,6 +55,30 @@ public class ProctoringSettingsValidator
}
if (value.serverType == ProctoringServerType.ZOOM) {
if (StringUtils.isBlank(value.accountId)) {
context.disableDefaultConstraintViolation();
context
.buildConstraintViolationWithTemplate("proctoringSettings:accountId:notNull")
.addPropertyNode("accountId").addConstraintViolation();
passed = false;
}
if (StringUtils.isBlank(value.clientId)) {
context.disableDefaultConstraintViolation();
context
.buildConstraintViolationWithTemplate("proctoringSettings:clientId:notNull")
.addPropertyNode("clientId").addConstraintViolation();
passed = false;
}
if (StringUtils.isBlank(value.clientSecret)) {
context.disableDefaultConstraintViolation();
context
.buildConstraintViolationWithTemplate("proctoringSettings:clientSecret:notNull")
.addPropertyNode("clientSecret").addConstraintViolation();
passed = false;
}
if (StringUtils.isBlank(value.sdkKey)) {
context.disableDefaultConstraintViolation();
context

View file

@ -500,7 +500,7 @@ public class ExamAdministrationController extends EntityController<Exam, Exam> {
+ API.EXAM_ADMINISTRATION_PROCTORING_RESET_PATH_SEGMENT,
method = RequestMethod.POST,
produces = MediaType.APPLICATION_JSON_VALUE)
public Exam resetProctoringServiceSettings(
public Exam resetProctoringRooms(
@RequestParam(
name = API.PARAM_INSTITUTION_ID,
required = true,
@ -520,7 +520,6 @@ public class ExamAdministrationController extends EntityController<Exam, Exam> {
error.getMessage()));
return exam;
})
.flatMap(this.examAdminService::resetProctoringSettings)
.getOrThrow();
}

View file

@ -833,9 +833,10 @@ sebserver.exam.proctoring.form.features.RESET_BROADCAST_ON_LAVE=Reset broadcast
sebserver.exam.proctoring.form.useZoomAppClient=Use Zoom App-Client
sebserver.exam.proctoring.form.useZoomAppClient.tooltip=If this is set SEB Server opens a start link for the meeting instead of a new popup-window with the Zoom Web Client.<br/>A Zoom App Client must already be installed on the proctor's device or can be installed by following the instructions shown in the browser window.
sebserver.exam.proctoring.form.saveSettings=Save Settings
sebserver.exam.proctoring.form.resetSettings=Reset Settings
sebserver.exam.proctoring.form.resetConfirm=Reset will first cleanup and remove all existing proctoring rooms for this exam and then reset to default or template settings.<br/>Please make sure there are no active SEB client connections for this exam, otherwise this reset will be denied.<br/><br/>Do you want to reset proctoring for this exam now?
sebserver.exam.proctoring.form.resetSettings=Reset Rooms
sebserver.exam.proctoring.form.resetConfirm=Reset will cleanup and remove all existing proctoring rooms for this exam.<br/>So you are able to switch to another proctoring service or just for cleanup and testing purposes.
sebserver.exam.proctoring.form.resetActive=There are still active SEB client connection for this exam. Please disconnect or cancel them first.<br/>This action is only possible when there are no active SEB client connection within this exam.
sebserver.exam.proctoring.form.resetOk=Successfully deleted all existing proctoring rooms for this exam.
sebserver.exam.proctoring.type.servertype.JITSI_MEET=Jitsi Meet Server
sebserver.exam.proctoring.type.servertype.JITSI_MEET.tooltip=Use a Jitsi Meet server for proctoring
@ -1840,7 +1841,7 @@ sebserver.examconfig.props.label.terminateProcesses.tooltip=SEB will attempt to
sebserver.examconfig.props.label.prohibitedProcesses.ignoreInAAC=Ignore in AAC
sebserver.examconfig.props.label.prohibitedProcesses.ignoreInAAC.tooltip=When using the AAC kiosk mode (which prevents network and screen access for other processes), ignore this prohibited process
sebserver.examconfig.props.label.sebAllowedVersions=Allowed SEB Versions
sebserver.examconfig.props.label.sebAllowedVersions.tooltip=List of text inputs which represent either a specific or a minimal SEB version which is allowed to access the (exam) session using current settings.<br/>The version string has the following format: [OS.mayor.minor.patch(.minimal)], OS and mayor version are mandatory,<br/>"minimal" indicates if version shall be interpreted as minimal version this and all above are valid.
sebserver.examconfig.props.label.sebAllowedVersions.tooltip=List of text inputs which represent either a specific or a minimal SEB version which is allowed to access the (exam) session using current settings.<br/>The version string has the following format: [OS.mayor.minor.patch(.AE)(.minimal)], OS and mayor version are mandatory,<br/>OS is either "Win", "Mac" or "iOS", "minimal" indicates if version shall be interpreted as minimal version this and all above are valid. AE indicates a Alliance Edition version.
sebserver.examconfig.props.label.sebAllowedVersions.addAction=Add new allowed SEB version
sebserver.examconfig.props.label.sebAllowedVersions.deleteAction=Delete allowed SEB version
sebserver.examconfig.props.validation.SEBVersionValidator=At least one SEB Version has wrong format
@ -2275,7 +2276,8 @@ sebserver.finished.exam.connection.title=SEB Client Connection
sebserver.finished.connection.form.id=User Name or Session
sebserver.finished.connection.form.id.tooltip=The user session identifier or username sent by the SEB client after LMS login
sebserver.finished.connection.form.info=Connection Info
sebserver.finished.connection.form.info.tooltip=Format: IP Address,SEB Version, OSName
sebserver.finished.connection.form.info.tooltip=SEB Version, OSName and IP Address
sebserver.finished.connection.form.info.wrong.client.tooltip:This SEB client version is not allowed due to the allowed SEB client setting of the exam configuration for this exam.
sebserver.finished.connection.form.status=Status
sebserver.finished.connection.form.status.tooltip=The current connection status
sebserver.finished.connection.form.exam=Exam