2024-07-12 09:37:56 +00:00
|
|
|
package account_client
|
2024-05-21 13:50:26 +00:00
|
|
|
|
|
|
|
import (
|
2024-05-24 10:25:37 +00:00
|
|
|
"bufio"
|
|
|
|
"context"
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
2024-05-21 13:50:26 +00:00
|
|
|
"github.com/gofiber/fiber/v2"
|
|
|
|
"go.uber.org/zap"
|
2024-06-07 14:28:54 +00:00
|
|
|
"penahub.gitlab.yandexcloud.net/backend/penahub_common/log_mw"
|
2024-05-21 13:50:26 +00:00
|
|
|
qutils "penahub.gitlab.yandexcloud.net/backend/quiz/common.git/utils"
|
|
|
|
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/errors"
|
|
|
|
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/client"
|
|
|
|
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/controller/http"
|
|
|
|
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/interface/repository"
|
|
|
|
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Deps struct {
|
|
|
|
MiddleWare *http.MiddleWare
|
|
|
|
AccountRepo *repository.AccountRepository
|
|
|
|
Logger *zap.Logger
|
|
|
|
Encrypt *qutils.Encrypt
|
|
|
|
AuthClient *client.AuthClient
|
|
|
|
}
|
|
|
|
|
|
|
|
type AccountController struct {
|
|
|
|
middleWare *http.MiddleWare
|
|
|
|
accountRepo *repository.AccountRepository
|
|
|
|
logger *zap.Logger
|
|
|
|
encrypt *qutils.Encrypt
|
|
|
|
authClient *client.AuthClient
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewAccountController(deps Deps) *AccountController {
|
|
|
|
return &AccountController{
|
|
|
|
middleWare: deps.MiddleWare,
|
|
|
|
accountRepo: deps.AccountRepo,
|
|
|
|
logger: deps.Logger,
|
|
|
|
encrypt: deps.Encrypt,
|
|
|
|
authClient: deps.AuthClient,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-05-23 07:15:26 +00:00
|
|
|
func (receiver *AccountController) Delete(ctx *fiber.Ctx) error {
|
2024-05-21 13:50:26 +00:00
|
|
|
userID, ok := receiver.middleWare.ExtractUserID(ctx)
|
|
|
|
if !ok || userID == "" {
|
|
|
|
return receiver.middleWare.NoAuth(ctx)
|
|
|
|
}
|
|
|
|
|
|
|
|
account, err := receiver.accountRepo.Remove(ctx.Context(), userID)
|
|
|
|
if err != nil {
|
|
|
|
return receiver.middleWare.ErrorOld(ctx, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return ctx.Status(fiber.StatusOK).JSON(account)
|
|
|
|
}
|
|
|
|
|
2024-05-23 07:15:26 +00:00
|
|
|
func (receiver *AccountController) Update(ctx *fiber.Ctx) error {
|
2024-05-21 13:50:26 +00:00
|
|
|
userID, ok := receiver.middleWare.ExtractUserID(ctx)
|
|
|
|
if !ok || userID == "" {
|
|
|
|
return receiver.middleWare.NoAuth(ctx)
|
|
|
|
}
|
|
|
|
|
|
|
|
var request models.Name
|
|
|
|
if err := ctx.BodyParser(&request); err != nil {
|
|
|
|
return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "failed to bind json", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
account, err := receiver.accountRepo.UpdateName(ctx.Context(), userID, &request)
|
|
|
|
if err != nil {
|
|
|
|
return receiver.middleWare.ErrorOld(ctx, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return ctx.Status(fiber.StatusOK).JSON(account)
|
|
|
|
}
|
|
|
|
|
2024-05-23 07:15:26 +00:00
|
|
|
func (receiver *AccountController) SetVerificationStatus(ctx *fiber.Ctx) error {
|
2024-05-21 13:50:26 +00:00
|
|
|
userID := ctx.Params("userId")
|
|
|
|
if userID == "" {
|
|
|
|
return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "invalid format for parameter userId")
|
|
|
|
}
|
|
|
|
|
|
|
|
var request models.SetAccountStatus
|
|
|
|
if err := ctx.BodyParser(&request); err != nil {
|
|
|
|
return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "failed to bind json", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
account, err := receiver.accountRepo.SetStatus(ctx.Context(), userID, request.Status)
|
|
|
|
if err != nil {
|
|
|
|
receiver.logger.Error("failed to set status on <SetVerificationStatus> of <AccountService>", zap.Error(err))
|
|
|
|
return receiver.middleWare.ErrorOld(ctx, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return ctx.Status(fiber.StatusOK).JSON(account)
|
|
|
|
}
|
|
|
|
|
2024-05-23 07:15:26 +00:00
|
|
|
func (receiver *AccountController) Get(ctx *fiber.Ctx) error {
|
2024-05-21 13:50:26 +00:00
|
|
|
userID, ok := receiver.middleWare.ExtractUserID(ctx)
|
|
|
|
if !ok || userID == "" {
|
|
|
|
return receiver.middleWare.NoAuth(ctx)
|
|
|
|
}
|
|
|
|
|
2024-06-07 14:28:54 +00:00
|
|
|
hlogger := log_mw.ExtractLogger(ctx)
|
2024-05-23 14:34:45 +00:00
|
|
|
|
2024-05-21 13:50:26 +00:00
|
|
|
account, err := receiver.accountRepo.FindByUserID(ctx.Context(), userID)
|
|
|
|
if err != nil {
|
2024-06-08 17:17:26 +00:00
|
|
|
if err.Type() == errors.ErrNotFound {
|
2024-06-08 17:24:30 +00:00
|
|
|
return receiver.middleWare.Error(ctx, fiber.StatusNotFound, "no account", err)
|
2024-06-08 17:17:26 +00:00
|
|
|
}
|
2024-05-21 13:50:26 +00:00
|
|
|
return receiver.middleWare.ErrorOld(ctx, err)
|
|
|
|
}
|
|
|
|
|
2024-05-23 14:34:45 +00:00
|
|
|
hlogger.Emit(models.InfoGetAccount{
|
|
|
|
CtxUserID: userID,
|
|
|
|
CtxAccountID: account.ID,
|
|
|
|
})
|
|
|
|
|
2024-05-21 13:50:26 +00:00
|
|
|
return ctx.Status(fiber.StatusOK).JSON(account)
|
|
|
|
}
|
|
|
|
|
2024-05-23 07:15:26 +00:00
|
|
|
func (receiver *AccountController) Create(ctx *fiber.Ctx) error {
|
2024-05-21 13:50:26 +00:00
|
|
|
userID, ok := receiver.middleWare.ExtractUserID(ctx)
|
|
|
|
if !ok || userID == "" {
|
|
|
|
return receiver.middleWare.NoAuth(ctx)
|
|
|
|
}
|
|
|
|
|
2024-06-07 14:28:54 +00:00
|
|
|
hlogger := log_mw.ExtractLogger(ctx)
|
2024-05-23 14:34:45 +00:00
|
|
|
|
2024-05-21 13:50:26 +00:00
|
|
|
var er error
|
|
|
|
|
|
|
|
quizFrom := ctx.Cookies("quizFrom")
|
|
|
|
quizUser := ctx.Cookies("quizUser")
|
|
|
|
if quizUser != "" {
|
|
|
|
quizUser, er = receiver.encrypt.DecryptStr([]byte(quizUser))
|
|
|
|
if er != nil {
|
|
|
|
return receiver.middleWare.ErrorOld(ctx, er)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
account, err := receiver.accountRepo.FindByUserID(ctx.Context(), userID)
|
|
|
|
if err != nil && err.Type() != errors.ErrNotFound {
|
|
|
|
return receiver.middleWare.ErrorOld(ctx, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if account != nil {
|
|
|
|
return receiver.middleWare.Error(ctx, fiber.StatusBadRequest, "account exists")
|
|
|
|
}
|
|
|
|
|
|
|
|
user, err := receiver.authClient.GetUser(ctx.Context(), userID)
|
|
|
|
if err != nil {
|
|
|
|
return receiver.middleWare.ErrorOld(ctx, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
account, err = receiver.accountRepo.Insert(ctx.Context(), &models.Account{
|
|
|
|
UserID: user.ID, Wallet: models.Wallet{Currency: models.DefaultCurrency}, From: quizFrom, Partner: quizUser})
|
|
|
|
if err != nil {
|
|
|
|
return receiver.middleWare.ErrorOld(ctx, err)
|
|
|
|
}
|
|
|
|
|
2024-05-23 14:34:45 +00:00
|
|
|
quiz := ""
|
|
|
|
if quizFrom != "" {
|
|
|
|
quiz = "quiz"
|
|
|
|
}
|
|
|
|
|
|
|
|
hlogger.Emit(models.InfoCreateAccount{
|
|
|
|
CtxUserID: userID,
|
|
|
|
CtxAccountID: account.ID,
|
|
|
|
KeyFromSource: quiz,
|
|
|
|
KeyFromID: quizFrom,
|
|
|
|
KeyFromPartner: quizUser,
|
|
|
|
CtxLogin: user.Login,
|
|
|
|
CtxEmail: user.Email,
|
|
|
|
CtxPhone: user.PhoneNumber,
|
|
|
|
KeyCurrency: account.Wallet.Currency,
|
|
|
|
})
|
|
|
|
|
2024-05-21 13:50:26 +00:00
|
|
|
return ctx.Status(fiber.StatusOK).JSON(account)
|
|
|
|
}
|
|
|
|
|
2024-05-24 10:25:37 +00:00
|
|
|
func (receiver *AccountController) AccountPipe(ctx *fiber.Ctx) error {
|
|
|
|
userID, ok := receiver.middleWare.ExtractUserID(ctx)
|
|
|
|
if !ok || userID == "" {
|
|
|
|
return receiver.middleWare.NoAuth(ctx)
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx.Set(fiber.HeaderContentType, "text/event-stream")
|
|
|
|
ctx.Set("Cache-Control", "no-cache")
|
|
|
|
ctx.Set("Connection", "keep-alive")
|
|
|
|
ctx.Set("Transfer-Encoding", "chunked")
|
|
|
|
|
|
|
|
accountCh := make(chan models.Account)
|
|
|
|
cancelCtx, cancel := context.WithCancel(ctx.Context())
|
|
|
|
|
|
|
|
go func(ctx context.Context) {
|
|
|
|
defer close(accountCh)
|
|
|
|
if err := receiver.accountRepo.AccountPipe(ctx, userID, accountCh); err != nil {
|
|
|
|
receiver.logger.Error("error in account pipe repo method", zap.Error(err))
|
|
|
|
}
|
|
|
|
}(cancelCtx)
|
|
|
|
|
|
|
|
ctx.Status(fiber.StatusOK).Context().SetBodyStreamWriter(func(w *bufio.Writer) {
|
|
|
|
for {
|
|
|
|
select {
|
|
|
|
case account, ok := <-accountCh:
|
|
|
|
if !ok {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
accountJSON, err := json.Marshal(account)
|
|
|
|
if err != nil {
|
|
|
|
receiver.logger.Error("error marshal account JSON", zap.Error(err))
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
fmt.Fprintf(w, "data: %s\n\n", accountJSON)
|
|
|
|
if err := w.Flush(); err != nil {
|
|
|
|
receiver.logger.Error("error flushing", zap.Error(err))
|
|
|
|
cancel()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|