Merge remote-tracking branch 'origin/dev-1.5' into development

This commit is contained in:
anhefti 2023-06-15 11:14:11 +02:00
commit e2aabd4044
10 changed files with 17 additions and 15 deletions

View file

@ -16,6 +16,7 @@ import java.util.function.Predicate;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.apache.commons.text.StringEscapeUtils;
import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Label;
@ -161,7 +162,7 @@ public class ExamDeletePopup {
new ActionEvent(action), new ActionEvent(action),
action.pageContext()); action.pageContext());
final String examName = examToDelete.toName().name; final String examName = StringEscapeUtils.escapeXml11(examToDelete.toName().name);
final List<EntityKey> dependencies = report.results.stream() final List<EntityKey> dependencies = report.results.stream()
.filter(key -> !key.equals(entityKey)) .filter(key -> !key.equals(entityKey))
.collect(Collectors.toList()); .collect(Collectors.toList());

View file

@ -15,7 +15,6 @@ import java.util.function.BooleanSupplier;
import java.util.function.Function; import java.util.function.Function;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.commons.text.StringEscapeUtils;
import org.eclipse.swt.SWT; import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Composite;
@ -482,7 +481,7 @@ public class LmsSetupForm implements TemplateComposer {
case TOKEN_REQUEST: { case TOKEN_REQUEST: {
throw new PageMessageException(new LocTextKey( throw new PageMessageException(new LocTextKey(
"sebserver.lmssetup.action.test.tokenRequestError", "sebserver.lmssetup.action.test.tokenRequestError",
Utils.formatHTMLLinesForceEscaped(StringEscapeUtils.escapeHtml4(error.message)))); Utils.formatHTMLLinesForceEscaped(Utils.escapeHTML_XML_EcmaScript(error.message))));
} }
case QUIZ_ACCESS_API_REQUEST: { case QUIZ_ACCESS_API_REQUEST: {
if (error.message.contains("quizaccess_sebserver_get_exams")) { if (error.message.contains("quizaccess_sebserver_get_exams")) {

View file

@ -46,7 +46,7 @@ public final class Message extends MessageBox {
super.prepareOpen(); super.prepareOpen();
} catch (final IllegalArgumentException e) { } catch (final IllegalArgumentException e) {
// fallback on markup text error // fallback on markup text error
super.setMessage(StringEscapeUtils.escapeHtml4(super.getMessage())); super.setMessage(StringEscapeUtils.escapeXml11(super.getMessage()));
super.prepareOpen(); super.prepareOpen();
} }
final GridLayout layout = (GridLayout) super.shell.getLayout(); final GridLayout layout = (GridLayout) super.shell.getLayout();

View file

@ -63,7 +63,7 @@ public class MockCourseAccessAPI implements CourseAccessAPI {
"quiz1", institutionId, lmsSetupId, lmsType, "Demo Quiz 1 (MOCKUP)", "<p>Demo Quiz Mockup</p>", "quiz1", institutionId, lmsSetupId, lmsType, "Demo Quiz 1 (MOCKUP)", "<p>Demo Quiz Mockup</p>",
"2020-01-01T09:00:00Z", null, "http://lms.mockup.com/api/")); "2020-01-01T09:00:00Z", null, "http://lms.mockup.com/api/"));
this.mockups.add(new QuizData( this.mockups.add(new QuizData(
"quiz2", institutionId, lmsSetupId, lmsType, "Demo Quiz 2 (MOCKUP) äöüèÜÄÖ ?< ", "quiz2 äöüèÜÄÖ ?<", institutionId, lmsSetupId, lmsType, "Demo Quiz 2 (MOCKUP) äöüèÜÄÖ ?< ",
"<p>Demo Quiz Mockup</p>", "<p>Demo Quiz Mockup</p>",
"2020-01-01T09:00:00Z", "2025-01-01T09:00:00Z", "http://lms.mockup.com/api/")); "2020-01-01T09:00:00Z", "2025-01-01T09:00:00Z", "http://lms.mockup.com/api/"));
this.mockups.add(new QuizData( this.mockups.add(new QuizData(

View file

@ -431,10 +431,10 @@ public class MoodlePluginCourseAccess extends AbstractCachedCourseAccess impleme
final String fromElement = String.valueOf(page * size); final String fromElement = String.valueOf(page * size);
final LinkedMultiValueMap<String, String> attributes = new LinkedMultiValueMap<>(); final LinkedMultiValueMap<String, String> attributes = new LinkedMultiValueMap<>();
// TODO clarify with Amr and Luca if this is OK
// and if it is possible to apply the nameCondition also the the course name (shortname)
if (this.applyNameCriteria && StringUtils.isNotBlank(nameCondition)) { if (this.applyNameCriteria && StringUtils.isNotBlank(nameCondition)) {
sqlCondition = sqlCondition + " AND (m.name LIKE '" + sqlCondition = sqlCondition + " AND (name LIKE '" +
Utils.toSQLWildcard(nameCondition) +
"' OR shortname LIKE '" +
Utils.toSQLWildcard(nameCondition) + Utils.toSQLWildcard(nameCondition) +
"')"; "')";
} }

View file

@ -57,7 +57,7 @@ public class MooldePluginLmsAPITemplateFactory implements LmsAPITemplateFactory
final ExamConfigurationValueService examConfigurationValueService, final ExamConfigurationValueService examConfigurationValueService,
final ClientHttpRequestFactoryService clientHttpRequestFactoryService, final ClientHttpRequestFactoryService clientHttpRequestFactoryService,
@Value("${sebserver.webservice.lms.moodle.api.token.request.paths:}") final String alternativeTokenRequestPaths, @Value("${sebserver.webservice.lms.moodle.api.token.request.paths:}") final String alternativeTokenRequestPaths,
@Value("${sebserver.webservice.lms.moodle.fetch.applyNameCriteria:false}") final boolean applyNameCriteria) { @Value("${sebserver.webservice.lms.moodle.fetch.applyNameCriteria:true}") final boolean applyNameCriteria) {
this.jsonMapper = jsonMapper; this.jsonMapper = jsonMapper;
this.cacheManager = cacheManager; this.cacheManager = cacheManager;

View file

@ -267,8 +267,7 @@ public class ExamSessionServiceImpl implements ExamSessionService {
filterMap filterMap
.putIfAbsent(Exam.FILTER_ATTR_ACTIVE, Constants.TRUE_STRING) .putIfAbsent(Exam.FILTER_ATTR_ACTIVE, Constants.TRUE_STRING)
.putIfAbsent(Exam.FILTER_ATTR_STATUS, ExamStatus.RUNNING.name()) .putIfAbsent(Exam.FILTER_ATTR_STATUS, ExamStatus.RUNNING.name());
.putIfAbsent(Exam.FILTER_ATTR_HIDE_MISSING, Constants.TRUE_STRING);
return this.examDAO.allMatching(filterMap, predicate) return this.examDAO.allMatching(filterMap, predicate)
.map(col -> col.stream() .map(col -> col.stream()

View file

@ -410,11 +410,14 @@ class ExamUpdateHandler {
.getLmsAPITemplate(lmsSetupId) .getLmsAPITemplate(lmsSetupId)
.getOrThrow(); .getOrThrow();
final Exam exam = exams.get(quizId);
if (!lmsTemplate.getType().features.contains(Features.COURSE_RECOVERY)) { if (!lmsTemplate.getType().features.contains(Features.COURSE_RECOVERY)) {
if (exam.lmsAvailable == null || exam.isLmsAvailable()) {
this.examDAO.markLMSAvailability(quizId, false, updateId);
}
throw new UnsupportedOperationException("No Course Recovery"); throw new UnsupportedOperationException("No Course Recovery");
} }
final Exam exam = exams.get(quizId);
final int attempts = Integer.parseInt(this.additionalAttributesDAO.getAdditionalAttribute( final int attempts = Integer.parseInt(this.additionalAttributesDAO.getAdditionalAttribute(
EntityType.EXAM, EntityType.EXAM,
exam.id, exam.id,

View file

@ -81,7 +81,7 @@ sebserver.webservice.lms.openedx.api.token.request.paths=/oauth2/access_token
sebserver.webservice.lms.moodle.api.token.request.paths=/login/token.php sebserver.webservice.lms.moodle.api.token.request.paths=/login/token.php
sebserver.webservice.lms.moodle.prependShortCourseName=true sebserver.webservice.lms.moodle.prependShortCourseName=true
sebserver.webservice.lms.moodle.fetch.cutoffdate.yearsBeforeNow=2 sebserver.webservice.lms.moodle.fetch.cutoffdate.yearsBeforeNow=2
sebserver.webservice.lms.moodle.fetch.applyNameCriteria=false sebserver.webservice.lms.moodle.fetch.applyNameCriteria=true
sebserver.webservice.lms.olat.sendAdditionalAttributesWithRestriction=false sebserver.webservice.lms.olat.sendAdditionalAttributesWithRestriction=false
sebserver.webservice.lms.address.alias= sebserver.webservice.lms.address.alias=
sebserver.webservice.lms.datafetch.validity.seconds=600 sebserver.webservice.lms.datafetch.validity.seconds=600

View file

@ -36,12 +36,12 @@ public class ExamAPITest extends AdministrationAPIIntegrationTester {
sebAdminAccess, sebAdminAccess,
sebAdminAccess, sebAdminAccess,
"LmsSetupMock", "LmsSetupMock",
"quiz2", "quiz2 äöüèÜÄÖ ?<",
ExamType.MANAGED, ExamType.MANAGED,
"user5"); "user5");
assertNotNull(exam); assertNotNull(exam);
assertEquals("quiz2", exam.getExternalId()); assertEquals("quiz2 äöüèÜÄÖ ?<", exam.getExternalId()); // Note cannot set right collation on h2
assertEquals(ExamType.MANAGED, exam.getType()); assertEquals(ExamType.MANAGED, exam.getType());
assertFalse(exam.getSupporter().isEmpty()); assertFalse(exam.getSupporter().isEmpty());