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 } isOwner, err := o.dal.QuizRepo.CheckQuizOwner(ctx.Context(), accountId, quizID) if err != nil { return false, fiber.NewError(fiber.StatusInternalServerError, err.Error()) } return isOwner, nil } // имеем id результата и id аккаунта проверяем с помощью CheckResultOwner func (o *OwnerShip) CheckResult(ctx *fiber.Ctx) (bool, error) { accountID, ok := middleware.GetAccountId(ctx) if !ok { return false, fiber.NewError(fiber.StatusUnauthorized, "account id is required") } resultIDStr := ctx.Params("resultID") if resultIDStr == "" { return false, fiber.NewError(fiber.StatusBadRequest, "invalid resultID") } resultID, err := strconv.ParseUint(resultIDStr, 10, 64) if err != nil { return false, fiber.NewError(fiber.StatusBadRequest, "invalid result ID format") } isOwner, err := o.dal.ResultRepo.CheckResultOwner(ctx.Context(), resultID, accountID) if err != nil { return false, fiber.NewError(fiber.StatusInternalServerError, err.Error()) } return isOwner, 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/:resultID": (*OwnerShip).CheckResult, // resultID в роуте (id ответа) "POST /results/getResults/:quizID": (*OwnerShip).CheckQuiz, // quizID в роуте "POST /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() } }