s3tables: Extract resource owner and bucket extraction into helper method
Create extractResourceOwnerAndBucket() helper to consolidate the repeated pattern of unmarshaling metadata and extracting bucket name from resource path. This pattern was duplicated in handleTagResource, handleListTagsForResource, and handleUntagResource. Update all three handlers to use the helper. Also update remaining uses of getPrincipalFromRequest() (in handler_bucket_create, handler_bucket_get_list_delete, handler_namespace) to use getAccountID() after consolidating the two identical methods.
This commit is contained in:
@@ -15,7 +15,7 @@ import (
|
|||||||
func (h *S3TablesHandler) handleCreateTableBucket(w http.ResponseWriter, r *http.Request, filerClient FilerClient) error {
|
func (h *S3TablesHandler) handleCreateTableBucket(w http.ResponseWriter, r *http.Request, filerClient FilerClient) error {
|
||||||
// Check permission
|
// Check permission
|
||||||
accountID := h.getAccountID(r)
|
accountID := h.getAccountID(r)
|
||||||
principal := h.getPrincipalFromRequest(r)
|
principal := h.getAccountID(r)
|
||||||
if !CanCreateTableBucket(principal, accountID, "") {
|
if !CanCreateTableBucket(principal, accountID, "") {
|
||||||
h.writeError(w, http.StatusForbidden, ErrCodeAccessDenied, "not authorized to create table buckets")
|
h.writeError(w, http.StatusForbidden, ErrCodeAccessDenied, "not authorized to create table buckets")
|
||||||
return NewAuthError("CreateTableBucket", principal, "not authorized to create table buckets")
|
return NewAuthError("CreateTableBucket", principal, "not authorized to create table buckets")
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ func (h *S3TablesHandler) handleGetTableBucket(w http.ResponseWriter, r *http.Re
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check permission
|
// Check permission
|
||||||
principal := h.getPrincipalFromRequest(r)
|
principal := h.getAccountID(r)
|
||||||
if !CanGetTableBucket(principal, metadata.OwnerAccountID, bucketPolicy) {
|
if !CanGetTableBucket(principal, metadata.OwnerAccountID, bucketPolicy) {
|
||||||
h.writeError(w, http.StatusForbidden, ErrCodeAccessDenied, "not authorized to get table bucket details")
|
h.writeError(w, http.StatusForbidden, ErrCodeAccessDenied, "not authorized to get table bucket details")
|
||||||
return ErrAccessDenied
|
return ErrAccessDenied
|
||||||
@@ -90,7 +90,7 @@ func (h *S3TablesHandler) handleListTableBuckets(w http.ResponseWriter, r *http.
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check permission
|
// Check permission
|
||||||
principal := h.getPrincipalFromRequest(r)
|
principal := h.getAccountID(r)
|
||||||
accountID := h.getAccountID(r)
|
accountID := h.getAccountID(r)
|
||||||
if !CanListTableBuckets(principal, accountID, "") {
|
if !CanListTableBuckets(principal, accountID, "") {
|
||||||
h.writeError(w, http.StatusForbidden, ErrCodeAccessDenied, "not authorized to list table buckets")
|
h.writeError(w, http.StatusForbidden, ErrCodeAccessDenied, "not authorized to list table buckets")
|
||||||
@@ -260,7 +260,7 @@ func (h *S3TablesHandler) handleDeleteTableBucket(w http.ResponseWriter, r *http
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 2. Check permission
|
// 2. Check permission
|
||||||
principal := h.getPrincipalFromRequest(r)
|
principal := h.getAccountID(r)
|
||||||
if !CanDeleteTableBucket(principal, metadata.OwnerAccountID, bucketPolicy) {
|
if !CanDeleteTableBucket(principal, metadata.OwnerAccountID, bucketPolicy) {
|
||||||
return NewAuthError("DeleteTableBucket", principal, fmt.Sprintf("not authorized to delete bucket %s", bucketName))
|
return NewAuthError("DeleteTableBucket", principal, fmt.Sprintf("not authorized to delete bucket %s", bucketName))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ func (h *S3TablesHandler) handleCreateNamespace(w http.ResponseWriter, r *http.R
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check permission
|
// Check permission
|
||||||
principal := h.getPrincipalFromRequest(r)
|
principal := h.getAccountID(r)
|
||||||
if !CanCreateNamespace(principal, bucketMetadata.OwnerAccountID, bucketPolicy) {
|
if !CanCreateNamespace(principal, bucketMetadata.OwnerAccountID, bucketPolicy) {
|
||||||
h.writeError(w, http.StatusForbidden, ErrCodeAccessDenied, "not authorized to create namespace in this bucket")
|
h.writeError(w, http.StatusForbidden, ErrCodeAccessDenied, "not authorized to create namespace in this bucket")
|
||||||
return ErrAccessDenied
|
return ErrAccessDenied
|
||||||
@@ -197,7 +197,7 @@ func (h *S3TablesHandler) handleGetNamespace(w http.ResponseWriter, r *http.Requ
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check permission
|
// Check permission
|
||||||
principal := h.getPrincipalFromRequest(r)
|
principal := h.getAccountID(r)
|
||||||
if !CanGetNamespace(principal, metadata.OwnerAccountID, bucketPolicy) {
|
if !CanGetNamespace(principal, metadata.OwnerAccountID, bucketPolicy) {
|
||||||
h.writeError(w, http.StatusNotFound, ErrCodeNoSuchNamespace, "namespace not found")
|
h.writeError(w, http.StatusNotFound, ErrCodeNoSuchNamespace, "namespace not found")
|
||||||
return ErrAccessDenied
|
return ErrAccessDenied
|
||||||
@@ -269,7 +269,7 @@ func (h *S3TablesHandler) handleListNamespaces(w http.ResponseWriter, r *http.Re
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
principal := h.getPrincipalFromRequest(r)
|
principal := h.getAccountID(r)
|
||||||
if !CanListNamespaces(principal, bucketMetadata.OwnerAccountID, bucketPolicy) {
|
if !CanListNamespaces(principal, bucketMetadata.OwnerAccountID, bucketPolicy) {
|
||||||
h.writeError(w, http.StatusNotFound, ErrCodeNoSuchBucket, fmt.Sprintf("table bucket %s not found", bucketName))
|
h.writeError(w, http.StatusNotFound, ErrCodeNoSuchBucket, fmt.Sprintf("table bucket %s not found", bucketName))
|
||||||
return ErrAccessDenied
|
return ErrAccessDenied
|
||||||
@@ -440,7 +440,7 @@ func (h *S3TablesHandler) handleDeleteNamespace(w http.ResponseWriter, r *http.R
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check permission
|
// Check permission
|
||||||
principal := h.getPrincipalFromRequest(r)
|
principal := h.getAccountID(r)
|
||||||
if !CanDeleteNamespace(principal, metadata.OwnerAccountID, bucketPolicy) {
|
if !CanDeleteNamespace(principal, metadata.OwnerAccountID, bucketPolicy) {
|
||||||
h.writeError(w, http.StatusNotFound, ErrCodeNoSuchNamespace, "namespace not found")
|
h.writeError(w, http.StatusNotFound, ErrCodeNoSuchNamespace, "namespace not found")
|
||||||
return ErrAccessDenied
|
return ErrAccessDenied
|
||||||
|
|||||||
@@ -10,6 +10,42 @@ import (
|
|||||||
"github.com/seaweedfs/seaweedfs/weed/pb/filer_pb"
|
"github.com/seaweedfs/seaweedfs/weed/pb/filer_pb"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// extractResourceOwnerAndBucket extracts ownership info and bucket name from resource metadata.
|
||||||
|
// This helper consolidates the repeated pattern used in handleTagResource, handleListTagsForResource,
|
||||||
|
// and handleUntagResource.
|
||||||
|
func (h *S3TablesHandler) extractResourceOwnerAndBucket(
|
||||||
|
data []byte,
|
||||||
|
resourcePath string,
|
||||||
|
rType ResourceType,
|
||||||
|
) (ownerAccountID, bucketName string, err error) {
|
||||||
|
if rType == ResourceTypeTable {
|
||||||
|
var meta tableMetadataInternal
|
||||||
|
if err := json.Unmarshal(data, &meta); err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
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 {
|
||||||
|
var meta tableBucketMetadata
|
||||||
|
if err := json.Unmarshal(data, &meta); err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
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]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ownerAccountID, bucketName, nil
|
||||||
|
}
|
||||||
|
|
||||||
// handlePutTableBucketPolicy puts a policy on a table bucket
|
// handlePutTableBucketPolicy puts a policy on a table bucket
|
||||||
func (h *S3TablesHandler) handlePutTableBucketPolicy(w http.ResponseWriter, r *http.Request, filerClient FilerClient) error {
|
func (h *S3TablesHandler) handlePutTableBucketPolicy(w http.ResponseWriter, r *http.Request, filerClient FilerClient) error {
|
||||||
|
|
||||||
@@ -515,32 +551,9 @@ func (h *S3TablesHandler) handleTagResource(w http.ResponseWriter, r *http.Reque
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var ownerAccountID string
|
ownerAccountID, bucketName, err := h.extractResourceOwnerAndBucket(data, resourcePath, rType)
|
||||||
var bucketName string
|
if err != nil {
|
||||||
if rType == ResourceTypeTable {
|
return err
|
||||||
var meta tableMetadataInternal
|
|
||||||
if err := json.Unmarshal(data, &meta); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
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 {
|
|
||||||
var meta tableBucketMetadata
|
|
||||||
if err := json.Unmarshal(data, &meta); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
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
|
// Fetch bucket policy if we have a bucket name
|
||||||
@@ -637,32 +650,9 @@ func (h *S3TablesHandler) handleListTagsForResource(w http.ResponseWriter, r *ht
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var ownerAccountID string
|
ownerAccountID, bucketName, err := h.extractResourceOwnerAndBucket(data, resourcePath, rType)
|
||||||
var bucketName string
|
if err != nil {
|
||||||
if rType == ResourceTypeTable {
|
return err
|
||||||
var meta tableMetadataInternal
|
|
||||||
if err := json.Unmarshal(data, &meta); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
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 {
|
|
||||||
var meta tableBucketMetadata
|
|
||||||
if err := json.Unmarshal(data, &meta); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
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
|
// Fetch bucket policy if we have a bucket name
|
||||||
@@ -747,30 +737,9 @@ func (h *S3TablesHandler) handleUntagResource(w http.ResponseWriter, r *http.Req
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var ownerAccountID string
|
ownerAccountID, bucketName, err := h.extractResourceOwnerAndBucket(data, resourcePath, rType)
|
||||||
var bucketName string
|
if err != nil {
|
||||||
if rType == ResourceTypeTable {
|
return err
|
||||||
var meta tableMetadataInternal
|
|
||||||
if err := json.Unmarshal(data, &meta); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
ownerAccountID = meta.OwnerAccountID
|
|
||||||
// Extract bucket name from resource path for tables
|
|
||||||
parts := strings.Split(strings.Trim(resourcePath, "/"), "/")
|
|
||||||
if len(parts) >= 2 {
|
|
||||||
bucketName = parts[1]
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
var meta tableBucketMetadata
|
|
||||||
if err := json.Unmarshal(data, &meta); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
ownerAccountID = meta.OwnerAccountID
|
|
||||||
// Extract bucket name from resource path for buckets
|
|
||||||
parts := strings.Split(strings.Trim(resourcePath, "/"), "/")
|
|
||||||
if len(parts) >= 2 {
|
|
||||||
bucketName = parts[1]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch bucket policy if we have a bucket name
|
// Fetch bucket policy if we have a bucket name
|
||||||
|
|||||||
Reference in New Issue
Block a user