package session import ( "crypto/ecdsa" "github.com/nspcc-dev/neofs-api-go/pkg" "github.com/nspcc-dev/neofs-api-go/pkg/owner" "github.com/nspcc-dev/neofs-api-go/util/signature" "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" ) // Token represents NeoFS API v2-compatible // session token. type Token session.SessionToken // NewTokenFromV2 wraps session.SessionToken message structure // into Token. func NewTokenFromV2(tV2 *session.SessionToken) *Token { return (*Token)(tV2) } // NewToken creates and returns blank Token. func NewToken() *Token { return NewTokenFromV2(new(session.SessionToken)) } // ToV2 converts Token to session.SessionToken message structure. 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) }) } // 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 signature.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 signature.VerifyDataWithSource(signedData, func() (key, sig []byte) { tSig := tV2.GetSignature() return tSig.GetKey(), tSig.GetSign() }) == nil } // Signature returns Token signature. func (t *Token) Signature() *pkg.Signature { return pkg.NewSignatureFromV2( (*session.SessionToken)(t). GetSignature(), ) } // 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) }