mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-09-20 06:54:24 +00:00
s3: separate Object Lock configuration permission (#11361)
* s3: separate object lock configuration permission * test: synchronize manifest cancellation setup
This commit is contained in:
@@ -402,6 +402,11 @@ func TestResolveChunkManifestKeepsRealErrorAfterInternalCancellation(t *testing.
|
||||
<-ctx.Done()
|
||||
return nil, earlyErr
|
||||
case "late":
|
||||
// The assertion is specifically about preserving the earlier input's
|
||||
// real error after a later input cancels the batch. Do not let the
|
||||
// later lookup cancel the batch before the earlier lookup has entered;
|
||||
// that scheduling race is especially visible on slower 32-bit CI.
|
||||
<-earlyStarted
|
||||
close(lateStarted)
|
||||
return nil, lateErr
|
||||
default:
|
||||
|
||||
+3
-1
@@ -137,7 +137,7 @@ var baseS3ActionMap = map[string]string{
|
||||
"GetBucketNotification": s3_constants.ACTION_READ,
|
||||
"PutBucketNotification": s3_constants.ACTION_WRITE,
|
||||
"GetBucketObjectLockConfiguration": s3_constants.ACTION_READ,
|
||||
"PutBucketObjectLockConfiguration": s3_constants.ACTION_WRITE,
|
||||
"PutBucketObjectLockConfiguration": s3_constants.ACTION_PUT_BUCKET_OBJECT_LOCK_CONFIG,
|
||||
// Multipart upload operations
|
||||
"CreateMultipartUpload": s3_constants.ACTION_WRITE,
|
||||
"UploadPart": s3_constants.ACTION_WRITE,
|
||||
@@ -191,6 +191,8 @@ func MapToIdentitiesAction(action string) string {
|
||||
return StatementActionTagging
|
||||
case s3_constants.ACTION_DELETE_BUCKET:
|
||||
return StatementActionDelete
|
||||
case s3_constants.ACTION_PUT_BUCKET_OBJECT_LOCK_CONFIG:
|
||||
return "PutBucketObjectLockConfiguration"
|
||||
case s3_constants.ACTION_PUT_BUCKET_POLICY:
|
||||
return "PutBucketPolicy"
|
||||
case s3_constants.ACTION_DELETE_BUCKET_POLICY:
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
package s3api
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
iamlib "github.com/seaweedfs/seaweedfs/weed/iam"
|
||||
"github.com/seaweedfs/seaweedfs/weed/s3api/s3_constants"
|
||||
)
|
||||
|
||||
func TestPutObjectLockConfigurationUsesDedicatedAction(t *testing.T) {
|
||||
bindings := handlerActionBindings(t)
|
||||
if got := bindings["PutObjectLockConfigurationHandler"]; got != "ACTION_PUT_BUCKET_OBJECT_LOCK_CONFIG" {
|
||||
t.Fatalf("PutObjectLockConfigurationHandler is gated on %s, want ACTION_PUT_BUCKET_OBJECT_LOCK_CONFIG", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestObjectWriteDoesNotAllowPutObjectLockConfiguration(t *testing.T) {
|
||||
objectWriter := &Identity{
|
||||
Name: "object-writer",
|
||||
Actions: []Action{Action(s3_constants.ACTION_WRITE + ":test-bucket")},
|
||||
}
|
||||
|
||||
if !objectWriter.CanDo(s3_constants.ACTION_WRITE, "test-bucket", "some/key") {
|
||||
t.Fatal("precondition failed: the identity should be able to write objects")
|
||||
}
|
||||
if objectWriter.CanDo(s3_constants.ACTION_PUT_BUCKET_OBJECT_LOCK_CONFIG, "test-bucket", "") {
|
||||
t.Fatal("an object writer was allowed to change the bucket Object Lock configuration")
|
||||
}
|
||||
|
||||
lockManager := &Identity{
|
||||
Name: "lock-manager",
|
||||
Actions: []Action{
|
||||
Action(s3_constants.ACTION_PUT_BUCKET_OBJECT_LOCK_CONFIG + ":test-bucket"),
|
||||
},
|
||||
}
|
||||
if !lockManager.CanDo(s3_constants.ACTION_PUT_BUCKET_OBJECT_LOCK_CONFIG, "test-bucket", "") {
|
||||
t.Fatal("an explicitly delegated identity was denied permission to change the bucket Object Lock configuration")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPutObjectLockConfigurationActionRoundTrips(t *testing.T) {
|
||||
for _, policyAction := range []string{
|
||||
"s3:PutBucketObjectLockConfiguration",
|
||||
"PutBucketObjectLockConfiguration",
|
||||
} {
|
||||
if got := iamlib.MapToStatementAction(policyAction); got != s3_constants.ACTION_PUT_BUCKET_OBJECT_LOCK_CONFIG {
|
||||
t.Errorf("MapToStatementAction(%q) = %q, want %q", policyAction, got, s3_constants.ACTION_PUT_BUCKET_OBJECT_LOCK_CONFIG)
|
||||
}
|
||||
}
|
||||
|
||||
if got := iamlib.MapToIdentitiesAction(s3_constants.ACTION_PUT_BUCKET_OBJECT_LOCK_CONFIG); got != "PutBucketObjectLockConfiguration" {
|
||||
t.Errorf("MapToIdentitiesAction(%q) = %q, want PutBucketObjectLockConfiguration", s3_constants.ACTION_PUT_BUCKET_OBJECT_LOCK_CONFIG, got)
|
||||
}
|
||||
if got := mapBaseActionToS3Format(s3_constants.ACTION_PUT_BUCKET_OBJECT_LOCK_CONFIG); got != s3_constants.S3_ACTION_PUT_BUCKET_OBJECT_LOCK {
|
||||
t.Errorf("mapBaseActionToS3Format(%q) = %q, want %q", s3_constants.ACTION_PUT_BUCKET_OBJECT_LOCK_CONFIG, got, s3_constants.S3_ACTION_PUT_BUCKET_OBJECT_LOCK)
|
||||
}
|
||||
}
|
||||
@@ -965,7 +965,7 @@ func (s3a *S3ApiServer) registerRouter(router *mux.Router) {
|
||||
|
||||
// GetObjectLockConfiguration / PutObjectLockConfiguration (bucket-level operations)
|
||||
bucket.Methods(http.MethodGet).HandlerFunc(track(s3a.iam.Auth(s3a.cb.Limit(s3a.GetObjectLockConfigurationHandler, ACTION_READ)), "GET")).Queries("object-lock", "")
|
||||
bucket.Methods(http.MethodPut).HandlerFunc(track(s3a.iam.Auth(s3a.cb.Limit(s3a.PutObjectLockConfigurationHandler, ACTION_WRITE)), "PUT")).Queries("object-lock", "")
|
||||
bucket.Methods(http.MethodPut).HandlerFunc(track(s3a.iam.Auth(s3a.cb.Limit(s3a.PutObjectLockConfigurationHandler, ACTION_PUT_BUCKET_OBJECT_LOCK_CONFIG)), "PUT")).Queries("object-lock", "")
|
||||
|
||||
// GetBucketTagging
|
||||
bucket.Methods(http.MethodGet).HandlerFunc(track(s3a.iam.Auth(s3a.cb.Limit(s3a.GetBucketTaggingHandler, ACTION_TAGGING)), "GET")).Queries("tagging", "")
|
||||
|
||||
Reference in New Issue
Block a user