mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-08-19 05:36:58 +00:00
unique bucket name
This commit is contained in:
@@ -10,7 +10,8 @@
|
||||
"name": "test-oidc",
|
||||
"type": "mock",
|
||||
"config": {
|
||||
"issuer": "test-oidc-issuer"
|
||||
"issuer": "test-oidc-issuer",
|
||||
"clientId": "test-oidc-client"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -18,11 +19,11 @@
|
||||
"type": "oidc",
|
||||
"enabled": true,
|
||||
"config": {
|
||||
"issuer": "http://localhost:8090/realms/seaweedfs-test",
|
||||
"issuer": "http://localhost:8080/realms/seaweedfs-test",
|
||||
"clientId": "seaweedfs-s3",
|
||||
"clientSecret": "seaweedfs-s3-secret",
|
||||
"jwksUri": "http://localhost:8090/realms/seaweedfs-test/protocol/openid-connect/certs",
|
||||
"userInfoUri": "http://localhost:8090/realms/seaweedfs-test/protocol/openid-connect/userinfo",
|
||||
"jwksUri": "http://localhost:8080/realms/seaweedfs-test/protocol/openid-connect/certs",
|
||||
"userInfoUri": "http://localhost:8080/realms/seaweedfs-test/protocol/openid-connect/userinfo",
|
||||
"scopes": ["openid", "profile", "email"],
|
||||
"claimsMapping": {
|
||||
"username": "preferred_username",
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
@@ -17,6 +18,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
"github.com/aws/aws-sdk-go/service/s3"
|
||||
@@ -612,6 +614,19 @@ func (f *S3IAMTestFramework) ExpireSessionForTesting(sessionToken string) error
|
||||
return nil
|
||||
}
|
||||
|
||||
// GenerateUniqueBucketName generates a unique bucket name for testing
|
||||
func (f *S3IAMTestFramework) GenerateUniqueBucketName(prefix string) string {
|
||||
// Use test name and timestamp to ensure uniqueness
|
||||
testName := strings.ToLower(f.t.Name())
|
||||
testName = strings.ReplaceAll(testName, "/", "-")
|
||||
testName = strings.ReplaceAll(testName, "_", "-")
|
||||
|
||||
// Add random suffix to handle parallel tests
|
||||
randomSuffix := rand.Intn(10000)
|
||||
|
||||
return fmt.Sprintf("%s-%s-%d", prefix, testName, randomSuffix)
|
||||
}
|
||||
|
||||
// CreateBucket creates a bucket and tracks it for cleanup
|
||||
func (f *S3IAMTestFramework) CreateBucket(s3Client *s3.S3, bucketName string) error {
|
||||
_, err := s3Client.CreateBucket(&s3.CreateBucketInput{
|
||||
@@ -626,6 +641,51 @@ func (f *S3IAMTestFramework) CreateBucket(s3Client *s3.S3, bucketName string) er
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreateBucketWithCleanup creates a bucket, cleaning up any existing bucket first
|
||||
func (f *S3IAMTestFramework) CreateBucketWithCleanup(s3Client *s3.S3, bucketName string) error {
|
||||
// First try to create the bucket normally
|
||||
_, err := s3Client.CreateBucket(&s3.CreateBucketInput{
|
||||
Bucket: aws.String(bucketName),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
// If bucket already exists, clean it up first
|
||||
if awsErr, ok := err.(awserr.Error); ok && awsErr.Code() == "BucketAlreadyExists" {
|
||||
f.t.Logf("Bucket %s already exists, cleaning up first", bucketName)
|
||||
|
||||
// Empty the existing bucket
|
||||
f.emptyBucket(s3Client, bucketName)
|
||||
|
||||
// Don't need to recreate - bucket already exists and is now empty
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Track bucket for cleanup
|
||||
f.createdBuckets = append(f.createdBuckets, bucketName)
|
||||
return nil
|
||||
}
|
||||
|
||||
// emptyBucket removes all objects from a bucket
|
||||
func (f *S3IAMTestFramework) emptyBucket(s3Client *s3.S3, bucketName string) {
|
||||
// Delete all objects
|
||||
listResult, err := s3Client.ListObjects(&s3.ListObjectsInput{
|
||||
Bucket: aws.String(bucketName),
|
||||
})
|
||||
if err == nil {
|
||||
for _, obj := range listResult.Contents {
|
||||
_, err := s3Client.DeleteObject(&s3.DeleteObjectInput{
|
||||
Bucket: aws.String(bucketName),
|
||||
Key: obj.Key,
|
||||
})
|
||||
if err != nil {
|
||||
f.t.Logf("Warning: Failed to delete object %s/%s: %v", bucketName, *obj.Key, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Cleanup cleans up test resources
|
||||
func (f *S3IAMTestFramework) Cleanup() {
|
||||
// Clean up buckets (best effort)
|
||||
|
||||
@@ -15,11 +15,11 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
testEndpoint = "http://localhost:8333"
|
||||
testRegion = "us-west-2"
|
||||
testBucket = "test-iam-bucket"
|
||||
testObjectKey = "test-object.txt"
|
||||
testObjectData = "Hello, SeaweedFS IAM Integration!"
|
||||
testEndpoint = "http://localhost:8333"
|
||||
testRegion = "us-west-2"
|
||||
testBucketPrefix = "test-iam-bucket"
|
||||
testObjectKey = "test-object.txt"
|
||||
testObjectData = "Hello, SeaweedFS IAM Integration!"
|
||||
)
|
||||
|
||||
// TestS3IAMAuthentication tests S3 API authentication with IAM JWT tokens
|
||||
@@ -176,33 +176,22 @@ func TestS3IAMPolicyEnforcement(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
// Should NOT be able to read objects
|
||||
// TODO: Fix IAM policy evaluation system - explicit deny statements are not being enforced
|
||||
// This is a known issue where the policy engine allows read operations despite explicit deny
|
||||
_, err = writeOnlyClient.GetObject(&s3.GetObjectInput{
|
||||
Bucket: aws.String(testBucket),
|
||||
Key: aws.String(testObjectKey),
|
||||
})
|
||||
if err == nil {
|
||||
t.Skip("KNOWN ISSUE: IAM policy evaluation system does not properly enforce explicit deny statements for write-only roles")
|
||||
} else {
|
||||
// If the error is properly returned, verify it's AccessDenied
|
||||
if awsErr, ok := err.(awserr.Error); ok {
|
||||
assert.Equal(t, "AccessDenied", awsErr.Code())
|
||||
}
|
||||
require.Error(t, err)
|
||||
if awsErr, ok := err.(awserr.Error); ok {
|
||||
assert.Equal(t, "AccessDenied", awsErr.Code())
|
||||
}
|
||||
|
||||
// Should NOT be able to list objects
|
||||
// TODO: Same IAM policy evaluation issue as above
|
||||
_, err = writeOnlyClient.ListObjects(&s3.ListObjectsInput{
|
||||
Bucket: aws.String(testBucket),
|
||||
})
|
||||
if err == nil {
|
||||
t.Skip("KNOWN ISSUE: IAM policy evaluation system does not properly enforce explicit deny statements for list operations")
|
||||
} else {
|
||||
// If the error is properly returned, verify it's AccessDenied
|
||||
if awsErr, ok := err.(awserr.Error); ok {
|
||||
assert.Equal(t, "AccessDenied", awsErr.Code())
|
||||
}
|
||||
require.Error(t, err)
|
||||
if awsErr, ok := err.(awserr.Error); ok {
|
||||
assert.Equal(t, "AccessDenied", awsErr.Code())
|
||||
}
|
||||
})
|
||||
|
||||
@@ -547,12 +536,13 @@ func TestS3IAMPresignedURLIntegration(t *testing.T) {
|
||||
adminClient, err := framework.CreateS3ClientWithJWT("admin-user", "TestAdminRole")
|
||||
require.NoError(t, err)
|
||||
|
||||
err = framework.CreateBucket(adminClient, testBucket)
|
||||
// Use static bucket name but with cleanup to handle conflicts
|
||||
err = framework.CreateBucketWithCleanup(adminClient, testBucketPrefix)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Put test object
|
||||
_, err = adminClient.PutObject(&s3.PutObjectInput{
|
||||
Bucket: aws.String(testBucket),
|
||||
Bucket: aws.String(testBucketPrefix),
|
||||
Key: aws.String(testObjectKey),
|
||||
Body: strings.NewReader(testObjectData),
|
||||
})
|
||||
@@ -565,7 +555,7 @@ func TestS3IAMPresignedURLIntegration(t *testing.T) {
|
||||
|
||||
// Test direct object access with JWT token (which is what JWT authentication supports)
|
||||
_, err := adminClient.GetObject(&s3.GetObjectInput{
|
||||
Bucket: aws.String(testBucket),
|
||||
Bucket: aws.String(testBucketPrefix),
|
||||
Key: aws.String(testObjectKey),
|
||||
})
|
||||
require.NoError(t, err, "Direct object access with JWT should work")
|
||||
|
||||
Reference in New Issue
Block a user