try proctoring popup with RAP Browser tool and new RAPServlet mapping

This commit is contained in:
anhefti 2020-10-05 15:20:14 +02:00
parent 0e806b99bb
commit 99bc028208
9 changed files with 75 additions and 10 deletions

View file

@ -33,6 +33,7 @@ public class ProctoringSettings implements Entity {
public static final String ATTR_SERVER_URL = "serverURL"; public static final String ATTR_SERVER_URL = "serverURL";
public static final String ATTR_APP_KEY = "appKey"; public static final String ATTR_APP_KEY = "appKey";
public static final String ATTR_APP_SECRET = "appSecret"; public static final String ATTR_APP_SECRET = "appSecret";
public static final String ATTR_COLLECTING_ROOM_SIZE = "collectingRoomSize";
@JsonProperty(Domain.EXAM.ATTR_ID) @JsonProperty(Domain.EXAM.ATTR_ID)
public final Long examId; public final Long examId;
@ -53,12 +54,16 @@ public class ProctoringSettings implements Entity {
@JsonProperty(ATTR_APP_SECRET) @JsonProperty(ATTR_APP_SECRET)
public final CharSequence appSecret; public final CharSequence appSecret;
@JsonProperty(ATTR_COLLECTING_ROOM_SIZE)
public final Long collectingRoomSize;
@JsonCreator @JsonCreator
public ProctoringSettings( public ProctoringSettings(
@JsonProperty(Domain.EXAM.ATTR_ID) final Long examId, @JsonProperty(Domain.EXAM.ATTR_ID) final Long examId,
@JsonProperty(ATTR_ENABLE_PROCTORING) final Boolean enableProctoring, @JsonProperty(ATTR_ENABLE_PROCTORING) final Boolean enableProctoring,
@JsonProperty(ATTR_SERVER_TYPE) final ServerType serverType, @JsonProperty(ATTR_SERVER_TYPE) final ServerType serverType,
@JsonProperty(ATTR_SERVER_URL) final String serverURL, @JsonProperty(ATTR_SERVER_URL) final String serverURL,
@JsonProperty(ATTR_COLLECTING_ROOM_SIZE) final Long collectingRoomSize,
@JsonProperty(ATTR_APP_KEY) final String appKey, @JsonProperty(ATTR_APP_KEY) final String appKey,
@JsonProperty(ATTR_APP_SECRET) final CharSequence appSecret) { @JsonProperty(ATTR_APP_SECRET) final CharSequence appSecret) {
@ -66,6 +71,7 @@ public class ProctoringSettings implements Entity {
this.enableProctoring = BooleanUtils.isTrue(enableProctoring); this.enableProctoring = BooleanUtils.isTrue(enableProctoring);
this.serverType = (serverType != null) ? serverType : ServerType.JITSI_MEET; this.serverType = (serverType != null) ? serverType : ServerType.JITSI_MEET;
this.serverURL = serverURL; this.serverURL = serverURL;
this.collectingRoomSize = (collectingRoomSize != null) ? collectingRoomSize : 20;
this.appKey = appKey; this.appKey = appKey;
this.appSecret = appSecret; this.appSecret = appSecret;
} }
@ -101,6 +107,10 @@ public class ProctoringSettings implements Entity {
return this.serverURL; return this.serverURL;
} }
public Long getCollectingRoomSize() {
return this.collectingRoomSize;
}
public String getAppKey() { public String getAppKey() {
return this.appKey; return this.appKey;
} }
@ -140,7 +150,7 @@ public class ProctoringSettings implements Entity {
@Override @Override
public String toString() { public String toString() {
final StringBuilder builder = new StringBuilder(); final StringBuilder builder = new StringBuilder();
builder.append("ExamProctoring [examId="); builder.append("ProctoringSettings [examId=");
builder.append(this.examId); builder.append(this.examId);
builder.append(", enableProctoring="); builder.append(", enableProctoring=");
builder.append(this.enableProctoring); builder.append(this.enableProctoring);
@ -148,10 +158,8 @@ public class ProctoringSettings implements Entity {
builder.append(this.serverType); builder.append(this.serverType);
builder.append(", serverURL="); builder.append(", serverURL=");
builder.append(this.serverURL); builder.append(this.serverURL);
builder.append(", appKey="); builder.append(", collectingRoomSize=");
builder.append(this.appKey); builder.append(this.collectingRoomSize);
builder.append(", appSecret=");
builder.append("--");
builder.append("]"); builder.append("]");
return builder.toString(); return builder.toString();
} }

View file

@ -51,6 +51,8 @@ public class GuiWebsecurityConfig extends WebSecurityConfigurerAdapter {
.ignoring() .ignoring()
.requestMatchers(PUBLIC_URLS) .requestMatchers(PUBLIC_URLS)
.antMatchers(this.guiEntryPoint) .antMatchers(this.guiEntryPoint)
.antMatchers("/proc*")
.antMatchers("/proc/*")
.antMatchers("/proctoring/*"); .antMatchers("/proctoring/*");
} }

View file

@ -55,6 +55,21 @@ public class RAPConfiguration implements ApplicationConfiguration {
properties.put(WebClient.THEME_ID, DEFAULT_THEME_NAME); properties.put(WebClient.THEME_ID, DEFAULT_THEME_NAME);
// properties.put(WebClient.FAVICON, "icons/favicon.png"); // properties.put(WebClient.FAVICON, "icons/favicon.png");
application.addEntryPoint("/gui", new RAPSpringEntryPointFactory(), properties); application.addEntryPoint("/gui", new RAPSpringEntryPointFactory(), properties);
application.addEntryPoint("/proc", new EntryPointFactory() {
@Override
public EntryPoint create() {
return new AbstractEntryPoint() {
private static final long serialVersionUID = -1299125117752916270L;
@Override
protected void createContents(final Composite parent) {
System.out.print("******");
}
};
}
}, properties);
} catch (final RuntimeException re) { } catch (final RuntimeException re) {
throw re; throw re;

View file

@ -57,6 +57,11 @@ public class RAPSpringConfig {
return new ServletRegistrationBean<>(new RWTServlet(), this.entrypoint + "/*"); return new ServletRegistrationBean<>(new RWTServlet(), this.entrypoint + "/*");
} }
@Bean
public ServletRegistrationBean<RWTServlet> servletRegistrationBeanProc() {
return new ServletRegistrationBean<>(new RWTServlet(), "/proc/*");
}
@Bean @Bean
public ServletRegistrationBean<ProctoringServlet> servletProctoringRegistrationBean( public ServletRegistrationBean<ProctoringServlet> servletProctoringRegistrationBean(
final ApplicationContext applicationContext) { final ApplicationContext applicationContext) {

View file

@ -60,6 +60,8 @@ public class ExamProctoringSettings {
new LocTextKey("sebserver.exam.proctoring.form.type"); new LocTextKey("sebserver.exam.proctoring.form.type");
private final static LocTextKey SEB_PROCTORING_FORM_URL = private final static LocTextKey SEB_PROCTORING_FORM_URL =
new LocTextKey("sebserver.exam.proctoring.form.url"); new LocTextKey("sebserver.exam.proctoring.form.url");
private final static LocTextKey SEB_PROCTORING_FORM_ROOM_SIZE =
new LocTextKey("sebserver.exam.proctoring.form.collectingRoomSize");
private final static LocTextKey SEB_PROCTORING_FORM_APPKEY = private final static LocTextKey SEB_PROCTORING_FORM_APPKEY =
new LocTextKey("sebserver.exam.proctoring.form.appkey"); new LocTextKey("sebserver.exam.proctoring.form.appkey");
private final static LocTextKey SEB_PROCTORING_FORM_SECRET = private final static LocTextKey SEB_PROCTORING_FORM_SECRET =
@ -123,6 +125,7 @@ public class ExamProctoringSettings {
enabled, enabled,
serverType, serverType,
form.getFieldValue(ProctoringSettings.ATTR_SERVER_URL), form.getFieldValue(ProctoringSettings.ATTR_SERVER_URL),
Long.parseLong(form.getFieldValue(ProctoringSettings.ATTR_COLLECTING_ROOM_SIZE)),
form.getFieldValue(ProctoringSettings.ATTR_APP_KEY), form.getFieldValue(ProctoringSettings.ATTR_APP_KEY),
form.getFieldValue(ProctoringSettings.ATTR_APP_SECRET)); form.getFieldValue(ProctoringSettings.ATTR_APP_SECRET));
@ -196,8 +199,9 @@ public class ExamProctoringSettings {
final FormHandle<ProctoringSettings> formHandle = this.pageService.formBuilder( final FormHandle<ProctoringSettings> formHandle = this.pageService.formBuilder(
formContext) formContext)
.withDefaultSpanInput(6) .withDefaultSpanInput(5)
.withEmptyCellSeparation(false) .withEmptyCellSeparation(true)
.withDefaultSpanEmptyCell(1)
.readonly(isReadonly) .readonly(isReadonly)
.addField(FormBuilder.text( .addField(FormBuilder.text(
@ -223,11 +227,21 @@ public class ExamProctoringSettings {
ProctoringSettings.ATTR_SERVER_URL, ProctoringSettings.ATTR_SERVER_URL,
SEB_PROCTORING_FORM_URL, SEB_PROCTORING_FORM_URL,
proctoringSettings.serverURL)) proctoringSettings.serverURL))
.withDefaultSpanInput(1)
.addField(FormBuilder.text(
ProctoringSettings.ATTR_COLLECTING_ROOM_SIZE,
SEB_PROCTORING_FORM_ROOM_SIZE,
String.valueOf(proctoringSettings.getCollectingRoomSize()))
.asNumber(numString -> Long.parseLong(numString)))
.withDefaultSpanInput(5)
.withDefaultSpanEmptyCell(4)
.addField(FormBuilder.text( .addField(FormBuilder.text(
ProctoringSettings.ATTR_APP_KEY, ProctoringSettings.ATTR_APP_KEY,
SEB_PROCTORING_FORM_APPKEY, SEB_PROCTORING_FORM_APPKEY,
proctoringSettings.appKey)) proctoringSettings.appKey))
.withEmptyCellSeparation(false)
.addField(FormBuilder.password( .addField(FormBuilder.password(
ProctoringSettings.ATTR_APP_SECRET, ProctoringSettings.ATTR_APP_SECRET,

View file

@ -282,9 +282,9 @@ public class MonitoringClientConnection implements TemplateComposer {
// @formatter:off // @formatter:off
private static final String OPEN_SINGEL_ROOM_SCRIPT = private static final String OPEN_SINGEL_ROOM_SCRIPT =
"var existingWin = window.open('', '%s', 'height=420,width=620,location=no,scrollbars=yes,status=no,menubar=yes,toolbar=yes,titlebar=yes');\n" + "var existingWin = window.open('', '%s', 'height=420,width=620,location=no,scrollbars=yes,status=no,menubar=yes,toolbar=yes,titlebar=yes,dialog=yes');\n" +
"if(existingWin.location.href === 'about:blank'){\n" + "if(existingWin.location.href === 'about:blank'){\n" +
" existingWin.location.href = '%s/proctoring/%s';\n" + " existingWin.location.href = '%s/proc/%s';\n" +
" existingWin.focus();\n" + " existingWin.focus();\n" +
"} else {\n" + "} else {\n" +
" existingWin.focus();\n" + " existingWin.focus();\n" +
@ -306,6 +306,10 @@ public class MonitoringClientConnection implements TemplateComposer {
ProctoringServlet.SESSION_ATTR_PROCTORING_DATA, ProctoringServlet.SESSION_ATTR_PROCTORING_DATA,
proctoringConnectionData); proctoringConnectionData);
// final String url = this.guiServiceInfo.getExternalServerURIBuilder().toUriString() + "/proctoring/" + roomName;
// final ProctorDialog proctorDialog = new ProctorDialog(action.pageContext().getShell());
// proctorDialog.open(new LocTextKey("title"), url);
final JavaScriptExecutor javaScriptExecutor = RWT.getClient().getService(JavaScriptExecutor.class); final JavaScriptExecutor javaScriptExecutor = RWT.getClient().getService(JavaScriptExecutor.class);
final String script = String.format( final String script = String.format(
OPEN_SINGEL_ROOM_SCRIPT, OPEN_SINGEL_ROOM_SCRIPT,

View file

@ -115,7 +115,7 @@ public class ProctoringGUIService {
closeWindow(name); closeWindow(name);
final RoomConnectionData roomConnectionData = this.rooms.remove(name); final RoomConnectionData roomConnectionData = this.rooms.remove(name);
if (roomConnectionData != null) { if (roomConnectionData != null) {
// first send instruction to leave this room and join the personal single room // first send instruction to leave this room and join the personal room
final String connectionsString = StringUtils.join( final String connectionsString = StringUtils.join(
roomConnectionData.connections roomConnectionData.connections
.stream() .stream()

View file

@ -168,6 +168,7 @@ public class ExamAdminServiceImpl implements ExamAdminService {
getEnabled(mapping), getEnabled(mapping),
getServerType(mapping), getServerType(mapping),
getString(mapping, ProctoringSettings.ATTR_SERVER_URL), getString(mapping, ProctoringSettings.ATTR_SERVER_URL),
getCollectingRoomSize(mapping),
getString(mapping, ProctoringSettings.ATTR_APP_KEY), getString(mapping, ProctoringSettings.ATTR_APP_KEY),
getString(mapping, ProctoringSettings.ATTR_APP_SECRET)); getString(mapping, ProctoringSettings.ATTR_APP_SECRET));
}); });
@ -196,6 +197,12 @@ public class ExamAdminServiceImpl implements ExamAdminService {
ProctoringSettings.ATTR_SERVER_URL, ProctoringSettings.ATTR_SERVER_URL,
examProctoring.serverURL); examProctoring.serverURL);
this.additionalAttributesDAO.saveAdditionalAttribute(
EntityType.EXAM,
examId,
ProctoringSettings.ATTR_COLLECTING_ROOM_SIZE,
String.valueOf(examProctoring.collectingRoomSize));
this.additionalAttributesDAO.saveAdditionalAttribute( this.additionalAttributesDAO.saveAdditionalAttribute(
EntityType.EXAM, EntityType.EXAM,
examId, examId,
@ -254,4 +261,12 @@ public class ExamAdminServiceImpl implements ExamAdminService {
} }
} }
private Long getCollectingRoomSize(final Map<String, AdditionalAttributeRecord> mapping) {
if (mapping.containsKey(ProctoringSettings.ATTR_COLLECTING_ROOM_SIZE)) {
return Long.valueOf(mapping.get(ProctoringSettings.ATTR_COLLECTING_ROOM_SIZE).getValue());
} else {
return 20L;
}
}
} }

View file

@ -632,6 +632,8 @@ sebserver.exam.proctoring.form.type=Type
sebserver.exam.proctoring.form.type.tooltip=The type and server type of the external proctoring service. sebserver.exam.proctoring.form.type.tooltip=The type and server type of the external proctoring service.
sebserver.exam.proctoring.form.url=Server URL sebserver.exam.proctoring.form.url=Server URL
sebserver.exam.proctoring.form.url.tooltip=The proctoring server URL sebserver.exam.proctoring.form.url.tooltip=The proctoring server URL
sebserver.exam.proctoring.form.collectingRoomSize=Collecting Room Size
sebserver.exam.proctoring.form.collectingRoomSize.tooltip=The size of proctor rooms to collect connecting SEB clients into.
sebserver.exam.proctoring.form.appkey=Application Key sebserver.exam.proctoring.form.appkey=Application Key
sebserver.exam.proctoring.form.appkey.tooltip=The application key of the proctoring service server sebserver.exam.proctoring.form.appkey.tooltip=The application key of the proctoring service server
sebserver.exam.proctoring.form.secret=Secret sebserver.exam.proctoring.form.secret=Secret