SEBSERV-94 implementation and some code cleanup

This commit is contained in:
anhefti 2019-11-20 15:08:59 +01:00
parent 2e3594b95b
commit f379114b46
42 changed files with 984 additions and 133 deletions

View file

@ -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();

View file

@ -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;
}
}

View file

@ -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<ApplicationReadyEvent> {
public class WebserviceInit implements ApplicationListener<ApplicationReadyEvent> {
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<ApplicationReadyEvent
log.info("{}", this.webserviceInfo);
// TODO whatever has to be initialized for the web-service component right after startup comes here
// TODO integration of Flyway for database initialization and migration: https://flywaydb.org
// see also https://flywaydb.org/getstarted/firststeps/api
}
@Lazy
@Bean
public JNCryptor jnCryptor() {
final AES256JNCryptor aes256jnCryptor = new AES256JNCryptor();
aes256jnCryptor.setPBKDFIterations(Constants.JN_CRYPTOR_ITERATIONS);
return aes256jnCryptor;
@PreDestroy
public void gracefulShutdown() {
log.info("**** Gracefully Shutdown of SEB Server instance {} ****", this.webserviceInfo.getHostAddress());
}
}

View file

@ -13,6 +13,7 @@ import java.util.Collection;
import org.springframework.cache.annotation.CacheEvict;
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.util.Result;
import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.BulkActionSupportDAO;
import ch.ethz.seb.sebserver.webservice.servicelayer.session.impl.ExamSessionCacheService;
@ -40,6 +41,8 @@ public interface ExamDAO extends ActivatableEntityDAO<Exam, Exam>, BulkActionSup
* @return a Result containing the Exam by a given ClientConnection id or refer to an error if happened */
Result<Exam> byClientConnection(Long connectionId);
Result<Collection<Long>> getExamIdsForStatus(Long institutionId, ExamStatus status);
Result<Collection<Exam>> allForRunCheck();
Result<Collection<Exam>> allForEndCheck();

View file

@ -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<Collection<EntityKey>> delete(Set<EntityKey> all);

View file

@ -238,7 +238,7 @@ public class ConfigurationAttributeDAOImpl implements ConfigurationAttributeDAO
});
}
private Result<ConfigurationAttributeRecord> recordById(final Long id) {
Result<ConfigurationAttributeRecord> 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<ConfigurationAttribute> toDomainModel(final ConfigurationAttributeRecord record) {
static Result<ConfigurationAttribute> toDomainModel(final ConfigurationAttributeRecord record) {
return Result.tryCatch(() -> new ConfigurationAttribute(
record.getId(),
record.getParentId(),

View file

@ -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<ConfigurationValueRecord> 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<String, ConfigurationAttribute> 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<ConfigurationValueRecord> 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) {

View file

@ -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<Collection<Long>> 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<Collection<Exam>> allForRunCheck() {

View file

@ -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";

View file

@ -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<ConfigurationValue> getAdditionalDefaultValues(
Long institutionId,
Long configurationId,
final Function<String, ConfigurationAttribute> attributeResolver);
}

View file

@ -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

View file

@ -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<List<TemplateAttribute>> getTemplateAttributes(
final Long institutionId,

View file

@ -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,

View file

@ -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

View file

@ -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,

View file

@ -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,

View file

@ -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<String> 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<ConfigurationValue> 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;
}

View file

@ -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;

View file

@ -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<ConfigurationValue> getAdditionalDefaultValues(
final Long institutionId,
final Long configurationId,
final Function<String, ConfigurationAttribute> attributeResolver);
}

View file

@ -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<AdditionalDefaultValueProvider> defaultValueProvider;
public ExamConfigInitServiceImpl(
final Collection<AdditionalDefaultValueProvider> defaultValueProvider) {
this.defaultValueProvider = Utils.immutableCollectionOf(defaultValueProvider);
}
@Override
public Collection<ConfigurationValue> getAdditionalDefaultValues(
final Long institutionId,
final Long configurationId,
final Function<String, ConfigurationAttribute> attributeResolver) {
return this.defaultValueProvider
.stream()
.flatMap(provider -> provider.getAdditionalDefaultValues(
institutionId,
configurationId,
attributeResolver)
.stream())
.collect(Collectors.toList());
}
}

View file

@ -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<ConfigurationValue> 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<ConfigurationValue> getAdditionalDefaultValues(
final Long institutionId,
final Long configurationId,
final Function<String, ConfigurationAttribute> 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());
}
}

View file

@ -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<ConfigurationValue> 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<ConfigurationValue> getAdditionalDefaultValues(
final Long institutionId,
final Long configurationId,
final Function<String, ConfigurationAttribute> 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());
}
}

View file

@ -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<ConfigurationValue> loadFromXML(
final Long institutionId,
final Long configurationId,
final Function<String, ConfigurationAttribute> 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<ConfigurationValue> 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);
}
}
}

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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) {

View file

@ -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,

View file

@ -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<Exam> 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()

View file

@ -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) {

View file

@ -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<ConfigurationN
private final ConfigurationDAO configurationDAO;
private final ViewDAO viewDAO;
private final OrientationDAO orientationDAO;
private final SebExamConfigService sebExamConfigService;
private final SebExamConfigTemplateService sebExamConfigTemplateService;
private final ExamConfigService sebExamConfigService;
private final ExamConfigTemplateService sebExamConfigTemplateService;
protected ConfigurationNodeController(
final AuthorizationService authorization,
@ -94,8 +94,8 @@ public class ConfigurationNodeController extends EntityController<ConfigurationN
final ConfigurationDAO configurationDAO,
final ViewDAO viewDAO,
final OrientationDAO orientationDAO,
final SebExamConfigService sebExamConfigService,
final SebExamConfigTemplateService sebExamConfigTemplateService) {
final ExamConfigService sebExamConfigService,
final ExamConfigTemplateService sebExamConfigTemplateService) {
super(authorization,
bulkActionService,

View file

@ -35,7 +35,7 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.BulkActionServic
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ConfigurationDAO;
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ConfigurationValueDAO;
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserActivityLogDAO;
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.validation.BeanValidationService;
@WebServiceProfile
@ -45,7 +45,7 @@ public class ConfigurationValueController extends EntityController<Configuration
private final ConfigurationDAO configurationDAO;
private final ConfigurationValueDAO configurationValueDAO;
private final SebExamConfigService sebExamConfigService;
private final ExamConfigService sebExamConfigService;
protected ConfigurationValueController(
final AuthorizationService authorization,
@ -55,7 +55,7 @@ public class ConfigurationValueController extends EntityController<Configuration
final PaginationService paginationService,
final BeanValidationService beanValidationService,
final ConfigurationDAO configurationDAO,
final SebExamConfigService sebExamConfigService) {
final ExamConfigService sebExamConfigService) {
super(authorization,
bulkActionService,

View file

@ -60,7 +60,7 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap;
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserActivityLogDAO;
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserDAO;
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPIService;
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.session.ExamConfigUpdateService;
import ch.ethz.seb.sebserver.webservice.servicelayer.session.ExamSessionService;
import ch.ethz.seb.sebserver.webservice.servicelayer.validation.BeanValidationService;
@ -75,7 +75,7 @@ public class ExamAdministrationController extends EntityController<Exam, Exam> {
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<Exam, Exam> {
final BeanValidationService beanValidationService,
final LmsAPIService lmsAPIService,
final UserDAO userDAO,
final SebExamConfigService sebExamConfigService,
final ExamConfigService sebExamConfigService,
final ExamSessionService examSessionService,
final ExamConfigUpdateService examConfigUpdateService) {

View file

@ -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<SebClientConfig, SebClientConfig> {
private final SebClientConfigService sebClientConfigService;
private final ClientConfigService sebClientConfigService;
public SebClientConfigController(
final SebClientConfigDAO sebClientConfigDAO,
@ -62,7 +62,7 @@ public class SebClientConfigController extends ActivatableEntityController<SebCl
final BulkActionService bulkActionService,
final PaginationService paginationService,
final BeanValidationService beanValidationService,
final SebClientConfigService sebClientConfigService) {
final ClientConfigService sebClientConfigService) {
super(authorization,
bulkActionService,

View file

@ -18,7 +18,7 @@ import org.springframework.security.oauth2.provider.ClientRegistrationException;
import org.springframework.stereotype.Component;
import ch.ethz.seb.sebserver.gbl.util.Result;
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.SebClientConfigService;
import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.ClientConfigService;
/** A ClientDetailsService to manage different API clients of SEB Server webservice API.
*
@ -32,12 +32,12 @@ public class WebClientDetailsService implements ClientDetailsService {
private static final Logger log = LoggerFactory.getLogger(WebClientDetailsService.class);
private final SebClientConfigService sebClientConfigService;
private final ClientConfigService sebClientConfigService;
private final AdminAPIClientDetails adminClientDetails;
public WebClientDetailsService(
final AdminAPIClientDetails adminClientDetails,
final SebClientConfigService sebClientConfigService) {
final ClientConfigService sebClientConfigService) {
this.adminClientDetails = adminClientDetails;
this.sebClientConfigService = sebClientConfigService;

View file

@ -24,6 +24,8 @@ sebserver.webservice.http.redirect.gui=/gui
sebserver.webservice.api.admin.endpoint=/admin-api/v1
sebserver.webservice.api.admin.accessTokenValiditySeconds=3600
sebserver.webservice.api.admin.refreshTokenValiditySeconds=-1
sebserver.webservice.api.exam.config.init.permittedProcesses=config/initialPermittedProcesses.xml
sebserver.webservice.api.exam.config.init.prohibitedProcesses=config/initialProhibitedProcesses.xml
sebserver.webservice.api.exam.update-interval=1 * * * * *
sebserver.webservice.api.exam.time-prefix=0
sebserver.webservice.api.exam.time-suffix=0

View file

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>permittedProcesses</key>
<array>
<dict>
<key>active</key>
<true />
<key>allowUserToChooseApp</key>
<false />
<key>allowedExecutables</key>
<string />
<key>arguments</key>
<array></array>
<key>autostart</key>
<true />
<key>description</key>
<string />
<key>executable</key>
<string>firefox.exe</string>
<key>iconInTaskbar</key>
<true />
<key>identifier</key>
<string>Firefox</string>
<key>os</key>
<integer>1</integer>
<key>path</key>
<string>../xulrunner/</string>
<key>runInBackground</key>
<false />
<key>strongKill</key>
<true />
<key>title</key>
<string>SEB</string>
<key>windowHandlingProcess</key>
<string />
<key>originalName</key>
<string>firefox.exe</string>
</dict>
</array>
</dict>
</plist>

View file

@ -0,0 +1,361 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>prohibitedProcesses</key>
<array>
<dict>
<key>active</key>
<true />
<key>currentUser</key>
<true />
<key>strongKill</key>
<false />
<key>os</key>
<integer>1</integer>
<key>executable</key>
<string>join.me</string>
<key>originalName</key>
<string>join.me</string>
<key>description</key>
<string />
<key>identifier</key>
<string />
<key>windowHandlingProcess</key>
<string />
<key>user</key>
<string />
</dict>
<dict>
<key>active</key>
<true />
<key>currentUser</key>
<true />
<key>strongKill</key>
<false />
<key>os</key>
<integer>1</integer>
<key>executable</key>
<string>RPCSuite</string>
<key>originalName</key>
<string>RPCSuite</string>
<key>description</key>
<string />
<key>identifier</key>
<string />
<key>windowHandlingProcess</key>
<string />
<key>user</key>
<string />
</dict>
<dict>
<key>active</key>
<true />
<key>currentUser</key>
<true />
<key>strongKill</key>
<false />
<key>os</key>
<integer>1</integer>
<key>executable</key>
<string>RPCService</string>
<key>originalName</key>
<string>RPCService</string>
<key>description</key>
<string />
<key>identifier</key>
<string />
<key>windowHandlingProcess</key>
<string />
<key>user</key>
<string />
</dict>
<dict>
<key>active</key>
<true />
<key>currentUser</key>
<true />
<key>strongKill</key>
<false />
<key>os</key>
<integer>1</integer>
<key>executable</key>
<string>RemotePCDesktop</string>
<key>originalName</key>
<string>RemotePCDesktop</string>
<key>description</key>
<string />
<key>identifier</key>
<string />
<key>windowHandlingProcess</key>
<string />
<key>user</key>
<string />
</dict>
<dict>
<key>active</key>
<true />
<key>currentUser</key>
<true />
<key>strongKill</key>
<false />
<key>os</key>
<integer>1</integer>
<key>executable</key>
<string>beamyourscreen-host</string>
<key>originalName</key>
<string>beamyourscreen-host</string>
<key>description</key>
<string />
<key>identifier</key>
<string />
<key>windowHandlingProcess</key>
<string />
<key>user</key>
<string />
</dict>
<dict>
<key>active</key>
<true />
<key>currentUser</key>
<true />
<key>strongKill</key>
<false />
<key>os</key>
<integer>1</integer>
<key>executable</key>
<string>AeroAdmin</string>
<key>originalName</key>
<string>AeroAdmin</string>
<key>description</key>
<string />
<key>identifier</key>
<string />
<key>windowHandlingProcess</key>
<string />
<key>user</key>
<string />
</dict>
<dict>
<key>active</key>
<true />
<key>currentUser</key>
<true />
<key>strongKill</key>
<false />
<key>os</key>
<integer>1</integer>
<key>executable</key>
<string>Mikogo-host</string>
<key>originalName</key>
<string>Mikogo-host</string>
<key>description</key>
<string />
<key>identifier</key>
<string />
<key>windowHandlingProcess</key>
<string />
<key>user</key>
<string />
</dict>
<dict>
<key>active</key>
<true />
<key>currentUser</key>
<true />
<key>strongKill</key>
<false />
<key>os</key>
<integer>1</integer>
<key>executable</key>
<string>chromoting</string>
<key>originalName</key>
<string>chromoting</string>
<key>description</key>
<string />
<key>identifier</key>
<string />
<key>windowHandlingProcess</key>
<string />
<key>user</key>
<string />
</dict>
<dict>
<key>active</key>
<true />
<key>currentUser</key>
<true />
<key>strongKill</key>
<false />
<key>os</key>
<integer>1</integer>
<key>executable</key>
<string>vncserverui</string>
<key>originalName</key>
<string>vncserverui</string>
<key>description</key>
<string />
<key>identifier</key>
<string />
<key>windowHandlingProcess</key>
<string />
<key>user</key>
<string />
</dict>
<dict>
<key>active</key>
<true />
<key>currentUser</key>
<true />
<key>strongKill</key>
<false />
<key>os</key>
<integer>1</integer>
<key>executable</key>
<string>vncviewer</string>
<key>originalName</key>
<string>vncviewer</string>
<key>description</key>
<string />
<key>identifier</key>
<string />
<key>windowHandlingProcess</key>
<string />
<key>user</key>
<string />
</dict>
<dict>
<key>active</key>
<true />
<key>currentUser</key>
<true />
<key>strongKill</key>
<false />
<key>os</key>
<integer>1</integer>
<key>executable</key>
<string>vncserver</string>
<key>originalName</key>
<string>vncserver</string>
<key>description</key>
<string />
<key>identifier</key>
<string />
<key>windowHandlingProcess</key>
<string />
<key>user</key>
<string />
</dict>
<dict>
<key>active</key>
<true />
<key>currentUser</key>
<true />
<key>strongKill</key>
<false />
<key>os</key>
<integer>1</integer>
<key>executable</key>
<string>TeamViewer</string>
<key>originalName</key>
<string>TeamViewer</string>
<key>description</key>
<string />
<key>identifier</key>
<string />
<key>windowHandlingProcess</key>
<string />
<key>user</key>
<string />
</dict>
<dict>
<key>active</key>
<true />
<key>currentUser</key>
<true />
<key>strongKill</key>
<false />
<key>os</key>
<integer>1</integer>
<key>executable</key>
<string>GotoMeetingWinStore</string>
<key>originalName</key>
<string>GotoMeetingWinStore</string>
<key>description</key>
<string />
<key>identifier</key>
<string />
<key>windowHandlingProcess</key>
<string />
<key>user</key>
<string />
</dict>
<dict>
<key>active</key>
<true />
<key>currentUser</key>
<true />
<key>strongKill</key>
<false />
<key>os</key>
<integer>1</integer>
<key>executable</key>
<string>g2mcomm.exe</string>
<key>originalName</key>
<string>g2mcomm.exe</string>
<key>description</key>
<string />
<key>identifier</key>
<string />
<key>windowHandlingProcess</key>
<string />
<key>user</key>
<string />
</dict>
<dict>
<key>active</key>
<true />
<key>currentUser</key>
<true />
<key>strongKill</key>
<false />
<key>os</key>
<integer>1</integer>
<key>executable</key>
<string>SkypeHost</string>
<key>originalName</key>
<string>SkypeHost</string>
<key>description</key>
<string />
<key>identifier</key>
<string />
<key>windowHandlingProcess</key>
<string />
<key>user</key>
<string />
</dict>
<dict>
<key>active</key>
<true />
<key>currentUser</key>
<true />
<key>strongKill</key>
<false />
<key>os</key>
<integer>1</integer>
<key>executable</key>
<string>Skype</string>
<key>originalName</key>
<string>Skype</string>
<key>description</key>
<string />
<key>identifier</key>
<string />
<key>windowHandlingProcess</key>
<string />
<key>user</key>
<string />
</dict>
</array>
</dict>
</plist>

View file

@ -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;

View file

@ -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,

View file

@ -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 {