Exemplo n.º 1
0
        private async Task RunApiPostRequestAsync(string resource, object payload, CancellationToken cancellationToken)
        {
            // Run request
            var client  = new RestClient(_options.Value.CtfServerApiBaseUrl);
            var request = new RestRequest(resource, Method.Post);

            request.AddJsonBody(CtfApiRequest.Create(_options.Value.LabId, _cryptoService, payload));
            var response = await client.ExecuteAsync(request, cancellationToken);

            // WORKAROUND: The current implementation of RestSharp silently swallows exceptions; check and throw possible exceptions manually
            if (response.ErrorException != null)
            {
                throw response.ErrorException;
            }
            if (!response.IsSuccessful)
            {
                // Throw an exception which contains the entire response data, for easier debugging

                StringBuilder exceptionContentBuilder = new StringBuilder();
                exceptionContentBuilder.AppendLine($"Resource: {resource}");
                exceptionContentBuilder.AppendLine($"Status: {(int)response.StatusCode} {response.StatusDescription}");

                exceptionContentBuilder.AppendLine();
                exceptionContentBuilder.AppendLine("-- Response content: --");
                exceptionContentBuilder.AppendLine(response.Content ?? "(none)");

                throw new CtfApiException($"The server returned an error status code: {response.StatusCode} {response.StatusDescription}", exceptionContentBuilder.ToString());
            }
        }
Exemplo n.º 2
0
    public async Task <IActionResult> ClearGroupExerciseSubmissionsAsync(CtfApiRequest request)
    {
        try
        {
            // Resolve lab
            var lab = await _labService.GetLabAsync(request.LabId, HttpContext.RequestAborted);

            if (lab == null)
            {
                return(BadRequest(new { error = $"Could not resolve requested lab {request.LabId}" }));
            }

            // Decode request
            var apiExerciseSubmission = request.Decode <ApiGroupExerciseSubmission>(new CryptoService(lab.ApiCode));

            // Resolve exercise
            var exercise = await _exerciseService.FindExerciseAsync(lab.Id, apiExerciseSubmission.ExerciseNumber, HttpContext.RequestAborted);

            if (exercise == null)
            {
                return(NotFound(new { error = "Exercise not found" }));
            }

            // Get group members
            var groupMembers = await _userService.GetGroupMembersAsync(apiExerciseSubmission.GroupId).ToListAsync(HttpContext.RequestAborted);

            if (!groupMembers.Any())
            {
                return(NotFound(new { error = "Empty or not existing group" }));
            }

            // Clear exercise submissions for each group member
            foreach (var groupMember in groupMembers)
            {
                await _exerciseService.ClearExerciseSubmissionsAsync(exercise.Id, groupMember.Id, HttpContext.RequestAborted);
            }

            return(Ok());
        }
        catch (CryptographicException ex)
        {
            _logger.LogError(ex, "Clear exercise submission of group");
            return(StatusCode(StatusCodes.Status401Unauthorized, new { error = "Could not decode the request packet" }));
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Clear exercise submission of group");
            return(StatusCode(StatusCodes.Status500InternalServerError, new { error = "An internal error occured during processing of the request" }));
        }
    }
Exemplo n.º 3
0
    public async Task <IActionResult> ClearExerciseSubmissionsAsync(CtfApiRequest request)
    {
        try
        {
            // Resolve lab
            var lab = await _labService.GetLabAsync(request.LabId, HttpContext.RequestAborted);

            if (lab == null)
            {
                return(BadRequest(new { error = $"Could not resolve requested lab {request.LabId}" }));
            }

            // Decode request
            var apiExerciseSubmission = request.Decode <ApiExerciseSubmission>(new CryptoService(lab.ApiCode));

            // Resolve exercise
            var exercise = await _exerciseService.FindExerciseAsync(lab.Id, apiExerciseSubmission.ExerciseNumber, HttpContext.RequestAborted);

            if (exercise == null)
            {
                return(NotFound(new { error = "Exercise not found" }));
            }

            // Check user
            if (!await _userService.UserExistsAsync(apiExerciseSubmission.UserId, HttpContext.RequestAborted))
            {
                return(NotFound(new { error = "User not found" }));
            }

            // Clear exercise submissions
            await _exerciseService.ClearExerciseSubmissionsAsync(exercise.Id, apiExerciseSubmission.UserId, HttpContext.RequestAborted);

            return(Ok());
        }
        catch (CryptographicException ex)
        {
            _logger.LogError(ex, "Clear exercise submissions of user");
            return(StatusCode(StatusCodes.Status401Unauthorized, new { error = "Could not decode the request packet" }));
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Create exercise submissions of user");
            return(StatusCode(StatusCodes.Status500InternalServerError, new { error = "An internal error occured during processing of the request" }));
        }
    }
Exemplo n.º 4
0
        public async Task <IActionResult> ClearExerciseSubmissionsAsync(CtfApiRequest request)
        {
            try
            {
                // Resolve lab
                var lab = await _labService.GetLabAsync(request.LabId, HttpContext.RequestAborted);

                if (lab == null)
                {
                    return(BadRequest());
                }

                // Decode request
                var apiExerciseSubmission = request.Decode <ApiExerciseSubmission>(new CryptoService(lab.ApiCode));

                // Resolve exercise
                var exercise = await _exerciseService.FindExerciseAsync(lab.Id, apiExerciseSubmission.ExerciseNumber, HttpContext.RequestAborted);

                if (exercise == null)
                {
                    return(NotFound(new { error = "Exercise not found" }));
                }

                // Check user
                if (!await _userService.UserExistsAsync(apiExerciseSubmission.UserId, HttpContext.RequestAborted))
                {
                    return(NotFound(new { error = "User not found" }));
                }

                // Clear exercise submissions
                await _exerciseService.ClearExerciseSubmissionsAsync(exercise.Id, apiExerciseSubmission.UserId, HttpContext.RequestAborted);

                return(Ok());
            }
            catch (CryptographicException ex)
            {
                return(StatusCode(StatusCodes.Status401Unauthorized, new { error = ex.ToString() }));
            }
            catch (Exception ex)
            {
                return(StatusCode(StatusCodes.Status500InternalServerError, new { error = ex.ToString() }));
            }
        }
Exemplo n.º 5
0
        private async Task RunApiPostRequestAsync(string resource, object payload, CancellationToken cancellationToken = default)
        {
            // Run request
            var client  = new RestClient(_options.Value.CtfServerApiBaseUrl);
            var request = new RestRequest(resource, Method.POST);

            request.AddJsonBody(CtfApiRequest.Create(_options.Value.LabId, _cryptoService, payload));
            var response = await client.ExecuteAsync(request, cancellationToken);

            // WORKAROUND: The current implementation of RestSharp silently swallows exceptions; check and throw possible exceptions manually
            if (response.ErrorException != null)
            {
                throw response.ErrorException;
            }
            if (!response.IsSuccessful)
            {
                throw new WebException("The server returned an error status code: " + response.StatusDescription);
            }
        }
Exemplo n.º 6
0
    public async Task <IActionResult> CreateExerciseSubmissionAsync(CtfApiRequest request)
    {
        try
        {
            // Resolve lab
            var lab = await _labService.GetLabAsync(request.LabId, HttpContext.RequestAborted);

            if (lab == null)
            {
                return(BadRequest(new { error = $"Could not resolve requested lab {request.LabId}" }));
            }

            // Decode request
            var apiExerciseSubmission = request.Decode <ApiExerciseSubmission>(new CryptoService(lab.ApiCode));

            // Resolve exercise
            var exercise = await _exerciseService.FindExerciseAsync(lab.Id, apiExerciseSubmission.ExerciseNumber, HttpContext.RequestAborted);

            if (exercise == null)
            {
                return(NotFound(new { error = "Exercise not found" }));
            }

            // Check lab execution
            // This will also automatically check whether the given user exists
            var labExecution = await _labExecutionService.GetLabExecutionForUserAsync(apiExerciseSubmission.UserId, lab.Id, HttpContext.RequestAborted);

            var now = DateTime.Now;
            if (labExecution == null || now < labExecution.PreStart)
            {
                return(NotFound(new { error = "Lab is not active for this user" }));
            }

            // Some exercises may only be submitted after the pre-start phase has ended
            if (!exercise.IsPreStartAvailable && now < labExecution.Start)
            {
                return(NotFound(new { error = "This exercise may not be submitted in the pre-start phase" }));
            }

            // Create submission
            var submission = new ExerciseSubmission
            {
                ExerciseId     = exercise.Id,
                UserId         = apiExerciseSubmission.UserId,
                ExercisePassed = apiExerciseSubmission.ExercisePassed,
                SubmissionTime = apiExerciseSubmission.SubmissionTime ?? DateTime.Now,
                Weight         = apiExerciseSubmission.ExercisePassed ? 1 : (apiExerciseSubmission.Weight >= 0 ? apiExerciseSubmission.Weight : 1)
            };
            await _exerciseService.CreateExerciseSubmissionAsync(submission, HttpContext.RequestAborted);

            return(Ok());
        }
        catch (CryptographicException ex)
        {
            _logger.LogError(ex, "Create exercise submission for user");
            return(StatusCode(StatusCodes.Status401Unauthorized, new { error = "Could not decode the request packet" }));
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Create exercise submission for user");
            return(StatusCode(StatusCodes.Status500InternalServerError, new { error = "An internal error occured during processing of the request" }));
        }
    }