forked from TrueCloudLab/frostfs-node
[#1117] ape: Introduce `FormFrostfsIDRequestProperties` method
* `FormFrostfsIDRequestProperties` gets user claim tags and group id and sets them as ape request properties. * Make tree, container and object service use the method. * Fix unit-tests. Signed-off-by: Airat Arifullin <a.arifullin@yadro.com>refactor/remove_unused_const
parent
6c76c9b457
commit
b60a51b862
|
@ -0,0 +1,36 @@
|
||||||
|
package request
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
frostfsidcore "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/frostfsid"
|
||||||
|
apechain "git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain"
|
||||||
|
commonschema "git.frostfs.info/TrueCloudLab/policy-engine/schema/common"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
|
)
|
||||||
|
|
||||||
|
// FormFrostfsIDRequestProperties forms frostfsid specific request properties like user-claim tags and group ID.
|
||||||
|
func FormFrostfsIDRequestProperties(frostFSIDClient frostfsidcore.SubjectProvider, pk *keys.PublicKey) (map[string]string, error) {
|
||||||
|
reqProps := make(map[string]string)
|
||||||
|
subj, err := frostFSIDClient.GetSubjectExtended(pk.GetScriptHash())
|
||||||
|
if err != nil {
|
||||||
|
if !strings.Contains(err.Error(), frostfsidcore.SubjectNotFoundErrorMessage) {
|
||||||
|
return nil, fmt.Errorf("get subject error: %w", err)
|
||||||
|
}
|
||||||
|
return reqProps, nil
|
||||||
|
}
|
||||||
|
for k, v := range subj.KV {
|
||||||
|
propertyKey := fmt.Sprintf(commonschema.PropertyKeyFormatFrostFSIDUserClaim, k)
|
||||||
|
reqProps[propertyKey] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
groups := make([]string, len(subj.Groups))
|
||||||
|
for i, group := range subj.Groups {
|
||||||
|
groups[i] = strconv.FormatInt(group.ID, 10)
|
||||||
|
}
|
||||||
|
reqProps[commonschema.PropertyKeyFrostFSIDGroupID] = apechain.FormCondSliceContainsValue(groups)
|
||||||
|
|
||||||
|
return reqProps, nil
|
||||||
|
}
|
|
@ -27,7 +27,6 @@ import (
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
||||||
apechain "git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain"
|
apechain "git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain"
|
||||||
policyengine "git.frostfs.info/TrueCloudLab/policy-engine/pkg/engine"
|
policyengine "git.frostfs.info/TrueCloudLab/policy-engine/pkg/engine"
|
||||||
commonschema "git.frostfs.info/TrueCloudLab/policy-engine/schema/common"
|
|
||||||
nativeschema "git.frostfs.info/TrueCloudLab/policy-engine/schema/native"
|
nativeschema "git.frostfs.info/TrueCloudLab/policy-engine/schema/native"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
)
|
)
|
||||||
|
@ -619,16 +618,12 @@ func (ac *apeChecker) fillWithUserClaimTags(reqProps map[string]string, pk *keys
|
||||||
if reqProps == nil {
|
if reqProps == nil {
|
||||||
reqProps = make(map[string]string)
|
reqProps = make(map[string]string)
|
||||||
}
|
}
|
||||||
subj, err := ac.frostFSIDClient.GetSubject(pk.GetScriptHash())
|
props, err := aperequest.FormFrostfsIDRequestProperties(ac.frostFSIDClient, pk)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !strings.Contains(err.Error(), frostfsidcore.SubjectNotFoundErrorMessage) {
|
return reqProps, err
|
||||||
return nil, fmt.Errorf("get subject error: %w", err)
|
|
||||||
}
|
}
|
||||||
return reqProps, nil
|
for propertyName, properyValue := range props {
|
||||||
}
|
reqProps[propertyName] = properyValue
|
||||||
for k, v := range subj.KV {
|
|
||||||
properyKey := fmt.Sprintf(commonschema.PropertyKeyFormatFrostFSIDUserClaim, k)
|
|
||||||
reqProps[properyKey] = v
|
|
||||||
}
|
}
|
||||||
return reqProps, nil
|
return reqProps, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@ func TestAPE(t *testing.T) {
|
||||||
t.Run("deny get container no rule found", testDenyGetContainerNoRuleFound)
|
t.Run("deny get container no rule found", testDenyGetContainerNoRuleFound)
|
||||||
t.Run("deny get container for others", testDenyGetContainerForOthers)
|
t.Run("deny get container for others", testDenyGetContainerForOthers)
|
||||||
t.Run("deny get container by user claim tag", testDenyGetContainerByUserClaimTag)
|
t.Run("deny get container by user claim tag", testDenyGetContainerByUserClaimTag)
|
||||||
|
t.Run("deny get container by group id", testDenyGetContainerByGroupID)
|
||||||
t.Run("deny set container eACL for IR", testDenySetContainerEACLForIR)
|
t.Run("deny set container eACL for IR", testDenySetContainerEACLForIR)
|
||||||
t.Run("deny get container eACL for IR with session token", testDenyGetContainerEACLForIRSessionToken)
|
t.Run("deny get container eACL for IR with session token", testDenyGetContainerEACLForIRSessionToken)
|
||||||
t.Run("deny put container for others with session token", testDenyPutContainerForOthersSessionToken)
|
t.Run("deny put container for others with session token", testDenyPutContainerForOthersSessionToken)
|
||||||
|
@ -279,6 +280,19 @@ func testDenyGetContainerByUserClaimTag(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
subjectsExt: map[util.Uint160]*client.SubjectExtended{
|
||||||
|
pk.PublicKey().GetScriptHash(): {
|
||||||
|
KV: map[string]string{
|
||||||
|
"tag-attr1": "value1",
|
||||||
|
"tag-attr2": "value2",
|
||||||
|
},
|
||||||
|
Groups: []*client.Group{
|
||||||
|
{
|
||||||
|
ID: 19888,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
apeSrv := NewAPEServer(router, contRdr, ir, nm, frostfsIDSubjectReader, srv)
|
apeSrv := NewAPEServer(router, contRdr, ir, nm, frostfsIDSubjectReader, srv)
|
||||||
|
@ -339,6 +353,104 @@ func testDenyGetContainerByUserClaimTag(t *testing.T) {
|
||||||
require.ErrorAs(t, err, &errAccessDenied)
|
require.ErrorAs(t, err, &errAccessDenied)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testDenyGetContainerByGroupID(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
srv := &srvStub{
|
||||||
|
calls: map[string]int{},
|
||||||
|
}
|
||||||
|
router := inmemory.NewInMemory()
|
||||||
|
contRdr := &containerStub{
|
||||||
|
c: map[cid.ID]*containercore.Container{},
|
||||||
|
}
|
||||||
|
ir := &irStub{
|
||||||
|
keys: [][]byte{},
|
||||||
|
}
|
||||||
|
nm := &netmapStub{}
|
||||||
|
pk, err := keys.NewPrivateKey()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
frostfsIDSubjectReader := &frostfsidStub{
|
||||||
|
subjects: map[util.Uint160]*client.Subject{
|
||||||
|
pk.PublicKey().GetScriptHash(): {
|
||||||
|
KV: map[string]string{
|
||||||
|
"tag-attr1": "value1",
|
||||||
|
"tag-attr2": "value2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
subjectsExt: map[util.Uint160]*client.SubjectExtended{
|
||||||
|
pk.PublicKey().GetScriptHash(): {
|
||||||
|
KV: map[string]string{
|
||||||
|
"tag-attr1": "value1",
|
||||||
|
"tag-attr2": "value2",
|
||||||
|
},
|
||||||
|
Groups: []*client.Group{
|
||||||
|
{
|
||||||
|
ID: 19888,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
apeSrv := NewAPEServer(router, contRdr, ir, nm, frostfsIDSubjectReader, srv)
|
||||||
|
|
||||||
|
contID := cidtest.ID()
|
||||||
|
testContainer := containertest.Container()
|
||||||
|
pp := netmap.PlacementPolicy{}
|
||||||
|
require.NoError(t, pp.DecodeString("REP 1"))
|
||||||
|
testContainer.SetPlacementPolicy(pp)
|
||||||
|
contRdr.c[contID] = &containercore.Container{Value: testContainer}
|
||||||
|
|
||||||
|
nm.currentEpoch = 100
|
||||||
|
nm.netmaps = map[uint64]*netmap.NetMap{}
|
||||||
|
var testNetmap netmap.NetMap
|
||||||
|
testNetmap.SetEpoch(nm.currentEpoch)
|
||||||
|
testNetmap.SetNodes([]netmap.NodeInfo{{}})
|
||||||
|
nm.netmaps[nm.currentEpoch] = &testNetmap
|
||||||
|
nm.netmaps[nm.currentEpoch-1] = &testNetmap
|
||||||
|
|
||||||
|
_, _, err = router.MorphRuleChainStorage().AddMorphRuleChain(chain.Ingress, engine.ContainerTarget(contID.EncodeToString()), &chain.Chain{
|
||||||
|
Rules: []chain.Rule{
|
||||||
|
{
|
||||||
|
Status: chain.AccessDenied,
|
||||||
|
Actions: chain.Actions{
|
||||||
|
Names: []string{
|
||||||
|
nativeschema.MethodGetContainer,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Resources: chain.Resources{
|
||||||
|
Names: []string{
|
||||||
|
fmt.Sprintf(nativeschema.ResourceFormatRootContainer, contID.EncodeToString()),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Condition: []chain.Condition{
|
||||||
|
{
|
||||||
|
Object: chain.ObjectRequest,
|
||||||
|
Key: commonschema.PropertyKeyFrostFSIDGroupID,
|
||||||
|
Value: "19888",
|
||||||
|
Op: chain.CondStringEquals,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
req := &container.GetRequest{}
|
||||||
|
req.SetBody(&container.GetRequestBody{})
|
||||||
|
var refContID refs.ContainerID
|
||||||
|
contID.WriteToV2(&refContID)
|
||||||
|
req.GetBody().SetContainerID(&refContID)
|
||||||
|
|
||||||
|
require.NoError(t, signature.SignServiceMessage(&pk.PrivateKey, req))
|
||||||
|
|
||||||
|
resp, err := apeSrv.Get(context.Background(), req)
|
||||||
|
require.Nil(t, resp)
|
||||||
|
var errAccessDenied *apistatus.ObjectAccessDenied
|
||||||
|
require.ErrorAs(t, err, &errAccessDenied)
|
||||||
|
}
|
||||||
|
|
||||||
func testDenySetContainerEACLForIR(t *testing.T) {
|
func testDenySetContainerEACLForIR(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
srv := &srvStub{
|
srv := &srvStub{
|
||||||
|
@ -621,6 +733,21 @@ func testDenyPutContainerReadNamespaceFromFrostfsID(t *testing.T) {
|
||||||
Name: testDomainName,
|
Name: testDomainName,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
subjectsExt: map[util.Uint160]*client.SubjectExtended{
|
||||||
|
ownerScriptHash: {
|
||||||
|
Namespace: testDomainName,
|
||||||
|
Name: testDomainName,
|
||||||
|
KV: map[string]string{
|
||||||
|
"tag-attr1": "value1",
|
||||||
|
"tag-attr2": "value2",
|
||||||
|
},
|
||||||
|
Groups: []*client.Group{
|
||||||
|
{
|
||||||
|
ID: 19888,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
apeSrv := NewAPEServer(router, contRdr, ir, nm, frostfsIDSubjectReader, srv)
|
apeSrv := NewAPEServer(router, contRdr, ir, nm, frostfsIDSubjectReader, srv)
|
||||||
resp, err := apeSrv.Put(context.Background(), req)
|
resp, err := apeSrv.Put(context.Background(), req)
|
||||||
|
@ -690,6 +817,21 @@ func testDenyPutContainerInvalidNamespace(t *testing.T) {
|
||||||
Name: testDomainName,
|
Name: testDomainName,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
subjectsExt: map[util.Uint160]*client.SubjectExtended{
|
||||||
|
ownerScriptHash: {
|
||||||
|
Namespace: testDomainName,
|
||||||
|
Name: testDomainName,
|
||||||
|
KV: map[string]string{
|
||||||
|
"tag-attr1": "value1",
|
||||||
|
"tag-attr2": "value2",
|
||||||
|
},
|
||||||
|
Groups: []*client.Group{
|
||||||
|
{
|
||||||
|
ID: 19888,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
apeSrv := NewAPEServer(router, contRdr, ir, nm, frostfsIDSubjectReader, srv)
|
apeSrv := NewAPEServer(router, contRdr, ir, nm, frostfsIDSubjectReader, srv)
|
||||||
resp, err := apeSrv.Put(context.Background(), req)
|
resp, err := apeSrv.Put(context.Background(), req)
|
||||||
|
@ -800,6 +942,34 @@ func testDenyListContainersValidationNamespaceError(t *testing.T) {
|
||||||
Name: testDomainName,
|
Name: testDomainName,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
subjectsExt: map[util.Uint160]*client.SubjectExtended{
|
||||||
|
actorScriptHash: {
|
||||||
|
Namespace: actorDomain,
|
||||||
|
Name: actorDomain,
|
||||||
|
KV: map[string]string{
|
||||||
|
"tag-attr1": "value1",
|
||||||
|
"tag-attr2": "value2",
|
||||||
|
},
|
||||||
|
Groups: []*client.Group{
|
||||||
|
{
|
||||||
|
ID: 19777,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ownerScriptHash: {
|
||||||
|
Namespace: testDomainName,
|
||||||
|
Name: testDomainName,
|
||||||
|
KV: map[string]string{
|
||||||
|
"tag-attr1": "value1",
|
||||||
|
"tag-attr2": "value2",
|
||||||
|
},
|
||||||
|
Groups: []*client.Group{
|
||||||
|
{
|
||||||
|
ID: 19888,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
apeSrv := NewAPEServer(router, contRdr, ir, nm, frostfsIDSubjectReader, srv)
|
apeSrv := NewAPEServer(router, contRdr, ir, nm, frostfsIDSubjectReader, srv)
|
||||||
|
|
|
@ -4,17 +4,14 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
|
||||||
|
|
||||||
objectV2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object"
|
objectV2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object"
|
||||||
aperequest "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/ape/request"
|
aperequest "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/ape/request"
|
||||||
frostfsidcore "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/frostfsid"
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/acl"
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/acl"
|
||||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
||||||
commonschema "git.frostfs.info/TrueCloudLab/policy-engine/schema/common"
|
|
||||||
nativeschema "git.frostfs.info/TrueCloudLab/policy-engine/schema/native"
|
nativeschema "git.frostfs.info/TrueCloudLab/policy-engine/schema/native"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
)
|
)
|
||||||
|
@ -148,16 +145,12 @@ func (c *checkerImpl) fillWithUserClaimTags(reqProps map[string]string, prm Prm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
subj, err := c.frostFSIDClient.GetSubject(pk.GetScriptHash())
|
props, err := aperequest.FormFrostfsIDRequestProperties(c.frostFSIDClient, pk)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !strings.Contains(err.Error(), frostfsidcore.SubjectNotFoundErrorMessage) {
|
return reqProps, err
|
||||||
return nil, fmt.Errorf("get subject error: %w", err)
|
|
||||||
}
|
}
|
||||||
return reqProps, nil
|
for propertyName, properyValue := range props {
|
||||||
}
|
reqProps[propertyName] = properyValue
|
||||||
for k, v := range subj.KV {
|
|
||||||
properyKey := fmt.Sprintf(commonschema.PropertyKeyFormatFrostFSIDUserClaim, k)
|
|
||||||
reqProps[properyKey] = v
|
|
||||||
}
|
}
|
||||||
return reqProps, nil
|
return reqProps, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -275,6 +275,7 @@ func TestNewAPERequest(t *testing.T) {
|
||||||
nativeschema.PropertyKeyActorRole: prm.Role,
|
nativeschema.PropertyKeyActorRole: prm.Role,
|
||||||
fmt.Sprintf(commonschema.PropertyKeyFormatFrostFSIDUserClaim, "tag-attr1"): "value1",
|
fmt.Sprintf(commonschema.PropertyKeyFormatFrostFSIDUserClaim, "tag-attr1"): "value1",
|
||||||
fmt.Sprintf(commonschema.PropertyKeyFormatFrostFSIDUserClaim, "tag-attr2"): "value2",
|
fmt.Sprintf(commonschema.PropertyKeyFormatFrostFSIDUserClaim, "tag-attr2"): "value2",
|
||||||
|
commonschema.PropertyKeyFrostFSIDGroupID: "1",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -8,14 +8,12 @@ import (
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/ape/converter"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/ape/converter"
|
||||||
aperequest "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/ape/request"
|
aperequest "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/ape/request"
|
||||||
core "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/container"
|
core "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/container"
|
||||||
frostfsidcore "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/frostfsid"
|
|
||||||
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
||||||
cnrSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container"
|
cnrSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/acl"
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/acl"
|
||||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
apechain "git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain"
|
apechain "git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain"
|
||||||
"git.frostfs.info/TrueCloudLab/policy-engine/pkg/engine"
|
"git.frostfs.info/TrueCloudLab/policy-engine/pkg/engine"
|
||||||
commonschema "git.frostfs.info/TrueCloudLab/policy-engine/schema/common"
|
|
||||||
nativeschema "git.frostfs.info/TrueCloudLab/policy-engine/schema/native"
|
nativeschema "git.frostfs.info/TrueCloudLab/policy-engine/schema/native"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
)
|
)
|
||||||
|
@ -80,16 +78,12 @@ func (s *Service) fillWithUserClaimTags(reqProps map[string]string, publicKey *k
|
||||||
if reqProps == nil {
|
if reqProps == nil {
|
||||||
reqProps = make(map[string]string)
|
reqProps = make(map[string]string)
|
||||||
}
|
}
|
||||||
subj, err := s.frostfsidSubjectProvider.GetSubject(publicKey.GetScriptHash())
|
props, err := aperequest.FormFrostfsIDRequestProperties(s.frostfsidSubjectProvider, publicKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !strings.Contains(err.Error(), frostfsidcore.SubjectNotFoundErrorMessage) {
|
return reqProps, err
|
||||||
return nil, fmt.Errorf("get subject error: %w", err)
|
|
||||||
}
|
}
|
||||||
return reqProps, nil
|
for propertyName, properyValue := range props {
|
||||||
}
|
reqProps[propertyName] = properyValue
|
||||||
for k, v := range subj.KV {
|
|
||||||
properyKey := fmt.Sprintf(commonschema.PropertyKeyFormatFrostFSIDUserClaim, k)
|
|
||||||
reqProps[properyKey] = v
|
|
||||||
}
|
}
|
||||||
return reqProps, nil
|
return reqProps, nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue