From 85be264022c6aee8c55732ef603513cad5e99d08 Mon Sep 17 00:00:00 2001 From: Clay Risser Date: Mon, 18 Nov 2024 20:25:14 -0600 Subject: [PATCH 1/4] Added support for managing policies --- Makefile | 2 +- internal/app/s3manager/bucket_policy.go | 39 +++++++++ internal/app/s3manager/errors.go | 2 +- internal/app/s3manager/s3.go | 2 + main.go | 2 + web/template/bucket.html.tmpl | 102 +++++++++++++++++++++++- 6 files changed, 145 insertions(+), 4 deletions(-) create mode 100644 internal/app/s3manager/bucket_policy.go diff --git a/Makefile b/Makefile index 5ce2ff0a..c3420737 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ build: .PHONY: run run: - go run + go run main.go .PHONY: lint lint: diff --git a/internal/app/s3manager/bucket_policy.go b/internal/app/s3manager/bucket_policy.go new file mode 100644 index 00000000..ead4da83 --- /dev/null +++ b/internal/app/s3manager/bucket_policy.go @@ -0,0 +1,39 @@ +package s3manager + +import ( + "fmt" + "io" + "net/http" + + "github.com/gorilla/mux" +) + +func HandleGetBucketPolicy(s3 S3) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + bucketName := mux.Vars(r)["bucketName"] + policy, err := s3.GetBucketPolicy(r.Context(), bucketName) + if err != nil { + handleHTTPError(w, fmt.Errorf("error getting bucket policy: %w", err)) + return + } + w.Header().Set("Content-Type", "application/json") + w.Write([]byte(policy)) + } +} + +func HandlePutBucketPolicy(s3 S3) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + bucketName := mux.Vars(r)["bucketName"] + policy, err := io.ReadAll(r.Body) + if err != nil { + handleHTTPError(w, fmt.Errorf("error reading request body: %w", err)) + return + } + err = s3.SetBucketPolicy(r.Context(), bucketName, string(policy)) + if err != nil { + handleHTTPError(w, fmt.Errorf("error setting bucket policy: %w", err)) + return + } + w.WriteHeader(http.StatusNoContent) + } +} diff --git a/internal/app/s3manager/errors.go b/internal/app/s3manager/errors.go index 3a651c6e..97c0457f 100644 --- a/internal/app/s3manager/errors.go +++ b/internal/app/s3manager/errors.go @@ -32,7 +32,7 @@ func handleHTTPError(w http.ResponseWriter, err error) { code = http.StatusNotFound } - http.Error(w, http.StatusText(code), code) + http.Error(w, err.Error(), code) // Log if server error if code >= http.StatusInternalServerError { diff --git a/internal/app/s3manager/s3.go b/internal/app/s3manager/s3.go index 88587eee..099abe49 100644 --- a/internal/app/s3manager/s3.go +++ b/internal/app/s3manager/s3.go @@ -21,6 +21,8 @@ type S3 interface { PutObject(ctx context.Context, bucketName, objectName string, reader io.Reader, objectSize int64, opts minio.PutObjectOptions) (minio.UploadInfo, error) RemoveBucket(ctx context.Context, bucketName string) error RemoveObject(ctx context.Context, bucketName, objectName string, opts minio.RemoveObjectOptions) error + GetBucketPolicy(ctx context.Context, bucketName string) (string, error) + SetBucketPolicy(ctx context.Context, bucketName string, policy string) error } type SSEType struct { diff --git a/main.go b/main.go index 2ffe8abd..7bd28098 100644 --- a/main.go +++ b/main.go @@ -187,6 +187,8 @@ func main() { if configuration.AllowDelete { r.Handle("/api/buckets/{bucketName}/objects/{objectName:.*}", s3manager.HandleDeleteObject(s3)).Methods(http.MethodDelete) } + r.Handle("/api/buckets/{bucketName}/policy", s3manager.HandleGetBucketPolicy(s3)).Methods(http.MethodGet) + r.Handle("/api/buckets/{bucketName}/policy", s3manager.HandlePutBucketPolicy(s3)).Methods(http.MethodPut) lr := logging.Handler(os.Stdout)(r) srv := &http.Server{ diff --git a/web/template/bucket.html.tmpl b/web/template/bucket.html.tmpl index e2f8d28b..a68e7bb5 100644 --- a/web/template/bucket.html.tmpl +++ b/web/template/bucket.html.tmpl @@ -14,15 +14,20 @@