docxTemplater/handlers/yadisk.go
Danil Solovyov fba01b2518 Changes:
- Добавлена проверка токенов при запросе /amo/state
  - Исправлена работа с amo oauth-токенами
  - Добавлены примеры шаблонизатора
  - Добавлена возможность генерации и создания шаблонов из примеров
  - В ответ генератора добавлены ссылки для скачивания сгенерированных файлов
  - Вернул очиску temp после загрузки файла в Яндекс.Диск
  - yadisk.UploadResources - добавлено ожидание окончания отправки файла и таймаут в 5 секунд для отправки файла
  - Добавлены эндпоинты для загрузки файлов в хранилища
  - Актуализирован генератор по вебхуку
  - Обновлены генератор по данным
  - Обновлен генератор по лиду
2022-11-25 00:37:47 +05:00

385 lines
9.2 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 handlers
import (
"errors"
"fmt"
"github.com/Pena-Co-Ltd/amocrm_templategen_back/dal/model"
"github.com/Pena-Co-Ltd/amocrm_templategen_back/tools"
YaDisk "github.com/Pena-Co-Ltd/amocrm_templategen_back/yadisk"
"github.com/gorilla/schema"
"go.uber.org/zap"
"golang.org/x/oauth2"
"net/http"
"time"
)
type ReqYaDiskSaveToken struct {
AccessToken string `json:"access_token" schema:"access_token"`
Code string `json:"code" schema:"code"`
ExpiresIn int64 `json:"expires_in" schema:"expires_in"`
TokenType string `json:"token_type" schema:"token_type"`
RefreshToken string `json:"refresh_token" schema:"refresh_token"`
State string `json:"state" schema:"state"`
Scope string `json:"scope" schema:"scope"`
Error string `json:"error" schema:"error"`
}
func (h *Handlers) YaDiskSaveToken(w http.ResponseWriter, r *http.Request) {
var req ReqYaDiskSaveToken
err := r.ParseForm()
if err != nil {
h.reportError(w, err, http.StatusBadRequest)
return
}
err = schema.NewDecoder().Decode(&req, r.Form)
if err != nil {
h.reportError(w, err, http.StatusBadRequest)
return
}
if req.Error != "" {
err = errors.New("YaDiskErr:" + req.Error)
h.reportError(w, err, http.StatusBadRequest)
return
}
if req.AccessToken == "" && req.Code == "" {
err = errors.New("got empty token")
h.reportError(w, err, http.StatusBadRequest)
return
}
if req.State == "" {
err = errors.New("got empty state")
h.reportError(w, err, http.StatusBadRequest)
return
}
var state tools.StateToken
err = tools.DecryptTokenRC4(req.State, &state)
if err != nil {
h.reportError(w, err, http.StatusUnauthorized)
return
}
token := &oauth2.Token{
AccessToken: req.AccessToken,
TokenType: req.TokenType,
RefreshToken: req.RefreshToken,
Expiry: time.Now().Add(time.Duration(req.ExpiresIn) * time.Second),
}
yaDiskClient, err := h.YaDisk.NewClient(r.Context(), token, req.Code)
if err != nil {
h.reportError(w, err, http.StatusForbidden)
return
}
token = yaDiskClient.Token
yaUser, err := yaDiskClient.GetUser()
if err != nil {
h.reportError(w, err, http.StatusInternalServerError)
return
}
// Insert/Update token in DB
_, err = h.dal.YaDisk.InsertOrUpdate(r.Context(), &model.YaDisk{
UserID: state.UserID,
Name: fmt.Sprintf("Yandex Disk (%v)", yaUser.Login),
UID: yaUser.Uid,
Login: yaUser.Login,
DisplayName: yaUser.DisplayName,
AccessToken: token.AccessToken,
RefreshToken: token.RefreshToken,
ExpiresIn: token.Expiry,
TokenType: token.TokenType,
TemplateFolder: YaDisk.DEFAULT_TEMPLATE_FOLDER,
SaveFolder: YaDisk.DEFAULT_SAVE_FOLDER,
})
if err != nil {
h.reportError(w, err, 500)
return
}
// Make default directories in YandexDisk
_, err = yaDiskClient.PutResources(YaDisk.DEFAULT_FOLDER)
if err != nil {
h.logger.Error("ErrorHandler", zap.Error(err))
}
_, err = yaDiskClient.PutResources(YaDisk.DEFAULT_TEMPLATE_FOLDER)
if err != nil {
h.logger.Error("ErrorHandler", zap.Error(err))
}
_, err = yaDiskClient.PutResources(YaDisk.DEFAULT_SAVE_FOLDER)
if err != nil {
h.logger.Error("ErrorHandler", zap.Error(err))
}
http.Redirect(w, r, state.RedirectUrl, http.StatusPermanentRedirect)
}
type ReqYaDiskSetSettings struct {
ID string `json:"id"`
Name string `json:"name"`
TemplateFolder string `json:"template_folder"`
SaveFolder string `json:"save_folder"`
}
func (h *Handlers) YaDiskSetSettings(w http.ResponseWriter, r *http.Request) {
var req ReqYaDiskSetSettings
amoData := getAmoByJwt(r)
if amoData == nil {
h.reportError(w, ErrorUnauthorized, http.StatusUnauthorized)
return
}
err := decodePost(&req, r)
if err != nil {
h.reportError(w, err, http.StatusBadRequest)
return
}
if req.ID == "" {
h.reportError(w, errors.New("id required"), http.StatusBadRequest)
return
}
err = h.dal.YaDisk.Update(r.Context(), &model.YaDisk{
ID: req.ID,
Name: req.Name,
TemplateFolder: req.TemplateFolder,
SaveFolder: req.SaveFolder})
if err != nil {
h.reportError(w, err, http.StatusInternalServerError)
return
}
sendResponse(w, 200, nil)
}
// YaDiskGetList - возвращает список хранилищ Yandex закрепленных за пользователем по его UserID из JWT
func (h *Handlers) YaDiskGetList(w http.ResponseWriter, r *http.Request) {
amoData := getAmoByJwt(r)
if amoData == nil {
h.reportError(w, ErrorUnauthorized, http.StatusUnauthorized)
return
}
yadiskInfo, err := h.dal.YaDisk.GetListByUserID(r.Context(), amoData.UserID)
if err != nil {
h.reportError(w, err, http.StatusInternalServerError)
return
}
sendResponse(w, http.StatusOK, yadiskInfo)
}
type ReqYaDiskGetResources struct {
ID string `json:"id"` // ID хранилища
Path string `json:"path"` // Путь до папки. По умолчанию: disk:/
Limit int `json:"limit"` // По умолчанию: 20
Offset int `json:"offset"` // По умолчанию: 0
}
func (h *Handlers) YaDiskGetResources(w http.ResponseWriter, r *http.Request) {
var req ReqYaDiskGetResources
amoData := getAmoByJwt(r)
if amoData == nil {
h.reportError(w, ErrorUnauthorized, http.StatusUnauthorized)
return
}
err := decodePost(&req, r)
if err != nil {
h.reportError(w, err, http.StatusBadRequest)
return
}
if req.ID == "" {
h.reportError(w, errors.New("id required"), http.StatusBadRequest)
return
}
yadisk, err := h.dal.YaDisk.GetByID(r.Context(), req.ID)
if err != nil {
h.reportError(w, err, http.StatusInternalServerError)
return
}
client, err := h.YaDisk.NewClient(r.Context(), yadisk.Token(), "")
if err != nil {
h.reportError(w, err, http.StatusInternalServerError)
return
}
resource, err := client.GetResources(req.Path, req.Limit, req.Offset)
if err != nil {
h.reportError(w, err, http.StatusInternalServerError)
return
}
sendResponse(w, 200, resource)
}
type ReqYaDiskPutResources struct {
ID string `json:"id"`
Path string `json:"path"`
}
func (h *Handlers) YaDiskPutResources(w http.ResponseWriter, r *http.Request) {
var req ReqYaDiskPutResources
amoData := getAmoByJwt(r)
if amoData == nil {
h.reportError(w, ErrorUnauthorized, http.StatusUnauthorized)
return
}
err := decodePost(&req, r)
if err != nil {
h.reportError(w, err, http.StatusBadRequest)
return
}
if req.ID == "" {
h.reportError(w, errors.New("id required"), http.StatusBadRequest)
return
}
yadisk, err := h.dal.YaDisk.GetByID(r.Context(), req.ID)
if err != nil {
h.reportError(w, err, http.StatusInternalServerError)
return
}
client, err := h.YaDisk.NewClient(r.Context(), yadisk.Token(), "")
if err != nil {
h.reportError(w, err, http.StatusInternalServerError)
return
}
res, err := client.PutResources(req.Path)
if err != nil {
h.reportError(w, err, http.StatusInternalServerError)
return
}
sendResponse(w, http.StatusOK, res)
}
type ReqYaDiskUploadResources struct {
ID string `json:"id" schema:"id"`
Path string `json:"path" schema:"path"`
}
func (h *Handlers) YaDiskUploadResources(w http.ResponseWriter, r *http.Request) {
// Check form
fileData, fileHeader, err := r.FormFile("file")
defer fileData.Close()
var req ReqYaDiskUploadResources
err = schema.NewDecoder().Decode(&req, r.Form)
if err != nil {
h.reportError(w, err, http.StatusBadRequest)
return
}
if req.ID == "" {
h.reportError(w, errors.New("id required"), http.StatusBadRequest)
return
}
if req.Path == "" {
req.Path = "disk:"
}
var maxSize int64 = 10 << 20 // mb
if fileHeader.Size > maxSize {
h.reportError(w, errors.New("max size 10 mb"), http.StatusBadRequest)
return
}
// Upload file to the storage
storage, err := h.dal.YaDisk.GetByID(r.Context(), req.ID)
if err != nil {
h.reportError(w, err, http.StatusInternalServerError)
return
}
client, err := h.YaDisk.NewClient(r.Context(), storage.Token(), "")
if err != nil {
h.reportError(w, err, http.StatusInternalServerError)
return
}
storagePath := fmt.Sprintf("%v/%v", req.Path, fileHeader.Filename)
_, err = client.UploadResources(storagePath, fileData)
if err != nil {
h.reportError(w, err, http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusOK)
}
type ReqYaDiskDeleteResources struct {
ID string `json:"ID"`
Path string `json:"path"`
}
func (h *Handlers) YaDiskDeleteResources(w http.ResponseWriter, r *http.Request) {
var req ReqYaDiskPutResources
amoData := getAmoByJwt(r)
if amoData == nil {
h.reportError(w, ErrorUnauthorized, http.StatusUnauthorized)
return
}
err := decodePost(&req, r)
if err != nil {
h.reportError(w, err, http.StatusBadRequest)
return
}
if req.ID == "" {
h.reportError(w, errors.New("id required"), http.StatusBadRequest)
return
}
yadisk, err := h.dal.YaDisk.GetByID(r.Context(), req.ID)
if err != nil {
h.reportError(w, err, http.StatusInternalServerError)
return
}
client, err := h.YaDisk.NewClient(r.Context(), yadisk.Token(), "")
if err != nil {
h.reportError(w, err, http.StatusInternalServerError)
return
}
err = client.DeleteResources(req.Path)
if err != nil {
h.reportError(w, err, http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusOK)
}