Refactor data structure (#7472)

* refactor to avoids circular dependency

* converts a policy.PolicyDocument to policy_engine.PolicyDocument

* convert numeric types to strings

* Update weed/s3api/policy_conversion.go

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

* refactoring

* not skipping numeric and boolean values in arrays

* avoid nil

* edge cases

* handling conversion failure

The handling of unsupported types in convertToString could lead to silent policy alterations.
The conversion of map-based principals in convertPrincipal is too generic and could misinterpret policies.

* concise

* fix doc

* adjust warning

* recursion

* return errors

* reject empty principals

* better error message

---------

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
This commit is contained in:
Chris Lu
2025-11-12 23:46:52 -08:00
committed by GitHub
parent 508d06d9a5
commit 2a9d4d1e23
5 changed files with 877 additions and 19 deletions

View File

@@ -49,11 +49,8 @@ func (bpe *BucketPolicyEngine) LoadBucketPolicy(bucket string, entry *filer_pb.E
// LoadBucketPolicyFromCache loads a bucket policy from a cached BucketConfig
//
// NOTE: This function uses JSON marshaling/unmarshaling to convert between
// policy.PolicyDocument and policy_engine.PolicyDocument. This is inefficient
// but necessary because the two types are defined in different packages and
// have subtle differences. A future improvement would be to unify these types
// or create a direct conversion function for better performance and type safety.
// This function uses a type-safe conversion function to convert between
// policy.PolicyDocument and policy_engine.PolicyDocument with explicit field mapping and error handling.
func (bpe *BucketPolicyEngine) LoadBucketPolicyFromCache(bucket string, policyDoc *policy.PolicyDocument) error {
if policyDoc == nil {
// No policy for this bucket - remove it if it exists
@@ -61,10 +58,16 @@ func (bpe *BucketPolicyEngine) LoadBucketPolicyFromCache(bucket string, policyDo
return nil
}
// Convert policy.PolicyDocument to policy_engine.PolicyDocument
// We use JSON marshaling as an intermediate format since both types
// follow the same AWS S3 policy structure
policyJSON, err := json.Marshal(policyDoc)
// Convert policy.PolicyDocument to policy_engine.PolicyDocument using direct conversion
// This is more efficient than JSON marshaling and provides better type safety
enginePolicyDoc, err := ConvertPolicyDocumentToPolicyEngine(policyDoc)
if err != nil {
glog.Errorf("Failed to convert bucket policy for %s: %v", bucket, err)
return fmt.Errorf("failed to convert bucket policy: %w", err)
}
// Marshal the converted policy to JSON for storage in the engine
policyJSON, err := json.Marshal(enginePolicyDoc)
if err != nil {
glog.Errorf("Failed to marshal bucket policy for %s: %v", bucket, err)
return err