core/internal/middleware/check_ownership/mw.go
2025-04-28 00:06:32 +00:00

166 lines
5.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package check_ownership
import (
"fmt"
"gitea.pena/SQuiz/common/dal"
"gitea.pena/SQuiz/common/middleware"
"github.com/gofiber/fiber/v2"
"regexp"
"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")
}
// todo интересная штука заметил что параметры на этапе промежуточного по не существует, оч сильно усложняет надо будет обдумать
resultID, err := strconv.ParseUint(ctx.Params("resultID"), 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) {
accountID, ok := middleware.GetAccountId(ctx)
if !ok {
return false, fiber.NewError(fiber.StatusUnauthorized, "account id is required")
}
var body struct {
QuestionID uint64 `json:"id"`
}
if err := ctx.BodyParser(&body); err != nil {
return false, fiber.NewError(fiber.StatusBadRequest, "invalid request data")
}
isOwner, err := o.dal.QuestionRepo.CheckQuestionOwner(ctx.Context(), accountID, body.QuestionID)
if err != nil {
return false, fiber.NewError(fiber.StatusInternalServerError, err.Error())
}
return isOwner, 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[*regexp.Regexp]func(*OwnerShip, *fiber.Ctx) (bool, error){
regexp.MustCompile(`^POST /question/create$`): (*OwnerShip).CheckQuiz, // quiz_id
regexp.MustCompile(`^POST /question/getList$`): (*OwnerShip).CheckQuiz, // quiz_id
regexp.MustCompile(`^PATCH /question/edit$`): (*OwnerShip).CheckQuestion, // id
regexp.MustCompile(`^POST /question/copy$`): (*OwnerShip).CheckQuiz, // quiz_id
regexp.MustCompile(`^POST /question/history$`): (*OwnerShip).CheckQuestion, // id
regexp.MustCompile(`^DELETE /question/delete$`): (*OwnerShip).CheckQuestion, // id
//regexp.MustCompile(`^GET /result/\d+$`): (*OwnerShip).CheckResult, // resultID в роуте (id ответа)
// todo POST /results/getResults/16675
regexp.MustCompile(`^POST /results/getResults/\d+$`): (*OwnerShip).CheckQuiz, // quizID в роуте
// todo POST /results/16675/export
regexp.MustCompile(`^POST /results/\d+/export$`): (*OwnerShip).CheckQuiz, // quizID в роуте
// todo все роутф статистики клиентские
regexp.MustCompile(`^POST /statistic/\d+/devices$`): (*OwnerShip).CheckStatistic,
regexp.MustCompile(`^POST /statistic/\d+/general$`): (*OwnerShip).CheckStatistic,
regexp.MustCompile(`^POST /statistic/\d+/questions$`): (*OwnerShip).CheckStatistic,
// пока не в приоритете todo
regexp.MustCompile(`^DELETE /account/account/leadtarget/\d+$`): (*OwnerShip).CheckLeadTarget,
regexp.MustCompile(`^PUT /account/account/leadtarget$`): (*OwnerShip).CheckLeadTarget,
}
// todo подключить проверить
func OwnerShipMiddleware(o *OwnerShip) fiber.Handler {
return func(c *fiber.Ctx) error {
methodPath := fmt.Sprintf("%s %s", c.Method(), c.Path())
fmt.Println(methodPath)
fmt.Println(c.Params("resultID"))
for re, f := range pathCheckMap {
if re.MatchString(methodPath) {
ok, err := f(o, c)
if err != nil {
return err
}
if !ok {
return fiber.NewError(fiber.StatusForbidden, "access denied")
}
break
}
}
return c.Next()
}
}