From 07005c8753ebfaf114a7c173d518043eab96df36 Mon Sep 17 00:00:00 2001 From: Victor Lacasse-Beaudoin Date: Fri, 28 Apr 2023 15:57:09 -0400 Subject: [PATCH] =?UTF-8?q?WIP:=20Connecter=20/admin/documents/upload=20?= =?UTF-8?q?=C3=A0=20handleV1DocumentCreate?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/api.go | 139 +++++++++++++++++++++++++++++++- cmd/server.go | 44 ++++++++-- public/html/admin-upload.gohtml | 13 +++ 3 files changed, 188 insertions(+), 8 deletions(-) diff --git a/api/api.go b/api/api.go index 70334f9..b89346f 100644 --- a/api/api.go +++ b/api/api.go @@ -1,9 +1,13 @@ package api import ( + "bytes" + "encoding/json" "errors" "fmt" "io/ioutil" + "log" + "mime/multipart" "net/http" ) @@ -15,8 +19,11 @@ type API struct { } type APIOptions struct { - KeyAuth bool - Key string + KeyAuth bool + Key string + BasicAuth bool + Username string + Password string } func New(protocol, host string, port int, opts APIOptions) (*API, error) { @@ -97,5 +104,133 @@ func (a *API) Call(method, route string) ([]byte, error) { } return respBody, nil } + + //return nil, errors.New(fmt.Sprintf("method must be 'GET' or 'DELETE', got '%s'", method)) return nil, errors.New(fmt.Sprintf("method must be 'GET' or 'DELETE', got '%s'", method)) } + +func (a *API) UploadDocument(bucket string, file_header *multipart.FileHeader) (string, error) { + endpoint := fmt.Sprintf("%s://%s:%d", + a.Protocol, + a.Host, + a.Port, + ) + + route := fmt.Sprintf("/v1/bucket/%s", bucket) + + request := fmt.Sprintf("%s%s", endpoint, route) + + client := &http.Client{} + + // set the HTTP method, url, and request body + req, err := http.NewRequest(http.MethodPost, request, nil) + if err != nil { + return "", err + } + + if a.Opts.KeyAuth { + req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", a.Opts.Key)) + } + + req.Header.Add("Content-Type", "multipart/form-data") + + // CreateFormFile with multipart.NewWriter + //TODO + /* + buf := new(bytes.Buffer) + form := multipart.NewWriter(buf) + form.CreateFormFile("document", ) + */ + + //TODO + log.Println("req: ", req) + + file, file_header, err := req.FormFile("document") + if err != nil { + log.Println("Error during http#Request.Formfile") + return "", err + } + + log.Println("file: ", file, "file_header: ", file_header) + log.Println("file_header: ", file_header) + + resp, err := client.Do(req) + if err != nil { + log.Println("Error during http#Client.Do") + return "", err + } + + var res map[string]interface{} + + json.NewDecoder(resp.Body).Decode(&res) + return fmt.Sprintf("%s", res), nil +} + +// CallWithData takes data and returns a string representing a response body. +// Can be used for POST or PUT methods +func (a *API) CallWithData(method, route string, data []byte) (string, error) { + endpoint := fmt.Sprintf("%s://%s:%d", + a.Protocol, + a.Host, + a.Port, + ) + request := fmt.Sprintf("%s%s", endpoint, route) + + switch method { + case http.MethodPost: + // initialize http client + client := &http.Client{} + + // set the HTTP method, url, and request body + req, err := http.NewRequest(http.MethodPost, request, bytes.NewBuffer(data)) + if err != nil { + return "", err + } + + if a.Opts.KeyAuth { + req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", a.Opts.Key)) + } + + // set the request header Content-Type for json + req.Header.Set("Content-Type", "application/json; charset=utf-8") + resp, err := client.Do(req) + if err != nil { + return "", err + } + + var res map[string]interface{} + + json.NewDecoder(resp.Body).Decode(&res) + return fmt.Sprintf("%s\n", res["message"]), nil + /* + case http.MethodPut: + // initialize http client + client := &http.Client{} + + // set the HTTP method, url, and request body + req, err := http.NewRequest(http.MethodPut, request, bytes.NewBuffer(data)) + if err != nil { + return "", err + } + + if a.Opts.KeyAuth { + req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", a.Opts.Key)) + } + + // set the request header Content-Type for json + //req.Header.Set("Content-Type", "application/json; charset=utf-8") + resp, err := client.Do(req) + if err != nil { + return "", err + } + + var res map[string]interface{} + + json.NewDecoder(resp.Body).Decode(&res) + return fmt.Sprintf("%s\n", res["message"]), nil + */ + } + + //return "", errors.New(fmt.Sprintf("method must be 'POST' or 'PUT', got '%s'", method)) + return "", errors.New(fmt.Sprintf("method must be 'POST', got '%s'", method)) +} diff --git a/cmd/server.go b/cmd/server.go index 9889faf..a19fd5d 100644 --- a/cmd/server.go +++ b/cmd/server.go @@ -388,7 +388,11 @@ func handleV1DocumentCreate(c echo.Context) error { form_file, err := c.FormFile("file") if err != nil { - return err + log.Println(err) + return c.JSON(http.StatusBadRequest, map[string]interface{}{ + "message": "Error during handleV1DocumentCreate's echo#Context.FormFile", + "error": err, + }) } allowed := false @@ -729,13 +733,41 @@ func handleAdminDocumentsUpload(c echo.Context) error { } func handleAdminDocumentsUploadPOST(c echo.Context) error { - data := struct { - Message string - }{ - Message: "Pas implémenté", + client, err := api.New("http", "localhost", viper.GetInt("server.port"), api.APIOptions{ + KeyAuth: viper.GetBool("server.api.auth"), + Key: viper.GetString("server.api.key"), + BasicAuth: viper.GetBool("server.admin.auth"), + Username: viper.GetString("server.admin.username"), + Password: viper.GetString("server.admin.password"), + }) + if err != nil { + return c.JSON(http.StatusNotFound, map[string]string{"message": "Not Found"}) } - return c.Render(http.StatusOK, "admin-upload-html", data) + bucket := c.FormValue("bucket") + + document, err := c.FormFile("document") + if err != nil { + //return c.JSON(http.StatusBadRequest, map[string]string{"message": "Error during file parse"}) + return c.JSON(http.StatusNotFound, map[string]string{"message": "Error during echo#Context.FormFile", "error": err.Error()}) + } + + /* + file, err := document.Open() + if err != nil { + //return c.JSON(http.StatusNotFound, map[string]string{"message": "Not Found"}) + return c.JSON(http.StatusNotFound, map[string]string{"message": "Error during file.Open()", "error": err.Error()}) + } + defer file.Close() + */ + + response, err := client.UploadDocument(bucket, document) + if err != nil { + return c.JSON(http.StatusNotFound, map[string]string{"message": "Error duing api#client.UploadDocument", "error": err.Error()}) + //return c.JSON(http.StatusNotFound, map[string]string{"message": "Not Found"}) + } + + return c.Render(http.StatusOK, "admin-upload-html", struct{ Message string }{Message: response}) } // CSS Handlers diff --git a/public/html/admin-upload.gohtml b/public/html/admin-upload.gohtml index 7b80e9b..b7ff836 100644 --- a/public/html/admin-upload.gohtml +++ b/public/html/admin-upload.gohtml @@ -9,6 +9,19 @@ {{ template "header-html" }}

Upload

+
+ + + +
+ Document: +
+
+ +

{{ .Message }}