SEBSERV-351 implementation (no tests yet)
This commit is contained in:
parent
f131276bdd
commit
bb0c834676
17 changed files with 226 additions and 20 deletions
|
@ -28,4 +28,10 @@ public interface ConfigurationAttributeDAO extends EntityDAO<ConfigurationAttrib
|
||||||
* @return Result refer to a collection of child ConfigurationAttribute or to an error if happened */
|
* @return Result refer to a collection of child ConfigurationAttribute or to an error if happened */
|
||||||
Result<Collection<ConfigurationAttribute>> allChildAttributes(final Long parentId);
|
Result<Collection<ConfigurationAttribute>> allChildAttributes(final Long parentId);
|
||||||
|
|
||||||
|
/** Use this to geht an attribute identifier by attribute name
|
||||||
|
*
|
||||||
|
* @param configAttributeName the attribute name
|
||||||
|
* @return Result refer to the attribute identifier or to an error if happened */
|
||||||
|
Result<Long> getAttributeIdByName(String configAttributeName);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,4 +71,11 @@ public interface ConfigurationValueDAO extends EntityDAO<ConfigurationValue, Con
|
||||||
Long configurationId,
|
Long configurationId,
|
||||||
Long attributeId);
|
Long attributeId);
|
||||||
|
|
||||||
|
/** Use this to get a specific SEB Settings attribute value.
|
||||||
|
*
|
||||||
|
* @param configId the configuration identifier for the value
|
||||||
|
* @param attrId the attribute identifier
|
||||||
|
* @return the String value of the SEB setting attribute */
|
||||||
|
Result<String> getConfigAttributeValue(Long configId, Long attrId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,6 +93,19 @@ public class ConfigurationAttributeDAOImpl implements ConfigurationAttributeDAO
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public Result<Long> getAttributeIdByName(final String attributeName) {
|
||||||
|
return Result.tryCatch(() -> this.configurationAttributeRecordMapper
|
||||||
|
.selectByExample()
|
||||||
|
.where(
|
||||||
|
ConfigurationAttributeRecordDynamicSqlSupport.name,
|
||||||
|
SqlBuilder.isEqualTo(attributeName))
|
||||||
|
.build()
|
||||||
|
.execute()
|
||||||
|
.get(0).getId());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
public Result<Collection<ConfigurationAttribute>> allMatching(
|
public Result<Collection<ConfigurationAttribute>> allMatching(
|
||||||
|
|
|
@ -19,6 +19,7 @@ import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -122,6 +123,34 @@ public class ConfigurationValueDAOImpl implements ConfigurationValueDAO {
|
||||||
.collect(Collectors.toList()));
|
.collect(Collectors.toList()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Result<String> getConfigAttributeValue(final Long configId, final Long attrId) {
|
||||||
|
return Result.tryCatch(() -> {
|
||||||
|
|
||||||
|
final List<ConfigurationValueRecord> records = this.configurationValueRecordMapper.selectByExample()
|
||||||
|
.where(
|
||||||
|
ConfigurationValueRecordDynamicSqlSupport.configurationId,
|
||||||
|
isEqualTo(configId))
|
||||||
|
|
||||||
|
.and(
|
||||||
|
ConfigurationValueRecordDynamicSqlSupport.configurationAttributeId,
|
||||||
|
SqlBuilder.isEqualTo(attrId))
|
||||||
|
.build()
|
||||||
|
.execute();
|
||||||
|
|
||||||
|
if (records == null) {
|
||||||
|
throw new NoSuchElementException(
|
||||||
|
"No SEB setting attribute value found for configId: " + configId + " attrId: " + attrId);
|
||||||
|
}
|
||||||
|
if (records.size() > 1) {
|
||||||
|
log.warn("Found more then one attribute value for configId: {}, attrId:{} select first one.", configId,
|
||||||
|
attrId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return records.get(0).getValue();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
public Result<Collection<ConfigurationValue>> allOf(final Set<Long> pks) {
|
public Result<Collection<ConfigurationValue>> allOf(final Set<Long> pks) {
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 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.exam;
|
||||||
|
|
||||||
|
public interface ExamConfigurationValueService {
|
||||||
|
|
||||||
|
/** Get the actual SEB settings attribute value for the exam configuration mapped as default configuration
|
||||||
|
* to the given exam
|
||||||
|
*
|
||||||
|
* @param examId The exam identifier
|
||||||
|
* @param configAttributeName The name of the SEB settings attribute
|
||||||
|
* @return The current value of the above SEB settings attribute and given exam. */
|
||||||
|
String getMappedDefaultConfigAttributeValue(Long examId, String configAttributeName);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 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.exam.impl;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ConfigurationAttributeDAO;
|
||||||
|
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.ExamConfigurationMapDAO;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.servicelayer.exam.ExamConfigurationValueService;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class ExamConfigurationValueServiceImpl implements ExamConfigurationValueService {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(ExamConfigurationValueServiceImpl.class);
|
||||||
|
|
||||||
|
private final ExamConfigurationMapDAO examConfigurationMapDAO;
|
||||||
|
private final ConfigurationDAO configurationDAO;
|
||||||
|
private final ConfigurationAttributeDAO configurationAttributeDAO;
|
||||||
|
private final ConfigurationValueDAO configurationValueDAO;
|
||||||
|
|
||||||
|
public ExamConfigurationValueServiceImpl(
|
||||||
|
final ExamConfigurationMapDAO examConfigurationMapDAO,
|
||||||
|
final ConfigurationDAO configurationDAO,
|
||||||
|
final ConfigurationAttributeDAO configurationAttributeDAO,
|
||||||
|
final ConfigurationValueDAO configurationValueDAO) {
|
||||||
|
|
||||||
|
this.examConfigurationMapDAO = examConfigurationMapDAO;
|
||||||
|
this.configurationDAO = configurationDAO;
|
||||||
|
this.configurationAttributeDAO = configurationAttributeDAO;
|
||||||
|
this.configurationValueDAO = configurationValueDAO;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getMappedDefaultConfigAttributeValue(final Long examId, final String configAttributeName) {
|
||||||
|
try {
|
||||||
|
|
||||||
|
final Long configId = this.examConfigurationMapDAO
|
||||||
|
.getDefaultConfigurationNode(examId)
|
||||||
|
.flatMap(nodeId -> this.configurationDAO.getConfigurationLastStableVersion(nodeId))
|
||||||
|
.map(config -> config.id)
|
||||||
|
.getOrThrow();
|
||||||
|
|
||||||
|
final Long attrId = this.configurationAttributeDAO
|
||||||
|
.getAttributeIdByName(configAttributeName)
|
||||||
|
.onError(error -> log.error("Failed to get attribute id with name: {} for exam: {}",
|
||||||
|
configAttributeName, examId, error))
|
||||||
|
.getOr(null);
|
||||||
|
|
||||||
|
return this.configurationValueDAO
|
||||||
|
.getConfigAttributeValue(configId, attrId)
|
||||||
|
.getOrThrow();
|
||||||
|
|
||||||
|
} catch (final Exception e) {
|
||||||
|
log.error("Unexpected error while trying to extract SEB settings attribute value:", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -56,12 +56,12 @@ public interface SEBRestrictionAPI {
|
||||||
|
|
||||||
/** Applies SEB Client restrictions to the LMS with the given attributes.
|
/** Applies SEB Client restrictions to the LMS with the given attributes.
|
||||||
*
|
*
|
||||||
* @param externalExamId The exam/course identifier from LMS side (Exam.externalId)
|
* @param exam The exam to apply the restriction for
|
||||||
* @param sebRestrictionData containing all data for SEB Client restriction to apply to the LMS
|
* @param sebRestrictionData containing all data for SEB Client restriction to apply to the LMS
|
||||||
* @return Result refer to the given {@link SEBRestrictionData } if restriction was successful or to an error if
|
* @return Result refer to the given {@link SEBRestrictionData } if restriction was successful or to an error if
|
||||||
* not */
|
* not */
|
||||||
Result<SEBRestriction> applySEBClientRestriction(
|
Result<SEBRestriction> applySEBClientRestriction(
|
||||||
String externalExamId,
|
Exam exam,
|
||||||
SEBRestriction sebRestrictionData);
|
SEBRestriction sebRestrictionData);
|
||||||
|
|
||||||
/** Releases an already applied SEB Client restriction within the LMS for a given Exam.
|
/** Releases an already applied SEB Client restriction within the LMS for a given Exam.
|
||||||
|
|
|
@ -409,7 +409,7 @@ public class LmsAPITemplateAdapter implements LmsAPITemplate {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Result<SEBRestriction> applySEBClientRestriction(
|
public Result<SEBRestriction> applySEBClientRestriction(
|
||||||
final String externalExamId,
|
final Exam exam,
|
||||||
final SEBRestriction sebRestrictionData) {
|
final SEBRestriction sebRestrictionData) {
|
||||||
|
|
||||||
if (this.sebRestrictionAPI == null) {
|
if (this.sebRestrictionAPI == null) {
|
||||||
|
@ -418,11 +418,11 @@ public class LmsAPITemplateAdapter implements LmsAPITemplate {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
log.debug("Apply course restriction: {} for LMSSetup: {}", externalExamId, lmsSetup());
|
log.debug("Apply course restriction: {} for LMSSetup: {}", exam, lmsSetup());
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.restrictionRequest.protectedRun(() -> this.sebRestrictionAPI
|
return this.restrictionRequest.protectedRun(() -> this.sebRestrictionAPI
|
||||||
.applySEBClientRestriction(externalExamId, sebRestrictionData)
|
.applySEBClientRestriction(exam, sebRestrictionData)
|
||||||
.onError(error -> log.error(
|
.onError(error -> log.error(
|
||||||
"Failed to apply SEB restrictions: {}",
|
"Failed to apply SEB restrictions: {}",
|
||||||
error.getMessage()))
|
error.getMessage()))
|
||||||
|
|
|
@ -237,7 +237,7 @@ public class SEBRestrictionServiceImpl implements SEBRestrictionService {
|
||||||
return this.lmsAPIService
|
return this.lmsAPIService
|
||||||
.getLmsAPITemplate(exam.lmsSetupId)
|
.getLmsAPITemplate(exam.lmsSetupId)
|
||||||
.flatMap(lmsTemplate -> lmsTemplate.applySEBClientRestriction(
|
.flatMap(lmsTemplate -> lmsTemplate.applySEBClientRestriction(
|
||||||
exam.externalId,
|
exam,
|
||||||
sebRestrictionData))
|
sebRestrictionData))
|
||||||
.map(data -> exam)
|
.map(data -> exam)
|
||||||
.getOrThrow();
|
.getOrThrow();
|
||||||
|
|
|
@ -56,8 +56,8 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.lms.APITemplateDataSupplier
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPIService;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPIService;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPITemplate;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPITemplate;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.AbstractCachedCourseAccess;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.AbstractCachedCourseAccess;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.ans.AnsLmsData.SEBServerData;
|
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.ans.AnsLmsData.AssignmentData;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.ans.AnsLmsData.AssignmentData;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.ans.AnsLmsData.SEBServerData;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.ans.AnsLmsData.UserData;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.ans.AnsLmsData.UserData;
|
||||||
|
|
||||||
public class AnsLmsAPITemplate extends AbstractCachedCourseAccess implements LmsAPITemplate {
|
public class AnsLmsAPITemplate extends AbstractCachedCourseAccess implements LmsAPITemplate {
|
||||||
|
@ -371,10 +371,10 @@ public class AnsLmsAPITemplate extends AbstractCachedCourseAccess implements Lms
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Result<SEBRestriction> applySEBClientRestriction(
|
public Result<SEBRestriction> applySEBClientRestriction(
|
||||||
final String externalExamId,
|
final Exam exam,
|
||||||
final SEBRestriction sebRestrictionData) {
|
final SEBRestriction sebRestrictionData) {
|
||||||
return getRestTemplate()
|
return getRestTemplate()
|
||||||
.map(t -> this.setRestrictionForAssignmentId(t, externalExamId, sebRestrictionData));
|
.map(t -> this.setRestrictionForAssignmentId(t, exam.externalId, sebRestrictionData));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -148,16 +148,16 @@ public class OpenEdxCourseRestriction implements SEBRestrictionAPI {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Result<SEBRestriction> applySEBClientRestriction(
|
public Result<SEBRestriction> applySEBClientRestriction(
|
||||||
final String externalExamId,
|
final Exam exam,
|
||||||
final SEBRestriction sebRestrictionData) {
|
final SEBRestriction sebRestrictionData) {
|
||||||
|
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
log.debug("PUT SEB Client restriction on course: {} : {}", externalExamId, sebRestrictionData);
|
log.debug("PUT SEB Client restriction on course: {} : {}", exam.externalId, sebRestrictionData);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Result.tryCatch(() -> {
|
return Result.tryCatch(() -> {
|
||||||
final LmsSetup lmsSetup = this.openEdxRestTemplateFactory.apiTemplateDataSupplier.getLmsSetup();
|
final LmsSetup lmsSetup = this.openEdxRestTemplateFactory.apiTemplateDataSupplier.getLmsSetup();
|
||||||
final String url = lmsSetup.lmsApiUrl + getSEBRestrictionUrl(externalExamId);
|
final String url = lmsSetup.lmsApiUrl + getSEBRestrictionUrl(exam.externalId);
|
||||||
final HttpHeaders httpHeaders = new HttpHeaders();
|
final HttpHeaders httpHeaders = new HttpHeaders();
|
||||||
httpHeaders.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
|
httpHeaders.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
|
||||||
httpHeaders.add(HttpHeaders.CACHE_CONTROL, "no-cache, no-store, must-revalidate");
|
httpHeaders.add(HttpHeaders.CACHE_CONTROL, "no-cache, no-store, must-revalidate");
|
||||||
|
@ -172,7 +172,7 @@ public class OpenEdxCourseRestriction implements SEBRestrictionAPI {
|
||||||
.getBody();
|
.getBody();
|
||||||
|
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
log.debug("Successfully PUT SEB Client restriction on course: {} : {}", externalExamId, body);
|
log.debug("Successfully PUT SEB Client restriction on course: {} : {}", exam.externalId, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
return sebRestrictionData;
|
return sebRestrictionData;
|
||||||
|
|
|
@ -36,7 +36,7 @@ public class MockSEBRestrictionAPI implements SEBRestrictionAPI {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Result<SEBRestriction> applySEBClientRestriction(
|
public Result<SEBRestriction> applySEBClientRestriction(
|
||||||
final String externalExamId,
|
final Exam exam,
|
||||||
final SEBRestriction sebRestrictionData) {
|
final SEBRestriction sebRestrictionData) {
|
||||||
|
|
||||||
log.info("Apply SEB Client restriction: {}", sebRestrictionData);
|
log.info("Apply SEB Client restriction: {}", sebRestrictionData);
|
||||||
|
|
|
@ -126,11 +126,11 @@ public class MoodleCourseRestriction implements SEBRestrictionAPI {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Result<SEBRestriction> applySEBClientRestriction(
|
public Result<SEBRestriction> applySEBClientRestriction(
|
||||||
final String externalExamId,
|
final Exam exam,
|
||||||
final SEBRestriction sebRestrictionData) {
|
final SEBRestriction sebRestrictionData) {
|
||||||
|
|
||||||
return this.updateSEBRestriction(
|
return this.updateSEBRestriction(
|
||||||
externalExamId,
|
exam.externalId,
|
||||||
MoodleSEBRestriction.from(sebRestrictionData))
|
MoodleSEBRestriction.from(sebRestrictionData))
|
||||||
.map(result -> sebRestrictionData);
|
.map(result -> sebRestrictionData);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,8 +29,10 @@ public class MoodlePluginCourseRestriction implements SEBRestrictionAPI {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Result<SEBRestriction> applySEBClientRestriction(final String externalExamId,
|
public Result<SEBRestriction> applySEBClientRestriction(
|
||||||
|
final Exam exam,
|
||||||
final SEBRestriction sebRestrictionData) {
|
final SEBRestriction sebRestrictionData) {
|
||||||
|
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,7 @@ import ch.ethz.seb.sebserver.gbl.model.user.ExamineeAccountDetails;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.servicelayer.exam.ExamConfigurationValueService;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.APITemplateDataSupplier;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.APITemplateDataSupplier;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPIService;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPIService;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPITemplate;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPITemplate;
|
||||||
|
@ -62,9 +63,16 @@ public class OlatLmsAPITemplate extends AbstractCachedCourseAccess implements Lm
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(OlatLmsAPITemplate.class);
|
private static final Logger log = LoggerFactory.getLogger(OlatLmsAPITemplate.class);
|
||||||
|
|
||||||
|
private static final String ADDITIONAL_ATTR_QUIT_LINK = "ADDITIONAL_ATTR_QUIT_LINK";
|
||||||
|
private static final String ADDITIONAL_ATTR_QUIT_SECRET = "ADDITIONAL_ATTR_QUIT_SECRET";
|
||||||
|
|
||||||
|
private static final String CONFIG_ATTR_NAME_QUIT_LINK = "quitURL";
|
||||||
|
private static final String CONFIG_ATTR_NAME_QUIT_SECRET = "hashedQuitPassword";
|
||||||
|
|
||||||
private final ClientHttpRequestFactoryService clientHttpRequestFactoryService;
|
private final ClientHttpRequestFactoryService clientHttpRequestFactoryService;
|
||||||
private final ClientCredentialService clientCredentialService;
|
private final ClientCredentialService clientCredentialService;
|
||||||
private final APITemplateDataSupplier apiTemplateDataSupplier;
|
private final APITemplateDataSupplier apiTemplateDataSupplier;
|
||||||
|
private final ExamConfigurationValueService examConfigurationValueService;
|
||||||
private final Long lmsSetupId;
|
private final Long lmsSetupId;
|
||||||
|
|
||||||
private OlatLmsRestTemplate cachedRestTemplate;
|
private OlatLmsRestTemplate cachedRestTemplate;
|
||||||
|
@ -73,6 +81,7 @@ public class OlatLmsAPITemplate extends AbstractCachedCourseAccess implements Lm
|
||||||
final ClientHttpRequestFactoryService clientHttpRequestFactoryService,
|
final ClientHttpRequestFactoryService clientHttpRequestFactoryService,
|
||||||
final ClientCredentialService clientCredentialService,
|
final ClientCredentialService clientCredentialService,
|
||||||
final APITemplateDataSupplier apiTemplateDataSupplier,
|
final APITemplateDataSupplier apiTemplateDataSupplier,
|
||||||
|
final ExamConfigurationValueService examConfigurationValueService,
|
||||||
final CacheManager cacheManager) {
|
final CacheManager cacheManager) {
|
||||||
|
|
||||||
super(cacheManager);
|
super(cacheManager);
|
||||||
|
@ -80,6 +89,7 @@ public class OlatLmsAPITemplate extends AbstractCachedCourseAccess implements Lm
|
||||||
this.clientHttpRequestFactoryService = clientHttpRequestFactoryService;
|
this.clientHttpRequestFactoryService = clientHttpRequestFactoryService;
|
||||||
this.clientCredentialService = clientCredentialService;
|
this.clientCredentialService = clientCredentialService;
|
||||||
this.apiTemplateDataSupplier = apiTemplateDataSupplier;
|
this.apiTemplateDataSupplier = apiTemplateDataSupplier;
|
||||||
|
this.examConfigurationValueService = examConfigurationValueService;
|
||||||
this.lmsSetupId = apiTemplateDataSupplier.getLmsSetup().id;
|
this.lmsSetupId = apiTemplateDataSupplier.getLmsSetup().id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,7 +320,15 @@ public class OlatLmsAPITemplate extends AbstractCachedCourseAccess implements Lm
|
||||||
private SEBRestriction getRestrictionForAssignmentId(final RestTemplate restTemplate, final String id) {
|
private SEBRestriction getRestrictionForAssignmentId(final RestTemplate restTemplate, final String id) {
|
||||||
final String url = String.format("/restapi/assessment_modes/%s/seb_restriction", id);
|
final String url = String.format("/restapi/assessment_modes/%s/seb_restriction", id);
|
||||||
final RestrictionData r = this.apiGet(restTemplate, url, RestrictionData.class);
|
final RestrictionData r = this.apiGet(restTemplate, url, RestrictionData.class);
|
||||||
return new SEBRestriction(Long.valueOf(id), r.configKeys, r.browserExamKeys, new HashMap<String, String>());
|
final HashMap<String, String> additionalAttributes = new HashMap<>();
|
||||||
|
if (StringUtils.isNotBlank(r.quitLink)) {
|
||||||
|
additionalAttributes.put(ADDITIONAL_ATTR_QUIT_LINK, r.quitLink);
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotBlank(r.quitSecret)) {
|
||||||
|
additionalAttributes.put(ADDITIONAL_ATTR_QUIT_SECRET, r.quitSecret);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new SEBRestriction(Long.valueOf(id), r.configKeys, r.browserExamKeys, additionalAttributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SEBRestriction setRestrictionForAssignmentId(
|
private SEBRestriction setRestrictionForAssignmentId(
|
||||||
|
@ -322,6 +340,8 @@ public class OlatLmsAPITemplate extends AbstractCachedCourseAccess implements Lm
|
||||||
final RestrictionDataPost post = new RestrictionDataPost();
|
final RestrictionDataPost post = new RestrictionDataPost();
|
||||||
post.browserExamKeys = new ArrayList<>(restriction.browserExamKeys);
|
post.browserExamKeys = new ArrayList<>(restriction.browserExamKeys);
|
||||||
post.configKeys = new ArrayList<>(restriction.configKeys);
|
post.configKeys = new ArrayList<>(restriction.configKeys);
|
||||||
|
post.quitLink = restriction.getAdditionalProperties().getOrDefault(ADDITIONAL_ATTR_QUIT_LINK, null);
|
||||||
|
post.quitSecret = restriction.getAdditionalProperties().getOrDefault(ADDITIONAL_ATTR_QUIT_SECRET, null);
|
||||||
final RestrictionData r =
|
final RestrictionData r =
|
||||||
this.apiPost(restTemplate, url, post, RestrictionDataPost.class, RestrictionData.class);
|
this.apiPost(restTemplate, url, post, RestrictionDataPost.class, RestrictionData.class);
|
||||||
return new SEBRestriction(Long.valueOf(id), r.configKeys, r.browserExamKeys, new HashMap<String, String>());
|
return new SEBRestriction(Long.valueOf(id), r.configKeys, r.browserExamKeys, new HashMap<String, String>());
|
||||||
|
@ -343,10 +363,12 @@ public class OlatLmsAPITemplate extends AbstractCachedCourseAccess implements Lm
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Result<SEBRestriction> applySEBClientRestriction(
|
public Result<SEBRestriction> applySEBClientRestriction(
|
||||||
final String externalExamId,
|
final Exam exam,
|
||||||
final SEBRestriction sebRestrictionData) {
|
final SEBRestriction sebRestrictionData) {
|
||||||
|
|
||||||
|
populateWithQuitLinkAndSecret(exam, sebRestrictionData);
|
||||||
return getRestTemplate()
|
return getRestTemplate()
|
||||||
.map(t -> this.setRestrictionForAssignmentId(t, externalExamId, sebRestrictionData));
|
.map(t -> this.setRestrictionForAssignmentId(t, exam.externalId, sebRestrictionData));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -433,4 +455,28 @@ public class OlatLmsAPITemplate extends AbstractCachedCourseAccess implements Lm
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void populateWithQuitLinkAndSecret(final Exam exam, final SEBRestriction sebRestrictionData) {
|
||||||
|
try {
|
||||||
|
|
||||||
|
final String quitLink = this.examConfigurationValueService.getMappedDefaultConfigAttributeValue(
|
||||||
|
exam.id,
|
||||||
|
CONFIG_ATTR_NAME_QUIT_LINK);
|
||||||
|
|
||||||
|
final String quitSecret = this.examConfigurationValueService.getMappedDefaultConfigAttributeValue(
|
||||||
|
exam.id,
|
||||||
|
CONFIG_ATTR_NAME_QUIT_SECRET);
|
||||||
|
|
||||||
|
if (StringUtils.isNotEmpty(quitLink)) {
|
||||||
|
sebRestrictionData.additionalProperties.put(ADDITIONAL_ATTR_QUIT_LINK, quitLink);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringUtils.isNotEmpty(quitSecret)) {
|
||||||
|
sebRestrictionData.additionalProperties.put(ADDITIONAL_ATTR_QUIT_SECRET, quitSecret);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (final Exception e) {
|
||||||
|
log.error("Failed to populate SEB restriction with quit link and quit secret: ", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ import ch.ethz.seb.sebserver.gbl.client.ClientCredentialService;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup.LmsType;
|
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup.LmsType;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.servicelayer.exam.ExamConfigurationValueService;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.APITemplateDataSupplier;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.APITemplateDataSupplier;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPITemplate;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPITemplate;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPITemplateFactory;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPITemplateFactory;
|
||||||
|
@ -38,6 +39,7 @@ public class OlatLmsAPITemplateFactory implements LmsAPITemplateFactory {
|
||||||
|
|
||||||
private final ClientHttpRequestFactoryService clientHttpRequestFactoryService;
|
private final ClientHttpRequestFactoryService clientHttpRequestFactoryService;
|
||||||
private final ClientCredentialService clientCredentialService;
|
private final ClientCredentialService clientCredentialService;
|
||||||
|
private final ExamConfigurationValueService examConfigurationValueService;
|
||||||
private final AsyncService asyncService;
|
private final AsyncService asyncService;
|
||||||
private final Environment environment;
|
private final Environment environment;
|
||||||
private final CacheManager cacheManager;
|
private final CacheManager cacheManager;
|
||||||
|
@ -45,12 +47,14 @@ public class OlatLmsAPITemplateFactory implements LmsAPITemplateFactory {
|
||||||
public OlatLmsAPITemplateFactory(
|
public OlatLmsAPITemplateFactory(
|
||||||
final ClientHttpRequestFactoryService clientHttpRequestFactoryService,
|
final ClientHttpRequestFactoryService clientHttpRequestFactoryService,
|
||||||
final ClientCredentialService clientCredentialService,
|
final ClientCredentialService clientCredentialService,
|
||||||
|
final ExamConfigurationValueService examConfigurationValueService,
|
||||||
final AsyncService asyncService,
|
final AsyncService asyncService,
|
||||||
final Environment environment,
|
final Environment environment,
|
||||||
final CacheManager cacheManager) {
|
final CacheManager cacheManager) {
|
||||||
|
|
||||||
this.clientHttpRequestFactoryService = clientHttpRequestFactoryService;
|
this.clientHttpRequestFactoryService = clientHttpRequestFactoryService;
|
||||||
this.clientCredentialService = clientCredentialService;
|
this.clientCredentialService = clientCredentialService;
|
||||||
|
this.examConfigurationValueService = examConfigurationValueService;
|
||||||
this.asyncService = asyncService;
|
this.asyncService = asyncService;
|
||||||
this.environment = environment;
|
this.environment = environment;
|
||||||
this.cacheManager = cacheManager;
|
this.cacheManager = cacheManager;
|
||||||
|
@ -68,6 +72,7 @@ public class OlatLmsAPITemplateFactory implements LmsAPITemplateFactory {
|
||||||
this.clientHttpRequestFactoryService,
|
this.clientHttpRequestFactoryService,
|
||||||
this.clientCredentialService,
|
this.clientCredentialService,
|
||||||
apiTemplateDataSupplier,
|
apiTemplateDataSupplier,
|
||||||
|
this.examConfigurationValueService,
|
||||||
this.cacheManager);
|
this.cacheManager);
|
||||||
return new LmsAPITemplateAdapter(
|
return new LmsAPITemplateAdapter(
|
||||||
this.asyncService,
|
this.asyncService,
|
||||||
|
|
|
@ -61,12 +61,16 @@ public final class OlatLmsData {
|
||||||
* {
|
* {
|
||||||
* "browserExamKeys": [ "1" ],
|
* "browserExamKeys": [ "1" ],
|
||||||
* "configKeys": null,
|
* "configKeys": null,
|
||||||
|
* "quitLink": "<the quit link from Exam Configuration>",
|
||||||
|
* "quitSecret": "<the quit password from Exam Configuration (base64 encoded)>",
|
||||||
* "key": 8028160
|
* "key": 8028160
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
public long key;
|
public long key;
|
||||||
public List<String> browserExamKeys;
|
public List<String> browserExamKeys;
|
||||||
public List<String> configKeys;
|
public List<String> configKeys;
|
||||||
|
public String quitLink;
|
||||||
|
public String quitSecret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
@ -76,10 +80,14 @@ public final class OlatLmsData {
|
||||||
* {
|
* {
|
||||||
* "configKeys": ["a", "b"],
|
* "configKeys": ["a", "b"],
|
||||||
* "browserExamKeys": ["1", "2"]
|
* "browserExamKeys": ["1", "2"]
|
||||||
|
* "quitLink": "<the quit link from Exam Configuration>",
|
||||||
|
* "quitSecret": "<the quit password from Exam Configuration (base64 encoded)>",
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
public List<String> browserExamKeys;
|
public List<String> browserExamKeys;
|
||||||
public List<String> configKeys;
|
public List<String> configKeys;
|
||||||
|
public String quitLink;
|
||||||
|
public String quitSecret;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue