package bearer_test import ( "bytes" "math/rand" "testing" "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/acl" "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer" bearertest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer/test" cidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id/test" frostfscrypto "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto" frostfsecdsa "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto/ecdsa" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/eacl" eacltest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/eacl/test" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user" usertest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user/test" "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/stretchr/testify/require" ) // compares binary representations of two eacl.Table instances. func isEqualEACLTables(t1, t2 eacl.Table) bool { d1, err := t1.Marshal() if err != nil { panic(err) } d2, err := t2.Marshal() if err != nil { panic(err) } return bytes.Equal(d1, d2) } func TestToken_SetEACLTable(t *testing.T) { var val bearer.Token var m acl.BearerToken filled := bearertest.Token() val.WriteToV2(&m) require.Zero(t, m.GetBody()) val2 := filled require.NoError(t, val2.Unmarshal(val.Marshal())) require.Zero(t, val2.EACLTable()) val2 = filled jd, err := val.MarshalJSON() require.NoError(t, err) require.NoError(t, val2.UnmarshalJSON(jd)) require.Zero(t, val2.EACLTable()) // set value eaclTable := *eacltest.Table() val.SetEACLTable(eaclTable) require.True(t, isEqualEACLTables(eaclTable, val.EACLTable())) val.WriteToV2(&m) eaclTableV2 := eaclTable.ToV2() require.Equal(t, eaclTableV2, m.GetBody().GetEACL()) val2 = filled require.NoError(t, val2.Unmarshal(val.Marshal())) require.True(t, isEqualEACLTables(eaclTable, val.EACLTable())) val2 = filled jd, err = val.MarshalJSON() require.NoError(t, err) require.NoError(t, val2.UnmarshalJSON(jd)) require.True(t, isEqualEACLTables(eaclTable, val.EACLTable())) } func TestToken_ForUser(t *testing.T) { var val bearer.Token var m acl.BearerToken filled := bearertest.Token() val.WriteToV2(&m) require.Zero(t, m.GetBody()) val2 := filled require.NoError(t, val2.Unmarshal(val.Marshal())) val2.WriteToV2(&m) require.Zero(t, m.GetBody()) val2 = filled jd, err := val.MarshalJSON() require.NoError(t, err) require.NoError(t, val2.UnmarshalJSON(jd)) val2.WriteToV2(&m) require.Zero(t, m.GetBody()) // set value usr := *usertest.ID() var usrV2 refs.OwnerID usr.WriteToV2(&usrV2) val.ForUser(usr) val.WriteToV2(&m) require.Equal(t, usrV2, *m.GetBody().GetOwnerID()) val2 = filled require.NoError(t, val2.Unmarshal(val.Marshal())) val2.WriteToV2(&m) require.Equal(t, usrV2, *m.GetBody().GetOwnerID()) val2 = filled jd, err = val.MarshalJSON() require.NoError(t, err) require.NoError(t, val2.UnmarshalJSON(jd)) val2.WriteToV2(&m) require.Equal(t, usrV2, *m.GetBody().GetOwnerID()) } func testLifetimeClaim(t *testing.T, setter func(*bearer.Token, uint64), getter func(*acl.BearerToken) uint64) { var val bearer.Token var m acl.BearerToken filled := bearertest.Token() val.WriteToV2(&m) require.Zero(t, m.GetBody()) val2 := filled require.NoError(t, val2.Unmarshal(val.Marshal())) val2.WriteToV2(&m) require.Zero(t, m.GetBody()) val2 = filled jd, err := val.MarshalJSON() require.NoError(t, err) require.NoError(t, val2.UnmarshalJSON(jd)) val2.WriteToV2(&m) require.Zero(t, m.GetBody()) // set value exp := rand.Uint64() setter(&val, exp) val.WriteToV2(&m) require.Equal(t, exp, getter(&m)) val2 = filled require.NoError(t, val2.Unmarshal(val.Marshal())) val2.WriteToV2(&m) require.Equal(t, exp, getter(&m)) val2 = filled jd, err = val.MarshalJSON() require.NoError(t, err) require.NoError(t, val2.UnmarshalJSON(jd)) val2.WriteToV2(&m) require.Equal(t, exp, getter(&m)) } func TestToken_SetLifetime(t *testing.T) { t.Run("iat", func(t *testing.T) { testLifetimeClaim(t, (*bearer.Token).SetIat, func(token *acl.BearerToken) uint64 { return token.GetBody().GetLifetime().GetIat() }) }) t.Run("nbf", func(t *testing.T) { testLifetimeClaim(t, (*bearer.Token).SetNbf, func(token *acl.BearerToken) uint64 { return token.GetBody().GetLifetime().GetNbf() }) }) t.Run("exp", func(t *testing.T) { testLifetimeClaim(t, (*bearer.Token).SetExp, func(token *acl.BearerToken) uint64 { return token.GetBody().GetLifetime().GetExp() }) }) } func TestToken_InvalidAt(t *testing.T) { var val bearer.Token require.True(t, val.InvalidAt(0)) require.True(t, val.InvalidAt(1)) val.SetIat(1) val.SetNbf(2) val.SetExp(4) require.True(t, val.InvalidAt(0)) require.True(t, val.InvalidAt(1)) require.False(t, val.InvalidAt(2)) require.False(t, val.InvalidAt(3)) require.False(t, val.InvalidAt(4)) require.True(t, val.InvalidAt(5)) } func TestToken_AssertContainer(t *testing.T) { var val bearer.Token cnr := cidtest.ID() require.True(t, val.AssertContainer(cnr)) eaclTable := *eacltest.Table() eaclTable.SetCID(cidtest.ID()) val.SetEACLTable(eaclTable) require.False(t, val.AssertContainer(cnr)) eaclTable.SetCID(cnr) val.SetEACLTable(eaclTable) require.True(t, val.AssertContainer(cnr)) } func TestToken_AssertUser(t *testing.T) { var val bearer.Token usr := *usertest.ID() require.True(t, val.AssertUser(usr)) val.ForUser(*usertest.ID()) require.False(t, val.AssertUser(usr)) val.ForUser(usr) require.True(t, val.AssertUser(usr)) } func TestToken_Sign(t *testing.T) { var val bearer.Token require.False(t, val.VerifySignature()) k, err := keys.NewPrivateKey() require.NoError(t, err) key := k.PrivateKey val = bearertest.Token() require.NoError(t, val.Sign(key)) require.True(t, val.VerifySignature()) var m acl.BearerToken val.WriteToV2(&m) require.NotZero(t, m.GetSignature().GetKey()) require.NotZero(t, m.GetSignature().GetSign()) val2 := bearertest.Token() require.NoError(t, val2.Unmarshal(val.Marshal())) require.True(t, val2.VerifySignature()) jd, err := val.MarshalJSON() require.NoError(t, err) val2 = bearertest.Token() require.NoError(t, val2.UnmarshalJSON(jd)) require.True(t, val2.VerifySignature()) } func TestToken_ReadFromV2(t *testing.T) { var val bearer.Token var m acl.BearerToken require.Error(t, val.ReadFromV2(m)) var body acl.BearerTokenBody m.SetBody(&body) require.Error(t, val.ReadFromV2(m)) eaclTable := eacltest.Table().ToV2() body.SetEACL(eaclTable) 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)) body.SetEACL(nil) body.SetImpersonate(true) 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)) k, err := keys.NewPrivateKey() require.NoError(t, err) signer := frostfsecdsa.Signer(k.PrivateKey) var s frostfscrypto.Signature require.NoError(t, s.Calculate(signer, body.StableMarshal(nil))) s.WriteToV2(&sig) require.NoError(t, val.ReadFromV2(m)) require.True(t, val.VerifySignature()) require.Equal(t, sig.GetKey(), val.SigningKeyBytes()) } func TestResolveIssuer(t *testing.T) { k, err := keys.NewPrivateKey() require.NoError(t, err) var val bearer.Token require.Zero(t, bearer.ResolveIssuer(val)) var m acl.BearerToken var sig refs.Signature sig.SetKey([]byte("invalid key")) m.SetSignature(&sig) require.NoError(t, val.Unmarshal(m.StableMarshal(nil))) require.Zero(t, bearer.ResolveIssuer(val)) require.NoError(t, val.Sign(k.PrivateKey)) var usr user.ID user.IDFromKey(&usr, k.PrivateKey.PublicKey) require.Equal(t, usr, bearer.ResolveIssuer(val)) }