diff --git a/apihandler/document.go b/apihandler/document.go index a93bcb4..032057d 100644 --- a/apihandler/document.go +++ b/apihandler/document.go @@ -4,18 +4,20 @@ import ( "context" "net/http" + "git.agecem.com/agecem/agecem-org/apirequest" "git.agecem.com/agecem/agecem-org/apiresponse" "github.com/labstack/echo/v4" "github.com/minio/minio-go/v7" ) // V1DocumentPOST permet d'ajouter un object dans un bucket, par multipart/form-data -func (h *V1Handler) V1DocumentPOST(c echo.Context) error { +func (h *V1Handler) V1DocumentPOST(c echo.Context) (err error) { + var request apirequest.V1DocumentPOST var response apiresponse.V1DocumentPOST - bucket := c.Param("bucket") + request.Data.Bucket = c.Param("bucket") - form_file, err := c.FormFile("document") + request.Data.Document, err = c.FormFile("document") if err != nil { response.StatusCode = http.StatusBadRequest response.Message = "Error during HandleV1DocumentCreate's echo#Context.FormFile" @@ -26,7 +28,7 @@ func (h *V1Handler) V1DocumentPOST(c echo.Context) error { allowed := false for bucket_allowed := range h.Config.Server.Documents.Buckets { - if bucket == bucket_allowed { + if request.Data.Bucket == bucket_allowed { allowed = true } } @@ -35,11 +37,18 @@ func (h *V1Handler) V1DocumentPOST(c echo.Context) error { return c.JSON(apiresponse.NotFoundResponse()) } + if !request.Complete() { + response.Message = "Incomplete V1DocumentPOST request received" + response.StatusCode = http.StatusBadRequest + + return c.JSON(response.StatusCode, response) + } + ctx, cancel := context.WithCancel(context.Background()) defer cancel() - src, err := form_file.Open() + src, err := request.Data.Document.Open() if err != nil { response.StatusCode = http.StatusBadRequest response.Message = "Error during form_file.Open()" @@ -49,8 +58,8 @@ func (h *V1Handler) V1DocumentPOST(c echo.Context) error { } defer src.Close() - info, err := h.MediaClient.MinioClient.PutObject(ctx, bucket, form_file.Filename, src, form_file.Size, minio.PutObjectOptions{ - ContentType: form_file.Header.Get("Content-Type"), + info, err := h.MediaClient.MinioClient.PutObject(ctx, request.Data.Bucket, request.Data.Document.Filename, src, request.Data.Document.Size, minio.PutObjectOptions{ + ContentType: request.Data.Document.Header.Get("Content-Type"), }) if err != nil { response.StatusCode = http.StatusInternalServerError diff --git a/apirequest/document.go b/apirequest/document.go new file mode 100644 index 0000000..5c9ca67 --- /dev/null +++ b/apirequest/document.go @@ -0,0 +1,58 @@ +package apirequest + +import ( + "bytes" + "encoding/json" + "fmt" + "mime/multipart" + "net/http" + + "codeberg.org/vlbeaudoin/voki" + "codeberg.org/vlbeaudoin/voki/request" + "git.agecem.com/agecem/agecem-org/apiresponse" +) + +var _ request.Requester[apiresponse.V1DocumentPOST] = V1DocumentPOST{} + +type V1DocumentPOST struct { + Data struct { + Bucket string + Document *multipart.FileHeader + } +} + +func NewV1DocumentPOST(bucket string, document *multipart.FileHeader) (request V1DocumentPOST, err error) { + if bucket == "" { + err = fmt.Errorf("NewV1DocumentPOST requires non-nil bucket name") + return + } + + request.Data.Bucket = bucket + + if document == nil { + err = fmt.Errorf("NewV1DocumentPOST requires non-nil document") + return + } + + request.Data.Document = document + + return +} + +func (request V1DocumentPOST) Complete() bool { + return request.Data.Bucket != "" && request.Data.Document != nil +} + +func (request V1DocumentPOST) Request(v *voki.Voki) (response apiresponse.V1DocumentPOST, err error) { + if !request.Complete() { + err = fmt.Errorf("Incomplete V1DocumentPOST request") + return + } + + var buf bytes.Buffer + if err = json.NewEncoder(&buf).Encode(request.Data); err != nil { + return + } + + return response, v.UnmarshalIfComplete(http.MethodPost, fmt.Sprintf("/v1/bucket/%s", request.Data.Bucket), &buf, true, &response) +}