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) }