From 0fa7708fa12728d2fbfa79d104d544e7df9cf3ed Mon Sep 17 00:00:00 2001 From: ninjapiratica Date: Sat, 7 Dec 2024 18:40:59 -0800 Subject: [PATCH] Adjust model properties (#12) * Add MentoredUserIds to Membership Remove AddressId Make GetMemberships call return User as well * Update permissions * Update spacing --- .../Models/CustomPermissions.cs | 51 ++++++++++ NP.Lti13Platform.Core/Models/Membership.cs | 2 + NP.Lti13Platform.Core/Models/Tool.cs | 82 ---------------- NP.Lti13Platform.Core/Models/User.cs | 2 - .../Models/UserPermissions.cs | 31 ++++++ .../NP.Lti13Platform.Core.csproj | 4 +- .../Populators/CustomPopulator.cs | 96 ++++++++++--------- .../Populators/RolesPopulator.cs | 2 +- .../Services/ILti13CoreDataService.cs | 3 +- NP.Lti13Platform.Core/Startup.cs | 52 +++++----- .../Populators/CustomPopulator.cs | 26 ++--- .../ILti13NameRoleProvisioningDataService.cs | 4 +- .../Startup.cs | 24 +++-- .../NP.Lti13Platform.Test.csproj | 10 +- NP.Lti13Platform.WebExample/Program.cs | 39 ++++---- 15 files changed, 222 insertions(+), 206 deletions(-) create mode 100644 NP.Lti13Platform.Core/Models/CustomPermissions.cs create mode 100644 NP.Lti13Platform.Core/Models/UserPermissions.cs diff --git a/NP.Lti13Platform.Core/Models/CustomPermissions.cs b/NP.Lti13Platform.Core/Models/CustomPermissions.cs new file mode 100644 index 0000000..6ae895f --- /dev/null +++ b/NP.Lti13Platform.Core/Models/CustomPermissions.cs @@ -0,0 +1,51 @@ +namespace NP.Lti13Platform.Core.Models +{ + public class CustomPermissions + { + public bool UserId { get; set; } + public bool UserImage { get; set; } + public bool UserUsername { get; set; } + public bool UserOrg { get; set; } + public bool UserScopeMentor { get; set; } + public bool UserGradeLevelsOneRoster { get; set; } + + public bool ActualUserId { get; set; } + public bool ActualUserImage { get; set; } + public bool ActualUserUsername { get; set; } + public bool ActualUserOrg { get; set; } + public bool ActualUserScopeMentor { get; set; } + public bool ActualUserGradeLevelsOneRoster { get; set; } + + public bool ContextId { get; set; } + public bool ContextOrg { get; set; } + public bool ContextType { get; set; } + public bool ContextLabel { get; set; } + public bool ContextTitle { get; set; } + public bool ContextSourcedId { get; set; } + public bool ContextIdHistory { get; set; } + public bool ContextGradeLevelsOneRoster { get; set; } + + public bool ResourceLinkId { get; set; } + public bool ResourceLinkTitle { get; set; } + public bool ResourceLinkDescription { get; set; } + public bool ResourceLinkAvailableStartDateTime { get; set; } + public bool ResourceLinkAvailableUserStartDateTime { get; set; } + public bool ResourceLinkAvailableEndDateTime { get; set; } + public bool ResourceLinkAvailableUserEndDateTime { get; set; } + public bool ResourceLinkSubmissionStartDateTime { get; set; } + public bool ResourceLinkSubmissionUserStartDateTime { get; set; } + public bool ResourceLinkSubmissionEndDateTime { get; set; } + public bool ResourceLinkSubmissionUserEndDateTime { get; set; } + public bool ResourceLinkLineItemReleaseDateTime { get; set; } + public bool ResourceLinkLineItemUserReleaseDateTime { get; set; } + public bool ResourceLinkIdHistory { get; set; } + + public bool ToolPlatformProductFamilyCode { get; set; } + public bool ToolPlatformProductVersion { get; set; } + public bool ToolPlatformProductInstanceGuid { get; set; } + public bool ToolPlatformProductInstanceName { get; set; } + public bool ToolPlatformProductInstanceDescription { get; set; } + public bool ToolPlatformProductInstanceUrl { get; set; } + public bool ToolPlatformProductInstanceContactEmail { get; set; } + } +} diff --git a/NP.Lti13Platform.Core/Models/Membership.cs b/NP.Lti13Platform.Core/Models/Membership.cs index 74c9032..bbbf0e1 100644 --- a/NP.Lti13Platform.Core/Models/Membership.cs +++ b/NP.Lti13Platform.Core/Models/Membership.cs @@ -9,6 +9,8 @@ public class Membership public required MembershipStatus Status { get; set; } public required IEnumerable Roles { get; set; } + + public required IEnumerable MentoredUserIds { get; set; } } public enum MembershipStatus diff --git a/NP.Lti13Platform.Core/Models/Tool.cs b/NP.Lti13Platform.Core/Models/Tool.cs index 132ea0a..794f9cd 100644 --- a/NP.Lti13Platform.Core/Models/Tool.cs +++ b/NP.Lti13Platform.Core/Models/Tool.cs @@ -19,87 +19,5 @@ public class Tool public IDictionary? Custom { get; set; } public IEnumerable ServiceScopes { get; set; } = []; - - public required UserPermissions UserPermissions { get; set; } - - public required CustomPermissions CustomPermissions { get; set; } - } - - public class UserPermissions - { - public bool Address { get; set; } - public bool AddressCountry { get; set; } - public bool AddressFormatted { get; set; } - public bool AddressLocality { get; set; } - public bool AddressPostalCode { get; set; } - public bool AddressRegion { get; set; } - public bool AddressStreetAddress { get; set; } - public bool Birthdate { get; set; } - public bool Email { get; set; } - public bool EmailVerified { get; set; } - public bool FamilyName { get; set; } - public bool Gender { get; set; } - public bool GivenName { get; set; } - public bool Locale { get; set; } - public bool MiddleName { get; set; } - public bool Name { get; set; } - public bool Nickname { get; set; } - public bool PhoneNumber { get; set; } - public bool PhoneNumberVerified { get; set; } - public bool Picture { get; set; } - public bool PreferredUsername { get; set; } - public bool Profile { get; set; } - public bool UpdatedAt { get; set; } - public bool Website { get; set; } - public bool TimeZone { get; set; } - } - - public class CustomPermissions - { - public bool UserId { get; set; } - public bool UserImage { get; set; } - public bool UserUsername { get; set; } - public bool UserOrg { get; set; } - public bool UserScopeMentor { get; set; } - public bool UserGradeLevelsOneRoster { get; set; } - - public bool ActualUserId { get; set; } - public bool ActualUserImage { get; set; } - public bool ActualUserUsername { get; set; } - public bool ActualUserOrg { get; set; } - public bool ActualUserScopeMentor { get; set; } - public bool ActualUserGradeLevelsOneRoster { get; set; } - - public bool ContextId { get; set; } - public bool ContextOrg { get; set; } - public bool ContextType { get; set; } - public bool ContextLabel { get; set; } - public bool ContextTitle { get; set; } - public bool ContextSourcedId { get; set; } - public bool ContextIdHistory { get; set; } - public bool ContextGradeLevelsOneRoster { get; set; } - - public bool ResourceLinkId { get; set; } - public bool ResourceLinkTitle { get; set; } - public bool ResourceLinkDescription { get; set; } - public bool ResourceLinkAvailableStartDateTime { get; set; } - public bool ResourceLinkAvailableUserStartDateTime { get; set; } - public bool ResourceLinkAvailableEndDateTime { get; set; } - public bool ResourceLinkAvailableUserEndDateTime { get; set; } - public bool ResourceLinkSubmissionStartDateTime { get; set; } - public bool ResourceLinkSubmissionUserStartDateTime { get; set; } - public bool ResourceLinkSubmissionEndDateTime { get; set; } - public bool ResourceLinkSubmissionUserEndDateTime { get; set; } - public bool ResourceLinkLineItemReleaseDateTime { get; set; } - public bool ResourceLinkLineItemUserReleaseDateTime { get; set; } - public bool ResourceLinkIdHistory { get; set; } - - public bool ToolPlatformProductFamilyCode { get; set; } - public bool ToolPlatformProductVersion { get; set; } - public bool ToolPlatformProductInstanceGuid { get; set; } - public bool ToolPlatformProductInstanceName { get; set; } - public bool ToolPlatformProductInstanceDescription { get; set; } - public bool ToolPlatformProductInstanceUrl { get; set; } - public bool ToolPlatformProductInstanceContactEmail { get; set; } } } diff --git a/NP.Lti13Platform.Core/Models/User.cs b/NP.Lti13Platform.Core/Models/User.cs index 16bbfa2..816e170 100644 --- a/NP.Lti13Platform.Core/Models/User.cs +++ b/NP.Lti13Platform.Core/Models/User.cs @@ -53,8 +53,6 @@ public class User public class Address { - public required string Id { get; set; } - public string? Formatted { get; set; } public string? StreetAddress { get; set; } diff --git a/NP.Lti13Platform.Core/Models/UserPermissions.cs b/NP.Lti13Platform.Core/Models/UserPermissions.cs new file mode 100644 index 0000000..b19c031 --- /dev/null +++ b/NP.Lti13Platform.Core/Models/UserPermissions.cs @@ -0,0 +1,31 @@ +namespace NP.Lti13Platform.Core.Models +{ + public class UserPermissions + { + public bool Address { get; set; } + public bool AddressCountry { get; set; } + public bool AddressFormatted { get; set; } + public bool AddressLocality { get; set; } + public bool AddressPostalCode { get; set; } + public bool AddressRegion { get; set; } + public bool AddressStreetAddress { get; set; } + public bool Birthdate { get; set; } + public bool Email { get; set; } + public bool EmailVerified { get; set; } + public bool FamilyName { get; set; } + public bool Gender { get; set; } + public bool GivenName { get; set; } + public bool Locale { get; set; } + public bool MiddleName { get; set; } + public bool Name { get; set; } + public bool Nickname { get; set; } + public bool PhoneNumber { get; set; } + public bool PhoneNumberVerified { get; set; } + public bool Picture { get; set; } + public bool PreferredUsername { get; set; } + public bool Profile { get; set; } + public bool UpdatedAt { get; set; } + public bool Website { get; set; } + public bool TimeZone { get; set; } + } +} diff --git a/NP.Lti13Platform.Core/NP.Lti13Platform.Core.csproj b/NP.Lti13Platform.Core/NP.Lti13Platform.Core.csproj index 7ba3ea2..5ead43f 100644 --- a/NP.Lti13Platform.Core/NP.Lti13Platform.Core.csproj +++ b/NP.Lti13Platform.Core/NP.Lti13Platform.Core.csproj @@ -20,8 +20,8 @@ - - + + diff --git a/NP.Lti13Platform.Core/Populators/CustomPopulator.cs b/NP.Lti13Platform.Core/Populators/CustomPopulator.cs index 42688b4..599bade 100644 --- a/NP.Lti13Platform.Core/Populators/CustomPopulator.cs +++ b/NP.Lti13Platform.Core/Populators/CustomPopulator.cs @@ -43,7 +43,7 @@ public override async Task PopulateAsync(ICustomMessage obj, MessageScope scope, var membership = await dataService.GetMembershipAsync(scope.Context.Id, scope.UserScope.User.Id, cancellationToken); if (membership != null && membership.Roles.Contains(Lti13ContextRoles.Mentor)) { - mentoredUserIds = await dataService.GetMentoredUserIdsAsync(scope.Context.Id, scope.UserScope.User.Id, cancellationToken); + mentoredUserIds = membership.MentoredUserIds; } } @@ -53,7 +53,7 @@ public override async Task PopulateAsync(ICustomMessage obj, MessageScope scope, var membership = await dataService.GetMembershipAsync(scope.Context.Id, scope.UserScope.ActualUser.Id, cancellationToken); if (membership != null && membership.Roles.Contains(Lti13ContextRoles.Mentor)) { - actualUserMentoredUserIds = await dataService.GetMentoredUserIdsAsync(scope.Context.Id, scope.UserScope.ActualUser.Id, cancellationToken); + actualUserMentoredUserIds = membership.MentoredUserIds; } } @@ -73,56 +73,58 @@ public override async Task PopulateAsync(ICustomMessage obj, MessageScope scope, attempt = await dataService.GetAttemptAsync(scope.ResourceLink.Id, scope.UserScope.User.Id, cancellationToken); } + var customPermissions = await dataService.GetCustomPermissions(scope.Deployment.Id, cancellationToken); + foreach (var kvp in customDictionary.Where(kvp => kvp.Value.StartsWith('$'))) { // TODO: LIS variables customDictionary[kvp.Key] = kvp.Value switch { - Lti13UserVariables.Id when scope.Tool.CustomPermissions.UserId && !scope.UserScope.IsAnonymous => scope.UserScope.User.Id, - Lti13UserVariables.Image when scope.Tool.CustomPermissions.UserImage && !scope.UserScope.IsAnonymous => scope.UserScope.User.ImageUrl, - Lti13UserVariables.Username when scope.Tool.CustomPermissions.UserUsername && !scope.UserScope.IsAnonymous => scope.UserScope.User.Username, - Lti13UserVariables.Org when scope.Tool.CustomPermissions.UserOrg && !scope.UserScope.IsAnonymous => string.Join(',', scope.UserScope.User.Orgs), - Lti13UserVariables.ScopeMentor when scope.Tool.CustomPermissions.UserScopeMentor && !scope.UserScope.IsAnonymous => string.Join(',', mentoredUserIds), - Lti13UserVariables.GradeLevelsOneRoster when scope.Tool.CustomPermissions.UserGradeLevelsOneRoster && !scope.UserScope.IsAnonymous => string.Join(',', scope.UserScope.User.OneRosterGrades), - - Lti13ActualUserVariables.Id when scope.Tool.CustomPermissions.ActualUserId && !scope.UserScope.IsAnonymous => scope.UserScope.ActualUser?.Id, - Lti13ActualUserVariables.Image when scope.Tool.CustomPermissions.ActualUserImage && !scope.UserScope.IsAnonymous => scope.UserScope.ActualUser?.ImageUrl, - Lti13ActualUserVariables.Username when scope.Tool.CustomPermissions.ActualUserUsername && !scope.UserScope.IsAnonymous => scope.UserScope.ActualUser?.Username, - Lti13ActualUserVariables.Org when scope.Tool.CustomPermissions.ActualUserOrg && !scope.UserScope.IsAnonymous => scope.UserScope.ActualUser != null ? string.Join(',', scope.UserScope.ActualUser.Orgs) : string.Empty, - Lti13ActualUserVariables.ScopeMentor when scope.Tool.CustomPermissions.ActualUserScopeMentor && !scope.UserScope.IsAnonymous => string.Join(',', actualUserMentoredUserIds), - Lti13ActualUserVariables.GradeLevelsOneRoster when scope.Tool.CustomPermissions.ActualUserGradeLevelsOneRoster && !scope.UserScope.IsAnonymous => scope.UserScope.ActualUser != null ? string.Join(',', scope.UserScope.ActualUser.OneRosterGrades) : string.Empty, - - Lti13ContextVariables.Id when scope.Tool.CustomPermissions.ContextId => scope.Context?.Id, - Lti13ContextVariables.Org when scope.Tool.CustomPermissions.ContextOrg => scope.Context != null ? string.Join(',', scope.Context.Orgs) : string.Empty, - Lti13ContextVariables.Type when scope.Tool.CustomPermissions.ContextType => scope.Context != null ? string.Join(',', scope.Context.Types) : string.Empty, - Lti13ContextVariables.Label when scope.Tool.CustomPermissions.ContextLabel => scope.Context?.Label, - Lti13ContextVariables.Title when scope.Tool.CustomPermissions.ContextTitle => scope.Context?.Title, - Lti13ContextVariables.SourcedId when scope.Tool.CustomPermissions.ContextSourcedId => scope.Context?.SourcedId, - Lti13ContextVariables.IdHistory when scope.Tool.CustomPermissions.ContextIdHistory => scope.Context != null ? string.Join(',', scope.Context.ClonedIdHistory) : string.Empty, - Lti13ContextVariables.GradeLevelsOneRoster when scope.Tool.CustomPermissions.ContextGradeLevelsOneRoster => scope.Context != null ? string.Join(',', scope.Context.OneRosterGrades) : string.Empty, - - Lti13ResourceLinkVariables.Id when scope.Tool.CustomPermissions.ResourceLinkId => scope.ResourceLink?.Id, - Lti13ResourceLinkVariables.Title when scope.Tool.CustomPermissions.ResourceLinkTitle => scope.ResourceLink?.Title, - Lti13ResourceLinkVariables.Description when scope.Tool.CustomPermissions.ResourceLinkDescription => scope.ResourceLink?.Text, - Lti13ResourceLinkVariables.AvailableStartDateTime when scope.Tool.CustomPermissions.ResourceLinkAvailableStartDateTime => scope.ResourceLink?.AvailableStartDateTime?.ToString("O"), - Lti13ResourceLinkVariables.AvailableUserStartDateTime when scope.Tool.CustomPermissions.ResourceLinkAvailableUserStartDateTime => attempt?.AvailableStartDateTime?.ToString("O"), - Lti13ResourceLinkVariables.AvailableEndDateTime when scope.Tool.CustomPermissions.ResourceLinkAvailableEndDateTime => scope.ResourceLink?.AvailableEndDateTime?.ToString("O"), - Lti13ResourceLinkVariables.AvailableUserEndDateTime when scope.Tool.CustomPermissions.ResourceLinkAvailableUserEndDateTime => attempt?.AvailableEndDateTime?.ToString("O"), - Lti13ResourceLinkVariables.SubmissionStartDateTime when scope.Tool.CustomPermissions.ResourceLinkSubmissionStartDateTime => scope.ResourceLink?.SubmissionStartDateTime?.ToString("O"), - Lti13ResourceLinkVariables.SubmissionUserStartDateTime when scope.Tool.CustomPermissions.ResourceLinkSubmissionUserStartDateTime => attempt?.SubmisstionStartDateTime?.ToString("O"), - Lti13ResourceLinkVariables.SubmissionEndDateTime when scope.Tool.CustomPermissions.ResourceLinkSubmissionEndDateTime => scope.ResourceLink?.SubmissionEndDateTime?.ToString("O"), - Lti13ResourceLinkVariables.SubmissionUserEndDateTime when scope.Tool.CustomPermissions.ResourceLinkSubmissionUserEndDateTime => attempt?.SubmissionEndDateTime?.ToString("O"), - Lti13ResourceLinkVariables.LineItemReleaseDateTime when scope.Tool.CustomPermissions.ResourceLinkLineItemReleaseDateTime => lineItem?.GradesReleasedDateTime?.ToString("O"), - Lti13ResourceLinkVariables.LineItemUserReleaseDateTime when scope.Tool.CustomPermissions.ResourceLinkLineItemUserReleaseDateTime => grade?.ReleaseDateTime?.ToString("O"), - Lti13ResourceLinkVariables.IdHistory when scope.Tool.CustomPermissions.ResourceLinkIdHistory => scope.ResourceLink?.ClonedIdHistory != null ? string.Join(',', scope.ResourceLink.ClonedIdHistory) : string.Empty, - - Lti13ToolPlatformVariables.ProductFamilyCode when scope.Tool.CustomPermissions.ToolPlatformProductFamilyCode => platform?.ProductFamilyCode, - Lti13ToolPlatformVariables.Version when scope.Tool.CustomPermissions.ToolPlatformProductVersion => platform?.Version, - Lti13ToolPlatformVariables.InstanceGuid when scope.Tool.CustomPermissions.ToolPlatformProductInstanceGuid => platform?.Guid, - Lti13ToolPlatformVariables.InstanceName when scope.Tool.CustomPermissions.ToolPlatformProductInstanceName => platform?.Name, - Lti13ToolPlatformVariables.InstanceDescription when scope.Tool.CustomPermissions.ToolPlatformProductInstanceDescription => platform?.Description, - Lti13ToolPlatformVariables.InstanceUrl when scope.Tool.CustomPermissions.ToolPlatformProductInstanceUrl => platform?.Url, - Lti13ToolPlatformVariables.InstanceContactEmail when scope.Tool.CustomPermissions.ToolPlatformProductInstanceContactEmail => platform?.ContactEmail, + Lti13UserVariables.Id when customPermissions.UserId && !scope.UserScope.IsAnonymous => scope.UserScope.User.Id, + Lti13UserVariables.Image when customPermissions.UserImage && !scope.UserScope.IsAnonymous => scope.UserScope.User.ImageUrl, + Lti13UserVariables.Username when customPermissions.UserUsername && !scope.UserScope.IsAnonymous => scope.UserScope.User.Username, + Lti13UserVariables.Org when customPermissions.UserOrg && !scope.UserScope.IsAnonymous => string.Join(',', scope.UserScope.User.Orgs), + Lti13UserVariables.ScopeMentor when customPermissions.UserScopeMentor && !scope.UserScope.IsAnonymous => string.Join(',', mentoredUserIds), + Lti13UserVariables.GradeLevelsOneRoster when customPermissions.UserGradeLevelsOneRoster && !scope.UserScope.IsAnonymous => string.Join(',', scope.UserScope.User.OneRosterGrades), + + Lti13ActualUserVariables.Id when customPermissions.ActualUserId && !scope.UserScope.IsAnonymous => scope.UserScope.ActualUser?.Id, + Lti13ActualUserVariables.Image when customPermissions.ActualUserImage && !scope.UserScope.IsAnonymous => scope.UserScope.ActualUser?.ImageUrl, + Lti13ActualUserVariables.Username when customPermissions.ActualUserUsername && !scope.UserScope.IsAnonymous => scope.UserScope.ActualUser?.Username, + Lti13ActualUserVariables.Org when customPermissions.ActualUserOrg && !scope.UserScope.IsAnonymous => scope.UserScope.ActualUser != null ? string.Join(',', scope.UserScope.ActualUser.Orgs) : string.Empty, + Lti13ActualUserVariables.ScopeMentor when customPermissions.ActualUserScopeMentor && !scope.UserScope.IsAnonymous => string.Join(',', actualUserMentoredUserIds), + Lti13ActualUserVariables.GradeLevelsOneRoster when customPermissions.ActualUserGradeLevelsOneRoster && !scope.UserScope.IsAnonymous => scope.UserScope.ActualUser != null ? string.Join(',', scope.UserScope.ActualUser.OneRosterGrades) : string.Empty, + + Lti13ContextVariables.Id when customPermissions.ContextId => scope.Context?.Id, + Lti13ContextVariables.Org when customPermissions.ContextOrg => scope.Context != null ? string.Join(',', scope.Context.Orgs) : string.Empty, + Lti13ContextVariables.Type when customPermissions.ContextType => scope.Context != null ? string.Join(',', scope.Context.Types) : string.Empty, + Lti13ContextVariables.Label when customPermissions.ContextLabel => scope.Context?.Label, + Lti13ContextVariables.Title when customPermissions.ContextTitle => scope.Context?.Title, + Lti13ContextVariables.SourcedId when customPermissions.ContextSourcedId => scope.Context?.SourcedId, + Lti13ContextVariables.IdHistory when customPermissions.ContextIdHistory => scope.Context != null ? string.Join(',', scope.Context.ClonedIdHistory) : string.Empty, + Lti13ContextVariables.GradeLevelsOneRoster when customPermissions.ContextGradeLevelsOneRoster => scope.Context != null ? string.Join(',', scope.Context.OneRosterGrades) : string.Empty, + + Lti13ResourceLinkVariables.Id when customPermissions.ResourceLinkId => scope.ResourceLink?.Id, + Lti13ResourceLinkVariables.Title when customPermissions.ResourceLinkTitle => scope.ResourceLink?.Title, + Lti13ResourceLinkVariables.Description when customPermissions.ResourceLinkDescription => scope.ResourceLink?.Text, + Lti13ResourceLinkVariables.AvailableStartDateTime when customPermissions.ResourceLinkAvailableStartDateTime => scope.ResourceLink?.AvailableStartDateTime?.ToString("O"), + Lti13ResourceLinkVariables.AvailableUserStartDateTime when customPermissions.ResourceLinkAvailableUserStartDateTime => attempt?.AvailableStartDateTime?.ToString("O"), + Lti13ResourceLinkVariables.AvailableEndDateTime when customPermissions.ResourceLinkAvailableEndDateTime => scope.ResourceLink?.AvailableEndDateTime?.ToString("O"), + Lti13ResourceLinkVariables.AvailableUserEndDateTime when customPermissions.ResourceLinkAvailableUserEndDateTime => attempt?.AvailableEndDateTime?.ToString("O"), + Lti13ResourceLinkVariables.SubmissionStartDateTime when customPermissions.ResourceLinkSubmissionStartDateTime => scope.ResourceLink?.SubmissionStartDateTime?.ToString("O"), + Lti13ResourceLinkVariables.SubmissionUserStartDateTime when customPermissions.ResourceLinkSubmissionUserStartDateTime => attempt?.SubmisstionStartDateTime?.ToString("O"), + Lti13ResourceLinkVariables.SubmissionEndDateTime when customPermissions.ResourceLinkSubmissionEndDateTime => scope.ResourceLink?.SubmissionEndDateTime?.ToString("O"), + Lti13ResourceLinkVariables.SubmissionUserEndDateTime when customPermissions.ResourceLinkSubmissionUserEndDateTime => attempt?.SubmissionEndDateTime?.ToString("O"), + Lti13ResourceLinkVariables.LineItemReleaseDateTime when customPermissions.ResourceLinkLineItemReleaseDateTime => lineItem?.GradesReleasedDateTime?.ToString("O"), + Lti13ResourceLinkVariables.LineItemUserReleaseDateTime when customPermissions.ResourceLinkLineItemUserReleaseDateTime => grade?.ReleaseDateTime?.ToString("O"), + Lti13ResourceLinkVariables.IdHistory when customPermissions.ResourceLinkIdHistory => scope.ResourceLink?.ClonedIdHistory != null ? string.Join(',', scope.ResourceLink.ClonedIdHistory) : string.Empty, + + Lti13ToolPlatformVariables.ProductFamilyCode when customPermissions.ToolPlatformProductFamilyCode => platform?.ProductFamilyCode, + Lti13ToolPlatformVariables.Version when customPermissions.ToolPlatformProductVersion => platform?.Version, + Lti13ToolPlatformVariables.InstanceGuid when customPermissions.ToolPlatformProductInstanceGuid => platform?.Guid, + Lti13ToolPlatformVariables.InstanceName when customPermissions.ToolPlatformProductInstanceName => platform?.Name, + Lti13ToolPlatformVariables.InstanceDescription when customPermissions.ToolPlatformProductInstanceDescription => platform?.Description, + Lti13ToolPlatformVariables.InstanceUrl when customPermissions.ToolPlatformProductInstanceUrl => platform?.Url, + Lti13ToolPlatformVariables.InstanceContactEmail when customPermissions.ToolPlatformProductInstanceContactEmail => platform?.ContactEmail, _ => kvp.Value } ?? string.Empty; } diff --git a/NP.Lti13Platform.Core/Populators/RolesPopulator.cs b/NP.Lti13Platform.Core/Populators/RolesPopulator.cs index 0f879cf..10b6c4b 100644 --- a/NP.Lti13Platform.Core/Populators/RolesPopulator.cs +++ b/NP.Lti13Platform.Core/Populators/RolesPopulator.cs @@ -26,7 +26,7 @@ public override async Task PopulateAsync(IRolesMessage obj, MessageScope scope, if (obj.Roles.Contains(Lti13ContextRoles.Mentor)) { - obj.RoleScopeMentor = await dataService.GetMentoredUserIdsAsync(scope.Context.Id, scope.UserScope.User.Id, cancellationToken); + obj.RoleScopeMentor = membership.MentoredUserIds; } } } diff --git a/NP.Lti13Platform.Core/Services/ILti13CoreDataService.cs b/NP.Lti13Platform.Core/Services/ILti13CoreDataService.cs index 6a5a316..e7f80fa 100644 --- a/NP.Lti13Platform.Core/Services/ILti13CoreDataService.cs +++ b/NP.Lti13Platform.Core/Services/ILti13CoreDataService.cs @@ -10,7 +10,6 @@ public interface ILti13CoreDataService Task GetContextAsync(string contextId, CancellationToken cancellationToken = default); Task GetUserAsync(string userId, CancellationToken cancellationToken = default); Task GetMembershipAsync(string contextId, string userId, CancellationToken cancellationToken = default); - Task> GetMentoredUserIdsAsync(string contextId, string userId, CancellationToken cancellationToken = default); Task GetResourceLinkAsync(string resourceLinkId, CancellationToken cancellationToken = default); Task> GetLineItemsAsync(string deploymentId, string contextId, int pageIndex, int limit, string? resourceId = null, string? resourceLinkId = null, string? tag = null, CancellationToken cancellationToken = default); @@ -24,5 +23,7 @@ public interface ILti13CoreDataService Task> GetPublicKeysAsync(CancellationToken cancellationToken = default); Task GetPrivateKeyAsync(CancellationToken cancellationToken = default); + Task GetCustomPermissions(string deploymentId, CancellationToken cancellationToken = default); + Task GetUserPermissionsAsync(string deploymentId, string userId, CancellationToken cancellationToken = default); } } diff --git a/NP.Lti13Platform.Core/Startup.cs b/NP.Lti13Platform.Core/Startup.cs index 3f0a6e3..aa8f0cf 100644 --- a/NP.Lti13Platform.Core/Startup.cs +++ b/NP.Lti13Platform.Core/Startup.cs @@ -262,36 +262,38 @@ public static IEndpointRouteBuilder UseLti13PlatformCore(this IEndpointRouteBuil if (!isAnonymous) { + var userPermissions = await dataService.GetUserPermissionsAsync(deployment.Id, user.Id, cancellationToken); + ltiMessage.Subject = user.Id; - ltiMessage.Address = user.Address == null || !tool.UserPermissions.Address ? null : new AddressClaim + ltiMessage.Address = user.Address == null || !userPermissions.Address ? null : new AddressClaim { - Country = tool.UserPermissions.AddressCountry ? user.Address.Country : null, - Formatted = tool.UserPermissions.AddressFormatted ? user.Address.Formatted : null, - Locality = tool.UserPermissions.AddressLocality ? user.Address.Locality : null, - PostalCode = tool.UserPermissions.AddressPostalCode ? user.Address.PostalCode : null, - Region = tool.UserPermissions.AddressRegion ? user.Address.Region : null, - StreetAddress = tool.UserPermissions.AddressStreetAddress ? user.Address.StreetAddress : null + Country = userPermissions.AddressCountry ? user.Address.Country : null, + Formatted = userPermissions.AddressFormatted ? user.Address.Formatted : null, + Locality = userPermissions.AddressLocality ? user.Address.Locality : null, + PostalCode = userPermissions.AddressPostalCode ? user.Address.PostalCode : null, + Region = userPermissions.AddressRegion ? user.Address.Region : null, + StreetAddress = userPermissions.AddressStreetAddress ? user.Address.StreetAddress : null }; - ltiMessage.Birthdate = tool.UserPermissions.Birthdate ? user.Birthdate : null; - ltiMessage.Email = tool.UserPermissions.Email ? user.Email : null; - ltiMessage.EmailVerified = tool.UserPermissions.EmailVerified ? user.EmailVerified : null; - ltiMessage.FamilyName = tool.UserPermissions.FamilyName ? user.FamilyName : null; - ltiMessage.Gender = tool.UserPermissions.Gender ? user.Gender : null; - ltiMessage.GivenName = tool.UserPermissions.GivenName ? user.GivenName : null; - ltiMessage.Locale = tool.UserPermissions.Locale ? user.Locale : null; - ltiMessage.MiddleName = tool.UserPermissions.MiddleName ? user.MiddleName : null; - ltiMessage.Name = tool.UserPermissions.Name ? user.Name : null; - ltiMessage.Nickname = tool.UserPermissions.Nickname ? user.Nickname : null; - ltiMessage.PhoneNumber = tool.UserPermissions.PhoneNumber ? user.PhoneNumber : null; - ltiMessage.PhoneNumberVerified = tool.UserPermissions.PhoneNumberVerified ? user.PhoneNumberVerified : null; - ltiMessage.Picture = tool.UserPermissions.Picture ? user.Picture : null; - ltiMessage.PreferredUsername = tool.UserPermissions.PreferredUsername ? user.PreferredUsername : null; - ltiMessage.Profile = tool.UserPermissions.Profile ? user.Profile : null; - ltiMessage.UpdatedAt = tool.UserPermissions.UpdatedAt ? user.UpdatedAt : null; - ltiMessage.Website = tool.UserPermissions.Website ? user.Website : null; - ltiMessage.TimeZone = tool.UserPermissions.TimeZone ? user.TimeZone : null; + ltiMessage.Birthdate = userPermissions.Birthdate ? user.Birthdate : null; + ltiMessage.Email = userPermissions.Email ? user.Email : null; + ltiMessage.EmailVerified = userPermissions.EmailVerified ? user.EmailVerified : null; + ltiMessage.FamilyName = userPermissions.FamilyName ? user.FamilyName : null; + ltiMessage.Gender = userPermissions.Gender ? user.Gender : null; + ltiMessage.GivenName = userPermissions.GivenName ? user.GivenName : null; + ltiMessage.Locale = userPermissions.Locale ? user.Locale : null; + ltiMessage.MiddleName = userPermissions.MiddleName ? user.MiddleName : null; + ltiMessage.Name = userPermissions.Name ? user.Name : null; + ltiMessage.Nickname = userPermissions.Nickname ? user.Nickname : null; + ltiMessage.PhoneNumber = userPermissions.PhoneNumber ? user.PhoneNumber : null; + ltiMessage.PhoneNumberVerified = userPermissions.PhoneNumberVerified ? user.PhoneNumberVerified : null; + ltiMessage.Picture = userPermissions.Picture ? user.Picture : null; + ltiMessage.PreferredUsername = userPermissions.PreferredUsername ? user.PreferredUsername : null; + ltiMessage.Profile = userPermissions.Profile ? user.Profile : null; + ltiMessage.UpdatedAt = userPermissions.UpdatedAt ? user.UpdatedAt : null; + ltiMessage.Website = userPermissions.Website ? user.Website : null; + ltiMessage.TimeZone = userPermissions.TimeZone ? user.TimeZone : null; } var scope = new MessageScope( diff --git a/NP.Lti13Platform.NameRoleProvisioningServices/Populators/CustomPopulator.cs b/NP.Lti13Platform.NameRoleProvisioningServices/Populators/CustomPopulator.cs index 4f25750..53d4ebe 100644 --- a/NP.Lti13Platform.NameRoleProvisioningServices/Populators/CustomPopulator.cs +++ b/NP.Lti13Platform.NameRoleProvisioningServices/Populators/CustomPopulator.cs @@ -37,7 +37,7 @@ public override async Task PopulateAsync(ICustomMessage obj, MessageScope scope, var membership = await dataService.GetMembershipAsync(scope.Context.Id, scope.UserScope.User.Id, cancellationToken); if (membership != null && membership.Roles.Contains(Lti13ContextRoles.Mentor)) { - mentoredUserIds = await dataService.GetMentoredUserIdsAsync(scope.Context.Id, scope.UserScope.User.Id, cancellationToken); + mentoredUserIds = membership.MentoredUserIds; } } @@ -57,23 +57,25 @@ public override async Task PopulateAsync(ICustomMessage obj, MessageScope scope, attempt = await dataService.GetAttemptAsync(scope.ResourceLink.Id, scope.UserScope.User.Id, cancellationToken); } + var customPermissions = await dataService.GetCustomPermissions(scope.Deployment.Id, cancellationToken); + var dictionaryValues = customDictionary.ToList(); foreach (var kvp in dictionaryValues) { var value = kvp.Value switch { - Lti13UserVariables.Id when scope.Tool.CustomPermissions.UserId => scope.UserScope.User.Id, - Lti13UserVariables.Image when scope.Tool.CustomPermissions.UserImage => scope.UserScope.User.ImageUrl, - Lti13UserVariables.Username when scope.Tool.CustomPermissions.UserUsername => scope.UserScope.User.Username, - Lti13UserVariables.Org when scope.Tool.CustomPermissions.UserOrg => string.Join(',', scope.UserScope.User.Orgs), - Lti13UserVariables.ScopeMentor when scope.Tool.CustomPermissions.UserScopeMentor => string.Join(',', mentoredUserIds), - Lti13UserVariables.GradeLevelsOneRoster when scope.Tool.CustomPermissions.UserGradeLevelsOneRoster => string.Join(',', scope.UserScope.User.OneRosterGrades), + Lti13UserVariables.Id when customPermissions.UserId => scope.UserScope.User.Id, + Lti13UserVariables.Image when customPermissions.UserImage => scope.UserScope.User.ImageUrl, + Lti13UserVariables.Username when customPermissions.UserUsername => scope.UserScope.User.Username, + Lti13UserVariables.Org when customPermissions.UserOrg => string.Join(',', scope.UserScope.User.Orgs), + Lti13UserVariables.ScopeMentor when customPermissions.UserScopeMentor => string.Join(',', mentoredUserIds), + Lti13UserVariables.GradeLevelsOneRoster when customPermissions.UserGradeLevelsOneRoster => string.Join(',', scope.UserScope.User.OneRosterGrades), - Lti13ResourceLinkVariables.AvailableUserStartDateTime when scope.Tool.CustomPermissions.ResourceLinkAvailableUserStartDateTime => attempt?.AvailableStartDateTime?.ToString("O"), - Lti13ResourceLinkVariables.AvailableUserEndDateTime when scope.Tool.CustomPermissions.ResourceLinkAvailableUserEndDateTime => attempt?.AvailableEndDateTime?.ToString("O"), - Lti13ResourceLinkVariables.SubmissionUserStartDateTime when scope.Tool.CustomPermissions.ResourceLinkSubmissionUserStartDateTime => attempt?.SubmisstionStartDateTime?.ToString("O"), - Lti13ResourceLinkVariables.SubmissionUserEndDateTime when scope.Tool.CustomPermissions.ResourceLinkSubmissionUserEndDateTime => attempt?.SubmissionEndDateTime?.ToString("O"), - Lti13ResourceLinkVariables.LineItemUserReleaseDateTime when scope.Tool.CustomPermissions.ResourceLinkLineItemUserReleaseDateTime => grade?.ReleaseDateTime?.ToString("O"), + Lti13ResourceLinkVariables.AvailableUserStartDateTime when customPermissions.ResourceLinkAvailableUserStartDateTime => attempt?.AvailableStartDateTime?.ToString("O"), + Lti13ResourceLinkVariables.AvailableUserEndDateTime when customPermissions.ResourceLinkAvailableUserEndDateTime => attempt?.AvailableEndDateTime?.ToString("O"), + Lti13ResourceLinkVariables.SubmissionUserStartDateTime when customPermissions.ResourceLinkSubmissionUserStartDateTime => attempt?.SubmisstionStartDateTime?.ToString("O"), + Lti13ResourceLinkVariables.SubmissionUserEndDateTime when customPermissions.ResourceLinkSubmissionUserEndDateTime => attempt?.SubmissionEndDateTime?.ToString("O"), + Lti13ResourceLinkVariables.LineItemUserReleaseDateTime when customPermissions.ResourceLinkLineItemUserReleaseDateTime => grade?.ReleaseDateTime?.ToString("O"), _ => null }; diff --git a/NP.Lti13Platform.NameRoleProvisioningServices/Services/ILti13NameRoleProvisioningDataService.cs b/NP.Lti13Platform.NameRoleProvisioningServices/Services/ILti13NameRoleProvisioningDataService.cs index 116f632..e0b78c8 100644 --- a/NP.Lti13Platform.NameRoleProvisioningServices/Services/ILti13NameRoleProvisioningDataService.cs +++ b/NP.Lti13Platform.NameRoleProvisioningServices/Services/ILti13NameRoleProvisioningDataService.cs @@ -4,7 +4,7 @@ namespace NP.Lti13Platform.NameRoleProvisioningServices.Services { public interface ILti13NameRoleProvisioningDataService { - Task> GetMembershipsAsync(string deploymnetId, string contextId, int pageIndex, int limit, string? role, string? resourceLinkId, DateTime? asOfDate = null, CancellationToken cancellationToken = default); - Task> GetUsersAsync(IEnumerable userIds, DateTime? asOfDate = null, CancellationToken cancellationToken = default); + Task> GetMembershipsAsync(string deploymentId, string contextId, int pageIndex, int limit, string? role, string? resourceLinkId, DateTime? asOfDate = null, CancellationToken cancellationToken = default); + Task> GetUserPermissionsAsync(string deploymentId, IEnumerable userIds, CancellationToken cancellationToken = default); } } diff --git a/NP.Lti13Platform.NameRoleProvisioningServices/Startup.cs b/NP.Lti13Platform.NameRoleProvisioningServices/Startup.cs index 8ca8d70..2bd8881 100644 --- a/NP.Lti13Platform.NameRoleProvisioningServices/Startup.cs +++ b/NP.Lti13Platform.NameRoleProvisioningServices/Startup.cs @@ -141,7 +141,6 @@ public static IEndpointRouteBuilder UseLti13PlatformNameRoleProvisioningServices } var membersResponse = await nrpsDataService.GetMembershipsAsync(deploymentId, contextId, pageIndex, limit ?? int.MaxValue, role, rlid, cancellationToken: cancellationToken); - var usersResponse = await nrpsDataService.GetUsersAsync(membersResponse.Items.Select(m => m.UserId), cancellationToken: cancellationToken); var links = new Collection(); @@ -154,15 +153,14 @@ public static IEndpointRouteBuilder UseLti13PlatformNameRoleProvisioningServices httpContext.Response.Headers.Link = new StringValues([.. links]); - var currentUsers = membersResponse.Items.Join(usersResponse, x => x.UserId, x => x.Id, (m, u) => new { Membership = m, User = u, IsCurrent = true }); + var currentUsers = membersResponse.Items.Select(x => (x.Membership, x.User, IsCurrent: true)); if (since.HasValue) { var asOfDate = new DateTime(since.GetValueOrDefault()); var oldMembersResponse = await nrpsDataService.GetMembershipsAsync(deploymentId, contextId, pageIndex, limit ?? int.MaxValue, role, rlid, asOfDate, cancellationToken); - var oldUsersResponse = await nrpsDataService.GetUsersAsync(membersResponse.Items.Select(m => m.UserId), asOfDate, cancellationToken); - var oldUsers = oldMembersResponse.Items.Join(oldUsersResponse, x => x.UserId, x => x.Id, (m, u) => new { Membership = m, User = u, IsCurrent = false }); + var oldUsers = oldMembersResponse.Items.Select(x => (x.Membership, x.User, IsCurrent: false)); currentUsers = oldUsers .Concat(currentUsers) @@ -216,6 +214,12 @@ public static IEndpointRouteBuilder UseLti13PlatformNameRoleProvisioningServices } } + var usersWithRoles = currentUsers.Where(u => u.Membership.Roles.Any()); + + var userPermissions = await nrpsDataService.GetUserPermissionsAsync(deployment.Id, usersWithRoles.Select(u => u.User.Id), cancellationToken); + + var users = usersWithRoles.Join(userPermissions, u => u.User.Id, p => p.UserId, (u, p) => (u.User, u.Membership, p.UserPermissions, u.IsCurrent)); + return Results.Json(new { id = httpContext.Request.GetDisplayUrl(), @@ -225,17 +229,17 @@ public static IEndpointRouteBuilder UseLti13PlatformNameRoleProvisioningServices label = context.Label, title = context.Title }, - members = currentUsers.Where(u => u.Membership.Roles.Any()).Select(x => + members = users.Select(x => { return new { user_id = x.User.Id, roles = x.Membership.Roles, - name = tool.UserPermissions.Name ? x.User.Name : null, - given_name = tool.UserPermissions.GivenName ? x.User.GivenName : null, - family_name = tool.UserPermissions.FamilyName ? x.User.FamilyName : null, - email = tool.UserPermissions.Email ? x.User.Email : null, - picture = tool.UserPermissions.Picture ? x.User.Picture : null, + name = x.UserPermissions.Name ? x.User.Name : null, + given_name = x.UserPermissions.GivenName ? x.User.GivenName : null, + family_name = x.UserPermissions.FamilyName ? x.User.FamilyName : null, + email = x.UserPermissions.Email ? x.User.Email : null, + picture = x.UserPermissions.Picture ? x.User.Picture : null, status = x.Membership.Status switch { MembershipStatus.Active when x.IsCurrent => ACTIVE, diff --git a/NP.Lti13Platform.Test/NP.Lti13Platform.Test.csproj b/NP.Lti13Platform.Test/NP.Lti13Platform.Test.csproj index bea756b..671e8fc 100644 --- a/NP.Lti13Platform.Test/NP.Lti13Platform.Test.csproj +++ b/NP.Lti13Platform.Test/NP.Lti13Platform.Test.csproj @@ -10,14 +10,14 @@ - - - - + + + + runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/NP.Lti13Platform.WebExample/Program.cs b/NP.Lti13Platform.WebExample/Program.cs index bc58a61..13c6f2d 100644 --- a/NP.Lti13Platform.WebExample/Program.cs +++ b/NP.Lti13Platform.WebExample/Program.cs @@ -82,8 +82,6 @@ static DataService() LaunchUrl = "https://saltire.lti.app/tool", DeepLinkUrl = "https://saltire.lti.app/tool", Jwks = "https://saltire.lti.app/tool/jwks/1e49d5cbb9f93e9bb39a4c3cfcda929d", - UserPermissions = new UserPermissions { FamilyName = true, Name = true, GivenName = true }, - CustomPermissions = new CustomPermissions() { UserUsername = true }, ServiceScopes = [ AssignmentGradeServices.ServiceScopes.LineItem, @@ -118,7 +116,8 @@ static DataService() ContextId = "contextId", Roles = [], Status = MembershipStatus.Active, - UserId = "userId" + UserId = "userId", + MentoredUserIds = [] }); } @@ -147,11 +146,6 @@ static DataService() return Task.FromResult(Memberships.SingleOrDefault(m => m.ContextId == contextId && m.UserId == userId)); } - Task> ILti13CoreDataService.GetMentoredUserIdsAsync(string contextId, string userId, CancellationToken cancellationToken) - { - return Task.FromResult>([]); - } - Task ILti13CoreDataService.GetResourceLinkAsync(string resourceLinkId, CancellationToken cancellationToken) { return Task.FromResult(ResourceLinks.SingleOrDefault(r => r.Id == resourceLinkId)); @@ -271,25 +265,21 @@ Task ILti13CoreDataService.GetPrivateKeyAsync(CancellationToken can - Task> ILti13NameRoleProvisioningDataService.GetMembershipsAsync(string deploymentId, string contextId, int pageIndex, int limit, string? role, string? resourceLinkId, DateTime? asOfDate, CancellationToken cancellationToken) + Task> ILti13NameRoleProvisioningDataService.GetMembershipsAsync(string deploymentId, string contextId, int pageIndex, int limit, string? role, string? resourceLinkId, DateTime? asOfDate, CancellationToken cancellationToken) { if (ResourceLinks.Any(x => x.ContextId == contextId && x.DeploymentId == deploymentId && (resourceLinkId == null || resourceLinkId == x.Id))) { var memberships = Memberships.Where(m => m.ContextId == contextId && (role == null || m.Roles.Contains(role))).ToList(); + var users = Users.Where(u => memberships.Select(m => m.UserId).Contains(u.Id)).ToList(); - return Task.FromResult(new PartialList + return Task.FromResult(new PartialList<(Membership, User)> { - Items = memberships.Skip(pageIndex * limit).Take(limit).ToList(), + Items = memberships.Join(users, m => m.UserId, u => u.Id, (m, u) => (m, u)).Skip(pageIndex * limit).Take(limit).ToList(), TotalItems = memberships.Count }); } - return Task.FromResult(PartialList.Empty); - } - - Task> ILti13NameRoleProvisioningDataService.GetUsersAsync(IEnumerable userIds, DateTime? asOfDate, CancellationToken cancellationToken) - { - return Task.FromResult(Users.Where(x => userIds.Contains(x.Id))); + return Task.FromResult(PartialList<(Membership, User)>.Empty); } @@ -333,5 +323,20 @@ Task ILti13AssignmentGradeDataService.DeleteLineItemAsync(string lineItemId, Can return Task.CompletedTask; } + + Task ILti13CoreDataService.GetCustomPermissions(string deploymentId, CancellationToken cancellationToken) + { + return Task.FromResult(new CustomPermissions { UserId = true, UserUsername = true }); + } + + public Task GetUserPermissionsAsync(string deploymentId, string userId, CancellationToken cancellationToken = default) + { + return Task.FromResult(new UserPermissions { FamilyName = true, Name = true, GivenName = true }); + } + + public Task> GetUserPermissionsAsync(string deploymentId, IEnumerable userIds, CancellationToken cancellationToken = default) + { + return Task.FromResult(userIds.Select(x => (x, new UserPermissions { FamilyName = true, Name = true, GivenName = true }))); + } } } \ No newline at end of file