diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/ConfigurationValue.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/ConfigurationValue.java index 92fedb9b..8383a0cd 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/ConfigurationValue.java +++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/ConfigurationValue.java @@ -110,6 +110,16 @@ public final class ConfigurationValue implements GrantEntity { return this.value; } + public ConfigurationValue copyOf(final Long institutionId, final Long configurationId2) { + return new ConfigurationValue( + this.id, + institutionId, + configurationId2, + this.attributeId, + this.listIndex, + this.value); + } + @Override public String toString() { final StringBuilder builder = new StringBuilder(); diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/WebserviceConfig.java b/src/main/java/ch/ethz/seb/sebserver/webservice/WebserviceConfig.java new file mode 100644 index 00000000..a30dd3d1 --- /dev/null +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/WebserviceConfig.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET) + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +package ch.ethz.seb.sebserver.webservice; + +import org.cryptonode.jncryptor.AES256JNCryptor; +import org.cryptonode.jncryptor.JNCryptor; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.context.annotation.Lazy; + +import ch.ethz.seb.sebserver.gbl.Constants; +import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile; + +//TODO check if DataSourceAutoConfiguration and TokenStore bean definition is really needed here +//or if it is possible to move them to the WebServiceSecurityConfig. +//test with starting web and gui separately as well as together +@Configuration +@WebServiceProfile +@Import(DataSourceAutoConfiguration.class) +public class WebserviceConfig { + + @Lazy + @Bean + public JNCryptor jnCryptor() { + final AES256JNCryptor aes256jnCryptor = new AES256JNCryptor(); + aes256jnCryptor.setPBKDFIterations(Constants.JN_CRYPTOR_ITERATIONS); + return aes256jnCryptor; + } + +} diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/WebServiceInit.java b/src/main/java/ch/ethz/seb/sebserver/webservice/WebserviceInit.java similarity index 66% rename from src/main/java/ch/ethz/seb/sebserver/webservice/WebServiceInit.java rename to src/main/java/ch/ethz/seb/sebserver/webservice/WebserviceInit.java index 586d57a1..f9bf265e 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/WebServiceInit.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/WebserviceInit.java @@ -11,32 +11,26 @@ package ch.ethz.seb.sebserver.webservice; import java.net.InetAddress; import java.net.UnknownHostException; -import org.cryptonode.jncryptor.AES256JNCryptor; -import org.cryptonode.jncryptor.JNCryptor; +import javax.annotation.PreDestroy; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.context.ApplicationListener; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; -import org.springframework.context.annotation.Lazy; import org.springframework.core.env.Environment; +import org.springframework.stereotype.Component; -import ch.ethz.seb.sebserver.gbl.Constants; import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile; -// TODO check if DataSourceAutoConfiguration and TokenStore bean definition is really needed here -// or if it is possible to move them to the WebServiceSecurityConfig. -// test with starting web and gui separately as well as together -@Configuration +@Component @WebServiceProfile @Import(DataSourceAutoConfiguration.class) -public class WebServiceInit implements ApplicationListener { +public class WebserviceInit implements ApplicationListener { - private static final Logger log = LoggerFactory.getLogger(WebServiceInit.class); + private static final Logger log = LoggerFactory.getLogger(WebserviceInit.class); @Autowired private Environment environment; @@ -62,16 +56,14 @@ public class WebServiceInit implements ApplicationListener, BulkActionSup * @return a Result containing the Exam by a given ClientConnection id or refer to an error if happened */ Result byClientConnection(Long connectionId); + Result> getExamIdsForStatus(Long institutionId, ExamStatus status); + Result> allForRunCheck(); Result> allForEndCheck(); diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/SebClientConfigDAO.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/SebClientConfigDAO.java index bac56c77..c5b4f0a3 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/SebClientConfigDAO.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/SebClientConfigDAO.java @@ -18,7 +18,7 @@ import ch.ethz.seb.sebserver.gbl.model.sebconfig.SebClientConfig; import ch.ethz.seb.sebserver.gbl.util.Result; import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.BulkActionSupportDAO; import ch.ethz.seb.sebserver.webservice.servicelayer.client.ClientCredentials; -import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SebClientConfigService; +import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.ClientConfigService; /** Concrete EntityDAO interface of SebClientConfig entities */ public interface SebClientConfigDAO extends @@ -56,7 +56,7 @@ public interface SebClientConfigDAO extends @Override @CacheEvict( - cacheNames = SebClientConfigService.EXAM_CLIENT_DETAILS_CACHE, + cacheNames = ClientConfigService.EXAM_CLIENT_DETAILS_CACHE, allEntries = true) Result> delete(Set all); diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ConfigurationAttributeDAOImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ConfigurationAttributeDAOImpl.java index bd9ec510..4e3f180e 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ConfigurationAttributeDAOImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ConfigurationAttributeDAOImpl.java @@ -238,7 +238,7 @@ public class ConfigurationAttributeDAOImpl implements ConfigurationAttributeDAO }); } - private Result recordById(final Long id) { + Result recordById(final Long id) { return Result.tryCatch(() -> { final ConfigurationAttributeRecord record = this.configurationAttributeRecordMapper .selectByPrimaryKey(id); @@ -251,7 +251,7 @@ public class ConfigurationAttributeDAOImpl implements ConfigurationAttributeDAO }); } - private static Result toDomainModel(final ConfigurationAttributeRecord record) { + static Result toDomainModel(final ConfigurationAttributeRecord record) { return Result.tryCatch(() -> new ConfigurationAttribute( record.getId(), record.getParentId(), diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ConfigurationDAOBatchService.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ConfigurationDAOBatchService.java index 902bf322..cded5766 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ConfigurationDAOBatchService.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ConfigurationDAOBatchService.java @@ -14,6 +14,7 @@ import static org.mybatis.dynamic.sql.SqlBuilder.isNotEqualTo; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.function.Function; import java.util.stream.Collectors; @@ -58,6 +59,7 @@ import ch.ethz.seb.sebserver.webservice.datalayer.batis.model.ConfigurationRecor import ch.ethz.seb.sebserver.webservice.datalayer.batis.model.ConfigurationValueRecord; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ResourceNotFoundException; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.TransactionHandler; +import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.ExamConfigInitService; /** This service is internally used to implement MyBatis batch functionality for the most * intensive write operation on Configuration domain. */ @@ -75,14 +77,17 @@ class ConfigurationDAOBatchService { private final ConfigurationValueRecordMapper batchConfigurationValueRecordMapper; private final ConfigurationAttributeRecordMapper batchConfigurationAttributeRecordMapper; private final ConfigurationRecordMapper batchConfigurationRecordMapper; + private final ExamConfigInitService examConfigInitService; private final SqlSessionTemplate batchSqlSessionTemplate; protected ConfigurationDAOBatchService( - @Qualifier(BatisConfig.SQL_BATCH_SESSION_TEMPLATE) final SqlSessionTemplate batchSqlSessionTemplate) { + @Qualifier(BatisConfig.SQL_BATCH_SESSION_TEMPLATE) final SqlSessionTemplate batchSqlSessionTemplate, + final ExamConfigInitService examConfigInitService) { final org.apache.ibatis.session.Configuration batisConfig = batchSqlSessionTemplate.getConfiguration(); + this.examConfigInitService = examConfigInitService; log.info("Registered MyBatis Mappers: {}", batisConfig.getMapperRegistry().getMappers()); @@ -655,8 +660,10 @@ class ConfigurationDAOBatchService { this.batchConfigurationRecordMapper.insert(followup); this.batchSqlSessionTemplate.flushStatements(); - createAttributeValues(config, followup) - .getOrThrow(); + this.copyValues( + config.institutionId, + initConfig.getId(), + followup.getId()); return config; }); @@ -693,47 +700,95 @@ class ConfigurationDAOBatchService { }); // override with template values if available - final List templateValues = getTemplateValues(configNode); - templateValues.stream() - .forEach(templateValue -> { - final Long existingId = this.batchConfigurationValueRecordMapper - .selectIdsByExample() - .where( - ConfigurationValueRecordDynamicSqlSupport.configurationId, - isEqualTo(config.getId())) - .and( - ConfigurationValueRecordDynamicSqlSupport.configurationAttributeId, - isEqualTo(templateValue.getConfigurationAttributeId())) - .and( - ConfigurationValueRecordDynamicSqlSupport.listIndex, - isEqualTo(templateValue.getListIndex())) - .build() - .execute() - .stream() - .findFirst() - .orElse(null); - - final ConfigurationValueRecord valueRec = new ConfigurationValueRecord( - existingId, - configNode.institutionId, - config.getId(), - templateValue.getConfigurationAttributeId(), - templateValue.getListIndex(), - templateValue.getValue()); - - if (existingId != null) { - this.batchConfigurationValueRecordMapper.updateByPrimaryKey(valueRec); - } else { - this.batchConfigurationValueRecordMapper.insert(valueRec); - } - }); - - this.batchSqlSessionTemplate.flushStatements(); + if (configNode.templateId == null || configNode.templateId == ConfigurationNode.DEFAULT_TEMPLATE_ID) { + initAdditionalDefaultValues(configNode, config); + } else { + writeTemplateValues(configNode, config); + } return configNode; }); } + private void initAdditionalDefaultValues( + final ConfigurationNode configNode, + final ConfigurationRecord config) { + + // get all attributes and map the names to id's + final Map attributeMap = this.batchConfigurationAttributeRecordMapper + .selectByExample() + .build() + .execute() + .stream() + .map(ConfigurationAttributeDAOImpl::toDomainModel) + .map(Result::get) + .filter(Objects::nonNull) + .collect(Collectors.toMap( + attr -> attr.name, + Function.identity())); + + this.examConfigInitService.getAdditionalDefaultValues( + configNode.institutionId, + config.getId(), + attributeMap::get) + .stream() + .forEach(value -> { + final ConfigurationValueRecord valueRec = new ConfigurationValueRecord( + null, + value.institutionId, + value.configurationId, + value.attributeId, + value.listIndex, + value.value); + + this.batchConfigurationValueRecordMapper.insert(valueRec); + }); + + this.batchSqlSessionTemplate.flushStatements(); + } + + private void writeTemplateValues( + final ConfigurationNode configNode, + final ConfigurationRecord config) { + + final List templateValues = getTemplateValues(configNode); + templateValues.stream() + .forEach(templateValue -> { + final Long existingId = this.batchConfigurationValueRecordMapper + .selectIdsByExample() + .where( + ConfigurationValueRecordDynamicSqlSupport.configurationId, + isEqualTo(config.getId())) + .and( + ConfigurationValueRecordDynamicSqlSupport.configurationAttributeId, + isEqualTo(templateValue.getConfigurationAttributeId())) + .and( + ConfigurationValueRecordDynamicSqlSupport.listIndex, + isEqualTo(templateValue.getListIndex())) + .build() + .execute() + .stream() + .findFirst() + .orElse(null); + + final ConfigurationValueRecord valueRec = new ConfigurationValueRecord( + existingId, + configNode.institutionId, + config.getId(), + templateValue.getConfigurationAttributeId(), + templateValue.getListIndex(), + templateValue.getValue()); + + if (existingId != null) { + this.batchConfigurationValueRecordMapper.updateByPrimaryKey(valueRec); + } else { + this.batchConfigurationValueRecordMapper.insert(valueRec); + } + }); + + this.batchSqlSessionTemplate.flushStatements(); + } + private static boolean filterChildAttribute(final ConfigurationAttributeRecord rec) { if (rec.getParentId() == null) { diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ExamDAOImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ExamDAOImpl.java index 3208cf51..763fb460 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ExamDAOImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ExamDAOImpl.java @@ -151,6 +151,9 @@ public class ExamDAOImpl implements ExamDAO { .and( ExamRecordDynamicSqlSupport.type, isEqualToWhenPresent(filterMap.getExamType())) + .and( + ExamRecordDynamicSqlSupport.status, + isEqualToWhenPresent(filterMap.getExamStatus())) .build() .execute(); @@ -301,6 +304,26 @@ public class ExamDAOImpl implements ExamDAO { .longValue() > 0; } + @Override + @Transactional(readOnly = true) + public Result> getExamIdsForStatus(final Long institutionId, final ExamStatus status) { + return Result.tryCatch(() -> this.examRecordMapper.selectIdsByExample() + .where( + ExamRecordDynamicSqlSupport.active, + isEqualTo(BooleanUtils.toInteger(true))) + .and( + ExamRecordDynamicSqlSupport.institutionId, + isEqualToWhenPresent(institutionId)) + .and( + ExamRecordDynamicSqlSupport.status, + isEqualTo(status.name())) + .and( + ExamRecordDynamicSqlSupport.updating, + isEqualTo(BooleanUtils.toInteger(false))) + .build() + .execute()); + } + @Override @Transactional(readOnly = true) public Result> allForRunCheck() { diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/SebClientConfigService.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/ClientConfigService.java similarity index 95% rename from src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/SebClientConfigService.java rename to src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/ClientConfigService.java index 039a711c..f46fe11a 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/SebClientConfigService.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/ClientConfigService.java @@ -21,9 +21,9 @@ import ch.ethz.seb.sebserver.gbl.model.sebconfig.SebClientConfig; import ch.ethz.seb.sebserver.gbl.util.Result; import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.BulkActionEvent; -public interface SebClientConfigService { +public interface ClientConfigService { - Logger log = LoggerFactory.getLogger(SebClientConfigService.class); + Logger log = LoggerFactory.getLogger(ClientConfigService.class); public static final String EXAM_CLIENT_DETAILS_CACHE = "EXAM_CLIENT_DETAILS_CACHE"; diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/ExamConfigInitService.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/ExamConfigInitService.java new file mode 100644 index 00000000..88f8b1fc --- /dev/null +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/ExamConfigInitService.java @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET) + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +package ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig; + +import java.util.Collection; +import java.util.function.Function; + +import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute; +import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue; + +public interface ExamConfigInitService { + + Collection getAdditionalDefaultValues( + Long institutionId, + Long configurationId, + final Function attributeResolver); + +} diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/SebExamConfigService.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/ExamConfigService.java similarity index 97% rename from src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/SebExamConfigService.java rename to src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/ExamConfigService.java index c5825bd9..ad2bf0d1 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/SebExamConfigService.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/ExamConfigService.java @@ -19,7 +19,7 @@ import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue; import ch.ethz.seb.sebserver.gbl.util.Result; /** The base interface and service for all SEB Exam Configuration related functionality. */ -public interface SebExamConfigService { +public interface ExamConfigService { /** Validates a given ConfigurationValue by using registered ConfigurationValueValodator * beans to find a proper validator for the specified ConfigurationValue diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/SebExamConfigTemplateService.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/ExamConfigTemplateService.java similarity index 93% rename from src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/SebExamConfigTemplateService.java rename to src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/ExamConfigTemplateService.java index 1c6eeaa1..8efe327e 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/SebExamConfigTemplateService.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/ExamConfigTemplateService.java @@ -14,7 +14,7 @@ import ch.ethz.seb.sebserver.gbl.model.sebconfig.TemplateAttribute; import ch.ethz.seb.sebserver.gbl.util.Result; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap; -public interface SebExamConfigTemplateService { +public interface ExamConfigTemplateService { Result> getTemplateAttributes( final Long institutionId, diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/SebClientConfigServiceImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/ClientConfigServiceImpl.java similarity index 95% rename from src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/SebClientConfigServiceImpl.java rename to src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/ClientConfigServiceImpl.java index ff01650c..b168c5a7 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/SebClientConfigServiceImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/ClientConfigServiceImpl.java @@ -48,7 +48,7 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.client.ClientCredentialServ import ch.ethz.seb.sebserver.webservice.servicelayer.client.ClientCredentials; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.InstitutionDAO; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.SebClientConfigDAO; -import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SebClientConfigService; +import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.ClientConfigService; import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SebConfigEncryptionService; import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SebConfigEncryptionService.Strategy; import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.ZipService; @@ -58,9 +58,9 @@ import ch.ethz.seb.sebserver.webservice.weblayer.oauth.WebserviceResourceConfigu @Lazy @Service @WebServiceProfile -public class SebClientConfigServiceImpl implements SebClientConfigService { +public class ClientConfigServiceImpl implements ClientConfigService { - private static final Logger log = LoggerFactory.getLogger(SebClientConfigServiceImpl.class); + private static final Logger log = LoggerFactory.getLogger(ClientConfigServiceImpl.class); private final InstitutionDAO institutionDAO; private final SebClientConfigDAO sebClientConfigDAO; @@ -71,7 +71,7 @@ public class SebClientConfigServiceImpl implements SebClientConfigService { private final TokenStore tokenStore; private final WebserviceInfo webserviceInfo; - protected SebClientConfigServiceImpl( + protected ClientConfigServiceImpl( final InstitutionDAO institutionDAO, final SebClientConfigDAO sebClientConfigDAO, final ClientCredentialService clientCredentialService, diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/ExamConfigIO.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/ExamConfigIO.java index dd1230f3..cc0c3efc 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/ExamConfigIO.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/ExamConfigIO.java @@ -187,7 +187,7 @@ public class ExamConfigIO { // the SAX handler with a ConfigValue sink that saves the values to DB // and a attribute-name/id mapping function with pre-created mapping - final ExamConfigImportHandler examConfigImportHandler = new ExamConfigImportHandler( + final ExamConfigXMLParser examConfigImportHandler = new ExamConfigXMLParser( institutionId, configurationId, value -> this.configurationValueDAO diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/SebExamConfigServiceImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/ExamConfigServiceImpl.java similarity index 95% rename from src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/SebExamConfigServiceImpl.java rename to src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/ExamConfigServiceImpl.java index 10eb2883..448230d9 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/SebExamConfigServiceImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/ExamConfigServiceImpl.java @@ -44,16 +44,16 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.ConfigurationForm import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.ConfigurationValueValidator; import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SebConfigEncryptionService; import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SebConfigEncryptionService.Strategy; -import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SebExamConfigService; +import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.ExamConfigService; import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.ZipService; import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.impl.SebConfigEncryptionServiceImpl.EncryptionContext; @Lazy @Service @WebServiceProfile -public class SebExamConfigServiceImpl implements SebExamConfigService { +public class ExamConfigServiceImpl implements ExamConfigService { - private static final Logger log = LoggerFactory.getLogger(SebExamConfigServiceImpl.class); + private static final Logger log = LoggerFactory.getLogger(ExamConfigServiceImpl.class); private final ExamConfigIO examConfigIO; private final ConfigurationAttributeDAO configurationAttributeDAO; @@ -64,7 +64,7 @@ public class SebExamConfigServiceImpl implements SebExamConfigService { private final ZipService zipService; private final SebConfigEncryptionService sebConfigEncryptionService; - protected SebExamConfigServiceImpl( + protected ExamConfigServiceImpl( final ExamConfigIO examConfigIO, final ConfigurationAttributeDAO configurationAttributeDAO, final ConfigurationDAO configurationDAO, diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/SebExamConfigTemplateServiceImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/ExamConfigTemplateServiceImpl.java similarity index 94% rename from src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/SebExamConfigTemplateServiceImpl.java rename to src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/ExamConfigTemplateServiceImpl.java index 771ceb9c..47fd856b 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/SebExamConfigTemplateServiceImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/ExamConfigTemplateServiceImpl.java @@ -41,14 +41,14 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ConfigurationValueDAO; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.OrientationDAO; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ViewDAO; -import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SebExamConfigTemplateService; +import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.ExamConfigTemplateService; @Lazy @Service @WebServiceProfile -public class SebExamConfigTemplateServiceImpl implements SebExamConfigTemplateService { +public class ExamConfigTemplateServiceImpl implements ExamConfigTemplateService { - private static final Logger log = LoggerFactory.getLogger(SebExamConfigTemplateServiceImpl.class); + private static final Logger log = LoggerFactory.getLogger(ExamConfigTemplateServiceImpl.class); private final ViewDAO viewDAO; private final ConfigurationDAO configurationDAO; @@ -56,7 +56,7 @@ public class SebExamConfigTemplateServiceImpl implements SebExamConfigTemplateSe private final ConfigurationAttributeDAO configurationAttributeDAO; private final ConfigurationValueDAO configurationValueDAO; - protected SebExamConfigTemplateServiceImpl( + protected ExamConfigTemplateServiceImpl( final ViewDAO viewDAO, final ConfigurationDAO configurationDAO, final OrientationDAO orientationDAO, diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/ExamConfigImportHandler.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/ExamConfigXMLParser.java similarity index 92% rename from src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/ExamConfigImportHandler.java rename to src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/ExamConfigXMLParser.java index dccd99e0..3e6c8879 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/ExamConfigImportHandler.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/ExamConfigXMLParser.java @@ -27,12 +27,12 @@ import ch.ethz.seb.sebserver.gbl.Constants; import ch.ethz.seb.sebserver.gbl.model.sebconfig.AttributeType; import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute; import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue; -import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.impl.ExamConfigImportHandler.PListNode.Type; +import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.impl.ExamConfigXMLParser.PListNode.Type; import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.impl.converter.KioskModeConverter; -public class ExamConfigImportHandler extends DefaultHandler { +public class ExamConfigXMLParser extends DefaultHandler { - private static final Logger log = LoggerFactory.getLogger(ExamConfigImportHandler.class); + private static final Logger log = LoggerFactory.getLogger(ExamConfigXMLParser.class); private static final Set VALUE_ELEMENTS = new HashSet<>(Arrays.asList( Constants.XML_PLIST_BOOLEAN_FALSE, @@ -54,7 +54,7 @@ public class ExamConfigImportHandler extends DefaultHandler { private Boolean killExplorerShell = null; private Boolean createNewDesktop = null; - protected ExamConfigImportHandler( + public ExamConfigXMLParser( final Long institutionId, final Long configId, final Consumer valueConsumer, @@ -69,12 +69,16 @@ public class ExamConfigImportHandler extends DefaultHandler { @Override public void startDocument() throws SAXException { - log.debug("Start parsing document"); + if (log.isDebugEnabled()) { + log.debug("Start parsing document"); + } } @Override public void endDocument() throws SAXException { - log.debug("End parsing document"); + if (log.isDebugEnabled()) { + log.debug("End parsing document"); + } } @Override @@ -84,7 +88,9 @@ public class ExamConfigImportHandler extends DefaultHandler { final String qName, final Attributes attributes) throws SAXException { - log.debug("start element: {}", qName); + if (log.isDebugEnabled()) { + log.debug("start element: {}", qName); + } final Type type = Type.getType(qName); final PListNode top = (this.stack.isEmpty()) ? null : this.stack.peek(); @@ -269,11 +275,6 @@ public class ExamConfigImportHandler extends DefaultHandler { : top.name; final ConfigurationAttribute attribute = this.attributeResolver.apply(attrName); - if (attribute == null) { - log.warn("Import of unknown attribute. name={} value={}", attrName, top.value); - return; - } - if (top.inlineTable) { createInlineTableValue(top, attrName, attribute); return; @@ -308,7 +309,7 @@ public class ExamConfigImportHandler extends DefaultHandler { final int numColumns = columns.length; if (names.length != values.length) { throw new IllegalArgumentException( - "Failed to import InlineTable values. value/name array length mismatch"); + "Failed to get InlineTable values. value/name array length mismatch"); } String val = ""; @@ -359,7 +360,7 @@ public class ExamConfigImportHandler extends DefaultHandler { if (configurationValue != null) { if (log.isDebugEnabled()) { - log.debug("Save imported value: {} : {}", name, configurationValue); + log.debug("Put value: {} : {}", name, configurationValue); } this.valueConsumer.accept(configurationValue); @@ -377,7 +378,7 @@ public class ExamConfigImportHandler extends DefaultHandler { return handleKioskMode(name, listIndex, value); } - log.warn("Import of unknown attribute. name={} value={}", name, value); + log.warn("Unknown attribute. name={} value={}", name, value); return null; } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/AttributeValueConverterServiceImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/converter/AttributeValueConverterServiceImpl.java similarity index 97% rename from src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/AttributeValueConverterServiceImpl.java rename to src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/converter/AttributeValueConverterServiceImpl.java index 0115174b..72ace95c 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/AttributeValueConverterServiceImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/converter/AttributeValueConverterServiceImpl.java @@ -6,7 +6,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.impl; +package ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.impl.converter; import java.util.Collection; import java.util.HashMap; diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/init/AdditionalDefaultValueProvider.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/init/AdditionalDefaultValueProvider.java new file mode 100644 index 00000000..0aa858c9 --- /dev/null +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/init/AdditionalDefaultValueProvider.java @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET) + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +package ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.impl.init; + +import java.util.Collection; +import java.util.function.Function; + +import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute; +import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue; + +public interface AdditionalDefaultValueProvider { + + Collection getAdditionalDefaultValues( + final Long institutionId, + final Long configurationId, + final Function attributeResolver); + +} diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/init/ExamConfigInitServiceImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/init/ExamConfigInitServiceImpl.java new file mode 100644 index 00000000..3458c144 --- /dev/null +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/init/ExamConfigInitServiceImpl.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET) + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +package ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.impl.init; + +import java.util.Collection; +import java.util.function.Function; +import java.util.stream.Collectors; + +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Service; + +import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute; +import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue; +import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile; +import ch.ethz.seb.sebserver.gbl.util.Utils; +import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.ExamConfigInitService; + +@Lazy +@Service +@WebServiceProfile +public class ExamConfigInitServiceImpl implements ExamConfigInitService { + + private final Collection defaultValueProvider; + + public ExamConfigInitServiceImpl( + final Collection defaultValueProvider) { + + this.defaultValueProvider = Utils.immutableCollectionOf(defaultValueProvider); + } + + @Override + public Collection getAdditionalDefaultValues( + final Long institutionId, + final Long configurationId, + final Function attributeResolver) { + + return this.defaultValueProvider + .stream() + .flatMap(provider -> provider.getAdditionalDefaultValues( + institutionId, + configurationId, + attributeResolver) + .stream()) + .collect(Collectors.toList()); + } + +} diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/init/InitialPermittedProcesses.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/init/InitialPermittedProcesses.java new file mode 100644 index 00000000..ca67cd5c --- /dev/null +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/init/InitialPermittedProcesses.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET) + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +package ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.impl.init; + +import java.util.Collection; +import java.util.Collections; +import java.util.function.Function; +import java.util.stream.Collectors; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Component; + +import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute; +import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue; +import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile; + +@Lazy +@Component +@WebServiceProfile +public class InitialPermittedProcesses implements AdditionalDefaultValueProvider { + + private final String configFile; + private final XMLAttributeLoader xmlAttributeLoader; + private Collection cache = null; + + protected InitialPermittedProcesses( + final XMLAttributeLoader xmlAttributeLoader, + @Value("${sebserver.webservice.api.exam.config.init.permittedProcesses:config/additionalPermittedProcesses.xml}") final String configFile) { + + this.xmlAttributeLoader = xmlAttributeLoader; + this.configFile = configFile; + } + + @Override + public Collection getAdditionalDefaultValues( + final Long institutionId, + final Long configurationId, + final Function attributeResolver) { + + if (this.cache == null) { + this.cache = this.xmlAttributeLoader.loadFromXML( + institutionId, + configurationId, + attributeResolver, + this.configFile); + } + + if (this.cache == null) { + return Collections.emptyList(); + } + + return this.cache + .stream() + .map(value -> value.copyOf(institutionId, configurationId)) + .collect(Collectors.toList()); + } + +} diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/init/InitialProhibitedProcesses.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/init/InitialProhibitedProcesses.java new file mode 100644 index 00000000..01b09c54 --- /dev/null +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/init/InitialProhibitedProcesses.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET) + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +package ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.impl.init; + +import java.util.Collection; +import java.util.Collections; +import java.util.function.Function; +import java.util.stream.Collectors; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Component; + +import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute; +import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue; +import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile; + +@Lazy +@Component +@WebServiceProfile +public class InitialProhibitedProcesses implements AdditionalDefaultValueProvider { + + private final String configFile; + private final XMLAttributeLoader xmlAttributeLoader; + private Collection cache = null; + + protected InitialProhibitedProcesses( + final XMLAttributeLoader xmlAttributeLoader, + @Value("${sebserver.webservice.api.exam.config.init.prohibitedProcesses:config/initialProhibitedProcesses.xml}") final String configFile) { + + this.xmlAttributeLoader = xmlAttributeLoader; + this.configFile = configFile; + } + + @Override + public Collection getAdditionalDefaultValues( + final Long institutionId, + final Long configurationId, + final Function attributeResolver) { + + if (this.cache == null) { + this.cache = this.xmlAttributeLoader.loadFromXML( + institutionId, + configurationId, + attributeResolver, + this.configFile); + } + + if (this.cache == null) { + return Collections.emptyList(); + } + + return this.cache + .stream() + .map(value -> value.copyOf(institutionId, configurationId)) + .collect(Collectors.toList()); + } + +} diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/init/XMLAttributeLoader.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/init/XMLAttributeLoader.java new file mode 100644 index 00000000..27df9302 --- /dev/null +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/init/XMLAttributeLoader.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET) + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +package ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.impl.init; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.function.Function; + +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; + +import org.apache.tomcat.util.http.fileupload.IOUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.Lazy; +import org.springframework.core.io.ClassPathResource; +import org.springframework.stereotype.Component; + +import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute; +import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue; +import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile; +import ch.ethz.seb.sebserver.gbl.util.Utils; +import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.impl.ExamConfigXMLParser; + +@Lazy +@Component +@WebServiceProfile +public class XMLAttributeLoader { + + private static final Logger log = LoggerFactory.getLogger(XMLAttributeLoader.class); + + public Collection loadFromXML( + final Long institutionId, + final Long configurationId, + final Function attributeResolver, + final String xmlFileName) { + + InputStream inputStream; + try { + final ClassPathResource configFileResource = new ClassPathResource(xmlFileName); + inputStream = configFileResource.getInputStream(); + } catch (final Exception e) { + log.error("Failed to get config resources from: {}", xmlFileName, e); + return Collections.emptyList(); + } + + try { + + final Collection values = new ArrayList<>(); + + final ExamConfigXMLParser examConfigImportHandler = new ExamConfigXMLParser( + institutionId, + configurationId, + values::add, + attributeResolver); + + final SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); + final SAXParser parser = saxParserFactory.newSAXParser(); + parser.parse(inputStream, examConfigImportHandler); + + return Utils.immutableCollectionOf(values); + + } catch (final Exception e) { + log.error("Unexpected error while trying to get initial permitted processes", e); + return Collections.emptyList(); + } finally { + IOUtils.closeQuietly(inputStream); + } + } + +} diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/DecimalTypeValidator.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/validation/DecimalTypeValidator.java similarity index 96% rename from src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/DecimalTypeValidator.java rename to src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/validation/DecimalTypeValidator.java index 7709b253..441eac96 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/DecimalTypeValidator.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/validation/DecimalTypeValidator.java @@ -6,7 +6,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.impl; +package ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.impl.validation; import org.apache.commons.lang3.StringUtils; import org.springframework.context.annotation.Lazy; diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/ExitKeySequenceValidator.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/validation/ExitKeySequenceValidator.java similarity index 97% rename from src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/ExitKeySequenceValidator.java rename to src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/validation/ExitKeySequenceValidator.java index 3059f545..ba7bbe4b 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/ExitKeySequenceValidator.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/validation/ExitKeySequenceValidator.java @@ -6,7 +6,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.impl; +package ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.impl.validation; import java.util.Arrays; import java.util.List; diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/IntegerTypeValidator.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/validation/IntegerTypeValidator.java similarity index 95% rename from src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/IntegerTypeValidator.java rename to src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/validation/IntegerTypeValidator.java index a8cb59f3..80f67566 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/IntegerTypeValidator.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/validation/IntegerTypeValidator.java @@ -6,7 +6,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.impl; +package ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.impl.validation; import org.apache.commons.lang3.StringUtils; import org.springframework.context.annotation.Lazy; diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/WindowsSizeValidator.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/validation/WindowsSizeValidator.java similarity index 95% rename from src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/WindowsSizeValidator.java rename to src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/validation/WindowsSizeValidator.java index 98c35c61..f83d05c0 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/WindowsSizeValidator.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/validation/WindowsSizeValidator.java @@ -6,7 +6,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.impl; +package ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.impl.validation; import org.apache.commons.lang3.StringUtils; import org.springframework.context.annotation.Lazy; diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamSessionCacheService.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamSessionCacheService.java index 26f62535..ac22c147 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamSessionCacheService.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamSessionCacheService.java @@ -31,7 +31,7 @@ import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ClientEventRecord import ch.ethz.seb.sebserver.webservice.datalayer.batis.model.ClientEventRecord; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ClientConnectionDAO; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ExamDAO; -import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SebExamConfigService; +import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.ExamConfigService; /** Handles caching for exam session and defines caching for following object: * @@ -54,7 +54,7 @@ public class ExamSessionCacheService { private final ExamDAO examDAO; private final ClientConnectionDAO clientConnectionDAO; private final ClientIndicatorFactory clientIndicatorFactory; - private final SebExamConfigService sebExamConfigService; + private final ExamConfigService sebExamConfigService; private final ClientEventRecordMapper clientEventRecordMapper; private final ExamUpdateHandler examUpdateHandler; @@ -62,7 +62,7 @@ public class ExamSessionCacheService { final ExamDAO examDAO, final ClientConnectionDAO clientConnectionDAO, final ClientIndicatorFactory clientIndicatorFactory, - final SebExamConfigService sebExamConfigService, + final ExamConfigService sebExamConfigService, final ClientEventRecordMapper clientEventRecordMapper, final ExamUpdateHandler examUpdateHandler) { diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamSessionControlTask.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamSessionControlTask.java index 68dd1874..5b9f07ea 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamSessionControlTask.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamSessionControlTask.java @@ -33,6 +33,17 @@ class ExamSessionControlTask { private final Long examTimePrefix; private final Long examTimeSuffix; + // TODO for distributed systems we need a data-base based priority and flag that the individual + // tasks can check and set so that only one task is actually processing and the other just checks + // if a task is still processing and backup of not. + // Possibly this can be done with a overall master service setting on the DB in table webservice_server_info + + // TODO considering to have some caching of running exams end dates here to improve performance + // the end check task has than only to first update missing running exams and then + // check the exam ending within the cached end date of the exam. if an exam has ended by + // applying the check to the cached value, the process can double-check if the end date has + // no change and update if needed or end the exam and remove from cache. + protected ExamSessionControlTask( final ExamDAO examDAO, final ExamUpdateHandler examUpdateHandler, diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamSessionServiceImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamSessionServiceImpl.java index 14073aab..bd9e9fba 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamSessionServiceImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamSessionServiceImpl.java @@ -30,6 +30,7 @@ import ch.ethz.seb.sebserver.gbl.Constants; import ch.ethz.seb.sebserver.gbl.api.APIMessage; import ch.ethz.seb.sebserver.gbl.api.APIMessage.ErrorMessage; import ch.ethz.seb.sebserver.gbl.model.exam.Exam; +import ch.ethz.seb.sebserver.gbl.model.exam.Exam.ExamStatus; import ch.ethz.seb.sebserver.gbl.model.session.ClientConnection; import ch.ethz.seb.sebserver.gbl.model.session.ClientConnectionData; import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile; @@ -198,7 +199,9 @@ public class ExamSessionServiceImpl implements ExamSessionService { final FilterMap filterMap, final Predicate predicate) { - filterMap.putIfAbsent(Exam.FILTER_ATTR_ACTIVE, Constants.TRUE_STRING); + filterMap + .putIfAbsent(Exam.FILTER_ATTR_ACTIVE, Constants.TRUE_STRING) + .putIfAbsent(Exam.FILTER_ATTR_STATUS, ExamStatus.RUNNING.name()); return this.examDAO.allMatching(filterMap, predicate) .map(col -> col.stream() diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamUpdateHandler.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamUpdateHandler.java index 722a7d0a..a0dfed68 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamUpdateHandler.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamUpdateHandler.java @@ -32,7 +32,7 @@ import ch.ethz.seb.sebserver.webservice.WebserviceInfo; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ExamDAO; import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPIService; import ch.ethz.seb.sebserver.webservice.servicelayer.lms.SebRestrictionData; -import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SebExamConfigService; +import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.ExamConfigService; @Lazy @Service @@ -42,14 +42,14 @@ class ExamUpdateHandler { private static final Logger log = LoggerFactory.getLogger(ExamUpdateHandler.class); private final ExamDAO examDAO; - private final SebExamConfigService sebExamConfigService; + private final ExamConfigService sebExamConfigService; private final LmsAPIService lmsAPIService; private final String updatePrefix; private final Long examTimeSuffix; public ExamUpdateHandler( final ExamDAO examDAO, - final SebExamConfigService sebExamConfigService, + final ExamConfigService sebExamConfigService, final LmsAPIService lmsAPIService, final WebserviceInfo webserviceInfo, @Value("${sebserver.webservice.api.exam.time-suffix:3600000}") final Long examTimeSuffix) { 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 3fc92b20..252d9638 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 @@ -66,8 +66,8 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.OrientationDAO; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserActivityLogDAO; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ViewDAO; -import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SebExamConfigService; -import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SebExamConfigTemplateService; +import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.ExamConfigService; +import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.ExamConfigTemplateService; import ch.ethz.seb.sebserver.webservice.servicelayer.validation.BeanValidationService; @WebServiceProfile @@ -81,8 +81,8 @@ public class ConfigurationNodeController extends EntityController { private final ExamDAO examDAO; private final UserDAO userDAO; private final LmsAPIService lmsAPIService; - private final SebExamConfigService sebExamConfigService; + private final ExamConfigService sebExamConfigService; private final ExamSessionService examSessionService; private final ExamConfigUpdateService examConfigUpdateService; @@ -88,7 +88,7 @@ public class ExamAdministrationController extends EntityController { final BeanValidationService beanValidationService, final LmsAPIService lmsAPIService, final UserDAO userDAO, - final SebExamConfigService sebExamConfigService, + final ExamConfigService sebExamConfigService, final ExamSessionService examSessionService, final ExamConfigUpdateService examConfigUpdateService) { diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/SebClientConfigController.java b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/SebClientConfigController.java index 8914e46c..617be284 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/SebClientConfigController.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/SebClientConfigController.java @@ -44,7 +44,7 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.Authorization import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.BulkActionService; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.SebClientConfigDAO; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserActivityLogDAO; -import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SebClientConfigService; +import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.ClientConfigService; import ch.ethz.seb.sebserver.webservice.servicelayer.validation.BeanValidationService; @WebServiceProfile @@ -53,7 +53,7 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.validation.BeanValidationSe @RequestMapping("${sebserver.webservice.api.admin.endpoint}" + API.SEB_CLIENT_CONFIG_ENDPOINT) public class SebClientConfigController extends ActivatableEntityController { - private final SebClientConfigService sebClientConfigService; + private final ClientConfigService sebClientConfigService; public SebClientConfigController( final SebClientConfigDAO sebClientConfigDAO, @@ -62,7 +62,7 @@ public class SebClientConfigController extends ActivatableEntityController + + + + permittedProcesses + + + active + + allowUserToChooseApp + + allowedExecutables + + arguments + + autostart + + description + + executable + firefox.exe + iconInTaskbar + + identifier + Firefox + os + 1 + path + ../xulrunner/ + runInBackground + + strongKill + + title + SEB + windowHandlingProcess + + originalName + firefox.exe + + + + \ No newline at end of file diff --git a/src/main/resources/config/initialProhibitedProcesses.xml b/src/main/resources/config/initialProhibitedProcesses.xml new file mode 100644 index 00000000..309d048d --- /dev/null +++ b/src/main/resources/config/initialProhibitedProcesses.xml @@ -0,0 +1,361 @@ + + + + + prohibitedProcesses + + + active + + currentUser + + strongKill + + os + 1 + executable + join.me + originalName + join.me + description + + identifier + + windowHandlingProcess + + user + + + + active + + currentUser + + strongKill + + os + 1 + executable + RPCSuite + originalName + RPCSuite + description + + identifier + + windowHandlingProcess + + user + + + + active + + currentUser + + strongKill + + os + 1 + executable + RPCService + originalName + RPCService + description + + identifier + + windowHandlingProcess + + user + + + + active + + currentUser + + strongKill + + os + 1 + executable + RemotePCDesktop + originalName + RemotePCDesktop + description + + identifier + + windowHandlingProcess + + user + + + + active + + currentUser + + strongKill + + os + 1 + executable + beamyourscreen-host + originalName + beamyourscreen-host + description + + identifier + + windowHandlingProcess + + user + + + + active + + currentUser + + strongKill + + os + 1 + executable + AeroAdmin + originalName + AeroAdmin + description + + identifier + + windowHandlingProcess + + user + + + + active + + currentUser + + strongKill + + os + 1 + executable + Mikogo-host + originalName + Mikogo-host + description + + identifier + + windowHandlingProcess + + user + + + + active + + currentUser + + strongKill + + os + 1 + executable + chromoting + originalName + chromoting + description + + identifier + + windowHandlingProcess + + user + + + + active + + currentUser + + strongKill + + os + 1 + executable + vncserverui + originalName + vncserverui + description + + identifier + + windowHandlingProcess + + user + + + + active + + currentUser + + strongKill + + os + 1 + executable + vncviewer + originalName + vncviewer + description + + identifier + + windowHandlingProcess + + user + + + + active + + currentUser + + strongKill + + os + 1 + executable + vncserver + originalName + vncserver + description + + identifier + + windowHandlingProcess + + user + + + + active + + currentUser + + strongKill + + os + 1 + executable + TeamViewer + originalName + TeamViewer + description + + identifier + + windowHandlingProcess + + user + + + + active + + currentUser + + strongKill + + os + 1 + executable + GotoMeetingWinStore + originalName + GotoMeetingWinStore + description + + identifier + + windowHandlingProcess + + user + + + + active + + currentUser + + strongKill + + os + 1 + executable + g2mcomm.exe + originalName + g2mcomm.exe + description + + identifier + + windowHandlingProcess + + user + + + + active + + currentUser + + strongKill + + os + 1 + executable + SkypeHost + originalName + SkypeHost + description + + identifier + + windowHandlingProcess + + user + + + + active + + currentUser + + strongKill + + os + 1 + executable + Skype + originalName + Skype + description + + identifier + + windowHandlingProcess + + user + + + + + \ No newline at end of file diff --git a/src/test/java/ch/ethz/seb/sebserver/webservice/integration/api/exam/ExamAPIIntegrationTester.java b/src/test/java/ch/ethz/seb/sebserver/webservice/integration/api/exam/ExamAPIIntegrationTester.java index 05ffee1a..4204df31 100644 --- a/src/test/java/ch/ethz/seb/sebserver/webservice/integration/api/exam/ExamAPIIntegrationTester.java +++ b/src/test/java/ch/ethz/seb/sebserver/webservice/integration/api/exam/ExamAPIIntegrationTester.java @@ -50,7 +50,7 @@ import ch.ethz.seb.sebserver.SEBServer; import ch.ethz.seb.sebserver.WebSecurityConfig; import ch.ethz.seb.sebserver.gbl.api.API; import ch.ethz.seb.sebserver.gbl.api.JSONMapper; -import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SebClientConfigService; +import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.ClientConfigService; import ch.ethz.seb.sebserver.webservice.weblayer.oauth.AdminAPIClientDetails; import ch.ethz.seb.sebserver.webservice.weblayer.oauth.WebClientDetailsService; import ch.ethz.seb.sebserver.webservice.weblayer.oauth.WebserviceResourceConfiguration; @@ -287,7 +287,7 @@ public abstract class ExamAPIIntegrationTester { @Autowired AdminAPIClientDetails adminClientDetails; @Autowired - SebClientConfigService sebClientConfigService; + ClientConfigService sebClientConfigService; @Autowired @Qualifier(WebSecurityConfig.CLIENT_PASSWORD_ENCODER_BEAN_NAME) private PasswordEncoder clientPasswordEncoder; diff --git a/src/test/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/ExamConfigImportHandlerTest.java b/src/test/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/ExamConfigImportHandlerTest.java index 0a28c1af..df56431f 100644 --- a/src/test/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/ExamConfigImportHandlerTest.java +++ b/src/test/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/ExamConfigImportHandlerTest.java @@ -40,7 +40,7 @@ public class ExamConfigImportHandlerTest { @Test public void simpleStringValueTest() throws Exception { final ValueCollector valueCollector = new ValueCollector(); - final ExamConfigImportHandler candidate = new ExamConfigImportHandler( + final ExamConfigXMLParser candidate = new ExamConfigXMLParser( 1L, 1L, valueCollector, @@ -72,7 +72,7 @@ public class ExamConfigImportHandlerTest { @Test public void simpleIntegerValueTest() throws Exception { final ValueCollector valueCollector = new ValueCollector(); - final ExamConfigImportHandler candidate = new ExamConfigImportHandler( + final ExamConfigXMLParser candidate = new ExamConfigXMLParser( 1L, 1L, valueCollector, @@ -104,7 +104,7 @@ public class ExamConfigImportHandlerTest { @Test public void simpleBooleanValueTest() throws Exception { final ValueCollector valueCollector = new ValueCollector(); - final ExamConfigImportHandler candidate = new ExamConfigImportHandler( + final ExamConfigXMLParser candidate = new ExamConfigXMLParser( 1L, 1L, valueCollector, @@ -135,7 +135,7 @@ public class ExamConfigImportHandlerTest { @Test public void arrayOfStringValueTest() throws Exception { final ValueCollector valueCollector = new ValueCollector(); - final ExamConfigImportHandler candidate = new ExamConfigImportHandler( + final ExamConfigXMLParser candidate = new ExamConfigXMLParser( 1L, 1L, valueCollector, @@ -186,7 +186,7 @@ public class ExamConfigImportHandlerTest { attrNamesCollector.add(attrName); return attributeResolver.apply(attrName); }; - final ExamConfigImportHandler candidate = new ExamConfigImportHandler( + final ExamConfigXMLParser candidate = new ExamConfigXMLParser( 1L, 1L, valueCollector, @@ -255,7 +255,7 @@ public class ExamConfigImportHandlerTest { attrNamesCollector.add(attrName); return attributeResolver.apply(attrName); }; - final ExamConfigImportHandler candidate = new ExamConfigImportHandler( + final ExamConfigXMLParser candidate = new ExamConfigXMLParser( 1L, 1L, valueCollector, diff --git a/src/test/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/converter/TableConverterTest.java b/src/test/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/converter/TableConverterTest.java index 32d25dad..db92ba0c 100644 --- a/src/test/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/converter/TableConverterTest.java +++ b/src/test/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/converter/TableConverterTest.java @@ -28,7 +28,6 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ConfigurationAttributeD import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ConfigurationValueDAO; import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.AttributeValueConverter; import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.AttributeValueConverterService; -import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.impl.AttributeValueConverterServiceImpl; public class TableConverterTest {