remote proctoring

This commit is contained in:
anhefti 2020-10-06 11:30:37 +02:00
parent 3fd064055a
commit e9393068df
5 changed files with 52 additions and 19 deletions

View file

@ -33,6 +33,8 @@ public class GuiWebsecurityConfig extends WebSecurityConfigurerAdapter {
@Value("${sebserver.gui.entrypoint:/gui}") @Value("${sebserver.gui.entrypoint:/gui}")
private String guiEntryPoint; private String guiEntryPoint;
@Value("${sebserver.gui.remote.proctoring.entrypoint:/remote-proctoring}")
private String remoteProctoringEndpoint;
/** Gui-service related public URLS from spring web security perspective */ /** Gui-service related public URLS from spring web security perspective */
public static final RequestMatcher PUBLIC_URLS = new OrRequestMatcher( public static final RequestMatcher PUBLIC_URLS = new OrRequestMatcher(
@ -51,9 +53,7 @@ public class GuiWebsecurityConfig extends WebSecurityConfigurerAdapter {
.ignoring() .ignoring()
.requestMatchers(PUBLIC_URLS) .requestMatchers(PUBLIC_URLS)
.antMatchers(this.guiEntryPoint) .antMatchers(this.guiEntryPoint)
.antMatchers("/proc*") .antMatchers(this.remoteProctoringEndpoint + "/*");
.antMatchers("/proc/*")
.antMatchers("/proctoring/*");
} }
@Override @Override

View file

@ -58,18 +58,22 @@ public final class InstitutionalAuthenticationEntryPoint implements Authenticati
private static final Logger log = LoggerFactory.getLogger(InstitutionalAuthenticationEntryPoint.class); private static final Logger log = LoggerFactory.getLogger(InstitutionalAuthenticationEntryPoint.class);
private final String guiEntryPoint; private final String guiEntryPoint;
private final String remoteProctoringEndpoint;
private final String defaultLogo; private final String defaultLogo;
private final WebserviceURIService webserviceURIService; private final WebserviceURIService webserviceURIService;
private final ClientHttpRequestFactoryService clientHttpRequestFactoryService; private final ClientHttpRequestFactoryService clientHttpRequestFactoryService;
protected InstitutionalAuthenticationEntryPoint( protected InstitutionalAuthenticationEntryPoint(
@Value("${sebserver.gui.entrypoint}") final String guiEntryPoint, @Value("${sebserver.gui.entrypoint}") final String guiEntryPoint,
@Value("${sebserver.gui.remote.proctoring.entrypoint:/remote-proctoring}") final String remoteProctoringEndpoint,
@Value("${sebserver.gui.defaultLogo:" + Constants.NO_NAME + "}") final String defaultLogoFileName, @Value("${sebserver.gui.defaultLogo:" + Constants.NO_NAME + "}") final String defaultLogoFileName,
final WebserviceURIService webserviceURIService, final WebserviceURIService webserviceURIService,
final ClientHttpRequestFactoryService clientHttpRequestFactoryService, final ClientHttpRequestFactoryService clientHttpRequestFactoryService,
final ResourceLoader resourceLoader) { final ResourceLoader resourceLoader) {
this.guiEntryPoint = guiEntryPoint; this.guiEntryPoint = guiEntryPoint;
this.remoteProctoringEndpoint = remoteProctoringEndpoint;
this.webserviceURIService = webserviceURIService; this.webserviceURIService = webserviceURIService;
this.clientHttpRequestFactoryService = clientHttpRequestFactoryService; this.clientHttpRequestFactoryService = clientHttpRequestFactoryService;
@ -149,7 +153,7 @@ public final class InstitutionalAuthenticationEntryPoint implements Authenticati
request.getSession().setAttribute(API.PARAM_LOGO_IMAGE, logoImageBase64); request.getSession().setAttribute(API.PARAM_LOGO_IMAGE, logoImageBase64);
} }
forwardToEntryPoint(request, response, this.guiEntryPoint); forwardToEntryPoint(request, response, this.guiEntryPoint, false);
return; return;
} }
} catch (final Exception e) { } catch (final Exception e) {
@ -160,20 +164,35 @@ public final class InstitutionalAuthenticationEntryPoint implements Authenticati
request.getSession().setAttribute(INST_SUFFIX_ATTRIBUTE, null); request.getSession().setAttribute(INST_SUFFIX_ATTRIBUTE, null);
request.getSession().removeAttribute(API.PARAM_LOGO_IMAGE); request.getSession().removeAttribute(API.PARAM_LOGO_IMAGE);
response.setStatus(HttpStatus.UNAUTHORIZED.value()); response.setStatus(HttpStatus.UNAUTHORIZED.value());
forwardToEntryPoint(request, response, this.guiEntryPoint); forwardToEntryPoint(request, response, this.guiEntryPoint, true);
} }
private void forwardToEntryPoint( private void forwardToEntryPoint(
final HttpServletRequest request, final HttpServletRequest request,
final HttpServletResponse response, final HttpServletResponse response,
final String entryPoint) throws ServletException, IOException { final String entryPoint,
final boolean redirect) throws ServletException, IOException {
final RequestDispatcher dispatcher = request final String requestURI = request.getRequestURI();
.getServletContext() if (requestURI.startsWith(this.remoteProctoringEndpoint)) {
.getRequestDispatcher(entryPoint); final RequestDispatcher dispatcher = request
.getServletContext()
.getRequestDispatcher(requestURI);
dispatcher.forward(request, response); dispatcher.forward(request, response);
return;
}
if (redirect) {
response.sendRedirect(entryPoint);
} else {
final RequestDispatcher dispatcher = request
.getServletContext()
.getRequestDispatcher(entryPoint);
dispatcher.forward(request, response);
}
} }
public static String extractInstitutionalEndpoint(final HttpServletRequest request) { public static String extractInstitutionalEndpoint(final HttpServletRequest request) {

View file

@ -39,6 +39,12 @@ public class RAPSpringConfig {
@Value("${sebserver.gui.external.messages:messages}") @Value("${sebserver.gui.external.messages:messages}")
private String externalMessagesPath; private String externalMessagesPath;
@Value("${sebserver.gui.remote.proctoring.entrypoint:/remote-proctoring}")
private String remoteProctoringEndpoint;
@Value("${sebserver.gui.remote.proctoring.api-servler.endpoint:/remote-view-servlet}")
private String remoteProctoringViewServletEndpoint;
@Bean @Bean
public ServletContextInitializer initializer() { public ServletContextInitializer initializer() {
return new RAPServletContextInitializer(); return new RAPServletContextInitializer();
@ -54,12 +60,10 @@ public class RAPSpringConfig {
@Bean @Bean
public ServletRegistrationBean<RWTServlet> servletRegistrationBean() { public ServletRegistrationBean<RWTServlet> servletRegistrationBean() {
return new ServletRegistrationBean<>(new RWTServlet(), this.entrypoint + "/*"); return new ServletRegistrationBean<>(
} new RWTServlet(),
this.entrypoint + "/*",
@Bean this.remoteProctoringEndpoint + "/*");
public ServletRegistrationBean<RWTServlet> servletRegistrationBeanProc() {
return new ServletRegistrationBean<>(new RWTServlet(), "/proc/*");
} }
@Bean @Bean
@ -68,7 +72,9 @@ public class RAPSpringConfig {
final ProctoringServlet proctoringServlet = applicationContext final ProctoringServlet proctoringServlet = applicationContext
.getBean(ProctoringServlet.class); .getBean(ProctoringServlet.class);
return new ServletRegistrationBean<>(proctoringServlet, "/proctoring/*"); return new ServletRegistrationBean<>(
proctoringServlet,
this.remoteProctoringEndpoint + this.remoteProctoringViewServletEndpoint + "/*");
} }
@Bean @Bean

View file

@ -99,6 +99,7 @@ public class MonitoringClientConnection implements TemplateComposer {
private final GuiServiceInfo guiServiceInfo; private final GuiServiceInfo guiServiceInfo;
private final long pollInterval; private final long pollInterval;
private final int pageSize; private final int pageSize;
private final String remoteProctoringEndpoint;
private final TableFilterAttribute typeFilter; private final TableFilterAttribute typeFilter;
private final TableFilterAttribute textFilter = private final TableFilterAttribute textFilter =
@ -111,7 +112,8 @@ public class MonitoringClientConnection implements TemplateComposer {
final SEBClientEventDetailsPopup sebClientLogDetailsPopup, final SEBClientEventDetailsPopup sebClientLogDetailsPopup,
final GuiServiceInfo guiServiceInfo, final GuiServiceInfo guiServiceInfo,
@Value("${sebserver.gui.webservice.poll-interval:500}") final long pollInterval, @Value("${sebserver.gui.webservice.poll-interval:500}") final long pollInterval,
@Value("${sebserver.gui.list.page.size:20}") final Integer pageSize) { @Value("${sebserver.gui.list.page.size:20}") final Integer pageSize,
@Value("${sebserver.gui.remote.proctoring.entrypoint:/remote-proctoring}") final String remoteProctoringEndpoint) {
this.serverPushService = serverPushService; this.serverPushService = serverPushService;
this.pageService = pageService; this.pageService = pageService;
@ -122,6 +124,7 @@ public class MonitoringClientConnection implements TemplateComposer {
this.pollInterval = pollInterval; this.pollInterval = pollInterval;
this.sebClientLogDetailsPopup = sebClientLogDetailsPopup; this.sebClientLogDetailsPopup = sebClientLogDetailsPopup;
this.pageSize = pageSize; this.pageSize = pageSize;
this.remoteProctoringEndpoint = remoteProctoringEndpoint;
this.typeFilter = new TableFilterAttribute( this.typeFilter = new TableFilterAttribute(
CriteriaType.SINGLE_SELECTION, CriteriaType.SINGLE_SELECTION,
@ -284,7 +287,7 @@ public class MonitoringClientConnection implements TemplateComposer {
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,dialog=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/proc/%s';\n" + " existingWin.location.href = '%s%s/%s';\n" +
" existingWin.focus();\n" + " existingWin.focus();\n" +
"} else {\n" + "} else {\n" +
" existingWin.focus();\n" + " existingWin.focus();\n" +
@ -315,6 +318,7 @@ public class MonitoringClientConnection implements TemplateComposer {
OPEN_SINGEL_ROOM_SCRIPT, OPEN_SINGEL_ROOM_SCRIPT,
roomName, roomName,
this.guiServiceInfo.getExternalServerURIBuilder().toUriString(), this.guiServiceInfo.getExternalServerURIBuilder().toUriString(),
this.remoteProctoringEndpoint,
roomName); roomName);
javaScriptExecutor.execute(script); javaScriptExecutor.execute(script);
this.pageService.getCurrentUser() this.pageService.getCurrentUser()

View file

@ -27,6 +27,10 @@ sebserver.gui.webservice.mock-lms-enabled=true
sebserver.gui.seb.client.config.download.filename=SEBServerSettings.seb sebserver.gui.seb.client.config.download.filename=SEBServerSettings.seb
sebserver.gui.seb.exam.config.download.filename=SEBExamSettings.seb sebserver.gui.seb.exam.config.download.filename=SEBExamSettings.seb
# remote proctoring
sebserver.gui.remote.proctoring.entrypoint=/remote-proctoring
sebserver.gui.remote.proctoring.api-servler.endpoint=/remote-view-servlet
# Webservice connection details # Webservice connection details
sebserver.webservice.api.exam.endpoint=/exam-api sebserver.webservice.api.exam.endpoint=/exam-api
sebserver.webservice.api.exam.endpoint.discovery=${sebserver.webservice.api.exam.endpoint}/discovery sebserver.webservice.api.exam.endpoint.discovery=${sebserver.webservice.api.exam.endpoint}/discovery