202 lines
4.8 KiB
Go
202 lines
4.8 KiB
Go
package rest
|
|
|
|
import (
|
|
"context"
|
|
testerv1 "git.sch9.ru/new_gate/ms-tester/contracts/tester/v1"
|
|
"git.sch9.ru/new_gate/ms-tester/internal/contests"
|
|
"git.sch9.ru/new_gate/ms-tester/internal/models"
|
|
"git.sch9.ru/new_gate/ms-tester/internal/problems"
|
|
"git.sch9.ru/new_gate/ms-tester/pkg"
|
|
"github.com/gofiber/fiber/v2"
|
|
)
|
|
|
|
type Handlers struct {
|
|
problemsUC problems.UseCase
|
|
contestsUC contests.UseCase
|
|
|
|
jwtSecret string
|
|
}
|
|
|
|
func NewHandlers(problemsUC problems.UseCase, contestsUC contests.UseCase, jwtSecret string) *Handlers {
|
|
return &Handlers{
|
|
problemsUC: problemsUC,
|
|
contestsUC: contestsUC,
|
|
|
|
jwtSecret: jwtSecret,
|
|
}
|
|
}
|
|
|
|
const (
|
|
sessionKey = "session"
|
|
)
|
|
|
|
func sessionFromCtx(ctx context.Context) (*models.Session, error) {
|
|
const op = "sessionFromCtx"
|
|
|
|
session, ok := ctx.Value(sessionKey).(*models.Session)
|
|
if !ok {
|
|
return nil, pkg.Wrap(pkg.ErrUnauthenticated, nil, op, "")
|
|
}
|
|
|
|
return session, nil
|
|
}
|
|
|
|
func (h *Handlers) CreateContest(c *fiber.Ctx) 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:
|
|
id, err := h.contestsUC.CreateContest(ctx, "Название контеста")
|
|
if err != nil {
|
|
return c.SendStatus(pkg.ToREST(err))
|
|
}
|
|
|
|
return c.JSON(&testerv1.CreateContestResponse{
|
|
Id: id,
|
|
})
|
|
default:
|
|
return c.SendStatus(pkg.ToREST(pkg.NoPermission))
|
|
}
|
|
}
|
|
|
|
func (h *Handlers) GetContest(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:
|
|
contest, err := h.contestsUC.GetContest(ctx, id)
|
|
if err != nil {
|
|
return c.SendStatus(pkg.ToREST(err))
|
|
}
|
|
|
|
tasks, err := h.contestsUC.GetTasks(ctx, id)
|
|
if err != nil {
|
|
return c.SendStatus(pkg.ToREST(err))
|
|
}
|
|
|
|
solutions := make([]*models.SolutionsListItem, 0)
|
|
participantId, err := h.contestsUC.GetParticipantId(ctx, contest.Id, session.UserId)
|
|
if err == nil { // Admin or Teacher may not participate in contest
|
|
solutions, err = h.contestsUC.GetBestSolutions(ctx, id, participantId)
|
|
if err != nil {
|
|
return c.SendStatus(pkg.ToREST(err))
|
|
}
|
|
}
|
|
|
|
return c.JSON(GetContestResponseDTO(contest, tasks, solutions))
|
|
case models.RoleStudent:
|
|
contest, err := h.contestsUC.GetContest(ctx, id)
|
|
if err != nil {
|
|
return c.SendStatus(pkg.ToREST(err))
|
|
}
|
|
|
|
tasks, err := h.contestsUC.GetTasks(ctx, id)
|
|
if err != nil {
|
|
return c.SendStatus(pkg.ToREST(err))
|
|
}
|
|
|
|
participantId, err := h.contestsUC.GetParticipantId(ctx, contest.Id, session.UserId)
|
|
solutions, err := h.contestsUC.GetBestSolutions(c.Context(), id, participantId)
|
|
if err != nil {
|
|
return c.SendStatus(pkg.ToREST(err))
|
|
}
|
|
|
|
return c.JSON(GetContestResponseDTO(contest, tasks, solutions))
|
|
default:
|
|
return c.SendStatus(pkg.ToREST(pkg.NoPermission))
|
|
}
|
|
}
|
|
|
|
func (h *Handlers) UpdateContest(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:
|
|
var req testerv1.UpdateContestRequest
|
|
err := c.BodyParser(&req)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = h.contestsUC.UpdateContest(ctx, id, models.ContestUpdate{
|
|
Title: req.Title,
|
|
})
|
|
if err != nil {
|
|
return c.SendStatus(pkg.ToREST(err))
|
|
}
|
|
|
|
return c.SendStatus(fiber.StatusOK)
|
|
default:
|
|
return c.SendStatus(pkg.ToREST(pkg.NoPermission))
|
|
}
|
|
}
|
|
|
|
func (h *Handlers) DeleteContest(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:
|
|
err := h.contestsUC.DeleteContest(ctx, id)
|
|
if err != nil {
|
|
return c.SendStatus(pkg.ToREST(err))
|
|
}
|
|
|
|
return c.SendStatus(fiber.StatusOK)
|
|
default:
|
|
return c.SendStatus(pkg.ToREST(pkg.NoPermission))
|
|
}
|
|
}
|
|
|
|
func (h *Handlers) ListContests(c *fiber.Ctx, params testerv1.ListContestsParams) error {
|
|
ctx := c.Context()
|
|
|
|
session, err := sessionFromCtx(ctx)
|
|
if err != nil {
|
|
return c.SendStatus(pkg.ToREST(err))
|
|
}
|
|
|
|
filter := models.ContestsFilter{
|
|
Page: params.Page,
|
|
PageSize: params.PageSize,
|
|
}
|
|
|
|
switch session.Role {
|
|
case models.RoleAdmin, models.RoleTeacher:
|
|
contestsList, err := h.contestsUC.ListContests(ctx, filter)
|
|
if err != nil {
|
|
return c.SendStatus(pkg.ToREST(err))
|
|
}
|
|
|
|
return c.JSON(ListContestsResponseDTO(contestsList))
|
|
case models.RoleStudent:
|
|
filter.UserId = &session.UserId
|
|
contestsList, err := h.contestsUC.ListContests(ctx, filter)
|
|
if err != nil {
|
|
return c.SendStatus(pkg.ToREST(err))
|
|
}
|
|
|
|
return c.JSON(ListContestsResponseDTO(contestsList))
|
|
default:
|
|
return c.SendStatus(pkg.ToREST(pkg.NoPermission))
|
|
}
|
|
}
|