fixed privilege check on SEB Client Events list and update quiz filter
This commit is contained in:
parent
a37ab31ff1
commit
e7af727854
7 changed files with 441 additions and 439 deletions
|
@ -1,41 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) 2019 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;
|
||||
|
||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import ch.ethz.seb.sebserver.SEBServerInit;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
|
||||
@Component
|
||||
@GuiProfile
|
||||
public class GuiInit implements ApplicationListener<ApplicationReadyEvent> {
|
||||
|
||||
private final SEBServerInit sebServerInit;
|
||||
|
||||
protected GuiInit(final SEBServerInit sebServerInit) {
|
||||
this.sebServerInit = sebServerInit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(final ApplicationReadyEvent event) {
|
||||
|
||||
this.sebServerInit.init();
|
||||
|
||||
SEBServerInit.INIT_LOGGER.info("---->");
|
||||
SEBServerInit.INIT_LOGGER.info("----> **** GUI Service starting up... ****");
|
||||
|
||||
SEBServerInit.INIT_LOGGER.info("---->");
|
||||
SEBServerInit.INIT_LOGGER.info("----> GUI Service sucessfully successfully started up!");
|
||||
SEBServerInit.INIT_LOGGER.info("---->");
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2019 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;
|
||||
|
||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import ch.ethz.seb.sebserver.SEBServerInit;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
|
||||
@Component
|
||||
@GuiProfile
|
||||
public class GuiInit implements ApplicationListener<ApplicationReadyEvent> {
|
||||
|
||||
private final SEBServerInit sebServerInit;
|
||||
|
||||
protected GuiInit(final SEBServerInit sebServerInit) {
|
||||
this.sebServerInit = sebServerInit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(final ApplicationReadyEvent event) {
|
||||
|
||||
this.sebServerInit.init();
|
||||
|
||||
SEBServerInit.INIT_LOGGER.info("---->");
|
||||
SEBServerInit.INIT_LOGGER.info("----> **** GUI Service starting up... ****");
|
||||
|
||||
SEBServerInit.INIT_LOGGER.info("---->");
|
||||
SEBServerInit.INIT_LOGGER.info("----> GUI Service successfully successfully started up!");
|
||||
SEBServerInit.INIT_LOGGER.info("---->");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -73,12 +73,12 @@ public final class InstitutionalAuthenticationEntryPoint implements Authenticati
|
|||
this.webserviceURIService = webserviceURIService;
|
||||
this.clientHttpRequestFactoryService = clientHttpRequestFactoryService;
|
||||
|
||||
String _defaultLogo = null;
|
||||
String _defaultLogo;
|
||||
if (!Constants.NO_NAME.equals(defaultLogoFileName)) {
|
||||
try {
|
||||
|
||||
final String extension = ImageUploadSelection.SUPPORTED_IMAGE_FILES.stream()
|
||||
.filter(ext -> defaultLogoFileName.endsWith(ext))
|
||||
.filter(defaultLogoFileName::endsWith)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
|
@ -141,7 +141,7 @@ public final class InstitutionalAuthenticationEntryPoint implements Authenticati
|
|||
: null);
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Known and active gui entrypoint requested:", institutions);
|
||||
log.debug("Known and active gui entrypoint requested: {}", institutions);
|
||||
}
|
||||
|
||||
final String logoImageBase64 = requestLogoImage(institutionalEndpoint);
|
||||
|
@ -184,9 +184,7 @@ public final class InstitutionalAuthenticationEntryPoint implements Authenticati
|
|||
}
|
||||
|
||||
try {
|
||||
return requestURI.substring(
|
||||
requestURI.lastIndexOf(Constants.SLASH) + 1,
|
||||
requestURI.length());
|
||||
return requestURI.substring(requestURI.lastIndexOf(Constants.SLASH) + 1);
|
||||
} catch (final Exception e) {
|
||||
log.error("Failed to extract institutional URL suffix: {}", e.getMessage());
|
||||
return null;
|
||||
|
@ -231,12 +229,12 @@ public final class InstitutionalAuthenticationEntryPoint implements Authenticati
|
|||
if (exchange.getStatusCodeValue() == HttpStatus.OK.value()) {
|
||||
return exchange.getBody();
|
||||
} else {
|
||||
log.warn("Failed to verify insitution from requested entrypoint url: {}, response: {}",
|
||||
log.warn("Failed to verify institution from requested entrypoint url: {}, response: {}",
|
||||
institutionalEndpoint,
|
||||
exchange);
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
log.warn("Failed to verify insitution from requested entrypoint url: {}",
|
||||
log.warn("Failed to verify institution from requested entrypoint url: {}",
|
||||
institutionalEndpoint,
|
||||
e);
|
||||
}
|
||||
|
@ -245,7 +243,7 @@ public final class InstitutionalAuthenticationEntryPoint implements Authenticati
|
|||
}
|
||||
|
||||
/** TODO this seems not to work as expected. Different Theme is only possible in RAP on different
|
||||
* entry-points and since entry-points are statically defined within the RAPConficuration
|
||||
* entry-points and since entry-points are statically defined within the RAPConfiguration
|
||||
* there is no possibility to apply them dynamically within an institution so far.
|
||||
*
|
||||
* @param institutionalEndpoint
|
||||
|
|
|
@ -1,164 +1,164 @@
|
|||
/*
|
||||
* Copyright (c) 2018 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;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import org.eclipse.rap.rwt.RWT;
|
||||
import org.eclipse.rap.rwt.application.AbstractEntryPoint;
|
||||
import org.eclipse.rap.rwt.application.Application;
|
||||
import org.eclipse.rap.rwt.application.ApplicationConfiguration;
|
||||
import org.eclipse.rap.rwt.application.EntryPoint;
|
||||
import org.eclipse.rap.rwt.application.EntryPointFactory;
|
||||
import org.eclipse.rap.rwt.client.WebClient;
|
||||
import org.eclipse.rap.rwt.internal.theme.ThemeUtil;
|
||||
import org.eclipse.rap.rwt.service.ServiceManager;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.context.support.WebApplicationContextUtils;
|
||||
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.download.DownloadService;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.AuthorizationContextHolder;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.SEBServerAuthorizationContext;
|
||||
|
||||
public class RAPConfiguration implements ApplicationConfiguration {
|
||||
|
||||
private static final String DEFAULT_THEME_NAME = "sebserver";
|
||||
private static final Logger log = LoggerFactory.getLogger(RAPConfiguration.class);
|
||||
|
||||
@Override
|
||||
public void configure(final Application application) {
|
||||
try {
|
||||
|
||||
// TODO get file path from properties
|
||||
//application.addStyleSheet(RWT.DEFAULT_THEME_ID, "static/css/sebserver.css");
|
||||
application.addStyleSheet(DEFAULT_THEME_NAME, "resource/theme/default.css");
|
||||
application.addStyleSheet(DEFAULT_THEME_NAME, "static/css/sebserver.css");
|
||||
application.addStyleSheet("sms", "resource/theme/default.css");
|
||||
application.addStyleSheet("sms", "static/css/sms.css");
|
||||
|
||||
final Map<String, String> properties = new HashMap<>();
|
||||
properties.put(WebClient.PAGE_TITLE, "SEB Server");
|
||||
properties.put(WebClient.BODY_HTML, "<big>Loading Application<big>");
|
||||
properties.put(WebClient.THEME_ID, DEFAULT_THEME_NAME);
|
||||
// properties.put(WebClient.FAVICON, "icons/favicon.png");
|
||||
application.addEntryPoint("/gui", new RAPSpringEntryPointFactory(), properties);
|
||||
|
||||
} catch (final RuntimeException re) {
|
||||
throw re;
|
||||
} catch (final Exception e) {
|
||||
log.error("Error during CSS parsing. Please check the custom CSS files for errors.", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static interface EntryPointService {
|
||||
|
||||
void loadLoginPage(final Composite parent);
|
||||
|
||||
void loadMainPage(final Composite parent);
|
||||
}
|
||||
|
||||
public static final class RAPSpringEntryPointFactory implements EntryPointFactory {
|
||||
|
||||
private boolean initialized = false;
|
||||
|
||||
@Override
|
||||
public EntryPoint create() {
|
||||
|
||||
return new AbstractEntryPoint() {
|
||||
|
||||
private static final long serialVersionUID = -1299125117752916270L;
|
||||
|
||||
@Override
|
||||
protected void createContents(final Composite parent) {
|
||||
final HttpSession httpSession = RWT
|
||||
.getUISession(parent.getDisplay())
|
||||
.getHttpSession();
|
||||
|
||||
log.debug("Create new GUI entrypoint. HttpSession: " + httpSession);
|
||||
if (httpSession == null) {
|
||||
log.error("HttpSession not available from RWT.getUISession().getHttpSession()");
|
||||
throw new IllegalStateException(
|
||||
"HttpSession not available from RWT.getUISession().getHttpSession()");
|
||||
}
|
||||
|
||||
final Object themeId = httpSession.getAttribute("themeId");
|
||||
if (themeId != null) {
|
||||
ThemeUtil.setCurrentThemeId(RWT.getUISession(parent.getDisplay()), String.valueOf(themeId));
|
||||
parent.redraw();
|
||||
parent.layout(true);
|
||||
parent.redraw();
|
||||
|
||||
}
|
||||
|
||||
final WebApplicationContext webApplicationContext = getWebApplicationContext(httpSession);
|
||||
initSpringBasedRAPServices(webApplicationContext);
|
||||
|
||||
final EntryPointService entryPointService = webApplicationContext
|
||||
.getBean(EntryPointService.class);
|
||||
|
||||
if (isAuthenticated(httpSession, webApplicationContext)) {
|
||||
entryPointService.loadMainPage(parent);
|
||||
} else {
|
||||
entryPointService.loadLoginPage(parent);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void initSpringBasedRAPServices(final WebApplicationContext webApplicationContext) {
|
||||
if (!this.initialized) {
|
||||
try {
|
||||
final ServiceManager manager = RWT.getServiceManager();
|
||||
final DownloadService downloadService = webApplicationContext.getBean(DownloadService.class);
|
||||
manager.registerServiceHandler(DownloadService.DOWNLOAD_SERVICE_NAME, downloadService);
|
||||
this.initialized = true;
|
||||
} catch (final IllegalArgumentException iae) {
|
||||
log.warn("Failed to register DownloadService on ServiceManager. Already registered: ", iae);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isAuthenticated(
|
||||
final HttpSession httpSession,
|
||||
final WebApplicationContext webApplicationContext) {
|
||||
|
||||
final AuthorizationContextHolder authorizationContextHolder = webApplicationContext
|
||||
.getBean(AuthorizationContextHolder.class);
|
||||
final SEBServerAuthorizationContext authorizationContext = authorizationContextHolder
|
||||
.getAuthorizationContext(httpSession);
|
||||
return authorizationContext.isValid() && authorizationContext.isLoggedIn();
|
||||
}
|
||||
|
||||
private WebApplicationContext getWebApplicationContext(final HttpSession httpSession) {
|
||||
try {
|
||||
final ServletContext servletContext = httpSession.getServletContext();
|
||||
|
||||
log.debug("Initialize Spring-Context on Servlet-Context: " + servletContext);
|
||||
|
||||
return WebApplicationContextUtils
|
||||
.getRequiredWebApplicationContext(servletContext);
|
||||
|
||||
} catch (final RuntimeException e) {
|
||||
log.error("Failed to initialize Spring-Context on HttpSession: " + httpSession);
|
||||
throw e;
|
||||
} catch (final Exception e) {
|
||||
log.error("Failed to initialize Spring-Context on HttpSession: " + httpSession);
|
||||
throw new RuntimeException("Failed to initialize Spring-Context on HttpSession: " + httpSession);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2018 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;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import org.eclipse.rap.rwt.RWT;
|
||||
import org.eclipse.rap.rwt.application.AbstractEntryPoint;
|
||||
import org.eclipse.rap.rwt.application.Application;
|
||||
import org.eclipse.rap.rwt.application.ApplicationConfiguration;
|
||||
import org.eclipse.rap.rwt.application.EntryPoint;
|
||||
import org.eclipse.rap.rwt.application.EntryPointFactory;
|
||||
import org.eclipse.rap.rwt.client.WebClient;
|
||||
import org.eclipse.rap.rwt.internal.theme.ThemeUtil;
|
||||
import org.eclipse.rap.rwt.service.ServiceManager;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.context.support.WebApplicationContextUtils;
|
||||
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.download.DownloadService;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.AuthorizationContextHolder;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.SEBServerAuthorizationContext;
|
||||
|
||||
public class RAPConfiguration implements ApplicationConfiguration {
|
||||
|
||||
private static final String DEFAULT_THEME_NAME = "sebserver";
|
||||
private static final Logger log = LoggerFactory.getLogger(RAPConfiguration.class);
|
||||
|
||||
@Override
|
||||
public void configure(final Application application) {
|
||||
try {
|
||||
|
||||
// TODO get file path from properties
|
||||
//application.addStyleSheet(RWT.DEFAULT_THEME_ID, "static/css/sebserver.css");
|
||||
application.addStyleSheet(DEFAULT_THEME_NAME, "resource/theme/default.css");
|
||||
application.addStyleSheet(DEFAULT_THEME_NAME, "static/css/sebserver.css");
|
||||
application.addStyleSheet("sms", "resource/theme/default.css");
|
||||
application.addStyleSheet("sms", "static/css/sms.css");
|
||||
|
||||
final Map<String, String> properties = new HashMap<>();
|
||||
properties.put(WebClient.PAGE_TITLE, "SEB Server");
|
||||
properties.put(WebClient.BODY_HTML, "<big>Loading Application<big>");
|
||||
properties.put(WebClient.THEME_ID, DEFAULT_THEME_NAME);
|
||||
// properties.put(WebClient.FAVICON, "icons/favicon.png");
|
||||
application.addEntryPoint("/gui", new RAPSpringEntryPointFactory(), properties);
|
||||
|
||||
} catch (final RuntimeException re) {
|
||||
throw re;
|
||||
} catch (final Exception e) {
|
||||
log.error("Error during CSS parsing. Please check the custom CSS files for errors.", e);
|
||||
}
|
||||
}
|
||||
|
||||
public interface EntryPointService {
|
||||
|
||||
void loadLoginPage(final Composite parent);
|
||||
|
||||
void loadMainPage(final Composite parent);
|
||||
}
|
||||
|
||||
public static final class RAPSpringEntryPointFactory implements EntryPointFactory {
|
||||
|
||||
private boolean initialized = false;
|
||||
|
||||
@Override
|
||||
public EntryPoint create() {
|
||||
|
||||
return new AbstractEntryPoint() {
|
||||
|
||||
private static final long serialVersionUID = -1299125117752916270L;
|
||||
|
||||
@Override
|
||||
protected void createContents(final Composite parent) {
|
||||
final HttpSession httpSession = RWT
|
||||
.getUISession(parent.getDisplay())
|
||||
.getHttpSession();
|
||||
|
||||
log.debug("Create new GUI entrypoint. HttpSession: " + httpSession);
|
||||
if (httpSession == null) {
|
||||
log.error("HttpSession not available from RWT.getUISession().getHttpSession()");
|
||||
throw new IllegalStateException(
|
||||
"HttpSession not available from RWT.getUISession().getHttpSession()");
|
||||
}
|
||||
|
||||
final Object themeId = httpSession.getAttribute("themeId");
|
||||
if (themeId != null) {
|
||||
ThemeUtil.setCurrentThemeId(RWT.getUISession(parent.getDisplay()), String.valueOf(themeId));
|
||||
parent.redraw();
|
||||
parent.layout(true);
|
||||
parent.redraw();
|
||||
|
||||
}
|
||||
|
||||
final WebApplicationContext webApplicationContext = getWebApplicationContext(httpSession);
|
||||
initSpringBasedRAPServices(webApplicationContext);
|
||||
|
||||
final EntryPointService entryPointService = webApplicationContext
|
||||
.getBean(EntryPointService.class);
|
||||
|
||||
if (isAuthenticated(httpSession, webApplicationContext)) {
|
||||
entryPointService.loadMainPage(parent);
|
||||
} else {
|
||||
entryPointService.loadLoginPage(parent);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void initSpringBasedRAPServices(final WebApplicationContext webApplicationContext) {
|
||||
if (!this.initialized) {
|
||||
try {
|
||||
final ServiceManager manager = RWT.getServiceManager();
|
||||
final DownloadService downloadService = webApplicationContext.getBean(DownloadService.class);
|
||||
manager.registerServiceHandler(DownloadService.DOWNLOAD_SERVICE_NAME, downloadService);
|
||||
this.initialized = true;
|
||||
} catch (final IllegalArgumentException iae) {
|
||||
log.warn("Failed to register DownloadService on ServiceManager. Already registered: ", iae);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isAuthenticated(
|
||||
final HttpSession httpSession,
|
||||
final WebApplicationContext webApplicationContext) {
|
||||
|
||||
final AuthorizationContextHolder authorizationContextHolder = webApplicationContext
|
||||
.getBean(AuthorizationContextHolder.class);
|
||||
final SEBServerAuthorizationContext authorizationContext = authorizationContextHolder
|
||||
.getAuthorizationContext(httpSession);
|
||||
return authorizationContext.isValid() && authorizationContext.isLoggedIn();
|
||||
}
|
||||
|
||||
private WebApplicationContext getWebApplicationContext(final HttpSession httpSession) {
|
||||
try {
|
||||
final ServletContext servletContext = httpSession.getServletContext();
|
||||
|
||||
log.debug("Initialize Spring-Context on Servlet-Context: " + servletContext);
|
||||
|
||||
return WebApplicationContextUtils
|
||||
.getRequiredWebApplicationContext(servletContext);
|
||||
|
||||
} catch (final RuntimeException e) {
|
||||
log.error("Failed to initialize Spring-Context on HttpSession: " + httpSession);
|
||||
throw e;
|
||||
} catch (final Exception e) {
|
||||
log.error("Failed to initialize Spring-Context on HttpSession: " + httpSession);
|
||||
throw new RuntimeException("Failed to initialize Spring-Context on HttpSession: " + httpSession);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,83 +1,81 @@
|
|||
/*
|
||||
* Copyright (c) 2018 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;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletContextListener;
|
||||
import javax.servlet.ServletException;
|
||||
|
||||
import org.eclipse.rap.rwt.engine.RWTServlet;
|
||||
import org.eclipse.rap.rwt.engine.RWTServletContextListener;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.web.servlet.ServletContextInitializer;
|
||||
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
|
||||
import org.springframework.boot.web.servlet.ServletRegistrationBean;
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
|
||||
@Configuration
|
||||
@GuiProfile
|
||||
public class RAPSpringConfig {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(RAPSpringConfig.class);
|
||||
|
||||
@Value("${sebserver.gui.entrypoint}")
|
||||
private String entrypoint;
|
||||
|
||||
@Value("${sebserver.gui.external.messages:messages}")
|
||||
private String externalMessagesPath;
|
||||
|
||||
@Bean
|
||||
public ServletContextInitializer initializer() {
|
||||
return new RAPServletContextInitializer();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ServletListenerRegistrationBean<ServletContextListener> listenerRegistrationBean() {
|
||||
final ServletListenerRegistrationBean<ServletContextListener> bean =
|
||||
new ServletListenerRegistrationBean<>();
|
||||
bean.setListener(new RWTServletContextListener());
|
||||
return bean;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ServletRegistrationBean<RWTServlet> servletRegistrationBean() {
|
||||
return new ServletRegistrationBean<>(new RWTServlet(), this.entrypoint + "/*");
|
||||
}
|
||||
|
||||
@Bean
|
||||
public MessageSource messageSource() {
|
||||
final ReloadableResourceBundleMessageSource reloadableResourceBundleMessageSource =
|
||||
new ReloadableResourceBundleMessageSource();
|
||||
|
||||
log.info(" +++ Register external messages resources from: {}", this.externalMessagesPath);
|
||||
|
||||
reloadableResourceBundleMessageSource.setBasenames(
|
||||
this.externalMessagesPath,
|
||||
"classpath:messages");
|
||||
|
||||
return reloadableResourceBundleMessageSource;
|
||||
}
|
||||
|
||||
private static class RAPServletContextInitializer implements ServletContextInitializer {
|
||||
@Override
|
||||
public void onStartup(final ServletContext servletContext) throws ServletException {
|
||||
servletContext.setInitParameter(
|
||||
"org.eclipse.rap.applicationConfiguration",
|
||||
RAPConfiguration.class.getName());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2018 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;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
import org.eclipse.rap.rwt.engine.RWTServlet;
|
||||
import org.eclipse.rap.rwt.engine.RWTServletContextListener;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.web.servlet.ServletContextInitializer;
|
||||
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
|
||||
import org.springframework.boot.web.servlet.ServletRegistrationBean;
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletContextListener;
|
||||
|
||||
@Configuration
|
||||
@GuiProfile
|
||||
public class RAPSpringConfig {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(RAPSpringConfig.class);
|
||||
|
||||
@Value("${sebserver.gui.entrypoint}")
|
||||
private String entrypoint;
|
||||
|
||||
@Value("${sebserver.gui.external.messages:messages}")
|
||||
private String externalMessagesPath;
|
||||
|
||||
@Bean
|
||||
public ServletContextInitializer initializer() {
|
||||
return new RAPServletContextInitializer();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ServletListenerRegistrationBean<ServletContextListener> listenerRegistrationBean() {
|
||||
final ServletListenerRegistrationBean<ServletContextListener> bean =
|
||||
new ServletListenerRegistrationBean<>();
|
||||
bean.setListener(new RWTServletContextListener());
|
||||
return bean;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ServletRegistrationBean<RWTServlet> servletRegistrationBean() {
|
||||
return new ServletRegistrationBean<>(new RWTServlet(), this.entrypoint + "/*");
|
||||
}
|
||||
|
||||
@Bean
|
||||
public MessageSource messageSource() {
|
||||
final ReloadableResourceBundleMessageSource reloadableResourceBundleMessageSource =
|
||||
new ReloadableResourceBundleMessageSource();
|
||||
|
||||
log.info(" +++ Register external messages resources from: {}", this.externalMessagesPath);
|
||||
|
||||
reloadableResourceBundleMessageSource.setBasenames(
|
||||
this.externalMessagesPath,
|
||||
"classpath:messages");
|
||||
|
||||
return reloadableResourceBundleMessageSource;
|
||||
}
|
||||
|
||||
private static class RAPServletContextInitializer implements ServletContextInitializer {
|
||||
@Override
|
||||
public void onStartup(final ServletContext servletContext) {
|
||||
servletContext.setInitParameter(
|
||||
"org.eclipse.rap.applicationConfiguration",
|
||||
RAPConfiguration.class.getName());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -123,7 +123,7 @@ public class WidgetFactory {
|
|||
private ImageData image = null;
|
||||
private ImageData greyedImage = null;
|
||||
|
||||
private ImageIcon(final String fileName) {
|
||||
ImageIcon(final String fileName) {
|
||||
this.fileName = fileName;
|
||||
}
|
||||
|
||||
|
@ -199,7 +199,7 @@ public class WidgetFactory {
|
|||
|
||||
public final String key;
|
||||
|
||||
private CustomVariant(final String key) {
|
||||
CustomVariant(final String key) {
|
||||
this.key = key;
|
||||
}
|
||||
}
|
||||
|
@ -268,7 +268,7 @@ public class WidgetFactory {
|
|||
* @param parent The parent Composite
|
||||
* @return the scrolled Composite to add the form content */
|
||||
public Composite createPopupScrollComposite(final Composite parent) {
|
||||
final Composite grid = PageService.createManagedVScrolledComposite(
|
||||
return PageService.createManagedVScrolledComposite(
|
||||
parent,
|
||||
scrolledComposite -> {
|
||||
final Composite g = new Composite(scrolledComposite, SWT.NONE);
|
||||
|
@ -277,7 +277,6 @@ public class WidgetFactory {
|
|||
return g;
|
||||
},
|
||||
false);
|
||||
return grid;
|
||||
}
|
||||
|
||||
public Composite createWarningPanel(final Composite parent) {
|
||||
|
@ -733,7 +732,7 @@ public class WidgetFactory {
|
|||
new FileUploadSelection(parent, this.i18nSupport, readonly);
|
||||
|
||||
if (supportedFiles != null) {
|
||||
supportedFiles.forEach(ext -> fileUploadSelection.withSupportFor(ext));
|
||||
supportedFiles.forEach(fileUploadSelection::withSupportFor);
|
||||
}
|
||||
return fileUploadSelection;
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup;
|
|||
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetupTestResult;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap;
|
||||
import org.joda.time.DateTimeZone;
|
||||
|
||||
/** Defines the LMS API access service interface with all functionality needed to access
|
||||
* a LMS API within a given LmsSetup configuration.
|
||||
|
@ -101,12 +102,12 @@ public interface LmsAPIService {
|
|||
static Predicate<QuizData> quizFilterPredicate(final FilterMap filterMap) {
|
||||
final String name = filterMap.getQuizName();
|
||||
final DateTime from = filterMap.getQuizFromTime();
|
||||
//final DateTime now = DateTime.now(DateTimeZone.UTC);
|
||||
return q -> {
|
||||
final boolean nameFilter = StringUtils.isBlank(name) || (q.name != null && q.name.contains(name));
|
||||
final boolean startTimeFilter =
|
||||
(from == null) || (q.startTime != null && (q.startTime.isEqual(from) || q.startTime.isAfter(from)));
|
||||
return nameFilter && startTimeFilter /* && endTimeFilter */;
|
||||
final boolean currentlyRunning = DateTime.now(DateTimeZone.UTC).isBefore(q.endTime);
|
||||
return nameFilter && (startTimeFilter || currentlyRunning) ;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,135 +1,141 @@
|
|||
/*
|
||||
* Copyright (c) 2019 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.webservice.weblayer.api;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.mybatis.dynamic.sql.SqlTable;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||
import ch.ethz.seb.sebserver.gbl.api.API.BulkActionType;
|
||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.api.authorization.PrivilegeType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||
import ch.ethz.seb.sebserver.gbl.model.GrantEntity;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Page;
|
||||
import ch.ethz.seb.sebserver.gbl.model.session.ClientEvent;
|
||||
import ch.ethz.seb.sebserver.gbl.model.session.ExtendedClientEvent;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
||||
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ClientEventRecordDynamicSqlSupport;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.PaginationService;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.AuthorizationService;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.PermissionDeniedException;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.UserService;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.impl.SEBServerUser;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.BulkActionService;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ClientEventDAO;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ExamDAO;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserActivityLogDAO;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.validation.BeanValidationService;
|
||||
|
||||
@WebServiceProfile
|
||||
@RestController
|
||||
@RequestMapping("${sebserver.webservice.api.admin.endpoint}" + API.SEB_CLIENT_EVENT_ENDPOINT)
|
||||
public class ClientEventController extends ReadonlyEntityController<ClientEvent, ClientEvent> {
|
||||
|
||||
private final ExamDAO examDAO;
|
||||
private final ClientEventDAO clientEventDAO;
|
||||
|
||||
protected ClientEventController(
|
||||
final AuthorizationService authorization,
|
||||
final BulkActionService bulkActionService,
|
||||
final ClientEventDAO entityDAO,
|
||||
final UserActivityLogDAO userActivityLogDAO,
|
||||
final PaginationService paginationService,
|
||||
final BeanValidationService beanValidationService,
|
||||
final ExamDAO examDAO) {
|
||||
|
||||
super(authorization,
|
||||
bulkActionService,
|
||||
entityDAO,
|
||||
userActivityLogDAO,
|
||||
paginationService,
|
||||
beanValidationService);
|
||||
|
||||
this.examDAO = examDAO;
|
||||
this.clientEventDAO = entityDAO;
|
||||
}
|
||||
|
||||
@RequestMapping(
|
||||
path = API.SEB_CLIENT_EVENT_SEARCH_PATH_SEGMENT,
|
||||
method = RequestMethod.GET,
|
||||
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
|
||||
produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
public Page<ExtendedClientEvent> getExtendedPage(
|
||||
@RequestParam(
|
||||
name = API.PARAM_INSTITUTION_ID,
|
||||
required = true,
|
||||
defaultValue = UserService.USERS_INSTITUTION_AS_DEFAULT) final Long institutionId,
|
||||
@RequestParam(name = Page.ATTR_PAGE_NUMBER, required = false) final Integer pageNumber,
|
||||
@RequestParam(name = Page.ATTR_PAGE_SIZE, required = false) final Integer pageSize,
|
||||
@RequestParam(name = Page.ATTR_SORT, required = false) final String sort,
|
||||
@RequestParam final MultiValueMap<String, String> allRequestParams) {
|
||||
|
||||
// at least current user must have base read access for specified entity type within its own institution
|
||||
checkReadPrivilege(institutionId);
|
||||
|
||||
final FilterMap filterMap = new FilterMap(allRequestParams);
|
||||
|
||||
// if current user has no read access for specified entity type within other institution
|
||||
// then the current users institutionId is put as a SQL filter criteria attribute to extends query performance
|
||||
if (!this.authorization.hasGrant(PrivilegeType.READ, getGrantEntityType())) {
|
||||
filterMap.putIfAbsent(API.PARAM_INSTITUTION_ID, String.valueOf(institutionId));
|
||||
}
|
||||
|
||||
return this.paginationService.getPage(
|
||||
pageNumber,
|
||||
pageSize,
|
||||
sort,
|
||||
getSQLTableOfEntity().name(),
|
||||
() -> this.clientEventDAO.allMatchingExtended(filterMap, this::hasReadAccess))
|
||||
.getOrThrow();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<EntityKey> getDependencies(final String modelId, final BulkActionType bulkActionType) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SqlTable getSQLTableOfEntity() {
|
||||
return ClientEventRecordDynamicSqlSupport.clientEventRecord;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GrantEntity toGrantEntity(final ClientEvent entity) {
|
||||
return this.examDAO
|
||||
.byClientConnection(entity.connectionId)
|
||||
.getOrThrow();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void checkReadPrivilege(final Long institutionId) {
|
||||
final SEBServerUser currentUser = this.authorization.getUserService().getCurrentUser();
|
||||
if (currentUser.institutionId().longValue() != institutionId.longValue()) {
|
||||
throw new PermissionDeniedException(
|
||||
EntityType.CLIENT_EVENT,
|
||||
PrivilegeType.READ,
|
||||
currentUser.getUserInfo());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2019 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.webservice.weblayer.api;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.mybatis.dynamic.sql.SqlTable;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||
import ch.ethz.seb.sebserver.gbl.api.API.BulkActionType;
|
||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.api.authorization.PrivilegeType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||
import ch.ethz.seb.sebserver.gbl.model.GrantEntity;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Page;
|
||||
import ch.ethz.seb.sebserver.gbl.model.session.ClientEvent;
|
||||
import ch.ethz.seb.sebserver.gbl.model.session.ExtendedClientEvent;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
||||
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ClientEventRecordDynamicSqlSupport;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.PaginationService;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.AuthorizationService;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.PermissionDeniedException;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.UserService;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.impl.SEBServerUser;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.BulkActionService;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ClientEventDAO;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ExamDAO;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserActivityLogDAO;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.validation.BeanValidationService;
|
||||
|
||||
@WebServiceProfile
|
||||
@RestController
|
||||
@RequestMapping("${sebserver.webservice.api.admin.endpoint}" + API.SEB_CLIENT_EVENT_ENDPOINT)
|
||||
public class ClientEventController extends ReadonlyEntityController<ClientEvent, ClientEvent> {
|
||||
|
||||
private final ExamDAO examDAO;
|
||||
private final ClientEventDAO clientEventDAO;
|
||||
|
||||
protected ClientEventController(
|
||||
final AuthorizationService authorization,
|
||||
final BulkActionService bulkActionService,
|
||||
final ClientEventDAO entityDAO,
|
||||
final UserActivityLogDAO userActivityLogDAO,
|
||||
final PaginationService paginationService,
|
||||
final BeanValidationService beanValidationService,
|
||||
final ExamDAO examDAO) {
|
||||
|
||||
super(authorization,
|
||||
bulkActionService,
|
||||
entityDAO,
|
||||
userActivityLogDAO,
|
||||
paginationService,
|
||||
beanValidationService);
|
||||
|
||||
this.examDAO = examDAO;
|
||||
this.clientEventDAO = entityDAO;
|
||||
}
|
||||
|
||||
@RequestMapping(
|
||||
path = API.SEB_CLIENT_EVENT_SEARCH_PATH_SEGMENT,
|
||||
method = RequestMethod.GET,
|
||||
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
|
||||
produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||
public Page<ExtendedClientEvent> getExtendedPage(
|
||||
@RequestParam(
|
||||
name = API.PARAM_INSTITUTION_ID,
|
||||
required = true,
|
||||
defaultValue = UserService.USERS_INSTITUTION_AS_DEFAULT) final Long institutionId,
|
||||
@RequestParam(name = Page.ATTR_PAGE_NUMBER, required = false) final Integer pageNumber,
|
||||
@RequestParam(name = Page.ATTR_PAGE_SIZE, required = false) final Integer pageSize,
|
||||
@RequestParam(name = Page.ATTR_SORT, required = false) final String sort,
|
||||
@RequestParam final MultiValueMap<String, String> allRequestParams) {
|
||||
|
||||
// at least current user must have base read access for specified entity type within its own institution
|
||||
checkReadPrivilege(institutionId);
|
||||
|
||||
final FilterMap filterMap = new FilterMap(allRequestParams);
|
||||
|
||||
// if current user has no read access for specified entity type within other institution
|
||||
// then the current users institutionId is put as a SQL filter criteria attribute to extends query performance
|
||||
if (!this.authorization.hasGrant(PrivilegeType.READ, getGrantEntityType())) {
|
||||
filterMap.putIfAbsent(API.PARAM_INSTITUTION_ID, String.valueOf(institutionId));
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
return this.paginationService.getPage(
|
||||
pageNumber,
|
||||
pageSize,
|
||||
sort,
|
||||
getSQLTableOfEntity().name(),
|
||||
() -> this.clientEventDAO.allMatchingExtended(filterMap, this::hasReadAccess))
|
||||
.getOrThrow();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<EntityKey> getDependencies(final String modelId, final BulkActionType bulkActionType) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SqlTable getSQLTableOfEntity() {
|
||||
return ClientEventRecordDynamicSqlSupport.clientEventRecord;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GrantEntity toGrantEntity(final ClientEvent entity) {
|
||||
return this.examDAO
|
||||
.byClientConnection(entity.connectionId)
|
||||
.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void checkReadPrivilege(final Long institutionId) {
|
||||
final SEBServerUser currentUser = this.authorization.getUserService().getCurrentUser();
|
||||
if (currentUser.institutionId().longValue() != institutionId.longValue()) {
|
||||
throw new PermissionDeniedException(
|
||||
EntityType.CLIENT_EVENT,
|
||||
PrivilegeType.READ,
|
||||
currentUser.getUserInfo());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue