2025-04-22 13:08:31 +00:00
|
|
|
|
package check_ownership
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
|
|
|
|
"gitea.pena/SQuiz/common/dal"
|
|
|
|
|
"gitea.pena/SQuiz/common/middleware"
|
|
|
|
|
"github.com/gofiber/fiber/v2"
|
2025-04-23 13:16:05 +00:00
|
|
|
|
"regexp"
|
2025-04-22 13:08:31 +00:00
|
|
|
|
"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
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-22 17:21:58 +00:00
|
|
|
|
isOwner, err := o.dal.QuizRepo.CheckQuizOwner(ctx.Context(), accountId, quizID)
|
2025-04-22 13:08:31 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
return false, fiber.NewError(fiber.StatusInternalServerError, err.Error())
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-22 17:21:58 +00:00
|
|
|
|
return isOwner, nil
|
2025-04-22 13:08:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// имеем id результата и id аккаунта проверяем с помощью CheckResultOwner
|
|
|
|
|
func (o *OwnerShip) CheckResult(ctx *fiber.Ctx) (bool, error) {
|
2025-04-22 17:21:58 +00:00
|
|
|
|
accountID, ok := middleware.GetAccountId(ctx)
|
|
|
|
|
if !ok {
|
|
|
|
|
return false, fiber.NewError(fiber.StatusUnauthorized, "account id is required")
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-23 13:16:05 +00:00
|
|
|
|
// todo интересная штука заметил что параметры на этапе промежуточного по не существует, оч сильно усложняет надо будет обдумать
|
|
|
|
|
resultID, err := strconv.ParseUint(ctx.Params("resultID"), 10, 64)
|
2025-04-22 17:21:58 +00:00
|
|
|
|
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
|
2025-04-22 13:08:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// имеем id вопроса и id аккаунта проверяем что квиз этого вопроса относится к аккаунту
|
|
|
|
|
func (o *OwnerShip) CheckQuestion(ctx *fiber.Ctx) (bool, error) {
|
2025-04-22 17:38:49 +00:00
|
|
|
|
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
|
2025-04-22 13:08:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// проверка для лид таргета надо проверить что в лид имеет отношение к аккаунту
|
|
|
|
|
func (o *OwnerShip) CheckLeadTarget(ctx *fiber.Ctx) (bool, error) {
|
|
|
|
|
return true, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (o *OwnerShip) CheckStatistic(ctx *fiber.Ctx) (bool, error) {
|
|
|
|
|
return true, nil
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-23 13:16:05 +00:00
|
|
|
|
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,
|
2025-04-22 13:08:31 +00:00
|
|
|
|
|
|
|
|
|
// пока не в приоритете todo
|
2025-04-23 13:16:05 +00:00
|
|
|
|
regexp.MustCompile(`^DELETE /account/account/leadtarget/\d+$`): (*OwnerShip).CheckLeadTarget,
|
|
|
|
|
regexp.MustCompile(`^PUT /account/account/leadtarget$`): (*OwnerShip).CheckLeadTarget,
|
2025-04-22 13:08:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
2025-04-22 17:40:00 +00:00
|
|
|
|
// todo подключить проверить
|
2025-04-22 13:08:31 +00:00
|
|
|
|
func OwnerShipMiddleware(o *OwnerShip) fiber.Handler {
|
|
|
|
|
return func(c *fiber.Ctx) error {
|
|
|
|
|
methodPath := fmt.Sprintf("%s %s", c.Method(), c.Path())
|
|
|
|
|
|
2025-04-23 13:16:05 +00:00
|
|
|
|
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
|
2025-04-22 13:08:31 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return c.Next()
|
|
|
|
|
}
|
|
|
|
|
}
|