Example #1
0
 /* 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);
        }
Example #3
0
        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));
        }
Example #4
0
        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()
            });
        }
Example #5
0
        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,
                }
            });
        }
Example #6
0
        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);
        }