diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/GuiInit.java b/src/main/java/ch/ethz/seb/sebserver/gui/GuiInit.java index 88574d9b..5a139167 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/GuiInit.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/GuiInit.java @@ -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 { - - 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 { + + 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("---->"); + } + +} diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/InstitutionalAuthenticationEntryPoint.java b/src/main/java/ch/ethz/seb/sebserver/gui/InstitutionalAuthenticationEntryPoint.java index 9d02c350..7f06c4e3 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/InstitutionalAuthenticationEntryPoint.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/InstitutionalAuthenticationEntryPoint.java @@ -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 diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/RAPConfiguration.java b/src/main/java/ch/ethz/seb/sebserver/gui/RAPConfiguration.java index 9273d58a..a282b658 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/RAPConfiguration.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/RAPConfiguration.java @@ -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 properties = new HashMap<>(); - properties.put(WebClient.PAGE_TITLE, "SEB Server"); - properties.put(WebClient.BODY_HTML, "Loading Application"); - 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 properties = new HashMap<>(); + properties.put(WebClient.PAGE_TITLE, "SEB Server"); + properties.put(WebClient.BODY_HTML, "Loading Application"); + 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); + } + } + + } +} diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/RAPSpringConfig.java b/src/main/java/ch/ethz/seb/sebserver/gui/RAPSpringConfig.java index 67db3257..3b24c2d3 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/RAPSpringConfig.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/RAPSpringConfig.java @@ -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 listenerRegistrationBean() { - final ServletListenerRegistrationBean bean = - new ServletListenerRegistrationBean<>(); - bean.setListener(new RWTServletContextListener()); - return bean; - } - - @Bean - public ServletRegistrationBean 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 listenerRegistrationBean() { + final ServletListenerRegistrationBean bean = + new ServletListenerRegistrationBean<>(); + bean.setListener(new RWTServletContextListener()); + return bean; + } + + @Bean + public ServletRegistrationBean 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()); + } + } + +} diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/widget/WidgetFactory.java b/src/main/java/ch/ethz/seb/sebserver/gui/widget/WidgetFactory.java index 4675e3c0..03ec4d87 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/widget/WidgetFactory.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/widget/WidgetFactory.java @@ -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; } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/LmsAPIService.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/LmsAPIService.java index cbdf65ab..33e27a37 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/LmsAPIService.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/LmsAPIService.java @@ -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 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) ; }; } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ClientEventController.java b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ClientEventController.java index 343b1b3e..be6cbefe 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ClientEventController.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ClientEventController.java @@ -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 { - - 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 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 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 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 { + + 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 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 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 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()); + } + } + +}