Merge branch 'master' of https://github.com/SafeExamBrowser/seb-server.git
This commit is contained in:
commit
cccbc48805
61 changed files with 7744 additions and 7773 deletions
|
@ -34,7 +34,7 @@ public class GuiInit implements ApplicationListener<ApplicationReadyEvent> {
|
|||
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("----> 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
|
||||
|
|
|
@ -63,7 +63,7 @@ public class RAPConfiguration implements ApplicationConfiguration {
|
|||
}
|
||||
}
|
||||
|
||||
public static interface EntryPointService {
|
||||
public interface EntryPointService {
|
||||
|
||||
void loadLoginPage(final Composite parent);
|
||||
|
||||
|
@ -160,5 +160,5 @@ public class RAPConfiguration implements ApplicationConfiguration {
|
|||
}
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,10 +8,7 @@
|
|||
|
||||
package ch.ethz.seb.sebserver.gui;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletContextListener;
|
||||
import javax.servlet.ServletException;
|
||||
|
||||
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;
|
||||
|
@ -25,7 +22,8 @@ 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;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletContextListener;
|
||||
|
||||
@Configuration
|
||||
@GuiProfile
|
||||
|
@ -73,7 +71,7 @@ public class RAPSpringConfig {
|
|||
|
||||
private static class RAPServletContextInitializer implements ServletContextInitializer {
|
||||
@Override
|
||||
public void onStartup(final ServletContext servletContext) throws ServletException {
|
||||
public void onStartup(final ServletContext servletContext) {
|
||||
servletContext.setInitParameter(
|
||||
"org.eclipse.rap.applicationConfiguration",
|
||||
RAPConfiguration.class.getName());
|
||||
|
|
|
@ -82,8 +82,8 @@ public class ResourceService {
|
|||
|
||||
private static final String MISSING_CLIENT_PING_NAME_KEY = "MISSING";
|
||||
|
||||
public static final Comparator<Tuple<String>> RESOURCE_COMPARATOR = (t1, t2) -> t1._2.compareTo(t2._2);
|
||||
public static final Comparator<Tuple3<String>> RESOURCE_COMPARATOR_TUPLE_3 = (t1, t2) -> t1._2.compareTo(t2._2);
|
||||
public static final Comparator<Tuple<String>> RESOURCE_COMPARATOR = Comparator.comparing(t -> t._2);
|
||||
public static final Comparator<Tuple3<String>> RESOURCE_COMPARATOR_TUPLE_3 = Comparator.comparing(t -> t._2);
|
||||
|
||||
public static final EnumSet<EntityType> ENTITY_TYPE_EXCLUDE_MAP = EnumSet.of(
|
||||
EntityType.ADDITIONAL_ATTRIBUTES,
|
||||
|
|
|
@ -24,7 +24,7 @@ public class FieldValidationError {
|
|||
public FieldValidationError(final APIMessage apiMessage) {
|
||||
this(
|
||||
apiMessage.messageCode,
|
||||
apiMessage.attributes.toArray(new String[apiMessage.attributes.size()]));
|
||||
apiMessage.attributes.toArray(new String[0]));
|
||||
}
|
||||
|
||||
public FieldValidationError(
|
||||
|
@ -44,7 +44,7 @@ public class FieldValidationError {
|
|||
return new String[0];
|
||||
}
|
||||
|
||||
return this.attributes.toArray(new String[this.attributes.size()]);
|
||||
return this.attributes.toArray(new String[0]);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -27,34 +27,34 @@ public interface PageContext {
|
|||
Logger log = LoggerFactory.getLogger(PageContext.class);
|
||||
|
||||
/** Defines attribute keys that can be used to store attribute values within the page context state */
|
||||
public interface AttributeKeys {
|
||||
interface AttributeKeys {
|
||||
|
||||
public static final String PAGE_TEMPLATE_COMPOSER_NAME = "ATTR_PAGE_TEMPLATE_COMPOSER_NAME";
|
||||
String PAGE_TEMPLATE_COMPOSER_NAME = "ATTR_PAGE_TEMPLATE_COMPOSER_NAME";
|
||||
|
||||
public static final String READ_ONLY = "READ_ONLY";
|
||||
public static final String READ_ONLY_FROM = "READ_ONLY_FROM";
|
||||
String READ_ONLY = "READ_ONLY";
|
||||
String READ_ONLY_FROM = "READ_ONLY_FROM";
|
||||
|
||||
public static final String ENTITY_ID = "ENTITY_ID";
|
||||
public static final String PARENT_ENTITY_ID = "PARENT_ENTITY_ID";
|
||||
public static final String ENTITY_TYPE = "ENTITY_TYPE";
|
||||
public static final String PARENT_ENTITY_TYPE = "PARENT_ENTITY_TYPE";
|
||||
String ENTITY_ID = "ENTITY_ID";
|
||||
String PARENT_ENTITY_ID = "PARENT_ENTITY_ID";
|
||||
String ENTITY_TYPE = "ENTITY_TYPE";
|
||||
String PARENT_ENTITY_TYPE = "PARENT_ENTITY_TYPE";
|
||||
|
||||
public static final String IMPORT_FROM_QUIZ_DATA = "IMPORT_FROM_QUIZ_DATA";
|
||||
String IMPORT_FROM_QUIZ_DATA = "IMPORT_FROM_QUIZ_DATA";
|
||||
|
||||
public static final String COPY_AS_TEMPLATE = "COPY_AS_TEMPLATE";
|
||||
public static final String CREATE_FROM_TEMPLATE = "CREATE_FROM_TEMPLATE";
|
||||
String COPY_AS_TEMPLATE = "COPY_AS_TEMPLATE";
|
||||
String CREATE_FROM_TEMPLATE = "CREATE_FROM_TEMPLATE";
|
||||
|
||||
}
|
||||
|
||||
/** The resource-bundle key of the generic load entity error message. */
|
||||
public static final String GENERIC_LOAD_ERROR_TEXT_KEY = "sebserver.error.get.entity";
|
||||
public static final String GENERIC_REMOVE_ERROR_TEXT_KEY = "sebserver.error.remove.entity";
|
||||
public static final String GENERIC_SAVE_ERROR_TEXT_KEY = "sebserver.error.save.entity";
|
||||
public static final String GENERIC_ACTIVATE_ERROR_TEXT_KEY = "sebserver.error.activate.entity";
|
||||
public static final String GENERIC_IMPORT_ERROR_TEXT_KEY = "sebserver.error.import";
|
||||
public static final LocTextKey SUCCESS_MSG_TITLE =
|
||||
String GENERIC_LOAD_ERROR_TEXT_KEY = "sebserver.error.get.entity";
|
||||
String GENERIC_REMOVE_ERROR_TEXT_KEY = "sebserver.error.remove.entity";
|
||||
String GENERIC_SAVE_ERROR_TEXT_KEY = "sebserver.error.save.entity";
|
||||
String GENERIC_ACTIVATE_ERROR_TEXT_KEY = "sebserver.error.activate.entity";
|
||||
String GENERIC_IMPORT_ERROR_TEXT_KEY = "sebserver.error.import";
|
||||
LocTextKey SUCCESS_MSG_TITLE =
|
||||
new LocTextKey("sebserver.page.message");
|
||||
public static final LocTextKey UNEXPECTED_ERROR_KEY =
|
||||
LocTextKey UNEXPECTED_ERROR_KEY =
|
||||
new LocTextKey("sebserver.error.action.unexpected.message");
|
||||
|
||||
/** Get the I18nSupport service
|
||||
|
@ -84,11 +84,11 @@ public interface PageContext {
|
|||
|
||||
/** Get a copy of this PageContext.
|
||||
*
|
||||
* @return */
|
||||
* @return a deep copy of this PageContext */
|
||||
PageContext copy();
|
||||
|
||||
/** Create a copy of this PageContext with a new parent Composite.
|
||||
* The implementation should take care of the imutability of PageContext and return a copy with the new parent
|
||||
* The implementation should take care of the immutability of PageContext and return a copy with the new parent
|
||||
* by leave this PageContext as is.
|
||||
*
|
||||
* @param parent the new parent Composite
|
||||
|
@ -97,15 +97,15 @@ public interface PageContext {
|
|||
|
||||
/** Create a copy of this PageContext with and additionally page context attributes.
|
||||
* The additionally page context attributes will get merged with them already defined
|
||||
* The implementation should take care of the imutability of PageContext and return a copy with the merge
|
||||
* The implementation should take care of the immutability of PageContext and return a copy with the merge
|
||||
* by leave this and the given PageContext as is.
|
||||
*
|
||||
* @param attributes additionally page context attributes.
|
||||
* @param otherContext the other PageContext to copy the attributes from
|
||||
* @return a copy of this PageContext with with and additionally page context attributes. */
|
||||
PageContext copyOfAttributes(PageContext otherContext);
|
||||
|
||||
/** Adds the specified attribute to the existing page context attributes.
|
||||
* The implementation should take care of the imutability of PageContext and return a copy
|
||||
* The implementation should take care of the immutability of PageContext and return a copy
|
||||
* by leave this PageContext as is.
|
||||
*
|
||||
* @param key the key of the attribute
|
||||
|
@ -162,7 +162,7 @@ public interface PageContext {
|
|||
|
||||
/** Create a copy of this PageContext and resets both entity keys attributes, the base and the parent EntityKey
|
||||
*
|
||||
* @return copy of this PageContext with reseted EntityKey attributes (base and parent) */
|
||||
* @return copy of this PageContext with reset EntityKey attributes (base and parent) */
|
||||
PageContext clearEntityKeys();
|
||||
|
||||
/** Indicates if an attribute with the specified name exists within this PageContext
|
||||
|
@ -181,7 +181,7 @@ public interface PageContext {
|
|||
* block that will be executed on users OK selection.
|
||||
*
|
||||
* @param confirmMessage the localized confirm message key
|
||||
* @param onOK callback code block that will be called on users selection */
|
||||
* @param callback callback code block that will be called on users selection */
|
||||
void applyConfirmDialog(LocTextKey confirmMessage, final Consumer<Boolean> callback);
|
||||
|
||||
/** This can be used to forward to a defined page.
|
||||
|
|
|
@ -8,8 +8,12 @@
|
|||
|
||||
package ch.ethz.seb.sebserver.gui.service.page;
|
||||
|
||||
/** Defines a global SEB Server page */
|
||||
public interface PageDefinition {
|
||||
|
||||
/** Get the type class of the TemplateComposer that composes the page.
|
||||
*
|
||||
* @return the type class of the TemplateComposer that composes the page. */
|
||||
Class<? extends TemplateComposer> composer();
|
||||
|
||||
PageContext applyPageContext(PageContext pageContext);
|
||||
|
|
|
@ -363,7 +363,7 @@ public interface PageService {
|
|||
return content;
|
||||
}
|
||||
|
||||
/** Used to update the crolledComposite when some if its content has dynamically changed
|
||||
/** Used to update the scrolledComposite when some if its content has dynamically changed
|
||||
* its dimensions.
|
||||
*
|
||||
* @param composite The Component that changed its dimensions */
|
||||
|
|
|
@ -22,9 +22,9 @@ public interface PageStateDefinition {
|
|||
|
||||
Type type();
|
||||
|
||||
public Class<? extends TemplateComposer> contentPaneComposer();
|
||||
Class<? extends TemplateComposer> contentPaneComposer();
|
||||
|
||||
public Class<? extends TemplateComposer> actionPaneComposer();
|
||||
Class<? extends TemplateComposer> actionPaneComposer();
|
||||
|
||||
Activity activityAnchor();
|
||||
}
|
||||
|
|
|
@ -8,12 +8,20 @@
|
|||
|
||||
package ch.ethz.seb.sebserver.gui.service.page;
|
||||
|
||||
/** interface defining a RAP page template composer */
|
||||
public interface TemplateComposer {
|
||||
|
||||
/** Validate given PageContext for completeness to compose a specific TemplateComposer implementation
|
||||
* Default returns always true.
|
||||
* @param pageContext The PageContext instance to check
|
||||
* @return true if the PageContext contains all mandatory data to compose this page template */
|
||||
default boolean validate(final PageContext pageContext) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Compose a specific page template for the given PageContext
|
||||
*
|
||||
* @param pageContext The PageContext instance */
|
||||
void compose(PageContext pageContext);
|
||||
|
||||
}
|
||||
|
|
|
@ -156,7 +156,7 @@ public class DefaultPageLayout implements TemplateComposer {
|
|||
logoutSuccess.open(null);
|
||||
|
||||
// TODO Try to invalidate RWT's user session.
|
||||
// This seems to be more difficult then expected and just invalidate the HttpSession dosn't work
|
||||
// This seems to be more difficult then expected and just invalidate the HttpSession doesn't work
|
||||
// Try to send a redirect JSON to the client: https://bugs.eclipse.org/bugs/show_bug.cgi?id=388249
|
||||
});
|
||||
}
|
||||
|
@ -347,12 +347,8 @@ public class DefaultPageLayout implements TemplateComposer {
|
|||
final Display display = pageContext.getShell().getDisplay();
|
||||
final Image image = new Image(display, input);
|
||||
final Rectangle imageBounds = image.getBounds();
|
||||
final int width = (imageBounds.width > LOGO_IMAGE_MAX_WIDTH)
|
||||
? LOGO_IMAGE_MAX_WIDTH
|
||||
: imageBounds.width;
|
||||
final int height = (imageBounds.height > LOGO_IMAGE_MAX_HEIGHT)
|
||||
? LOGO_IMAGE_MAX_HEIGHT
|
||||
: imageBounds.height;
|
||||
final int width = Math.min(imageBounds.width, LOGO_IMAGE_MAX_WIDTH);
|
||||
final int height = Math.min(imageBounds.height, LOGO_IMAGE_MAX_HEIGHT);
|
||||
final ImageData imageData = image.getImageData().scaledTo(width, height);
|
||||
|
||||
logo.setData(RWT.CUSTOM_VARIANT, "bgLogoNoImage");
|
||||
|
|
|
@ -89,7 +89,7 @@ public class ModalInputDialog<T> extends Dialog {
|
|||
|
||||
open(
|
||||
title,
|
||||
(Predicate<T>) t -> true,
|
||||
t -> true,
|
||||
() -> {
|
||||
}, contentComposer);
|
||||
}
|
||||
|
@ -130,7 +130,7 @@ public class ModalInputDialog<T> extends Dialog {
|
|||
gridData.widthHint = this.dialogWidth;
|
||||
main.setLayoutData(gridData);
|
||||
|
||||
final Supplier<T> valueSuppier = contentComposer.compose(main);
|
||||
final Supplier<T> valueSupplier = contentComposer.compose(main);
|
||||
gridData.heightHint = calcDialogHeight(main);
|
||||
|
||||
final Button ok = this.widgetFactory.buttonLocalized(shell, OK_TEXT_KEY);
|
||||
|
@ -138,8 +138,8 @@ public class ModalInputDialog<T> extends Dialog {
|
|||
data.widthHint = this.buttonWidth;
|
||||
ok.setLayoutData(data);
|
||||
ok.addListener(SWT.Selection, event -> {
|
||||
if (valueSuppier != null) {
|
||||
final T result = valueSuppier.get();
|
||||
if (valueSupplier != null) {
|
||||
final T result = valueSupplier.get();
|
||||
if (callback.test(result)) {
|
||||
shell.close();
|
||||
}
|
||||
|
@ -192,9 +192,7 @@ public class ModalInputDialog<T> extends Dialog {
|
|||
final GridData data = new GridData(GridData.HORIZONTAL_ALIGN_CENTER);
|
||||
data.widthHint = this.buttonWidth;
|
||||
close.setLayoutData(data);
|
||||
close.addListener(SWT.Selection, event -> {
|
||||
shell.close();
|
||||
});
|
||||
close.addListener(SWT.Selection, event -> shell.close());
|
||||
|
||||
finishUp(shell);
|
||||
}
|
||||
|
@ -216,10 +214,7 @@ public class ModalInputDialog<T> extends Dialog {
|
|||
final int availableHeight = (displayHeight < actualHeight + 100)
|
||||
? displayHeight - 100
|
||||
: actualHeight;
|
||||
final int height = (availableHeight > this.dialogHeight)
|
||||
? this.dialogHeight
|
||||
: availableHeight;
|
||||
return height;
|
||||
return Math.min(availableHeight, this.dialogHeight);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -118,8 +118,7 @@ public class PageContextImpl implements PageContext {
|
|||
|
||||
@Override
|
||||
public PageContext withAttribute(final String key, final String value) {
|
||||
final Map<String, String> attrs = new HashMap<>();
|
||||
attrs.putAll(this.attributes);
|
||||
final Map<String, String> attrs = new HashMap<>(this.attributes);
|
||||
attrs.put(key, value);
|
||||
return new PageContextImpl(
|
||||
this.i18nSupport,
|
||||
|
@ -136,11 +135,7 @@ public class PageContextImpl implements PageContext {
|
|||
|
||||
@Override
|
||||
public String getAttribute(final String name, final String def) {
|
||||
if (this.attributes.containsKey(name)) {
|
||||
return this.attributes.get(name);
|
||||
} else {
|
||||
return def;
|
||||
}
|
||||
return this.attributes.getOrDefault(name, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -203,8 +198,7 @@ public class PageContextImpl implements PageContext {
|
|||
|
||||
@Override
|
||||
public PageContext removeAttribute(final String name) {
|
||||
final Map<String, String> attrs = new HashMap<>();
|
||||
attrs.putAll(this.attributes);
|
||||
final Map<String, String> attrs = new HashMap<>(this.attributes);
|
||||
attrs.remove(name);
|
||||
return new PageContextImpl(
|
||||
this.i18nSupport,
|
||||
|
@ -333,7 +327,7 @@ public class PageContextImpl implements PageContext {
|
|||
this.onOK.accept(true);
|
||||
} catch (final Exception e) {
|
||||
log.error(
|
||||
"Unexpected on confirm callback execution. This should not happen, plase secure the given onOK Runnable",
|
||||
"Unexpected on confirm callback execution. This should not happen, please secure the given onOK Runnable",
|
||||
e);
|
||||
this.onOK.accept(false);
|
||||
}
|
||||
|
|
|
@ -227,7 +227,7 @@ public class PageServiceImpl implements PageService {
|
|||
final int dependencies = (int) entities.stream()
|
||||
.flatMap(entity -> {
|
||||
final RestCall<Set<EntityKey>>.RestCallBuilder builder =
|
||||
restService.<Set<EntityKey>>getBuilder(
|
||||
restService.getBuilder(
|
||||
entity.entityType(),
|
||||
CallType.GET_DEPENDENCIES);
|
||||
|
||||
|
@ -366,7 +366,7 @@ public class PageServiceImpl implements PageService {
|
|||
final boolean logoutSuccessful = this.currentUser.logout();
|
||||
|
||||
if (!logoutSuccessful) {
|
||||
log.warn("Failed to logout. See logfiles for more information");
|
||||
log.warn("Failed to logout. See log-files for more information");
|
||||
}
|
||||
|
||||
} catch (final Exception e) {
|
||||
|
|
|
@ -78,7 +78,7 @@ public class ServerPushService {
|
|||
} catch (final Exception e) {
|
||||
log.warn(
|
||||
"Failed to update on Server Push Session {}. It seems that the UISession is not available anymore. "
|
||||
+ "This may source from a connection interruption.",
|
||||
+ "This may source from a connection interruption. cause: {}",
|
||||
Thread.currentThread().getName(), e.getMessage());
|
||||
}
|
||||
});
|
||||
|
|
|
@ -8,16 +8,9 @@
|
|||
|
||||
package ch.ethz.seb.sebserver.gui.service.remote.download;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.eclipse.rap.rwt.RWT;
|
||||
import org.eclipse.rap.rwt.service.ServiceHandler;
|
||||
|
@ -26,10 +19,14 @@ import org.slf4j.LoggerFactory;
|
|||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/** Implements a eclipse RAP ServiceHandler to handle downloads */
|
||||
@Lazy
|
||||
@Service
|
||||
@GuiProfile
|
||||
|
@ -54,7 +51,7 @@ public class DownloadService implements ServiceHandler {
|
|||
@Override
|
||||
public void service(
|
||||
final HttpServletRequest request,
|
||||
final HttpServletResponse response) throws IOException, ServletException {
|
||||
final HttpServletResponse response) {
|
||||
|
||||
log.debug("Received download service request: {}", request.getRequestURI());
|
||||
|
||||
|
|
|
@ -11,8 +11,13 @@ package ch.ethz.seb.sebserver.gui.service.remote.download;
|
|||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/** Interface defining a service to handle downloads */
|
||||
public interface DownloadServiceHandler {
|
||||
|
||||
/** Process a requested download
|
||||
*
|
||||
* @param request The download HttpServletRequest
|
||||
* @param response the response to send the download to */
|
||||
void processDownload(final HttpServletRequest request, final HttpServletResponse response);
|
||||
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ public class SebClientConfigDownload extends AbstractDownloadServiceHandler {
|
|||
IOUtils.copyLarge(input, downloadOut);
|
||||
} catch (final IOException e) {
|
||||
log.error(
|
||||
"Unexpected error while streaming incomming config data from web-service to output-stream of download response: ",
|
||||
"Unexpected error while streaming incoming config data from web-service to output-stream of download response: ",
|
||||
e);
|
||||
} finally {
|
||||
try {
|
||||
|
|
|
@ -49,7 +49,7 @@ public class SebExamConfigDownload extends AbstractDownloadServiceHandler {
|
|||
IOUtils.copyLarge(input, downloadOut);
|
||||
} catch (final IOException e) {
|
||||
log.error(
|
||||
"Unexpected error while streaming incomming config data from web-service to output-stream of download response: ",
|
||||
"Unexpected error while streaming incoming config data from web-service to output-stream of download response: ",
|
||||
e);
|
||||
} finally {
|
||||
try {
|
||||
|
|
|
@ -48,7 +48,7 @@ public class SebExamConfigPlaintextDownload extends AbstractDownloadServiceHandl
|
|||
IOUtils.copyLarge(input, downloadOut);
|
||||
} catch (final IOException e) {
|
||||
log.error(
|
||||
"Unexpected error while streaming incomming config data from web-service to output-stream of download response: ",
|
||||
"Unexpected error while streaming incoming config data from web-service to output-stream of download response: ",
|
||||
e);
|
||||
} finally {
|
||||
try {
|
||||
|
|
|
@ -31,19 +31,15 @@ public abstract class AbstractExportCall extends RestCall<InputStream> {
|
|||
@Override
|
||||
protected Result<InputStream> exchange(final RestCallBuilder builder) {
|
||||
|
||||
return Result.tryCatch(() -> {
|
||||
|
||||
return builder
|
||||
.getRestTemplate()
|
||||
.execute(
|
||||
builder.buildURI(),
|
||||
this.httpMethod,
|
||||
(final ClientHttpRequest requestCallback) -> {
|
||||
},
|
||||
response -> IOUtils.toBufferedInputStream(response.getBody()),
|
||||
builder.getURIVariables());
|
||||
|
||||
});
|
||||
return Result.tryCatch(() -> builder
|
||||
.getRestTemplate()
|
||||
.execute(
|
||||
builder.buildURI(),
|
||||
this.httpMethod,
|
||||
(final ClientHttpRequest requestCallback) -> {
|
||||
},
|
||||
response -> IOUtils.toBufferedInputStream(response.getBody()),
|
||||
builder.getURIVariables()));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,10 +8,18 @@
|
|||
|
||||
package ch.ethz.seb.sebserver.gui.service.remote.webservice.api;
|
||||
|
||||
/** Defines a form binding to get form parameter and values either in JSON format
|
||||
* or as form-url-encoded string */
|
||||
public interface FormBinding {
|
||||
|
||||
/** Get the form parameter and values in JSON format
|
||||
*
|
||||
* @return the form parameter and values in JSON format */
|
||||
String getFormAsJson();
|
||||
|
||||
/** Get the form parameter and values in form-url-encoded string format.
|
||||
*
|
||||
* @return the form parameter and values in form-url-encoded string format.*/
|
||||
String getFormUrlEncoded();
|
||||
|
||||
}
|
||||
|
|
|
@ -8,14 +8,18 @@
|
|||
|
||||
package ch.ethz.seb.sebserver.gui.service.remote.webservice.api;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||
import ch.ethz.seb.sebserver.gbl.api.APIMessage;
|
||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.api.JSONMapper;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Entity;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Page;
|
||||
import ch.ethz.seb.sebserver.gbl.model.PageSortOrder;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||
import com.fasterxml.jackson.core.JsonParseException;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -32,20 +36,13 @@ import org.springframework.web.client.RestClientResponseException;
|
|||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParseException;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||
import ch.ethz.seb.sebserver.gbl.api.APIMessage;
|
||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.api.JSONMapper;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Entity;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Page;
|
||||
import ch.ethz.seb.sebserver.gbl.model.PageSortOrder;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
public abstract class RestCall<T> {
|
||||
|
||||
|
@ -173,7 +170,7 @@ public abstract class RestCall<T> {
|
|||
}
|
||||
|
||||
private Result<T> handleRestCallError(final ResponseEntity<String> responseEntity)
|
||||
throws IOException, JsonParseException, JsonMappingException {
|
||||
throws IOException {
|
||||
|
||||
final RestCallError restCallError =
|
||||
new RestCallError("Response Entity: " + responseEntity.toString());
|
||||
|
@ -225,6 +222,7 @@ public abstract class RestCall<T> {
|
|||
this.uriComponentsBuilder = builder.uriComponentsBuilder;
|
||||
this.httpHeaders = builder.httpHeaders;
|
||||
this.body = builder.body;
|
||||
this.streamingBody = builder.streamingBody;
|
||||
this.queryParams = new LinkedMultiValueMap<>(builder.queryParams);
|
||||
this.uriVariables = new HashMap<>(builder.uriVariables);
|
||||
}
|
||||
|
|
|
@ -49,9 +49,7 @@ public class RestCallError extends RuntimeException implements APIMessageError {
|
|||
public boolean isFieldValidationError() {
|
||||
return this.errors
|
||||
.stream()
|
||||
.filter(error -> APIMessage.ErrorMessage.FIELD_VALIDATION.isOf(error))
|
||||
.findFirst()
|
||||
.isPresent();
|
||||
.anyMatch(APIMessage.ErrorMessage.FIELD_VALIDATION::isOf);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -52,7 +52,7 @@ public interface RestService {
|
|||
* NOTE not all RestCall can be get within this method. Only the ones that have a defined CallType
|
||||
*
|
||||
* @param entityType The EntityType of the RestCall
|
||||
* @param callType The CallType of the RestCall (not UNDEFINDED)
|
||||
* @param callType The CallType of the RestCall (not UNDEFINED)
|
||||
* @return RestCall instance */
|
||||
<T> RestCall<T> getRestCall(EntityType entityType, CallType callType);
|
||||
|
||||
|
@ -65,7 +65,7 @@ public interface RestService {
|
|||
/** Get a certain RestCallBuilder by EntityType and CallType.
|
||||
*
|
||||
* @param entityType The EntityType of the RestCall to get a builder for
|
||||
* @param callType The CallType of the RestCall to get a builder for (not UNDEFINDED)
|
||||
* @param callType The CallType of the RestCall to get a builder for (not UNDEFINED)
|
||||
* @return RestCallBuilder instance to build a dedicated call and execute it */
|
||||
<T> RestCall<T>.RestCallBuilder getBuilder(
|
||||
EntityType entityType,
|
||||
|
|
|
@ -21,6 +21,7 @@ import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
|
|||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
|
||||
|
||||
|
||||
@Lazy
|
||||
@Component
|
||||
@GuiProfile
|
||||
|
|
|
@ -119,17 +119,15 @@ public class CurrentUser {
|
|||
return userInfo
|
||||
.getRoles()
|
||||
.stream()
|
||||
.map(roleName -> UserRole.valueOf(roleName))
|
||||
.map(UserRole::valueOf)
|
||||
.map(role -> new RoleTypeKey(entityType, role))
|
||||
.map(key -> this.privileges.get(key))
|
||||
.filter(priv -> (priv != null) && priv.hasGrant(
|
||||
.anyMatch(privilege -> (privilege != null) && privilege.hasGrant(
|
||||
userInfo.uuid,
|
||||
userInfo.institutionId,
|
||||
privilegeType,
|
||||
institutionId,
|
||||
ownerId))
|
||||
.findFirst()
|
||||
.isPresent();
|
||||
ownerId));
|
||||
} catch (final Exception e) {
|
||||
log.error("Failed to verify privilege: PrivilegeType {} EntityType {}",
|
||||
privilegeType, entityType, e);
|
||||
|
@ -149,17 +147,15 @@ public class CurrentUser {
|
|||
final UserInfo userInfo = get();
|
||||
return userInfo.getRoles()
|
||||
.stream()
|
||||
.map(roleName -> UserRole.valueOf(roleName))
|
||||
.map(UserRole::valueOf)
|
||||
.map(role -> new RoleTypeKey(entityType, role))
|
||||
.map(key -> this.privileges.get(key))
|
||||
.filter(priv -> (priv != null) && priv.hasGrant(
|
||||
.anyMatch(privilege -> (privilege != null) && privilege.hasGrant(
|
||||
userInfo.uuid,
|
||||
userInfo.institutionId,
|
||||
privilegeType,
|
||||
grantEntity.getInstitutionId(),
|
||||
grantEntity.getOwnerId()))
|
||||
.findFirst()
|
||||
.isPresent();
|
||||
grantEntity.getOwnerId()));
|
||||
} catch (final Exception e) {
|
||||
log.error("Failed to verify privilege: PrivilegeType {} EntityType {}",
|
||||
privilegeType, entityType, e);
|
||||
|
@ -234,9 +230,9 @@ public class CurrentUser {
|
|||
if (privileges != null) {
|
||||
this.privileges = privileges
|
||||
.stream()
|
||||
.reduce(new HashMap<RoleTypeKey, Privilege>(),
|
||||
(map, priv) -> {
|
||||
map.put(priv.roleTypeKey, priv);
|
||||
.reduce(new HashMap<>(),
|
||||
(map, privilege) -> {
|
||||
map.put(privilege.roleTypeKey, privilege);
|
||||
return map;
|
||||
},
|
||||
(map1, map2) -> {
|
||||
|
|
|
@ -8,15 +8,12 @@
|
|||
|
||||
package ch.ethz.seb.sebserver.gui.service.remote.webservice.auth;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import ch.ethz.seb.sebserver.ClientHttpRequestFactoryService;
|
||||
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
|
||||
import ch.ethz.seb.sebserver.gbl.model.user.UserRole;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -44,12 +41,13 @@ import org.springframework.web.client.ResponseExtractor;
|
|||
import org.springframework.web.client.RestClientException;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import ch.ethz.seb.sebserver.ClientHttpRequestFactoryService;
|
||||
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
|
||||
import ch.ethz.seb.sebserver.gbl.model.user.UserRole;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||
import javax.servlet.http.HttpSession;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@Lazy
|
||||
@Component
|
||||
|
@ -171,7 +169,7 @@ public class OAuth2AuthorizationContextHolder implements AuthorizationContextHol
|
|||
this.restTemplate.setErrorHandler(new ErrorHandler(this.resource));
|
||||
this.restTemplate
|
||||
.getMessageConverters()
|
||||
.add(0, new StringHttpMessageConverter(Charset.forName("UTF-8")));
|
||||
.add(0, new StringHttpMessageConverter(StandardCharsets.UTF_8));
|
||||
|
||||
this.revokeTokenURI = webserviceURIService.getOAuthRevokeTokenURI();
|
||||
this.currentUserURI = webserviceURIService.getCurrentUserRequestURI();
|
||||
|
|
|
@ -34,7 +34,7 @@ public interface SEBServerAuthorizationContext {
|
|||
*
|
||||
* @param username the username for login
|
||||
* @param password the password for login
|
||||
* @return */
|
||||
* @return true if login was successful, false if no */
|
||||
boolean login(String username, CharSequence password);
|
||||
|
||||
/** Requests a logout on SEB Server webservice if a user is currently logged in
|
||||
|
|
|
@ -14,29 +14,29 @@ public class WebserviceConnectionData {
|
|||
|
||||
final String id;
|
||||
final String webserviceProtocol;
|
||||
final String webserviceServerAdress;
|
||||
final String webserviceServerAddress;
|
||||
final String webserviceServerPort;
|
||||
final String webserviceAPIPath;
|
||||
final String webserviceServerAddress;
|
||||
final String webserviceServerURL;
|
||||
|
||||
private final UriComponentsBuilder webserviceURIBuilder;
|
||||
|
||||
protected WebserviceConnectionData(
|
||||
final String id,
|
||||
final String webserviceProtocol,
|
||||
final String webserviceServerAdress,
|
||||
final String webserviceServerAddress,
|
||||
final String webserviceServerPort,
|
||||
final String webserviceAPIPath) {
|
||||
|
||||
this.id = id;
|
||||
this.webserviceProtocol = webserviceProtocol;
|
||||
this.webserviceServerAdress = webserviceServerAdress;
|
||||
this.webserviceServerAddress = webserviceServerAddress;
|
||||
this.webserviceServerPort = webserviceServerPort;
|
||||
this.webserviceAPIPath = webserviceAPIPath;
|
||||
|
||||
this.webserviceServerAddress = webserviceProtocol + "://" + webserviceServerAdress + ":" + webserviceServerPort;
|
||||
this.webserviceServerURL = webserviceProtocol + "://" + webserviceServerAddress + ":" + webserviceServerPort;
|
||||
this.webserviceURIBuilder = UriComponentsBuilder
|
||||
.fromHttpUrl(webserviceProtocol + "://" + webserviceServerAdress)
|
||||
.fromHttpUrl(webserviceProtocol + "://" + webserviceServerAddress)
|
||||
.port(webserviceServerPort)
|
||||
.path(webserviceAPIPath);
|
||||
}
|
||||
|
@ -49,8 +49,8 @@ public class WebserviceConnectionData {
|
|||
return this.webserviceProtocol;
|
||||
}
|
||||
|
||||
public String getWebserviceServerAdress() {
|
||||
return this.webserviceServerAdress;
|
||||
public String getWebserviceServerAddress() {
|
||||
return this.webserviceServerAddress;
|
||||
}
|
||||
|
||||
public String getWebserviceServerPort() {
|
||||
|
@ -61,8 +61,8 @@ public class WebserviceConnectionData {
|
|||
return this.webserviceAPIPath;
|
||||
}
|
||||
|
||||
public String getWebserviceServerAddress() {
|
||||
return this.webserviceServerAddress;
|
||||
public String getWebserviceServerURL() {
|
||||
return this.webserviceServerURL;
|
||||
}
|
||||
|
||||
public UriComponentsBuilder getWebserviceURIBuilder() {
|
||||
|
@ -101,8 +101,8 @@ public class WebserviceConnectionData {
|
|||
builder.append(this.id);
|
||||
builder.append(", webserviceProtocol=");
|
||||
builder.append(this.webserviceProtocol);
|
||||
builder.append(", webserviceServerAdress=");
|
||||
builder.append(this.webserviceServerAdress);
|
||||
builder.append(", webserviceServerAddress=");
|
||||
builder.append(this.webserviceServerAddress);
|
||||
builder.append(", webserviceServerPort=");
|
||||
builder.append(this.webserviceServerPort);
|
||||
builder.append(", webserviceAPIPath=");
|
||||
|
|
|
@ -25,15 +25,15 @@ public class WebserviceURIService {
|
|||
|
||||
public WebserviceURIService(
|
||||
@Value("${sebserver.gui.webservice.protocol}") final String webserviceProtocol,
|
||||
@Value("${sebserver.gui.webservice.address}") final String webserviceServerAdress,
|
||||
@Value("${sebserver.gui.webservice.address}") final String webserviceServerAddress,
|
||||
@Value("${sebserver.gui.webservice.port}") final String webserviceServerPort,
|
||||
@Value("${server.servlet.context-path}") final String servletContextPath,
|
||||
@Value("${sebserver.gui.webservice.apipath}") final String webserviceAPIPath) {
|
||||
|
||||
this.servletContextPath = servletContextPath;
|
||||
this.webserviceServerAddress = webserviceProtocol + "://" + webserviceServerAdress + ":" + webserviceServerPort;
|
||||
this.webserviceServerAddress = webserviceProtocol + "://" + webserviceServerAddress + ":" + webserviceServerPort;
|
||||
this.webserviceURIBuilder = UriComponentsBuilder
|
||||
.fromHttpUrl(webserviceProtocol + "://" + webserviceServerAdress)
|
||||
.fromHttpUrl(webserviceProtocol + "://" + webserviceServerAddress)
|
||||
.port(webserviceServerPort)
|
||||
.path(servletContextPath)
|
||||
.path(webserviceAPIPath);
|
||||
|
|
|
@ -49,12 +49,10 @@ public class ClientConnectionDetails {
|
|||
|
||||
private static final int NUMBER_OF_NONE_INDICATOR_ROWS = 3;
|
||||
|
||||
private final PageService pageService;
|
||||
private final ResourceService resourceService;
|
||||
private final Exam exam;
|
||||
private final EnumMap<IndicatorType, IndicatorData> indicatorMapping;
|
||||
private final RestCall<ClientConnectionData>.RestCallBuilder restCallBuilder;
|
||||
private final FormHandle<?> formhandle;
|
||||
private final FormHandle<?> formHandle;
|
||||
private final ColorData colorData;
|
||||
|
||||
private ClientConnectionData connectionData = null;
|
||||
|
@ -69,9 +67,7 @@ public class ClientConnectionDetails {
|
|||
|
||||
final Display display = pageContext.getRoot().getDisplay();
|
||||
|
||||
this.pageService = pageService;
|
||||
this.resourceService = pageService.getResourceService();
|
||||
this.exam = exam;
|
||||
this.restCallBuilder = restCallBuilder;
|
||||
this.colorData = new ColorData(display);
|
||||
this.indicatorMapping = IndicatorData.createFormIndicators(
|
||||
|
@ -80,12 +76,12 @@ public class ClientConnectionDetails {
|
|||
this.colorData,
|
||||
NUMBER_OF_NONE_INDICATOR_ROWS);
|
||||
|
||||
final FormBuilder formBuilder = this.pageService.formBuilder(pageContext)
|
||||
final FormBuilder formBuilder = pageService.formBuilder(pageContext)
|
||||
.readonly(true)
|
||||
.addField(FormBuilder.text(
|
||||
QuizData.QUIZ_ATTR_NAME,
|
||||
EXAM_NAME_TEXT_KEY,
|
||||
this.exam.getName()))
|
||||
exam.getName()))
|
||||
.addField(FormBuilder.text(
|
||||
Domain.CLIENT_CONNECTION.ATTR_EXAM_USER_SESSION_ID,
|
||||
CONNECTION_ID_TEXT_KEY,
|
||||
|
@ -112,7 +108,7 @@ public class ClientConnectionDetails {
|
|||
.withDefaultLabel(indData.indicator.name))
|
||||
.addEmptyCell());
|
||||
|
||||
this.formhandle = formBuilder.build();
|
||||
this.formHandle = formBuilder.build();
|
||||
}
|
||||
|
||||
public void updateData() {
|
||||
|
@ -136,7 +132,7 @@ public class ClientConnectionDetails {
|
|||
return;
|
||||
}
|
||||
|
||||
final Form form = this.formhandle.getForm();
|
||||
final Form form = this.formHandle.getForm();
|
||||
form.setFieldValue(
|
||||
Domain.CLIENT_CONNECTION.ATTR_EXAM_USER_SESSION_ID,
|
||||
this.connectionData.clientConnection.userSessionId);
|
||||
|
|
|
@ -371,7 +371,7 @@ public final class ClientConnectionTable {
|
|||
private void sortTable() {
|
||||
this.tableMapping = this.tableMapping.entrySet()
|
||||
.stream()
|
||||
.sorted((e1, e2) -> e1.getValue().compareTo(e2.getValue()))
|
||||
.sorted(Entry.comparingByValue())
|
||||
.collect(Collectors.toMap(
|
||||
Entry::getKey,
|
||||
Entry::getValue,
|
||||
|
@ -398,13 +398,12 @@ public final class ClientConnectionTable {
|
|||
final String attribute = this.resourceService
|
||||
.getCurrentUser()
|
||||
.getAttribute(USER_SESSION_STATUS_FILTER_ATTRIBUTE);
|
||||
this.statusFilter.clear();
|
||||
if (attribute != null) {
|
||||
this.statusFilter.clear();
|
||||
Arrays.asList(StringUtils.split(attribute, Constants.LIST_SEPARATOR))
|
||||
.forEach(name -> this.statusFilter.add(ConnectionStatus.valueOf(name)));
|
||||
|
||||
} else {
|
||||
this.statusFilter.clear();
|
||||
this.statusFilter.add(ConnectionStatus.DISABLED);
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
|
@ -460,7 +459,7 @@ public final class ClientConnectionTable {
|
|||
}
|
||||
|
||||
void updateData(final TableItem tableItem) {
|
||||
tableItem.setText(0, getConnectionIdentifer());
|
||||
tableItem.setText(0, getConnectionIdentifier());
|
||||
tableItem.setText(1, getConnectionAddress());
|
||||
tableItem.setText(2, getStatusName());
|
||||
}
|
||||
|
@ -533,7 +532,7 @@ public final class ClientConnectionTable {
|
|||
public int compareTo(final UpdatableTableItem other) {
|
||||
return Comparator.comparingInt(UpdatableTableItem::statusWeight)
|
||||
.thenComparingInt(UpdatableTableItem::thresholdsWeight)
|
||||
.thenComparing(UpdatableTableItem::getConnectionIdentifer)
|
||||
.thenComparing(UpdatableTableItem::getConnectionIdentifier)
|
||||
.compare(this, other);
|
||||
}
|
||||
|
||||
|
@ -580,7 +579,7 @@ public final class ClientConnectionTable {
|
|||
return Constants.EMPTY_NOTE;
|
||||
}
|
||||
|
||||
String getConnectionIdentifer() {
|
||||
String getConnectionIdentifier() {
|
||||
if (this.connectionData != null && this.connectionData.clientConnection.userSessionId != null) {
|
||||
return this.connectionData.clientConnection.userSessionId;
|
||||
}
|
||||
|
@ -608,10 +607,7 @@ public final class ClientConnectionTable {
|
|||
final IndicatorData indicatorData =
|
||||
ClientConnectionTable.this.indicatorMapping.get(indicatorValue.getType());
|
||||
|
||||
if (indicatorData == null) {
|
||||
log.error("No IndicatorData of type: {} found", indicatorValue.getType());
|
||||
} else {
|
||||
|
||||
if (indicatorData != null) {
|
||||
final double value = indicatorValue.getValue();
|
||||
final int indicatorWeight = IndicatorData.getWeight(indicatorData, value);
|
||||
if (this.indicatorWeights[indicatorData.index] != indicatorWeight) {
|
||||
|
|
|
@ -8,18 +8,17 @@
|
|||
|
||||
package ch.ethz.seb.sebserver.gui.service.session;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumMap;
|
||||
|
||||
import org.eclipse.swt.graphics.Color;
|
||||
import org.eclipse.swt.widgets.Display;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.Indicator;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.Indicator.IndicatorType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.Indicator.Threshold;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||
import org.eclipse.swt.graphics.Color;
|
||||
import org.eclipse.swt.widgets.Display;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.EnumMap;
|
||||
|
||||
final class IndicatorData {
|
||||
|
||||
|
@ -47,13 +46,13 @@ final class IndicatorData {
|
|||
|
||||
this.thresholdColor = new ThresholdColor[indicator.thresholds.size()];
|
||||
final ArrayList<Threshold> sortedThresholds = new ArrayList<>(indicator.thresholds);
|
||||
Collections.sort(sortedThresholds, (t1, t2) -> t1.value.compareTo(t2.value));
|
||||
sortedThresholds.sort(Comparator.comparing(t -> t.value));
|
||||
for (int i = 0; i < indicator.thresholds.size(); i++) {
|
||||
this.thresholdColor[i] = new ThresholdColor(sortedThresholds.get(i), display, colorData);
|
||||
}
|
||||
}
|
||||
|
||||
static final EnumMap<IndicatorType, IndicatorData> createFormIndicators(
|
||||
static EnumMap<IndicatorType, IndicatorData> createFormIndicators(
|
||||
final Collection<Indicator> indicators,
|
||||
final Display display,
|
||||
final ColorData colorData,
|
||||
|
@ -73,7 +72,7 @@ final class IndicatorData {
|
|||
return indicatorMapping;
|
||||
}
|
||||
|
||||
static final int getWeight(final IndicatorData indicatorData, final double value) {
|
||||
static int getWeight(final IndicatorData indicatorData, final double value) {
|
||||
for (int j = 0; j < indicatorData.thresholdColor.length; j++) {
|
||||
if (value < indicatorData.thresholdColor[j].value) {
|
||||
return (j == 0) ? -1 : j - 1;
|
||||
|
|
|
@ -92,13 +92,11 @@ public class InstructionProcessor {
|
|||
StringUtils.join(connectionTokens, Constants.LIST_SEPARATOR),
|
||||
null);
|
||||
|
||||
processInstruction(() -> {
|
||||
return this.restService.getBuilder(PropagateInstruction.class)
|
||||
.withURIVariable(API.PARAM_MODEL_ID, String.valueOf(examId))
|
||||
.withBody(clientInstruction)
|
||||
.call()
|
||||
.getOrThrow();
|
||||
},
|
||||
processInstruction(() -> this.restService.getBuilder(PropagateInstruction.class)
|
||||
.withURIVariable(API.PARAM_MODEL_ID, String.valueOf(examId))
|
||||
.withBody(clientInstruction)
|
||||
.call()
|
||||
.getOrThrow(),
|
||||
pageContext);
|
||||
|
||||
}
|
||||
|
@ -116,7 +114,6 @@ public class InstructionProcessor {
|
|||
ConnectionStatus.AUTHENTICATED));
|
||||
|
||||
if (connectionTokens.isEmpty()) {
|
||||
// TOOD message
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -126,15 +123,13 @@ public class InstructionProcessor {
|
|||
connectionTokens);
|
||||
}
|
||||
|
||||
processInstruction(() -> {
|
||||
return this.restService.getBuilder(DisableClientConnection.class)
|
||||
.withURIVariable(API.PARAM_MODEL_ID, String.valueOf(examId))
|
||||
.withFormParam(
|
||||
Domain.CLIENT_CONNECTION.ATTR_CONNECTION_TOKEN,
|
||||
StringUtils.join(connectionTokens, Constants.LIST_SEPARATOR))
|
||||
.call()
|
||||
.getOrThrow();
|
||||
},
|
||||
processInstruction(() -> this.restService.getBuilder(DisableClientConnection.class)
|
||||
.withURIVariable(API.PARAM_MODEL_ID, String.valueOf(examId))
|
||||
.withFormParam(
|
||||
Domain.CLIENT_CONNECTION.ATTR_CONNECTION_TOKEN,
|
||||
StringUtils.join(connectionTokens, Constants.LIST_SEPARATOR))
|
||||
.call()
|
||||
.getOrThrow(),
|
||||
pageContext);
|
||||
|
||||
}
|
||||
|
|
|
@ -96,12 +96,12 @@ public class EntityTable<ROW extends Entity> {
|
|||
private final BiConsumer<TableItem, ROW> rowDecorator;
|
||||
private final Consumer<Set<ROW>> selectionListener;
|
||||
|
||||
int pageNumber = 1;
|
||||
int pageNumber;
|
||||
int pageSize;
|
||||
String sortColumn = null;
|
||||
PageSortOrder sortOrder = PageSortOrder.ASCENDING;
|
||||
boolean columnsWithSameWidth = true;
|
||||
boolean hideNavigation = false;
|
||||
boolean hideNavigation;
|
||||
|
||||
EntityTable(
|
||||
final String name,
|
||||
|
@ -149,13 +149,10 @@ public class EntityTable<ROW extends Entity> {
|
|||
this.rowDecorator = rowDecorator;
|
||||
this.selectionListener = selectionListener;
|
||||
this.pageSize = pageSize;
|
||||
this.filter =
|
||||
columns
|
||||
.stream()
|
||||
.map(column -> column.getFilterAttribute())
|
||||
.filter(Objects::nonNull)
|
||||
.findFirst()
|
||||
.isPresent() ? new TableFilter<>(this) : null;
|
||||
this.filter = columns
|
||||
.stream()
|
||||
.map(ColumnDefinition::getFilterAttribute)
|
||||
.anyMatch(Objects::nonNull) ? new TableFilter<>(this) : null;
|
||||
|
||||
this.table = this.widgetFactory.tableLocalized(this.composite);
|
||||
final GridLayout gridLayout = new GridLayout(columns.size(), true);
|
||||
|
@ -207,17 +204,15 @@ public class EntityTable<ROW extends Entity> {
|
|||
}
|
||||
|
||||
for (int i = 0; i < columns.size(); i++) {
|
||||
final Rectangle itemBoundes = item.getBounds(i);
|
||||
if (itemBoundes.contains(point)) {
|
||||
final Rectangle itemBounds = item.getBounds(i);
|
||||
if (itemBounds.contains(point)) {
|
||||
handleCellSelection(item, i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.table.addListener(SWT.Selection, event -> {
|
||||
this.notifySelectionChange();
|
||||
});
|
||||
this.table.addListener(SWT.Selection, event -> this.notifySelectionChange());
|
||||
|
||||
this.navigator = new TableNavigator(this);
|
||||
|
||||
|
@ -375,8 +370,7 @@ public class EntityTable<ROW extends Entity> {
|
|||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
return Arrays.asList(selection)
|
||||
.stream()
|
||||
return Arrays.stream(selection)
|
||||
.map(this::getRowData)
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
@ -391,8 +385,7 @@ public class EntityTable<ROW extends Entity> {
|
|||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
return Arrays.asList(selection)
|
||||
.stream()
|
||||
return Arrays.stream(selection)
|
||||
.filter(item -> grantCheck == null || grantCheck.test(getRowData(item)))
|
||||
.map(this::getRowDataId)
|
||||
.collect(Collectors.toSet());
|
||||
|
@ -415,8 +408,7 @@ public class EntityTable<ROW extends Entity> {
|
|||
}
|
||||
|
||||
private TableColumn getTableColumn(final String name) {
|
||||
return Arrays.asList(this.table.getColumns())
|
||||
.stream()
|
||||
return Arrays.stream(this.table.getColumns())
|
||||
.filter(col -> {
|
||||
@SuppressWarnings("unchecked")
|
||||
final ColumnDefinition<ROW> def = (ColumnDefinition<ROW>) col.getData(COLUMN_DEFINITION);
|
||||
|
@ -541,7 +533,7 @@ public class EntityTable<ROW extends Entity> {
|
|||
.filter(c -> c.getWidthProportion() > 0)
|
||||
.reduce(0,
|
||||
(acc, c) -> acc + c.getWidthProportion(),
|
||||
(acc1, acc2) -> acc1 + acc2);
|
||||
Integer::sum);
|
||||
|
||||
// The unit size either with proportion or for a entire column if all columns are equal in size
|
||||
final int columnUnitSize = (pSize > 0)
|
||||
|
|
|
@ -100,7 +100,7 @@ public class TableBuilder<ROW extends Entity> {
|
|||
return this;
|
||||
}
|
||||
|
||||
public TableBuilder<ROW> withMultiselection() {
|
||||
public TableBuilder<ROW> withMultiSelection() {
|
||||
this.type |= SWT.MULTI;
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ public class TableFilter<ROW extends Entity> {
|
|||
private static final LocTextKey DATE_TO_TEXT = new LocTextKey("sebserver.overall.date.to");
|
||||
private static final LocTextKey ALL_TEXT = new LocTextKey("sebserver.overall.status.all");
|
||||
|
||||
public static enum CriteriaType {
|
||||
public enum CriteriaType {
|
||||
TEXT,
|
||||
SINGLE_SELECTION,
|
||||
DATE,
|
||||
|
@ -82,7 +82,7 @@ public class TableFilter<ROW extends Entity> {
|
|||
public MultiValueMap<String, String> getFilterParameter() {
|
||||
return this.components
|
||||
.stream()
|
||||
.reduce(new LinkedMultiValueMap<String, String>(),
|
||||
.reduce(new LinkedMultiValueMap<>(),
|
||||
(map, comp) -> comp.putFilterParameter(map),
|
||||
(map1, map2) -> {
|
||||
map1.putAll(map2);
|
||||
|
@ -92,8 +92,7 @@ public class TableFilter<ROW extends Entity> {
|
|||
|
||||
public void reset() {
|
||||
this.components
|
||||
.stream()
|
||||
.forEach(comp -> comp.reset());
|
||||
.forEach(FilterComponent::reset);
|
||||
}
|
||||
|
||||
private void buildComponents() {
|
||||
|
@ -158,7 +157,7 @@ public class TableFilter<ROW extends Entity> {
|
|||
.append(Constants.FORM_URL_ENCODED_NAME_VALUE_SEPARATOR)
|
||||
.append(filter.getValue())
|
||||
.append(Constants.LIST_SEPARATOR),
|
||||
(sb1, sb2) -> sb1.append(sb2));
|
||||
StringBuilder::append);
|
||||
if (builder.length() > 0) {
|
||||
builder.deleteCharAt(builder.length() - 1);
|
||||
}
|
||||
|
@ -171,22 +170,19 @@ public class TableFilter<ROW extends Entity> {
|
|||
}
|
||||
|
||||
try {
|
||||
Arrays.asList(StringUtils.split(
|
||||
Arrays.stream(StringUtils.split(
|
||||
attribute,
|
||||
Constants.LIST_SEPARATOR_CHAR))
|
||||
.stream()
|
||||
.map(nameValue -> StringUtils.split(
|
||||
nameValue,
|
||||
Constants.FORM_URL_ENCODED_NAME_VALUE_SEPARATOR))
|
||||
.forEach(nameValue -> {
|
||||
this.components
|
||||
.stream()
|
||||
.filter(filter -> nameValue[0].equals(filter.attribute.columnName))
|
||||
.findFirst()
|
||||
.ifPresent(filter -> filter.setValue((nameValue.length > 1)
|
||||
? nameValue[1]
|
||||
: StringUtils.EMPTY));
|
||||
});
|
||||
.forEach(nameValue -> this.components
|
||||
.stream()
|
||||
.filter(filter -> nameValue[0].equals(filter.attribute.columnName))
|
||||
.findFirst()
|
||||
.ifPresent(filter -> filter.setValue((nameValue.length > 1)
|
||||
? nameValue[1]
|
||||
: StringUtils.EMPTY)));
|
||||
} catch (final Exception e) {
|
||||
log.error("Failed to set filter attributes: ", e);
|
||||
}
|
||||
|
@ -208,9 +204,7 @@ public class TableFilter<ROW extends Entity> {
|
|||
ImageIcon.SEARCH,
|
||||
inner,
|
||||
new LocTextKey("sebserver.overall.action.filter"),
|
||||
event -> {
|
||||
this.entityTable.applyFilter();
|
||||
});
|
||||
event -> this.entityTable.applyFilter());
|
||||
imageButton.setLayoutData(gridData);
|
||||
final Label imageButton2 = this.entityTable.widgetFactory.imageButton(
|
||||
ImageIcon.CANCEL,
|
||||
|
@ -276,7 +270,7 @@ public class TableFilter<ROW extends Entity> {
|
|||
}
|
||||
}
|
||||
|
||||
private class NullFilter extends FilterComponent {
|
||||
private static class NullFilter extends FilterComponent {
|
||||
|
||||
private Label label;
|
||||
|
||||
|
@ -493,7 +487,6 @@ public class TableFilter<ROW extends Entity> {
|
|||
private class DateRange extends FilterComponent {
|
||||
|
||||
private Composite innerComposite;
|
||||
//private final GridData rw1 = new GridData(SWT.FILL, SWT.FILL, true, true);
|
||||
private DateTime fromDateSelector;
|
||||
private DateTime toDateSelector;
|
||||
private DateTime fromTimeSelector;
|
||||
|
|
|
@ -68,7 +68,7 @@ public class TableNavigator {
|
|||
|
||||
if (numberOfPages > 1) {
|
||||
createBackwardLabel(pageNumber > 1, pageNumber, numNav);
|
||||
final int pageNavSize = (numberOfPages > PAGE_NAV_SIZE) ? PAGE_NAV_SIZE : numberOfPages;
|
||||
final int pageNavSize = Math.min(numberOfPages, PAGE_NAV_SIZE);
|
||||
final int half = pageNavSize / 2;
|
||||
int start = pageNumber - half;
|
||||
if (start < 1) {
|
||||
|
@ -107,14 +107,12 @@ public class TableNavigator {
|
|||
|
||||
final GridData rowData = new GridData(22, 16);
|
||||
final Label pageLabel = new Label(parent, SWT.NONE);
|
||||
pageLabel.setText(" " + String.valueOf(page) + " ");
|
||||
pageLabel.setText(" " + page + " ");
|
||||
pageLabel.setLayoutData(rowData);
|
||||
pageLabel.setAlignment(SWT.CENTER);
|
||||
if (selectable) {
|
||||
pageLabel.setData(RWT.CUSTOM_VARIANT, CustomVariant.LIST_NAVIGATION.key);
|
||||
pageLabel.addListener(SWT.MouseDown, event -> {
|
||||
this.entityTable.selectPage(page);
|
||||
});
|
||||
pageLabel.addListener(SWT.MouseDown, event -> this.entityTable.selectPage(page));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -131,9 +129,7 @@ public class TableNavigator {
|
|||
forward.setLayoutData(rowData);
|
||||
forward.setAlignment(SWT.CENTER);
|
||||
if (visible) {
|
||||
forward.addListener(SWT.MouseDown, event -> {
|
||||
this.entityTable.selectPage(pageNumber + 1);
|
||||
});
|
||||
forward.addListener(SWT.MouseDown, event -> this.entityTable.selectPage(pageNumber + 1));
|
||||
} else {
|
||||
forward.setVisible(false);
|
||||
}
|
||||
|
@ -144,9 +140,7 @@ public class TableNavigator {
|
|||
end.setLayoutData(rowData);
|
||||
end.setAlignment(SWT.CENTER);
|
||||
if (visible) {
|
||||
end.addListener(SWT.MouseDown, event -> {
|
||||
this.entityTable.selectPage(numberOfPages);
|
||||
});
|
||||
end.addListener(SWT.MouseDown, event -> this.entityTable.selectPage(numberOfPages));
|
||||
} else {
|
||||
end.setVisible(false);
|
||||
}
|
||||
|
@ -164,9 +158,7 @@ public class TableNavigator {
|
|||
start.setAlignment(SWT.CENTER);
|
||||
start.setData(RWT.CUSTOM_VARIANT, CustomVariant.LIST_NAVIGATION.key);
|
||||
if (visible) {
|
||||
start.addListener(SWT.MouseDown, event -> {
|
||||
this.entityTable.selectPage(1);
|
||||
});
|
||||
start.addListener(SWT.MouseDown, event -> this.entityTable.selectPage(1));
|
||||
} else {
|
||||
start.setVisible(false);
|
||||
}
|
||||
|
@ -177,9 +169,7 @@ public class TableNavigator {
|
|||
backward.setAlignment(SWT.CENTER);
|
||||
backward.setData(RWT.CUSTOM_VARIANT, CustomVariant.LIST_NAVIGATION.key);
|
||||
if (visible) {
|
||||
backward.addListener(SWT.MouseDown, event -> {
|
||||
this.entityTable.selectPage(pageNumber - 1);
|
||||
});
|
||||
backward.addListener(SWT.MouseDown, event -> this.entityTable.selectPage(pageNumber - 1));
|
||||
} else {
|
||||
backward.setVisible(false);
|
||||
}
|
||||
|
|
|
@ -166,10 +166,8 @@ public class FileUploadSelection extends Composite {
|
|||
private boolean fileSupported(final String fileName) {
|
||||
return this.supportedFileExtensions
|
||||
.stream()
|
||||
.filter(fileType -> fileName.toUpperCase(Locale.ROOT)
|
||||
.endsWith(fileType.toUpperCase(Locale.ROOT)))
|
||||
.findFirst()
|
||||
.isPresent();
|
||||
.anyMatch(fileType -> fileName.toUpperCase(Locale.ROOT)
|
||||
.endsWith(fileType.toUpperCase(Locale.ROOT)));
|
||||
}
|
||||
|
||||
private final class InputReceiver extends FileUploadReceiver {
|
||||
|
|
|
@ -157,7 +157,7 @@ public class GridTable extends Composite {
|
|||
return StringUtils.join(
|
||||
this.rows
|
||||
.stream()
|
||||
.map(row -> row.getValue())
|
||||
.map(Row::getValue)
|
||||
.collect(Collectors.toList()),
|
||||
Constants.LIST_SEPARATOR);
|
||||
}
|
||||
|
@ -209,10 +209,9 @@ public class GridTable extends Composite {
|
|||
.stream()
|
||||
.reduce(0,
|
||||
(i, c2) -> i + c2.columnDef.widthFactor,
|
||||
(i1, i2) -> i1 + i2);
|
||||
Integer::sum);
|
||||
|
||||
this.columns
|
||||
.stream()
|
||||
.forEach(c -> c.header.widthHint = c.columnDef.widthFactor * widthUnit);
|
||||
|
||||
super.layout(true, true);
|
||||
|
@ -273,7 +272,7 @@ public class GridTable extends Composite {
|
|||
this.defaultValue = defaultValue;
|
||||
}
|
||||
|
||||
public static final ColumnDef fromString(
|
||||
public static ColumnDef fromString(
|
||||
final String string,
|
||||
final Map<String, String> defaultValueMap) {
|
||||
|
||||
|
|
|
@ -48,10 +48,7 @@ public final class ImageUploadSelection extends Composite {
|
|||
private static final long serialVersionUID = 368264811155804533L;
|
||||
private static final Logger log = LoggerFactory.getLogger(ImageUploadSelection.class);
|
||||
|
||||
public static final Set<String> SUPPORTED_IMAGE_FILES = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
|
||||
".png",
|
||||
".jpg",
|
||||
".jpeg")));
|
||||
public static final Set<String> SUPPORTED_IMAGE_FILES = Set.of(".png", ".jpg", ".jpeg");
|
||||
|
||||
private final ServerPushService serverPushService;
|
||||
|
||||
|
@ -152,12 +149,12 @@ public final class ImageUploadSelection extends Composite {
|
|||
setImage(this, input);
|
||||
}
|
||||
|
||||
private static final boolean uploadInProgress(final ServerPushContext context) {
|
||||
private static boolean uploadInProgress(final ServerPushContext context) {
|
||||
final ImageUploadSelection imageUpload = (ImageUploadSelection) context.getAnchor();
|
||||
return imageUpload.loadNewImage && !imageUpload.imageLoaded;
|
||||
}
|
||||
|
||||
private static final void update(final ServerPushContext context) {
|
||||
private static void update(final ServerPushContext context) {
|
||||
final ImageUploadSelection imageUpload = (ImageUploadSelection) context.getAnchor();
|
||||
if (imageUpload.imageBase64 != null
|
||||
&& imageUpload.loadNewImage
|
||||
|
@ -181,12 +178,8 @@ public final class ImageUploadSelection extends Composite {
|
|||
|
||||
final Image image = new Image(imageUpload.imageCanvas.getDisplay(), input);
|
||||
final Rectangle imageBounds = image.getBounds();
|
||||
final int width = (imageBounds.width > imageUpload.maxWidth)
|
||||
? imageUpload.maxWidth
|
||||
: imageBounds.width;
|
||||
final int height = (imageBounds.height > imageUpload.maxHeight)
|
||||
? imageUpload.maxHeight
|
||||
: imageBounds.height;
|
||||
final int width = Math.min(imageBounds.width, imageUpload.maxWidth);
|
||||
final int height = Math.min(imageBounds.height, imageUpload.maxHeight);
|
||||
final ImageData imageData = image.getImageData().scaledTo(width, height);
|
||||
imageUpload.imageCanvas.setBackgroundImage(new Image(imageUpload.imageCanvas.getDisplay(), imageData));
|
||||
}
|
||||
|
@ -194,10 +187,8 @@ public final class ImageUploadSelection extends Composite {
|
|||
private static boolean fileSupported(final String fileName) {
|
||||
return SUPPORTED_IMAGE_FILES
|
||||
.stream()
|
||||
.filter(fileType -> fileName.toUpperCase(Locale.ROOT)
|
||||
.endsWith(fileType.toUpperCase(Locale.ROOT)))
|
||||
.findFirst()
|
||||
.isPresent();
|
||||
.anyMatch(fileType -> fileName.toUpperCase(Locale.ROOT)
|
||||
.endsWith(fileType.toUpperCase(Locale.ROOT)));
|
||||
}
|
||||
|
||||
private final class ImageReceiver extends FileUploadReceiver {
|
||||
|
|
|
@ -8,12 +8,11 @@
|
|||
|
||||
package ch.ethz.seb.sebserver.gui.widget;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Tuple;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Tuple3;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.layout.GridData;
|
||||
|
@ -22,11 +21,10 @@ import org.eclipse.swt.widgets.Button;
|
|||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Listener;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Tuple;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Tuple3;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public final class MultiSelectionCheckbox extends Composite implements Selection {
|
||||
|
||||
|
@ -121,7 +119,7 @@ public final class MultiSelectionCheckbox extends Composite implements Selection
|
|||
.stream()
|
||||
.filter(Button::getSelection)
|
||||
.map(button -> (String) button.getData(OPTION_VALUE))
|
||||
.collect(Collectors.toList()).toArray());
|
||||
.toArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -8,13 +8,9 @@
|
|||
|
||||
package ch.ethz.seb.sebserver.gui.widget;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Tuple;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.eclipse.rap.rwt.widgets.DropDown;
|
||||
import org.eclipse.swt.SWT;
|
||||
|
@ -29,9 +25,10 @@ import org.eclipse.swt.widgets.Text;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Tuple;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.PageService;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public final class MultiSelectionCombo extends Composite implements Selection {
|
||||
|
||||
|
@ -75,12 +72,8 @@ public final class MultiSelectionCombo extends Composite implements Selection {
|
|||
this.textCell = new GridData(SWT.LEFT, SWT.CENTER, true, true);
|
||||
this.textInput.setLayoutData(this.textCell);
|
||||
this.dropDown = new DropDown(this.textInput, SWT.NONE);
|
||||
this.textInput.addListener(SWT.FocusIn, event -> {
|
||||
openDropDown();
|
||||
});
|
||||
this.textInput.addListener(SWT.Modify, event -> {
|
||||
openDropDown();
|
||||
});
|
||||
this.textInput.addListener(SWT.FocusIn, event -> openDropDown());
|
||||
this.textInput.addListener(SWT.Modify, event -> openDropDown());
|
||||
this.dropDown.addListener(SWT.Selection, event -> {
|
||||
final int selectionIndex = this.dropDown.getSelectionIndex();
|
||||
if (selectionIndex >= 0) {
|
||||
|
@ -98,12 +91,10 @@ public final class MultiSelectionCombo extends Composite implements Selection {
|
|||
this.dropDown.setVisible(false);
|
||||
return;
|
||||
}
|
||||
final Collection<String> items = this.availableValues
|
||||
this.dropDown.setItems(this.availableValues
|
||||
.stream()
|
||||
.filter(it -> it._2 != null && it._2.startsWith(text))
|
||||
.map(t -> t._2)
|
||||
.collect(Collectors.toList());
|
||||
this.dropDown.setItems(items.toArray(new String[items.size()]));
|
||||
.map(t -> t._2).toArray(String[]::new));
|
||||
this.dropDown.setSelectionIndex(0);
|
||||
this.dropDown.setVisible(true);
|
||||
}
|
||||
|
@ -132,8 +123,7 @@ public final class MultiSelectionCombo extends Composite implements Selection {
|
|||
return;
|
||||
}
|
||||
|
||||
Arrays.asList(StringUtils.split(keys, Constants.LIST_SEPARATOR))
|
||||
.stream()
|
||||
Arrays.stream(StringUtils.split(keys, Constants.LIST_SEPARATOR))
|
||||
.map(this::itemForId)
|
||||
.forEach(this::addSelection);
|
||||
}
|
||||
|
@ -159,7 +149,6 @@ public final class MultiSelectionCombo extends Composite implements Selection {
|
|||
public void clear() {
|
||||
this.selectedValues.clear();
|
||||
this.selectionControls
|
||||
.stream()
|
||||
.forEach(Control::dispose);
|
||||
this.selectionControls.clear();
|
||||
this.availableValues.clear();
|
||||
|
@ -176,9 +165,7 @@ public final class MultiSelectionCombo extends Composite implements Selection {
|
|||
label.setData(OPTION_VALUE, item._2);
|
||||
final GridData textCell = new GridData(SWT.LEFT, SWT.CENTER, true, true);
|
||||
label.setLayoutData(textCell);
|
||||
label.addListener(SWT.MouseDoubleClick, event -> {
|
||||
removeComboSelection(event);
|
||||
});
|
||||
label.addListener(SWT.MouseDoubleClick, this::removeComboSelection);
|
||||
this.selectionControls.add(label);
|
||||
|
||||
this.availableValues.remove(item);
|
||||
|
@ -217,8 +204,7 @@ public final class MultiSelectionCombo extends Composite implements Selection {
|
|||
|
||||
private void adaptColumnWidth(final Event event) {
|
||||
try {
|
||||
final int currentTableWidth = this.getClientArea().width;
|
||||
this.textCell.widthHint = currentTableWidth;
|
||||
this.textCell.widthHint = this.getClientArea().width;
|
||||
this.layout();
|
||||
} catch (final Exception e) {
|
||||
log.warn("Failed to adaptColumnWidth: ", e);
|
||||
|
@ -230,11 +216,7 @@ public final class MultiSelectionCombo extends Composite implements Selection {
|
|||
.stream()
|
||||
.filter(it -> it._2 != null && it._2.equals(name))
|
||||
.findFirst();
|
||||
if (findFirst.isPresent()) {
|
||||
return findFirst.get();
|
||||
}
|
||||
|
||||
return null;
|
||||
return findFirst.orElse(null);
|
||||
}
|
||||
|
||||
private Tuple<String> itemForId(final String id) {
|
||||
|
@ -242,11 +224,7 @@ public final class MultiSelectionCombo extends Composite implements Selection {
|
|||
.stream()
|
||||
.filter(it -> it._1 != null && it._1.equals(id))
|
||||
.findFirst();
|
||||
if (findFirst.isPresent()) {
|
||||
return findFirst.get();
|
||||
}
|
||||
|
||||
return null;
|
||||
return findFirst.orElse(null);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -99,7 +99,7 @@ public final class RadioSelection extends Composite implements Selection {
|
|||
return this.radioButtons
|
||||
.values()
|
||||
.stream()
|
||||
.filter(button -> button.getSelection())
|
||||
.filter(Button::getSelection)
|
||||
.findFirst()
|
||||
.map(button -> (String) button.getData(OPTION_VALUE))
|
||||
.orElse(null);
|
||||
|
@ -109,7 +109,6 @@ public final class RadioSelection extends Composite implements Selection {
|
|||
public void clear() {
|
||||
this.radioButtons
|
||||
.values()
|
||||
.stream()
|
||||
.forEach(button -> button.setSelection(false));
|
||||
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ import ch.ethz.seb.sebserver.gbl.util.Tuple;
|
|||
|
||||
public interface Selection {
|
||||
|
||||
static final String OPTION_VALUE = "OPTION_VALUE";
|
||||
String OPTION_VALUE = "OPTION_VALUE";
|
||||
|
||||
enum Type {
|
||||
SINGLE,
|
||||
|
|
|
@ -87,7 +87,7 @@ public final class SingleSelection extends Combo implements Selection {
|
|||
@Override
|
||||
public void clear() {
|
||||
super.clearSelection();
|
||||
super.setItems(this.valueMapping.toArray(new String[this.valueMapping.size()]));
|
||||
super.setItems(this.valueMapping.toArray(new String[0]));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -57,13 +57,6 @@ public class WebserviceInit implements ApplicationListener<ApplicationReadyEvent
|
|||
|
||||
SEBServerInit.INIT_LOGGER.info("----> **** Webservice starting up... ****");
|
||||
|
||||
SEBServerInit.INIT_LOGGER.info("----> ");
|
||||
SEBServerInit.INIT_LOGGER.info("----> Init Database with flyway...");
|
||||
SEBServerInit.INIT_LOGGER.info("----> TODO ");
|
||||
|
||||
// TODO integration of Flyway for database initialization and migration: https://flywaydb.org
|
||||
// see also https://flywaydb.org/getstarted/firststeps/api
|
||||
|
||||
SEBServerInit.INIT_LOGGER.info("----> ");
|
||||
SEBServerInit.INIT_LOGGER.info("----> Intitialize Services...");
|
||||
SEBServerInit.INIT_LOGGER.info("----> ");
|
||||
|
|
|
@ -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) ;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -60,10 +60,10 @@ public interface ClientConfigService {
|
|||
unless = "#result.hasError()")
|
||||
Result<ClientDetails> getClientConfigDetails(String clientName);
|
||||
|
||||
@CacheEvict(
|
||||
cacheNames = EXAM_CLIENT_DETAILS_CACHE,
|
||||
allEntries = true)
|
||||
@EventListener(BulkActionEvent.class)
|
||||
void flushClientConfigData(BulkActionEvent event);
|
||||
|
||||
/** Internally used to check OAuth2 access for a active SebClientConfig.
|
||||
*
|
||||
* @param config the SebClientConfig to check access
|
||||
* @return true if the system was able to gain an access token for the client. False otherwise
|
||||
*/
|
||||
boolean checkAccess(SebClientConfig config);
|
||||
}
|
||||
|
|
|
@ -10,8 +10,7 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.impl;
|
|||
|
||||
import ch.ethz.seb.sebserver.WebSecurityConfig;
|
||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||
import ch.ethz.seb.sebserver.gbl.api.API.BulkActionType;
|
||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||
import ch.ethz.seb.sebserver.gbl.model.institution.Institution;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.SebClientConfig;
|
||||
|
@ -19,8 +18,6 @@ import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
|||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||
import ch.ethz.seb.sebserver.webservice.WebserviceInfo;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.impl.BulkAction;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.impl.BulkActionEvent;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.client.ClientCredentialService;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.client.ClientCredentials;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.InstitutionDAO;
|
||||
|
@ -38,12 +35,21 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.security.oauth2.common.OAuth2AccessToken;
|
||||
import org.springframework.security.oauth2.provider.ClientDetails;
|
||||
import org.springframework.security.oauth2.provider.client.BaseClientDetails;
|
||||
import org.springframework.security.oauth2.provider.token.TokenStore;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
@ -51,6 +57,7 @@ import java.io.OutputStream;
|
|||
import java.io.PipedInputStream;
|
||||
import java.io.PipedOutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.UUID;
|
||||
|
@ -316,19 +323,48 @@ public class ClientConfigServiceImpl implements ClientConfigService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void flushClientConfigData(final BulkActionEvent event) {
|
||||
public boolean checkAccess(SebClientConfig config) {
|
||||
if(!config.isActive()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
final BulkAction bulkAction = event.getBulkAction();
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
String externalServerURL = webserviceInfo.getExternalServerURL() +
|
||||
API.OAUTH_TOKEN_ENDPOINT;
|
||||
|
||||
if (bulkAction.type == BulkActionType.DEACTIVATE ||
|
||||
bulkAction.type == BulkActionType.HARD_DELETE) {
|
||||
MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
|
||||
headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE);
|
||||
ClientCredentials credentials = sebClientConfigDAO
|
||||
.getSebClientCredentials(config.getModelId())
|
||||
.getOrThrow();
|
||||
CharSequence plainClientSecret = clientCredentialService.getPlainClientSecret(credentials);
|
||||
String basicAuth = credentials.clientId +
|
||||
String.valueOf(Constants.COLON) +
|
||||
plainClientSecret;
|
||||
String encoded = Base64.getEncoder()
|
||||
.encodeToString(basicAuth.getBytes());
|
||||
|
||||
bulkAction.extractKeys(EntityType.SEB_CLIENT_CONFIGURATION)
|
||||
.forEach(this::flushClientConfigData);
|
||||
headers.add(HttpHeaders.AUTHORIZATION, "Basic " + encoded);
|
||||
HttpEntity<String> entity = new HttpEntity<>(
|
||||
"grant_type=client_credentials&scope=read write",
|
||||
headers);
|
||||
|
||||
ResponseEntity<String> exchange = restTemplate.exchange(
|
||||
externalServerURL,
|
||||
HttpMethod.POST,
|
||||
entity,
|
||||
String.class);
|
||||
|
||||
if (exchange.getStatusCode().value() == HttpStatus.OK.value()) {
|
||||
return true;
|
||||
} else {
|
||||
log.warn("Failed to check access SebClientConfig {} response: {}", config, exchange.getStatusCode());
|
||||
return false;
|
||||
}
|
||||
|
||||
} catch (final Exception e) {
|
||||
log.error("Unexpected error while trying to flush ClientConfig data ", e);
|
||||
} catch (Exception e) {
|
||||
log.warn("Failed to check access for SebClientConfig: {} cause: {}", config, e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
package ch.ethz.seb.sebserver.webservice.servicelayer.session.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
@ -93,6 +94,17 @@ public class ClientIndicatorFactory {
|
|||
final PingIntervalClientIndicator pingIndicator = this.applicationContext
|
||||
.getBean(PingIntervalClientIndicator.class);
|
||||
pingIndicator.hidden = true;
|
||||
final Indicator indicator = new Indicator(
|
||||
null,
|
||||
clientConnection.examId,
|
||||
"hidden_ping_indicator",
|
||||
IndicatorType.LAST_PING,
|
||||
"",
|
||||
Arrays.asList(new Indicator.Threshold(5000d, "")));
|
||||
pingIndicator.init(
|
||||
indicator,
|
||||
clientConnection.id,
|
||||
this.enableCaching);
|
||||
result.add(pingIndicator);
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,6 @@ public final class PingIntervalClientIndicator extends AbstractPingIndicator {
|
|||
|
||||
long pingErrorThreshold;
|
||||
boolean missingPing = false;
|
||||
|
||||
boolean hidden = false;
|
||||
|
||||
public PingIntervalClientIndicator(final ClientEventExtensionMapper clientEventExtensionMapper) {
|
||||
|
|
|
@ -95,13 +95,19 @@ public class ClientEventController extends ReadonlyEntityController<ClientEvent,
|
|||
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();
|
||||
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
|
||||
|
@ -118,7 +124,7 @@ public class ClientEventController extends ReadonlyEntityController<ClientEvent,
|
|||
protected GrantEntity toGrantEntity(final ClientEvent entity) {
|
||||
return this.examDAO
|
||||
.byClientConnection(entity.connectionId)
|
||||
.getOrThrow();
|
||||
.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -39,6 +39,7 @@ import org.springframework.web.bind.annotation.PathVariable;
|
|||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import javax.servlet.ServletOutputStream;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
@ -144,6 +145,15 @@ public class SebClientConfigController extends ActivatableEntityController<SebCl
|
|||
.map(this::checkPasswordMatch);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Result<SebClientConfig> notifySaved(SebClientConfig entity) {
|
||||
if (entity.isActive()) {
|
||||
// try to get access token for SEB client
|
||||
sebClientConfigService.checkAccess(entity);
|
||||
}
|
||||
return super.notifySaved(entity);
|
||||
}
|
||||
|
||||
private SebClientConfig checkPasswordMatch(final SebClientConfig entity) {
|
||||
Collection<APIMessage> errors = new ArrayList<>();
|
||||
if (entity.hasEncryptionSecret() && !entity.encryptSecret.equals(entity.encryptSecretConfirm)) {
|
||||
|
|
|
@ -17,6 +17,7 @@ import org.springframework.security.oauth2.common.OAuth2AccessToken;
|
|||
import org.springframework.security.oauth2.provider.OAuth2Authentication;
|
||||
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
|
||||
|
||||
// TODO check if we can apply some caching here to get better performance for SEB client connection attempts
|
||||
public class DefaultTokenServicesFallback extends DefaultTokenServices {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(DefaultTokenServicesFallback.class);
|
||||
|
@ -29,22 +30,22 @@ public class DefaultTokenServicesFallback extends DefaultTokenServices {
|
|||
return super.createAccessToken(authentication);
|
||||
} catch (final DuplicateKeyException e) {
|
||||
|
||||
log.info(
|
||||
"Catched DuplicateKeyException, try to handle it by trying to get the already stored access token after waited some time");
|
||||
log.warn(
|
||||
"Caught DuplicateKeyException, try to handle it by trying to get the already stored access token after waited some time");
|
||||
|
||||
final String clientName = authentication.getName();
|
||||
if (StringUtils.isNotBlank(clientName)) {
|
||||
|
||||
// wait a second...
|
||||
// wait some time...
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
Thread.sleep(500);
|
||||
} catch (final InterruptedException e1) {
|
||||
log.warn("Failed to sleep: {}", e1.getMessage());
|
||||
}
|
||||
|
||||
final OAuth2AccessToken accessToken = this.getAccessToken(authentication);
|
||||
if (accessToken != null) {
|
||||
log.info("Found original accees token for client: {} token: {}", clientName, accessToken);
|
||||
log.debug("Found original access token for client: {} ", clientName);
|
||||
return accessToken;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ sebserver.init.adminaccount.gen-on-init=false
|
|||
sebserver.webservice.distributed=false
|
||||
sebserver.webservice.http.scheme=http
|
||||
sebserver.webservice.http.external.servername=
|
||||
sebserver.webservice.http.external.port=
|
||||
sebserver.webservice.http.external.port=${server.port}
|
||||
sebserver.webservice.http.redirect.gui=/gui
|
||||
|
||||
|
||||
|
|
|
@ -175,7 +175,7 @@ INSERT INTO configuration_attribute VALUES
|
|||
(304, 'enablePrivateClipboard', 'CHECKBOX', null, null, null, null, 'true'),
|
||||
(305, 'enableLogging', 'CHECKBOX', null, null, null, null, 'false'),
|
||||
(306, 'logDirectoryWin', 'TEXT_FIELD', null, null, null, null, ''),
|
||||
(307, 'logDirectoryOSX', 'TEXT_FIELD', null, null, null, null, 'NSTemporaryDirectory'),
|
||||
(307, 'logDirectoryOSX', 'TEXT_FIELD', null, null, null, null, 'F'),
|
||||
(308, 'minMacOSVersion', 'SINGLE_SELECTION', null, '0,1,2,3,4,5,6,7', null, null, '0'),
|
||||
(309, 'enableAppSwitcherCheck', 'CHECKBOX', null, null, null, null, 'true'),
|
||||
(310, 'forceAppFolderInstall', 'CHECKBOX', null, null, null, null, 'true'),
|
||||
|
@ -263,7 +263,7 @@ INSERT INTO configuration_attribute VALUES
|
|||
(927, 'mobileStatusBarAppearanceExtended', 'SINGLE_SELECTION', null, '0,1,2,3,4', null, null, '1'),
|
||||
(928, 'newBrowserWindowShowURL', 'SINGLE_SELECTION', null, '0,1,2,3', null, null, '1'),
|
||||
(929, 'pinEmbeddedCertificates', 'CHECKBOX', null, null, null, null, 'false'),
|
||||
(930, 'sendBrowserExamKey', 'CHECKBOX', null, null, null, null, 'false'),
|
||||
(930, 'sendBrowserExamKey', 'CHECKBOX', null, null, null, null, 'true'),
|
||||
(931, 'showNavigationButtons', 'CHECKBOX', null, null, null, null, 'false'),
|
||||
(932, 'showScanQRCodeButton', 'CHECKBOX', null, null, null, null, 'false'),
|
||||
(933, 'startResource', 'TEXT_FIELD', null, null, null, null, ''),
|
||||
|
|
|
@ -198,7 +198,7 @@ INSERT IGNORE INTO configuration_attribute VALUES
|
|||
(304, 'enablePrivateClipboard', 'CHECKBOX', null, null, null, null, 'true'),
|
||||
(305, 'enableLogging', 'CHECKBOX', null, null, null, null, 'false'),
|
||||
(306, 'logDirectoryWin', 'TEXT_FIELD', null, null, null, null, ''),
|
||||
(307, 'logDirectoryOSX', 'TEXT_FIELD', null, null, null, null, 'NSTemporaryDirectory'),
|
||||
(307, 'logDirectoryOSX', 'TEXT_FIELD', null, null, null, null, ''),
|
||||
(308, 'minMacOSVersion', 'SINGLE_SELECTION', null, '0,1,2,3,4,5,6,7', null, null, '0'),
|
||||
(309, 'enableAppSwitcherCheck', 'CHECKBOX', null, null, null, null, 'true'),
|
||||
(310, 'forceAppFolderInstall', 'CHECKBOX', null, null, null, null, 'true'),
|
||||
|
@ -286,7 +286,7 @@ INSERT IGNORE INTO configuration_attribute VALUES
|
|||
(927, 'mobileStatusBarAppearanceExtended', 'SINGLE_SELECTION', null, '0,1,2,3,4', null, null, '1'),
|
||||
(928, 'newBrowserWindowShowURL', 'SINGLE_SELECTION', null, '0,1,2,3', null, null, '1'),
|
||||
(929, 'pinEmbeddedCertificates', 'CHECKBOX', null, null, null, null, 'false'),
|
||||
(930, 'sendBrowserExamKey', 'CHECKBOX', null, null, null, null, 'false'),
|
||||
(930, 'sendBrowserExamKey', 'CHECKBOX', null, null, null, null, 'true'),
|
||||
(931, 'showNavigationButtons', 'CHECKBOX', null, null, null, null, 'false'),
|
||||
(932, 'showScanQRCodeButton', 'CHECKBOX', null, null, null, null, 'false'),
|
||||
(933, 'startResource', 'TEXT_FIELD', null, null, null, null, ''),
|
||||
|
|
Loading…
Add table
Reference in a new issue