diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/api/API.java b/src/main/java/ch/ethz/seb/sebserver/gbl/api/API.java index 4dc4a47b..8ccc5728 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gbl/api/API.java +++ b/src/main/java/ch/ethz/seb/sebserver/gbl/api/API.java @@ -144,7 +144,7 @@ public final class API { public static final String QUIZ_DISCOVERY_ENDPOINT = "/quiz"; public static final String EXAM_ADMINISTRATION_ENDPOINT = "/exam"; - public static final String EXAM_ADMINISTRATION_DOWNLOAD_CONFIG_PATH_SEGMENT = "/download-config"; + //public static final String EXAM_ADMINISTRATION_DOWNLOAD_CONFIG_PATH_SEGMENT = "/download-config"; public static final String EXAM_ADMINISTRATION_CONSISTENCY_CHECK_PATH_SEGMENT = "/check-consistency"; public static final String EXAM_ADMINISTRATION_CONSISTENCY_CHECK_INCLUDE_RESTRICTION = "include-restriction"; public static final String EXAM_ADMINISTRATION_SEB_RESTRICTION_PATH_SEGMENT = "/seb-restriction"; @@ -170,7 +170,7 @@ public final class API { public static final String CONFIGURATION_VALUE_ENDPOINT = "/configuration_value"; public static final String CONFIGURATION_TABLE_VALUE_PATH_SEGMENT = "/table"; public static final String CONFIGURATION_ATTRIBUTE_ENDPOINT = "/configuration_attribute"; - public static final String CONFIGURATION_PLAIN_XML_DOWNLOAD_PATH_SEGMENT = "/downloadxml"; + public static final String CONFIGURATION_SEB_SETTINGS_DOWNLOAD_PATH_SEGMENT = "/downloadSettings"; public static final String CONFIGURATION_IMPORT_PATH_SEGMENT = "/import"; public static final String IMPORT_PASSWORD_ATTR_NAME = "importFilePassword"; public static final String IMPORT_FILE_ATTR_NAME = "importFile"; diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/configs/SEBSettingsForm.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/configs/SEBSettingsForm.java index c67cabf1..2ae44a2b 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/configs/SEBSettingsForm.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/configs/SEBSettingsForm.java @@ -50,7 +50,7 @@ import ch.ethz.seb.sebserver.gui.service.page.PageMessageException; import ch.ethz.seb.sebserver.gui.service.page.PageService; import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer; import ch.ethz.seb.sebserver.gui.service.remote.download.DownloadService; -import ch.ethz.seb.sebserver.gui.service.remote.download.SEBExamConfigPlaintextDownload; +import ch.ethz.seb.sebserver.gui.service.remote.download.SEBExamSettingsDownload; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetConfigurations; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetExamConfigNode; @@ -237,7 +237,7 @@ public class SEBSettingsForm implements TemplateComposer { .withExec(action -> { final String downloadURL = this.downloadService.createDownloadURL( entityKey.modelId, - SEBExamConfigPlaintextDownload.class, + SEBExamSettingsDownload.class, this.downloadFileName); urlLauncher.openURL(downloadURL); return action; diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/monitoring/SEBClientEvents.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/monitoring/SEBClientEvents.java index 123fc5ae..b522ac71 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/monitoring/SEBClientEvents.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/monitoring/SEBClientEvents.java @@ -8,6 +8,7 @@ package ch.ethz.seb.sebserver.gui.content.monitoring; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.Consumer; @@ -15,6 +16,8 @@ import java.util.function.Function; import java.util.stream.Collectors; import org.apache.tomcat.util.buf.StringUtils; +import org.eclipse.rap.rwt.RWT; +import org.eclipse.rap.rwt.client.service.UrlLauncher; import org.eclipse.swt.widgets.Composite; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -24,12 +27,15 @@ import org.springframework.stereotype.Component; import org.springframework.util.MultiValueMap; import ch.ethz.seb.sebserver.gbl.Constants; +import ch.ethz.seb.sebserver.gbl.api.API; import ch.ethz.seb.sebserver.gbl.api.EntityType; import ch.ethz.seb.sebserver.gbl.api.authorization.PrivilegeType; import ch.ethz.seb.sebserver.gbl.model.Domain; import ch.ethz.seb.sebserver.gbl.model.EntityName; +import ch.ethz.seb.sebserver.gbl.model.Page; import ch.ethz.seb.sebserver.gbl.model.session.ClientConnection; import ch.ethz.seb.sebserver.gbl.model.session.ClientEvent; +import ch.ethz.seb.sebserver.gbl.model.session.ClientEvent.ExportType; import ch.ethz.seb.sebserver.gbl.model.session.ExtendedClientEvent; import ch.ethz.seb.sebserver.gbl.profile.GuiProfile; import ch.ethz.seb.sebserver.gbl.util.Utils; @@ -42,6 +48,8 @@ import ch.ethz.seb.sebserver.gui.service.page.PageService; import ch.ethz.seb.sebserver.gui.service.page.PageService.PageActionBuilder; import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer; import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction; +import ch.ethz.seb.sebserver.gui.service.remote.download.DownloadService; +import ch.ethz.seb.sebserver.gui.service.remote.download.SEBClientLogExport; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.logs.GetClientEventNames; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.logs.GetExtendedClientEventPage; @@ -84,23 +92,29 @@ public class SEBClientEvents implements TemplateComposer { private final ResourceService resourceService; private final RestService restService; private final I18nSupport i18nSupport; + private final DownloadService downloadService; private final SEBClientEventDetailsPopup sebClientEventDetailsPopup; private final SEBClientEventDeletePopup sebClientEventDeletePopup; private final int pageSize; + private final String exportFileName; public SEBClientEvents( final PageService pageService, + final DownloadService downloadService, final SEBClientEventDetailsPopup sebClientEventDetailsPopup, final SEBClientEventDeletePopup sebClientEventDeletePopup, + @Value("${sebserver.gui.seb.client.logs.export.filename:SEBClientLogs}") final String exportFileName, @Value("${sebserver.gui.list.page.size:20}") final Integer pageSize) { this.pageService = pageService; + this.downloadService = downloadService; this.resourceService = pageService.getResourceService(); this.restService = this.resourceService.getRestService(); this.i18nSupport = this.resourceService.getI18nSupport(); this.sebClientEventDetailsPopup = sebClientEventDetailsPopup; this.sebClientEventDeletePopup = sebClientEventDeletePopup; this.pageSize = pageSize; + this.exportFileName = exportFileName; this.examFilter = new TableFilterAttribute( CriteriaType.SINGLE_SELECTION, @@ -219,12 +233,52 @@ public class SEBClientEvents implements TemplateComposer { .noEventPropagation() .publish(false) + .newAction(ActionDefinition.LOGS_SEB_CLIENT_EXPORT_CSV) + .withExec(action -> this.exportLogs(action, ExportType.CSV, table)) + .noEventPropagation() + .publishIf(() -> writeGrant, table.hasAnyContent()) + .newAction(ActionDefinition.LOGS_SEB_CLIENT_DELETE_ALL) .withExec(action -> this.getOpenDelete(action, table.getFilterCriteria())) .noEventPropagation() .publishIf(() -> writeGrant, table.hasAnyContent()); } + private PageAction exportLogs( + final PageAction action, + final ExportType type, + final EntityTable table) { + + try { + + final UrlLauncher urlLauncher = RWT.getClient().getService(UrlLauncher.class); + final String fileName = this.exportFileName + + Constants.UNDERLINE + + this.i18nSupport.formatDisplayDate(Utils.getMillisecondsNow()) + .replace(" ", "_") + .replace(".", "_") + + Constants.FILE_EXT_CSV; + final Map queryAttrs = new HashMap<>(); + + queryAttrs.put(API.SEB_CLIENT_EVENT_EXPORT_TYPE, type.name()); + final String sortAttr = table.getSortOrder().encode(table.getSortColumn()); + queryAttrs.put(Page.ATTR_SORT, sortAttr); + table.getFilterCriteria().forEach((name, value) -> queryAttrs.put(name, value.get(0))); + + final String downloadURL = this.downloadService + .createDownloadURL( + SEBClientLogExport.class, + fileName, + queryAttrs); + + urlLauncher.openURL(downloadURL); + } catch (final Exception e) { + log.error("Failed open export log download: ", e); + } + + return action; + } + private PageAction getOpenDelete( final PageAction pageAction, final MultiValueMap filterCriteria) { @@ -270,4 +324,4 @@ public class SEBClientEvents implements TemplateComposer { .formatDisplayDateTime(Utils.toDateTimeUTC(event.serverTime)); } -} +} \ No newline at end of file diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/download/SEBClientConfigDownload.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/download/SEBClientConfigDownload.java index 5ff68524..06c7af07 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/download/SEBClientConfigDownload.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/download/SEBClientConfigDownload.java @@ -48,32 +48,35 @@ public class SEBClientConfigDownload extends AbstractDownloadServiceHandler { final OutputStream downloadOut, final HttpServletRequest request) { - final RestCall.RestCallBuilder restCallBuilder = this.restService + final RestCall.RestCallBuilder restCallBuilder = this.restService .getBuilder(ExportClientConfig.class) - .withURIVariable(API.PARAM_MODEL_ID, modelId); + .withURIVariable(API.PARAM_MODEL_ID, modelId) + .withResponseExtractor(response -> { + try { + final InputStream input = response.getBody(); + IOUtils.copyLarge(input, downloadOut); + } catch (final IOException e) { + log.error("Unexpected error while streaming to output-stream of download response: ", e); + throw new RuntimeException(e); + } finally { + try { + downloadOut.flush(); + downloadOut.close(); + } catch (final IOException e) { + log.error("Unexpected error while trying to close download output-stream"); + } + } + + return true; + }); if (StringUtils.isNotBlank(parentModelId)) { restCallBuilder.withQueryParam(EXAM.ATTR_ID, parentModelId); } - final InputStream input = restCallBuilder + restCallBuilder .call() - .getOrThrow(); - - try { - IOUtils.copyLarge(input, downloadOut); - } catch (final IOException e) { - log.error( - "Unexpected error while streaming incoming config data from web-service to output-stream of download response: ", - e); - } finally { - try { - downloadOut.flush(); - downloadOut.close(); - } catch (final IOException e) { - log.error("Unexpected error while trying to close download output-stream"); - } - } + .onError(error -> log.error("SEB exam settings download failed: ", error)); } } diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/download/SEBClientLogExport.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/download/SEBClientLogExport.java index ee36957c..23cced15 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/download/SEBClientLogExport.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/download/SEBClientLogExport.java @@ -25,7 +25,7 @@ import org.springframework.util.MultiValueMap; import ch.ethz.seb.sebserver.gbl.profile.GuiProfile; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService; -import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.ExportSEBClientLogs; +import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.logs.ExportSEBClientLogs; @Lazy @Component @@ -63,9 +63,8 @@ public class SEBClientLogExport extends AbstractDownloadServiceHandler { final InputStream input = response.getBody(); IOUtils.copyLarge(input, downloadOut); } catch (final IOException e) { - log.error( - "Unexpected error while streaming incoming config data from web-service to output-stream of download response: ", - e); + log.error("Unexpected error while streaming to output-stream of download response: ", e); + throw new RuntimeException(e); } finally { try { downloadOut.flush(); @@ -79,8 +78,7 @@ public class SEBClientLogExport extends AbstractDownloadServiceHandler { }) .withQueryParams(queryParams) .call() - .onError(error -> log.error("Download failed: ", error)); - + .onError(error -> log.error("SEB Client logs download failed: ", error)); } } diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/download/SEBExamConfigPlaintextDownload.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/download/SEBExamConfigPlaintextDownload.java deleted file mode 100644 index 6d844c37..00000000 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/download/SEBExamConfigPlaintextDownload.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET) - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -package ch.ethz.seb.sebserver.gui.service.remote.download; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -import javax.servlet.http.HttpServletRequest; - -import org.apache.commons.io.IOUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.context.annotation.Lazy; -import org.springframework.stereotype.Component; - -import ch.ethz.seb.sebserver.gbl.api.API; -import ch.ethz.seb.sebserver.gbl.profile.GuiProfile; -import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService; -import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.ExportPlainXML; - -@Lazy -@Component -@GuiProfile -public class SEBExamConfigPlaintextDownload extends AbstractDownloadServiceHandler { - - private static final Logger log = LoggerFactory.getLogger(SEBExamConfigPlaintextDownload.class); - - private final RestService restService; - - protected SEBExamConfigPlaintextDownload(final RestService restService) { - this.restService = restService; - } - - @Override - protected void webserviceCall( - final String modelId, - final String parentModelId, - final OutputStream downloadOut, - final HttpServletRequest request) { - - final InputStream input = this.restService.getBuilder(ExportPlainXML.class) - .withURIVariable(API.PARAM_MODEL_ID, modelId) - .call() - .getOrThrow(); - - try { - IOUtils.copyLarge(input, downloadOut); - } catch (final IOException e) { - log.error( - "Unexpected error while streaming incoming config data from web-service to output-stream of download response: ", - e); - } finally { - try { - downloadOut.flush(); - downloadOut.close(); - } catch (final IOException e) { - log.error("Unexpected error while trying to close download output-stream"); - } - } - } - -} diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/download/SEBExamConfigDownload.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/download/SEBExamSettingsDownload.java similarity index 53% rename from src/main/java/ch/ethz/seb/sebserver/gui/service/remote/download/SEBExamConfigDownload.java rename to src/main/java/ch/ethz/seb/sebserver/gui/service/remote/download/SEBExamSettingsDownload.java index bca25b02..b44a86b8 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/download/SEBExamConfigDownload.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/download/SEBExamSettingsDownload.java @@ -23,18 +23,18 @@ import org.springframework.stereotype.Component; import ch.ethz.seb.sebserver.gbl.api.API; import ch.ethz.seb.sebserver.gbl.profile.GuiProfile; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService; -import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.ExportExamConfig; +import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.ExportSEBSettingsConfig; @Lazy @Component @GuiProfile -public class SEBExamConfigDownload extends AbstractDownloadServiceHandler { +public class SEBExamSettingsDownload extends AbstractDownloadServiceHandler { - private static final Logger log = LoggerFactory.getLogger(SEBExamConfigDownload.class); + private static final Logger log = LoggerFactory.getLogger(SEBExamSettingsDownload.class); private final RestService restService; - protected SEBExamConfigDownload(final RestService restService) { + protected SEBExamSettingsDownload(final RestService restService) { this.restService = restService; } @@ -45,26 +45,29 @@ public class SEBExamConfigDownload extends AbstractDownloadServiceHandler { final OutputStream downloadOut, final HttpServletRequest request) { - final InputStream input = this.restService.getBuilder(ExportExamConfig.class) + this.restService + .getBuilder(ExportSEBSettingsConfig.class) .withURIVariable(API.PARAM_MODEL_ID, modelId) - .withURIVariable(API.PARAM_PARENT_MODEL_ID, parentModelId) - .call() - .getOrThrow(); + .withResponseExtractor(response -> { + try { + final InputStream input = response.getBody(); + IOUtils.copyLarge(input, downloadOut); + } catch (final IOException e) { + log.error("Unexpected error while streaming to output-stream of download response: ", e); + throw new RuntimeException(e); + } finally { + try { + downloadOut.flush(); + downloadOut.close(); + } catch (final IOException e) { + log.error("Unexpected error while trying to close download output-stream"); + } + } - try { - IOUtils.copyLarge(input, downloadOut); - } catch (final IOException e) { - log.error( - "Unexpected error while streaming incoming config data from web-service to output-stream of download response: ", - e); - } finally { - try { - downloadOut.flush(); - downloadOut.close(); - } catch (final IOException e) { - log.error("Unexpected error while trying to close download output-stream"); - } - } + return true; + }) + .call() + .onError(error -> log.error("SEB exam settings download failed: ", error)); } } diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/AbstractExportCall.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/AbstractExportCall.java deleted file mode 100644 index 6690249e..00000000 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/AbstractExportCall.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET) - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -package ch.ethz.seb.sebserver.gui.service.remote.webservice.api; - -import java.io.InputStream; - -import org.apache.commons.io.IOUtils; -import org.springframework.http.HttpMethod; -import org.springframework.http.MediaType; -import org.springframework.http.client.ClientHttpRequest; - -import ch.ethz.seb.sebserver.gbl.util.Result; - -@Deprecated // This is not streaming correctly. Use AbstractDownloadCall instead -public abstract class AbstractExportCall extends RestCall { - - protected AbstractExportCall( - final TypeKey typeKey, - final HttpMethod httpMethod, - final MediaType contentType, - final String path) { - - super(typeKey, httpMethod, contentType, path); - } - - @Override - protected Result exchange(final RestCallBuilder builder) { - - return Result.tryCatch(() -> builder - .getRestTemplate() - .execute( - builder.buildURI(), - this.httpMethod, - (final ClientHttpRequest requestCallback) -> { - }, - response -> IOUtils.toBufferedInputStream(response.getBody()), - builder.getURIVariables())); - } - -} diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/exam/ExportExamConfig.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/exam/ExportExamConfig.java deleted file mode 100644 index 69e12bd4..00000000 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/exam/ExportExamConfig.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET) - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -package ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam; - -import java.io.InputStream; - -import org.springframework.context.annotation.Lazy; -import org.springframework.http.HttpMethod; -import org.springframework.http.MediaType; -import org.springframework.stereotype.Component; - -import com.fasterxml.jackson.core.type.TypeReference; - -import ch.ethz.seb.sebserver.gbl.api.API; -import ch.ethz.seb.sebserver.gbl.api.EntityType; -import ch.ethz.seb.sebserver.gbl.profile.GuiProfile; -import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.AbstractExportCall; - -@Lazy -@Component -@GuiProfile -public class ExportExamConfig extends AbstractExportCall { - - public ExportExamConfig() { - super(new TypeKey<>( - CallType.UNDEFINED, - EntityType.EXAM, - new TypeReference() { - }), - HttpMethod.GET, - MediaType.APPLICATION_FORM_URLENCODED, - API.EXAM_ADMINISTRATION_ENDPOINT - + API.MODEL_ID_VAR_PATH_SEGMENT - + API.EXAM_ADMINISTRATION_DOWNLOAD_CONFIG_PATH_SEGMENT - + API.PARENT_MODEL_ID_VAR_PATH_SEGMENT); - } - -} diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/seb/examconfig/ExportPlainXML.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/exam/ExportSEBSettingsConfig.java similarity index 53% rename from src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/seb/examconfig/ExportPlainXML.java rename to src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/exam/ExportSEBSettingsConfig.java index 8708736b..07a0f8af 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/seb/examconfig/ExportPlainXML.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/exam/ExportSEBSettingsConfig.java @@ -6,38 +6,26 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig; - -import java.io.InputStream; +package ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam; import org.springframework.context.annotation.Lazy; -import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; import org.springframework.stereotype.Component; -import com.fasterxml.jackson.core.type.TypeReference; - import ch.ethz.seb.sebserver.gbl.api.API; -import ch.ethz.seb.sebserver.gbl.api.EntityType; import ch.ethz.seb.sebserver.gbl.profile.GuiProfile; -import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.AbstractExportCall; +import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.AbstractDownloadCall; @Lazy @Component @GuiProfile -public class ExportPlainXML extends AbstractExportCall { +public class ExportSEBSettingsConfig extends AbstractDownloadCall { - public ExportPlainXML() { - super(new TypeKey<>( - CallType.UNDEFINED, - EntityType.CONFIGURATION_NODE, - new TypeReference() { - }), - HttpMethod.GET, - MediaType.APPLICATION_FORM_URLENCODED, + public ExportSEBSettingsConfig() { + super(MediaType.APPLICATION_FORM_URLENCODED, API.CONFIGURATION_NODE_ENDPOINT + API.MODEL_ID_VAR_PATH_SEGMENT - + API.CONFIGURATION_PLAIN_XML_DOWNLOAD_PATH_SEGMENT); + + API.CONFIGURATION_SEB_SETTINGS_DOWNLOAD_PATH_SEGMENT); } } diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/exam/ExportSEBClientLogs.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/logs/ExportSEBClientLogs.java similarity index 96% rename from src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/exam/ExportSEBClientLogs.java rename to src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/logs/ExportSEBClientLogs.java index 8e76abba..fb1dca48 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/exam/ExportSEBClientLogs.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/logs/ExportSEBClientLogs.java @@ -6,7 +6,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam; +package ch.ethz.seb.sebserver.gui.service.remote.webservice.api.logs; import org.springframework.context.annotation.Lazy; import org.springframework.http.MediaType; diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/seb/clientconfig/ExportClientConfig.java b/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/seb/clientconfig/ExportClientConfig.java index 39c11fce..b3a6d0c1 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/seb/clientconfig/ExportClientConfig.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/service/remote/webservice/api/seb/clientconfig/ExportClientConfig.java @@ -8,33 +8,21 @@ package ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.clientconfig; -import java.io.InputStream; - import org.springframework.context.annotation.Lazy; -import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; import org.springframework.stereotype.Component; -import com.fasterxml.jackson.core.type.TypeReference; - import ch.ethz.seb.sebserver.gbl.api.API; -import ch.ethz.seb.sebserver.gbl.api.EntityType; import ch.ethz.seb.sebserver.gbl.profile.GuiProfile; -import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.AbstractExportCall; +import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.AbstractDownloadCall; @Lazy @Component @GuiProfile -public class ExportClientConfig extends AbstractExportCall { +public class ExportClientConfig extends AbstractDownloadCall { public ExportClientConfig() { - super(new TypeKey<>( - CallType.UNDEFINED, - EntityType.SEB_CLIENT_CONFIGURATION, - new TypeReference() { - }), - HttpMethod.GET, - MediaType.APPLICATION_FORM_URLENCODED, + super(MediaType.APPLICATION_FORM_URLENCODED, API.SEB_CLIENT_CONFIG_ENDPOINT + API.SEB_CLIENT_CONFIG_DOWNLOAD_PATH_SEGMENT + API.MODEL_ID_VAR_PATH_SEGMENT); diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ConfigurationNodeController.java b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ConfigurationNodeController.java index aacac396..1ef3fe79 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ConfigurationNodeController.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ConfigurationNodeController.java @@ -221,7 +221,7 @@ public class ConfigurationNodeController extends EntityController { - private static final Logger log = LoggerFactory.getLogger(ExamAdministrationController.class); - private final ExamDAO examDAO; private final UserDAO userDAO; private final ExamAdminService examAdminService; private final ExamTemplateService examTemplateService; private final LmsAPIService lmsAPIService; - private final ExamConfigService sebExamConfigService; private final ExamSessionService examSessionService; private final SEBRestrictionService sebRestrictionService; @@ -104,7 +94,6 @@ public class ExamAdministrationController extends EntityController { final UserDAO userDAO, final ExamAdminService examAdminService, final ExamTemplateService examTemplateService, - final ExamConfigService sebExamConfigService, final ExamSessionService examSessionService, final SEBRestrictionService sebRestrictionService) { @@ -120,7 +109,6 @@ public class ExamAdministrationController extends EntityController { this.examAdminService = examAdminService; this.examTemplateService = examTemplateService; this.lmsAPIService = lmsAPIService; - this.sebExamConfigService = sebExamConfigService; this.examSessionService = examSessionService; this.sebRestrictionService = sebRestrictionService; } @@ -179,46 +167,6 @@ public class ExamAdministrationController extends EntityController { } } - @RequestMapping( - path = API.MODEL_ID_VAR_PATH_SEGMENT - + API.EXAM_ADMINISTRATION_DOWNLOAD_CONFIG_PATH_SEGMENT - + API.PARENT_MODEL_ID_VAR_PATH_SEGMENT, - method = RequestMethod.GET, - produces = MediaType.APPLICATION_OCTET_STREAM_VALUE) - public void downloadPlainXMLConfig( - @PathVariable final Long modelId, - @PathVariable final Long parentModelId, - @RequestParam( - name = API.PARAM_INSTITUTION_ID, - required = true, - defaultValue = UserService.USERS_INSTITUTION_AS_DEFAULT) final Long institutionId, - final HttpServletResponse response) throws IOException { - - this.entityDAO.byPK(modelId) - .flatMap(this.authorization::checkRead) - .flatMap(this.userActivityLogDAO::logExport); - - final ServletOutputStream outputStream = response.getOutputStream(); - - try { - - this.sebExamConfigService.exportForExam( - outputStream, - institutionId, - parentModelId, - modelId); - - response.setStatus(HttpStatus.OK.value()); - - } catch (final Exception e) { - log.error("Unexpected error while trying to downstream exam config: ", e); - response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value()); - } finally { - outputStream.flush(); - outputStream.close(); - } - } - @RequestMapping( path = API.MODEL_ID_VAR_PATH_SEGMENT + API.EXAM_ADMINISTRATION_CHECK_IMPORTED_PATH_SEGMENT, diff --git a/src/main/resources/config/application-dev.properties b/src/main/resources/config/application-dev.properties index e7329017..250767d0 100644 --- a/src/main/resources/config/application-dev.properties +++ b/src/main/resources/config/application-dev.properties @@ -17,7 +17,7 @@ logging.level.ch.ethz.seb.sebserver.webservice.servicelayer.session.impl.indicat #logging.level.ch.ethz.seb.sebserver.webservice.servicelayer.dao.impl=DEBUG #logging.level.ch.ethz.seb.sebserver.webservice.datalayer.batis=DEBUG #logging.level.ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper=DEBUG -logging.level.ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ExamRecordMapper=DEBUG +#logging.level.ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ExamRecordMapper=DEBUG #logging.level.ch.ethz.seb.sebserver.webservice.weblayer.api.ExamAPI_V1_Controller=TRACE logging.level.com.zaxxer.hikari=DEBUG diff --git a/src/test/java/ch/ethz/seb/sebserver/gui/integration/UseCasesIntegrationTest.java b/src/test/java/ch/ethz/seb/sebserver/gui/integration/UseCasesIntegrationTest.java index a6f805ed..816a7281 100644 --- a/src/test/java/ch/ethz/seb/sebserver/gui/integration/UseCasesIntegrationTest.java +++ b/src/test/java/ch/ethz/seb/sebserver/gui/integration/UseCasesIntegrationTest.java @@ -108,7 +108,7 @@ import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.DeleteExam; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.DeleteExamConfigMapping; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.DeleteExamTemplate; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.DeleteIndicatorTemplate; -import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.ExportExamConfig; +import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.ExportSEBSettingsConfig; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetExam; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetExamConfigMapping; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetExamConfigMappingNames; @@ -161,7 +161,6 @@ import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.clientconfig. import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.AttachDefaultOrientation; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.CopyConfiguration; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.ExportConfigKey; -import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.ExportPlainXML; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetConfigAttributes; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetConfigurationPage; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.examconfig.GetConfigurationTableValues; @@ -1028,31 +1027,36 @@ public class UseCasesIntegrationTest extends GuiIntegrationTest { assertEquals("http://fallback.com/fallback", configWithPassword.fallbackStartURL); // export client config No Password Protection - Result exportResponse = restService + Result exportResponse = restService .getBuilder(ExportClientConfig.class) .withURIVariable(API.PARAM_MODEL_ID, sebClientConfig.getModelId()) + .withResponseExtractor(response -> { + final InputStream input = response.getBody(); + final List readLines = IOUtils.readLines(input, "UTF-8"); + assertNotNull(readLines); + assertFalse(readLines.isEmpty()); + return true; + }) .call(); - assertNotNull(exportResponse); assertFalse(exportResponse.hasError()); - List readLines = IOUtils.readLines(exportResponse.get(), "UTF-8"); - assertNotNull(readLines); - assertFalse(readLines.isEmpty()); - // export client config With Password Protection exportResponse = restService .getBuilder(ExportClientConfig.class) .withURIVariable(API.PARAM_MODEL_ID, configWithPassword.getModelId()) + .withResponseExtractor(response -> { + final InputStream input = response.getBody(); + final List readLines = IOUtils.readLines(input, "UTF-8"); + assertNotNull(readLines); + assertFalse(readLines.isEmpty()); + return true; + }) .call(); assertNotNull(exportResponse); assertFalse(exportResponse.hasError()); - readLines = IOUtils.readLines(exportResponse.get(), "UTF-8"); - assertNotNull(readLines); - assertFalse(readLines.isEmpty()); - // get page final Result> pageResponse = restService .getBuilder(GetClientConfigPage.class) @@ -1463,10 +1467,9 @@ public class UseCasesIntegrationTest extends GuiIntegrationTest { new GetConfigurationTableValues(), new GetExamConfigNodePage(), new SaveExamConfigHistory(), - new ExportExamConfig(), + new ExportSEBSettingsConfig(), new ImportNewExamConfig(), new ImportExamConfigOnExistingConfig(), - new ExportPlainXML(), new GetFollowupConfiguration()); // get all configuration attributes @@ -1498,23 +1501,26 @@ public class UseCasesIntegrationTest extends GuiIntegrationTest { assertTrue(followup.followup); // export1 - final InputStream input = restService - .getBuilder(ExportPlainXML.class) + restService + .getBuilder(ExportSEBSettingsConfig.class) .withURIVariable(API.PARAM_MODEL_ID, configurationNode.getModelId()) + .withResponseExtractor(response -> { + final InputStream input = response.getBody(); + final String xmlString = StreamUtils.copyToString(input, Charsets.UTF_8); + assertNotNull(xmlString); + for (final ConfigurationAttribute attribute : attributes) { + if (attribute.name.contains(".") || attribute.name.equals("kioskMode")) { + continue; + } + if (!xmlString.contains(attribute.name)) { + fail("missing attribute: " + attribute.name); + } + } + return true; + }) .call() .getOrThrow(); - final String xmlString = StreamUtils.copyToString(input, Charsets.UTF_8); - assertNotNull(xmlString); - for (final ConfigurationAttribute attribute : attributes) { - if (attribute.name.contains(".") || attribute.name.equals("kioskMode")) { - continue; - } - if (!xmlString.contains(attribute.name)) { - fail("missing attribute: " + attribute.name); - } - } - // import plain config InputStream inputStream = new ClassPathResource("importTest.seb").getInputStream(); Configuration importedConfig = restService @@ -1873,7 +1879,7 @@ public class UseCasesIntegrationTest extends GuiIntegrationTest { new CheckExamConsistency(), new DeleteExamConfigMapping(), new ExportConfigKey(), - new ExportExamConfig()); + new ExportSEBSettingsConfig()); // get exam final Result> exams = restService @@ -2018,17 +2024,20 @@ public class UseCasesIntegrationTest extends GuiIntegrationTest { //assertEquals("e4af6cf8deb9434e69e8dc6c373418712546de35807d8bfbd6bb98790f8d0774", configKey.key); // export config to XML - final InputStream input = restService.getBuilder(ExportExamConfig.class) + restService.getBuilder(ExportSEBSettingsConfig.class) .withURIVariable(API.PARAM_MODEL_ID, String.valueOf(examConfigurationMap.configurationNodeId)) .withURIVariable(API.PARAM_PARENT_MODEL_ID, String.valueOf(examConfigurationMap.examId)) + .withResponseExtractor(response -> { + final InputStream input = response.getBody(); + final String xmlString = StreamUtils.copyToString(input, Charsets.UTF_8); + assertNotNull(xmlString); +// assertEquals( +// "allowAudioCaptureallowBrowsingBackForwardallowDictationallowDictionaryLookupallowDisplayMirroringallowDownUploadsallowedDisplayBuiltinallowedDisplaysMaxNumber1allowFlashFullscreenallowiOSBetaVersionNumber0allowiOSVersionNumberMajor9allowiOSVersionNumberMinor3allowiOSVersionNumberPatch5allowPDFPlugInallowPreferencesWindowallowQuitallowScreenSharingallowSiriallowSpellCheckallowSpellCheckDictionaryda-DKen-AUen-GBen-USes-ESfr-FRpt-PTsv-SEsv-FIallowSwitchToApplicationsallowUserAppFolderInstallallowUserSwitchingallowVideoCaptureallowVirtualMachineallowWlanaudioControlEnabledaudioMuteaudioSetVolumeLevelaudioVolumeLevel25blacklistURLFilterblockPopUpWindowsbrowserMessagingPingTime120000browserMessagingSocketws://localhost:8706browserScreenKeyboardbrowserURLSaltbrowserUserAgentbrowserUserAgentiOS0browserUserAgentiOSCustombrowserUserAgentMac0browserUserAgentMacCustombrowserUserAgentWinDesktopMode0browserUserAgentWinDesktopModeCustombrowserUserAgentWinTouchMode0browserUserAgentWinTouchModeCustombrowserUserAgentWinTouchModeIPadMozilla/5.0 (iPad; CPU OS 12_4_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1.2 Mobile/15E148 Safari/604.1browserViewMode0browserWindowAllowReloadbrowserWindowShowURL0browserWindowTitleSuffixchooseFileToUploadPolicy0createNewDesktopdetectStoppedProcessdownloadAndOpenSebConfigdownloadDirectoryOSXdownloadDirectoryWindownloadPDFFilesenableAltEscenableAltF4enableAltMouseWheelenableAltTabenableAppSwitcherCheckenableBrowserWindowToolbarenableCtrlEscenableDrawingEditorenableEscenableF1enableF10enableF11enableF12enableF2enableF3enableF4enableF5enableF6enableF7enableF8enableF9enableJavaenableJavaScriptenableLoggingenablePlugInsenablePrintScreenenablePrivateClipboardenableRightMouseenableSebBrowserenableStartMenuenableTouchExitenableZoomPageenableZoomTextexamSessionClearCookiesOnEndexamSessionClearCookiesOnStartexitKey12exitKey210exitKey35forceAppFolderInstallhashedAdminPasswordhashedQuitPasswordhideBrowserWindowToolbarhookKeysignoreExitKeysinsideSebEnableChangeAPasswordinsideSebEnableEaseOfAccessinsideSebEnableLockThisComputerinsideSebEnableLogOffinsideSebEnableNetworkConnectionSelectorinsideSebEnableShutDowninsideSebEnableStartTaskManagerinsideSebEnableSwitchUserinsideSebEnableVmWareClientShadekillExplorerShelllockOnMessageSocketCloselogDirectoryOSXlogDirectoryWinlogLevel1mainBrowserWindowHeight100%mainBrowserWindowPositioning1mainBrowserWindowWidth100%minMacOSVersion0mobileAllowPictureInPictureMediaPlaybackmobileAllowQRCodeConfigmobileAllowSingleAppModemobileEnableASAMmobileEnableGuidedAccessLinkTransformmobilePreventAutoLockmobileShowSettingsmobileStatusBarAppearance1mobileStatusBarAppearanceExtended1monitorProcessesnewBrowserWindowAllowReloadnewBrowserWindowByLinkBlockForeignnewBrowserWindowByLinkHeight100%newBrowserWindowByLinkPolicy2newBrowserWindowByLinkPositioning2newBrowserWindowByLinkWidth100%newBrowserWindowByScriptBlockForeignnewBrowserWindowByScriptPolicy2newBrowserWindowNavigationnewBrowserWindowShowReloadWarningnewBrowserWindowShowURL1openDownloadsoriginatorVersionSEB_Server_0.3.0permittedProcessesactiveallowUserToChooseAppargumentsautostartdescriptionexecutablefirefox.exeiconInTaskbaridentifierFirefoxoriginalNamefirefox.exeos1path../xulrunner/runInBackgroundstrongKilltitleSEBpinEmbeddedCertificatesprohibitedProcessesactivecurrentUserdescriptionexecutableRiotidentifieroriginalNameRiotos1strongKilluseractivecurrentUserdescriptionexecutableseamonkeyidentifieroriginalNameseamonkeyos1strongKilluseractivecurrentUserdescriptionexecutableDiscordidentifieroriginalNameDiscordos1strongKilluseractivecurrentUserdescriptionexecutableSlackidentifieroriginalNameSlackos1strongKilluseractivecurrentUserdescriptionexecutableTeamsidentifieroriginalNameTeamsos1strongKilluseractivecurrentUserdescriptionexecutableCamRecorderidentifieroriginalNameCamRecorderos1strongKilluseractivecurrentUserdescriptionexecutablejoin.meidentifieroriginalNamejoin.meos1strongKilluseractivecurrentUserdescriptionexecutableRPCSuiteidentifieroriginalNameRPCSuiteos1strongKilluseractivecurrentUserdescriptionexecutableRPCServiceidentifieroriginalNameRPCServiceos1strongKilluseractivecurrentUserdescriptionexecutableRemotePCDesktopidentifieroriginalNameRemotePCDesktopos1strongKilluseractivecurrentUserdescriptionexecutablebeamyourscreen-hostidentifieroriginalNamebeamyourscreen-hostos1strongKilluseractivecurrentUserdescriptionexecutableAeroAdminidentifieroriginalNameAeroAdminos1strongKilluseractivecurrentUserdescriptionexecutableMikogo-hostidentifieroriginalNameMikogo-hostos1strongKilluseractivecurrentUserdescriptionexecutablechromotingidentifieroriginalNamechromotingos1strongKilluseractivecurrentUserdescriptionexecutablevncserveruiidentifieroriginalNamevncserveruios1strongKilluseractivecurrentUserdescriptionexecutablevncvieweridentifieroriginalNamevncvieweros1strongKilluseractivecurrentUserdescriptionexecutablevncserveridentifieroriginalNamevncserveros1strongKilluseractivecurrentUserdescriptionexecutableTeamVieweridentifieroriginalNameTeamVieweros1strongKilluseractivecurrentUserdescriptionexecutableGotoMeetingWinStoreidentifieroriginalNameGotoMeetingWinStoreos1strongKilluseractivecurrentUserdescriptionexecutableg2mcomm.exeidentifieroriginalNameg2mcomm.exeos1strongKilluseractivecurrentUserdescriptionexecutableSkypeHostidentifieroriginalNameSkypeHostos1strongKilluseractivecurrentUserdescriptionexecutableSkypeidentifieroriginalNameSkypeos1strongKilluserproxiesAutoConfigurationEnabledAutoConfigurationJavaScriptAutoConfigurationURLAutoDiscoveryEnabledExceptionsListExcludeSimpleHostnamesFTPEnableFTPPassiveFTPPasswordFTPPort21FTPProxyFTPRequiresPasswordFTPUsernameHTTPEnableHTTPPasswordHTTPPort80HTTPProxyHTTPRequiresPasswordHTTPSEnableHTTPSPasswordHTTPSPort443HTTPSProxyHTTPSRequiresPasswordHTTPSUsernameHTTPUsernameRTSPEnableRTSPPasswordRTSPPort554RTSPProxyRTSPRequiresPasswordRTSPUsernameSOCKSEnableSOCKSPasswordSOCKSPort1080SOCKSProxySOCKSRequiresPasswordSOCKSUsernameproxySettingsPolicy0quitURLquitURLConfirmremoveBrowserProfileremoveLocalStoragerestartExamPasswordProtectedrestartExamTextrestartExamURLrestartExamUseStartURLsebConfigPurpose0sebServicePolicy2sendBrowserExamKeyshowBackToStartButtonshowInputLanguageshowMenuBarshowNavigationButtonsshowReloadButtonshowReloadWarningshowScanQRCodeButtonshowSettingsInAppshowTaskBarshowTimestartResourcetaskBarHeight40touchOptimizedURLFilterEnableURLFilterEnableContentFilterURLFilterMessage0URLFilterRulesuseAsymmetricOnlyEncryptionwhitelistURLFilterzoomMode0", +// xmlString); + return true; + }) .call() .getOrThrow(); - - final String xmlString = StreamUtils.copyToString(input, Charsets.UTF_8); - assertNotNull(xmlString); -// assertEquals( -// "allowAudioCaptureallowBrowsingBackForwardallowDictationallowDictionaryLookupallowDisplayMirroringallowDownUploadsallowedDisplayBuiltinallowedDisplaysMaxNumber1allowFlashFullscreenallowiOSBetaVersionNumber0allowiOSVersionNumberMajor9allowiOSVersionNumberMinor3allowiOSVersionNumberPatch5allowPDFPlugInallowPreferencesWindowallowQuitallowScreenSharingallowSiriallowSpellCheckallowSpellCheckDictionaryda-DKen-AUen-GBen-USes-ESfr-FRpt-PTsv-SEsv-FIallowSwitchToApplicationsallowUserAppFolderInstallallowUserSwitchingallowVideoCaptureallowVirtualMachineallowWlanaudioControlEnabledaudioMuteaudioSetVolumeLevelaudioVolumeLevel25blacklistURLFilterblockPopUpWindowsbrowserMessagingPingTime120000browserMessagingSocketws://localhost:8706browserScreenKeyboardbrowserURLSaltbrowserUserAgentbrowserUserAgentiOS0browserUserAgentiOSCustombrowserUserAgentMac0browserUserAgentMacCustombrowserUserAgentWinDesktopMode0browserUserAgentWinDesktopModeCustombrowserUserAgentWinTouchMode0browserUserAgentWinTouchModeCustombrowserUserAgentWinTouchModeIPadMozilla/5.0 (iPad; CPU OS 12_4_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1.2 Mobile/15E148 Safari/604.1browserViewMode0browserWindowAllowReloadbrowserWindowShowURL0browserWindowTitleSuffixchooseFileToUploadPolicy0createNewDesktopdetectStoppedProcessdownloadAndOpenSebConfigdownloadDirectoryOSXdownloadDirectoryWindownloadPDFFilesenableAltEscenableAltF4enableAltMouseWheelenableAltTabenableAppSwitcherCheckenableBrowserWindowToolbarenableCtrlEscenableDrawingEditorenableEscenableF1enableF10enableF11enableF12enableF2enableF3enableF4enableF5enableF6enableF7enableF8enableF9enableJavaenableJavaScriptenableLoggingenablePlugInsenablePrintScreenenablePrivateClipboardenableRightMouseenableSebBrowserenableStartMenuenableTouchExitenableZoomPageenableZoomTextexamSessionClearCookiesOnEndexamSessionClearCookiesOnStartexitKey12exitKey210exitKey35forceAppFolderInstallhashedAdminPasswordhashedQuitPasswordhideBrowserWindowToolbarhookKeysignoreExitKeysinsideSebEnableChangeAPasswordinsideSebEnableEaseOfAccessinsideSebEnableLockThisComputerinsideSebEnableLogOffinsideSebEnableNetworkConnectionSelectorinsideSebEnableShutDowninsideSebEnableStartTaskManagerinsideSebEnableSwitchUserinsideSebEnableVmWareClientShadekillExplorerShelllockOnMessageSocketCloselogDirectoryOSXlogDirectoryWinlogLevel1mainBrowserWindowHeight100%mainBrowserWindowPositioning1mainBrowserWindowWidth100%minMacOSVersion0mobileAllowPictureInPictureMediaPlaybackmobileAllowQRCodeConfigmobileAllowSingleAppModemobileEnableASAMmobileEnableGuidedAccessLinkTransformmobilePreventAutoLockmobileShowSettingsmobileStatusBarAppearance1mobileStatusBarAppearanceExtended1monitorProcessesnewBrowserWindowAllowReloadnewBrowserWindowByLinkBlockForeignnewBrowserWindowByLinkHeight100%newBrowserWindowByLinkPolicy2newBrowserWindowByLinkPositioning2newBrowserWindowByLinkWidth100%newBrowserWindowByScriptBlockForeignnewBrowserWindowByScriptPolicy2newBrowserWindowNavigationnewBrowserWindowShowReloadWarningnewBrowserWindowShowURL1openDownloadsoriginatorVersionSEB_Server_0.3.0permittedProcessesactiveallowUserToChooseAppargumentsautostartdescriptionexecutablefirefox.exeiconInTaskbaridentifierFirefoxoriginalNamefirefox.exeos1path../xulrunner/runInBackgroundstrongKilltitleSEBpinEmbeddedCertificatesprohibitedProcessesactivecurrentUserdescriptionexecutableRiotidentifieroriginalNameRiotos1strongKilluseractivecurrentUserdescriptionexecutableseamonkeyidentifieroriginalNameseamonkeyos1strongKilluseractivecurrentUserdescriptionexecutableDiscordidentifieroriginalNameDiscordos1strongKilluseractivecurrentUserdescriptionexecutableSlackidentifieroriginalNameSlackos1strongKilluseractivecurrentUserdescriptionexecutableTeamsidentifieroriginalNameTeamsos1strongKilluseractivecurrentUserdescriptionexecutableCamRecorderidentifieroriginalNameCamRecorderos1strongKilluseractivecurrentUserdescriptionexecutablejoin.meidentifieroriginalNamejoin.meos1strongKilluseractivecurrentUserdescriptionexecutableRPCSuiteidentifieroriginalNameRPCSuiteos1strongKilluseractivecurrentUserdescriptionexecutableRPCServiceidentifieroriginalNameRPCServiceos1strongKilluseractivecurrentUserdescriptionexecutableRemotePCDesktopidentifieroriginalNameRemotePCDesktopos1strongKilluseractivecurrentUserdescriptionexecutablebeamyourscreen-hostidentifieroriginalNamebeamyourscreen-hostos1strongKilluseractivecurrentUserdescriptionexecutableAeroAdminidentifieroriginalNameAeroAdminos1strongKilluseractivecurrentUserdescriptionexecutableMikogo-hostidentifieroriginalNameMikogo-hostos1strongKilluseractivecurrentUserdescriptionexecutablechromotingidentifieroriginalNamechromotingos1strongKilluseractivecurrentUserdescriptionexecutablevncserveruiidentifieroriginalNamevncserveruios1strongKilluseractivecurrentUserdescriptionexecutablevncvieweridentifieroriginalNamevncvieweros1strongKilluseractivecurrentUserdescriptionexecutablevncserveridentifieroriginalNamevncserveros1strongKilluseractivecurrentUserdescriptionexecutableTeamVieweridentifieroriginalNameTeamVieweros1strongKilluseractivecurrentUserdescriptionexecutableGotoMeetingWinStoreidentifieroriginalNameGotoMeetingWinStoreos1strongKilluseractivecurrentUserdescriptionexecutableg2mcomm.exeidentifieroriginalNameg2mcomm.exeos1strongKilluseractivecurrentUserdescriptionexecutableSkypeHostidentifieroriginalNameSkypeHostos1strongKilluseractivecurrentUserdescriptionexecutableSkypeidentifieroriginalNameSkypeos1strongKilluserproxiesAutoConfigurationEnabledAutoConfigurationJavaScriptAutoConfigurationURLAutoDiscoveryEnabledExceptionsListExcludeSimpleHostnamesFTPEnableFTPPassiveFTPPasswordFTPPort21FTPProxyFTPRequiresPasswordFTPUsernameHTTPEnableHTTPPasswordHTTPPort80HTTPProxyHTTPRequiresPasswordHTTPSEnableHTTPSPasswordHTTPSPort443HTTPSProxyHTTPSRequiresPasswordHTTPSUsernameHTTPUsernameRTSPEnableRTSPPasswordRTSPPort554RTSPProxyRTSPRequiresPasswordRTSPUsernameSOCKSEnableSOCKSPasswordSOCKSPort1080SOCKSProxySOCKSRequiresPasswordSOCKSUsernameproxySettingsPolicy0quitURLquitURLConfirmremoveBrowserProfileremoveLocalStoragerestartExamPasswordProtectedrestartExamTextrestartExamURLrestartExamUseStartURLsebConfigPurpose0sebServicePolicy2sendBrowserExamKeyshowBackToStartButtonshowInputLanguageshowMenuBarshowNavigationButtonsshowReloadButtonshowReloadWarningshowScanQRCodeButtonshowSettingsInAppshowTaskBarshowTimestartResourcetaskBarHeight40touchOptimizedURLFilterEnableURLFilterEnableContentFilterURLFilterMessage0URLFilterRulesuseAsymmetricOnlyEncryptionwhitelistURLFilterzoomMode0", -// xmlString); } @Autowired