[#144] sdk/client: Add call option to set session token

Signed-off-by: Alex Vanin <alexey@nspcc.ru>
This commit is contained in:
Alex Vanin 2020-09-15 13:51:36 +03:00 committed by Stanislav Bogatyrev
parent 3783133173
commit 5fa271e141
2 changed files with 109 additions and 7 deletions

View file

@ -9,9 +9,11 @@ import (
"io"
"github.com/nspcc-dev/neofs-api-go/pkg/object"
signer "github.com/nspcc-dev/neofs-api-go/util/signature"
"github.com/nspcc-dev/neofs-api-go/v2/client"
v2object "github.com/nspcc-dev/neofs-api-go/v2/object"
v2refs "github.com/nspcc-dev/neofs-api-go/v2/refs"
v2session "github.com/nspcc-dev/neofs-api-go/v2/session"
"github.com/nspcc-dev/neofs-api-go/v2/signature"
"github.com/pkg/errors"
)
@ -200,8 +202,19 @@ func (c *Client) putObjectV2(ctx context.Context, p *PutObjectParams, opts ...Ca
body := new(v2object.PutRequestBody)
req.SetBody(body)
v2Addr := new(v2refs.Address)
v2Addr.SetObjectID(p.obj.GetID().ToV2())
v2Addr.SetContainerID(p.obj.GetContainerID().ToV2())
// set meta header
req.SetMetaHeader(v2MetaHeaderFromOpts(callOpts))
meta := v2MetaHeaderFromOpts(callOpts)
if err = c.attachV2SessionToken(callOpts, meta, v2SessionReqInfo{
addr: v2Addr,
verb: v2session.ObjectVerbPut,
}); err != nil {
return nil, errors.Wrap(err, "could not sign session token")
}
req.SetMetaHeader(meta)
// initialize init part
initPart := new(v2object.PutObjectPartInit)
@ -304,7 +317,14 @@ func (c *Client) deleteObjectV2(ctx context.Context, p *DeleteObjectParams, opts
req.SetBody(body)
// set meta header
req.SetMetaHeader(v2MetaHeaderFromOpts(callOpts))
meta := v2MetaHeaderFromOpts(callOpts)
if err = c.attachV2SessionToken(callOpts, meta, v2SessionReqInfo{
addr: p.addr.ToV2(),
verb: v2session.ObjectVerbDelete,
}); err != nil {
return errors.Wrap(err, "could not sign session token")
}
req.SetMetaHeader(meta)
// fill body fields
body.SetAddress(p.addr.ToV2())
@ -377,7 +397,14 @@ func (c *Client) getObjectV2(ctx context.Context, p *GetObjectParams, opts ...Ca
req.SetBody(body)
// set meta header
req.SetMetaHeader(v2MetaHeaderFromOpts(callOpts))
meta := v2MetaHeaderFromOpts(callOpts)
if err = c.attachV2SessionToken(callOpts, meta, v2SessionReqInfo{
addr: p.addr.ToV2(),
verb: v2session.ObjectVerbGet,
}); err != nil {
return nil, errors.Wrap(err, "could not sign session token")
}
req.SetMetaHeader(meta)
// fill body fields
body.SetAddress(p.addr.ToV2())
@ -503,7 +530,14 @@ func (c *Client) getObjectHeaderV2(ctx context.Context, p *ObjectHeaderParams, o
req.SetBody(body)
// set meta header
req.SetMetaHeader(v2MetaHeaderFromOpts(callOpts))
meta := v2MetaHeaderFromOpts(callOpts)
if err = c.attachV2SessionToken(callOpts, meta, v2SessionReqInfo{
addr: p.addr.ToV2(),
verb: v2session.ObjectVerbHead,
}); err != nil {
return nil, errors.Wrap(err, "could not sign session token")
}
req.SetMetaHeader(meta)
// fill body fields
body.SetAddress(p.addr.ToV2())
@ -626,7 +660,14 @@ func (c *Client) objectPayloadRangeV2(ctx context.Context, p *RangeDataParams, o
req.SetBody(body)
// set meta header
req.SetMetaHeader(v2MetaHeaderFromOpts(callOpts))
meta := v2MetaHeaderFromOpts(callOpts)
if err = c.attachV2SessionToken(callOpts, meta, v2SessionReqInfo{
addr: p.addr.ToV2(),
verb: v2session.ObjectVerbRange,
}); err != nil {
return nil, errors.Wrap(err, "could not sign session token")
}
req.SetMetaHeader(meta)
// fill body fields
body.SetAddress(p.addr.ToV2())
@ -761,7 +802,14 @@ func (c *Client) objectPayloadRangeHashV2(ctx context.Context, p *RangeChecksumP
req.SetBody(body)
// set meta header
req.SetMetaHeader(v2MetaHeaderFromOpts(callOpts))
meta := v2MetaHeaderFromOpts(callOpts)
if err = c.attachV2SessionToken(callOpts, meta, v2SessionReqInfo{
addr: p.addr.ToV2(),
verb: v2session.ObjectVerbRangeHash,
}); err != nil {
return nil, errors.Wrap(err, "could not sign session token")
}
req.SetMetaHeader(meta)
// fill body fields
body.SetAddress(p.addr.ToV2())
@ -867,3 +915,42 @@ func v2ObjectClient(proto TransportProtocol, opts *clientOptions) (*v2object.Cli
return nil, unsupportedProtocolErr
}
}
func (c Client) attachV2SessionToken(opts callOptions, hdr *v2session.RequestMetaHeader, info v2SessionReqInfo) error {
if opts.session == nil {
return nil
}
opCtx := new(v2session.ObjectSessionContext)
opCtx.SetAddress(info.addr)
opCtx.SetVerb(info.verb)
lt := new(v2session.TokenLifetime)
lt.SetIat(info.iat)
lt.SetNbf(info.nbf)
lt.SetExp(info.exp)
body := new(v2session.SessionTokenBody)
body.SetID(opts.session.ID())
body.SetSessionKey(opts.session.SessionKey())
body.SetContext(opCtx)
body.SetLifetime(lt)
token := new(v2session.SessionToken)
token.SetBody(body)
signWrapper := signature.StableMarshalerWrapper{SM: token.GetBody()}
err := signer.SignDataWithHandler(c.key, signWrapper, func(key []byte, sig []byte) {
sessionTokenSignature := new(v2refs.Signature)
sessionTokenSignature.SetKey(key)
sessionTokenSignature.SetSign(sig)
token.SetSignature(sessionTokenSignature)
})
if err != nil {
return err
}
hdr.SetSessionToken(token)
return nil
}

View file

@ -2,9 +2,11 @@ package client
import (
"github.com/nspcc-dev/neofs-api-go/pkg"
"github.com/nspcc-dev/neofs-api-go/pkg/token"
v2accounting "github.com/nspcc-dev/neofs-api-go/v2/accounting"
v2container "github.com/nspcc-dev/neofs-api-go/v2/container"
v2object "github.com/nspcc-dev/neofs-api-go/v2/object"
"github.com/nspcc-dev/neofs-api-go/v2/refs"
v2session "github.com/nspcc-dev/neofs-api-go/v2/session"
"google.golang.org/grpc"
)
@ -27,7 +29,7 @@ type (
xHeaders []xHeader
ttl uint32
epoch uint64
// add session token
session *token.SessionToken
// add bearer token
}
@ -45,6 +47,13 @@ type (
objectClientV2 *v2object.Client
}
v2SessionReqInfo struct {
addr *refs.Address
verb v2session.ObjectSessionVerb
exp, nbf, iat uint64
}
)
func defaultCallOptions() callOptions {
@ -92,6 +101,12 @@ func WithEpoch(epoch uint64) CallOption {
})
}
func WithSession(token *token.SessionToken) CallOption {
return newFuncCallOption(func(option *callOptions) {
option.session = token
})
}
func v2MetaHeaderFromOpts(options callOptions) *v2session.RequestMetaHeader {
meta := new(v2session.RequestMetaHeader)
meta.SetVersion(options.version.ToV2())