diff --git a/src/main/java/ch/ethz/seb/sebserver/WebSecurityConfig.java b/src/main/java/ch/ethz/seb/sebserver/WebSecurityConfig.java index 4029fd3c..ac981677 100644 --- a/src/main/java/ch/ethz/seb/sebserver/WebSecurityConfig.java +++ b/src/main/java/ch/ethz/seb/sebserver/WebSecurityConfig.java @@ -8,6 +8,7 @@ package ch.ethz.seb.sebserver; +import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.net.HttpURLConnection; @@ -22,6 +23,8 @@ import javax.servlet.http.HttpServletResponse; import org.apache.http.client.HttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.ssl.SSLContextBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.web.servlet.error.ErrorController; import org.springframework.context.annotation.Bean; @@ -57,6 +60,8 @@ import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile; @Order(6) public class WebSecurityConfig extends WebSecurityConfigurerAdapter implements ErrorController { + private static final Logger log = LoggerFactory.getLogger(WebSecurityConfig.class); + @Value("${sebserver.webservice.api.admin.endpoint}") private String adminEndpoint; @Value("${sebserver.webservice.api.redirect.unauthorized}") @@ -106,16 +111,8 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter implements E @DevGuiProfile @DevWebServiceProfile public ClientHttpRequestFactory clientHttpRequestFactory() { - // TODO set connection and read timeout!? configurable!? - return new SimpleClientHttpRequestFactory() { - - @Override - protected void prepareConnection(final HttpURLConnection connection, final String httpMethod) - throws IOException { - super.prepareConnection(connection, httpMethod); - connection.setInstanceFollowRedirects(false); - } - }; + log.info("Initialize with insecure ClientHttpRequestFactory for development"); + return new DevClientHttpRequestFactory(); } /** A ClientHttpRequestFactory used in production with TSL SSL configuration. @@ -139,15 +136,22 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter implements E public ClientHttpRequestFactory clientHttpRequestFactoryTLS(final Environment env) throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException, CertificateException, FileNotFoundException, IOException { + log.info("Initialize with secure ClientHttpRequestFactory for production"); + final char[] password = env - .getProperty("sebserver.gui.truststore.pwd") + .getProperty("sebserver.gui.truststore.pwd", "") .toCharArray(); + if (password.length < 3) { + log.error("Missing or incorrect trust-store password: " + String.valueOf(password)); + throw new IllegalArgumentException("Missing or incorrect trust-store password"); + } + + final File trustStoreFile = ResourceUtils.getFile("classpath:truststore.jks"); + final SSLContext sslContext = SSLContextBuilder .create() - .loadTrustMaterial(ResourceUtils.getFile( - "classpath:truststore.jks"), - password) + .loadTrustMaterial(trustStoreFile, password) .build(); final HttpClient client = HttpClients.custom() @@ -158,4 +162,17 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter implements E return new HttpComponentsClientHttpRequestFactory(client); } + // TODO set connection and read timeout!? configurable!? + private static class DevClientHttpRequestFactory extends SimpleClientHttpRequestFactory { + + @Override + protected void prepareConnection( + final HttpURLConnection connection, + final String httpMethod) throws IOException { + + super.prepareConnection(connection, httpMethod); + connection.setInstanceFollowRedirects(false); + } + } + } diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/EntityKey.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/EntityKey.java index 7c3f0482..9f6aca6b 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gbl/model/EntityKey.java +++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/EntityKey.java @@ -8,6 +8,8 @@ package ch.ethz.seb.sebserver.gbl.model; +import java.io.Serializable; + import javax.validation.constraints.NotNull; import com.fasterxml.jackson.annotation.JsonCreator; @@ -15,7 +17,9 @@ import com.fasterxml.jackson.annotation.JsonProperty; import ch.ethz.seb.sebserver.gbl.api.EntityType; -public class EntityKey { +public class EntityKey implements Serializable { + + private static final long serialVersionUID = -2368065921846821061L; @JsonProperty(value = "modelId", required = true) @NotNull diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/ExamineeAccountDetails.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/ExamineeAccountDetails.java index 4e772206..43a0bd37 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/ExamineeAccountDetails.java +++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/ExamineeAccountDetails.java @@ -51,7 +51,7 @@ public class ExamineeAccountDetails { return this.name; } - public String getUsername() { + public String getUserName() { return this.username; } 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 03618e37..9265e383 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/RAPConfiguration.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/RAPConfiguration.java @@ -36,16 +36,19 @@ public class RAPConfiguration implements ApplicationConfiguration { @Override public void configure(final Application application) { - final Map properties = new HashMap<>(); - properties.put(WebClient.PAGE_TITLE, "SEB Server"); - properties.put(WebClient.BODY_HTML, "Loading Application"); -// properties.put(WebClient.FAVICON, "icons/favicon.png"); - - application.addEntryPoint("/gui", RAPSpringEntryPointFactory, properties); - try { + final Map properties = new HashMap<>(); + properties.put(WebClient.PAGE_TITLE, "SEB Server"); + properties.put(WebClient.BODY_HTML, "Loading Application"); + // properties.put(WebClient.FAVICON, "icons/favicon.png"); + + application.addEntryPoint("/gui", RAPSpringEntryPointFactory, properties); + // TODO get file path from properties application.addStyleSheet(RWT.DEFAULT_THEME_ID, "static/css/sebserver.css"); + + } 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); } 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 dca20f24..deee0a59 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/RAPSpringConfig.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/RAPSpringConfig.java @@ -32,15 +32,7 @@ public class RAPSpringConfig { @Bean public ServletContextInitializer initializer() { - return new ServletContextInitializer() { - - @Override - public void onStartup(final ServletContext servletContext) throws ServletException { - servletContext.setInitParameter( - "org.eclipse.rap.applicationConfiguration", - RAPConfiguration.class.getName()); - } - }; + return new RAPServletContextInitializer(); } @Bean @@ -56,4 +48,13 @@ public class RAPSpringConfig { return new ServletRegistrationBean<>(new RWTServlet(), this.entrypoint + "/*"); } + private static class RAPServletContextInitializer implements ServletContextInitializer { + @Override + public void onStartup(final ServletContext servletContext) throws ServletException { + servletContext.setInitParameter( + "org.eclipse.rap.applicationConfiguration", + RAPConfiguration.class.getName()); + } + } + } diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/InstitutionForm.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/InstitutionForm.java index 5ac9b200..1accf32e 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/InstitutionForm.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/InstitutionForm.java @@ -87,8 +87,7 @@ public class InstitutionForm implements TemplateComposer { final boolean isReadonly = pageContext.isReadonly(); // new PageContext with actual EntityKey - final PageContext formContext = pageContext; - pageContext.withEntityKey(institution.getEntityKey()); + final PageContext formContext = pageContext.withEntityKey(institution.getEntityKey()); if (log.isDebugEnabled()) { log.debug("Institution Form for Institution {}", institution.name); diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/MainPage.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/MainPage.java index 77dd19c9..654bfe45 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/MainPage.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/MainPage.java @@ -8,6 +8,8 @@ package ch.ethz.seb.sebserver.gui.content; +import java.util.function.Consumer; + import org.eclipse.rap.rwt.RWT; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.SashForm; @@ -118,40 +120,22 @@ public class MainPage implements TemplateComposer { contentObjectslayout.marginHeight = 0; contentObjectslayout.marginWidth = 0; contentObjects.setLayout(contentObjectslayout); - contentObjects.setData(PageEventListener.LISTENER_ATTRIBUTE_KEY, - new ActionEventListener() { - @Override - public int priority() { - return 2; - } - - @Override - public void notify(final ActionEvent event) { - pageContext.composerService().compose( - event.action.definition.contentPaneComposer, - event.action.pageContext().copyOf(contentObjects)); - } - }); + contentObjects.setData( + PageEventListener.LISTENER_ATTRIBUTE_KEY, + new ContentActionEventListener(event -> pageContext.composerService().compose( + event.action.definition.contentPaneComposer, + event.action.pageContext().copyOf(contentObjects)), 2)); final Composite actionPane = new Composite(mainSash, SWT.NONE); actionPane.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); final GridLayout actionPaneGrid = new GridLayout(); actionPane.setLayout(actionPaneGrid); actionPane.setData(RWT.CUSTOM_VARIANT, "actionPane"); - actionPane.setData(PageEventListener.LISTENER_ATTRIBUTE_KEY, - new ActionEventListener() { - @Override - public int priority() { - return 1; - } - - @Override - public void notify(final ActionEvent event) { - pageContext.composerService().compose( - event.action.definition.actionPaneComposer, - event.action.pageContext().copyOf(actionPane)); - } - }); + actionPane.setData( + PageEventListener.LISTENER_ATTRIBUTE_KEY, + new ContentActionEventListener(event -> pageContext.composerService().compose( + event.action.definition.actionPaneComposer, + event.action.pageContext().copyOf(actionPane)), 1)); pageContext.composerService().compose( ActivitiesPane.class, @@ -160,4 +144,25 @@ public class MainPage implements TemplateComposer { mainSash.setWeights(DEFAULT_SASH_WEIGHTS); } + private static final class ContentActionEventListener implements ActionEventListener { + + private final int priority; + private final Consumer apply; + + protected ContentActionEventListener(final Consumer apply, final int priority) { + this.apply = apply; + this.priority = priority; + } + + @Override + public int priority() { + return this.priority; + } + + @Override + public void notify(final ActionEvent event) { + this.apply.accept(event); + } + } + } diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/UserAccountForm.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/UserAccountForm.java index b0d441ea..969c79dd 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/UserAccountForm.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/UserAccountForm.java @@ -112,8 +112,7 @@ public class UserAccountForm implements TemplateComposer { .getOr(false); // new PageContext with actual EntityKey - final PageContext formContext = pageContext; - pageContext.withEntityKey(userAccount.getEntityKey()); + final PageContext formContext = pageContext.withEntityKey(userAccount.getEntityKey()); if (log.isDebugEnabled()) { log.debug("UserAccount Form for user {}", userAccount.getName()); diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/activity/ActivitiesPane.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/activity/ActivitiesPane.java index 797b0201..07e2b5b2 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/activity/ActivitiesPane.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/activity/ActivitiesPane.java @@ -120,24 +120,7 @@ public class ActivitiesPane implements TemplateComposer { navigation.addListener(SWT.Selection, event -> handleSelection(pageContext, event)); navigation.setData( PageEventListener.LISTENER_ATTRIBUTE_KEY, - new ActionEventListener() { - @Override - public void notify(final ActionEvent event) { - final MainPageState mainPageState = MainPageState.get(); - mainPageState.action = event.action; - if (!event.activity) { - final EntityKey entityKey = event.action.getEntityKey(); - final String modelId = (entityKey != null) ? entityKey.modelId : null; - final TreeItem item = findItemByActionDefinition( - navigation.getItems(), - event.action.definition, - modelId); - if (item != null) { - navigation.select(item); - } - } - } - }); + new ActivitiesActionEventListener(navigation)); // page-selection on (re)load final MainPageState mainPageState = MainPageState.get(); @@ -175,9 +158,12 @@ public class ActivitiesPane implements TemplateComposer { for (final TreeItem item : items) { final Action action = getActivitySelection(item); + if (action == null) { + continue; + } + final EntityKey entityKey = action.getEntityKey(); - if (action != null - && (action.definition == actionDefinition || action.definition == actionDefinition.activityAlias) && + if ((action.definition == actionDefinition || action.definition == actionDefinition.activityAlias) && (entityKey == null || (modelId != null && modelId.equals(entityKey.modelId)))) { return item; } @@ -212,4 +198,29 @@ public class ActivitiesPane implements TemplateComposer { item.setData(ATTR_ACTIVITY_SELECTION, action); } + private final class ActivitiesActionEventListener implements ActionEventListener { + private final Tree navigation; + + private ActivitiesActionEventListener(final Tree navigation) { + this.navigation = navigation; + } + + @Override + public void notify(final ActionEvent event) { + final MainPageState mainPageState = MainPageState.get(); + mainPageState.action = event.action; + if (!event.activity) { + final EntityKey entityKey = event.action.getEntityKey(); + final String modelId = (entityKey != null) ? entityKey.modelId : null; + final TreeItem item = findItemByActionDefinition( + this.navigation.getItems(), + event.action.definition, + modelId); + if (item != null) { + this.navigation.select(item); + } + } + } + } + } diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/form/SelectionFieldBuilder.java b/src/main/java/ch/ethz/seb/sebserver/gui/form/SelectionFieldBuilder.java index 34dcf66a..eeb44665 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/form/SelectionFieldBuilder.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/form/SelectionFieldBuilder.java @@ -76,9 +76,9 @@ public final class SelectionFieldBuilder extends FieldBuilder { ((Control) selection).setLayoutData(gridData); selection.select(this.value); if (this.multi) { - builder.form.putField(this.name, lab, (MultiSelection) selection); + builder.form.putField(this.name, lab, selection. getTypeInstance()); } else { - builder.form.putField(this.name, lab, (SingleSelection) selection); + builder.form.putField(this.name, lab, selection. getTypeInstance()); } if (this.selectionListener != null) { ((Control) selection).addListener(SWT.Selection, e -> { diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/event/ActionEventListener.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/event/ActionEventListener.java index b9a1ce0b..d8121d1b 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/event/ActionEventListener.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/event/ActionEventListener.java @@ -15,52 +15,4 @@ public interface ActionEventListener extends PageEventListener { return type == ActionEvent.class; } -// static ActionEventListener of(final Consumer eventConsumer) { -// return new ActionEventListener() { -// @Override -// public void notify(final ActionEvent event) { -// eventConsumer.accept(event); -// } -// }; -// } -// - -// static ActionEventListener of( -// final Predicate predicate, -// final Consumer eventConsumer) { -// -// return new ActionEventListener() { -// @Override -// public void notify(final ActionEvent event) { -// if (predicate.test(event)) { -// eventConsumer.accept(event); -// } -// } -// }; -// } - -// static ActionEventListener of( -// final ActionDefinition actionDefinition, -// final Consumer eventConsumer) { -// -// return new ActionEventListener() { -// @Override -// public void notify(final ActionEvent event) { -// if (event.actionDefinition == actionDefinition) { -// eventConsumer.accept(event); -// } -// } -// }; -// } -// -// static void injectListener( -// final Widget widget, -// final ActionDefinition actionDefinition, -// final Consumer eventConsumer) { -// -// widget.setData( -// PageEventListener.LISTENER_ATTRIBUTE_KEY, -// of(actionDefinition, eventConsumer)); -// } - } diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/MainPageState.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/MainPageState.java index a550af76..aa35a59c 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/MainPageState.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/MainPageState.java @@ -28,6 +28,7 @@ public final class MainPageState { public static MainPageState get() { try { + final HttpSession httpSession = RWT .getUISession() .getHttpSession(); @@ -39,6 +40,9 @@ public final class MainPageState { } return mainPageState; + + } catch (final RuntimeException re) { + throw re; } catch (final Exception e) { log.error("Unexpected error while trying to get MainPageState from user-session"); } diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/PageContextImpl.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/PageContextImpl.java index b47e1534..63fb87fb 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/PageContextImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/page/impl/PageContextImpl.java @@ -138,27 +138,6 @@ public class PageContextImpl implements PageContext { attrs); } -// @Override -// public PageContext withSelection(final ActivitySelection selection, final boolean clearAttributes) { -// if (selection == null) { -// return this; -// } -// -// final Map attrs = new HashMap<>(); -// if (!clearAttributes) { -// attrs.putAll(this.attributes); -// } -// attrs.putAll(selection.getAttributes()); -// -// return new PageContextImpl( -// this.restService, -// this.i18nSupport, -// this.composerService, -// this.root, -// this.parent, -// attrs); -// } - @Override public String getAttribute(final String name) { return this.attributes.get(name); @@ -268,7 +247,6 @@ public class PageContextImpl implements PageContext { } @Override - @SuppressWarnings("serial") public void applyConfirmDialog(final LocTextKey confirmMessage, final Runnable onOK) { final Message messageBox = new Message( this.root.getShell(), @@ -276,30 +254,9 @@ public class PageContextImpl implements PageContext { this.i18nSupport.getText(confirmMessage), SWT.OK | SWT.CANCEL); messageBox.setMarkupEnabled(true); - messageBox.open(new DialogCallback() { - @Override - public void dialogClosed(final int returnCode) { - if (returnCode == SWT.OK) { - try { - onOK.run(); - } catch (final Throwable t) { - log.error( - "Unexpected on confirm callback execution. This should not happen, plase secure the given onOK Runnable", - t); - } - } - } - }); + messageBox.open(new ConfirmDialogCallback(onOK)); } -// public void applyValidationErrorDialog(final Collection validationErrors) { -// final Message messageBox = new Message( -// this.root.getShell(), -// this.i18nSupport.getText("org.sebserver.dialog.validationErrors.title"), -// this.i18nSupport.getText(confirmMessage), -// SWT.OK); -// } - @Override public void forwardToPage( final PageDefinition pageDefinition, @@ -391,6 +348,28 @@ public class PageContextImpl implements PageContext { + "]"; } + private final class ConfirmDialogCallback implements DialogCallback { + private static final long serialVersionUID = 1491270214433492441L; + private final Runnable onOK; + + private ConfirmDialogCallback(final Runnable onOK) { + this.onOK = onOK; + } + + @Override + public void dialogClosed(final int returnCode) { + if (returnCode == SWT.OK) { + try { + this.onOK.run(); + } catch (final Throwable t) { + log.error( + "Unexpected on confirm callback execution. This should not happen, plase secure the given onOK Runnable", + t); + } + } + } + } + private static final class ListenerComparator implements Comparator> { @Override public int compare(final PageEventListener o1, final PageEventListener o2) { diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/RestCall.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/RestCall.java index 34b5cbb6..fe505c3c 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/RestCall.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/RestCall.java @@ -91,6 +91,7 @@ public abstract class RestCall { final RestCallError restCallError = new RestCallError("Response Entity: " + responseEntity.toString()); + restCallError.errors.addAll(RestCall.this.jsonMapper.readValue( responseEntity.getBody(), new TypeReference>() { @@ -106,14 +107,25 @@ public abstract class RestCall { } catch (final Throwable t) { final RestCallError restCallError = new RestCallError("Unexpected error while rest call", t); try { + final String responseBody = ((RestClientResponseException) t).getResponseBodyAsString(); + restCallError.errors.addAll(RestCall.this.jsonMapper.readValue( responseBody, new TypeReference>() { })); - } catch (final Exception e) { - log.error("Unexpected error-response while webservice API call for: {}", builder, e); + + } catch (final ClassCastException cce) { + log.error("Unexpected error-response while webservice API call for: {}", builder, cce); log.error("Unexpected error-response cause: ", t); + restCallError.errors.add(APIMessage.ErrorMessage.UNEXPECTED.of(cce)); + } catch (final RuntimeException re) { + log.error("Unexpected runtime error while webservice API call for: {}", builder, re); + log.error("Unexpected runtime error cause: ", t); + restCallError.errors.add(APIMessage.ErrorMessage.UNEXPECTED.of(re)); + } catch (final Exception e) { + log.error("Unexpected error while webservice API call for: {}", builder, e); + log.error("Unexpected error cause: ", t); restCallError.errors.add(APIMessage.ErrorMessage.UNEXPECTED.of(e)); } diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/auth/OAuth2AuthorizationContextHolder.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/auth/OAuth2AuthorizationContextHolder.java index a33c6db6..019c4815 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/auth/OAuth2AuthorizationContextHolder.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/auth/OAuth2AuthorizationContextHolder.java @@ -170,14 +170,7 @@ public class OAuth2AuthorizationContextHolder implements AuthorizationContextHol this.restTemplate = new DisposableOAuth2RestTemplate(this.resource); this.restTemplate.setRequestFactory(clientHttpRequestFactory); - this.restTemplate.setErrorHandler(new OAuth2ErrorHandler(this.resource) { - @Override - public boolean hasError(final ClientHttpResponse response) throws IOException { - final HttpStatus statusCode = HttpStatus.resolve(response.getRawStatusCode()); - return (statusCode != null && statusCode.series() == HttpStatus.Series.SERVER_ERROR); - } - - }); + this.restTemplate.setErrorHandler(new ErrorHandler(this.resource)); this.revokeTokenURI = webserviceURIService.getOAuthRevokeTokenURI(); this.currentUserURI = webserviceURIService.getCurrentUserRequestURI(); @@ -297,5 +290,17 @@ public class OAuth2AuthorizationContextHolder implements AuthorizationContextHol .contains(role.name()); } + private final class ErrorHandler extends OAuth2ErrorHandler { + private ErrorHandler(final OAuth2ProtectedResourceDetails resource) { + super(resource); + } + + @Override + public boolean hasError(final ClientHttpResponse response) throws IOException { + final HttpStatus statusCode = HttpStatus.resolve(response.getRawStatusCode()); + return (statusCode != null && statusCode.series() == HttpStatus.Series.SERVER_ERROR); + } + } + } } diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/table/TableNavigator.java b/src/main/java/ch/ethz/seb/sebserver/gui/table/TableNavigator.java index 0978c7d2..1b6e3d37 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/table/TableNavigator.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/table/TableNavigator.java @@ -21,8 +21,9 @@ import ch.ethz.seb.sebserver.gui.widget.WidgetFactory; public class TableNavigator { + private final static int PAGE_NAV_SIZE = 3; + private final Composite composite; - private final int pageNavSize = 3; private final EntityTable entityTable; TableNavigator(final EntityTable entityTable) { @@ -56,7 +57,7 @@ public class TableNavigator { createRewardLabel(pageNumber, numNav); } - for (int i = pageNumber - this.pageNavSize; i < pageNumber + this.pageNavSize; i++) { + for (int i = pageNumber - PAGE_NAV_SIZE; i < pageNumber + PAGE_NAV_SIZE; i++) { if (i >= 1 && i <= numberOfPages) { createPageNumberLabel(i, i != pageNumber, numNav); } diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/widget/ImageUpload.java b/src/main/java/ch/ethz/seb/sebserver/gui/widget/ImageUpload.java index 3682b802..de6f2fe1 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/widget/ImageUpload.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/widget/ImageUpload.java @@ -41,7 +41,7 @@ public class ImageUpload extends Composite { private static final Logger log = LoggerFactory.getLogger(ImageUpload.class); - private final ServerPushService serverPushService; + private transient final ServerPushService serverPushService; private final Composite imageCanvas; private final FileUpload fileUpload; @@ -136,8 +136,10 @@ public class ImageUpload extends Composite { private static final void wait(final ServerPushContext context) { try { Thread.sleep(200); - } catch (final Exception e) { + } catch (final InterruptedException e) { + log.info("InterruptedException while wait for image uplaod. Just ignore it"); } + } private static final void update(final ServerPushContext context) { @@ -145,6 +147,7 @@ public class ImageUpload extends Composite { if (imageUpload.imageBase64 != null && imageUpload.loadNewImage && imageUpload.imageLoaded) { + final Base64InputStream input = new Base64InputStream( new ByteArrayInputStream( imageUpload.imageBase64.getBytes(StandardCharsets.UTF_8)), diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/widget/MultiSelection.java b/src/main/java/ch/ethz/seb/sebserver/gui/widget/MultiSelection.java index 6496354f..81c358f6 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/widget/MultiSelection.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/widget/MultiSelection.java @@ -133,4 +133,10 @@ public class MultiSelection extends Composite implements Selection { deselectAll(); } + @SuppressWarnings("unchecked") + @Override + public MultiSelection getTypeInstance() { + return this; + } + } diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/widget/Selection.java b/src/main/java/ch/ethz/seb/sebserver/gui/widget/Selection.java index 299a3b15..5e5ab1ff 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/widget/Selection.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/widget/Selection.java @@ -24,4 +24,6 @@ public interface Selection { void setVisible(boolean visible); + T getTypeInstance(); + } diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/widget/SingleSelection.java b/src/main/java/ch/ethz/seb/sebserver/gui/widget/SingleSelection.java index 30858377..173bb9e1 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/widget/SingleSelection.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/widget/SingleSelection.java @@ -72,4 +72,10 @@ public class SingleSelection extends Combo implements Selection { super.setItems(this.valueMapping.toArray(new String[this.valueMapping.size()])); } + @SuppressWarnings("unchecked") + @Override + public SingleSelection getTypeInstance() { + return this; + } + } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/PaginationService.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/PaginationService.java index 8c613ffc..d2b576a0 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/PaginationService.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/PaginationService.java @@ -255,6 +255,12 @@ public class PaginationService { examTableMap.put( Domain.EXAM.ATTR_STATUS, ExamRecordDynamicSqlSupport.status.name()); + this.sortColumnMapping.put( + ExamRecordDynamicSqlSupport.examRecord.name(), + examTableMap); + this.defaultSortColumn.put( + ExamRecordDynamicSqlSupport.examRecord.name(), + Domain.EXAM.ATTR_ID); } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/authorization/PermissionDeniedException.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/authorization/PermissionDeniedException.java index cf2f9926..48a1b721 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/authorization/PermissionDeniedException.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/authorization/PermissionDeniedException.java @@ -16,8 +16,7 @@ public class PermissionDeniedException extends RuntimeException { private static final long serialVersionUID = 5333137812363042580L; public final EntityType entityType; - public final GrantEntity entity; - public final PrivilegeType grantType; + public final PrivilegeType privilegeType; public final String userId; public PermissionDeniedException( @@ -27,8 +26,7 @@ public class PermissionDeniedException extends RuntimeException { super("No grant: " + grantType + " on type: " + entityType + " for user: " + userId); this.entityType = entityType; - this.entity = null; - this.grantType = grantType; + this.privilegeType = grantType; this.userId = userId; } @@ -43,8 +41,7 @@ public class PermissionDeniedException extends RuntimeException { " entity owner: " + entity.getOwnerId() + " for user: " + userId); this.entityType = entity.entityType(); - this.entity = entity; - this.grantType = grantType; + this.privilegeType = grantType; this.userId = userId; } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/bulkaction/BulkActionService.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/bulkaction/BulkActionService.java index 7bf8b3de..b1a3346b 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/bulkaction/BulkActionService.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/bulkaction/BulkActionService.java @@ -156,22 +156,14 @@ public class BulkActionService { this.supporter.get(EntityType.INDICATOR), this.supporter.get(EntityType.CLIENT_CONNECTION), this.supporter.get(EntityType.CONFIGURATION_NODE)); - case LMS_SETUP: - return Arrays.asList( - this.supporter.get(EntityType.EXAM), - this.supporter.get(EntityType.INDICATOR), - this.supporter.get(EntityType.CLIENT_CONNECTION)); case USER: return Arrays.asList( this.supporter.get(EntityType.EXAM), this.supporter.get(EntityType.INDICATOR), this.supporter.get(EntityType.CLIENT_CONNECTION), this.supporter.get(EntityType.CONFIGURATION_NODE)); + case LMS_SETUP: case EXAM: - return Arrays.asList( - this.supporter.get(EntityType.EXAM), - this.supporter.get(EntityType.INDICATOR), - this.supporter.get(EntityType.CLIENT_CONNECTION)); case CONFIGURATION: return Arrays.asList( this.supporter.get(EntityType.EXAM),