Index: 3rdParty_sources/versions.txt =================================================================== diff -u -r3f71f6dbe6fdfaccdb5be53cea559235e0ff2e0f -r4436ad48ebfcbce1f25ad39db54f55c32873afc1 --- 3rdParty_sources/versions.txt (.../versions.txt) (revision 3f71f6dbe6fdfaccdb5be53cea559235e0ff2e0f) +++ 3rdParty_sources/versions.txt (.../versions.txt) (revision 4436ad48ebfcbce1f25ad39db54f55c32873afc1) @@ -25,8 +25,9 @@ Commons Validator 1.6 -CSRF Guard master from 2020.01.07 with a custom modification in CsrfGuard.java +CSRF Guard 4.1.3 with a custom modification in CsrfGuardUtils.java + Etherpad Client 1.2.13 Hibernate Core 5.3.6 Index: lams_build/3rdParty.userlibraries =================================================================== diff -u -r4a5316b22bd1d32badb579f76583afd435866822 -r4436ad48ebfcbce1f25ad39db54f55c32873afc1 --- lams_build/3rdParty.userlibraries (.../3rdParty.userlibraries) (revision 4a5316b22bd1d32badb579f76583afd435866822) +++ lams_build/3rdParty.userlibraries (.../3rdParty.userlibraries) (revision 4436ad48ebfcbce1f25ad39db54f55c32873afc1) @@ -49,5 +49,6 @@ + Index: lams_build/build.xml =================================================================== diff -u -r5694a8e26e12cfd208ef7f26d736f02dc6749f23 -r4436ad48ebfcbce1f25ad39db54f55c32873afc1 --- lams_build/build.xml (.../build.xml) (revision 5694a8e26e12cfd208ef7f26d736f02dc6749f23) +++ lams_build/build.xml (.../build.xml) (revision 4436ad48ebfcbce1f25ad39db54f55c32873afc1) @@ -917,7 +917,6 @@ - Index: lams_build/liblist.txt =================================================================== diff -u -r4a5316b22bd1d32badb579f76583afd435866822 -r4436ad48ebfcbce1f25ad39db54f55c32873afc1 --- lams_build/liblist.txt (.../liblist.txt) (revision 4a5316b22bd1d32badb579f76583afd435866822) +++ lams_build/liblist.txt (.../liblist.txt) (revision 4436ad48ebfcbce1f25ad39db54f55c32873afc1) @@ -24,9 +24,8 @@ clamav-client clamav-client-2.0.2.jar 2.0.2 MIT cdarras on GitHub ClamAV antivirus client -csrfguard csrfguard-3.1.0-custom-2020.01.07.jar custom build BSD License OWASP prevents CSRF attacks - based on 3.1.0 master from 2020.01.07 with a custom modification in CsrfGuard.java - +csrfguard csrfguard-4.1.3-custom-2022.04.03.jar custom build BSD License OWASP prevents CSRF attacks + based on 4.1.3 4.1.3 tag with a custom modification in CsrfGuardUtils.java etherpad etherpad_lite_client-1.2.13.jar 1.2.13 Apache License 2.0 Nils Fredrik Gjerull Client for Etherpad fckeditor fckeditor-java-core-2.6.jar 2.6 GPL, LGPL, MPL Frederico Caldeira Knabben Java connector for CKEditor Index: lams_central/web/WEB-INF/web.xml =================================================================== diff -u -r5694a8e26e12cfd208ef7f26d736f02dc6749f23 -r4436ad48ebfcbce1f25ad39db54f55c32873afc1 --- lams_central/web/WEB-INF/web.xml (.../web.xml) (revision 5694a8e26e12cfd208ef7f26d736f02dc6749f23) +++ lams_central/web/WEB-INF/web.xml (.../web.xml) (revision 4436ad48ebfcbce1f25ad39db54f55c32873afc1) @@ -131,6 +131,7 @@ CSRFGuard *.do + /ForgotPasswordRequest Index: lams_central/web/authoring/svgGenerator.jsp =================================================================== diff -u -r476bdb809eab2960310273b6ea0e3682b57064cd -r4436ad48ebfcbce1f25ad39db54f55c32873afc1 --- lams_central/web/authoring/svgGenerator.jsp (.../svgGenerator.jsp) (revision 476bdb809eab2960310273b6ea0e3682b57064cd) +++ lams_central/web/authoring/svgGenerator.jsp (.../svgGenerator.jsp) (revision 4436ad48ebfcbce1f25ad39db54f55c32873afc1) @@ -51,6 +51,7 @@ activitiesOnlySelectable = ${param.selectable eq 'true'}, isLtiContentSelection = false, initLearningDesignID = '${param.learningDesignID}', + initRelaunchMonitorLessonID = null, csrfTokenName = '', csrfTokenValue = ''; Index: lams_gradebook/src/java/org/lamsfoundation/lams/gradebook/service/GradebookService.java =================================================================== diff -u -rbfa7dfb5557d54767b137652b34dd89c13fb1227 -r4436ad48ebfcbce1f25ad39db54f55c32873afc1 --- lams_gradebook/src/java/org/lamsfoundation/lams/gradebook/service/GradebookService.java (.../GradebookService.java) (revision bfa7dfb5557d54767b137652b34dd89c13fb1227) +++ lams_gradebook/src/java/org/lamsfoundation/lams/gradebook/service/GradebookService.java (.../GradebookService.java) (revision 4436ad48ebfcbce1f25ad39db54f55c32873afc1) @@ -1085,17 +1085,15 @@ @Override public String getReleaseMarksEmailContent(long lessonID, int userID) { - // temporary comment so template gets loaded every time - // eventually it will be loaded just once -// if (RELEASE_MARKS_EMAIL_TEMPLATE_CONTENT == null) { - try { - RELEASE_MARKS_EMAIL_TEMPLATE_CONTENT = Files - .readString(Paths.get(Configuration.get(ConfigurationKeys.LAMS_EAR_DIR), FileUtil.LAMS_WWW_DIR, - "gradebookReleaseLessonMarksEmailTemplate.html")); - } catch (Exception e) { - throw new RuntimeException("Can not read release marks email template", e); + if (RELEASE_MARKS_EMAIL_TEMPLATE_CONTENT == null) { + try { + RELEASE_MARKS_EMAIL_TEMPLATE_CONTENT = Files + .readString(Paths.get(Configuration.get(ConfigurationKeys.LAMS_EAR_DIR), FileUtil.LAMS_WWW_DIR, + "gradebookReleaseLessonMarksEmailTemplate.html")); + } catch (Exception e) { + throw new RuntimeException("Can not read release marks email template", e); + } } -// } User user = userService.getUserById(userID); Lesson lesson = lessonService.getLesson(lessonID); Index: lams_monitoring/web/includes/javascript/monitorLesson.js =================================================================== diff -u -rd30456574288df7fd628ad569ec5e74b23f971a3 -r4436ad48ebfcbce1f25ad39db54f55c32873afc1 --- lams_monitoring/web/includes/javascript/monitorLesson.js (.../monitorLesson.js) (revision d30456574288df7fd628ad569ec5e74b23f971a3) +++ lams_monitoring/web/includes/javascript/monitorLesson.js (.../monitorLesson.js) (revision 4436ad48ebfcbce1f25ad39db54f55c32873afc1) @@ -1469,8 +1469,15 @@ if (response.contributeActivities) { $.each(response.contributeActivities, function(){ if (activity.id == this.activityID) { - activity.requiresAttention = true; - return false; + let allComplete = true; + $.each(this.contributeEntries, function(){ + if (!this.isComplete) { + allComplete = false; + return false; + } + }); + activity.requiresAttention = !allComplete; + return false; } }); } Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java =================================================================== diff -u -rf0ff6bc30e8fa7e5d4201b7b9571194845ad3a83 -r4436ad48ebfcbce1f25ad39db54f55c32873afc1 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java (.../AssessmentServiceImpl.java) (revision f0ff6bc30e8fa7e5d4201b7b9571194845ad3a83) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java (.../AssessmentServiceImpl.java) (revision 4436ad48ebfcbce1f25ad39db54f55c32873afc1) @@ -58,6 +58,8 @@ import org.lamsfoundation.lams.confidencelevel.VsaAnswerDTO; import org.lamsfoundation.lams.contentrepository.client.IToolContentHandler; import org.lamsfoundation.lams.events.IEventNotificationService; +import org.lamsfoundation.lams.flux.FluxMap; +import org.lamsfoundation.lams.flux.FluxRegistry; import org.lamsfoundation.lams.learning.service.ILearnerService; import org.lamsfoundation.lams.learningdesign.Grouping; import org.lamsfoundation.lams.learningdesign.ToolActivity; @@ -143,6 +145,8 @@ import com.fasterxml.jackson.databind.node.JsonNodeFactory; import com.fasterxml.jackson.databind.node.ObjectNode; +import reactor.core.publisher.Flux; + /** * @author Andrey Balan */ @@ -195,6 +199,13 @@ private ILearnerInteractionService learnerInteractionService; + public AssessmentServiceImpl() { + FluxRegistry.initFluxMap(AssessmentConstants.COMPLETION_CHARTS_UPDATE_FLUX_NAME, + AssessmentConstants.ANSWERS_UPDATED_SINK_NAME, null, + (Long toolContentId) -> getCompletionChartsData(toolContentId), FluxMap.SHORT_THROTTLE, + FluxMap.STANDARD_TIMEOUT); + } + // ******************************************************************************* // Service method // ******************************************************************************* @@ -707,6 +718,12 @@ learnerService.createCommandForLearners(assessment.getContentId(), userIds, jsonCommand.toString()); } + if (isAnswerModified) { + // need to flush so subscribers to sink see new answers in DB + assessmentResultDao.flush(); + FluxRegistry.emit(AssessmentConstants.ANSWERS_UPDATED_SINK_NAME, assessment.getContentId()); + } + return true; } @@ -796,6 +813,34 @@ return questionResult; } + private String getCompletionChartsData(long toolContentId) { + try { + ObjectNode chartJson = JsonNodeFactory.instance.objectNode(); + + chartJson.put("possibleLearners", getCountLessonLearnersByContentId(toolContentId)); + chartJson.put("startedLearners", getCountUsersByContentId(toolContentId)); + chartJson.put("completedLearners", getCountLearnersWithFinishedCurrentAttempt(toolContentId)); + + chartJson.put("sessionCount", getSessionsByContentId(toolContentId).size()); + Map> answeredQuestionsByUsers = getAnsweredQuestionsByUsers(toolContentId); + if (!answeredQuestionsByUsers.isEmpty()) { + chartJson.set("answeredQuestionsByUsers", JsonUtil.readObject(answeredQuestionsByUsers)); + Map answeredQuestionsByUsersCount = answeredQuestionsByUsers.entrySet().stream() + .collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue().size())); + chartJson.set("answeredQuestionsByUsersCount", JsonUtil.readObject(answeredQuestionsByUsersCount)); + } + return chartJson.toString(); + } catch (Exception e) { + log.error("Unable to fetch completion charts data for tool content ID " + toolContentId); + return ""; + } + } + + @Override + public Flux getCompletionChartsDataFlux(long toolContentId) { + return FluxRegistry.get(AssessmentConstants.COMPLETION_CHARTS_UPDATE_FLUX_NAME, toolContentId); + } + /** * * @return grade that user scored by answering that question