diff options
| -rw-r--r-- | weed/s3api/policy_engine/conditions.go | 65 | ||||
| -rw-r--r-- | weed/s3api/s3api_object_handlers.go | 24 |
2 files changed, 45 insertions, 44 deletions
diff --git a/weed/s3api/policy_engine/conditions.go b/weed/s3api/policy_engine/conditions.go index ffbae51e6..466130a0a 100644 --- a/weed/s3api/policy_engine/conditions.go +++ b/weed/s3api/policy_engine/conditions.go @@ -709,6 +709,27 @@ func GetConditionEvaluator(operator string) (ConditionEvaluator, error) { // ExistingObjectTagPrefix is the prefix for S3 policy condition keys const ExistingObjectTagPrefix = "s3:ExistingObjectTag/" +// getConditionContextValue resolves the value(s) for a condition key. +// For s3:ExistingObjectTag/<key> conditions, it looks up the tag in objectEntry. +// For other condition keys, it looks up the value in contextValues. +func getConditionContextValue(key string, contextValues map[string][]string, objectEntry map[string][]byte) []string { + if strings.HasPrefix(key, ExistingObjectTagPrefix) { + tagKey := key[len(ExistingObjectTagPrefix):] + metadataKey := s3_constants.AmzObjectTaggingPrefix + tagKey + if objectEntry != nil { + if tagValue, exists := objectEntry[metadataKey]; exists { + return []string{string(tagValue)} + } + } + return []string{} + } + + if vals, exists := contextValues[key]; exists { + return vals + } + return []string{} +} + // EvaluateConditions evaluates all conditions in a policy statement // objectEntry is the object's metadata from entry.Extended (can be nil) func EvaluateConditions(conditions PolicyConditions, contextValues map[string][]string, objectEntry map[string][]byte) bool { @@ -724,29 +745,7 @@ func EvaluateConditions(conditions PolicyConditions, contextValues map[string][] } for key, value := range conditionMap { - var contextVals []string - - // Handle s3:ExistingObjectTag/<tag-key> condition keys - // These refer to tags that already exist on the object - if strings.HasPrefix(key, ExistingObjectTagPrefix) { - // Extract tag value from entry.Extended using the tag prefix - tagKey := key[len(ExistingObjectTagPrefix):] - metadataKey := s3_constants.AmzObjectTaggingPrefix + tagKey - if objectEntry != nil { - if tagValue, exists := objectEntry[metadataKey]; exists { - contextVals = []string{string(tagValue)} - } - } - // If tag doesn't exist, contextVals remains empty - } else { - // Regular condition key lookup - var exists bool - contextVals, exists = contextValues[key] - if !exists { - contextVals = []string{} - } - } - + contextVals := getConditionContextValue(key, contextValues, objectEntry) if !conditionEvaluator.Evaluate(value.Strings(), contextVals) { return false // If any condition fails, the whole condition block fails } @@ -777,25 +776,7 @@ func EvaluateConditionsLegacy(conditions map[string]interface{}, contextValues m } for key, value := range conditionMapTyped { - var contextVals []string - - // Handle s3:ExistingObjectTag/<tag-key> condition keys - if strings.HasPrefix(key, ExistingObjectTagPrefix) { - tagKey := key[len(ExistingObjectTagPrefix):] - metadataKey := s3_constants.AmzObjectTaggingPrefix + tagKey - if objectEntry != nil { - if tagValue, exists := objectEntry[metadataKey]; exists { - contextVals = []string{string(tagValue)} - } - } - } else { - var exists bool - contextVals, exists = contextValues[key] - if !exists { - contextVals = []string{} - } - } - + contextVals := getConditionContextValue(key, contextValues, objectEntry) if !conditionEvaluator.Evaluate(value, contextVals) { return false // If any condition fails, the whole condition block fails } diff --git a/weed/s3api/s3api_object_handlers.go b/weed/s3api/s3api_object_handlers.go index 034710c3c..e9145aca0 100644 --- a/weed/s3api/s3api_object_handlers.go +++ b/weed/s3api/s3api_object_handlers.go @@ -636,7 +636,17 @@ func (s3a *S3ApiServer) GetObjectHandler(w http.ResponseWriter, r *http.Request) // Re-check bucket policy with object entry for tag-based conditions (e.g., s3:ExistingObjectTag) if objectEntryForSSE != nil { - identity, _ := s3_constants.GetIdentityFromContext(r).(*Identity) + identityRaw := s3_constants.GetIdentityFromContext(r) + var identity *Identity + if identityRaw != nil { + var ok bool + identity, ok = identityRaw.(*Identity) + if !ok { + glog.Errorf("GetObjectHandler: unexpected identity type in context for %s/%s", bucket, object) + s3err.WriteErrorResponse(w, r, s3err.ErrInternalError) + return + } + } principal := buildPrincipalARN(identity) if errCode, _ := s3a.checkPolicyWithEntry(r, bucket, object, string(s3_constants.ACTION_READ), principal, objectEntryForSSE.Extended); errCode != s3err.ErrNone { s3err.WriteErrorResponse(w, r, errCode) @@ -2198,7 +2208,17 @@ func (s3a *S3ApiServer) HeadObjectHandler(w http.ResponseWriter, r *http.Request } // Re-check bucket policy with object entry for tag-based conditions (e.g., s3:ExistingObjectTag) - identity, _ := s3_constants.GetIdentityFromContext(r).(*Identity) + identityRaw := s3_constants.GetIdentityFromContext(r) + var identity *Identity + if identityRaw != nil { + var ok bool + identity, ok = identityRaw.(*Identity) + if !ok { + glog.Errorf("HeadObjectHandler: unexpected identity type in context for %s/%s", bucket, object) + s3err.WriteErrorResponse(w, r, s3err.ErrInternalError) + return + } + } principal := buildPrincipalARN(identity) if errCode, _ := s3a.checkPolicyWithEntry(r, bucket, object, string(s3_constants.ACTION_READ), principal, objectEntryForSSE.Extended); errCode != s3err.ErrNone { s3err.WriteErrorResponse(w, r, errCode) |
