Skip to content

Commit

Permalink
WIP: bearer: Improve testing and increase coverage
Browse files Browse the repository at this point in the history
Signed-off-by: Leonard Lyubich <leonard@morphbits.io>
  • Loading branch information
cthulhu-rider committed Sep 18, 2024
1 parent cd58843 commit 393c5f9
Showing 1 changed file with 153 additions and 67 deletions.
220 changes: 153 additions & 67 deletions bearer/bearer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,68 @@ package bearer_test

import (
"bytes"
"math"
"testing"

"github.com/nspcc-dev/neofs-api-go/v2/acl"
"github.com/nspcc-dev/neofs-api-go/v2/refs"
"github.com/nspcc-dev/neofs-sdk-go/bearer"
bearertest "github.com/nspcc-dev/neofs-sdk-go/bearer/test"
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
cidtest "github.com/nspcc-dev/neofs-sdk-go/container/id/test"
neofscrypto "github.com/nspcc-dev/neofs-sdk-go/crypto"
neofscryptotest "github.com/nspcc-dev/neofs-sdk-go/crypto/test"
"github.com/nspcc-dev/neofs-sdk-go/eacl"
eacltest "github.com/nspcc-dev/neofs-sdk-go/eacl/test"
"github.com/nspcc-dev/neofs-sdk-go/user"
usertest "github.com/nspcc-dev/neofs-sdk-go/user/test"
"github.com/stretchr/testify/require"
)

// Bearer token components.
const (
anyValidExp = 32058350
anyValidIat = 1209418302
anyValidNbf = 93843742391
)

// Crypto.
const (
anyValidSignatureScheme = 1208743532
)

var (
anyValidIssuerPublicKeyBytes = []byte{3, 202, 217, 142, 98, 209, 190, 188, 145, 123, 174, 21, 173, 239, 239,
245, 67, 148, 205, 119, 58, 223, 219, 209, 220, 113, 215, 134, 228, 101, 249, 34, 218}
anyValidSignatureBytes = []byte("any_signature") // valid structurally, not logically
anyValidSignature = neofscrypto.NewSignatureFromRawKey(anyValidSignatureScheme, anyValidIssuerPublicKeyBytes, anyValidSignatureBytes)
)

// Other NeoFS stuff.
var (
anyValidContainerID = cid.ID{243, 245, 75, 198, 48, 107, 141, 121, 255, 49, 51, 168, 21, 254, 62, 66,
6, 147, 43, 35, 99, 242, 163, 20, 26, 30, 147, 240, 79, 114, 252, 227}
anyValidIssuer = user.ID{53, 51, 5, 166, 111, 29, 20, 101, 192, 165, 28, 167, 57,
160, 82, 80, 41, 203, 20, 254, 30, 138, 195, 17, 92}
anyValidSubject = user.ID{53, 147, 14, 186, 66, 195, 247, 51, 14, 249, 145, 102,
233, 115, 142, 143, 145, 26, 229, 252, 61, 36, 160, 242, 243}
)

// EACL.
var (
anyValidFilters = []eacl.Filter{
eacl.ConstructFilter(eacl.FilterHeaderType(4509681), "key_54093643", eacl.Match(949385), "val_34811040"),
eacl.ConstructFilter(eacl.FilterHeaderType(582984), "key_1298432", eacl.Match(7539428), "val_8243258"),
}
anyValidTargets = []eacl.Target{
eacl.NewTargetByRole(eacl.Role(690857412)),
}
anyValidRecords = []eacl.Record{
eacl.ConstructRecord(eacl.Action(5692342), eacl.Operation(12943052), []eacl.Target{anyValidTargets[0]}, anyValidFilters[0]),
eacl.ConstructRecord(eacl.Action(43658603), eacl.Operation(12943052), anyValidTargets, anyValidFilters...),
}
anyValidEACL = eacl.NewTableForContainer(anyValidContainerID, anyValidRecords)
)

// compares binary representations of two eacl.Table instances.
func isEqualEACLTables(t1, t2 eacl.Table) bool {
return bytes.Equal(t1.Marshal(), t2.Marshal())
Expand Down Expand Up @@ -244,76 +291,115 @@ func TestToken_SignedData(t *testing.T) {
}

func TestToken_ReadFromV2(t *testing.T) {
var val bearer.Token
var lt acl.TokenLifetime
lt.SetExp(anyValidExp)
lt.SetIat(anyValidIat)
lt.SetNbf(anyValidNbf)
var ms refs.OwnerID
ms.SetValue(anyValidSubject[:])
var mi refs.OwnerID
mi.SetValue(anyValidIssuer[:])
var mb acl.BearerTokenBody
mb.SetEACL(anyValidEACL.ToV2())
mb.SetOwnerID(&ms)
mb.SetIssuer(&mi)
mb.SetLifetime(&lt)
var msig refs.Signature
anyValidSignature.WriteToV2(&msig)
var m acl.BearerToken
m.SetBody(&mb)
m.SetSignature(&msig)

require.Error(t, val.ReadFromV2(m))

var body acl.BearerTokenBody
m.SetBody(&body)

require.Error(t, val.ReadFromV2(m))

eaclTable := eacltest.Table()
eaclTableV2 := eaclTable.ToV2()
body.SetEACL(eaclTableV2)

require.Error(t, val.ReadFromV2(m))

var lifetime acl.TokenLifetime
body.SetLifetime(&lifetime)

require.Error(t, val.ReadFromV2(m))

const iat, nbf, exp = 1, 2, 3
lifetime.SetIat(iat)
lifetime.SetNbf(nbf)
lifetime.SetExp(exp)

body.SetLifetime(&lifetime)

require.Error(t, val.ReadFromV2(m))

var sig refs.Signature
m.SetSignature(&sig)

require.NoError(t, val.ReadFromV2(m))

var m2 acl.BearerToken

val.WriteToV2(&m2)
require.Equal(t, m, m2)

usr, usr2 := usertest.ID(), usertest.ID()

require.True(t, val.AssertUser(usr))
require.True(t, val.AssertUser(usr2))

var usrV2 refs.OwnerID
usr.WriteToV2(&usrV2)

body.SetOwnerID(&usrV2)

require.NoError(t, val.ReadFromV2(m))

val.WriteToV2(&m2)
require.Equal(t, m, m2)

require.True(t, val.AssertUser(usr))
require.False(t, val.AssertUser(usr2))

var s neofscrypto.Signature

require.NoError(t, s.CalculateMarshalled(neofscryptotest.Signer(), &body, nil))

s.WriteToV2(&sig)

var val bearer.Token
require.NoError(t, val.ReadFromV2(m))
require.True(t, val.VerifySignature())
s, ok := val.Signature()
require.Equal(t, anyValidEACL, val.EACLTable())
require.Equal(t, anyValidIssuer, val.Issuer())
require.True(t, val.AssertUser(anyValidSubject))
require.EqualValues(t, anyValidExp, val.Exp())
require.EqualValues(t, anyValidIat, val.Iat())
require.EqualValues(t, anyValidNbf, val.Nbf())
sig, ok := val.Signature()
require.True(t, ok)
require.True(t, s.Verify(body.StableMarshal(nil)))
require.Equal(t, sig.GetKey(), s.PublicKeyBytes())
require.Equal(t, anyValidSignature, sig)

// reset optional fields
mb.SetIssuer(nil)
mb.SetOwnerID(nil)
val2 := val
require.NoError(t, val2.ReadFromV2(m))
require.Zero(t, val2.Issuer())
require.True(t, val2.AssertUser(usertest.ID()))

t.Run("invalid", func(t *testing.T) {
for _, tc := range []struct {
name, err string
corrupt func(*acl.BearerToken)
}{
{name: "body/missing", err: "missing token body",
corrupt: func(m *acl.BearerToken) { m.SetBody(nil) }},
{name: "invalid container/nil value", err: "invalid eACL: invalid container ID: invalid length 0",
corrupt: func(m *acl.BearerToken) { m.GetBody().GetEACL().SetContainerID(new(refs.ContainerID)) }},
{name: "invalid container/empty value", err: "invalid eACL: invalid container ID: invalid length 0", corrupt: func(m *acl.BearerToken) {
var mc refs.ContainerID
mc.SetValue([]byte{})
m.GetBody().GetEACL().SetContainerID(&mc)
}},
{name: "invalid container/undersized value", err: "invalid eACL: invalid container ID: invalid length 31", corrupt: func(m *acl.BearerToken) {
var mc refs.ContainerID
mc.SetValue(make([]byte, 31))
m.GetBody().GetEACL().SetContainerID(&mc)
}},
{name: "invalid container/oversized value", err: "invalid eACL: invalid container ID: invalid length 33", corrupt: func(m *acl.BearerToken) {
var mc refs.ContainerID
mc.SetValue(make([]byte, 33))
m.GetBody().GetEACL().SetContainerID(&mc)
}},
{name: "body/subject/value/nil", err: "invalid target user: invalid length 0, expected 25",
corrupt: func(m *acl.BearerToken) { m.GetBody().GetOwnerID().SetValue(nil) }},
{name: "body/subject/value/empty", err: "invalid target user: invalid length 0, expected 25",
corrupt: func(m *acl.BearerToken) { m.GetBody().GetOwnerID().SetValue([]byte{}) }},
{name: "body/subject/value/undersize", err: "invalid target user: invalid length 24, expected 25",
corrupt: func(m *acl.BearerToken) { m.GetBody().GetOwnerID().SetValue(make([]byte, 24)) }},
{name: "body/subject/value/oversize", err: "invalid target user: invalid length 26, expected 25",
corrupt: func(m *acl.BearerToken) { m.GetBody().GetOwnerID().SetValue(make([]byte, 26)) }},
{name: "body/subject/value/wrong prefix", err: "invalid target user: invalid prefix byte 0x42, expected 0x35",
corrupt: func(m *acl.BearerToken) { m.GetBody().GetOwnerID().GetValue()[0] = 0x42 }},
{name: "body/subject/value/checksum mismatch", err: "invalid target user: checksum mismatch",
corrupt: func(m *acl.BearerToken) {
v := m.GetBody().GetOwnerID().GetValue()
v[len(v)-1]++
}},
{name: "body/lifetime/missing", err: "missing token lifetime",
corrupt: func(m *acl.BearerToken) { m.GetBody().SetLifetime(nil) }},
{name: "body/issuer/value/nil", err: "invalid issuer: invalid length 0, expected 25",
corrupt: func(m *acl.BearerToken) { m.GetBody().GetIssuer().SetValue(nil) }},
{name: "body/issuer/value/empty", err: "invalid issuer: invalid length 0, expected 25",
corrupt: func(m *acl.BearerToken) { m.GetBody().GetIssuer().SetValue([]byte{}) }},
{name: "body/issuer/value/undersize", err: "invalid issuer: invalid length 24, expected 25",
corrupt: func(m *acl.BearerToken) { m.GetBody().GetIssuer().SetValue(make([]byte, 24)) }},
{name: "body/issuer/value/oversize", err: "invalid issuer: invalid length 26, expected 25",
corrupt: func(m *acl.BearerToken) { m.GetBody().GetIssuer().SetValue(make([]byte, 26)) }},
{name: "body/issuer/value/wrong prefix", err: "invalid issuer: invalid prefix byte 0x42, expected 0x35",
corrupt: func(m *acl.BearerToken) { m.GetBody().GetIssuer().GetValue()[0] = 0x42 }},
{name: "body/issuer/value/checksum mismatch", err: "invalid issuer: checksum mismatch",
corrupt: func(m *acl.BearerToken) {
v := m.GetBody().GetIssuer().GetValue()
v[len(v)-1]++
}},
{name: "signature/missing", err: "missing body signature",
corrupt: func(m *acl.BearerToken) { m.SetSignature(nil) }},
{name: "signature/invalid scheme", err: "invalid body signature: scheme 2147483648 overflows int32",
corrupt: func(m *acl.BearerToken) { m.GetSignature().SetScheme(math.MaxInt32 + 1) }},
} {
t.Run(tc.name, func(t *testing.T) {
st := val
var m acl.BearerToken
st.WriteToV2(&m)
tc.corrupt(&m)
require.EqualError(t, new(bearer.Token).ReadFromV2(m), tc.err)
})
}
})
}

func TestResolveIssuer(t *testing.T) {
Expand Down

0 comments on commit 393c5f9

Please sign in to comment.