forked from TrueCloudLab/frostfs-api-go
e023b6e51e
Now owner ID field is not required to be set. According to latest neofs-api, this field set if token was issued for specific owner ID. If this field is not set, then any user can use this token while it is correctly signed and has valid lifetime. Lifetime is also can be omitted since node interpret empty lifetime as a lifetime with zero values. Signed-off-by: Alex Vanin <alexey@nspcc.ru>
105 lines
2.2 KiB
Go
105 lines
2.2 KiB
Go
package token
|
|
|
|
import (
|
|
"crypto/ecdsa"
|
|
"errors"
|
|
|
|
"github.com/nspcc-dev/neofs-api-go/pkg/acl/eacl"
|
|
"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/acl"
|
|
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
|
v2signature "github.com/nspcc-dev/neofs-api-go/v2/signature"
|
|
)
|
|
|
|
type BearerToken struct {
|
|
token acl.BearerToken
|
|
}
|
|
|
|
func (b BearerToken) ToV2() *acl.BearerToken {
|
|
return &b.token
|
|
}
|
|
|
|
func (b *BearerToken) SetLifetime(exp, nbf, iat uint64) {
|
|
body := b.token.GetBody()
|
|
if body == nil {
|
|
body = new(acl.BearerTokenBody)
|
|
}
|
|
|
|
lt := new(acl.TokenLifetime)
|
|
lt.SetExp(exp)
|
|
lt.SetNbf(nbf)
|
|
lt.SetIat(iat)
|
|
|
|
body.SetLifetime(lt)
|
|
b.token.SetBody(body)
|
|
}
|
|
|
|
func (b *BearerToken) SetEACLTable(table *eacl.Table) {
|
|
body := b.token.GetBody()
|
|
if body == nil {
|
|
body = new(acl.BearerTokenBody)
|
|
}
|
|
|
|
body.SetEACL(table.ToV2())
|
|
b.token.SetBody(body)
|
|
}
|
|
|
|
func (b *BearerToken) SetOwner(id *owner.ID) {
|
|
body := b.token.GetBody()
|
|
if body == nil {
|
|
body = new(acl.BearerTokenBody)
|
|
}
|
|
|
|
body.SetOwnerID(id.ToV2())
|
|
b.token.SetBody(body)
|
|
}
|
|
|
|
func (b *BearerToken) SignToken(key *ecdsa.PrivateKey) error {
|
|
err := sanityCheck(b)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
signWrapper := v2signature.StableMarshalerWrapper{SM: b.token.GetBody()}
|
|
return signature.SignDataWithHandler(key, signWrapper, func(key []byte, sig []byte) {
|
|
bearerSignature := new(refs.Signature)
|
|
bearerSignature.SetKey(key)
|
|
bearerSignature.SetSign(sig)
|
|
b.token.SetSignature(bearerSignature)
|
|
})
|
|
}
|
|
|
|
func NewBearerToken() *BearerToken {
|
|
b := new(BearerToken)
|
|
b.token = acl.BearerToken{}
|
|
b.token.SetBody(new(acl.BearerTokenBody))
|
|
|
|
return b
|
|
}
|
|
|
|
func NewBearerTokenFromV2(v2 *acl.BearerToken) *BearerToken {
|
|
if v2 == nil {
|
|
v2 = new(acl.BearerToken)
|
|
}
|
|
|
|
return &BearerToken{
|
|
token: *v2,
|
|
}
|
|
}
|
|
|
|
// sanityCheck if bearer token is ready to be issued
|
|
func sanityCheck(b *BearerToken) error {
|
|
switch {
|
|
case b == nil:
|
|
return errors.New("bearer token is not set")
|
|
case b.token.GetBody() == nil:
|
|
return errors.New("bearer token body is not set")
|
|
case b.token.GetBody().GetEACL() == nil:
|
|
return errors.New("bearer token EACL table is not set")
|
|
}
|
|
|
|
// consider checking EACL sanity there, lifetime correctness, etc.
|
|
|
|
return nil
|
|
}
|