From 8fb5c6992db4f1f0cd70b1f39792eab0858dc1c2 Mon Sep 17 00:00:00 2001 From: Pasha Date: Tue, 22 Apr 2025 16:08:31 +0300 Subject: [PATCH] added mw for check ownership, added function check quiz owner --- .../http_controllers/result/result.go | 2 +- .../http_controllers/result/route.go | 2 +- internal/middleware/check_ownership/mw.go | 124 ++++++++++++++++++ 3 files changed, 126 insertions(+), 2 deletions(-) create mode 100644 internal/middleware/check_ownership/mw.go diff --git a/internal/controllers/http_controllers/result/result.go b/internal/controllers/http_controllers/result/result.go index 6c250cf..e3b5b70 100644 --- a/internal/controllers/http_controllers/result/result.go +++ b/internal/controllers/http_controllers/result/result.go @@ -55,7 +55,7 @@ func (r *Result) GetResultsByQuizID(ctx *fiber.Ctx) error { return ctx.Status(fiber.StatusBadRequest).SendString("Invalid request data") } - quizIDStr := ctx.Params("quizId") + quizIDStr := ctx.Params("quizID") quizID, err := strconv.ParseUint(quizIDStr, 10, 64) if err != nil { return ctx.Status(fiber.StatusBadRequest).SendString("Invalid quiz ID format") diff --git a/internal/controllers/http_controllers/result/route.go b/internal/controllers/http_controllers/result/route.go index a70af9d..b7b72c6 100644 --- a/internal/controllers/http_controllers/result/route.go +++ b/internal/controllers/http_controllers/result/route.go @@ -3,7 +3,7 @@ package result import "github.com/gofiber/fiber/v2" func (r *Result) Register(router fiber.Router) { - router.Post("/results/getResults/:quizId", r.GetResultsByQuizID) + router.Post("/results/getResults/:quizID", r.GetResultsByQuizID) router.Delete("/results/delete/:resultId", r.DelResultByID) router.Patch("/result/seen", r.SetStatus) router.Post("/results/:quizID/export", r.ExportResultsToCSV) diff --git a/internal/middleware/check_ownership/mw.go b/internal/middleware/check_ownership/mw.go new file mode 100644 index 0000000..bb8b480 --- /dev/null +++ b/internal/middleware/check_ownership/mw.go @@ -0,0 +1,124 @@ +package check_ownership + +import ( + "fmt" + "gitea.pena/SQuiz/common/dal" + "gitea.pena/SQuiz/common/middleware" + "github.com/gofiber/fiber/v2" + "strconv" +) + +type Owner interface { + Check(ctx *fiber.Ctx) (bool, error) +} + +type OwnerShip struct { + dal *dal.DAL +} + +func NewOwnerShip(dal *dal.DAL) *OwnerShip { + return &OwnerShip{ + dal: dal, + } +} + +// имеем id квиза и id аккаунта проверяем что квиз принадлежит аккаунту +func (o *OwnerShip) CheckQuiz(ctx *fiber.Ctx) (bool, error) { + accountId, ok := middleware.GetAccountId(ctx) + if !ok { + return false, fiber.NewError(fiber.StatusUnauthorized, "account id is required") + } + + quizIDStr := ctx.Params("quizID") + var quizID uint64 + var err error + + if quizIDStr != "" { + quizID, err = strconv.ParseUint(quizIDStr, 10, 64) + if err != nil { + return false, fiber.NewError(fiber.StatusBadRequest, "invalid quiz ID") + } + } + + if quizIDStr == "" { + var body struct { + QuizID uint64 `json:"quiz_id"` + } + + if err := ctx.BodyParser(&body); err != nil { + return false, fiber.NewError(fiber.StatusBadRequest, "invalid request data") + } + + quizID = body.QuizID + } + + quiz, err := o.dal.QuizRepo.GetQuizById(ctx.Context(), accountId, quizID) + if err != nil { + return false, fiber.NewError(fiber.StatusInternalServerError, err.Error()) + } + + if quiz.AccountId != accountId { + return false, fiber.NewError(fiber.StatusForbidden, "quiz does not belong to the account") + } + + return true, nil +} + +// имеем id результата и id аккаунта проверяем с помощью CheckResultOwner +func (o *OwnerShip) CheckResult(ctx *fiber.Ctx) (bool, error) { + return true, nil +} + +// имеем id вопроса и id аккаунта проверяем что квиз этого вопроса относится к аккаунту +func (o *OwnerShip) CheckQuestion(ctx *fiber.Ctx) (bool, error) { + return true, nil +} + +// проверка для лид таргета надо проверить что в лид имеет отношение к аккаунту +func (o *OwnerShip) CheckLeadTarget(ctx *fiber.Ctx) (bool, error) { + return true, nil +} + +func (o *OwnerShip) CheckStatistic(ctx *fiber.Ctx) (bool, error) { + return true, nil +} + +var pathCheckMap = map[string]func(*OwnerShip, *fiber.Ctx) (bool, error){ + "POST /question/create": (*OwnerShip).CheckQuiz, // quiz_id + "POST /question/getList": (*OwnerShip).CheckQuiz, // quiz_id + "PATCH /question/edit": (*OwnerShip).CheckQuestion, // id + "POST /question/copy": (*OwnerShip).CheckQuiz, // quiz_id + "POST /question/history": (*OwnerShip).CheckQuestion, // id + "DELETE /question/delete": (*OwnerShip).CheckQuestion, // id + + "GET /result/result/:resultID": (*OwnerShip).CheckResult, // resultID в роуте (id ответа) + "POST /result/results/getResults/:quizID": (*OwnerShip).CheckQuiz, // quizID в роуте + "POST /result/results/:quizID/export": (*OwnerShip).CheckQuiz, // quizID в роуте + + // todo обсудить с Мишей + "POST /statistic/:quizID/devices": (*OwnerShip).CheckStatistic, + "POST /statistic/:quizID/general": (*OwnerShip).CheckStatistic, + "POST /statistic/:quizID/questions": (*OwnerShip).CheckStatistic, + + // пока не в приоритете todo + "DELETE /account/account/leadtarget/:id": (*OwnerShip).CheckLeadTarget, + "PUT /account/account/leadtarget": (*OwnerShip).CheckLeadTarget, +} + +func OwnerShipMiddleware(o *OwnerShip) fiber.Handler { + return func(c *fiber.Ctx) error { + methodPath := fmt.Sprintf("%s %s", c.Method(), c.Path()) + + if f, ok := pathCheckMap[methodPath]; ok { + ok, err := f(o, c) + if err != nil { + return err + } + if !ok { + return fiber.NewError(fiber.StatusForbidden, "access denied") + } + } + + return c.Next() + } +}