Example #1
0
        private async Task ValidateSubmissionCreateDtoAsync(SubmissionCreateDto dto)
        {
            var problem = await Context.Problems.FindAsync(dto.ProblemId);

            if (problem is null)
            {
                throw new ValidationException("Invalid problem ID.");
            }

            switch (problem.Type)
            {
            case ProblemType.Ordinary:
                if (dto.Program.Language == Language.LabArchive)
                {
                    throw new ValidationException("Ordinary problem does not accept this language..");
                }
                else if (!Regex.IsMatch(dto.Program.Code, @"^[a-zA-Z0-9\+/]*={0,3}$", RegexOptions.None))
                {
                    throw new ValidationException("Invalid program code.");
                }
                break;

            case ProblemType.TestKitLab:
                throw new ValidationException("Cannot submit testkit lab problems through this API.");

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Example #2
0
        public async Task <SubmissionInfoDto> CreateSubmissionAsync(SubmissionCreateDto dto)
        {
            await ValidateSubmissionCreateDtoAsync(dto);

            var submission = new Submission
            {
                UserId    = Accessor.HttpContext.User.GetSubjectId(),
                ProblemId = dto.ProblemId.GetValueOrDefault(),
                Program   = dto.Program,
                Hidden    = true,
                Verdict   = Verdict.Pending,
                Time      = null,
                Memory    = null,
                FailedOn  = null,
                Score     = null,
                Progress  = null,
                Message   = null,
                JudgedBy  = null,
                JudgedAt  = null
            };
            await Context.Submissions.AddAsync(submission);

            await Context.SaveChangesAsync();

            _queue.EnqueueTask(new JobRequestMessage(JobType.JudgeSubmission, submission.Id, 1));

            await Context.Entry(submission).Reference(s => s.User).LoadAsync();

            var result = new SubmissionInfoDto(submission, true);

            await LogInformation($"CreateSubmission [Admin] ProblemId={result.ProblemId} " +
                                 $"Language={result.Language} Length={result.CodeBytes}");

            return(result);
        }
 public async Task <ActionResult <SubmissionInfoDto> > CreateSubmission(SubmissionCreateDto dto)
 {
     try
     {
         return(Ok(await _service.CreateSubmissionAsync(dto)));
     }
     catch (ValidationException e)
     {
         return(BadRequest(e.Message));
     }
 }
Example #4
0
        public async Task <SubmissionInfoDto> CreateSubmissionAsync(SubmissionCreateDto dto)
        {
            var contest = await ValidateSubmissionCreateDtoAsync(dto);

            var user = await Manager.GetUserAsync(Accessor.HttpContext.User);

            var lastSubmission = await Context.Submissions
                                 .Where(s => s.UserId == user.Id)
                                 .OrderByDescending(s => s.Id)
                                 .FirstOrDefaultAsync();

            if (lastSubmission != null &&
                (DateTime.Now.ToUniversalTime() - lastSubmission.CreatedAt).TotalSeconds < 5)
            {
                throw new TooManyRequestsException("Cannot submit twice between 5 seconds.");
            }

            var submission = new Submission
            {
                UserId    = Accessor.HttpContext.User.GetSubjectId(),
                ProblemId = dto.ProblemId.GetValueOrDefault(),
                Program   = dto.Program,
                Verdict   = Verdict.Pending,
                Hidden    = DateTime.Now.ToUniversalTime() < contest.BeginTime,
                Time      = null,
                Memory    = null,
                FailedOn  = null,
                Score     = null,
                Progress  = null,
                Message   = null,
                JudgedBy  = null,
                JudgedAt  = null
            };
            await Context.Submissions.AddAsync(submission);

            await Context.SaveChangesAsync();

            _queue.EnqueueTask(new JobRequestMessage(JobType.JudgeSubmission, submission.Id, 1));

            await Context.Entry(submission).Reference(s => s.User).LoadAsync();

            var result = new SubmissionInfoDto(submission, true);

            await LogInformation($"CreateSubmission Id={result.Id} ProblemId={result.ProblemId}" +
                                 $" ContestantId={user.ContestantId} Language={result.Language}");

            return(result);
        }
Example #5
0
 public async Task <ActionResult <SubmissionInfoDto> > CreateSubmission(SubmissionCreateDto dto)
 {
     try
     {
         return(Ok(await _service.CreateSubmissionAsync(dto)));
     }
     catch (ValidationException e)
     {
         return(BadRequest(e.Message));
     }
     catch (UnauthorizedAccessException e)
     {
         return(Unauthorized(e.Message));
     }
     catch (TooManyRequestsException e)
     {
         return(StatusCode(StatusCodes.Status429TooManyRequests, e.Message));
     }
 }
Example #6
0
        private async Task <Contest> ValidateSubmissionCreateDtoAsync(SubmissionCreateDto dto)
        {
            var problem = await Context.Problems.FindAsync(dto.ProblemId);

            if (problem is null)
            {
                throw new ValidationException("Invalid problem ID.");
            }

            var user = await Manager.GetUserAsync(Accessor.HttpContext.User);

            var contest = await Context.Contests.FindAsync(problem.ContestId);

            var registered = await Context.Registrations
                             .AnyAsync(r => r.ContestId == contest.Id && r.UserId == user.Id);

            if (await Manager.IsInRoleAsync(user, ApplicationRoles.Administrator) ||
                await Manager.IsInRoleAsync(user, ApplicationRoles.ContestManager))
            {
                // Administrator and contest manager can submit to any problem.
            }
            else if (DateTime.Now.ToUniversalTime() < contest.BeginTime)
            {
                throw new UnauthorizedAccessException("Cannot submit until contest has begun.");
            }
            else if (DateTime.Now.ToUniversalTime() < contest.EndTime && !registered)
            {
                if (contest.IsPublic)
                {
                    // Automatically register for user if it is submitting during contest.
                    var registration = new Registration
                    {
                        UserId           = user.Id,
                        ContestId        = contest.Id,
                        IsParticipant    = true,
                        IsContestManager = false,
                        Statistics       = new List <RegistrationProblemStatistics>()
                    };
                    await Context.Registrations.AddAsync(registration);

                    await Context.SaveChangesAsync();
                }
                else
                {
                    throw new UnauthorizedAccessException("Unregistered user cannot submit until contest has ended.");
                }
            }

            switch (problem.Type)
            {
            case ProblemType.Ordinary:
                if (dto.Program.Language == Language.LabArchive)
                {
                    throw new ValidationException("Ordinary problem does not accept this language..");
                }
                else if (!Regex.IsMatch(dto.Program.Code, @"^[a-zA-Z0-9\+/]*={0,3}$", RegexOptions.None))
                {
                    throw new ValidationException("Invalid program code.");
                }

                break;

            case ProblemType.TestKitLab:
                throw new ValidationException("Cannot submit testkit lab problems through this API.");

            default:
                throw new ArgumentOutOfRangeException();
            }

            return(contest);
        }