2021-04-11 09:48:15 +00:00
|
|
|
|
package service
|
|
|
|
|
|
|
|
|
|
import (
|
2021-05-01 12:36:22 +00:00
|
|
|
|
"context"
|
2024-02-22 14:52:06 +00:00
|
|
|
|
"crypto/sha256"
|
|
|
|
|
"encoding/hex"
|
2021-04-11 09:48:15 +00:00
|
|
|
|
"encoding/json"
|
2021-05-01 12:36:22 +00:00
|
|
|
|
"errors"
|
2021-05-15 20:10:07 +00:00
|
|
|
|
"fmt"
|
2024-02-21 18:07:40 +00:00
|
|
|
|
"github.com/go-redis/redis/v8"
|
2021-09-05 15:24:13 +00:00
|
|
|
|
"heruvym/dal/minio"
|
|
|
|
|
"heruvym/dal/mongo"
|
|
|
|
|
"heruvym/jwt_adapter"
|
2024-02-11 20:16:40 +00:00
|
|
|
|
"heruvym/middleware"
|
2021-09-05 15:24:13 +00:00
|
|
|
|
"heruvym/model"
|
|
|
|
|
"heruvym/tools"
|
2024-02-21 14:42:23 +00:00
|
|
|
|
"heruvym/utils"
|
2024-02-22 14:52:06 +00:00
|
|
|
|
"io"
|
2021-04-11 09:48:15 +00:00
|
|
|
|
"net/http"
|
2021-09-05 15:24:13 +00:00
|
|
|
|
"strings"
|
|
|
|
|
"sync"
|
2024-02-21 18:07:40 +00:00
|
|
|
|
"time"
|
2022-11-02 18:52:02 +00:00
|
|
|
|
|
|
|
|
|
"github.com/rs/xid"
|
2024-11-25 22:17:44 +00:00
|
|
|
|
"gitea.pena/PenaSide/hlog"
|
2022-11-02 18:52:02 +00:00
|
|
|
|
tb "gopkg.in/tucnak/telebot.v2"
|
2021-04-11 09:48:15 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type Heruvym struct {
|
|
|
|
|
logger hlog.Logger
|
2021-09-05 15:24:13 +00:00
|
|
|
|
dal *mongo.DAL
|
2022-03-03 17:56:03 +00:00
|
|
|
|
bs *minio.BlobStore
|
2022-04-14 17:43:13 +00:00
|
|
|
|
|
2024-02-21 18:07:40 +00:00
|
|
|
|
notifier *tb.Bot
|
|
|
|
|
tgChatID int64
|
|
|
|
|
redisClient *redis.Client
|
2021-04-11 09:48:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-03-01 17:38:03 +00:00
|
|
|
|
func New(
|
|
|
|
|
blobs *minio.BlobStore,
|
|
|
|
|
dataAccessLayer *mongo.DAL,
|
|
|
|
|
log hlog.Logger,
|
2024-02-13 14:39:01 +00:00
|
|
|
|
notifier *tb.Bot,
|
2024-02-21 18:07:40 +00:00
|
|
|
|
tgChatID int64, redisClient *redis.Client) *Heruvym {
|
2021-04-11 09:48:15 +00:00
|
|
|
|
return &Heruvym{
|
2024-02-21 18:07:40 +00:00
|
|
|
|
logger: log.Module("Service"),
|
|
|
|
|
dal: dataAccessLayer,
|
|
|
|
|
bs: blobs,
|
|
|
|
|
notifier: notifier,
|
|
|
|
|
tgChatID: tgChatID,
|
|
|
|
|
redisClient: redisClient,
|
2021-04-11 09:48:15 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-01 17:50:03 +00:00
|
|
|
|
func (h Heruvym) Register(m *http.ServeMux) *http.ServeMux {
|
2021-04-11 09:48:15 +00:00
|
|
|
|
|
|
|
|
|
m.HandleFunc("/create", h.CreateTicket)
|
2021-05-02 22:25:12 +00:00
|
|
|
|
m.HandleFunc("/subscribe", tools.SseWrapper(h.GetList))
|
|
|
|
|
m.HandleFunc("/ticket", tools.SseWrapper(h.Subscribe))
|
|
|
|
|
m.HandleFunc("/send", tools.HandlerWrapper(h.PutMessage))
|
2021-05-11 10:57:58 +00:00
|
|
|
|
m.HandleFunc("/getTickets", tools.HandlerWrapper(h.GetTickets))
|
|
|
|
|
m.HandleFunc("/getMessages", tools.HandlerWrapper(h.GetMessages))
|
|
|
|
|
m.HandleFunc("/pick", tools.HandlerWrapper(h.Pick))
|
|
|
|
|
m.HandleFunc("/delegate", tools.HandlerWrapper(h.Delegate))
|
|
|
|
|
m.HandleFunc("/vote", tools.HandlerWrapper(h.Vote))
|
|
|
|
|
m.HandleFunc("/close", tools.HandlerWrapper(h.CloseTicket))
|
2021-04-11 09:48:15 +00:00
|
|
|
|
|
|
|
|
|
return m
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type CreateTicketReq struct {
|
|
|
|
|
Title string `json:"Title"`
|
|
|
|
|
Message string `json:"Message"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type CreateTicketResp struct {
|
|
|
|
|
Ticket string `json:"Ticket"`
|
2023-04-05 21:10:08 +00:00
|
|
|
|
Sess string `json:"sess"`
|
2021-04-11 09:48:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Heruvym) CreateTicket(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
defer func() {
|
|
|
|
|
if err := r.Body.Close(); err != nil {
|
|
|
|
|
h.logger.Emit(ErrorClose{
|
|
|
|
|
Err: err,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}()
|
|
|
|
|
|
2021-09-05 15:24:13 +00:00
|
|
|
|
var (
|
2022-03-03 17:56:03 +00:00
|
|
|
|
err error
|
2021-09-05 15:24:13 +00:00
|
|
|
|
request CreateTicketReq
|
|
|
|
|
)
|
2021-04-11 09:48:15 +00:00
|
|
|
|
|
|
|
|
|
if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
|
|
|
|
|
http.Error(w, "Invalid json", http.StatusBadRequest)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if request.Title == "" {
|
2023-04-24 14:50:13 +00:00
|
|
|
|
http.Error(w, "No Title", http.StatusBadRequest)
|
2021-04-11 09:48:15 +00:00
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if request.Message == "" {
|
2023-04-24 14:50:13 +00:00
|
|
|
|
http.Error(w, "No Message", http.StatusBadRequest)
|
2021-04-11 09:48:15 +00:00
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ctx := r.Context()
|
|
|
|
|
|
|
|
|
|
session := jwt_adapter.Get(ctx)
|
|
|
|
|
|
|
|
|
|
if session == nil {
|
2023-04-24 14:50:13 +00:00
|
|
|
|
http.Error(w, "No session", http.StatusUnauthorized)
|
2021-04-11 09:48:15 +00:00
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2021-09-05 15:24:13 +00:00
|
|
|
|
var (
|
|
|
|
|
ticketID string
|
2022-03-03 17:56:03 +00:00
|
|
|
|
tickets []model.Ticket
|
2023-03-01 17:38:03 +00:00
|
|
|
|
role = jwt_adapter.GetRole(ctx)
|
2021-04-11 09:48:15 +00:00
|
|
|
|
)
|
2023-03-01 17:38:03 +00:00
|
|
|
|
if role == "" {
|
|
|
|
|
tickets, _, err = h.dal.GetTickets4Sess(ctx, session.Id)
|
2021-04-11 09:48:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-09-05 15:24:13 +00:00
|
|
|
|
if err != nil || len(tickets) == 0 {
|
2022-04-14 17:43:13 +00:00
|
|
|
|
|
2021-09-05 15:24:13 +00:00
|
|
|
|
ticketID, err = h.dal.CreateTicket(
|
|
|
|
|
ctx,
|
2023-03-01 17:38:03 +00:00
|
|
|
|
session.Id,
|
|
|
|
|
session.Id,
|
2024-03-07 18:58:59 +00:00
|
|
|
|
r.Header["Origin"][0],
|
2021-09-05 15:24:13 +00:00
|
|
|
|
request.Title,
|
|
|
|
|
request.Message,
|
|
|
|
|
[]string{},
|
|
|
|
|
)
|
|
|
|
|
if err != nil {
|
|
|
|
|
http.Error(w, "CannotCreateTicket", http.StatusInternalServerError)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if _, err := h.dal.PutMessage(ctx,
|
|
|
|
|
request.Message,
|
2023-03-01 17:38:03 +00:00
|
|
|
|
session.Id,
|
|
|
|
|
session.Id,
|
2021-09-05 15:24:13 +00:00
|
|
|
|
ticketID,
|
|
|
|
|
[]string{},
|
|
|
|
|
); err != nil {
|
|
|
|
|
http.Error(w, "CannotCreateMessage", http.StatusInternalServerError)
|
|
|
|
|
return
|
|
|
|
|
}
|
2024-02-17 21:54:46 +00:00
|
|
|
|
|
|
|
|
|
domain := ctx.Value(middleware.HostKey).(string)
|
|
|
|
|
if domain == "" {
|
|
|
|
|
fmt.Println("domain is nil err")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
go func() {
|
2024-03-03 18:56:07 +00:00
|
|
|
|
if session.Id != "" && role != "admin" {
|
2024-02-17 21:54:46 +00:00
|
|
|
|
if err == nil && h.notifier != nil {
|
2024-03-03 18:55:29 +00:00
|
|
|
|
var userLink, supportLink string
|
2024-02-17 21:54:46 +00:00
|
|
|
|
if session.StandardClaims.Issuer != "" {
|
|
|
|
|
fmt.Println("MABNAT", domain)
|
|
|
|
|
if domain[0] == 's' {
|
|
|
|
|
userLink = fmt.Sprintf("https://sadmin.pena/users/%s", session.Id)
|
2024-03-03 18:55:29 +00:00
|
|
|
|
supportLink = fmt.Sprintf("https://sadmin.pena/support/%s", ticketID)
|
2024-02-17 21:54:46 +00:00
|
|
|
|
} else {
|
|
|
|
|
userLink = fmt.Sprintf("https://admin.pena/users/%s", session.Id)
|
2024-03-03 18:55:29 +00:00
|
|
|
|
supportLink = fmt.Sprintf("https://admin.pena/support/%s", ticketID)
|
2024-02-17 21:54:46 +00:00
|
|
|
|
}
|
|
|
|
|
} else {
|
2024-05-02 21:42:57 +00:00
|
|
|
|
if domain[0] == 's' {
|
2024-03-03 18:56:07 +00:00
|
|
|
|
supportLink = fmt.Sprintf("https://sadmin.pena/support/%s", ticketID)
|
2024-05-02 21:42:57 +00:00
|
|
|
|
} else {
|
|
|
|
|
supportLink = fmt.Sprintf("https://admin.pena/support/%s", ticketID)
|
|
|
|
|
}
|
2024-02-17 21:54:46 +00:00
|
|
|
|
userLink = "незарегистрированного пользователя"
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-03 18:55:29 +00:00
|
|
|
|
message := fmt.Sprintf("Вам пришло сообщение от %s сссылка на пользователя с %s, ccылка на чат - %s",
|
|
|
|
|
userLink, domain, supportLink)
|
2024-02-17 21:54:46 +00:00
|
|
|
|
|
|
|
|
|
if _, err := h.notifier.Send(tb.ChatID(h.tgChatID), message); err != nil {
|
|
|
|
|
fmt.Println("CAN NOT NOTIFY", err)
|
|
|
|
|
}
|
|
|
|
|
return
|
2023-05-06 18:45:56 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2024-02-17 21:54:46 +00:00
|
|
|
|
}()
|
|
|
|
|
|
2021-09-05 15:24:13 +00:00
|
|
|
|
} else {
|
|
|
|
|
ticketID = tickets[0].ID
|
2021-04-11 09:48:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-04-05 21:10:08 +00:00
|
|
|
|
response, err := json.Marshal(CreateTicketResp{Ticket: ticketID, Sess: session.Id})
|
2021-04-11 09:48:15 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
h.logger.Emit(ErrorMarshal{
|
|
|
|
|
Err: err,
|
|
|
|
|
})
|
|
|
|
|
http.Error(w, "CannotMarshalMessage", http.StatusInternalServerError)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if _, err := w.Write(response); err != nil {
|
|
|
|
|
h.logger.Emit(ErrorMarshal{
|
|
|
|
|
Err: err,
|
|
|
|
|
})
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-05-01 10:05:45 +00:00
|
|
|
|
|
2021-05-02 22:25:12 +00:00
|
|
|
|
var _ tools.DataEmitter = (&Heruvym{}).GetList
|
2021-05-01 10:05:45 +00:00
|
|
|
|
|
2021-05-01 12:36:22 +00:00
|
|
|
|
func (h *Heruvym) GetList(ctx context.Context) chan interface{} {
|
2024-02-20 18:43:12 +00:00
|
|
|
|
fmt.Println("GetList")
|
2021-09-05 15:24:13 +00:00
|
|
|
|
defer func() {
|
|
|
|
|
if rec := recover(); rec != nil {
|
|
|
|
|
fmt.Println(rec)
|
|
|
|
|
}
|
|
|
|
|
}()
|
2021-05-01 12:36:22 +00:00
|
|
|
|
sess := jwt_adapter.Get(ctx)
|
2024-02-20 18:43:12 +00:00
|
|
|
|
fmt.Println("sess", sess)
|
2021-09-05 15:24:13 +00:00
|
|
|
|
if sess == nil {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-01 12:36:22 +00:00
|
|
|
|
output := make(chan interface{})
|
|
|
|
|
|
2023-03-01 17:38:03 +00:00
|
|
|
|
if sess.Id == "" {
|
|
|
|
|
go h.unauthorizedTickets(ctx, sess.Id, output)
|
2021-05-01 12:36:22 +00:00
|
|
|
|
} else {
|
2023-03-01 17:38:03 +00:00
|
|
|
|
role := jwt_adapter.GetRole(ctx)
|
2021-09-05 15:24:13 +00:00
|
|
|
|
|
2023-03-01 17:38:03 +00:00
|
|
|
|
fmt.Println("ALL TICKETS Sess ", sess.Id, role)
|
2021-05-02 22:25:12 +00:00
|
|
|
|
if role == "admin" || role == "manager" {
|
|
|
|
|
go h.allTickets(ctx, output)
|
|
|
|
|
} else {
|
2023-03-01 17:38:03 +00:00
|
|
|
|
go h.userTickets(ctx, sess.Id, output)
|
2021-05-02 22:25:12 +00:00
|
|
|
|
}
|
2021-05-01 12:36:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return output
|
2021-05-01 10:05:45 +00:00
|
|
|
|
}
|
2021-05-01 12:36:22 +00:00
|
|
|
|
|
2021-05-02 22:25:12 +00:00
|
|
|
|
func (h *Heruvym) allTickets(ctx context.Context, output chan interface{}) {
|
2021-09-05 15:24:13 +00:00
|
|
|
|
defer func() {
|
|
|
|
|
if v := recover(); v != nil {
|
|
|
|
|
fmt.Println("AllTicketsRec", v)
|
|
|
|
|
}
|
|
|
|
|
}()
|
|
|
|
|
|
2022-04-14 17:43:13 +00:00
|
|
|
|
//data, count, err := h.dal.YieldTickets(ctx, 20)
|
|
|
|
|
//
|
|
|
|
|
//if err != nil {
|
|
|
|
|
// output <- errors.New("cannot get tickets:" + err.Error())
|
|
|
|
|
// return
|
|
|
|
|
//}
|
|
|
|
|
//
|
|
|
|
|
//if data != nil {
|
|
|
|
|
// output <- GetTicketsResp{data, count}
|
|
|
|
|
//}
|
2022-03-03 17:56:03 +00:00
|
|
|
|
|
|
|
|
|
if err := h.dal.WatchAllTickets(ctx, func(ticket model.Ticket) error {
|
2021-05-02 22:25:12 +00:00
|
|
|
|
output <- ticket
|
|
|
|
|
return nil
|
|
|
|
|
}); err != nil {
|
2021-09-05 15:24:13 +00:00
|
|
|
|
output <- errors.New("cannot watch all tickets" + err.Error())
|
2021-05-02 22:25:12 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Heruvym) userTickets(ctx context.Context, userID string, output chan interface{}) {
|
|
|
|
|
|
2022-02-27 15:27:44 +00:00
|
|
|
|
defer func() {
|
|
|
|
|
if v := recover(); v != nil {
|
|
|
|
|
fmt.Println("USERTICKS", v)
|
|
|
|
|
}
|
2022-03-03 17:56:03 +00:00
|
|
|
|
}()
|
2022-02-27 15:27:44 +00:00
|
|
|
|
|
2023-03-29 13:15:07 +00:00
|
|
|
|
data, count, err := h.dal.YieldUserTickets(ctx, userID, 20, 0)
|
2022-02-27 15:27:44 +00:00
|
|
|
|
|
2022-03-03 17:56:03 +00:00
|
|
|
|
if err != nil {
|
2021-09-05 15:24:13 +00:00
|
|
|
|
output <- errors.New("cannot get tickets:" + err.Error())
|
2021-05-15 20:10:07 +00:00
|
|
|
|
return
|
2021-05-02 22:25:12 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-03-03 17:56:03 +00:00
|
|
|
|
if data != nil {
|
|
|
|
|
output <- GetTicketsResp{data, count}
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-02 22:25:12 +00:00
|
|
|
|
if err := h.dal.WatchTickets(ctx, userID, func(ticket model.Ticket) error {
|
|
|
|
|
output <- ticket
|
|
|
|
|
return nil
|
|
|
|
|
}); err != nil {
|
|
|
|
|
output <- errors.New("cannot watch tickets")
|
2021-05-15 20:10:07 +00:00
|
|
|
|
return
|
2021-05-02 22:25:12 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Heruvym) hasNoRole(output chan interface{}) {
|
|
|
|
|
output <- errors.New("no role in profile")
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-01 12:36:22 +00:00
|
|
|
|
func (h *Heruvym) unauthorizedTickets(ctx context.Context, sess string, output chan interface{}) {
|
2021-09-05 15:24:13 +00:00
|
|
|
|
//defer close(output)
|
2021-05-01 12:36:22 +00:00
|
|
|
|
|
2022-03-03 17:56:03 +00:00
|
|
|
|
tickets, count, err := h.dal.GetTickets4Sess(ctx, sess)
|
|
|
|
|
|
2021-05-01 17:50:03 +00:00
|
|
|
|
if err != nil {
|
2021-05-01 12:36:22 +00:00
|
|
|
|
output <- errors.New("no tickets for session")
|
2021-09-05 15:24:13 +00:00
|
|
|
|
return
|
2021-05-01 12:36:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-09-05 15:24:13 +00:00
|
|
|
|
if tickets != nil {
|
2022-03-03 17:56:03 +00:00
|
|
|
|
output <- GetTicketsResp{tickets, count}
|
2021-05-01 12:36:22 +00:00
|
|
|
|
}
|
2021-05-01 17:50:03 +00:00
|
|
|
|
}
|
2021-05-02 22:25:12 +00:00
|
|
|
|
|
|
|
|
|
type ReqPutMessage struct {
|
|
|
|
|
Message string `json:"message"`
|
|
|
|
|
TicketID string `json:"ticket"`
|
|
|
|
|
Files []string `json:"files"`
|
|
|
|
|
Lang string `json:"lang"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Heruvym) PutMessage(
|
|
|
|
|
ctx context.Context,
|
|
|
|
|
request ReqPutMessage,
|
|
|
|
|
) (interface{}, int) {
|
|
|
|
|
sess := jwt_adapter.Get(ctx)
|
2024-02-11 20:16:40 +00:00
|
|
|
|
fmt.Println("PUTMES", sess)
|
2021-05-02 22:25:12 +00:00
|
|
|
|
|
2021-09-05 15:24:13 +00:00
|
|
|
|
request.Files = []string{}
|
|
|
|
|
|
2024-02-11 20:16:40 +00:00
|
|
|
|
domain := ctx.Value(middleware.HostKey).(string)
|
|
|
|
|
if domain == "" {
|
|
|
|
|
fmt.Println("domain is nil err")
|
|
|
|
|
return errors.New("domain is nil"), http.StatusBadRequest
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-02 22:25:12 +00:00
|
|
|
|
message, err := h.dal.PutMessage(
|
|
|
|
|
ctx,
|
|
|
|
|
request.Message,
|
2023-03-01 17:38:03 +00:00
|
|
|
|
sess.Id,
|
|
|
|
|
sess.Id,
|
2021-05-02 22:25:12 +00:00
|
|
|
|
request.TicketID,
|
2022-02-27 15:27:44 +00:00
|
|
|
|
[]string{},
|
2021-05-02 22:25:12 +00:00
|
|
|
|
)
|
2024-02-20 18:43:12 +00:00
|
|
|
|
fmt.Println("PUTMES00", err)
|
2021-05-02 22:25:12 +00:00
|
|
|
|
if err != nil {
|
2023-04-13 18:08:35 +00:00
|
|
|
|
fmt.Println("PUTMES1", err)
|
2021-05-02 22:25:12 +00:00
|
|
|
|
return errors.New("can not put message"), http.StatusInternalServerError
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-03 18:55:29 +00:00
|
|
|
|
role := jwt_adapter.GetRole(ctx)
|
2022-04-14 17:43:13 +00:00
|
|
|
|
go func() {
|
2024-03-03 18:56:07 +00:00
|
|
|
|
if sess.Id != "" && role != "admin" {
|
2022-11-02 18:52:02 +00:00
|
|
|
|
if err == nil && h.notifier != nil {
|
2024-03-03 18:55:29 +00:00
|
|
|
|
var userLink,supportLink string
|
2024-02-17 21:54:46 +00:00
|
|
|
|
if sess.StandardClaims.Issuer != "" {
|
|
|
|
|
fmt.Println("MABNAT", domain)
|
|
|
|
|
if domain[0] == 's' {
|
|
|
|
|
userLink = fmt.Sprintf("https://sadmin.pena/users/%s", sess.Id)
|
2024-03-03 18:55:29 +00:00
|
|
|
|
supportLink = fmt.Sprintf("https://sadmin.pena/support/%s", request.TicketID)
|
2024-02-11 20:16:40 +00:00
|
|
|
|
} else {
|
2024-02-17 21:54:46 +00:00
|
|
|
|
userLink = fmt.Sprintf("https://admin.pena/users/%s", sess.Id)
|
2024-03-03 18:55:29 +00:00
|
|
|
|
supportLink = fmt.Sprintf("https://admin.pena/support/%s", request.TicketID)
|
2024-02-11 20:16:40 +00:00
|
|
|
|
}
|
|
|
|
|
} else {
|
2024-05-02 21:42:57 +00:00
|
|
|
|
if domain[0] == 's' {
|
2024-03-03 18:56:07 +00:00
|
|
|
|
supportLink = fmt.Sprintf("https://sadmin.pena/support/%s", request.TicketID)
|
2024-05-02 21:42:57 +00:00
|
|
|
|
} else {
|
|
|
|
|
supportLink = fmt.Sprintf("https://admin.pena/support/%s", request.TicketID)
|
|
|
|
|
}
|
2024-02-11 20:16:40 +00:00
|
|
|
|
userLink = "незарегистрированного пользователя"
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-03 18:55:29 +00:00
|
|
|
|
message := fmt.Sprintf("Вам пришло сообщение от %s сссылка на пользователя с %s, ссылка на чат - %s",
|
|
|
|
|
userLink, domain, supportLink)
|
2024-02-11 20:16:40 +00:00
|
|
|
|
|
2024-02-13 14:39:01 +00:00
|
|
|
|
if _, err := h.notifier.Send(tb.ChatID(h.tgChatID), message); err != nil {
|
2022-04-14 17:43:13 +00:00
|
|
|
|
fmt.Println("CAN NOT NOTIFY", err)
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
2024-02-11 20:16:40 +00:00
|
|
|
|
}
|
2022-04-14 17:43:13 +00:00
|
|
|
|
}()
|
|
|
|
|
|
2021-05-02 22:25:12 +00:00
|
|
|
|
if err := h.dal.UpdateTopMessage(ctx, request.TicketID, message); err != nil {
|
2024-02-09 00:20:01 +00:00
|
|
|
|
fmt.Println("PUTMES01", err, request.TicketID, message)
|
|
|
|
|
//return errors.New("can not update ticket"), http.StatusInternalServerError
|
2021-05-02 22:25:12 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-02-20 18:43:12 +00:00
|
|
|
|
fmt.Println("PUTMES03")
|
2021-05-02 22:25:12 +00:00
|
|
|
|
return nil, http.StatusOK
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-27 15:27:44 +00:00
|
|
|
|
type ReqScreenshot struct {
|
2022-03-03 17:56:03 +00:00
|
|
|
|
TicketID string `json:"ticket"`
|
|
|
|
|
Lang string `json:"lang"`
|
2022-02-27 15:27:44 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Heruvym) RequestScreenshot(
|
|
|
|
|
ctx context.Context,
|
|
|
|
|
request ReqScreenshot,
|
|
|
|
|
) (interface{}, int) {
|
|
|
|
|
sess := jwt_adapter.Get(ctx)
|
|
|
|
|
|
|
|
|
|
_, err := h.dal.PutSCRequest(
|
|
|
|
|
ctx,
|
2023-03-01 17:38:03 +00:00
|
|
|
|
sess.Id,
|
|
|
|
|
sess.Id,
|
2022-02-27 15:27:44 +00:00
|
|
|
|
request.TicketID,
|
|
|
|
|
)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return errors.New("can not put message"), http.StatusInternalServerError
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil, http.StatusOK
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-02 22:25:12 +00:00
|
|
|
|
var _ tools.DataEmitter = (&Heruvym{}).Subscribe
|
|
|
|
|
|
|
|
|
|
func (h *Heruvym) Subscribe(ctx context.Context) chan interface{} {
|
|
|
|
|
sess := jwt_adapter.Get(ctx)
|
2022-02-27 15:27:44 +00:00
|
|
|
|
fmt.Println("SESS Subsc", sess)
|
2021-05-02 22:25:12 +00:00
|
|
|
|
|
2021-05-15 20:10:07 +00:00
|
|
|
|
ticketID := ctx.Value(tools.ContextURLKey).(string)
|
2022-03-03 17:56:03 +00:00
|
|
|
|
|
2021-05-02 22:25:12 +00:00
|
|
|
|
output := make(chan interface{})
|
2023-03-01 17:38:03 +00:00
|
|
|
|
if sess.Id == "" {
|
2021-05-02 22:25:12 +00:00
|
|
|
|
go func() {
|
2023-03-01 17:38:03 +00:00
|
|
|
|
ticket, err := h.dal.GetTicket4Sess(ctx, ticketID, sess.Id)
|
2021-05-02 22:25:12 +00:00
|
|
|
|
if err != nil || ticket == nil {
|
|
|
|
|
output <- errors.New("no tickets 4 session")
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-14 16:34:55 +00:00
|
|
|
|
/*if err := h.dal.YieldMessages(ctx, ticketID, func(message model.Message) error {
|
2021-05-02 22:25:12 +00:00
|
|
|
|
output <- message
|
2021-09-05 15:24:13 +00:00
|
|
|
|
fmt.Println("OOOOOOLd")
|
2021-05-02 22:25:12 +00:00
|
|
|
|
|
2021-09-05 15:24:13 +00:00
|
|
|
|
//if err := h.dal.SetShown(ctx, message.ID, sess.Session); err != nil {
|
|
|
|
|
//
|
|
|
|
|
// output <- errors.New("cannot show message " + err.Error())
|
|
|
|
|
// return err
|
|
|
|
|
//}
|
2021-05-02 22:25:12 +00:00
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}); err != nil {
|
2021-05-15 20:10:07 +00:00
|
|
|
|
output <- errors.New("cannot read messages " + err.Error())
|
2023-04-14 16:34:55 +00:00
|
|
|
|
}*/
|
2021-05-02 22:25:12 +00:00
|
|
|
|
|
|
|
|
|
if err := h.dal.WatchMessages(ctx, ticketID,
|
|
|
|
|
func(message model.Message) error {
|
|
|
|
|
output <- message
|
|
|
|
|
|
2021-09-05 15:24:13 +00:00
|
|
|
|
//if err := h.dal.SetShown(ctx, message.ID, sess.Session); err != nil {
|
|
|
|
|
// fmt.Println("3", err)
|
|
|
|
|
// output <- errors.New("cannot show watch message " + err.Error())
|
|
|
|
|
// return err
|
|
|
|
|
//}
|
2021-05-02 22:25:12 +00:00
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}); err != nil {
|
2021-05-15 20:10:07 +00:00
|
|
|
|
fmt.Println("4", err)
|
|
|
|
|
output <- errors.New("cannot watch messages " + err.Error())
|
2021-05-02 22:25:12 +00:00
|
|
|
|
}
|
|
|
|
|
}()
|
|
|
|
|
} else {
|
2023-03-01 17:38:03 +00:00
|
|
|
|
role := jwt_adapter.GetRole(ctx)
|
2021-05-02 22:25:12 +00:00
|
|
|
|
|
|
|
|
|
if role == "admin" || role == "manager" {
|
|
|
|
|
go func() {
|
|
|
|
|
|
|
|
|
|
if err := h.dal.YieldMessages(ctx, ticketID, func(message model.Message) error {
|
|
|
|
|
output <- message
|
|
|
|
|
|
2021-09-05 15:24:13 +00:00
|
|
|
|
//if err := h.dal.SetShown(ctx, message.ID, sess.User); err != nil {
|
|
|
|
|
// fmt.Println("2", err)
|
|
|
|
|
// output <- errors.New("cannot show message " + err.Error())
|
|
|
|
|
// return err
|
|
|
|
|
//}
|
2021-05-02 22:25:12 +00:00
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}); err != nil {
|
2021-05-15 20:10:07 +00:00
|
|
|
|
fmt.Println("1", err)
|
|
|
|
|
output <- errors.New("cannot read messages " + err.Error())
|
2021-05-02 22:25:12 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err := h.dal.WatchMessages(ctx, ticketID,
|
|
|
|
|
func(message model.Message) error {
|
|
|
|
|
output <- message
|
|
|
|
|
|
2021-09-05 15:24:13 +00:00
|
|
|
|
//if err := h.dal.SetShown(ctx, message.ID, sess.Session); err != nil {
|
|
|
|
|
// fmt.Println("3", err)
|
|
|
|
|
// output <- errors.New("cannot show watch message " + err.Error())
|
|
|
|
|
// return err
|
|
|
|
|
//}
|
2021-05-02 22:25:12 +00:00
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}); err != nil {
|
2021-05-15 20:10:07 +00:00
|
|
|
|
fmt.Println("4", err)
|
|
|
|
|
output <- errors.New("cannot watch messages " + err.Error())
|
2021-05-02 22:25:12 +00:00
|
|
|
|
}
|
|
|
|
|
}()
|
|
|
|
|
} else {
|
|
|
|
|
go func() {
|
2022-04-14 17:43:13 +00:00
|
|
|
|
defer func() {
|
|
|
|
|
if v := recover(); v != nil {
|
|
|
|
|
fmt.Println("heryvym panic", v)
|
|
|
|
|
}
|
|
|
|
|
}()
|
2023-03-01 17:38:03 +00:00
|
|
|
|
ticket, err := h.dal.GetTicket4User(ctx, ticketID, sess.Id)
|
2021-05-02 22:25:12 +00:00
|
|
|
|
if err != nil || ticket == nil {
|
|
|
|
|
output <- errors.New("no tickets 4 user")
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-14 17:38:55 +00:00
|
|
|
|
/*if err := h.dal.YieldMessages(ctx, ticketID, func(message model.Message) error {
|
2021-05-02 22:25:12 +00:00
|
|
|
|
output <- message
|
|
|
|
|
|
2021-09-05 15:24:13 +00:00
|
|
|
|
//if err := h.dal.SetShown(ctx, message.ID, sess.User); err != nil {
|
|
|
|
|
// fmt.Println("2", err)
|
|
|
|
|
// output <- errors.New("cannot show message " + err.Error())
|
|
|
|
|
// return err
|
|
|
|
|
//}
|
2021-05-02 22:25:12 +00:00
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}); err != nil {
|
2021-05-15 20:10:07 +00:00
|
|
|
|
fmt.Println("1", err)
|
|
|
|
|
output <- errors.New("cannot read messages " + err.Error())
|
2023-04-14 17:38:55 +00:00
|
|
|
|
}*/
|
2021-05-02 22:25:12 +00:00
|
|
|
|
|
|
|
|
|
if err := h.dal.WatchMessages(ctx, ticketID,
|
|
|
|
|
func(message model.Message) error {
|
|
|
|
|
output <- message
|
|
|
|
|
|
2021-09-05 15:24:13 +00:00
|
|
|
|
//if err := h.dal.SetShown(ctx, message.ID, sess.Session); err != nil {
|
|
|
|
|
// fmt.Println("3", err)
|
|
|
|
|
// output <- errors.New("cannot show watch message " + err.Error())
|
|
|
|
|
// return err
|
|
|
|
|
//}
|
2021-05-02 22:25:12 +00:00
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}); err != nil {
|
2021-05-15 20:10:07 +00:00
|
|
|
|
fmt.Println("4", err)
|
|
|
|
|
output <- errors.New("cannot watch messages " + err.Error())
|
2021-05-02 22:25:12 +00:00
|
|
|
|
}
|
|
|
|
|
}()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return output
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Heruvym) handleOwnMessages(output chan interface{}) {
|
|
|
|
|
defer close(output)
|
2021-05-11 10:57:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type GetTicketsReq struct {
|
|
|
|
|
Amount int64 `json:"amt"`
|
|
|
|
|
Page int64 `json:"page"`
|
|
|
|
|
Search string `json:"srch"`
|
|
|
|
|
Status string `json:"status"`
|
|
|
|
|
}
|
2022-02-27 15:27:44 +00:00
|
|
|
|
type GetTicketsResp struct {
|
2022-03-03 17:56:03 +00:00
|
|
|
|
Data []model.Ticket `json:"data"`
|
|
|
|
|
Count int64 `json:"count"`
|
2022-02-27 15:27:44 +00:00
|
|
|
|
}
|
2021-05-11 10:57:58 +00:00
|
|
|
|
|
|
|
|
|
func (h *Heruvym) GetTickets(
|
|
|
|
|
ctx context.Context,
|
2022-02-27 15:27:44 +00:00
|
|
|
|
request GetTicketsReq) (GetTicketsResp, int) {
|
2023-04-05 21:10:08 +00:00
|
|
|
|
|
2023-03-29 13:15:07 +00:00
|
|
|
|
role := jwt_adapter.GetRole(ctx)
|
|
|
|
|
|
|
|
|
|
if role == "admin" {
|
|
|
|
|
result, count, err := h.dal.GetTicketPage(ctx,
|
|
|
|
|
request.Status,
|
|
|
|
|
request.Search,
|
|
|
|
|
request.Amount,
|
|
|
|
|
request.Page,
|
|
|
|
|
)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return GetTicketsResp{}, http.StatusNoContent
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return GetTicketsResp{
|
|
|
|
|
Data: *result,
|
|
|
|
|
Count: count,
|
|
|
|
|
}, http.StatusOK
|
|
|
|
|
} else {
|
|
|
|
|
|
2023-04-05 21:10:08 +00:00
|
|
|
|
sess := jwt_adapter.Get(ctx)
|
2021-05-11 10:57:58 +00:00
|
|
|
|
|
2023-03-29 13:37:17 +00:00
|
|
|
|
result, count, err := h.dal.YieldUserTickets(ctx, sess.Id, request.Amount, request.Page*request.Amount)
|
2023-03-29 13:15:07 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
return GetTicketsResp{}, http.StatusNoContent
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return GetTicketsResp{
|
2023-03-29 14:01:34 +00:00
|
|
|
|
Data: result,
|
2023-03-29 13:15:07 +00:00
|
|
|
|
Count: count,
|
|
|
|
|
}, http.StatusOK
|
|
|
|
|
}
|
2021-05-11 10:57:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type GetMessagesReq struct {
|
|
|
|
|
Amount int64 `json:"amt"`
|
|
|
|
|
Page int64 `json:"page"`
|
|
|
|
|
Search string `json:"srch"`
|
|
|
|
|
TicketID string `json:"ticket"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Heruvym) GetMessages(
|
|
|
|
|
ctx context.Context,
|
|
|
|
|
request GetMessagesReq) ([]model.Message, int) {
|
|
|
|
|
result, err := h.dal.GetMessagesPage(ctx,
|
|
|
|
|
request.Search,
|
|
|
|
|
request.TicketID,
|
|
|
|
|
request.Amount,
|
|
|
|
|
request.Page,
|
|
|
|
|
)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, http.StatusNoContent
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result, http.StatusOK
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type CloseTicketReq struct {
|
|
|
|
|
TicketID string `json:"ticket"`
|
|
|
|
|
}
|
2022-02-27 15:27:44 +00:00
|
|
|
|
type CloseTicketResp struct {
|
|
|
|
|
TicketID string `json:"ticket"`
|
|
|
|
|
}
|
2021-05-11 10:57:58 +00:00
|
|
|
|
|
2022-02-27 15:27:44 +00:00
|
|
|
|
func (h *Heruvym) CloseTicket(ctx context.Context, req CloseTicketReq) (*CloseTicketResp, int) {
|
2021-05-11 10:57:58 +00:00
|
|
|
|
if err := h.dal.SetTicketStatus(ctx, req.TicketID, model.StateClose); err != nil {
|
2022-02-27 15:27:44 +00:00
|
|
|
|
return nil, http.StatusBadRequest
|
2021-05-11 10:57:58 +00:00
|
|
|
|
}
|
2021-05-02 22:25:12 +00:00
|
|
|
|
|
2022-04-14 17:43:13 +00:00
|
|
|
|
if _, err := h.dal.PutMessage(ctx, "close", "close", "close", req.TicketID, []string{}); err != nil {
|
|
|
|
|
return nil, http.StatusBadRequest
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-27 15:27:44 +00:00
|
|
|
|
return &CloseTicketResp{
|
|
|
|
|
TicketID: req.TicketID,
|
|
|
|
|
}, http.StatusOK
|
2021-05-11 10:57:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type VoteReq struct {
|
|
|
|
|
TicketID string `json:"ticket"`
|
|
|
|
|
Rate int `json:"rate"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Heruvym) Vote(ctx context.Context, req VoteReq) (error, int) {
|
|
|
|
|
if err := h.dal.SetRate(ctx, req.TicketID, req.Rate); err != nil {
|
|
|
|
|
return err, http.StatusBadRequest
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil, http.StatusOK
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type PickReq struct {
|
|
|
|
|
TicketID string `json:"ticket"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Heruvym) Pick(ctx context.Context, req PickReq) (error, int) {
|
|
|
|
|
sess := jwt_adapter.Get(ctx)
|
2023-03-01 17:38:03 +00:00
|
|
|
|
if err := h.dal.SetAnswerer(ctx, req.TicketID, sess.Id); err != nil {
|
2021-05-11 10:57:58 +00:00
|
|
|
|
return err, http.StatusBadRequest
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil, http.StatusOK
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type DelegateReq struct {
|
|
|
|
|
TicketID string `json:"ticket"`
|
|
|
|
|
AnswererID string `json:"answerer"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (h *Heruvym) Delegate(ctx context.Context, req DelegateReq) (error, int) {
|
|
|
|
|
if err := h.dal.SetAnswerer(ctx, req.TicketID, req.AnswererID); err != nil {
|
|
|
|
|
return err, http.StatusBadRequest
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil, http.StatusOK
|
2021-05-02 22:25:12 +00:00
|
|
|
|
}
|
2022-03-03 17:56:03 +00:00
|
|
|
|
|
2021-09-05 15:24:13 +00:00
|
|
|
|
// MB Size constants
|
|
|
|
|
const (
|
|
|
|
|
MB = 1 << 20
|
|
|
|
|
)
|
|
|
|
|
|
2024-02-22 14:52:06 +00:00
|
|
|
|
var fileTypeLimits = map[string]int64{
|
|
|
|
|
"image": 5 * MB,
|
|
|
|
|
"video": 50 * MB,
|
|
|
|
|
"document": 10 * MB,
|
|
|
|
|
}
|
|
|
|
|
|
2021-09-05 15:24:13 +00:00
|
|
|
|
type PutFileReq struct {
|
|
|
|
|
Ticket string `json:"ticket"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type PutFileResp struct {
|
|
|
|
|
Message string `json:"message"`
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-03 17:56:03 +00:00
|
|
|
|
func (h *Heruvym) PutFile(w http.ResponseWriter, r *http.Request) {
|
2021-09-05 15:24:13 +00:00
|
|
|
|
defer r.Body.Close()
|
|
|
|
|
|
2024-02-21 14:42:23 +00:00
|
|
|
|
sess := jwt_adapter.Get(r.Context())
|
|
|
|
|
if sess == nil {
|
|
|
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
|
|
|
if _, err := w.Write([]byte("not authorized")); err != nil {
|
|
|
|
|
fmt.Println("CAN NOT WRITE", err)
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-21 18:07:40 +00:00
|
|
|
|
TimeKey := fmt.Sprintf("sendLockHeruvym:%s", sess.Id)
|
2024-05-10 11:56:51 +00:00
|
|
|
|
isNewKey, err := h.redisClient.SetNX(r.Context(), TimeKey, time.Now().Unix(), 30*time.Second).Result()
|
2024-02-21 18:07:40 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
fmt.Println("failed check last upload time in Redis:", err)
|
|
|
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
|
|
|
if _, err := w.Write([]byte("internal server error")); err != nil {
|
|
|
|
|
fmt.Println("CAN NOT WRITE", err)
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !isNewKey {
|
|
|
|
|
w.WriteHeader(http.StatusTooManyRequests)
|
|
|
|
|
if _, err := w.Write([]byte("file upload limit exceeded")); err != nil {
|
|
|
|
|
fmt.Println("CAN NOT WRITE", err)
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2021-09-05 15:24:13 +00:00
|
|
|
|
if err := r.ParseMultipartForm(10 * MB); err != nil {
|
2023-05-16 09:35:07 +00:00
|
|
|
|
w.WriteHeader(http.StatusBadRequest)
|
2022-03-03 17:56:03 +00:00
|
|
|
|
if _, err := w.Write([]byte("can not parse multipart " + err.Error())); err != nil {
|
2021-09-05 15:24:13 +00:00
|
|
|
|
fmt.Println("CAN NOT WRITE", err)
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if r.MultipartForm == nil {
|
2023-05-16 09:35:07 +00:00
|
|
|
|
w.WriteHeader(http.StatusBadRequest)
|
2021-09-05 15:24:13 +00:00
|
|
|
|
if _, err := w.Write([]byte("no multipart")); err != nil {
|
|
|
|
|
fmt.Println("CAN NOT WRITE", err)
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if r.MultipartForm.File == nil {
|
2023-05-16 09:35:07 +00:00
|
|
|
|
w.WriteHeader(http.StatusBadRequest)
|
2021-09-05 15:24:13 +00:00
|
|
|
|
if _, err := w.Write([]byte("no file")); err != nil {
|
|
|
|
|
fmt.Println("CAN NOT WRITE", err)
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-21 14:42:23 +00:00
|
|
|
|
for _, files := range r.MultipartForm.File {
|
|
|
|
|
for _, fileHeader := range files {
|
|
|
|
|
fileSize := fileHeader.Size
|
|
|
|
|
fileType := utils.GetFileType(fileHeader.Filename)
|
2021-09-05 15:24:13 +00:00
|
|
|
|
|
2024-02-22 15:26:34 +00:00
|
|
|
|
if limit, ok := fileTypeLimits[fileType]; ok {
|
|
|
|
|
if fileSize > limit {
|
2024-02-21 14:42:23 +00:00
|
|
|
|
w.WriteHeader(http.StatusRequestEntityTooLarge)
|
2024-02-22 15:26:34 +00:00
|
|
|
|
if _, err := w.Write([]byte(fileType + " file size exceeds the limit")); err != nil {
|
2024-02-21 14:42:23 +00:00
|
|
|
|
fmt.Println("CAN NOT WRITE", err)
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
2024-02-22 15:26:34 +00:00
|
|
|
|
} else {
|
2024-02-21 14:42:23 +00:00
|
|
|
|
w.WriteHeader(http.StatusNotAcceptable)
|
|
|
|
|
if _, err := w.Write([]byte("Unsupported file type")); err != nil {
|
|
|
|
|
fmt.Println("CAN NOT WRITE", err)
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
2021-09-05 15:24:13 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-21 14:42:23 +00:00
|
|
|
|
filesCount := len(r.MultipartForm.File)
|
|
|
|
|
|
|
|
|
|
if filesCount == 0 {
|
2023-05-16 09:35:07 +00:00
|
|
|
|
w.WriteHeader(http.StatusBadRequest)
|
2024-02-21 14:42:23 +00:00
|
|
|
|
if _, err := w.Write([]byte("no files")); err != nil {
|
2021-09-05 15:24:13 +00:00
|
|
|
|
fmt.Println("CAN NOT WRITE", err)
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var req PutFileReq
|
2022-11-02 18:52:02 +00:00
|
|
|
|
req.Ticket = r.MultipartForm.Value["ticket"][0]
|
2021-09-05 15:24:13 +00:00
|
|
|
|
|
|
|
|
|
var (
|
|
|
|
|
fileIDs, filenames []string
|
2022-03-03 17:56:03 +00:00
|
|
|
|
errFile error
|
2021-09-05 15:24:13 +00:00
|
|
|
|
)
|
2022-03-03 17:56:03 +00:00
|
|
|
|
wg := new(sync.WaitGroup)
|
|
|
|
|
m := new(sync.Mutex)
|
2021-09-05 15:24:13 +00:00
|
|
|
|
|
|
|
|
|
wg.Add(filesCount)
|
|
|
|
|
for name, file := range r.MultipartForm.File {
|
|
|
|
|
file := file
|
|
|
|
|
name := name
|
|
|
|
|
go func() {
|
|
|
|
|
defer wg.Done()
|
|
|
|
|
|
|
|
|
|
freader, err := file[0].Open()
|
|
|
|
|
if err != nil {
|
|
|
|
|
fmt.Println("can not open ", err.Error())
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-22 14:52:06 +00:00
|
|
|
|
hash := sha256.New()
|
|
|
|
|
if _, err := io.Copy(hash, freader); err != nil {
|
|
|
|
|
fmt.Println("error calculating file hash: ", err)
|
|
|
|
|
errFile = err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_, err = freader.Seek(0, 0)
|
|
|
|
|
if err != nil {
|
|
|
|
|
fmt.Println("error seeking back to the beginning of the file: ", err)
|
|
|
|
|
errFile = err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
hashInBytes := hash.Sum(nil)
|
|
|
|
|
fileHash := hex.EncodeToString(hashInBytes)
|
|
|
|
|
splitted := strings.Split(name, ".")
|
|
|
|
|
filename := fmt.Sprintf("%s_%s.%s", fileHash, sess.Id, splitted[len(splitted)-1])
|
|
|
|
|
|
2021-09-05 15:24:13 +00:00
|
|
|
|
defer func() {
|
|
|
|
|
if err := freader.Close(); err != nil {
|
|
|
|
|
errFile = err
|
|
|
|
|
}
|
|
|
|
|
}()
|
|
|
|
|
|
2024-02-22 13:34:33 +00:00
|
|
|
|
exists, err := h.bs.FileExists(r.Context(), filename)
|
|
|
|
|
if err != nil {
|
|
|
|
|
errFile = err
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if exists {
|
2024-03-03 15:08:01 +00:00
|
|
|
|
response := struct {
|
|
|
|
|
File string `json:"file"`
|
|
|
|
|
}{
|
|
|
|
|
File: filename,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
resp, err := json.Marshal(response)
|
|
|
|
|
if err != nil {
|
|
|
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
|
|
|
if _, err := w.Write([]byte("error marshaling response: " + err.Error())); err != nil {
|
|
|
|
|
fmt.Println("CAN NOT WRITE", err)
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-22 13:34:33 +00:00
|
|
|
|
w.WriteHeader(http.StatusAlreadyReported)
|
2024-03-03 15:08:01 +00:00
|
|
|
|
if _, err := w.Write(resp); err != nil {
|
2024-02-22 13:34:33 +00:00
|
|
|
|
fmt.Println("CAN NOT WRITE", err)
|
|
|
|
|
}
|
2024-03-13 15:08:46 +00:00
|
|
|
|
m.Lock()
|
|
|
|
|
defer m.Unlock()
|
|
|
|
|
fileIDs = append(fileIDs, filename)
|
|
|
|
|
filenames = append(filenames, name)
|
2024-02-22 13:34:33 +00:00
|
|
|
|
return
|
|
|
|
|
}
|
2021-09-05 15:24:13 +00:00
|
|
|
|
|
|
|
|
|
if err := h.bs.PutFile(
|
|
|
|
|
r.Context(),
|
|
|
|
|
filename,
|
|
|
|
|
freader,
|
|
|
|
|
file[0].Size); err != nil {
|
|
|
|
|
errFile = err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m.Lock()
|
|
|
|
|
defer m.Unlock()
|
|
|
|
|
fileIDs = append(fileIDs, filename)
|
|
|
|
|
filenames = append(filenames, name)
|
|
|
|
|
}()
|
|
|
|
|
}
|
|
|
|
|
wg.Wait()
|
2024-03-13 15:08:46 +00:00
|
|
|
|
|
|
|
|
|
if len(fileIDs) == 0 {
|
|
|
|
|
return
|
|
|
|
|
}
|
2021-09-05 15:24:13 +00:00
|
|
|
|
|
|
|
|
|
if errFile != nil {
|
2023-05-16 09:35:07 +00:00
|
|
|
|
w.WriteHeader(http.StatusInternalServerError)
|
2022-03-03 17:56:03 +00:00
|
|
|
|
if _, err := w.Write([]byte("can not store files " + errFile.Error())); err != nil {
|
2021-09-05 15:24:13 +00:00
|
|
|
|
fmt.Println("CAN NOT WRITE", err)
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
message, err := h.dal.PutMessage(
|
|
|
|
|
r.Context(),
|
|
|
|
|
strings.Join(filenames, ", "),
|
2023-03-01 17:38:03 +00:00
|
|
|
|
sess.Id,
|
|
|
|
|
sess.Id,
|
2021-09-05 15:24:13 +00:00
|
|
|
|
req.Ticket,
|
|
|
|
|
fileIDs,
|
|
|
|
|
)
|
|
|
|
|
|
2022-03-03 17:56:03 +00:00
|
|
|
|
if err != nil {
|
2021-09-05 15:24:13 +00:00
|
|
|
|
for _, filename := range filenames {
|
|
|
|
|
if err := h.bs.DeleteFile(r.Context(), filename); err != nil {
|
|
|
|
|
fmt.Println("can not delete", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-16 09:35:07 +00:00
|
|
|
|
w.WriteHeader(http.StatusInternalServerError)
|
2022-03-03 17:56:03 +00:00
|
|
|
|
if _, err := w.Write([]byte("can not store message " + err.Error())); err != nil {
|
2021-09-05 15:24:13 +00:00
|
|
|
|
fmt.Println("CAN NOT WRITE", err)
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
resp, err := json.Marshal(&PutFileResp{Message: message.ID})
|
|
|
|
|
if err != nil {
|
2023-05-16 09:35:07 +00:00
|
|
|
|
w.WriteHeader(http.StatusInternalServerError)
|
2022-03-03 17:56:03 +00:00
|
|
|
|
if _, err := w.Write([]byte("can not marshal resp " + err.Error())); err != nil {
|
2021-09-05 15:24:13 +00:00
|
|
|
|
fmt.Println("CAN NOT WRITE", err)
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
2024-05-08 17:44:52 +00:00
|
|
|
|
ctx := r.Context()
|
|
|
|
|
domain := ctx.Value(middleware.HostKey).(string)
|
|
|
|
|
if domain == "" {
|
|
|
|
|
fmt.Println("domain is nil err")
|
|
|
|
|
}
|
|
|
|
|
role := jwt_adapter.GetRole(ctx)
|
|
|
|
|
go func() {
|
|
|
|
|
if sess.Id != "" && role != "admin" {
|
|
|
|
|
if err == nil && h.notifier != nil {
|
|
|
|
|
var userLink, supportLink string
|
|
|
|
|
if sess.StandardClaims.Issuer != "" {
|
|
|
|
|
fmt.Println("MABNAT", domain)
|
|
|
|
|
if domain[0] == 's' {
|
|
|
|
|
userLink = fmt.Sprintf("https://sadmin.pena/users/%s", sess.Id)
|
|
|
|
|
supportLink = fmt.Sprintf("https://sadmin.pena/support/%s", req.Ticket)
|
|
|
|
|
} else {
|
|
|
|
|
userLink = fmt.Sprintf("https://admin.pena/users/%s", sess.Id)
|
|
|
|
|
supportLink = fmt.Sprintf("https://admin.pena/support/%s", req.Ticket)
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if domain[0] == 's' {
|
|
|
|
|
supportLink = fmt.Sprintf("https://sadmin.pena/support/%s", req.Ticket)
|
|
|
|
|
} else {
|
|
|
|
|
supportLink = fmt.Sprintf("https://admin.pena/support/%s", req.Ticket)
|
|
|
|
|
}
|
|
|
|
|
userLink = "незарегистрированного пользователя"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
message := fmt.Sprintf("Вам пришло сообщение от %s сссылка на пользователя с %s, ccылка на чат - %s",
|
|
|
|
|
userLink, domain, supportLink)
|
|
|
|
|
|
|
|
|
|
if _, err := h.notifier.Send(tb.ChatID(h.tgChatID), message); err != nil {
|
|
|
|
|
fmt.Println("CAN NOT NOTIFY", err)
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}()
|
|
|
|
|
|
2021-09-05 15:24:13 +00:00
|
|
|
|
|
2022-02-27 15:27:44 +00:00
|
|
|
|
if _, err := w.Write(resp); err != nil {
|
|
|
|
|
fmt.Println("CAN NOT WRITE", err)
|
|
|
|
|
}
|
2023-05-16 09:35:07 +00:00
|
|
|
|
w.WriteHeader(http.StatusOK) // Необязательно, т.к. w.Write сам вызывает w.WriteHeader(http.StatusOK) перед выполнением
|
2022-02-27 15:27:44 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type PutSCReq struct {
|
|
|
|
|
Ticket string `json:"ticket"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type PutSCResp struct {
|
|
|
|
|
Message string `json:"message"`
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-03 17:56:03 +00:00
|
|
|
|
func (h *Heruvym) PutSC(w http.ResponseWriter, r *http.Request) {
|
2022-02-27 15:27:44 +00:00
|
|
|
|
defer r.Body.Close()
|
|
|
|
|
|
|
|
|
|
if err := r.ParseMultipartForm(10 * MB); err != nil {
|
2023-05-16 09:35:07 +00:00
|
|
|
|
w.WriteHeader(http.StatusBadRequest)
|
2022-03-03 17:56:03 +00:00
|
|
|
|
if _, err := w.Write([]byte("can not parse multipart " + err.Error())); err != nil {
|
2022-02-27 15:27:44 +00:00
|
|
|
|
fmt.Println("CAN NOT WRITE", err)
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if r.MultipartForm == nil {
|
2023-05-16 09:35:07 +00:00
|
|
|
|
w.WriteHeader(http.StatusBadRequest)
|
2022-02-27 15:27:44 +00:00
|
|
|
|
if _, err := w.Write([]byte("no multipart")); err != nil {
|
|
|
|
|
fmt.Println("CAN NOT WRITE", err)
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if r.MultipartForm.File == nil {
|
2023-05-16 09:35:07 +00:00
|
|
|
|
w.WriteHeader(http.StatusBadRequest)
|
2022-02-27 15:27:44 +00:00
|
|
|
|
if _, err := w.Write([]byte("no file")); err != nil {
|
|
|
|
|
fmt.Println("CAN NOT WRITE", err)
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-03 17:56:03 +00:00
|
|
|
|
filesCount := len(r.MultipartForm.File)
|
2022-02-27 15:27:44 +00:00
|
|
|
|
|
|
|
|
|
if filesCount == 0 {
|
2023-05-16 09:35:07 +00:00
|
|
|
|
w.WriteHeader(http.StatusBadRequest)
|
2022-02-27 15:27:44 +00:00
|
|
|
|
if _, err := w.Write([]byte("no files")); err != nil {
|
|
|
|
|
fmt.Println("CAN NOT WRITE", err)
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sess := jwt_adapter.Get(r.Context())
|
|
|
|
|
if sess == nil {
|
2023-05-16 09:35:07 +00:00
|
|
|
|
w.WriteHeader(http.StatusUnauthorized)
|
2022-02-27 15:27:44 +00:00
|
|
|
|
if _, err := w.Write([]byte("not authorized")); err != nil {
|
|
|
|
|
fmt.Println("CAN NOT WRITE", err)
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var req PutFileReq
|
|
|
|
|
|
2022-11-02 18:52:02 +00:00
|
|
|
|
req.Ticket = r.MultipartForm.Value["ticket"][0]
|
2022-02-27 15:27:44 +00:00
|
|
|
|
var (
|
|
|
|
|
fileIDs, filenames []string
|
2022-03-03 17:56:03 +00:00
|
|
|
|
errFile error
|
2022-02-27 15:27:44 +00:00
|
|
|
|
)
|
2022-03-03 17:56:03 +00:00
|
|
|
|
wg := new(sync.WaitGroup)
|
|
|
|
|
m := new(sync.Mutex)
|
2022-02-27 15:27:44 +00:00
|
|
|
|
|
|
|
|
|
wg.Add(filesCount)
|
|
|
|
|
for name, file := range r.MultipartForm.File {
|
|
|
|
|
file := file
|
|
|
|
|
name := name
|
|
|
|
|
go func() {
|
|
|
|
|
defer wg.Done()
|
|
|
|
|
|
|
|
|
|
freader, err := file[0].Open()
|
|
|
|
|
if err != nil {
|
|
|
|
|
fmt.Println("can not open ", err.Error())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
defer func() {
|
|
|
|
|
if err := freader.Close(); err != nil {
|
|
|
|
|
errFile = err
|
|
|
|
|
}
|
|
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
splitted := strings.Split(name, ".")
|
2022-03-03 17:56:03 +00:00
|
|
|
|
filename := fmt.Sprintf("%s.%s", xid.New().String(), splitted[len(splitted)-1])
|
2022-02-27 15:27:44 +00:00
|
|
|
|
|
|
|
|
|
if err := h.bs.PutFile(
|
|
|
|
|
r.Context(),
|
|
|
|
|
filename,
|
|
|
|
|
freader,
|
|
|
|
|
file[0].Size); err != nil {
|
|
|
|
|
errFile = err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m.Lock()
|
|
|
|
|
defer m.Unlock()
|
|
|
|
|
fileIDs = append(fileIDs, filename)
|
|
|
|
|
filenames = append(filenames, name)
|
|
|
|
|
}()
|
|
|
|
|
}
|
|
|
|
|
wg.Wait()
|
|
|
|
|
|
|
|
|
|
if errFile != nil {
|
2023-05-16 09:35:07 +00:00
|
|
|
|
w.WriteHeader(http.StatusInternalServerError)
|
2022-03-03 17:56:03 +00:00
|
|
|
|
if _, err := w.Write([]byte("can not store files " + errFile.Error())); err != nil {
|
2022-02-27 15:27:44 +00:00
|
|
|
|
fmt.Println("CAN NOT WRITE", err)
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
message, err := h.dal.PutSCResponse(
|
|
|
|
|
r.Context(),
|
|
|
|
|
strings.Join(filenames, ", "),
|
2023-03-01 17:38:03 +00:00
|
|
|
|
sess.Id,
|
|
|
|
|
sess.Id,
|
2022-02-27 15:27:44 +00:00
|
|
|
|
req.Ticket,
|
|
|
|
|
fileIDs,
|
|
|
|
|
)
|
|
|
|
|
|
2022-03-03 17:56:03 +00:00
|
|
|
|
if err != nil {
|
2022-02-27 15:27:44 +00:00
|
|
|
|
for _, filename := range filenames {
|
|
|
|
|
if err := h.bs.DeleteFile(r.Context(), filename); err != nil {
|
|
|
|
|
fmt.Println("can not delete", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-05-16 09:35:07 +00:00
|
|
|
|
w.WriteHeader(http.StatusInternalServerError)
|
2022-03-03 17:56:03 +00:00
|
|
|
|
if _, err := w.Write([]byte("can not store message " + err.Error())); err != nil {
|
2022-02-27 15:27:44 +00:00
|
|
|
|
fmt.Println("CAN NOT WRITE", err)
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
resp, err := json.Marshal(&PutFileResp{Message: message.ID})
|
|
|
|
|
if err != nil {
|
2023-05-16 09:35:07 +00:00
|
|
|
|
w.WriteHeader(http.StatusInternalServerError)
|
2022-03-03 17:56:03 +00:00
|
|
|
|
if _, err := w.Write([]byte("can not marshal resp " + err.Error())); err != nil {
|
2022-02-27 15:27:44 +00:00
|
|
|
|
fmt.Println("CAN NOT WRITE", err)
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2021-09-05 15:24:13 +00:00
|
|
|
|
if _, err := w.Write(resp); err != nil {
|
|
|
|
|
fmt.Println("CAN NOT WRITE", err)
|
|
|
|
|
}
|
|
|
|
|
w.WriteHeader(http.StatusOK)
|
2022-03-03 17:56:03 +00:00
|
|
|
|
}
|
2023-08-08 22:27:24 +00:00
|
|
|
|
|
|
|
|
|
type ShownReq struct {
|
2024-02-11 20:16:40 +00:00
|
|
|
|
ID string `json:"id"`
|
2023-08-08 22:27:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-08-08 23:44:13 +00:00
|
|
|
|
func (h *Heruvym) SetShown(ctx context.Context, req ShownReq) (error, int) {
|
2024-02-11 20:16:40 +00:00
|
|
|
|
return h.dal.SetShown(ctx, req.ID, "me"), http.StatusOK
|
2023-08-08 22:27:24 +00:00
|
|
|
|
}
|