forked from TrueCloudLab/frostfs-sdk-go
[#53] session: move package from neofs-api-go
Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
This commit is contained in:
parent
1feafcbcbf
commit
ee47683848
6 changed files with 825 additions and 0 deletions
282
session/session.go
Normal file
282
session/session.go
Normal file
|
@ -0,0 +1,282 @@
|
|||
package session
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
|
||||
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
||||
"github.com/nspcc-dev/neofs-api-go/v2/session"
|
||||
v2signature "github.com/nspcc-dev/neofs-api-go/v2/signature"
|
||||
"github.com/nspcc-dev/neofs-sdk-go/owner"
|
||||
"github.com/nspcc-dev/neofs-sdk-go/signature"
|
||||
sigutil "github.com/nspcc-dev/neofs-sdk-go/util/signature"
|
||||
)
|
||||
|
||||
// Token represents NeoFS API v2-compatible
|
||||
// session token.
|
||||
type Token session.SessionToken
|
||||
|
||||
// NewTokenFromV2 wraps session.SessionToken message structure
|
||||
// into Token.
|
||||
//
|
||||
// Nil session.SessionToken converts to nil.
|
||||
func NewTokenFromV2(tV2 *session.SessionToken) *Token {
|
||||
return (*Token)(tV2)
|
||||
}
|
||||
|
||||
// NewToken creates and returns blank Token.
|
||||
//
|
||||
// Defaults:
|
||||
// - body: nil;
|
||||
// - id: nil;
|
||||
// - ownerId: nil;
|
||||
// - sessionKey: nil;
|
||||
// - exp: 0;
|
||||
// - iat: 0;
|
||||
// - nbf: 0;
|
||||
func NewToken() *Token {
|
||||
return NewTokenFromV2(new(session.SessionToken))
|
||||
}
|
||||
|
||||
// ToV2 converts Token to session.SessionToken message structure.
|
||||
//
|
||||
// Nil Token converts to nil.
|
||||
func (t *Token) ToV2() *session.SessionToken {
|
||||
return (*session.SessionToken)(t)
|
||||
}
|
||||
|
||||
func (t *Token) setBodyField(setter func(*session.SessionTokenBody)) {
|
||||
token := (*session.SessionToken)(t)
|
||||
body := token.GetBody()
|
||||
|
||||
if body == nil {
|
||||
body = new(session.SessionTokenBody)
|
||||
token.SetBody(body)
|
||||
}
|
||||
|
||||
setter(body)
|
||||
}
|
||||
|
||||
// ID returns Token identifier.
|
||||
func (t *Token) ID() []byte {
|
||||
return (*session.SessionToken)(t).
|
||||
GetBody().
|
||||
GetID()
|
||||
}
|
||||
|
||||
// SetID sets Token identifier.
|
||||
func (t *Token) SetID(v []byte) {
|
||||
t.setBodyField(func(body *session.SessionTokenBody) {
|
||||
body.SetID(v)
|
||||
})
|
||||
}
|
||||
|
||||
// OwnerID returns Token's owner identifier.
|
||||
func (t *Token) OwnerID() *owner.ID {
|
||||
return owner.NewIDFromV2(
|
||||
(*session.SessionToken)(t).
|
||||
GetBody().
|
||||
GetOwnerID(),
|
||||
)
|
||||
}
|
||||
|
||||
// SetOwnerID sets Token's owner identifier.
|
||||
func (t *Token) SetOwnerID(v *owner.ID) {
|
||||
t.setBodyField(func(body *session.SessionTokenBody) {
|
||||
body.SetOwnerID(v.ToV2())
|
||||
})
|
||||
}
|
||||
|
||||
// SessionKey returns public key of the session
|
||||
// in a binary format.
|
||||
func (t *Token) SessionKey() []byte {
|
||||
return (*session.SessionToken)(t).
|
||||
GetBody().
|
||||
GetSessionKey()
|
||||
}
|
||||
|
||||
// SetSessionKey sets public key of the session
|
||||
// in a binary format.
|
||||
func (t *Token) SetSessionKey(v []byte) {
|
||||
t.setBodyField(func(body *session.SessionTokenBody) {
|
||||
body.SetSessionKey(v)
|
||||
})
|
||||
}
|
||||
|
||||
func (t *Token) setLifetimeField(f func(*session.TokenLifetime)) {
|
||||
t.setBodyField(func(body *session.SessionTokenBody) {
|
||||
lt := body.GetLifetime()
|
||||
if lt == nil {
|
||||
lt = new(session.TokenLifetime)
|
||||
body.SetLifetime(lt)
|
||||
}
|
||||
|
||||
f(lt)
|
||||
})
|
||||
}
|
||||
|
||||
// Exp returns epoch number of the token expiration.
|
||||
func (t *Token) Exp() uint64 {
|
||||
return (*session.SessionToken)(t).
|
||||
GetBody().
|
||||
GetLifetime().
|
||||
GetExp()
|
||||
}
|
||||
|
||||
// SetExp sets epoch number of the token expiration.
|
||||
func (t *Token) SetExp(exp uint64) {
|
||||
t.setLifetimeField(func(lt *session.TokenLifetime) {
|
||||
lt.SetExp(exp)
|
||||
})
|
||||
}
|
||||
|
||||
// Nbf returns starting epoch number of the token.
|
||||
func (t *Token) Nbf() uint64 {
|
||||
return (*session.SessionToken)(t).
|
||||
GetBody().
|
||||
GetLifetime().
|
||||
GetNbf()
|
||||
}
|
||||
|
||||
// SetNbf sets starting epoch number of the token.
|
||||
func (t *Token) SetNbf(nbf uint64) {
|
||||
t.setLifetimeField(func(lt *session.TokenLifetime) {
|
||||
lt.SetNbf(nbf)
|
||||
})
|
||||
}
|
||||
|
||||
// Iat returns starting epoch number of the token.
|
||||
func (t *Token) Iat() uint64 {
|
||||
return (*session.SessionToken)(t).
|
||||
GetBody().
|
||||
GetLifetime().
|
||||
GetIat()
|
||||
}
|
||||
|
||||
// SetIat sets the number of the epoch in which the token was issued.
|
||||
func (t *Token) SetIat(iat uint64) {
|
||||
t.setLifetimeField(func(lt *session.TokenLifetime) {
|
||||
lt.SetIat(iat)
|
||||
})
|
||||
}
|
||||
|
||||
// Sign calculates and writes signature of the Token data.
|
||||
//
|
||||
// Returns signature calculation errors.
|
||||
func (t *Token) Sign(key *ecdsa.PrivateKey) error {
|
||||
tV2 := (*session.SessionToken)(t)
|
||||
|
||||
signedData := v2signature.StableMarshalerWrapper{
|
||||
SM: tV2.GetBody(),
|
||||
}
|
||||
|
||||
return sigutil.SignDataWithHandler(key, signedData, func(key, sig []byte) {
|
||||
tSig := tV2.GetSignature()
|
||||
if tSig == nil {
|
||||
tSig = new(refs.Signature)
|
||||
}
|
||||
|
||||
tSig.SetKey(key)
|
||||
tSig.SetSign(sig)
|
||||
|
||||
tV2.SetSignature(tSig)
|
||||
})
|
||||
}
|
||||
|
||||
// VerifySignature checks if token signature is
|
||||
// presented and valid.
|
||||
func (t *Token) VerifySignature() bool {
|
||||
tV2 := (*session.SessionToken)(t)
|
||||
|
||||
signedData := v2signature.StableMarshalerWrapper{
|
||||
SM: tV2.GetBody(),
|
||||
}
|
||||
|
||||
return sigutil.VerifyDataWithSource(signedData, func() (key, sig []byte) {
|
||||
tSig := tV2.GetSignature()
|
||||
return tSig.GetKey(), tSig.GetSign()
|
||||
}) == nil
|
||||
}
|
||||
|
||||
// Signature returns Token signature.
|
||||
func (t *Token) Signature() *signature.Signature {
|
||||
return signature.NewFromV2(
|
||||
(*session.SessionToken)(t).
|
||||
GetSignature(),
|
||||
)
|
||||
}
|
||||
|
||||
// SetContext sets context of the Token.
|
||||
//
|
||||
// Supported contexts:
|
||||
// - *ContainerContext.
|
||||
//
|
||||
// Resets context if it is not supported.
|
||||
func (t *Token) SetContext(v interface{}) {
|
||||
var cV2 session.SessionTokenContext
|
||||
|
||||
switch c := v.(type) {
|
||||
case *ContainerContext:
|
||||
cV2 = c.ToV2()
|
||||
}
|
||||
|
||||
t.setBodyField(func(body *session.SessionTokenBody) {
|
||||
body.SetContext(cV2)
|
||||
})
|
||||
}
|
||||
|
||||
// Context returns context of the Token.
|
||||
//
|
||||
// Supports same contexts as SetContext.
|
||||
//
|
||||
// Returns nil if context is not supported.
|
||||
func (t *Token) Context() interface{} {
|
||||
switch v := (*session.SessionToken)(t).
|
||||
GetBody().
|
||||
GetContext(); c := v.(type) {
|
||||
default:
|
||||
return nil
|
||||
case *session.ContainerSessionContext:
|
||||
return ContainerContextFromV2(c)
|
||||
}
|
||||
}
|
||||
|
||||
// GetContainerContext is a helper function that casts
|
||||
// Token context to ContainerContext.
|
||||
//
|
||||
// Returns nil if context is not a ContainerContext.
|
||||
func GetContainerContext(t *Token) *ContainerContext {
|
||||
c, _ := t.Context().(*ContainerContext)
|
||||
return c
|
||||
}
|
||||
|
||||
// Marshal marshals Token into a protobuf binary form.
|
||||
//
|
||||
// Buffer is allocated when the argument is empty.
|
||||
// Otherwise, the first buffer is used.
|
||||
func (t *Token) Marshal(bs ...[]byte) ([]byte, error) {
|
||||
var buf []byte
|
||||
if len(bs) > 0 {
|
||||
buf = bs[0]
|
||||
}
|
||||
|
||||
return (*session.SessionToken)(t).
|
||||
StableMarshal(buf)
|
||||
}
|
||||
|
||||
// Unmarshal unmarshals protobuf binary representation of Token.
|
||||
func (t *Token) Unmarshal(data []byte) error {
|
||||
return (*session.SessionToken)(t).
|
||||
Unmarshal(data)
|
||||
}
|
||||
|
||||
// MarshalJSON encodes Token to protobuf JSON format.
|
||||
func (t *Token) MarshalJSON() ([]byte, error) {
|
||||
return (*session.SessionToken)(t).
|
||||
MarshalJSON()
|
||||
}
|
||||
|
||||
// UnmarshalJSON decodes Token from protobuf JSON format.
|
||||
func (t *Token) UnmarshalJSON(data []byte) error {
|
||||
return (*session.SessionToken)(t).
|
||||
UnmarshalJSON(data)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue