Browse Source

s3tables: Fetch bucket policy in handleListTagsForResource for permission evaluation

Update handleListTagsForResource to fetch and pass bucket policy to
CheckPermission, matching the behavior of handleTagResource/handleUntagResource.
This enables bucket-policy-based permission grants to be evaluated for
ListTagsForResource, not just ownership-based checks.
pull/8147/head
Chris Lu 4 days ago
parent
commit
0b41ade726
  1. 43
      weed/s3api/s3tables/handler_policy.go

43
weed/s3api/s3tables/handler_policy.go

@ -59,7 +59,7 @@ func (h *S3TablesHandler) handlePutTableBucketPolicy(w http.ResponseWriter, r *h
} }
// Check permission // Check permission
principal := h.getPrincipalFromRequest(r)
principal := h.getAccountID(r)
if !CanPutTableBucketPolicy(principal, bucketMetadata.OwnerAccountID, "") { if !CanPutTableBucketPolicy(principal, bucketMetadata.OwnerAccountID, "") {
h.writeError(w, http.StatusForbidden, ErrCodeAccessDenied, "not authorized to put table bucket policy") h.writeError(w, http.StatusForbidden, ErrCodeAccessDenied, "not authorized to put table bucket policy")
return NewAuthError("PutTableBucketPolicy", principal, "not authorized to put table bucket policy") return NewAuthError("PutTableBucketPolicy", principal, "not authorized to put table bucket policy")
@ -132,7 +132,7 @@ func (h *S3TablesHandler) handleGetTableBucketPolicy(w http.ResponseWriter, r *h
} }
// Check permission // Check permission
principal := h.getPrincipalFromRequest(r)
principal := h.getAccountID(r)
if !CanGetTableBucketPolicy(principal, bucketMetadata.OwnerAccountID, string(policy)) { if !CanGetTableBucketPolicy(principal, bucketMetadata.OwnerAccountID, string(policy)) {
h.writeError(w, http.StatusForbidden, ErrCodeAccessDenied, "not authorized to get table bucket policy") h.writeError(w, http.StatusForbidden, ErrCodeAccessDenied, "not authorized to get table bucket policy")
return NewAuthError("GetTableBucketPolicy", principal, "not authorized to get table bucket policy") return NewAuthError("GetTableBucketPolicy", principal, "not authorized to get table bucket policy")
@ -198,7 +198,7 @@ func (h *S3TablesHandler) handleDeleteTableBucketPolicy(w http.ResponseWriter, r
} }
// Check permission // Check permission
principal := h.getPrincipalFromRequest(r)
principal := h.getAccountID(r)
if !CanDeleteTableBucketPolicy(principal, bucketMetadata.OwnerAccountID, bucketPolicy) { if !CanDeleteTableBucketPolicy(principal, bucketMetadata.OwnerAccountID, bucketPolicy) {
h.writeError(w, http.StatusForbidden, ErrCodeAccessDenied, "not authorized to delete table bucket policy") h.writeError(w, http.StatusForbidden, ErrCodeAccessDenied, "not authorized to delete table bucket policy")
return NewAuthError("DeleteTableBucketPolicy", principal, "not authorized to delete table bucket policy") return NewAuthError("DeleteTableBucketPolicy", principal, "not authorized to delete table bucket policy")
@ -287,7 +287,7 @@ func (h *S3TablesHandler) handlePutTablePolicy(w http.ResponseWriter, r *http.Re
} }
// Check permission // Check permission
principal := h.getPrincipalFromRequest(r)
principal := h.getAccountID(r)
if !CanPutTablePolicy(principal, metadata.OwnerAccountID, bucketPolicy) { if !CanPutTablePolicy(principal, metadata.OwnerAccountID, bucketPolicy) {
h.writeError(w, http.StatusForbidden, ErrCodeAccessDenied, "not authorized to put table policy") h.writeError(w, http.StatusForbidden, ErrCodeAccessDenied, "not authorized to put table policy")
return NewAuthError("PutTablePolicy", principal, "not authorized to put table policy") return NewAuthError("PutTablePolicy", principal, "not authorized to put table policy")
@ -383,7 +383,7 @@ func (h *S3TablesHandler) handleGetTablePolicy(w http.ResponseWriter, r *http.Re
} }
// Check permission // Check permission
principal := h.getPrincipalFromRequest(r)
principal := h.getAccountID(r)
if !CanGetTablePolicy(principal, metadata.OwnerAccountID, bucketPolicy) { if !CanGetTablePolicy(principal, metadata.OwnerAccountID, bucketPolicy) {
h.writeError(w, http.StatusForbidden, ErrCodeAccessDenied, "not authorized to get table policy") h.writeError(w, http.StatusForbidden, ErrCodeAccessDenied, "not authorized to get table policy")
return NewAuthError("GetTablePolicy", principal, "not authorized to get table policy") return NewAuthError("GetTablePolicy", principal, "not authorized to get table policy")
@ -461,7 +461,7 @@ func (h *S3TablesHandler) handleDeleteTablePolicy(w http.ResponseWriter, r *http
} }
// Check permission // Check permission
principal := h.getPrincipalFromRequest(r)
principal := h.getAccountID(r)
if !CanDeleteTablePolicy(principal, metadata.OwnerAccountID, bucketPolicy) { if !CanDeleteTablePolicy(principal, metadata.OwnerAccountID, bucketPolicy) {
h.writeError(w, http.StatusForbidden, ErrCodeAccessDenied, "not authorized to delete table policy") h.writeError(w, http.StatusForbidden, ErrCodeAccessDenied, "not authorized to delete table policy")
return NewAuthError("DeleteTablePolicy", principal, "not authorized to delete table policy") return NewAuthError("DeleteTablePolicy", principal, "not authorized to delete table policy")
@ -553,7 +553,7 @@ func (h *S3TablesHandler) handleTagResource(w http.ResponseWriter, r *http.Reque
} }
// Check Permission inside the closure because we just got the ID // Check Permission inside the closure because we just got the ID
principal := h.getPrincipalFromRequest(r)
principal := h.getAccountID(r)
if !CanManageTags(principal, ownerAccountID, bucketPolicy) { if !CanManageTags(principal, ownerAccountID, bucketPolicy) {
return NewAuthError("TagResource", principal, "not authorized to tag resource") return NewAuthError("TagResource", principal, "not authorized to tag resource")
} }
@ -629,6 +629,7 @@ func (h *S3TablesHandler) handleListTagsForResource(w http.ResponseWriter, r *ht
} }
tags := make(map[string]string) tags := make(map[string]string)
var bucketPolicy string
err = filerClient.WithFilerClient(false, func(client filer_pb.SeaweedFilerClient) error { err = filerClient.WithFilerClient(false, func(client filer_pb.SeaweedFilerClient) error {
// Read metadata for ownership check // Read metadata for ownership check
data, err := h.getExtendedAttribute(r.Context(), client, resourcePath, ExtendedKeyMetadata) data, err := h.getExtendedAttribute(r.Context(), client, resourcePath, ExtendedKeyMetadata)
@ -637,23 +638,45 @@ func (h *S3TablesHandler) handleListTagsForResource(w http.ResponseWriter, r *ht
} }
var ownerAccountID string var ownerAccountID string
var bucketName string
if rType == ResourceTypeTable { if rType == ResourceTypeTable {
var meta tableMetadataInternal var meta tableMetadataInternal
if err := json.Unmarshal(data, &meta); err != nil { if err := json.Unmarshal(data, &meta); err != nil {
return err return err
} }
ownerAccountID = meta.OwnerAccountID ownerAccountID = meta.OwnerAccountID
// Extract bucket name from resource path for tables
// resourcePath format: /tables/{bucket}/{namespace}/{table}
parts := strings.Split(strings.Trim(resourcePath, "/"), "/")
if len(parts) >= 2 {
bucketName = parts[1]
}
} else { } else {
var meta tableBucketMetadata var meta tableBucketMetadata
if err := json.Unmarshal(data, &meta); err != nil { if err := json.Unmarshal(data, &meta); err != nil {
return err return err
} }
ownerAccountID = meta.OwnerAccountID ownerAccountID = meta.OwnerAccountID
// Extract bucket name from resource path for buckets
// resourcePath format: /tables/{bucket}
parts := strings.Split(strings.Trim(resourcePath, "/"), "/")
if len(parts) >= 2 {
bucketName = parts[1]
}
}
// Fetch bucket policy if we have a bucket name
if bucketName != "" {
bucketPath := getTableBucketPath(bucketName)
policyData, err := h.getExtendedAttribute(r.Context(), client, bucketPath, ExtendedKeyPolicy)
if err == nil {
bucketPolicy = string(policyData)
}
} }
// Check Permission // Check Permission
principal := h.getPrincipalFromRequest(r)
if !CheckPermission("ListTagsForResource", principal, ownerAccountID, "") {
principal := h.getAccountID(r)
if !CheckPermission("ListTagsForResource", principal, ownerAccountID, bucketPolicy) {
return NewAuthError("ListTagsForResource", principal, "not authorized to list tags for resource") return NewAuthError("ListTagsForResource", principal, "not authorized to list tags for resource")
} }
@ -760,7 +783,7 @@ func (h *S3TablesHandler) handleUntagResource(w http.ResponseWriter, r *http.Req
} }
// Check Permission // Check Permission
principal := h.getPrincipalFromRequest(r)
principal := h.getAccountID(r)
if !CanManageTags(principal, ownerAccountID, bucketPolicy) { if !CanManageTags(principal, ownerAccountID, bucketPolicy) {
return NewAuthError("UntagResource", principal, "not authorized to untag resource") return NewAuthError("UntagResource", principal, "not authorized to untag resource")
} }

Loading…
Cancel
Save