forked from TrueCloudLab/frostfs-api-go
Merge pull request #92 from nspcc-dev/add-bearer-token-to-request-data
Add bearer token to signed request data
This commit is contained in:
commit
2bef390cc6
7 changed files with 98 additions and 0 deletions
|
@ -12,6 +12,10 @@ type signedBearerToken struct {
|
||||||
BearerToken
|
BearerToken
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type bearerMsgWrapper struct {
|
||||||
|
*BearerTokenMsg
|
||||||
|
}
|
||||||
|
|
||||||
const fixedBearerTokenDataSize = 0 +
|
const fixedBearerTokenDataSize = 0 +
|
||||||
refs.OwnerIDSize +
|
refs.OwnerIDSize +
|
||||||
8
|
8
|
||||||
|
@ -124,3 +128,29 @@ func (m *BearerTokenMsg) SetOwnerKey(v []byte) {
|
||||||
func (m *BearerTokenMsg) SetSignature(v []byte) {
|
func (m *BearerTokenMsg) SetSignature(v []byte) {
|
||||||
m.Signature = v
|
m.Signature = v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func wrapBearerTokenMsg(msg *BearerTokenMsg) bearerMsgWrapper {
|
||||||
|
return bearerMsgWrapper{
|
||||||
|
BearerTokenMsg: msg,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExpirationEpoch returns the result of ValidUntil field getter.
|
||||||
|
//
|
||||||
|
// If message is nil, 0 returns.
|
||||||
|
func (s bearerMsgWrapper) ExpirationEpoch() uint64 {
|
||||||
|
if s.BearerTokenMsg != nil {
|
||||||
|
return s.GetValidUntil()
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetExpirationEpoch passes argument to ValidUntil field setter.
|
||||||
|
//
|
||||||
|
// If message is nil, nothing changes.
|
||||||
|
func (s bearerMsgWrapper) SetExpirationEpoch(v uint64) {
|
||||||
|
if s.BearerTokenMsg != nil {
|
||||||
|
s.SetValidUntil(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -194,3 +194,18 @@ func TestBearerTokenMsg_Setters(t *testing.T) {
|
||||||
s.SetSignature(sig)
|
s.SetSignature(sig)
|
||||||
require.Equal(t, sig, s.GetSignature())
|
require.Equal(t, sig, s.GetSignature())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBearerMsgWrapper_ExpirationEpoch(t *testing.T) {
|
||||||
|
s := wrapBearerTokenMsg(nil)
|
||||||
|
require.Zero(t, s.ExpirationEpoch())
|
||||||
|
require.NotPanics(t, func() {
|
||||||
|
s.SetExpirationEpoch(1)
|
||||||
|
})
|
||||||
|
|
||||||
|
msg := new(BearerTokenMsg)
|
||||||
|
s = wrapBearerTokenMsg(msg)
|
||||||
|
|
||||||
|
epoch := uint64(7)
|
||||||
|
s.SetExpirationEpoch(epoch)
|
||||||
|
require.Equal(t, epoch, s.ExpirationEpoch())
|
||||||
|
}
|
||||||
|
|
|
@ -209,6 +209,9 @@ func SignRequestData(key *ecdsa.PrivateKey, src RequestSignedData) error {
|
||||||
NewSignedSessionToken(
|
NewSignedSessionToken(
|
||||||
src.GetSessionToken(),
|
src.GetSessionToken(),
|
||||||
),
|
),
|
||||||
|
NewSignedBearerToken(
|
||||||
|
src.GetBearerToken(),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -231,6 +234,9 @@ func VerifyRequestData(src RequestVerifyData) error {
|
||||||
NewVerifiedSessionToken(
|
NewVerifiedSessionToken(
|
||||||
src.GetSessionToken(),
|
src.GetSessionToken(),
|
||||||
),
|
),
|
||||||
|
NewVerifiedBearerToken(
|
||||||
|
src.GetBearerToken(),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -18,6 +18,8 @@ type testSignedDataSrc struct {
|
||||||
sig []byte
|
sig []byte
|
||||||
key *ecdsa.PublicKey
|
key *ecdsa.PublicKey
|
||||||
token SessionToken
|
token SessionToken
|
||||||
|
|
||||||
|
bearer BearerToken
|
||||||
}
|
}
|
||||||
|
|
||||||
type testSignedDataReader struct {
|
type testSignedDataReader struct {
|
||||||
|
@ -54,6 +56,10 @@ func (s testSignedDataSrc) GetSessionToken() SessionToken {
|
||||||
return s.token
|
return s.token
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s testSignedDataSrc) GetBearerToken() BearerToken {
|
||||||
|
return s.bearer
|
||||||
|
}
|
||||||
|
|
||||||
func (s testSignedDataReader) SignedDataSize() int {
|
func (s testSignedDataReader) SignedDataSize() int {
|
||||||
return len(s.data)
|
return len(s.data)
|
||||||
}
|
}
|
||||||
|
@ -273,14 +279,21 @@ func TestSignVerifyDataWithSessionToken(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
token = new(Token)
|
token = new(Token)
|
||||||
initVerb = Token_Info_Verb(1)
|
initVerb = Token_Info_Verb(1)
|
||||||
|
|
||||||
|
bearer = wrapBearerTokenMsg(new(BearerTokenMsg))
|
||||||
|
bearerEpoch = uint64(8)
|
||||||
)
|
)
|
||||||
|
|
||||||
token.SetVerb(initVerb)
|
token.SetVerb(initVerb)
|
||||||
|
|
||||||
|
bearer.SetExpirationEpoch(bearerEpoch)
|
||||||
|
|
||||||
// create test data with token
|
// create test data with token
|
||||||
src := &testSignedDataSrc{
|
src := &testSignedDataSrc{
|
||||||
data: testData(t, 10),
|
data: testData(t, 10),
|
||||||
token: token,
|
token: token,
|
||||||
|
|
||||||
|
bearer: bearer,
|
||||||
}
|
}
|
||||||
|
|
||||||
// create test private key
|
// create test private key
|
||||||
|
@ -313,6 +326,18 @@ func TestSignVerifyDataWithSessionToken(t *testing.T) {
|
||||||
// ascertain that verification is passed
|
// ascertain that verification is passed
|
||||||
require.NoError(t, VerifyRequestData(src))
|
require.NoError(t, VerifyRequestData(src))
|
||||||
|
|
||||||
|
// break the Bearer token
|
||||||
|
bearer.SetExpirationEpoch(bearerEpoch + 1)
|
||||||
|
|
||||||
|
// ascertain that verification is failed
|
||||||
|
require.Error(t, VerifyRequestData(src))
|
||||||
|
|
||||||
|
// restore the Bearer token
|
||||||
|
bearer.SetExpirationEpoch(bearerEpoch)
|
||||||
|
|
||||||
|
// ascertain that verification is passed
|
||||||
|
require.NoError(t, VerifyRequestData(src))
|
||||||
|
|
||||||
// wrap to data reader
|
// wrap to data reader
|
||||||
rdr := &testSignedDataReader{
|
rdr := &testSignedDataReader{
|
||||||
testSignedDataSrc: src,
|
testSignedDataSrc: src,
|
||||||
|
|
|
@ -254,6 +254,7 @@ type DataWithSignKeySource interface {
|
||||||
type RequestData interface {
|
type RequestData interface {
|
||||||
SignedDataSource
|
SignedDataSource
|
||||||
SessionTokenSource
|
SessionTokenSource
|
||||||
|
BearerTokenSource
|
||||||
}
|
}
|
||||||
|
|
||||||
// RequestSignedData is an interface of request information with signature write access.
|
// RequestSignedData is an interface of request information with signature write access.
|
||||||
|
|
|
@ -103,3 +103,14 @@ func (t testCustomField) MarshalTo(data []byte) (int, error) { return 0, nil }
|
||||||
|
|
||||||
// Marshal skip, it's for test usage only.
|
// Marshal skip, it's for test usage only.
|
||||||
func (t testCustomField) Marshal() ([]byte, error) { return nil, nil }
|
func (t testCustomField) Marshal() ([]byte, error) { return nil, nil }
|
||||||
|
|
||||||
|
// GetBearerToken wraps Bearer field and return BearerToken interface.
|
||||||
|
//
|
||||||
|
// If Bearer field value is nil, nil returns.
|
||||||
|
func (m RequestVerificationHeader) GetBearerToken() BearerToken {
|
||||||
|
if t := m.GetBearer(); t != nil {
|
||||||
|
return wrapBearerTokenMsg(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -128,3 +128,13 @@ func TestRequestVerificationHeader_SetBearer(t *testing.T) {
|
||||||
|
|
||||||
require.Equal(t, token, h.GetBearer())
|
require.Equal(t, token, h.GetBearer())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRequestVerificationHeader_GetBearerToken(t *testing.T) {
|
||||||
|
s := new(RequestVerificationHeader)
|
||||||
|
|
||||||
|
require.Nil(t, s.GetBearerToken())
|
||||||
|
|
||||||
|
bearer := new(BearerTokenMsg)
|
||||||
|
s.SetBearer(bearer)
|
||||||
|
require.Equal(t, wrapBearerTokenMsg(bearer), s.GetBearerToken())
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue