Example #1
0
        public async Task <UserQueryResultListModel> QueryUser(string patterns)
        {
            var user = await userManager.GetUserAsync(User);

            IQueryable <UserInfo> users;

            if (PrivilegeHelper.IsTeacher(user.Privilege))
            {
                users = userManager.Users.Where(i =>
                                                (i.Name != null && i.Name.Contains(patterns)) ||
                                                i.NormalizedEmail.Contains(patterns.ToUpperInvariant()) ||
                                                i.NormalizedUserName.Contains(patterns.ToUpperInvariant()));
            }
            else
            {
                users = userManager.Users.Where(i => i.NormalizedUserName.Contains(patterns.ToUpper()));
            }

            var result = users.Select(i => new UserQueryResultModel
            {
                UserId   = i.Id,
                UserName = i.UserName,
                Name     = i.Name,
                Email    = i.Email
            });

            return(new UserQueryResultListModel
            {
                Users = await result.ToListAsync(),
                TotalCount = await result.CountAsync()
            });
        }
Example #2
0
        public async Task <IQueryable <Contest> > QueryContestAsync(string?userId, int groupId)
        {
            var user = await userManager.FindByIdAsync(userId);

            var group = await groupService.GetGroupAsync(groupId);

            if (group is null)
            {
                throw new NotFoundException("找不到该小组");
            }

            if (!PrivilegeHelper.IsTeacher(user?.Privilege))
            {
                if (group.IsPrivate)
                {
                    if (!dbContext.GroupJoin.Any(i => i.GroupId == groupId && i.UserId == userId))
                    {
                        throw new ForbiddenException("未参加该小组");
                    }
                }
            }

            IQueryable <Contest> contests = dbContext.GroupContestConfig
                                            .Where(i => i.GroupId == groupId).OrderByDescending(i => i.Id).Select(i => i.Contest);

            return(contests);
        }
Example #3
0
        public async Task <IQueryable <Problem> > QueryProblemAsync(string?userId, int contestId)
        {
            var user = await userManager.FindByIdAsync(userId);

            var contest = await contestService.GetContestAsync(contestId);

            if (contest is null)
            {
                throw new NotFoundException("找不到该比赛");
            }

            if (!PrivilegeHelper.IsTeacher(user?.Privilege))
            {
                if (contest.Hidden)
                {
                    throw new ForbiddenException();
                }
            }

            IQueryable <Problem> problems = dbContext.ContestProblemConfig
                                            .Where(i => i.ContestId == contestId)
                                            .OrderBy(i => i.Id)
                                            .Select(i => i.Problem);

            return(problems);
        }
Example #4
0
        public async Task <IQueryable <Contest> > QueryContestAsync(string?userId)
        {
            var user = await userManager.FindByIdAsync(userId);

            IQueryable <Contest> contests = dbContext.Contest;

            if (!PrivilegeHelper.IsTeacher(user?.Privilege))
            {
                contests = contests.Where(i => !i.Hidden || (i.SpecifyCompetitors && i.ContestRegister.Any(j => j.ContestId == i.Id && j.UserId == userId)));
            }
            return(contests);
        }
Example #5
0
        public async Task <IQueryable <Problem> > QueryProblemAsync(string?userId)
        {
            var user = await userManager.FindByIdAsync(userId);

            IQueryable <Problem> problems = dbContext.Problem;

            if (!PrivilegeHelper.IsTeacher(user?.Privilege))
            {
                problems = problems.Where(i => !i.Hidden);
            }

            return(problems);
        }
Example #6
0
        public async Task <IQueryable <Group> > QueryGroupAsync(string?userId)
        {
            var user = await userManager.FindByIdAsync(userId);

            IQueryable <Group> groups = dbContext.Group;

            if (!PrivilegeHelper.IsTeacher(user?.Privilege))
            {
                groups = groups.Where(i => (i.IsPrivate && i.GroupJoin.Any(j => j.GroupId == i.Id && j.UserId == userId)) || !i.IsPrivate);
            }

            return(groups);
        }
            public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
            {
                var dbContext = context.HttpContext.RequestServices.GetService <WebHostDbContext>();

                var userId   = context.HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier);
                var userInfo = await dbContext.Users.FirstOrDefaultAsync(i => i.Id == userId);

                if (userInfo == null)
                {
                    throw new AuthenticationException("没有登录账户");
                }
                if (!PrivilegeHelper.IsTeacher(userInfo?.Privilege ?? 0))
                {
                    throw new ForbiddenException();
                }

                await next();
            }
Example #8
0
        public async Task <IQueryable <Problem> > QueryProblemAsync(string?userId, int contestId, int groupId)
        {
            var user = await userManager.FindByIdAsync(userId);

            var contest = await contestService.GetContestAsync(contestId);

            if (contest is null)
            {
                throw new NotFoundException("找不到该比赛");
            }

            var group = await groupService.GetGroupAsync(groupId);

            if (group is null)
            {
                throw new NotFoundException("找不到该小组");
            }

            if (!dbContext.GroupContestConfig.Any(i => i.GroupId == groupId && i.ContestId == contestId))
            {
                throw new NotFoundException("找不到该比赛");
            }

            if (!PrivilegeHelper.IsTeacher(user?.Privilege))
            {
                if (contest.Hidden)
                {
                    throw new ForbiddenException();
                }

                // user was not in this private group
                if (group.IsPrivate && !dbContext.GroupJoin.Any(i => i.GroupId == groupId && i.UserId == userId))
                {
                    throw new ForbiddenException("未参加该小组");
                }
            }

            IQueryable <Problem> problems = dbContext.ContestProblemConfig
                                            .Where(i => i.ContestId == contestId)
                                            .OrderBy(i => i.Id)
                                            .Select(i => i.Problem);

            return(problems);
        }
Example #9
0
        public async Task <UserInfoModel> UserInfo(string?userId = null)
        {
            var signedIn    = signInManager.IsSignedIn(User);
            var userInfoRet = new UserInfoModel
            {
                SignedIn = string.IsNullOrEmpty(userId) && signedIn
            };

            if (string.IsNullOrEmpty(userId))
            {
                userId = userManager.GetUserId(User);
            }
            var user = await userManager.FindByIdAsync(userId);

            var currentUser = string.IsNullOrEmpty(userId) ? user : await userManager.GetUserAsync(User);

            if (userId == null || user == null)
            {
                return(new UserInfoModel());
            }
            userInfoRet.UserId     = user.Id;
            userInfoRet.UserName   = user.UserName;
            userInfoRet.Privilege  = user.Privilege;
            userInfoRet.Coins      = user.Coins;
            userInfoRet.Experience = user.Experience;
            userInfoRet.OtherInfo  = IdentityHelper.GetOtherUserInfo(string.IsNullOrEmpty(user.OtherInfo) ? "{}" : user.OtherInfo);

            if (userInfoRet.SignedIn || PrivilegeHelper.IsTeacher(currentUser?.Privilege))
            {
                userInfoRet.Name                 = user.Name;
                userInfoRet.EmailConfirmed       = user.EmailConfirmed;
                userInfoRet.PhoneNumberConfirmed = user.PhoneNumberConfirmed;
                userInfoRet.Email                = user.Email;
                userInfoRet.PhoneNumber          = user.PhoneNumber;
            }

            return(userInfoRet);
        }
Example #10
0
        public async Task <SubmitSuccessModel> SubmitSolution([FromBody] SubmitModel model)
        {
            var user = await userManager.GetUserAsync(User);

            var now = DateTime.Now;
            var allowJumpToResult = true;

            if (user.Privilege == 5)
            {
                throw new ForbiddenException("不允许提交,请与管理员联系");
            }

            if (model.GroupId != 0)
            {
                var inGroup = await groupService.IsInGroupAsync(user.Id, model.GroupId);

                if (!inGroup)
                {
                    throw new ForbiddenException("未参加该小组");
                }
            }

            var problem = await problemService.GetProblemAsync(model.ProblemId);

            if (problem == null)
            {
                throw new NotFoundException("该题目不存在");
            }
            var problemConfig = problem.Config.DeserializeJson <ProblemConfig>(false);

            // For older version compatibility
            if (problemConfig.SourceFiles.Count == 0)
            {
                problemConfig.SourceFiles.Add(string.IsNullOrEmpty(problemConfig.SubmitFileName) ? "${random}${extension}" : $"{problemConfig.SubmitFileName}${{extension}}");
            }

            var sources = new List <Source>();

            foreach (var i in model.Content)
            {
                if (problemConfig.CodeSizeLimit != 0 && problemConfig.CodeSizeLimit < Encoding.UTF8.GetByteCount(i.Content))
                {
                    throw new BadRequestException("提交内容长度超出限制");
                }
                if (problemConfig.SourceFiles.Contains(i.FileName))
                {
                    sources.Add(new Source
                    {
                        FileName = i.FileName,
                        Content  = i.Content
                    });
                }
            }

            var useDefaultDisabledConfig = false;

            var langConfig = (await languageService.GetLanguageConfigAsync()).ToList();
            var langs      = problemConfig.Languages?.Split(';', StringSplitOptions.RemoveEmptyEntries) ?? new string[0];

            if (langs.Length == 0)
            {
                langs = langConfig.Select(i => i.Name).ToArray();
            }
            else
            {
                useDefaultDisabledConfig = true;
            }

            if (model.ContestId != 0)
            {
                var contest = await contestService.GetContestAsync(model.ContestId);

                if (contest != null)
                {
                    if (contest.StartTime > now || now > contest.EndTime)
                    {
                        throw new ForbiddenException("当前不允许提交");
                    }
                    if (contest.Hidden && !PrivilegeHelper.IsTeacher(user.Privilege))
                    {
                        throw new NotFoundException("该比赛不存在");
                    }

                    var contestConfig = contest.Config.DeserializeJson <ContestConfig>(false);
                    if (contestConfig.SubmissionLimit != 0)
                    {
                        var judges = await judgeService.QueryJudgesAsync(user.Id,
                                                                         model.GroupId == 0?null : (int?)model.GroupId,
                                                                         model.ContestId,
                                                                         model.ProblemId);

                        if (contestConfig.SubmissionLimit <= await judges.CountAsync())
                        {
                            throw new ForbiddenException("超出提交次数限制");
                        }
                    }
                    if (contestConfig.ResultMode != ResultDisplayMode.Intime)
                    {
                        allowJumpToResult = false;
                    }
                    var contestLangs = contestConfig.Languages?.Split(';', StringSplitOptions.RemoveEmptyEntries) ?? new string[0];
                    if (contestLangs.Length != 0)
                    {
                        langs = langs.Intersect(contestLangs).ToArray();
                        useDefaultDisabledConfig = true;
                    }
                }
            }
            else if (problem.Hidden && !PrivilegeHelper.IsTeacher(user.Privilege))
            {
                throw new NotFoundException("该题目不存在");
            }

            if (!useDefaultDisabledConfig)
            {
                langs = langs.Where(i => langConfig.Any(j => j.Name == i && !j.DisabledByDefault)).ToArray();
            }

            if (!langs.Contains(model.Language))
            {
                throw new ForbiddenException("不允许使用该语言提交");
            }

            user.SubmissionCount++;
            await userManager.UpdateAsync(user);

            var id = await judgeService.QueueJudgeAsync(new Judge
            {
                Content        = sources.SerializeJsonAsString(),
                Language       = model.Language,
                ProblemId      = model.ProblemId,
                ContestId      = model.ContestId == 0 ? null : (int?)model.ContestId,
                GroupId        = model.GroupId == 0 ? null : (int?)model.GroupId,
                UserId         = user.Id,
                Description    = "Online Judge",
                AdditionalInfo = "v2"
            });

            return(new SubmitSuccessModel
            {
                Jump = allowJumpToResult,
                ResultId = id
            });
        }
Example #11
0
        public async Task <ResultModel> GetJudgeResult(int id)
        {
            var user = await userManager.GetUserAsync(User);

            var judge = await judgeService.GetJudgeAsync(id);

            if (judge == null)
            {
                throw new NotFoundException("评测结果不存在");
            }
            if (!PrivilegeHelper.IsTeacher(user.Privilege) && judge.UserId != user.Id && !judge.IsPublic)
            {
                throw new ForbiddenException("没有权限查看该评测结果");
            }

            var ret = new ResultModel
            {
                ResultId    = judge.Id,
                UserId      = judge.UserId,
                UserName    = judge.UserInfo.UserName,
                ProblemId   = judge.ProblemId,
                ProblemName = judge.Problem.Name,
                ContestId   = judge.ContestId,
                ContestName = judge.Contest?.Name,
                GroupId     = judge.GroupId,
                GroupName   = judge.Group?.Name,
                ResultType  = judge.ResultType,
                Content     = judge.AdditionalInfo == "v2" ?
                              judge.Content.DeserializeJson <List <Source> >() :
                              new List <Source>
                {
                    new Source
                    {
                        FileName = "default",
                        Content  = judge.Content
                    }
                },
                Time        = judge.JudgeTime,
                Language    = judge.Language,
                JudgeResult = (string.IsNullOrWhiteSpace(judge.Result) ? "{}" : judge.Result)
                              .DeserializeJson <JudgeResult>(false)
            };

            ret.JudgeResult.JudgePoints ??= new List <JudgePoint>();

            if (judge.ContestId != null && !PrivilegeHelper.IsTeacher(user.Privilege))
            {
                var contest = await contestService.GetContestAsync(judge.ContestId.Value);

                if (contest != null)
                {
                    var config = contest.Config.DeserializeJson <ContestConfig>(false);
                    if (!config.CanMakeResultPublic && !PrivilegeHelper.IsTeacher(user.Privilege) && judge.UserId != user.Id)
                    {
                        throw new ForbiddenException("没有权限查看该评测结果");
                    }
                    switch (config.ResultMode)
                    {
                    case ResultDisplayMode.Never:
                        throw new ForbiddenException("当前不允许查看该评测结果");

                    case ResultDisplayMode.AfterContest:
                        if (DateTime.Now < contest.EndTime)
                        {
                            throw new ForbiddenException("当前不允许查看该评测结果");
                        }
                        break;
                    }
                    ret.ResultDisplayType = config.ResultType switch
                    {
                        ResultDisplayType.Summary => 1,
                        _ => 0
                    };
                }
            }

            return(ret);
        }
    }
Example #12
0
        public async Task <RankContestStatisticsModel> GetRankForContest(int contestId, int groupId)
        {
            var user = await userManager.GetUserAsync(User);

            var contest = await contestService.GetContestAsync(contestId);

            if (contest is null)
            {
                throw new NotFoundException("该比赛不存在");
            }
            if (groupId != 0)
            {
                var groups = await groupService.QueryGroupAsync(user?.Id);

                groups = groups.Where(i => i.GroupContestConfig.Any(j => j.ContestId == contestId && j.GroupId == groupId));
                if (!await groups.AnyAsync())
                {
                    throw new NotFoundException("该比赛不存在或未加入对应小组");
                }
            }

            var config = contest.Config.DeserializeJson <ContestConfig>(false);

            if (!config.ShowRank && !PrivilegeHelper.IsTeacher(user?.Privilege))
            {
                throw new ForbiddenException("不允许查看排名");
            }

            var judges = await judgeService.QueryJudgesAsync(null,
                                                             groupId == 0?null : (int?)groupId,
                                                             contestId);

            if (config.AutoStopRank && !PrivilegeHelper.IsTeacher(user?.Privilege) && DateTime.Now < contest.EndTime)
            {
                var time = contest.EndTime.AddHours(-1);
                judges = judges.Where(i => i.JudgeTime < time);
            }

            var ret = new RankContestStatisticsModel
            {
                ContestId = contestId,
                GroupId   = groupId
            };

            var results = judges.OrderBy(i => i.Id).Select(i => new
            {
                i.Id,
                i.ProblemId,
                ProblemName = i.Problem.Name,
                i.UserId,
                i.UserInfo.UserName,
                i.UserInfo.Name,
                i.ResultType,
                Time  = i.JudgeTime,
                Score = i.FullScore
            }).Cacheable();

            var isAccepted = new Dictionary <(string UserId, int ProblemId), bool>();

            foreach (var i in results)
            {
                if (!ret.UserInfos.ContainsKey(i.UserId))
                {
                    ret.UserInfos[i.UserId] = new RankUserInfoModel
                    {
                        UserName = i.UserName,
                        Name     = PrivilegeHelper.IsTeacher(user?.Privilege) ? i.Name : string.Empty
                    }
                }
                ;
                if (!ret.ProblemInfos.ContainsKey(i.ProblemId))
                {
                    ret.ProblemInfos[i.ProblemId] = new RankProblemInfoModel
                    {
                        ProblemName = i.ProblemName
                    }
                }
                ;
                if (!ret.RankInfos.ContainsKey(i.UserId))
                {
                    ret.RankInfos[i.UserId] = new Dictionary <int, RankContestItemModel>();
                }
                if (!ret.RankInfos[i.UserId].ContainsKey(i.ProblemId))
                {
                    ret.RankInfos[i.UserId][i.ProblemId] = new RankContestItemModel();
                }

                if (config.Type != ContestType.LastSubmit)
                {
                    ret.RankInfos[i.UserId][i.ProblemId].Accepted = ret.RankInfos[i.UserId][i.ProblemId].Accepted || (i.ResultType == (int)ResultCode.Accepted);
                }
                else
                {
                    ret.RankInfos[i.UserId][i.ProblemId].Accepted = ret.RankInfos[i.UserId][i.ProblemId].Accepted && (i.ResultType == (int)ResultCode.Accepted);
                }

                if (!isAccepted.ContainsKey((i.UserId, i.ProblemId)))
                {
                    isAccepted[(i.UserId, i.ProblemId)] = false;