mirror of
https://github.com/chrislusf/seaweedfs
synced 2025-07-25 21:12:47 +02:00
* fix object locking read and write No logic to include object lock metadata in HEAD/GET response headers No logic to extract object lock metadata from PUT request headers * add tests for object locking * Update weed/s3api/s3api_object_handlers_put.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update weed/s3api/s3api_object_handlers.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * refactor * add unit tests * sync versions * Update s3_worm_integration_test.go * fix legal hold values * lint * fix tests * racing condition when enable versioning * fix tests * validate put object lock header * allow check lock permissions for PUT * default to OFF legal hold * only set object lock headers for objects that are actually from object lock-enabled buckets fix --- FAIL: TestAddObjectLockHeadersToResponse/Handle_entry_with_no_object_lock_metadata (0.00s) * address comments * fix tests * purge * fix * refactoring * address comment * address comment * Update weed/s3api/s3api_object_handlers_put.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update weed/s3api/s3api_object_handlers_put.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update weed/s3api/s3api_object_handlers.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * avoid nil * ensure locked objects cannot be overwritten --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
114 lines
4.2 KiB
Go
114 lines
4.2 KiB
Go
package retention
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/aws/aws-sdk-go-v2/aws"
|
|
"github.com/aws/aws-sdk-go-v2/service/s3"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// TestReproduceObjectLockIssue reproduces the Object Lock header processing issue step by step
|
|
func TestReproduceObjectLockIssue(t *testing.T) {
|
|
client := getS3Client(t)
|
|
bucketName := fmt.Sprintf("object-lock-test-%d", time.Now().UnixNano())
|
|
|
|
t.Logf("=== Reproducing Object Lock Header Processing Issue ===")
|
|
t.Logf("Bucket name: %s", bucketName)
|
|
|
|
// Step 1: Create bucket with Object Lock enabled header
|
|
t.Logf("\n1. Creating bucket with ObjectLockEnabledForBucket=true")
|
|
t.Logf(" This should send x-amz-bucket-object-lock-enabled: true header")
|
|
|
|
createResp, err := client.CreateBucket(context.TODO(), &s3.CreateBucketInput{
|
|
Bucket: aws.String(bucketName),
|
|
ObjectLockEnabledForBucket: aws.Bool(true), // This sets the x-amz-bucket-object-lock-enabled header
|
|
})
|
|
|
|
if err != nil {
|
|
t.Fatalf("Bucket creation failed: %v", err)
|
|
}
|
|
t.Logf("✅ Bucket created successfully")
|
|
t.Logf(" Response: %+v", createResp)
|
|
|
|
// Step 2: Check if Object Lock is actually enabled
|
|
t.Logf("\n2. Checking Object Lock configuration to verify it was enabled")
|
|
|
|
objectLockResp, err := client.GetObjectLockConfiguration(context.TODO(), &s3.GetObjectLockConfigurationInput{
|
|
Bucket: aws.String(bucketName),
|
|
})
|
|
|
|
if err != nil {
|
|
t.Logf("❌ GetObjectLockConfiguration FAILED: %v", err)
|
|
t.Logf(" This demonstrates the issue with header processing!")
|
|
t.Logf(" S3 clients expect this call to succeed if Object Lock is supported")
|
|
t.Logf(" When this fails, clients conclude that Object Lock is not supported")
|
|
|
|
// This failure demonstrates the bug - the bucket was created but Object Lock wasn't enabled
|
|
t.Logf("\n🐛 BUG CONFIRMED:")
|
|
t.Logf(" - Bucket creation with ObjectLockEnabledForBucket=true succeeded")
|
|
t.Logf(" - But GetObjectLockConfiguration fails")
|
|
t.Logf(" - This means the x-amz-bucket-object-lock-enabled header was ignored")
|
|
|
|
} else {
|
|
t.Logf("✅ GetObjectLockConfiguration succeeded!")
|
|
t.Logf(" Response: %+v", objectLockResp)
|
|
t.Logf(" Object Lock is properly enabled - this is the expected behavior")
|
|
}
|
|
|
|
// Step 3: Check versioning status (required for Object Lock)
|
|
t.Logf("\n3. Checking bucket versioning status (required for Object Lock)")
|
|
|
|
versioningResp, err := client.GetBucketVersioning(context.TODO(), &s3.GetBucketVersioningInput{
|
|
Bucket: aws.String(bucketName),
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
t.Logf(" Versioning status: %v", versioningResp.Status)
|
|
if versioningResp.Status != "Enabled" {
|
|
t.Logf(" ⚠️ Versioning should be automatically enabled when Object Lock is enabled")
|
|
}
|
|
|
|
// Cleanup
|
|
t.Logf("\n4. Cleaning up test bucket")
|
|
_, err = client.DeleteBucket(context.TODO(), &s3.DeleteBucketInput{
|
|
Bucket: aws.String(bucketName),
|
|
})
|
|
if err != nil {
|
|
t.Logf(" Warning: Failed to delete bucket: %v", err)
|
|
}
|
|
|
|
t.Logf("\n=== Issue Reproduction Complete ===")
|
|
t.Logf("Expected behavior after fix:")
|
|
t.Logf(" - CreateBucket with ObjectLockEnabledForBucket=true should enable Object Lock")
|
|
t.Logf(" - GetObjectLockConfiguration should return enabled configuration")
|
|
t.Logf(" - Versioning should be automatically enabled")
|
|
}
|
|
|
|
// TestNormalBucketCreationStillWorks tests that normal bucket creation still works
|
|
func TestNormalBucketCreationStillWorks(t *testing.T) {
|
|
client := getS3Client(t)
|
|
bucketName := fmt.Sprintf("normal-test-%d", time.Now().UnixNano())
|
|
|
|
t.Logf("=== Testing Normal Bucket Creation ===")
|
|
|
|
// Create bucket without Object Lock
|
|
_, err := client.CreateBucket(context.TODO(), &s3.CreateBucketInput{
|
|
Bucket: aws.String(bucketName),
|
|
})
|
|
require.NoError(t, err)
|
|
t.Logf("✅ Normal bucket creation works")
|
|
|
|
// Object Lock should NOT be enabled
|
|
_, err = client.GetObjectLockConfiguration(context.TODO(), &s3.GetObjectLockConfigurationInput{
|
|
Bucket: aws.String(bucketName),
|
|
})
|
|
require.Error(t, err, "GetObjectLockConfiguration should fail for bucket without Object Lock")
|
|
t.Logf("✅ GetObjectLockConfiguration correctly fails for normal bucket")
|
|
|
|
// Cleanup
|
|
client.DeleteBucket(context.TODO(), &s3.DeleteBucketInput{Bucket: aws.String(bucketName)})
|
|
}
|