From 2700197eb24b82e423c29cf21faf13cddb4f20f9 Mon Sep 17 00:00:00 2001 From: chrislu Date: Sat, 12 Jul 2025 11:24:06 -0700 Subject: [PATCH] rename to ExtObjectLockModeKey --- weed/s3api/s3_constants/extend_key.go | 2 +- weed/s3api/s3api_object_retention.go | 131 +------------------------- 2 files changed, 4 insertions(+), 129 deletions(-) diff --git a/weed/s3api/s3_constants/extend_key.go b/weed/s3api/s3_constants/extend_key.go index 9df6dbeba..79fcbb239 100644 --- a/weed/s3api/s3_constants/extend_key.go +++ b/weed/s3api/s3_constants/extend_key.go @@ -13,7 +13,7 @@ const ( ExtLatestVersionFileNameKey = "Seaweed-X-Amz-Latest-Version-File-Name" // Object Retention and Legal Hold - ExtRetentionModeKey = "Seaweed-X-Amz-Retention-Mode" + ExtObjectLockModeKey = "Seaweed-X-Amz-Object-Lock-Mode" ExtRetentionUntilDateKey = "Seaweed-X-Amz-Retention-Until-Date" ExtLegalHoldKey = "Seaweed-X-Amz-Legal-Hold" ExtObjectLockEnabledKey = "Seaweed-X-Amz-Object-Lock-Enabled" diff --git a/weed/s3api/s3api_object_retention.go b/weed/s3api/s3api_object_retention.go index fa06732ee..b23806c35 100644 --- a/weed/s3api/s3api_object_retention.go +++ b/weed/s3api/s3api_object_retention.go @@ -48,24 +48,6 @@ type DefaultRetention struct { Years int `xml:"Years,omitempty"` } -// Custom time marshalling for AWS S3 ISO8601 format -func (or *ObjectRetention) MarshalXML(e *xml.Encoder, start xml.StartElement) error { - type Alias ObjectRetention - aux := &struct { - *Alias - RetainUntilDate *string `xml:"RetainUntilDate,omitempty"` - }{ - Alias: (*Alias)(or), - } - - if or.RetainUntilDate != nil { - dateStr := or.RetainUntilDate.UTC().Format(time.RFC3339) - aux.RetainUntilDate = &dateStr - } - - return e.EncodeElement(aux, start) -} - // Custom time unmarshalling for AWS S3 ISO8601 format func (or *ObjectRetention) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { type Alias ObjectRetention @@ -199,7 +181,7 @@ func (s3a *S3ApiServer) getObjectRetention(bucket, object, versionId string) (*O retention := &ObjectRetention{} - if modeBytes, exists := entry.Extended[s3_constants.ExtRetentionModeKey]; exists { + if modeBytes, exists := entry.Extended[s3_constants.ExtObjectLockModeKey]; exists { retention.Mode = string(modeBytes) } @@ -261,7 +243,7 @@ func (s3a *S3ApiServer) setObjectRetention(bucket, object, versionId string, ret // Check if object is already under retention if entry.Extended != nil { - if existingMode, exists := entry.Extended[s3_constants.ExtRetentionModeKey]; exists { + if existingMode, exists := entry.Extended[s3_constants.ExtObjectLockModeKey]; exists { if string(existingMode) == s3_constants.RetentionModeCompliance && !bypassGovernance { return fmt.Errorf("cannot modify retention on object under COMPLIANCE mode") } @@ -283,7 +265,7 @@ func (s3a *S3ApiServer) setObjectRetention(bucket, object, versionId string, ret } if retention.Mode != "" { - entry.Extended[s3_constants.ExtRetentionModeKey] = []byte(retention.Mode) + entry.Extended[s3_constants.ExtObjectLockModeKey] = []byte(retention.Mode) } if retention.RetainUntilDate != nil { @@ -464,112 +446,5 @@ func (s3a *S3ApiServer) checkObjectLockPermissions(bucket, object, versionId str } } - // Check existing WORM enforcement for compatibility - if err := s3a.checkLegacyWormEnforcement(bucket, object, versionId, bypassGovernance); err != nil { - return err - } - - return nil -} - -// checkLegacyWormEnforcement checks the existing WORM infrastructure for compatibility -func (s3a *S3ApiServer) checkLegacyWormEnforcement(bucket, object, versionId string, bypassGovernance bool) error { - var entry *filer_pb.Entry - var err error - - if versionId != "" { - entry, err = s3a.getSpecificObjectVersion(bucket, object, versionId) - } else { - // Check if versioning is enabled - versioningEnabled, vErr := s3a.isVersioningEnabled(bucket) - if vErr != nil { - // If we can't check versioning, skip WORM check to avoid false positives - return nil - } - - if versioningEnabled { - entry, err = s3a.getLatestObjectVersion(bucket, object) - } else { - bucketDir := s3a.option.BucketsPath + "/" + bucket - entry, err = s3a.getEntry(bucketDir, object) - } - } - - if err != nil { - // If object doesn't exist, no WORM enforcement applies - return nil - } - - // Check if legacy WORM is enforced - if entry.WormEnforcedAtTsNs == 0 { - return nil - } - - // Check if this is under legacy WORM enforcement - // For compatibility, we treat legacy WORM similar to GOVERNANCE mode - // (can be bypassed with appropriate permissions) - if !bypassGovernance { - return fmt.Errorf("object is under legacy WORM enforcement and cannot be deleted or modified without bypass") - } - return nil } - -// isObjectWormProtected checks both S3 retention and legacy WORM for complete protection status -func (s3a *S3ApiServer) isObjectWormProtected(bucket, object, versionId string) (bool, error) { - // Check S3 object retention - retentionActive, err := s3a.isObjectRetentionActive(bucket, object, versionId) - if err != nil { - glog.V(4).Infof("Error checking S3 retention for %s/%s: %v", bucket, object, err) - } - - // Check S3 legal hold - legalHoldActive, err := s3a.isObjectLegalHoldActive(bucket, object, versionId) - if err != nil { - glog.V(4).Infof("Error checking S3 legal hold for %s/%s: %v", bucket, object, err) - } - - // Check legacy WORM enforcement - legacyWormActive, err := s3a.isLegacyWormActive(bucket, object, versionId) - if err != nil { - glog.V(4).Infof("Error checking legacy WORM for %s/%s: %v", bucket, object, err) - } - - return retentionActive || legalHoldActive || legacyWormActive, nil -} - -// isLegacyWormActive checks if an object is under legacy WORM enforcement -func (s3a *S3ApiServer) isLegacyWormActive(bucket, object, versionId string) (bool, error) { - var entry *filer_pb.Entry - var err error - - if versionId != "" { - entry, err = s3a.getSpecificObjectVersion(bucket, object, versionId) - } else { - // Check if versioning is enabled - versioningEnabled, vErr := s3a.isVersioningEnabled(bucket) - if vErr != nil { - return false, nil - } - - if versioningEnabled { - entry, err = s3a.getLatestObjectVersion(bucket, object) - } else { - bucketDir := s3a.option.BucketsPath + "/" + bucket - entry, err = s3a.getEntry(bucketDir, object) - } - } - - if err != nil { - return false, nil - } - - // Check if legacy WORM is enforced and still active - if entry.WormEnforcedAtTsNs == 0 { - return false, nil - } - - // For now, we consider legacy WORM as always active when set - // The original WORM system should handle time-based expiration - return true, nil -}