Browse Source

implement `PutBucketAclHandler`

Signed-off-by: changlin.shi <changlin.shi@ly.com>
pull/3847/head
changlin.shi 2 years ago
parent
commit
558ba1094a
  1. 36
      weed/s3api/s3api_acp.go
  2. 41
      weed/s3api/s3api_bucket_handlers.go
  3. 6
      weed/s3api/s3api_bucket_skip_handlers.go
  4. 7
      weed/s3api/s3err/s3api_errors.go

36
weed/s3api/s3api_acp.go

@ -1,8 +1,11 @@
package s3api package s3api
import ( import (
"github.com/seaweedfs/seaweedfs/weed/glog"
"github.com/seaweedfs/seaweedfs/weed/pb/filer_pb"
"github.com/seaweedfs/seaweedfs/weed/s3api/s3_constants" "github.com/seaweedfs/seaweedfs/weed/s3api/s3_constants"
"github.com/seaweedfs/seaweedfs/weed/s3api/s3account" "github.com/seaweedfs/seaweedfs/weed/s3api/s3account"
"github.com/seaweedfs/seaweedfs/weed/s3api/s3acl"
"github.com/seaweedfs/seaweedfs/weed/s3api/s3err" "github.com/seaweedfs/seaweedfs/weed/s3api/s3err"
"net/http" "net/http"
) )
@ -27,3 +30,36 @@ func (s3a *S3ApiServer) checkAccessByOwnership(r *http.Request, bucket string) s
} }
return s3err.ErrAccessDenied return s3err.ErrAccessDenied
} }
//Check access for PutBucketAclHandler
func (s3a *S3ApiServer) checkAccessForPutBucketAcl(accountId, bucket string) (*BucketMetaData, s3err.ErrorCode) {
bucketMetadata, errCode := s3a.bucketRegistry.GetBucketMetadata(bucket)
if errCode != s3err.ErrNone {
return nil, errCode
}
if bucketMetadata.ObjectOwnership == s3_constants.OwnershipBucketOwnerEnforced {
return nil, s3err.AccessControlListNotSupported
}
if accountId == s3account.AccountAdmin.Id || accountId == *bucketMetadata.Owner.ID {
return bucketMetadata, s3err.ErrNone
}
if len(bucketMetadata.Acl) > 0 {
reqGrants := s3acl.DetermineReqGrants(accountId, s3_constants.PermissionWriteAcp)
for _, bucketGrant := range bucketMetadata.Acl {
for _, reqGrant := range reqGrants {
if s3acl.GrantEquals(bucketGrant, reqGrant) {
return bucketMetadata, s3err.ErrNone
}
}
}
}
glog.V(3).Infof("acl denied! request account id: %s", accountId)
return nil, s3err.ErrAccessDenied
}
func updateBucketEntry(s3a *S3ApiServer, entry *filer_pb.Entry) error {
return s3a.updateEntry(s3a.option.BucketsPath, entry)
}

41
weed/s3api/s3api_bucket_handlers.go

@ -6,6 +6,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil" "github.com/aws/aws-sdk-go/private/protocol/xml/xmlutil"
"github.com/seaweedfs/seaweedfs/weed/s3api/s3acl"
"github.com/seaweedfs/seaweedfs/weed/util" "github.com/seaweedfs/seaweedfs/weed/util"
"math" "math"
"net/http" "net/http"
@ -238,6 +239,46 @@ func (s3a *S3ApiServer) hasAccess(r *http.Request, entry *filer_pb.Entry) bool {
return true return true
} }
// PutBucketAclHandler Put bucket ACL
// https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketAcl.html
func (s3a *S3ApiServer) PutBucketAclHandler(w http.ResponseWriter, r *http.Request) {
bucket, _ := s3_constants.GetBucketAndObject(r)
glog.V(3).Infof("PutBucketAclHandler %s", bucket)
accountId := s3acl.GetAccountId(r)
bucketMetadata, errorCode := s3a.checkAccessForPutBucketAcl(accountId, bucket)
if errorCode != s3err.ErrNone {
s3err.WriteErrorResponse(w, r, errorCode)
return
}
grants, errCode := s3acl.ExtractAcl(r, s3a.accountManager, bucketMetadata.ObjectOwnership, "", *bucketMetadata.Owner.ID, accountId)
if errCode != s3err.ErrNone {
s3err.WriteErrorResponse(w, r, errCode)
return
}
bucketEntry, err := s3a.getEntry(s3a.option.BucketsPath, bucket)
if err != nil {
glog.Warning(err)
s3err.WriteErrorResponse(w, r, s3err.ErrInternalError)
return
}
errCode = s3acl.AssembleEntryWithAcp(bucketEntry, *bucketMetadata.Owner.ID, grants)
if errCode != s3err.ErrNone {
s3err.WriteErrorResponse(w, r, errCode)
return
}
err = updateBucketEntry(s3a, bucketEntry)
if err != nil {
s3err.WriteErrorResponse(w, r, s3err.ErrInternalError)
return
}
s3err.WriteEmptyResponse(w, r, http.StatusOK)
}
// GetBucketAclHandler Get Bucket ACL // GetBucketAclHandler Get Bucket ACL
// https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketAcl.html // https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetBucketAcl.html
func (s3a *S3ApiServer) GetBucketAclHandler(w http.ResponseWriter, r *http.Request) { func (s3a *S3ApiServer) GetBucketAclHandler(w http.ResponseWriter, r *http.Request) {

6
weed/s3api/s3api_bucket_skip_handlers.go

@ -41,9 +41,3 @@ func (s3a *S3ApiServer) PutBucketPolicyHandler(w http.ResponseWriter, r *http.Re
func (s3a *S3ApiServer) DeleteBucketPolicyHandler(w http.ResponseWriter, r *http.Request) { func (s3a *S3ApiServer) DeleteBucketPolicyHandler(w http.ResponseWriter, r *http.Request) {
s3err.WriteErrorResponse(w, r, http.StatusNoContent) s3err.WriteErrorResponse(w, r, http.StatusNoContent)
} }
// PutBucketAclHandler Put bucket ACL
// https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketAcl.html
func (s3a *S3ApiServer) PutBucketAclHandler(w http.ResponseWriter, r *http.Request) {
s3err.WriteErrorResponse(w, r, s3err.ErrNotImplemented)
}

7
weed/s3api/s3err/s3api_errors.go

@ -109,6 +109,7 @@ const (
ErrRequestBytesExceed ErrRequestBytesExceed
OwnershipControlsNotFoundError OwnershipControlsNotFoundError
AccessControlListNotSupported
) )
// error code to APIError structure, these fields carry respective // error code to APIError structure, these fields carry respective
@ -416,12 +417,16 @@ var errorCodeResponse = map[ErrorCode]APIError{
Description: "Simultaneous request bytes exceed limitations", Description: "Simultaneous request bytes exceed limitations",
HTTPStatusCode: http.StatusTooManyRequests, HTTPStatusCode: http.StatusTooManyRequests,
}, },
OwnershipControlsNotFoundError: { OwnershipControlsNotFoundError: {
Code: "OwnershipControlsNotFoundError", Code: "OwnershipControlsNotFoundError",
Description: "The bucket ownership controls were not found", Description: "The bucket ownership controls were not found",
HTTPStatusCode: http.StatusNotFound, HTTPStatusCode: http.StatusNotFound,
}, },
AccessControlListNotSupported: {
Code: "AccessControlListNotSupported",
Description: "The bucket does not allow ACLs",
HTTPStatusCode: http.StatusBadRequest,
},
} }
// GetAPIError provides API Error for input API error code. // GetAPIError provides API Error for input API error code.

Loading…
Cancel
Save