diff --git a/weed/s3api/auth_credentials.go b/weed/s3api/auth_credentials.go index 02138af8d..c5dae782d 100644 --- a/weed/s3api/auth_credentials.go +++ b/weed/s3api/auth_credentials.go @@ -132,6 +132,9 @@ func (iam *IdentityAccessManagement) Auth(f http.HandlerFunc, action Action) htt if errCode == s3err.ErrNone { if identity != nil && identity.Name != "" { r.Header.Set(xhttp.AmzIdentityId, identity.Name) + if identity.isAdmin() { + r.Header.Set(xhttp.AmzIsAdmin, "true") + } } f(w, r) return @@ -190,10 +193,8 @@ func (iam *IdentityAccessManagement) authRequest(r *http.Request, action Action) } func (identity *Identity) canDo(action Action, bucket string) bool { - for _, a := range identity.Actions { - if a == "Admin" { - return true - } + if identity.isAdmin() { + return true } for _, a := range identity.Actions { if a == action { @@ -211,3 +212,12 @@ func (identity *Identity) canDo(action Action, bucket string) bool { } return false } + +func (identity *Identity) isAdmin() bool { + for _, a := range identity.Actions { + if a == "Admin" { + return true + } + } + return false +} diff --git a/weed/s3api/http/header.go b/weed/s3api/http/header.go index cdd383c84..f496429fc 100644 --- a/weed/s3api/http/header.go +++ b/weed/s3api/http/header.go @@ -32,4 +32,5 @@ const ( // Non-Standard S3 HTTP request constants const ( AmzIdentityId = "x-amz-identity-id" + AmzIsAdmin = "x-amz-is-admin" // only set to http request header as a context ) diff --git a/weed/s3api/s3api_bucket_handlers.go b/weed/s3api/s3api_bucket_handlers.go index c892999f1..fe33cfe78 100644 --- a/weed/s3api/s3api_bucket_handlers.go +++ b/weed/s3api/s3api_bucket_handlers.go @@ -40,10 +40,8 @@ func (s3a *S3ApiServer) ListBucketsHandler(w http.ResponseWriter, r *http.Reques var buckets []*s3.Bucket for _, entry := range entries { if entry.IsDirectory { - if id, ok := entry.Extended[xhttp.AmzIdentityId]; ok { - if identityId != string(id) { - continue - } + if !s3a.hasAccess(r, entry) { + continue } buckets = append(buckets, &s3.Bucket{ Name: aws.String(entry.Name), @@ -126,13 +124,9 @@ func (s3a *S3ApiServer) DeleteBucketHandler(w http.ResponseWriter, r *http.Reque return } - if entry.Extended != nil { - if id, ok := entry.Extended[xhttp.AmzIdentityId]; ok { - if string(id) != r.Header.Get(xhttp.AmzIdentityId) { - writeErrorResponse(w, s3err.ErrAccessDenied, r.URL) - return - } - } + if !s3a.hasAccess(r, entry) { + writeErrorResponse(w, s3err.ErrAccessDenied, r.URL) + return } err = s3a.WithFilerClient(func(client filer_pb.SeaweedFilerClient) error { @@ -170,14 +164,28 @@ func (s3a *S3ApiServer) HeadBucketHandler(w http.ResponseWriter, r *http.Request return } - if entry.Extended != nil { - if id, ok := entry.Extended[xhttp.AmzIdentityId]; ok { - if string(id) != r.Header.Get(xhttp.AmzIdentityId) { - writeErrorResponse(w, s3err.ErrAccessDenied, r.URL) - return - } - } + if !s3a.hasAccess(r, entry) { + writeErrorResponse(w, s3err.ErrAccessDenied, r.URL) + return } writeSuccessResponseEmpty(w) } + +func (s3a *S3ApiServer) hasAccess(r *http.Request, entry *filer_pb.Entry) bool { + isAdmin := r.Header.Get(xhttp.AmzIsAdmin) != "" + if isAdmin { + return true + } + if entry.Extended == nil { + return true + } + + identityId := r.Header.Get(xhttp.AmzIdentityId) + if id, ok := entry.Extended[xhttp.AmzIdentityId]; ok { + if identityId != string(id) { + return false + } + } + return true +} \ No newline at end of file