From 6bf6a3b1a38a012791c58f2dc1029d71298464f3 Mon Sep 17 00:00:00 2001 From: Alex Vanin Date: Thu, 11 Apr 2024 14:31:53 +0300 Subject: [PATCH] [#362] Check user and groups during policy check Signed-off-by: Alex Vanin --- api/middleware/policy.go | 28 ++++++++++++++----- .../policy/morph_rule_chain_storage.go | 14 ++++++---- 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/api/middleware/policy.go b/api/middleware/policy.go index cc86635..5953f01 100644 --- a/api/middleware/policy.go +++ b/api/middleware/policy.go @@ -97,7 +97,7 @@ func PolicyCheck(cfg PolicyConfig) Func { func policyCheck(r *http.Request, cfg PolicyConfig) error { reqType, bktName, objName := getBucketObject(r, cfg.Domains) - req, err := getPolicyRequest(r, cfg, reqType, bktName, objName) + req, userKey, userGroups, err := getPolicyRequest(r, cfg, reqType, bktName, objName) if err != nil { return err } @@ -117,6 +117,19 @@ func policyCheck(r *http.Request, cfg PolicyConfig) error { target.Container = &cnrTarget } + if userKey != nil { + entityName := fmt.Sprintf("%s:%s", reqInfo.Namespace, userKey.Address()) + uTarget := engine.UserTarget(entityName) + target.User = &uTarget + } + + gts := make([]engine.Target, len(userGroups)) + for i, group := range userGroups { + entityName := fmt.Sprintf("%s:%s", reqInfo.Namespace, group) + gts[i] = engine.GroupTarget(entityName) + } + target.Groups = gts + st, found, err := cfg.Storage.IsAllowed(chain.S3, target, req) if err != nil { return err @@ -145,25 +158,26 @@ func policyCheck(r *http.Request, cfg PolicyConfig) error { return nil } -func getPolicyRequest(r *http.Request, cfg PolicyConfig, reqType ReqType, bktName string, objName string) (*testutil.Request, error) { +func getPolicyRequest(r *http.Request, cfg PolicyConfig, reqType ReqType, bktName string, objName string) (*testutil.Request, *keys.PublicKey, []string, error) { var ( owner string groups []string tags map[string]string + pk *keys.PublicKey ) ctx := r.Context() bd, err := GetBoxData(ctx) if err == nil && bd.Gate.BearerToken != nil { - pk, err := keys.NewPublicKeyFromBytes(bd.Gate.BearerToken.SigningKeyBytes(), elliptic.P256()) + pk, err = keys.NewPublicKeyFromBytes(bd.Gate.BearerToken.SigningKeyBytes(), elliptic.P256()) if err != nil { - return nil, fmt.Errorf("parse pubclic key from btoken: %w", err) + return nil, nil, nil, fmt.Errorf("parse pubclic key from btoken: %w", err) } owner = pk.Address() groups, tags, err = cfg.FrostfsID.GetUserGroupIDsAndClaims(pk.GetScriptHash()) if err != nil { - return nil, fmt.Errorf("get group ids: %w", err) + return nil, nil, nil, fmt.Errorf("get group ids: %w", err) } } @@ -178,13 +192,13 @@ func getPolicyRequest(r *http.Request, cfg PolicyConfig, reqType ReqType, bktNam properties, err := determineProperties(r, cfg.Decoder, cfg.BucketResolver, cfg.Tagging, reqType, op, bktName, objName, owner, groups, tags) if err != nil { - return nil, fmt.Errorf("determine properties: %w", err) + return nil, nil, nil, fmt.Errorf("determine properties: %w", err) } reqLogOrDefault(r.Context(), cfg.Log).Debug(logs.PolicyRequest, zap.String("action", op), zap.String("resource", res), zap.Any("properties", properties)) - return testutil.NewRequest(op, testutil.NewResource(res, nil), properties), nil + return testutil.NewRequest(op, testutil.NewResource(res, nil), properties), pk, groups, nil } type ReqType int diff --git a/internal/frostfs/policy/morph_rule_chain_storage.go b/internal/frostfs/policy/morph_rule_chain_storage.go index 5684729..1d82617 100644 --- a/internal/frostfs/policy/morph_rule_chain_storage.go +++ b/internal/frostfs/policy/morph_rule_chain_storage.go @@ -117,12 +117,16 @@ func (c *MorphRuleChainStorage) SaveACLChains(cid string, chains []*chain.Chain) } func getKind(target engine.Target) policycontract.Kind { - var kind policycontract.Kind = policycontract.Container - if target.Type != engine.Container { - kind = policycontract.Namespace + switch target.Type { + case engine.Container: + return policycontract.Container + case engine.User: + return 'u' + case engine.Group: + return 'g' + default: + return policycontract.Namespace } - - return kind } func getBucketPolicyName(cnrID cid.ID) []byte { -- 2.45.2