Introduce APEOverride for Bearer-token #225

Merged
fyrchik merged 2 commits from aarifullin/frostfs-sdk-go:feat/beartoken_ape into master 2024-05-31 12:14:44 +00:00
12 changed files with 245 additions and 70 deletions

View file

@ -1,10 +1,10 @@
package apemanager
package ape
import (
"errors"
"fmt"
apemanager_v2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/apemanager"
apeV2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/ape"
)
var (
@ -27,11 +27,11 @@ type Chain struct {
}
// ToV2 converts Chain to v2.
func (c *Chain) ToV2() *apemanager_v2.Chain {
v2ct := new(apemanager_v2.Chain)
func (c *Chain) ToV2() *apeV2.Chain {
v2ct := new(apeV2.Chain)
if c.Raw != nil {
v2Raw := new(apemanager_v2.ChainRaw)
v2Raw := new(apeV2.ChainRaw)
v2Raw.SetRaw(c.Raw)
v2ct.SetKind(v2Raw)
}
@ -40,11 +40,11 @@ func (c *Chain) ToV2() *apemanager_v2.Chain {
}
// ReadFromV2 fills Chain from v2.
func (c *Chain) ReadFromV2(v2ct *apemanager_v2.Chain) error {
func (c *Chain) ReadFromV2(v2ct *apeV2.Chain) error {
switch v := v2ct.GetKind().(type) {
default:
return fmt.Errorf("unsupported chain kind: %T", v)
case *apemanager_v2.ChainRaw:
case *apeV2.ChainRaw:
raw := v.GetRaw()
c.Raw = raw
}

View file

@ -1,11 +1,11 @@
package apemanager
package ape
import (
apemanager_v2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/apemanager"
apeV2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/ape"
)
// TargetType is an SDK representation for v2's TargetType.
type TargetType apemanager_v2.TargetType
type TargetType apeV2.TargetType
const (
TargetTypeUndefined TargetType = iota
@ -16,12 +16,12 @@ const (
)
// ToV2 converts TargetType to v2.
func (targetType TargetType) ToV2() apemanager_v2.TargetType {
return apemanager_v2.TargetType(targetType)
func (targetType TargetType) ToV2() apeV2.TargetType {
return apeV2.TargetType(targetType)
}
// FromV2 reads TargetType to v2.
func (targetType *TargetType) FromV2(v2targetType apemanager_v2.TargetType) {
func (targetType *TargetType) FromV2(v2targetType apeV2.TargetType) {
*targetType = TargetType(v2targetType)
}
@ -37,8 +37,8 @@ type ChainTarget struct {
}
// ToV2 converts ChainTarget to v2.
func (ct *ChainTarget) ToV2() *apemanager_v2.ChainTarget {
v2ct := new(apemanager_v2.ChainTarget)
func (ct *ChainTarget) ToV2() *apeV2.ChainTarget {
v2ct := new(apeV2.ChainTarget)
v2ct.SetTargetType(ct.TargetType.ToV2())
v2ct.SetName(ct.Name)
@ -47,7 +47,7 @@ func (ct *ChainTarget) ToV2() *apemanager_v2.ChainTarget {
}
// FromV2 reads ChainTarget frpm v2.
func (ct *ChainTarget) FromV2(v2ct *apemanager_v2.ChainTarget) {
func (ct *ChainTarget) FromV2(v2ct *apeV2.ChainTarget) {
ct.TargetType.FromV2(v2ct.GetTargetType())
ct.Name = v2ct.GetName()
}

View file

@ -1,21 +1,21 @@
package apemanager_test
package ape_test
import (
"testing"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/apemanager"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/ape"
"github.com/stretchr/testify/require"
apemanager_v2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/apemanager"
apeV2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/ape"
)
var (
m = map[apemanager.TargetType]apemanager_v2.TargetType{
apemanager.TargetTypeUndefined: apemanager_v2.TargetTypeUndefined,
apemanager.TargetTypeNamespace: apemanager_v2.TargetTypeNamespace,
apemanager.TargetTypeContainer: apemanager_v2.TargetTypeContainer,
apemanager.TargetTypeUser: apemanager_v2.TargetTypeUser,
apemanager.TargetTypeGroup: apemanager_v2.TargetTypeGroup,
m = map[ape.TargetType]apeV2.TargetType{
ape.TargetTypeUndefined: apeV2.TargetTypeUndefined,
ape.TargetTypeNamespace: apeV2.TargetTypeNamespace,
ape.TargetTypeContainer: apeV2.TargetTypeContainer,
ape.TargetTypeUser: apeV2.TargetTypeUser,
ape.TargetTypeGroup: apeV2.TargetTypeGroup,
}
)
@ -27,7 +27,7 @@ func TestTargetType(t *testing.T) {
})
t.Run("from v2 to sdk "+typev2.String(), func(t *testing.T) {
var typ apemanager.TargetType
var typ ape.TargetType
typ.FromV2(typev2)
require.Equal(t, typesdk, typ)
})
@ -36,12 +36,12 @@ func TestTargetType(t *testing.T) {
func TestChainTarget(t *testing.T) {
var (
typ = apemanager.TargetTypeNamespace
typ = ape.TargetTypeNamespace
name = "namespaceXXYYZZ"
)
t.Run("from sdk to v2", func(t *testing.T) {
ct := apemanager.ChainTarget{
ct := ape.ChainTarget{
TargetType: typ,
Name: name,
}
@ -52,11 +52,11 @@ func TestChainTarget(t *testing.T) {
})
t.Run("from v2 to sdk", func(t *testing.T) {
v2 := &apemanager_v2.ChainTarget{}
v2 := &apeV2.ChainTarget{}
v2.SetTargetType(m[typ])
v2.SetName(name)
var ct apemanager.ChainTarget
var ct ape.ChainTarget
ct.FromV2(v2)
require.Equal(t, typ, ct.TargetType)

View file

@ -1,12 +1,12 @@
package apemanager_test
package ape_test
import (
"testing"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/apemanager"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/ape"
"github.com/stretchr/testify/require"
apemanager_v2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/apemanager"
apeV2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/ape"
)
const (
@ -15,12 +15,12 @@ const (
func TestChainData(t *testing.T) {
t.Run("raw chain", func(t *testing.T) {
var c apemanager.Chain
var c ape.Chain
b := []byte(encoded)
c.Raw = b
v2, ok := c.ToV2().GetKind().(*apemanager_v2.ChainRaw)
v2, ok := c.ToV2().GetKind().(*apeV2.ChainRaw)
require.True(t, ok)
require.Equal(t, b, v2.Raw)
})
@ -29,13 +29,13 @@ func TestChainData(t *testing.T) {
func TestChainMessageV2(t *testing.T) {
b := []byte(encoded)
v2Raw := &apemanager_v2.ChainRaw{}
v2Raw := &apeV2.ChainRaw{}
v2Raw.SetRaw(b)
v2 := &apemanager_v2.Chain{}
v2 := &apeV2.Chain{}
v2.SetKind(v2Raw)
var c apemanager.Chain
var c ape.Chain
c.ReadFromV2(v2)
require.NotNil(t, c.Raw)

View file

@ -6,7 +6,9 @@ import (
"fmt"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/acl"
apeV2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/ape"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
apeSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/ape"
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
frostfscrypto "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto"
frostfsecdsa "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto/ecdsa"
@ -33,9 +35,85 @@ type Token struct {
sigSet bool
sig refs.Signature
apeOverrideSet bool
apeOverride APEOverride
impersonate bool
}
// APEOverride is the list of APE chains defined for a target.
// These chains are meant to serve as overrides to the already defined (or even undefined)
// APE chains for the target (see contract `Policy`).
//
// The server-side processing of the bearer token with set APE overrides must verify if a client is permitted
// to override chains for the target, preventing unauthorized access through the APE mechanism.
type APEOverride struct {
// Target for which chains are applied.
Target apeSDK.ChainTarget
// The list of APE chains.
Chains []apeSDK.Chain
}
// Marshal marshals APEOverride into a protobuf binary form.
func (c *APEOverride) Marshal() ([]byte, error) {
return c.ToV2().StableMarshal(nil), nil
}
// Unmarshal unmarshals protobuf binary representation of APEOverride.
func (c *APEOverride) Unmarshal(data []byte) error {
overrideV2 := new(acl.APEOverride)
if err := overrideV2.Unmarshal(data); err != nil {
return err
}
return c.FromV2(overrideV2)
}
// MarshalJSON encodes APEOverride to protobuf JSON format.
func (c *APEOverride) MarshalJSON() ([]byte, error) {
return c.ToV2().MarshalJSON()
}
// UnmarshalJSON decodes APEOverride from protobuf JSON format.
func (c *APEOverride) UnmarshalJSON(data []byte) error {
overrideV2 := new(acl.APEOverride)
if err := overrideV2.UnmarshalJSON(data); err != nil {
return err
}
return c.FromV2(overrideV2)
}
func (c *APEOverride) FromV2(tokenAPEChains *acl.APEOverride) error {
c.Target.FromV2(tokenAPEChains.GetTarget())
if chains := tokenAPEChains.GetChains(); len(chains) > 0 {
c.Chains = make([]apeSDK.Chain, len(chains))
for i := range chains {
if err := c.Chains[i].ReadFromV2(chains[i]); err != nil {
return fmt.Errorf("invalid APE chain: %w", err)
}
}
}
return nil
}
func (c *APEOverride) ToV2() *acl.APEOverride {
if c == nil {
return nil
}
apeOverride := new(acl.APEOverride)
apeOverride.SetTarget(c.Target.ToV2())
chains := make([]*apeV2.Chain, len(c.Chains))
for i := range c.Chains {
dkirillov marked this conversation as resolved Outdated

It seems this is unnecessary because of the next line

It seems this is unnecessary because of the next line

True. Fixed

True. Fixed
chains[i] = c.Chains[i].ToV2()
}
apeOverride.SetChains(chains)
return apeOverride
}
// reads Token from the acl.BearerToken message. If checkFieldPresence is set,
// returns an error on absence of any protocol-required field.
func (b *Token) readFromV2(m acl.BearerToken, checkFieldPresence bool) error {
@ -48,10 +126,11 @@ func (b *Token) readFromV2(m acl.BearerToken, checkFieldPresence bool) error {
b.impersonate = body.GetImpersonate()
apeOverrides := body.GetAPEOverride()
eaclTable := body.GetEACL()
if b.eaclTableSet = eaclTable != nil; b.eaclTableSet {
b.eaclTable = *eacl.NewTableFromV2(eaclTable)
} else if checkFieldPresence && !b.impersonate {
} else if checkFieldPresence && !b.impersonate && apeOverrides == nil {
return errors.New("missing eACL table")
}
@ -72,6 +151,14 @@ func (b *Token) readFromV2(m acl.BearerToken, checkFieldPresence bool) error {
return errors.New("missing token lifetime")
}
if b.apeOverrideSet = apeOverrides != nil; b.apeOverrideSet {
dkirillov marked this conversation as resolved Outdated

Why do we need this?
If we want make sure there is not old data then probably we need the same for other fields. Currently this isn't fully consistent I suppose

Why do we need this? If we want make sure there is not old data then probably we need the same for other fields. Currently this isn't fully consistent I suppose

Okay, I remate in old manner with flag and made consistent with other fields

Okay, I remate in old manner with flag and made consistent with other fields
if err = b.apeOverride.FromV2(apeOverrides); err != nil {
return err
}
} else if checkFieldPresence && !b.impersonate && !b.eaclTableSet {
return errors.New("missing APE override")
}
sig := m.GetSignature()
if b.sigSet = sig != nil; sig != nil {
b.sig = *sig
@ -90,7 +177,7 @@ func (b *Token) ReadFromV2(m acl.BearerToken) error {
}
func (b Token) fillBody() *acl.BearerTokenBody {
if !b.eaclTableSet && !b.targetUserSet && !b.lifetimeSet && !b.impersonate {
if !b.eaclTableSet && !b.targetUserSet && !b.lifetimeSet && !b.impersonate && !b.apeOverrideSet {
return nil
}
@ -116,6 +203,10 @@ func (b Token) fillBody() *acl.BearerTokenBody {
body.SetLifetime(&lifetime)
}
if b.apeOverrideSet {
body.SetAPEOverride(b.apeOverride.ToV2())
}
body.SetImpersonate(b.impersonate)
return &body
@ -214,6 +305,25 @@ func (b Token) EACLTable() eacl.Table {
return eacl.Table{}
}
// SetAPEOverride sets APE override to the bearer token.
//
// See also: APEOverride.
func (b *Token) SetAPEOverride(v APEOverride) {
b.apeOverride = v
b.apeOverrideSet = true
}
// APEOverride returns APE override set by SetAPEOverride.
//
dkirillov marked this conversation as resolved Outdated

Do we need comment for this method?

Do we need comment for this method?

Added

Added
// Zero Token has zero APEOverride.
func (b *Token) APEOverride() APEOverride {
if b.apeOverrideSet {
return b.apeOverride
}
return APEOverride{}
}
// SetImpersonate mark token as impersonate to consider token signer as request owner.
// If this field is true extended EACLTable in token body isn't processed.
func (b *Token) SetImpersonate(v bool) {

View file

@ -3,6 +3,7 @@ package bearer_test
import (
"bytes"
"math/rand"
"reflect"
"testing"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/acl"
@ -81,6 +82,58 @@ func TestToken_SetEACLTable(t *testing.T) {
require.True(t, isEqualEACLTables(eaclTable, val.EACLTable()))
}
func TestToken_SetAPEOverrides(t *testing.T) {
var val bearer.Token
var m acl.BearerToken
filled := bearertest.Token()
val.WriteToV2(&m)
require.Zero(t, m.GetBody())
val2 := filled
require.NoError(t, val2.Unmarshal(val.Marshal()))
require.Zero(t, val2.APEOverride())
val2 = filled
jd, err := val.MarshalJSON()
require.NoError(t, err)
require.NoError(t, val2.UnmarshalJSON(jd))
require.Zero(t, val2.APEOverride())
// set value
tApe := bearertest.APEOverride()
val.SetAPEOverride(tApe)
require.Equal(t, tApe, val.APEOverride())
val.WriteToV2(&m)
require.NotNil(t, m.GetBody().GetAPEOverride())
require.True(t, tokenAPEOverridesEqual(tApe.ToV2(), m.GetBody().GetAPEOverride()))
val2 = filled
require.NoError(t, val2.Unmarshal(val.Marshal()))
apeOverride := val2.APEOverride()
require.True(t, tokenAPEOverridesEqual(tApe.ToV2(), apeOverride.ToV2()))
val2 = filled
jd, err = val.MarshalJSON()
require.NoError(t, err)
require.NoError(t, val2.UnmarshalJSON(jd))
apeOverride = val.APEOverride()
require.True(t, tokenAPEOverridesEqual(tApe.ToV2(), apeOverride.ToV2()))
}
func tokenAPEOverridesEqual(lhs, rhs *acl.APEOverride) bool {
return reflect.DeepEqual(lhs, rhs)
}
func TestToken_ForUser(t *testing.T) {
var val bearer.Token
var m acl.BearerToken

View file

@ -1,6 +1,7 @@
package bearertest
import (
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/ape"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer"
eacltest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/eacl/test"
usertest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user/test"
@ -15,6 +16,17 @@ func Token() (t bearer.Token) {
t.SetIat(1)
t.ForUser(usertest.ID())
t.SetEACLTable(*eacltest.Table())
t.SetAPEOverride(APEOverride())
return t
}
func APEOverride() bearer.APEOverride {
return bearer.APEOverride{
Target: ape.ChainTarget{
TargetType: ape.TargetTypeContainer,
Name: "F8JsMnChywiPvbDvpxMbjTjx5KhWHHp6gCDt8BhzL9kF",
},
Chains: []ape.Chain{{Raw: []byte("{}")}},
}
}

View file

@ -4,12 +4,12 @@ import (
"context"
"fmt"
apemanager_v2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/apemanager"
apemanagerV2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/apemanager"
rpcapi "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
session_v2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session"
sessionV2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/signature"
apemanager_sdk "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/apemanager"
apeSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/ape"
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
)
@ -17,25 +17,25 @@ import (
type PrmAPEManagerAddChain struct {
XHeaders []string
ChainTarget apemanager_sdk.ChainTarget
ChainTarget apeSDK.ChainTarget
Chain apemanager_sdk.Chain
Chain apeSDK.Chain
}
func (prm *PrmAPEManagerAddChain) buildRequest(c *Client) (*apemanager_v2.AddChainRequest, error) {
func (prm *PrmAPEManagerAddChain) buildRequest(c *Client) (*apemanagerV2.AddChainRequest, error) {
if len(prm.XHeaders)%2 != 0 {
return nil, errorInvalidXHeaders
}
req := new(apemanager_v2.AddChainRequest)
reqBody := new(apemanager_v2.AddChainRequestBody)
req := new(apemanagerV2.AddChainRequest)
reqBody := new(apemanagerV2.AddChainRequestBody)
reqBody.SetTarget(prm.ChainTarget.ToV2())
reqBody.SetChain(prm.Chain.ToV2())
req.SetBody(reqBody)
var meta session_v2.RequestMetaHeader
var meta sessionV2.RequestMetaHeader
writeXHeadersToMeta(prm.XHeaders, &meta)
c.prepareRequest(req, &meta)
@ -48,7 +48,7 @@ type ResAPEManagerAddChain struct {
// ChainID of set Chain. If Chain does not contain chainID before request, then
// ChainID is generated.
ChainID apemanager_sdk.ChainID
ChainID apeSDK.ChainID
}
// APEManagerAddChain sets Chain for ChainTarget.

View file

@ -4,12 +4,12 @@ import (
"context"
"fmt"
apemanager_v2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/apemanager"
apemanagerV2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/apemanager"
rpcapi "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
session_v2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session"
sessionV2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/signature"
apemanager_sdk "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/apemanager"
apeSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/ape"
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
)
@ -17,22 +17,22 @@ import (
type PrmAPEManagerListChains struct {
XHeaders []string
ChainTarget apemanager_sdk.ChainTarget
ChainTarget apeSDK.ChainTarget
}
func (prm *PrmAPEManagerListChains) buildRequest(c *Client) (*apemanager_v2.ListChainsRequest, error) {
func (prm *PrmAPEManagerListChains) buildRequest(c *Client) (*apemanagerV2.ListChainsRequest, error) {
if len(prm.XHeaders)%2 != 0 {
return nil, errorInvalidXHeaders
}
req := new(apemanager_v2.ListChainsRequest)
reqBody := new(apemanager_v2.ListChainsRequestBody)
req := new(apemanagerV2.ListChainsRequest)
reqBody := new(apemanagerV2.ListChainsRequestBody)
reqBody.SetTarget(prm.ChainTarget.ToV2())
req.SetBody(reqBody)
var meta session_v2.RequestMetaHeader
var meta sessionV2.RequestMetaHeader
writeXHeadersToMeta(prm.XHeaders, &meta)
c.prepareRequest(req, &meta)
@ -43,7 +43,7 @@ func (prm *PrmAPEManagerListChains) buildRequest(c *Client) (*apemanager_v2.List
type ResAPEManagerListChains struct {
statusRes
Chains []apemanager_sdk.Chain
Chains []apeSDK.Chain
}
// APEManagerListChains lists Chains for ChainTarget.
@ -69,7 +69,7 @@ func (c *Client) APEManagerListChains(ctx context.Context, prm PrmAPEManagerList
}
for _, ch := range resp.GetBody().GetChains() {
var chSDK apemanager_sdk.Chain
var chSDK apeSDK.Chain
if err := chSDK.ReadFromV2(ch); err != nil {
return nil, err
}

View file

@ -4,12 +4,12 @@ import (
"context"
"fmt"
apemanager_v2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/apemanager"
apemanagerV2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/apemanager"
rpcapi "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
session_v2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session"
sessionV2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/signature"
apemanager_sdk "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/apemanager"
apeSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/ape"
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
)
@ -17,25 +17,25 @@ import (
type PrmAPEManagerRemoveChain struct {
XHeaders []string
ChainTarget apemanager_sdk.ChainTarget
ChainTarget apeSDK.ChainTarget
ChainID apemanager_sdk.ChainID
ChainID apeSDK.ChainID
}
func (prm *PrmAPEManagerRemoveChain) buildRequest(c *Client) (*apemanager_v2.RemoveChainRequest, error) {
func (prm *PrmAPEManagerRemoveChain) buildRequest(c *Client) (*apemanagerV2.RemoveChainRequest, error) {
if len(prm.XHeaders)%2 != 0 {
return nil, errorInvalidXHeaders
}
req := new(apemanager_v2.RemoveChainRequest)
reqBody := new(apemanager_v2.RemoveChainRequestBody)
req := new(apemanagerV2.RemoveChainRequest)
reqBody := new(apemanagerV2.RemoveChainRequestBody)
reqBody.SetTarget(prm.ChainTarget.ToV2())
reqBody.SetChainID(prm.ChainID)
req.SetBody(reqBody)
var meta session_v2.RequestMetaHeader
var meta sessionV2.RequestMetaHeader
writeXHeadersToMeta(prm.XHeaders, &meta)
c.prepareRequest(req, &meta)

2
go.mod
View file

@ -3,7 +3,7 @@ module git.frostfs.info/TrueCloudLab/frostfs-sdk-go
go 1.20
require (
git.frostfs.info/TrueCloudLab/frostfs-api-go/v2 v2.16.1-0.20240516133103-0803bc6ded00
git.frostfs.info/TrueCloudLab/frostfs-api-go/v2 v2.16.1-0.20240529164544-9e825239ac5f
git.frostfs.info/TrueCloudLab/frostfs-contract v0.0.0-20230307110621-19a8ef2d02fb
git.frostfs.info/TrueCloudLab/frostfs-crypto v0.6.0
git.frostfs.info/TrueCloudLab/hrw v1.2.1

BIN
go.sum

Binary file not shown.