docxTemplater/handlers/gdisk.go
Danil Solovyov 3d93651f1d Changes:
- Добавлен полный путь редиректа до виджета в амо
  - Исправлены мелкие ошибки эндпоинтов
  - Исправлена критическая ошибка при проверке данных на наличие папок в Google Disk
  - Начал писать документацию
2022-10-22 01:38:31 +05:00

446 lines
11 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"
"github.com/gorilla/schema"
"google.golang.org/api/drive/v3"
"net/http"
)
type ReqGDiskSaveToken struct {
State string `json:"state"`
Code string `json:"code"`
Scope string `json:"scope"`
}
// GDiskSaveToken - сохраняет токен авторизации
func (h *Handlers) GDiskSaveToken(w http.ResponseWriter, r *http.Request) {
var req ReqGDiskSaveToken
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, 500)
return
}
if req.State == "" {
err = errors.New("GDiskErr: got empty state")
h.reportError(w, err, http.StatusBadRequest)
return
}
if req.Code == "" {
err = errors.New("GDiskErr: got empty code")
h.reportError(w, err, http.StatusBadRequest)
return
}
// get user
var state tools.StateToken
err = tools.DecryptTokenRC4(req.State, &state)
if err != nil {
h.reportError(w, err, http.StatusUnauthorized)
return
}
// generate token
token, err := h.GDisk.GetToken(r.Context(), req.Code)
if err != nil {
h.reportError(w, err, 500)
return
}
gDisk, err := h.GDisk.NewClient(r.Context(), token)
if err != nil {
h.reportError(w, err, http.StatusInternalServerError)
return
}
token = gDisk.Token
gUser, err := gDisk.GetUserInfo()
if err != nil {
h.reportError(w, err, http.StatusInternalServerError)
return
}
// Make default directories in Google Drive
gDiskData, err := h.dal.GDisk.GetByEmail(r.Context(), gUser.EmailAddress)
if err != nil {
h.reportError(w, err, http.StatusInternalServerError)
return
}
var defaultId, defaultName, templateId, templateName, saveId, saveName string
if gDiskData != nil {
defaultId = gDiskData.DefaultFolderID
defaultName = gDiskData.DefaultFolder
templateId = gDiskData.TemplateFolderID
templateName = gDiskData.TemplateFolder
saveId = gDiskData.SaveFolderID
saveName = gDiskData.SaveFolder
}
defaultFolder, templateFolder, saveFolder, err := gDisk.MakeDefaultDirs(defaultId, defaultName, templateId,
templateName, saveId, saveName)
if err != nil {
h.reportError(w, err, http.StatusInternalServerError)
return
}
// Insert/Update token in DB
_, err = h.dal.GDisk.InsertOrUpdate(r.Context(), &model.GDisk{
UserID: state.UserID,
Name: fmt.Sprintf("Google Disk (%v)", gUser.EmailAddress),
DisplayName: gUser.DisplayName,
Email: gUser.EmailAddress,
PhotoLink: gUser.PhotoLink,
AccessToken: token.AccessToken,
RefreshToken: token.RefreshToken,
ExpiresIn: token.Expiry,
TokenType: token.TokenType,
DefaultFolder: defaultFolder.Name,
DefaultFolderID: defaultFolder.Id,
TemplateFolder: templateFolder.Name,
TemplateFolderID: templateFolder.Id,
SaveFolder: saveFolder.Name,
SaveFolderID: saveFolder.Id,
})
if err != nil {
h.reportError(w, err, http.StatusInternalServerError)
return
}
http.Redirect(w, r, state.RedirectUrl, http.StatusPermanentRedirect)
}
type ReqGDiskSetSettings struct {
ID string `json:"id"`
Name string `json:"name"` // Пользовательское название хранилища
DefaultFolder string `json:"default_folder"`
DefaultFolderId string `json:"default_folder_id"`
TemplateFolder string `json:"template_folder"`
TemplateFolderID string `json:"template_folder_id"`
SaveFolder string `json:"save_folder"`
SaveFolderID string `json:"save_folder_id"`
}
func (h *Handlers) GDiskSetSettings(w http.ResponseWriter, r *http.Request) {
var req ReqGDiskSetSettings
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.GDisk.Update(r.Context(), &model.GDisk{
ID: req.ID,
Name: req.Name,
DefaultFolder: req.DefaultFolder,
DefaultFolderID: req.DefaultFolderId,
TemplateFolder: req.TemplateFolder,
TemplateFolderID: req.TemplateFolderID,
SaveFolder: req.SaveFolder,
SaveFolderID: req.SaveFolderID,
})
if err != nil {
h.reportError(w, err, http.StatusInternalServerError)
return
}
sendResponse(w, 200, nil)
}
func (h *Handlers) GDiskGetFile(w http.ResponseWriter, r *http.Request) {
}
type ReqGDiskGetResources struct {
ID string `json:"id"` // ID хранилища
FolderID string `json:"folder_id"` // Folder id
Name string `json:"name,omitempty"` // Folder name
ParentID string `json:"parent_id,omitempty"` // Parent folder id
}
// GDiskGetResources - возвращает поиск по папке, включая список её файлов и папок.
// Поведение:
// - Если не указан FolderID и Name возвращает корневой каталог Google Drive
// - Если указан только Name ищет файл\папку по всему Google Drive
// - Если указан Name и ParentID ищет файл\папку только в родителе
// - ParentID игнорируется без Name
func (h *Handlers) GDiskGetResources(w http.ResponseWriter, r *http.Request) {
var req ReqGDiskGetResources
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
}
gdiskInfo, err := h.dal.GDisk.GetByID(r.Context(), req.ID)
if err != nil {
h.reportError(w, err, http.StatusInternalServerError)
return
}
if gdiskInfo == nil {
h.reportError(w, errors.New("gdisk info not found"), http.StatusForbidden)
return
}
client, err := h.GDisk.NewClient(r.Context(), gdiskInfo.Token())
if err != nil {
h.reportError(w, err, http.StatusForbidden)
return
}
var res *drive.FileList
if req.Name != "" {
res, err = client.GetResourcesByName(req.Name, req.ParentID)
} else {
res, err = client.GetResources(req.FolderID)
}
if err != nil {
h.reportError(w, err, http.StatusInternalServerError)
return
}
sendResponse(w, 200, res)
}
type ReqGDiskGetDirTemplate struct {
Email string `json:"email"` // Required. Google Email ?
}
// GDiskGetDirTemplate - возвращает данные по папке template, включая список её файлов и папок
func (h *Handlers) GDiskGetDirTemplate(w http.ResponseWriter, r *http.Request) {
var req ReqGDiskGetDirTemplate
err := decodePost(&req, r)
if err != nil {
h.reportError(w, err, http.StatusBadRequest)
return
}
if req.Email == "" {
h.reportError(w, errors.New("email required"), http.StatusBadRequest)
}
amoData := getAmoByJwt(r)
user := getJwtUser(r)
if amoData == nil && user == nil {
h.reportError(w, ErrorUnauthorized, http.StatusUnauthorized)
return
}
gdiskInfo, err := h.dal.GDisk.GetByEmail(r.Context(), req.Email)
if err != nil {
h.reportError(w, err, http.StatusInternalServerError)
return
}
if gdiskInfo == nil {
h.reportError(w, errors.New("gdisk info not found"), http.StatusForbidden)
return
}
if gdiskInfo.Token() == nil {
h.reportError(w, errors.New("google token invalid"), http.StatusForbidden)
return
}
client, err := h.GDisk.NewClient(r.Context(), gdiskInfo.Token())
if err != nil {
h.reportError(w, err, http.StatusInternalServerError)
return
}
dir, err := client.GetResources(gdiskInfo.TemplateFolderID)
if err != nil {
h.reportError(w, err, http.StatusInternalServerError)
return
}
sendResponse(w, 200, dir)
}
// GDiskGetList - возвращает список хранилищ Google закрепленных за пользователем по его UserID из JWT
func (h *Handlers) GDiskGetList(w http.ResponseWriter, r *http.Request) {
amoData := getAmoByJwt(r)
user := getJwtUser(r)
if amoData == nil && user == nil {
h.reportError(w, ErrorUnauthorized, http.StatusUnauthorized)
return
}
var userID string
if user != nil {
userID = user.UserID
} else {
userID = amoData.UserID
}
gdiskInfo, err := h.dal.GDisk.GetListByUserID(r.Context(), userID)
if err != nil {
h.reportError(w, err, http.StatusInternalServerError)
return
}
sendResponse(w, http.StatusOK, gdiskInfo)
}
type ReqGDiskPutResources struct {
ID string `json:"ID"`
Name string `json:"name"`
ParentID string `json:"parent_id"`
}
func (h *Handlers) GDiskPutResources(w http.ResponseWriter, r *http.Request) {
var req ReqGDiskPutResources
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
}
if req.Name == "" {
h.reportError(w, errors.New("name required"), http.StatusBadRequest)
return
}
gdiskInfo, err := h.dal.GDisk.GetByID(r.Context(), req.ID)
if err != nil {
h.reportError(w, err, http.StatusInternalServerError)
return
}
if gdiskInfo == nil {
h.reportError(w, errors.New("gdisk info not found"), http.StatusForbidden)
return
}
client, err := h.GDisk.NewClient(r.Context(), gdiskInfo.Token())
if err != nil {
h.reportError(w, err, http.StatusForbidden)
return
}
file, err := client.PutResources(req.Name, req.ParentID)
if err != nil {
h.reportError(w, err, http.StatusInternalServerError)
return
}
sendResponse(w, 200, file)
}
type ReqGDiskDeleteResources struct {
ID string `json:"id"`
FolderID string `json:"folder_id"`
}
func (h *Handlers) GDiskDeleteResources(w http.ResponseWriter, r *http.Request) {
var req ReqGDiskDeleteResources
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
}
if req.FolderID == "" {
h.reportError(w, errors.New("folder_id required"), http.StatusBadRequest)
return
}
gdiskInfo, err := h.dal.GDisk.GetByID(r.Context(), req.ID)
if err != nil {
h.reportError(w, err, http.StatusInternalServerError)
return
}
if gdiskInfo == nil {
h.reportError(w, errors.New("gdisk info not found"), http.StatusForbidden)
return
}
client, err := h.GDisk.NewClient(r.Context(), gdiskInfo.Token())
if err != nil {
h.reportError(w, err, http.StatusForbidden)
return
}
err = client.DeleteResources(req.FolderID)
if err != nil {
h.reportError(w, err, http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusOK)
}