Skip to content

Commit 7eef8fa

Browse files
committed
TD-4880 Prevent administrators from viewing Activity Delegates for self assessments in a category that doesn't match their own
1 parent de21044 commit 7eef8fa

File tree

6 files changed

+73
-1
lines changed

6 files changed

+73
-1
lines changed

DigitalLearningSolutions.Data/DataServices/CourseDataService.cs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ int EnrolOnActivitySelfAssessment(int selfAssessmentId, int candidateId, int sup
137137
public IEnumerable<CourseStatistics> GetDelegateCourseStatisticsAtCentre(string searchString, int centreId, int? categoryId, bool allCentreCourses, bool? hideInLearnerPortal, string isActive, string categoryName, string courseTopic, string hasAdminFields);
138138

139139
public IEnumerable<DelegateAssessmentStatistics> GetDelegateAssessmentStatisticsAtCentre(string searchString, int centreId, string categoryName, string isActive);
140+
141+
public IEnumerable<DelegateAssessmentStatistics> GetDelegateAssessmentStatisticsAtCentreByCategoryId(string searchString, int centreId, string categoryName, string isActive, int? categoryId);
140142
bool IsSelfEnrollmentAllowed(int customisationId);
141143
Customisation? GetCourse(int customisationId);
142144
}
@@ -1995,6 +1997,46 @@ AND sa.[Name] LIKE '%' + @searchString + '%'
19951997
return delegateAssessmentStatistics;
19961998
}
19971999

2000+
2001+
public IEnumerable<DelegateAssessmentStatistics> GetDelegateAssessmentStatisticsAtCentreByCategoryId(string searchString, int centreId, string categoryName, string isActive, int? categoryId)
2002+
{
2003+
string assessmentStatisticsSelectQuery = $@"SELECT
2004+
sa.Name AS Name,
2005+
cc.CategoryName AS Category,
2006+
CASE
2007+
WHEN sa.SupervisorSelfAssessmentReview = 0 AND sa.SupervisorResultsReview = 0 THEN 0
2008+
ELSE 1
2009+
END AS Supervised,
2010+
(SELECT COUNT(can.ID)
2011+
FROM dbo.CandidateAssessments AS can WITH (NOLOCK)
2012+
INNER JOIN Users AS u WITH (NOLOCK) ON u.ID = can.DelegateUserID
2013+
LEFT JOIN UserCentreDetails AS ucd WITH (NOLOCK) ON ucd.UserID = u.ID AND ucd.centreID = can.CentreID
2014+
WHERE can.CentreID = @centreId AND can.SelfAssessmentID = csa.SelfAssessmentID
2015+
AND can.RemovedDate IS NULL AND COALESCE(ucd.Email, u.PrimaryEmail) LIKE '%_@_%') AS DelegateCount,
2016+
(Select COUNT(*) FROM
2017+
(SELECT can.ID FROM dbo.CandidateAssessments AS can WITH (NOLOCK)
2018+
LEFT JOIN dbo.CandidateAssessmentSupervisors AS cas ON can.ID = cas.CandidateAssessmentID
2019+
LEFT JOIN dbo.CandidateAssessmentSupervisorVerifications AS casv ON cas.ID = casv.CandidateAssessmentSupervisorID
2020+
WHERE can.CentreID = @centreId AND can.SelfAssessmentID = CSA.SelfAssessmentID AND can.RemovedDate IS NULL
2021+
AND (can.SubmittedDate IS NOT NULL OR (casv.SignedOff = 1 AND casv.Verified IS NOT NULL)) GROUP BY can.ID) A
2022+
) AS SubmittedSignedOffCount,
2023+
CC.Active AS Active,
2024+
sa.ID AS SelfAssessmentId
2025+
from CentreSelfAssessments AS csa
2026+
INNER join SelfAssessments AS sa ON csa.SelfAssessmentID = sa.ID
2027+
INNER JOIN CourseCategories AS cc ON sa.CategoryID = cc.CourseCategoryID
2028+
WHERE csa.CentreID= @centreId
2029+
AND sa.[Name] LIKE '%' + @searchString + '%'
2030+
AND ((@categoryName = 'Any') OR (cc.CategoryName = @categoryName))
2031+
AND (ISNULL(@categoryId, 0) = 0 OR sa.CategoryID = @categoryId)
2032+
AND ((@isActive = 'Any') OR (@isActive = 'true' AND sa.ArchivedDate IS NULL) OR (@isActive = 'false' AND sa.ArchivedDate IS NOT NULL))
2033+
";
2034+
2035+
IEnumerable<DelegateAssessmentStatistics> delegateAssessmentStatistics = connection.Query<DelegateAssessmentStatistics>(assessmentStatisticsSelectQuery,
2036+
new { searchString, centreId, categoryName, isActive, categoryId }, commandTimeout: 3000);
2037+
return delegateAssessmentStatistics;
2038+
}
2039+
19982040
public bool IsSelfEnrollmentAllowed(int customisationId)
19992041
{
20002042
int selfRegister = connection.QueryFirstOrDefault<int>(

DigitalLearningSolutions.Data/DataServices/SelfAssessmentDataService/SelfAssessmentDataService.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using DigitalLearningSolutions.Data.Models.Frameworks;
1111
using DigitalLearningSolutions.Data.Models.SelfAssessments;
1212
using DigitalLearningSolutions.Data.Models.SelfAssessments.Export;
13+
using MailKit;
1314
using Microsoft.Extensions.Logging;
1415

1516
public interface ISelfAssessmentDataService
@@ -172,6 +173,7 @@ int GetSelfAssessmentActivityDelegatesExportCount(string searchString, string so
172173
bool IsUnsupervisedSelfAssessment(int selfAssessmentId);
173174
bool IsCentreSelfAssessment(int selfAssessmentId, int centreId);
174175
bool HasMinimumOptionalCompetencies(int selfAssessmentId, int delegateUserId);
176+
int GetSelfAssessmentCategoryId(int selfAssessmentId);
175177
}
176178

177179
public partial class SelfAssessmentDataService : ISelfAssessmentDataService
@@ -760,5 +762,13 @@ INNER JOIN SelfAssessments AS SA
760762
new { selfAssessmentId, delegateUserId }
761763
);
762764
}
765+
766+
public int GetSelfAssessmentCategoryId(int selfAssessmentId)
767+
{
768+
return connection.ExecuteScalar<int>(
769+
@"SELECT CategoryID FROM SelfAssessments WHERE ID = @selfAssessmentId",
770+
new { selfAssessmentId}
771+
);
772+
}
763773
}
764774
}

DigitalLearningSolutions.Web/Controllers/TrackingSystem/Delegates/ActivityDelegatesController.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,13 @@ public IActionResult Index(
132132
var centreId = User.GetCentreIdKnownNotNull();
133133
var adminCategoryId = User.GetAdminCategoryId();
134134

135+
var selfAssessmentCategoryId = selfAssessmentService.GetSelfAssessmentCategoryId((int)selfAssessmentId);
136+
137+
if (adminCategoryId > 0 && adminCategoryId != selfAssessmentCategoryId)
138+
{
139+
return RedirectToAction("StatusCode", "LearningSolutions", new { code = 403 });
140+
}
141+
135142
bool? isDelegateActive, isProgressLocked, removed, hasCompleted, submitted, signedOff;
136143
isDelegateActive = isProgressLocked = removed = hasCompleted = submitted = signedOff = null;
137144

DigitalLearningSolutions.Web/Controllers/TrackingSystem/Delegates/DelegateCoursesController.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ public IActionResult Index(
162162
if (isCourse == "true")
163163
delegateActivities = courseService.GetDelegateCourses(searchString ?? string.Empty, centreId, categoryId, true, null, isActive, categoryName, courseTopic, hasAdminFields).ToList();
164164
if (isSelfAssessment == "true" && courseTopic == "Any" && hasAdminFields == "Any")
165-
delegateAssessments = courseService.GetDelegateAssessments(searchString, centreId, categoryName, isActive);
165+
delegateAssessments = courseService.GetDelegateAssessmentsByCategoryId(searchString, centreId, categoryName, isActive, categoryId);
166166

167167
delegateAssessments = UpdateCompletedCount(delegateAssessments);
168168

DigitalLearningSolutions.Web/Services/CourseService.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ int diagCompletionThreshold
121121

122122
public IEnumerable<CourseStatisticsWithAdminFieldResponseCounts> GetDelegateCourses(string searchString, int centreId, int? categoryId, bool allCentreCourses, bool? hideInLearnerPortal, string isActive, string categoryName, string courseTopic, string hasAdminFields);
123123
public IEnumerable<DelegateAssessmentStatistics> GetDelegateAssessments(string searchString, int centreId, string categoryName, string isActive);
124+
public IEnumerable<DelegateAssessmentStatistics> GetDelegateAssessmentsByCategoryId(string searchString, int centreId, string categoryName, string isActive, int? categoryId);
124125
IEnumerable<AvailableCourse> GetAvailableCourses(int delegateId, int? centreId, int categoryId);
125126
bool IsCourseCompleted(int candidateId, int customisationId);
126127
bool IsCourseCompleted(int candidateId, int customisationId, int progressID);
@@ -568,6 +569,11 @@ public IEnumerable<DelegateAssessmentStatistics> GetDelegateAssessments(string s
568569
return courseDataService.GetDelegateAssessmentStatisticsAtCentre(searchString, centreId, categoryName, isActive);
569570
}
570571

572+
public IEnumerable<DelegateAssessmentStatistics> GetDelegateAssessmentsByCategoryId(string searchString, int centreId, string categoryName, string isActive, int? categoryId)
573+
{
574+
return courseDataService.GetDelegateAssessmentStatisticsAtCentreByCategoryId(searchString, centreId, categoryName, isActive, categoryId);
575+
}
576+
571577
public IEnumerable<AvailableCourse> GetAvailableCourses(int delegateId, int? centreId, int categoryId)
572578
{
573579
return courseDataService.GetAvailableCourses(delegateId, centreId, categoryId);

DigitalLearningSolutions.Web/Services/SelfAssessmentService.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Collections.Generic;
55
using System.Linq;
66
using DigitalLearningSolutions.Data.DataServices.SelfAssessmentDataService;
7+
using DigitalLearningSolutions.Data.ModelBinders;
78
using DigitalLearningSolutions.Data.Models.Common.Users;
89
using DigitalLearningSolutions.Data.Models.External.Filtered;
910
using DigitalLearningSolutions.Data.Models.Frameworks;
@@ -149,6 +150,7 @@ public int GetSelfAssessmentActivityDelegatesExportCount(string searchString, st
149150
IEnumerable<CandidateAssessment> GetCandidateAssessments(int delegateUserId, int selfAssessmentId);
150151
bool IsCentreSelfAssessment(int selfAssessmentId, int centreId);
151152
bool HasMinimumOptionalCompetencies(int selfAssessmentId, int delegateUserId);
153+
public int GetSelfAssessmentCategoryId(int selfAssessmentId);
152154

153155
}
154156

@@ -558,5 +560,10 @@ public bool HasMinimumOptionalCompetencies(int selfAssessmentId, int delegateUse
558560
{
559561
return selfAssessmentDataService.HasMinimumOptionalCompetencies(selfAssessmentId, delegateUserId);
560562
}
563+
564+
public int GetSelfAssessmentCategoryId(int selfAssessmentId)
565+
{
566+
return selfAssessmentDataService.GetSelfAssessmentCategoryId(selfAssessmentId);
567+
}
561568
}
562569
}

0 commit comments

Comments
 (0)