/* Pass limit=0 to disable limiting */ public async Task <List <UserRolesInfo> > GetCourseInstructorsAsync(string courseId, int limit = 50) { return(await db.Users .Where(u => !u.IsDeleted) .FilterByUserIds(await courseRoleUsersFilter.GetListOfUsersWithCourseRoleAsync(CourseRoleType.Instructor, courseId, includeHighRoles: true).ConfigureAwait(false)) .GetUserRolesInfoAsync(limit, userManager) .ConfigureAwait(false)); }
private async Task CopyGroupAccessesAsync(Group group, Group newGroup) { logger.Information($"Копирую доступы к группе «{group.Name}» (id={group.Id}) в группу «{newGroup.Name}» (id={newGroup.Id})"); var accesses = await db.GroupAccesses.Where(a => a.GroupId == group.Id && a.IsEnabled).ToListAsync().ConfigureAwait(false); var courseInstructorsIds = await courseRoleUsersFilter.GetListOfUsersWithCourseRoleAsync(CourseRoleType.Instructor, newGroup.CourseId, includeHighRoles : true).ConfigureAwait(false); foreach (var access in accesses) { if (!courseInstructorsIds.Contains(access.UserId)) { continue; } if (newGroup.OwnerId == access.UserId) { continue; } db.GroupAccesses.Add(new GroupAccess { GroupId = newGroup.Id, UserId = access.UserId, AccessType = access.AccessType, GrantedById = access.GrantedById, GrantTime = DateTime.Now, IsEnabled = true, }); } await db.SaveChangesAsync().ConfigureAwait(false); }
public async Task <List <UserRolesInfo> > FindUsers(UserSearchQuery query, int limit = 100) { var role = db.Roles.FirstOrDefault(r => r.Name == query.Role); var users = db.Users.Where(u => !u.IsDeleted); if (!string.IsNullOrEmpty(query.NamePrefix)) { var usersIds = GetUsersByNamePrefix(query.NamePrefix).Select(u => u.Id); users = users.Where(u => usersIds.Contains(u.Id)); } return(await users .FilterByRole(role, userManager) .FilterByUserIds( await courseRoleUsersFilter.GetListOfUsersWithCourseRoleAsync(query.CourseRoleType, query.CourseId, query.IncludeHighCourseRoles).ConfigureAwait(false), await courseRoleUsersFilter.GetListOfUsersByPrivilegeAsync(query.OnlyPrivileged, query.CourseId).ConfigureAwait(false) ) .GetUserRolesInfoAsync(limit, userManager).ConfigureAwait(false)); }
public async Task <ActionResult <InstructorsListResponse> > InstructorsList(Course course) { if (course == null) { return(NotFound()); } var instructorIds = await courseRoleUsersFilter.GetListOfUsersWithCourseRoleAsync(CourseRoleType.Instructor, course.Id, includeHighRoles : true).ConfigureAwait(false); var instructors = await usersRepo.GetUsersByIdsAsync(instructorIds).ConfigureAwait(false); return(new InstructorsListResponse { Instructors = instructors.Select(i => BuildShortUserInfo(i, discloseLogin: true)).ToList() }); }
public async Task <ActionResult <UsersSearchResponse> > Search([FromQuery] UsersSearchParameters parameters) { var words = parameters.Query?.Split(' ', '\t').ToList() ?? new List <string>(); if (words.Count > 10) { return(BadRequest(new ErrorResponse("Too many words in query"))); } var currentUser = await usersRepo.FindUserByIdAsync(UserId).ConfigureAwait(false); var isSystemAdministrator = usersRepo.IsSystemAdministrator(currentUser); if (!string.IsNullOrEmpty(parameters.CourseId)) { if (!parameters.CourseRoleType.HasValue) { return(BadRequest(new ErrorResponse("You should specify course_role with course_id"))); } if (parameters.CourseRoleType == CourseRoleType.Student) { return(BadRequest(new ErrorResponse("You can not search students by this method: there are too many students"))); } /* Only instructors can search by course role */ var isInstructor = await courseRolesRepo.HasUserAccessToCourseAsync(UserId, parameters.CourseId, CourseRoleType.Instructor).ConfigureAwait(false); if (!isInstructor) { return(StatusCode((int)HttpStatusCode.Unauthorized, new ErrorResponse("Only instructors can search by course role"))); } } else if (parameters.CourseRoleType.HasValue) { /* Only sys-admins can search all instructors or all course-admins */ if (!isSystemAdministrator) { return(StatusCode((int)HttpStatusCode.Unauthorized, new ErrorResponse("Only system administrator can search by course role without specified course_id"))); } } if (parameters.LmsRoleType.HasValue) { if (!isSystemAdministrator) { return(StatusCode((int)HttpStatusCode.Unauthorized, new ErrorResponse("Only system administrator can search by lms role"))); } } var request = new UserSearchRequest { CurrentUser = currentUser, Words = words, CourseId = parameters.CourseId, MinCourseRoleType = parameters.CourseRoleType, LmsRole = parameters.LmsRoleType, }; /* Start the search! * First of all we will try to find `strict` users: users with strict match for pattern. These users will be at first place in the response. */ var strictUsers = await userSearcher.SearchUsersAsync(request, strict : true, offset : 0, count : parameters.Offset + parameters.Count).ConfigureAwait(false); var users = strictUsers.ToList(); /* If strict users count is enough for answer, just take needed piece of list */ if (users.Count >= parameters.Offset + parameters.Count) { users = users.Skip(parameters.Offset).Take(parameters.Count).ToList(); } else { /* If there is part of strict users which we should return, then cut off it */ if (parameters.Offset < users.Count) { users = users.Skip(parameters.Offset).ToList(); } else { users.Clear(); } /* * (strict users) (non-strict users) * 0 1 2 3 4 5 6 * ^ ^ * offset offset+count */ var nonStrictUsers = await userSearcher.SearchUsersAsync(request, strict : false, offset : parameters.Offset - strictUsers.Count, count : parameters.Count - users.Count).ConfigureAwait(false); /* Add all non-strict users if there is no this user in strict users list */ foreach (var user in nonStrictUsers) { var alreadyExistUser = strictUsers.FirstOrDefault(u => u.User.Id == user.User.Id); if (alreadyExistUser != null) { alreadyExistUser.Fields.UnionWith(user.Fields); } else { users.Add(user); } } } var instructors = await courseRoleUsersFilter.GetListOfUsersWithCourseRoleAsync(CourseRoleType.Instructor, null, true).ConfigureAwait(false); var currentUserIsInstructor = instructors.Contains(User.GetUserId()); return(new UsersSearchResponse { Users = users.Select(u => new FoundUserResponse { User = BuildShortUserInfo(u.User, discloseLogin: u.Fields.Contains(SearchField.Login) || currentUserIsInstructor && instructors.Contains(u.User.Id), discloseEmail: u.Fields.Contains(SearchField.Email)), Fields = u.Fields.ToList(), }).ToList(), Pagination = new PaginationResponse { Offset = parameters.Offset, Count = users.Count, } }); }
public async Task <ActionResult <CodeReviewInstructorsStatisticsResponse> > InstructorsStatistics(Course course, int count = 10000, DateTime?from = null, DateTime?to = null) { if (course == null) { return(NotFound()); } if (!from.HasValue) { from = DateTime.MinValue; } if (!to.HasValue) { to = DateTime.MaxValue; } count = Math.Min(count, 10000); var instructorIds = await courseRoleUsersFilter.GetListOfUsersWithCourseRoleAsync(CourseRoleType.Instructor, course.Id).ConfigureAwait(false); var instructors = await usersRepo.GetUsersByIdsAsync(instructorIds).ConfigureAwait(false); var exerciseSlides = course.Slides.OfType <ExerciseSlide>().ToList(); var allSlideCheckings = await slideCheckingsRepo.GetManualCheckingQueueAsync <ManualExerciseChecking>(new ManualCheckingQueueFilterOptions { CourseId = course.Id, Count = count, OnlyChecked = null, From = @from.Value, To = to.Value, }).Include(c => c.Reviews).ToListAsync().ConfigureAwait(false); var result = new CodeReviewInstructorsStatisticsResponse { AnalyzedCodeReviewsCount = allSlideCheckings.Count, Instructors = new List <CodeReviewInstructorStatistics>() }; foreach (var instructor in instructors) { var checkingsCheckedByInstructor = allSlideCheckings.Where(c => c.IsChecked && (c.LockedById == instructor.Id || c.Reviews.Any(r => r.AuthorId == instructor.Id))).ToList(); var instructorGroups = await groupsRepo.GetMyGroupsFilterAccessibleToUserAsync(course.Id, instructor.Id).ConfigureAwait(false); var instructorGroupMemberIds = (await groupMembersRepo.GetGroupsMembersAsync(instructorGroups.Select(g => g.Id)).ConfigureAwait(false)).Select(m => m.UserId); var checkingQueue = allSlideCheckings.Where(c => !c.IsChecked && instructorGroupMemberIds.Contains(c.UserId)).ToList(); var comments = checkingsCheckedByInstructor.SelectMany(c => c.NotDeletedReviews).ToList(); var instructorStatistics = new CodeReviewInstructorStatistics { Instructor = BuildShortUserInfo(instructor, discloseLogin: true), Exercises = exerciseSlides.Select( slide => new CodeReviewExerciseStatistics { SlideId = slide.Id, ReviewedSubmissionsCount = checkingsCheckedByInstructor.Where(c => c.SlideId == slide.Id).DistinctBy(c => c.SubmissionId).Count(), QueueSize = checkingQueue.Count(c => c.SlideId == slide.Id), CommentsCount = comments.Count(c => c.ExerciseChecking.SlideId == slide.Id), } ) .Where(s => s.ReviewedSubmissionsCount + s.QueueSize + s.CommentsCount > 0) // Ignore empty (zeros) records .ToList() }; result.Instructors.Add(instructorStatistics); } return(result); }