From 44b275879bf8a67af35c0b3c6e5049d95b3df3df Mon Sep 17 00:00:00 2001 From: Konstantin Lebedev <9497591+kmlebedev@users.noreply.github.com> Date: Fri, 4 Oct 2024 22:59:14 +0500 Subject: [PATCH] [s3] add {Get,Put,Delete}BucketTagging and PublicAccessBlock Handlers (#6088) * add {Get,Put,Delete}BucketTagging Handlers * s3 add skip bucket PublicAccessBlock handlers --------- Co-authored-by: Chris Lu --- weed/s3api/s3api_bucket_skip_handlers.go | 38 ++++++++++++++++++++++++ weed/s3api/s3api_server.go | 10 +++++++ weed/s3api/s3err/s3api_errors.go | 6 ++++ 3 files changed, 54 insertions(+) diff --git a/weed/s3api/s3api_bucket_skip_handlers.go b/weed/s3api/s3api_bucket_skip_handlers.go index 0a8430e6e..549eaa8ce 100644 --- a/weed/s3api/s3api_bucket_skip_handlers.go +++ b/weed/s3api/s3api_bucket_skip_handlers.go @@ -1,6 +1,8 @@ package s3api import ( + "github.com/seaweedfs/seaweedfs/weed/glog" + "github.com/seaweedfs/seaweedfs/weed/s3api/s3_constants" "net/http" "github.com/seaweedfs/seaweedfs/weed/s3api/s3err" @@ -48,6 +50,28 @@ func (s3a *S3ApiServer) PutBucketVersioningHandler(w http.ResponseWriter, r *htt s3err.WriteErrorResponse(w, r, s3err.ErrNotImplemented) } +// GetBucketTaggingHandler Returns the tag set associated with the bucket +// https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketTagging.html +func (s3a *S3ApiServer) GetBucketTaggingHandler(w http.ResponseWriter, r *http.Request) { + bucket, _ := s3_constants.GetBucketAndObject(r) + glog.V(3).Infof("GetBucketTagging %s", bucket) + + if err := s3a.checkBucket(r, bucket); err != s3err.ErrNone { + s3err.WriteErrorResponse(w, r, err) + return + } + + s3err.WriteErrorResponse(w, r, s3err.ErrNoSuchTagSet) +} + +func (s3a *S3ApiServer) PutBucketTaggingHandler(w http.ResponseWriter, r *http.Request) { + s3err.WriteErrorResponse(w, r, s3err.ErrNotImplemented) +} + +func (s3a *S3ApiServer) DeleteBucketTaggingHandler(w http.ResponseWriter, r *http.Request) { + s3err.WriteErrorResponse(w, r, s3err.ErrNotImplemented) +} + // GetBucketEncryptionHandler Returns the default encryption configuration // https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketEncryption.html func (s3a *S3ApiServer) GetBucketEncryptionHandler(w http.ResponseWriter, r *http.Request) { @@ -61,3 +85,17 @@ func (s3a *S3ApiServer) PutBucketEncryptionHandler(w http.ResponseWriter, r *htt func (s3a *S3ApiServer) DeleteBucketEncryptionHandler(w http.ResponseWriter, r *http.Request) { s3err.WriteErrorResponse(w, r, s3err.ErrNotImplemented) } + +// GetPublicAccessBlockHandler Retrieves the PublicAccessBlock configuration for an S3 bucket +// https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetPublicAccessBlock.html +func (s3a *S3ApiServer) GetPublicAccessBlockHandler(w http.ResponseWriter, r *http.Request) { + s3err.WriteErrorResponse(w, r, s3err.ErrNotImplemented) +} + +func (s3a *S3ApiServer) PutPublicAccessBlockHandler(w http.ResponseWriter, r *http.Request) { + s3err.WriteErrorResponse(w, r, s3err.ErrNotImplemented) +} + +func (s3a *S3ApiServer) DeletePublicAccessBlockHandler(w http.ResponseWriter, r *http.Request) { + s3err.WriteErrorResponse(w, r, s3err.ErrNotImplemented) +} diff --git a/weed/s3api/s3api_server.go b/weed/s3api/s3api_server.go index 3b024def6..2f9e9e3fb 100644 --- a/weed/s3api/s3api_server.go +++ b/weed/s3api/s3api_server.go @@ -258,11 +258,21 @@ func (s3a *S3ApiServer) registerRouter(router *mux.Router) { bucket.Methods(http.MethodGet).HandlerFunc(track(s3a.iam.Auth(s3a.cb.Limit(s3a.GetBucketVersioningHandler, ACTION_READ)), "GET")).Queries("versioning", "") bucket.Methods(http.MethodPut).HandlerFunc(track(s3a.iam.Auth(s3a.cb.Limit(s3a.PutBucketVersioningHandler, ACTION_WRITE)), "PUT")).Queries("versioning", "") + // GetBucketTagging + bucket.Methods(http.MethodGet).HandlerFunc(track(s3a.iam.Auth(s3a.cb.Limit(s3a.GetBucketTaggingHandler, ACTION_TAGGING)), "GET")).Queries("tagging", "") + bucket.Methods(http.MethodPut).HandlerFunc(track(s3a.iam.Auth(s3a.cb.Limit(s3a.PutBucketTaggingHandler, ACTION_TAGGING)), "PUT")).Queries("tagging", "") + bucket.Methods(http.MethodDelete).HandlerFunc(track(s3a.iam.Auth(s3a.cb.Limit(s3a.DeleteBucketTaggingHandler, ACTION_TAGGING)), "DELETE")).Queries("tagging", "") + // GetBucketEncryption bucket.Methods(http.MethodGet).HandlerFunc(track(s3a.iam.Auth(s3a.cb.Limit(s3a.GetBucketEncryptionHandler, ACTION_ADMIN)), "GET")).Queries("encryption", "") bucket.Methods(http.MethodPut).HandlerFunc(track(s3a.iam.Auth(s3a.cb.Limit(s3a.PutBucketEncryptionHandler, ACTION_ADMIN)), "PUT")).Queries("encryption", "") bucket.Methods(http.MethodDelete).HandlerFunc(track(s3a.iam.Auth(s3a.cb.Limit(s3a.DeleteBucketEncryptionHandler, ACTION_ADMIN)), "DELETE")).Queries("encryption", "") + // GetPublicAccessBlockHandler + bucket.Methods(http.MethodGet).HandlerFunc(track(s3a.iam.Auth(s3a.cb.Limit(s3a.GetPublicAccessBlockHandler, ACTION_ADMIN)), "GET")).Queries("publicAccessBlock", "") + bucket.Methods(http.MethodPut).HandlerFunc(track(s3a.iam.Auth(s3a.cb.Limit(s3a.PutPublicAccessBlockHandler, ACTION_ADMIN)), "PUT")).Queries("publicAccessBlock", "") + bucket.Methods(http.MethodDelete).HandlerFunc(track(s3a.iam.Auth(s3a.cb.Limit(s3a.DeletePublicAccessBlockHandler, ACTION_ADMIN)), "DELETE")).Queries("publicAccessBlock", "") + // ListObjectsV2 bucket.Methods(http.MethodGet).HandlerFunc(track(s3a.iam.Auth(s3a.cb.Limit(s3a.ListObjectsV2Handler, ACTION_LIST)), "LIST")).Queries("list-type", "2") diff --git a/weed/s3api/s3err/s3api_errors.go b/weed/s3api/s3err/s3api_errors.go index 0348d4ddc..f41c3620c 100644 --- a/weed/s3api/s3err/s3api_errors.go +++ b/weed/s3api/s3err/s3api_errors.go @@ -109,6 +109,7 @@ const ( ErrRequestBytesExceed OwnershipControlsNotFoundError + ErrNoSuchTagSet ) // error code to APIError structure, these fields carry respective @@ -184,6 +185,11 @@ var errorCodeResponse = map[ErrorCode]APIError{ Description: "The bucket policy does not exist", HTTPStatusCode: http.StatusNotFound, }, + ErrNoSuchTagSet: { + Code: "NoSuchTagSet", + Description: "The TagSet does not exist", + HTTPStatusCode: http.StatusNotFound, + }, ErrNoSuchCORSConfiguration: { Code: "NoSuchCORSConfiguration", Description: "The CORS configuration does not exist",