From 608fc3d09b092a2ac3bc165342fffa9cfc1cfdb4 Mon Sep 17 00:00:00 2001
From: Pavel Pogodaev
Date: Fri, 12 Apr 2024 11:59:05 +0300
Subject: [PATCH] [#365] Include iam user tags in query
Signed-off-by: Pavel Pogodaev
---
api/middleware/policy.go | 5 +-
api/router_mock_test.go | 120 ++++++++++++------------
api/router_test.go | 15 ++-
internal/frostfs/frostfsid/frostfsid.go | 11 +--
4 files changed, 75 insertions(+), 76 deletions(-)
diff --git a/api/middleware/policy.go b/api/middleware/policy.go
index c06dbc7..19fe12e 100644
--- a/api/middleware/policy.go
+++ b/api/middleware/policy.go
@@ -51,7 +51,7 @@ type PolicySettings interface {
}
type FrostFSIDInformer interface {
- GetUserGroupIDsAndTags(userHash util.Uint160) ([]string, map[string]string, error)
+ GetUserGroupIDsAndClaims(userHash util.Uint160) ([]string, map[string]string, error)
}
type XMLDecoder interface {
@@ -161,7 +161,7 @@ func getPolicyRequest(r *http.Request, cfg PolicyConfig, reqType ReqType, bktNam
}
owner = pk.Address()
- groups, err = cfg.FrostfsID.GetUserGroupIDsAndTags(pk.GetScriptHash())
+ groups, tags, err = cfg.FrostfsID.GetUserGroupIDsAndClaims(pk.GetScriptHash())
if err != nil {
return nil, fmt.Errorf("get group ids: %w", err)
}
@@ -422,7 +422,6 @@ func determineProperties(r *http.Request, decoder XMLDecoder, resolver BucketRes
res[fmt.Sprintf(common.PropertyKeyFormatFrostFSIDUserClaim, k)] = v
}
-
if reqType == objectType {
if versionID := queries.Get(QueryVersionID); len(versionID) > 0 {
res[s3.PropertyKeyVersionID] = versionID
diff --git a/api/router_mock_test.go b/api/router_mock_test.go
index a3cd948..018a7e5 100644
--- a/api/router_mock_test.go
+++ b/api/router_mock_test.go
@@ -78,17 +78,15 @@ func (r *middlewareSettingsMock) ACLEnabled() bool {
}
type frostFSIDMock struct {
+ tags map[string]string
}
func (f *frostFSIDMock) ValidatePublicKey(*keys.PublicKey) error {
return nil
}
-func (f *frostFSIDMock) GetUserGroupIDsAndTags(util.Uint160) ([]string, map[string]string, error) {
- tags := make(map[string]string)
- tags["test"] = "user"
- tags["tag-test"] = "test"
- return []string{}, tags, nil
+func (f *frostFSIDMock) GetUserGroupIDsAndClaims(util.Uint160) ([]string, map[string]string, error) {
+ return []string{}, f.tags, nil
}
type xmlMock struct {
@@ -127,47 +125,47 @@ type handlerResult struct {
}
func (h *handlerMock) HeadObjectHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
func (h *handlerMock) GetObjectACLHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
func (h *handlerMock) PutObjectACLHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
func (h *handlerMock) GetObjectTaggingHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
func (h *handlerMock) PutObjectTaggingHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
func (h *handlerMock) DeleteObjectTaggingHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
func (h *handlerMock) SelectObjectContentHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
func (h *handlerMock) GetObjectRetentionHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
func (h *handlerMock) GetObjectLegalHoldHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
@@ -181,22 +179,22 @@ func (h *handlerMock) GetObjectHandler(w http.ResponseWriter, r *http.Request) {
}
func (h *handlerMock) GetObjectAttributesHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
func (h *handlerMock) CopyObjectHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
func (h *handlerMock) PutObjectRetentionHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
func (h *handlerMock) PutObjectLegalHoldHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
@@ -210,122 +208,122 @@ func (h *handlerMock) PutObjectHandler(w http.ResponseWriter, r *http.Request) {
}
func (h *handlerMock) DeleteObjectHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
func (h *handlerMock) GetBucketLocationHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
func (h *handlerMock) GetBucketPolicyStatusHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
func (h *handlerMock) GetBucketPolicyHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
func (h *handlerMock) GetBucketLifecycleHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
func (h *handlerMock) GetBucketEncryptionHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
func (h *handlerMock) GetBucketACLHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
func (h *handlerMock) PutBucketACLHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
func (h *handlerMock) GetBucketCorsHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
func (h *handlerMock) PutBucketCorsHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
func (h *handlerMock) DeleteBucketCorsHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
func (h *handlerMock) GetBucketWebsiteHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
func (h *handlerMock) GetBucketAccelerateHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
func (h *handlerMock) GetBucketRequestPaymentHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
func (h *handlerMock) GetBucketLoggingHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
func (h *handlerMock) GetBucketReplicationHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
func (h *handlerMock) GetBucketTaggingHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
func (h *handlerMock) DeleteBucketWebsiteHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
func (h *handlerMock) DeleteBucketTaggingHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
func (h *handlerMock) GetBucketObjectLockConfigHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
func (h *handlerMock) GetBucketVersioningHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
func (h *handlerMock) GetBucketNotificationHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
func (h *handlerMock) ListenBucketNotificationHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
func (h *handlerMock) ListObjectsV2MHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
@@ -339,7 +337,7 @@ func (h *handlerMock) ListObjectsV2Handler(w http.ResponseWriter, r *http.Reques
}
func (h *handlerMock) ListBucketObjectVersionsHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
@@ -353,22 +351,22 @@ func (h *handlerMock) ListObjectsV1Handler(w http.ResponseWriter, r *http.Reques
}
func (h *handlerMock) PutBucketLifecycleHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
func (h *handlerMock) PutBucketEncryptionHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
func (h *handlerMock) PutBucketPolicyHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
func (h *handlerMock) PutBucketObjectLockConfigHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
@@ -382,12 +380,12 @@ func (h *handlerMock) PutBucketTaggingHandler(w http.ResponseWriter, r *http.Req
}
func (h *handlerMock) PutBucketVersioningHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
func (h *handlerMock) PutBucketNotificationHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
@@ -417,32 +415,32 @@ func (h *handlerMock) HeadBucketHandler(w http.ResponseWriter, r *http.Request)
}
func (h *handlerMock) PostObject(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
func (h *handlerMock) DeleteMultipleObjectsHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
func (h *handlerMock) DeleteBucketPolicyHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
func (h *handlerMock) DeleteBucketLifecycleHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
func (h *handlerMock) DeleteBucketEncryptionHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
func (h *handlerMock) DeleteBucketHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
@@ -456,7 +454,7 @@ func (h *handlerMock) ListBucketsHandler(w http.ResponseWriter, r *http.Request)
}
func (h *handlerMock) Preflight(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
@@ -464,7 +462,7 @@ func (h *handlerMock) AppendCORSHeaders(http.ResponseWriter, *http.Request) {
}
func (h *handlerMock) CreateMultipartUploadHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
@@ -478,22 +476,22 @@ func (h *handlerMock) UploadPartHandler(w http.ResponseWriter, r *http.Request)
}
func (h *handlerMock) UploadPartCopy(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
func (h *handlerMock) CompleteMultipartUploadHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
func (h *handlerMock) AbortMultipartUploadHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
func (h *handlerMock) ListPartsHandler(http.ResponseWriter, *http.Request) {
- //TODO implement me
+ // TODO implement me
panic("implement me")
}
diff --git a/api/router_test.go b/api/router_test.go
index 5241da0..c1ca3dc 100644
--- a/api/router_test.go
+++ b/api/router_test.go
@@ -21,6 +21,7 @@ import (
"git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain"
"git.frostfs.info/TrueCloudLab/policy-engine/pkg/engine"
"git.frostfs.info/TrueCloudLab/policy-engine/pkg/engine/inmemory"
+ "git.frostfs.info/TrueCloudLab/policy-engine/schema/common"
"git.frostfs.info/TrueCloudLab/policy-engine/schema/s3"
"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
@@ -256,11 +257,19 @@ func TestDefaultBehaviorPolicyChecker(t *testing.T) {
}
func TestDefaultPolicyCheckerWithUserTags(t *testing.T) {
- chiRouter := prepareRouter(t)
+ router := prepareRouter(t)
ns, bktName := "", "bucket"
+ router.middlewareSettings.denyByDefault = true
- // check we can access bucket if rules not found
- createBucket(chiRouter, ns, bktName)
+ allowOperations(router, ns, []string{"s3:CreateBucket"}, engineiam.Conditions{
+ engineiam.CondStringEquals: engineiam.Condition{fmt.Sprintf(common.PropertyKeyFormatFrostFSIDUserClaim, "tag-test"): []string{"test"}},
+ })
+ createBucketErr(router, ns, bktName, apiErrors.ErrAccessDenied)
+
+ tags := make(map[string]string)
+ tags["tag-test"] = "test"
+ router.cfg.FrostfsID.(*frostFSIDMock).tags = tags
+ createBucket(router, ns, bktName)
}
func TestACLAPE(t *testing.T) {
diff --git a/internal/frostfs/frostfsid/frostfsid.go b/internal/frostfs/frostfsid/frostfsid.go
index cb5a9eb..6db6668 100644
--- a/internal/frostfs/frostfsid/frostfsid.go
+++ b/internal/frostfs/frostfsid/frostfsid.go
@@ -110,7 +110,7 @@ func (f *FrostFSID) GetUserKey(account, name string) (string, error) {
return hex.EncodeToString(key.Bytes()), nil
}
-func (f *FrostFSID) GetUserGroupIDsAndTags(userHash util.Uint160) ([]string, map[string]string, error) {
+func (f *FrostFSID) GetUserGroupIDsAndClaims(userHash util.Uint160) ([]string, map[string]string, error) {
subjExt, err := f.cli.GetSubjectExtended(userHash)
if err != nil {
if strings.Contains(err.Error(), "not found") {
@@ -124,12 +124,5 @@ func (f *FrostFSID) GetUserGroupIDsAndTags(userHash util.Uint160) ([]string, map
res[i] = strconv.FormatInt(group.ID, 10)
}
- tags := make(map[string]string)
- for k, v := range subjExt.KV {
- if strings.HasPrefix(k, "tag-") {
- tags[k] = v
- }
- }
-
- return res, tags, nil
+ return res, subjExt.KV, nil
}