docxTemplater/handlers/gdisk.go

520 lines
13 KiB
Go
Raw Normal View History

2022-07-28 15:00:43 +00:00
package handlers
import (
2022-08-10 13:53:34 +00:00
"errors"
"fmt"
"io"
2022-07-28 15:00:43 +00:00
"net/http"
"os"
"github.com/gorilla/schema"
"go.uber.org/zap"
"google.golang.org/api/drive/v3"
2022-12-31 14:46:28 +00:00
"penahub.gitlab.yandexcloud.net/backend/templategen/dal/model"
GDisk "penahub.gitlab.yandexcloud.net/backend/templategen/gdisk"
"penahub.gitlab.yandexcloud.net/backend/templategen/middleware"
2022-12-31 14:46:28 +00:00
"penahub.gitlab.yandexcloud.net/backend/templategen/templategen"
"penahub.gitlab.yandexcloud.net/backend/templategen/tools"
2022-07-28 15:00:43 +00:00
)
type ReqGDiskSaveToken struct {
State string `json:"state" schema:"state"`
Code string `json:"code" schema:"code"`
Scope string `json:"scope" schema:"scope"`
2022-07-28 15:00:43 +00:00
}
// GDiskSaveToken - сохраняет токен авторизации.
2022-07-28 15:00:43 +00:00
func (h *Handlers) GDiskSaveToken(w http.ResponseWriter, r *http.Request) {
var request ReqGDiskSaveToken
2022-07-28 15:00:43 +00:00
err := r.ParseForm()
if err != nil {
h.reportError(w, http.StatusBadRequest, err)
2022-07-28 15:00:43 +00:00
return
}
err = schema.NewDecoder().Decode(&request, r.Form)
2022-07-28 15:00:43 +00:00
if err != nil {
h.reportError(w, 500, err)
2022-07-28 15:00:43 +00:00
return
}
if request.State == "" {
err = errors.New("GDiskErr: got empty state")
h.reportError(w, http.StatusBadRequest, err)
return
}
if request.Code == "" {
err = errors.New("GDiskErr: got empty code")
h.reportError(w, http.StatusBadRequest, err)
return
}
2022-08-10 13:53:34 +00:00
// get user
var state tools.StateToken
err = tools.DecryptTokenAES(request.State, &state)
if err != nil {
h.reportError(w, http.StatusUnauthorized, err)
2022-08-10 13:53:34 +00:00
return
}
2022-07-28 15:00:43 +00:00
// generate token
token, err := h.GDisk.GetToken(r.Context(), request.Code)
2022-07-28 15:00:43 +00:00
if err != nil {
h.reportError(w, http.StatusInternalServerError, err)
2022-07-28 15:00:43 +00:00
return
}
2022-08-10 13:53:34 +00:00
gDisk, err := h.GDisk.NewClient(r.Context(), token)
2022-07-28 15:00:43 +00:00
if err != nil {
h.reportError(w, http.StatusInternalServerError, err)
return
}
token = gDisk.Token
gUser, err := gDisk.GetUserInfo(r.Context())
if err != nil {
h.reportError(w, http.StatusInternalServerError, err)
return
2022-07-28 15:00:43 +00:00
}
// Make default directories in Google Drive
gDiskData, err := h.dal.GDisk.GetByEmail(r.Context(), gUser.EmailAddress)
2022-07-28 15:00:43 +00:00
if err != nil {
h.reportError(w, http.StatusInternalServerError, err)
return
2022-07-28 15:00:43 +00:00
}
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, http.StatusInternalServerError, err)
return
}
2022-07-28 15:00:43 +00:00
// Insert/Update token in DB
_, err = h.dal.GDisk.InsertOrUpdate(r.Context(), &model.GDisk{
PenaID: state.PenaID,
Name: fmt.Sprintf("Google Disk (%v)", gUser.EmailAddress),
DisplayName: gUser.DisplayName,
Email: gUser.EmailAddress,
PhotoLink: gUser.PhotoLink,
2022-07-28 15:00:43 +00:00
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,
2022-07-28 15:00:43 +00:00
})
if err != nil {
h.reportError(w, http.StatusInternalServerError, err)
2022-07-28 15:00:43 +00:00
return
}
http.Redirect(w, r, state.RedirectURL, http.StatusPermanentRedirect)
2022-08-10 13:53:34 +00:00
}
2022-07-28 15:00:43 +00:00
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"`
2022-08-10 13:53:34 +00:00
}
2022-07-28 15:00:43 +00:00
func (h *Handlers) GDiskSetSettings(w http.ResponseWriter, r *http.Request) {
var request ReqGDiskSetSettings
amoData := middleware.GetAmoData(r)
if amoData == nil {
h.reportError(w, http.StatusUnauthorized, ErrorUnauthorized)
return
}
2022-07-28 15:00:43 +00:00
err := decodePost(&request, r)
2022-07-28 15:00:43 +00:00
if err != nil {
h.reportError(w, http.StatusBadRequest, err)
2022-08-10 13:53:34 +00:00
return
2022-07-28 15:00:43 +00:00
}
if request.ID == "" {
h.reportError(w, http.StatusBadRequest, errors.New("id required"))
return
}
err = h.dal.GDisk.Update(r.Context(), &model.GDisk{
ID: request.ID,
Name: request.Name,
DefaultFolder: request.DefaultFolder,
DefaultFolderID: request.DefaultFolderID,
TemplateFolder: request.TemplateFolder,
TemplateFolderID: request.TemplateFolderID,
SaveFolder: request.SaveFolder,
SaveFolderID: request.SaveFolderID,
})
if err != nil {
h.reportError(w, http.StatusInternalServerError, err)
2022-08-10 13:53:34 +00:00
return
}
w.WriteHeader(http.StatusOK)
}
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 request ReqGDiskGetResources
amoData := middleware.GetAmoData(r)
2022-08-10 13:53:34 +00:00
if amoData == nil {
h.reportError(w, http.StatusUnauthorized, ErrorUnauthorized)
2022-08-10 13:53:34 +00:00
return
}
err := decodePost(&request, r)
if err != nil {
h.reportError(w, http.StatusBadRequest, err)
return
}
if request.ID == "" {
h.reportError(w, http.StatusBadRequest, errors.New("id required"))
return
}
gdiskInfo, err := h.dal.GDisk.GetByID(r.Context(), request.ID)
2022-08-10 13:53:34 +00:00
if err != nil {
h.reportError(w, http.StatusInternalServerError, err)
2022-08-10 13:53:34 +00:00
return
}
if gdiskInfo == nil {
h.reportError(w, http.StatusForbidden, errors.New("gdisk info not found"))
2022-08-10 13:53:34 +00:00
return
}
client, err := h.GDisk.NewClient(r.Context(), gdiskInfo.Token())
if err != nil {
h.reportError(w, http.StatusForbidden, err)
2022-08-10 13:53:34 +00:00
return
}
var res *drive.FileList
2022-08-10 13:53:34 +00:00
if request.Name != "" {
res, err = client.GetResourcesByName(request.Name, request.ParentID)
} else {
res, err = client.GetResources(request.FolderID)
2022-08-10 13:53:34 +00:00
}
if err != nil {
h.reportError(w, http.StatusInternalServerError, err)
2022-08-10 13:53:34 +00:00
return
}
h.sendResponse(w, http.StatusOK, res)
2022-08-10 13:53:34 +00:00
}
type ReqGDiskGetDirTemplate struct {
Email string `json:"email"` // Required. Google Email ?
}
// GDiskGetDirTemplate - возвращает данные по папке template, включая список её файлов и папок.
2022-08-10 13:53:34 +00:00
func (h *Handlers) GDiskGetDirTemplate(w http.ResponseWriter, r *http.Request) {
var request ReqGDiskGetDirTemplate
err := decodePost(&request, r)
if err != nil {
h.reportError(w, http.StatusBadRequest, err)
return
}
if request.Email == "" {
h.reportError(w, http.StatusBadRequest, errors.New("email required"))
}
amoData := middleware.GetAmoData(r)
2022-08-10 13:53:34 +00:00
if amoData == nil {
h.reportError(w, http.StatusUnauthorized, ErrorUnauthorized)
2022-08-10 13:53:34 +00:00
return
}
gdiskInfo, err := h.dal.GDisk.GetByEmail(r.Context(), request.Email)
2022-08-10 13:53:34 +00:00
if err != nil {
h.reportError(w, http.StatusInternalServerError, err)
2022-08-10 13:53:34 +00:00
return
}
if gdiskInfo == nil {
h.reportError(w, http.StatusForbidden, errors.New("gdisk info not found"))
2022-08-10 13:53:34 +00:00
return
}
if gdiskInfo.Token() == nil {
h.reportError(w, http.StatusForbidden, errors.New("google token invalid"))
2022-08-10 13:53:34 +00:00
return
}
client, err := h.GDisk.NewClient(r.Context(), gdiskInfo.Token())
if err != nil {
h.reportError(w, http.StatusInternalServerError, err)
2022-08-10 13:53:34 +00:00
return
}
dir, err := client.GetResources(gdiskInfo.TemplateFolderID)
if err != nil {
h.reportError(w, http.StatusInternalServerError, err)
2022-08-10 13:53:34 +00:00
return
}
h.sendResponse(w, http.StatusOK, dir)
2022-08-10 13:53:34 +00:00
}
// GDiskGetList - возвращает список хранилищ Google закрепленных за пользователем по его UserID из JWT.
func (h *Handlers) GDiskGetList(w http.ResponseWriter, r *http.Request) {
amoData := middleware.GetAmoData(r)
if amoData == nil {
h.reportError(w, http.StatusUnauthorized, ErrorUnauthorized)
return
}
gdiskInfo, err := h.dal.GDisk.GetListByPenaID(r.Context(), amoData.PenaID)
if err != nil {
h.reportError(w, http.StatusInternalServerError, err)
return
}
h.sendResponse(w, http.StatusOK, gdiskInfo)
}
type ReqGDiskPutResources struct {
ID string `json:"ID"`
Name string `json:"name"`
ParentID string `json:"parent_id"`
}
// GDiskPutResources - создать папку в хранилище.
func (h *Handlers) GDiskPutResources(w http.ResponseWriter, r *http.Request) {
var request ReqGDiskPutResources
amoData := middleware.GetAmoData(r)
if amoData == nil {
h.reportError(w, http.StatusUnauthorized, ErrorUnauthorized)
return
}
2022-08-10 13:53:34 +00:00
err := decodePost(&request, r)
if err != nil {
h.reportError(w, http.StatusBadRequest, err)
return
}
if request.ID == "" {
h.reportError(w, http.StatusBadRequest, errors.New("id required"))
return
}
if request.Name == "" {
h.reportError(w, http.StatusBadRequest, errors.New("name required"))
return
}
gdiskInfo, err := h.dal.GDisk.GetByID(r.Context(), request.ID)
if err != nil {
h.reportError(w, http.StatusInternalServerError, err)
return
}
if gdiskInfo == nil {
h.reportError(w, http.StatusForbidden, errors.New("gdisk info not found"))
return
}
client, err := h.GDisk.NewClient(r.Context(), gdiskInfo.Token())
if err != nil {
h.reportError(w, http.StatusForbidden, err)
return
}
file, err := client.PutResources(request.Name, request.ParentID)
if err != nil {
h.reportError(w, http.StatusInternalServerError, err)
return
}
h.sendResponse(w, http.StatusOK, file)
2022-08-10 13:53:34 +00:00
}
type ReqGDiskUploadResources struct {
ID string `json:"id" schema:"id"` // Storage ID
ParentID string `json:"parent_id" schema:"parent_id"`
}
// GDiskUploadResources - загрузить файл в хранилище.
func (h *Handlers) GDiskUploadResources(w http.ResponseWriter, r *http.Request) {
// Check form
fileData, fileHeader, err := r.FormFile("file")
defer fileData.Close() //nolint
if err != nil {
h.reportError(w, http.StatusInternalServerError, err)
return
}
var req ReqGDiskUploadResources
err = schema.NewDecoder().Decode(&req, r.Form)
if err != nil {
h.reportError(w, http.StatusBadRequest, err)
return
}
if req.ID == "" {
h.reportError(w, http.StatusBadRequest, errors.New("id required"))
return
}
var maxSize int64 = 10 << 20 // mb
if fileHeader.Size > maxSize {
h.reportError(w, http.StatusBadRequest, errors.New("max size 10 mb"))
return
}
// Download file to the temp
downloadPath := fmt.Sprintf("%v/%v", templategen.TempDownloaded, fileHeader.Filename)
out, err := os.Create(downloadPath)
defer out.Close() //nolint
if err != nil {
h.reportError(w, http.StatusInternalServerError, err)
return
}
_, err = io.Copy(out, fileData)
if err != nil {
h.reportError(w, http.StatusInternalServerError, err)
return
}
// Upload file to the storage
storage, err := h.dal.GDisk.GetByID(r.Context(), req.ID)
if err != nil {
h.reportError(w, http.StatusInternalServerError, err)
return
}
client, err := h.GDisk.NewClient(r.Context(), storage.Token())
if err != nil {
h.reportError(w, http.StatusInternalServerError, err)
return
}
h.logger.Info("INFO", zap.String("downloadPath", downloadPath))
2022-12-19 12:01:38 +00:00
_, _, err = client.UploadFile(downloadPath, GDisk.MimeTypeDocx, req.ParentID)
if err != nil {
h.reportError(w, http.StatusInternalServerError, err)
return
}
w.WriteHeader(http.StatusOK)
}
type ReqGDiskDeleteResources struct {
ID string `json:"id"`
FolderID string `json:"folder_id"`
}
// GDiskDeleteResources - удалить папку\файл.
func (h *Handlers) GDiskDeleteResources(w http.ResponseWriter, r *http.Request) {
var request ReqGDiskDeleteResources
amoData := middleware.GetAmoData(r)
if amoData == nil {
h.reportError(w, http.StatusUnauthorized, ErrorUnauthorized)
return
}
err := decodePost(&request, r)
if err != nil {
h.reportError(w, http.StatusBadRequest, err)
return
}
if request.ID == "" {
h.reportError(w, http.StatusBadRequest, errors.New("id required"))
return
}
if request.FolderID == "" {
h.reportError(w, http.StatusBadRequest, errors.New("folder_id required"))
return
}
gdiskInfo, err := h.dal.GDisk.GetByID(r.Context(), request.ID)
if err != nil {
h.reportError(w, http.StatusInternalServerError, err)
return
}
if gdiskInfo == nil {
h.reportError(w, http.StatusForbidden, errors.New("gdisk info not found"))
return
}
client, err := h.GDisk.NewClient(r.Context(), gdiskInfo.Token())
if err != nil {
h.reportError(w, http.StatusForbidden, err)
return
}
err = client.DeleteResources(request.FolderID)
if err != nil {
h.reportError(w, http.StatusInternalServerError, err)
return
}
2022-07-28 15:00:43 +00:00
w.WriteHeader(http.StatusOK)
2022-07-28 15:00:43 +00:00
}