package rest import ( testerv1 "git.sch9.ru/new_gate/ms-tester/contracts/tester/v1" "git.sch9.ru/new_gate/ms-tester/internal/models" "git.sch9.ru/new_gate/ms-tester/pkg" "github.com/gofiber/fiber/v2" "io" ) const ( maxSolutionSize int64 = 10 * 1024 * 1024 ) func (h *Handlers) CreateSolution(c *fiber.Ctx, params testerv1.CreateSolutionParams) error { ctx := c.Context() session, err := sessionFromCtx(ctx) if err != nil { return c.SendStatus(pkg.ToREST(err)) } switch session.Role { case models.RoleAdmin, models.RoleTeacher, models.RoleStudent: s, err := c.FormFile("solution") if err != nil { return err } if s.Size == 0 || s.Size > maxSolutionSize { return c.SendStatus(fiber.StatusBadRequest) } f, err := s.Open() if err != nil { return err } defer f.Close() b, err := io.ReadAll(f) if err != nil { return err } id, err := h.contestsUC.CreateSolution(ctx, &models.SolutionCreation{ UserId: session.UserId, TaskId: params.TaskId, Language: params.Language, Solution: string(b), }) if err != nil { return c.SendStatus(pkg.ToREST(err)) } return c.JSON(testerv1.CreateSolutionResponse{ Id: id, }) default: return c.SendStatus(pkg.ToREST(pkg.NoPermission)) } } func (h *Handlers) GetSolution(c *fiber.Ctx, id int32) error { ctx := c.Context() session, err := sessionFromCtx(ctx) if err != nil { return c.SendStatus(pkg.ToREST(err)) } switch session.Role { case models.RoleAdmin, models.RoleTeacher: solution, err := h.contestsUC.GetSolution(ctx, id) if err != nil { return c.SendStatus(pkg.ToREST(err)) } return c.JSON(testerv1.GetSolutionResponse{Solution: SolutionDTO(*solution)}) case models.RoleStudent: _, err := h.contestsUC.GetParticipantId3(ctx, id) if err != nil { return c.SendStatus(pkg.ToREST(err)) } solution, err := h.contestsUC.GetSolution(ctx, id) if err != nil { return c.SendStatus(pkg.ToREST(err)) } return c.JSON(testerv1.GetSolutionResponse{Solution: SolutionDTO(*solution)}) default: return c.SendStatus(pkg.ToREST(pkg.NoPermission)) } } func (h *Handlers) ListSolutions(c *fiber.Ctx, params testerv1.ListSolutionsParams) error { ctx := c.Context() session, err := sessionFromCtx(ctx) if err != nil { return c.SendStatus(pkg.ToREST(err)) } filter := models.SolutionsFilter{ ContestId: params.ContestId, Page: params.Page, PageSize: params.PageSize, ParticipantId: params.ParticipantId, TaskId: params.TaskId, Language: params.Language, Order: params.Order, State: params.State, } switch session.Role { case models.RoleAdmin, models.RoleTeacher: solutionsList, err := h.contestsUC.ListSolutions(ctx, filter) if err != nil { return c.SendStatus(pkg.ToREST(err)) } return c.JSON(ListSolutionsResponseDTO(solutionsList)) case models.RoleStudent: if params.ContestId == nil { return c.SendStatus(pkg.ToREST(pkg.NoPermission)) } participantId, err := h.contestsUC.GetParticipantId(ctx, *params.ContestId, session.UserId) if err != nil { return c.SendStatus(pkg.ToREST(pkg.NoPermission)) } // Student cannot view other users' solutions if params.ParticipantId != nil && *params.ParticipantId != participantId { return c.SendStatus(pkg.ToREST(pkg.NoPermission)) } filter.ParticipantId = &participantId solutionsList, err := h.contestsUC.ListSolutions(ctx, filter) if err != nil { return c.SendStatus(pkg.ToREST(err)) } return c.JSON(ListSolutionsResponseDTO(solutionsList)) default: return c.SendStatus(pkg.ToREST(pkg.NoPermission)) } }