diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/Constants.java b/src/main/java/ch/ethz/seb/sebserver/gbl/Constants.java
index b1855220..0af7d6fc 100644
--- a/src/main/java/ch/ethz/seb/sebserver/gbl/Constants.java
+++ b/src/main/java/ch/ethz/seb/sebserver/gbl/Constants.java
@@ -74,6 +74,9 @@ public final class Constants {
public static final String URL_ADDRESS_SEPARATOR = COLON.toString() + SLASH.toString() + SLASH.toString();
public static final String URL_PATH_SEPARATOR = SLASH.toString();
+ public static final String DYN_HTML_ATTR_OPEN = "%%_";
+ public static final String DYN_HTML_ATTR_CLOSE = "_%%";
+
public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";
public static final String TIME_ZONE_OFFSET_TAIL_FORMAT = "|ZZ";
diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/session/proctoring/JitsiWindowScriptResolver.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/session/proctoring/JitsiWindowScriptResolver.java
index a1baea70..fa1299e3 100644
--- a/src/main/java/ch/ethz/seb/sebserver/gui/service/session/proctoring/JitsiWindowScriptResolver.java
+++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/session/proctoring/JitsiWindowScriptResolver.java
@@ -11,12 +11,16 @@ package ch.ethz.seb.sebserver.gui.service.session.proctoring;
import java.util.HashMap;
import java.util.Map;
+import org.apache.commons.io.IOUtils;
import org.apache.commons.text.StringSubstitutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
+import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;
+import ch.ethz.seb.sebserver.gbl.Constants;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringServiceSettings.ProctoringServerType;
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
import ch.ethz.seb.sebserver.gui.service.session.proctoring.ProctoringGUIService.ProctoringWindowData;
@@ -28,58 +32,21 @@ public class JitsiWindowScriptResolver implements ProctoringWindowScriptResolver
private static final Logger log = LoggerFactory.getLogger(JitsiWindowScriptResolver.class);
- private static final String ATTR_SUBJECT = "_subject_";
- private static final String ATTR_ACCESS_TOKEN = "_accessToken_";
- private static final String ATTR_ROOM_NAME = "_roomName_";
- private static final String ATTR_HOST = "_host_";
+ static final String RES_PATH =
+ "classpath:ch/ethz/seb/sebserver/gui/service/session/proctoring/jitsiWindow.html";
- // @formatter:off
- private static final String JITSI_WINDOW_HTML =
- "" +
- "" +
- "
" +
- " " +
- " " +
- "" +
- "" +
- "" +
- " " +
- "" +
- "" +
- "";
- // @formatter:on
+ private static final String ATTR_SUBJECT = "ATTR_SUBJECT";
+ private static final String ATTR_ACCESS_TOKEN = "ATTR_ACCESS_TOKEN";
+ private static final String ATTR_ROOM_NAME = "ATTR_ROOM_NAME";
+ private static final String ATTR_HOST = "ATTR_HOST";
+
+ private final Resource resourceFile;
+
+ public JitsiWindowScriptResolver(
+ @Value(RES_PATH) final Resource resourceFile) {
+
+ this.resourceFile = resourceFile;
+ }
@Override
public boolean applies(final ProctoringWindowData data) {
@@ -93,14 +60,28 @@ public class JitsiWindowScriptResolver implements ProctoringWindowScriptResolver
@Override
public String getProctoringWindowScript(final ProctoringWindowData data) {
+
final Map args = new HashMap<>();
args.put(ATTR_HOST, data.connectionData.serverHost);
args.put(ATTR_ROOM_NAME, data.connectionData.roomName);
args.put(ATTR_ACCESS_TOKEN, String.valueOf(data.connectionData.accessToken));
args.put(ATTR_SUBJECT, data.connectionData.subject);
- return new StringSubstitutor(args, "%%_", "_%%")
- .replace(JITSI_WINDOW_HTML);
+ return new StringSubstitutor(
+ args,
+ Constants.DYN_HTML_ATTR_OPEN,
+ Constants.DYN_HTML_ATTR_CLOSE)
+ .replace(getHTMLWindow());
+
+ }
+
+ private String getHTMLWindow() {
+ try {
+ return IOUtils.toString(this.resourceFile.getInputStream());
+ } catch (final Exception e) {
+ log.error("Failed to load Jitsi Meet window resources", e);
+ return "ERROR: " + e.getLocalizedMessage();
+ }
}
}
diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/session/proctoring/ProctoringWindowScriptResolver.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/session/proctoring/ProctoringWindowScriptResolver.java
index 84332244..259aad0c 100644
--- a/src/main/java/ch/ethz/seb/sebserver/gui/service/session/proctoring/ProctoringWindowScriptResolver.java
+++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/session/proctoring/ProctoringWindowScriptResolver.java
@@ -10,10 +10,24 @@ package ch.ethz.seb.sebserver.gui.service.session.proctoring;
import ch.ethz.seb.sebserver.gui.service.session.proctoring.ProctoringGUIService.ProctoringWindowData;
+/** Defines a proctoring window script resolver that generates the
+ * proctoring window html and script code for a particular
+ * proctoring service. */
public interface ProctoringWindowScriptResolver {
+ /** Indicates if the concrete implementation applies to given proctoring data.
+ * Usually this looks after the proctoring service type within the given data
+ * and returns true if the implementation is compatible with the given proctoring
+ * service type.
+ *
+ * @param data ProctoringWindowData instance containing actual proctoring data
+ * @return true if a concrete implementation applies to the given data */
boolean applies(ProctoringWindowData data);
+ /** Produces the html and java script page to open in a proctoring window pop-up.
+ *
+ * @param data ProctoringWindowData instance containing actual proctoring data
+ * @return the html and java script page to open in a proctoring window pop-up */
String getProctoringWindowScript(ProctoringWindowData data);
}
diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/session/proctoring/ZoomWindowScriptResolver.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/session/proctoring/ZoomWindowScriptResolver.java
index 61d88db1..e3da08ad 100644
--- a/src/main/java/ch/ethz/seb/sebserver/gui/service/session/proctoring/ZoomWindowScriptResolver.java
+++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/session/proctoring/ZoomWindowScriptResolver.java
@@ -11,13 +11,17 @@ package ch.ethz.seb.sebserver.gui.service.session.proctoring;
import java.util.HashMap;
import java.util.Map;
+import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.text.StringSubstitutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
+import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;
+import ch.ethz.seb.sebserver.gbl.Constants;
import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringServiceSettings.ProctoringServerType;
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
import ch.ethz.seb.sebserver.gui.service.session.proctoring.ProctoringGUIService.ProctoringWindowData;
@@ -29,120 +33,24 @@ public class ZoomWindowScriptResolver implements ProctoringWindowScriptResolver
private static final Logger log = LoggerFactory.getLogger(ZoomWindowScriptResolver.class);
- private static final String ATTR_SUBJECT = "_subject_";
- private static final String ATTR_API_KEY = "_apiKey_";
- private static final String ATTR_ACCESS_TOKEN = "_accessToken_";
- private static final String ATTR_ROOM_KEY = "_roomKey_";
- private static final String ATTR_ROOM_NAME = "_roomName_";
- private static final String ATTR_HOST = "_host_";
- private static final String ATTR_USER_NAME = "_username_";
+ static final String RES_PATH =
+ "classpath:ch/ethz/seb/sebserver/gui/service/session/proctoring/zoomWindow.html";
- // @formatter:off
- private static final String ZOOM_WINDOW_HTML =
- "\n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + " \n"
- + "";
- // @formatter:on
+ private static final String ATTR_SUBJECT = "ATTR_SUBJECT";
+ private static final String ATTR_API_KEY = "ATTR_API_KEY";
+ private static final String ATTR_ACCESS_TOKEN = "ATTR_ACCESS_TOKEN";
+ private static final String ATTR_ROOM_KEY = "ATTR_ROOM_KEY";
+ private static final String ATTR_ROOM_NAME = "ATTR_ROOM_NAME";
+ private static final String ATTR_HOST = "ATTR_HOST";
+ private static final String ATTR_USER_NAME = "ATTR_USER_NAME";
+
+ private final Resource resourceFile;
+
+ public ZoomWindowScriptResolver(
+ @Value(RES_PATH) final Resource resourceFile) {
+
+ this.resourceFile = resourceFile;
+ }
@Override
public boolean applies(final ProctoringWindowData data) {
@@ -169,8 +77,22 @@ public class ZoomWindowScriptResolver implements ProctoringWindowScriptResolver
args.put(ATTR_SUBJECT, data.connectionData.subject);
args.put(ATTR_USER_NAME, data.connectionData.userName);
- return new StringSubstitutor(args, "%%_", "_%%")
- .replace(ZOOM_WINDOW_HTML);
+ final String htmlWindow = getHTMLWindow();
+ final String replace = new StringSubstitutor(
+ args,
+ Constants.DYN_HTML_ATTR_OPEN,
+ Constants.DYN_HTML_ATTR_CLOSE)
+ .replace(htmlWindow);
+ return replace;
+ }
+
+ private String getHTMLWindow() {
+ try {
+ return IOUtils.toString(this.resourceFile.getInputStream());
+ } catch (final Exception e) {
+ log.error("Failed to load Jitsi Meet window resources", e);
+ return "ERROR: " + e.getLocalizedMessage();
+ }
}
}
diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/session/proctoring/jitsiWindow.html b/src/main/java/ch/ethz/seb/sebserver/gui/service/session/proctoring/jitsiWindow.html
new file mode 100644
index 00000000..66f94bb1
--- /dev/null
+++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/session/proctoring/jitsiWindow.html
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/session/proctoring/zoomWindow.html b/src/main/java/ch/ethz/seb/sebserver/gui/service/session/proctoring/zoomWindow.html
new file mode 100644
index 00000000..f5130ed3
--- /dev/null
+++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/session/proctoring/zoomWindow.html
@@ -0,0 +1,102 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/proctoring/ZoomRoomRequestResponse.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/proctoring/ZoomRoomRequestResponse.java
index 99daff85..d3cbd284 100644
--- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/proctoring/ZoomRoomRequestResponse.java
+++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/proctoring/ZoomRoomRequestResponse.java
@@ -131,7 +131,7 @@ public interface ZoomRoomRequestResponse {
@JsonIgnoreProperties(ignoreUnknown = true)
static class Settings {
- @JsonProperty final boolean host_video = false;
+ @JsonProperty final boolean host_video = true;
@JsonProperty final boolean participant_video = true;
@JsonProperty final boolean join_before_host = true;
@JsonProperty final int jbh_time = 0;
diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties
index b5afb240..a6c46b4a 100644
--- a/src/main/resources/messages.properties
+++ b/src/main/resources/messages.properties
@@ -1403,7 +1403,7 @@ sebserver.examconfig.props.label.zoomFeatureFlagChat=Enable Chat
sebserver.examconfig.props.label.zoomFeatureFlagChat.tooltip=
sebserver.examconfig.props.label.zoomFeatureFlagCloseCaptions=Enable Close Captions
sebserver.examconfig.props.label.zoomFeatureFlagCloseCaptions.tooltip=
-sebserver.examconfig.props.label.zoomFeatureFlagDisplayingName=Display Meeting Name
+sebserver.examconfig.props.label.zoomFeatureFlagDisplayingMeetingName=Display Meeting Name
sebserver.examconfig.props.label.zoomFeatureFlagDisplayMeetingName.tooltip
sebserver.examconfig.props.label.zoomFeatureFlagRaiseHand=Enable Raise Hand
sebserver.examconfig.props.label.zoomFeatureFlagRaiseHand.tooltip=
diff --git a/src/test/java/ch/ethz/seb/sebserver/gui/service/session/proctoring/JitsiWindowScriptResolverTest.java b/src/test/java/ch/ethz/seb/sebserver/gui/service/session/proctoring/JitsiWindowScriptResolverTest.java
new file mode 100644
index 00000000..14bec9eb
--- /dev/null
+++ b/src/test/java/ch/ethz/seb/sebserver/gui/service/session/proctoring/JitsiWindowScriptResolverTest.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2021 ETH Zürich, Educational Development and Technology (LET)
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+package ch.ethz.seb.sebserver.gui.service.session.proctoring;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+import org.springframework.core.io.DefaultResourceLoader;
+import org.springframework.core.io.Resource;
+
+import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringRoomConnection;
+import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringServiceSettings.ProctoringServerType;
+import ch.ethz.seb.sebserver.gui.service.session.proctoring.ProctoringGUIService.ProctoringWindowData;
+
+public class JitsiWindowScriptResolverTest {
+
+ @Test
+ public void testJitsiWindowScriptResolver() {
+ final DefaultResourceLoader defaultResourceLoader = new DefaultResourceLoader();
+ final Resource resource = defaultResourceLoader.getResource(JitsiWindowScriptResolver.RES_PATH);
+ final JitsiWindowScriptResolver jitsiWindowScriptResolver = new JitsiWindowScriptResolver(resource);
+
+ final ProctoringWindowData proctoringWindowData = new ProctoringWindowData(
+ "0",
+ "Test_Window",
+ new ProctoringRoomConnection(
+ ProctoringServerType.JITSI_MEET,
+ "CONNECTION_TOKEN",
+ "HOST",
+ "URL",
+ "ROOM",
+ "SUBJECT",
+ "ACCESS_TOKEN",
+ "API_KEY",
+ "ROOM_KEY",
+ "MEETING_ID",
+ "USER_NAME"));
+
+ final ProctoringWindowData proctoringWindowDataOther = new ProctoringWindowData(
+ "0",
+ "Test_Window",
+ new ProctoringRoomConnection(
+ ProctoringServerType.ZOOM,
+ "CONNECTION_TOKEN",
+ "HOST",
+ "URL",
+ "ROOM",
+ "SUBJECT",
+ "ACCESS_TOKEN",
+ "API_KEY",
+ "ROOM_KEY",
+ "MEETING_ID",
+ "USER_NAME"));
+
+ assertFalse(jitsiWindowScriptResolver.applies(proctoringWindowDataOther));
+ assertTrue(jitsiWindowScriptResolver.applies(proctoringWindowData));
+
+ final String proctoringWindowScript = jitsiWindowScriptResolver
+ .getProctoringWindowScript(proctoringWindowData);
+
+ assertEquals(
+ "\r\n"
+ + "\r\n"
+ + " \r\n"
+ + " \r\n"
+ + " \r\n"
+ + "\r\n"
+ + "\r\n"
+ + "\r\n"
+ + "\r\n"
+ + "\r\n"
+ + "",
+ proctoringWindowScript);
+ }
+
+}
diff --git a/src/test/java/ch/ethz/seb/sebserver/gui/service/session/proctoring/ZoomWindowScriptResolverTest.java b/src/test/java/ch/ethz/seb/sebserver/gui/service/session/proctoring/ZoomWindowScriptResolverTest.java
new file mode 100644
index 00000000..0bbd3517
--- /dev/null
+++ b/src/test/java/ch/ethz/seb/sebserver/gui/service/session/proctoring/ZoomWindowScriptResolverTest.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2021 ETH Zürich, Educational Development and Technology (LET)
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+package ch.ethz.seb.sebserver.gui.service.session.proctoring;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+import org.springframework.core.io.DefaultResourceLoader;
+import org.springframework.core.io.Resource;
+
+import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringRoomConnection;
+import ch.ethz.seb.sebserver.gbl.model.exam.ProctoringServiceSettings.ProctoringServerType;
+import ch.ethz.seb.sebserver.gui.service.session.proctoring.ProctoringGUIService.ProctoringWindowData;
+
+public class ZoomWindowScriptResolverTest {
+
+ @Test
+ public void testJitsiWindowScriptResolver() {
+ final DefaultResourceLoader defaultResourceLoader = new DefaultResourceLoader();
+ final Resource resource = defaultResourceLoader.getResource(ZoomWindowScriptResolver.RES_PATH);
+ final ZoomWindowScriptResolver zoomWindowScriptResolver = new ZoomWindowScriptResolver(resource);
+
+ final ProctoringWindowData proctoringWindowDataZoom = new ProctoringWindowData(
+ "0",
+ "Test_Window",
+ new ProctoringRoomConnection(
+ ProctoringServerType.ZOOM,
+ "CONNECTION_TOKEN",
+ "HOST",
+ "URL",
+ "ROOM",
+ "SUBJECT",
+ "ACCESS_TOKEN",
+ "API_KEY",
+ "ROOM_KEY",
+ "MEETING_ID",
+ "USER_NAME"));
+
+ final ProctoringWindowData proctoringWindowDataOther = new ProctoringWindowData(
+ "0",
+ "Test_Window",
+ new ProctoringRoomConnection(
+ ProctoringServerType.JITSI_MEET,
+ "CONNECTION_TOKEN",
+ "HOST",
+ "URL",
+ "ROOM",
+ "SUBJECT",
+ "ACCESS_TOKEN",
+ "API_KEY",
+ "ROOM_KEY",
+ "MEETING_ID",
+ "USER_NAME"));
+
+ assertFalse(zoomWindowScriptResolver.applies(proctoringWindowDataOther));
+ assertTrue(zoomWindowScriptResolver.applies(proctoringWindowDataZoom));
+
+ final String proctoringWindowScript = zoomWindowScriptResolver
+ .getProctoringWindowScript(proctoringWindowDataZoom);
+
+ assertEquals(
+ "\r\n"
+ + " \r\n"
+ + " \r\n"
+ + " \r\n"
+ + " \r\n"
+ + " \r\n"
+ + " \r\n"
+ + " \r\n"
+ + " \r\n"
+ + " \r\n"
+ + " \r\n"
+ + " \r\n"
+ + " \r\n"
+ + " \r\n"
+ + " \r\n"
+ + " \r\n"
+ + " \r\n"
+ + "",
+ proctoringWindowScript);
+ }
+
+}