git.frostfs.info/TrueCloudLab/frostfs-sdk-go@v0.0.0-20241022124111-5361f0ecebd3/bearer/bearer_test.go (about)

     1  package bearer_test
     2  
     3  import (
     4  	"bytes"
     5  	"math/rand"
     6  	"reflect"
     7  	"testing"
     8  
     9  	"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/acl"
    10  	"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
    11  	"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer"
    12  	bearertest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer/test"
    13  	cidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id/test"
    14  	frostfscrypto "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto"
    15  	frostfsecdsa "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto/ecdsa"
    16  	"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/eacl"
    17  	eacltest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/eacl/test"
    18  	"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
    19  	usertest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user/test"
    20  	"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
    21  	"github.com/stretchr/testify/require"
    22  )
    23  
    24  // compares binary representations of two eacl.Table instances.
    25  func isEqualEACLTables(t1, t2 eacl.Table) bool {
    26  	d1, err := t1.Marshal()
    27  	if err != nil {
    28  		panic(err)
    29  	}
    30  
    31  	d2, err := t2.Marshal()
    32  	if err != nil {
    33  		panic(err)
    34  	}
    35  
    36  	return bytes.Equal(d1, d2)
    37  }
    38  
    39  func TestToken_SetEACLTable(t *testing.T) {
    40  	var val bearer.Token
    41  	var m acl.BearerToken
    42  	filled := bearertest.Token()
    43  
    44  	val.WriteToV2(&m)
    45  	require.Zero(t, m.GetBody())
    46  
    47  	val2 := filled
    48  
    49  	require.NoError(t, val2.Unmarshal(val.Marshal()))
    50  	require.Zero(t, val2.EACLTable())
    51  
    52  	val2 = filled
    53  
    54  	jd, err := val.MarshalJSON()
    55  	require.NoError(t, err)
    56  
    57  	require.NoError(t, val2.UnmarshalJSON(jd))
    58  	require.Zero(t, val2.EACLTable())
    59  
    60  	// set value
    61  
    62  	eaclTable := *eacltest.Table()
    63  
    64  	val.SetEACLTable(eaclTable)
    65  	require.True(t, isEqualEACLTables(eaclTable, val.EACLTable()))
    66  
    67  	val.WriteToV2(&m)
    68  	eaclTableV2 := eaclTable.ToV2()
    69  	require.Equal(t, eaclTableV2, m.GetBody().GetEACL())
    70  
    71  	val2 = filled
    72  
    73  	require.NoError(t, val2.Unmarshal(val.Marshal()))
    74  	require.True(t, isEqualEACLTables(eaclTable, val.EACLTable()))
    75  
    76  	val2 = filled
    77  
    78  	jd, err = val.MarshalJSON()
    79  	require.NoError(t, err)
    80  
    81  	require.NoError(t, val2.UnmarshalJSON(jd))
    82  	require.True(t, isEqualEACLTables(eaclTable, val.EACLTable()))
    83  }
    84  
    85  func TestToken_SetAPEOverrides(t *testing.T) {
    86  	var val bearer.Token
    87  	var m acl.BearerToken
    88  	filled := bearertest.Token()
    89  
    90  	val.WriteToV2(&m)
    91  	require.Zero(t, m.GetBody())
    92  
    93  	val2 := filled
    94  
    95  	require.NoError(t, val2.Unmarshal(val.Marshal()))
    96  	require.Zero(t, val2.APEOverride())
    97  
    98  	val2 = filled
    99  
   100  	jd, err := val.MarshalJSON()
   101  	require.NoError(t, err)
   102  
   103  	require.NoError(t, val2.UnmarshalJSON(jd))
   104  	require.Zero(t, val2.APEOverride())
   105  
   106  	// set value
   107  
   108  	tApe := bearertest.APEOverride()
   109  
   110  	val.SetAPEOverride(tApe)
   111  	require.Equal(t, tApe, val.APEOverride())
   112  
   113  	val.WriteToV2(&m)
   114  	require.NotNil(t, m.GetBody().GetAPEOverride())
   115  	require.True(t, tokenAPEOverridesEqual(tApe.ToV2(), m.GetBody().GetAPEOverride()))
   116  
   117  	val2 = filled
   118  
   119  	require.NoError(t, val2.Unmarshal(val.Marshal()))
   120  	apeOverride := val2.APEOverride()
   121  	require.True(t, tokenAPEOverridesEqual(tApe.ToV2(), apeOverride.ToV2()))
   122  
   123  	val2 = filled
   124  
   125  	jd, err = val.MarshalJSON()
   126  	require.NoError(t, err)
   127  
   128  	require.NoError(t, val2.UnmarshalJSON(jd))
   129  	apeOverride = val.APEOverride()
   130  	require.True(t, tokenAPEOverridesEqual(tApe.ToV2(), apeOverride.ToV2()))
   131  }
   132  
   133  func tokenAPEOverridesEqual(lhs, rhs *acl.APEOverride) bool {
   134  	return reflect.DeepEqual(lhs, rhs)
   135  }
   136  
   137  func TestToken_ForUser(t *testing.T) {
   138  	var val bearer.Token
   139  	var m acl.BearerToken
   140  	filled := bearertest.Token()
   141  
   142  	val.WriteToV2(&m)
   143  	require.Zero(t, m.GetBody())
   144  
   145  	val2 := filled
   146  
   147  	require.NoError(t, val2.Unmarshal(val.Marshal()))
   148  
   149  	val2.WriteToV2(&m)
   150  	require.Zero(t, m.GetBody())
   151  
   152  	val2 = filled
   153  
   154  	jd, err := val.MarshalJSON()
   155  	require.NoError(t, err)
   156  
   157  	require.NoError(t, val2.UnmarshalJSON(jd))
   158  
   159  	val2.WriteToV2(&m)
   160  	require.Zero(t, m.GetBody())
   161  
   162  	// set value
   163  	usr := usertest.ID()
   164  
   165  	var usrV2 refs.OwnerID
   166  	usr.WriteToV2(&usrV2)
   167  
   168  	val.ForUser(usr)
   169  
   170  	val.WriteToV2(&m)
   171  	require.Equal(t, usrV2, *m.GetBody().GetOwnerID())
   172  
   173  	val2 = filled
   174  
   175  	require.NoError(t, val2.Unmarshal(val.Marshal()))
   176  
   177  	val2.WriteToV2(&m)
   178  	require.Equal(t, usrV2, *m.GetBody().GetOwnerID())
   179  
   180  	val2 = filled
   181  
   182  	jd, err = val.MarshalJSON()
   183  	require.NoError(t, err)
   184  
   185  	require.NoError(t, val2.UnmarshalJSON(jd))
   186  
   187  	val2.WriteToV2(&m)
   188  	require.Equal(t, usrV2, *m.GetBody().GetOwnerID())
   189  }
   190  
   191  func testLifetimeClaim(t *testing.T, setter func(*bearer.Token, uint64), getter func(*acl.BearerToken) uint64) {
   192  	var val bearer.Token
   193  	var m acl.BearerToken
   194  	filled := bearertest.Token()
   195  
   196  	val.WriteToV2(&m)
   197  	require.Zero(t, m.GetBody())
   198  
   199  	val2 := filled
   200  
   201  	require.NoError(t, val2.Unmarshal(val.Marshal()))
   202  
   203  	val2.WriteToV2(&m)
   204  	require.Zero(t, m.GetBody())
   205  
   206  	val2 = filled
   207  
   208  	jd, err := val.MarshalJSON()
   209  	require.NoError(t, err)
   210  
   211  	require.NoError(t, val2.UnmarshalJSON(jd))
   212  
   213  	val2.WriteToV2(&m)
   214  	require.Zero(t, m.GetBody())
   215  
   216  	// set value
   217  	exp := rand.Uint64()
   218  
   219  	setter(&val, exp)
   220  
   221  	val.WriteToV2(&m)
   222  	require.Equal(t, exp, getter(&m))
   223  
   224  	val2 = filled
   225  
   226  	require.NoError(t, val2.Unmarshal(val.Marshal()))
   227  
   228  	val2.WriteToV2(&m)
   229  	require.Equal(t, exp, getter(&m))
   230  
   231  	val2 = filled
   232  
   233  	jd, err = val.MarshalJSON()
   234  	require.NoError(t, err)
   235  
   236  	require.NoError(t, val2.UnmarshalJSON(jd))
   237  
   238  	val2.WriteToV2(&m)
   239  	require.Equal(t, exp, getter(&m))
   240  }
   241  
   242  func TestToken_SetLifetime(t *testing.T) {
   243  	t.Run("iat", func(t *testing.T) {
   244  		testLifetimeClaim(t, (*bearer.Token).SetIat, func(token *acl.BearerToken) uint64 {
   245  			return token.GetBody().GetLifetime().GetIat()
   246  		})
   247  	})
   248  
   249  	t.Run("nbf", func(t *testing.T) {
   250  		testLifetimeClaim(t, (*bearer.Token).SetNbf, func(token *acl.BearerToken) uint64 {
   251  			return token.GetBody().GetLifetime().GetNbf()
   252  		})
   253  	})
   254  
   255  	t.Run("exp", func(t *testing.T) {
   256  		testLifetimeClaim(t, (*bearer.Token).SetExp, func(token *acl.BearerToken) uint64 {
   257  			return token.GetBody().GetLifetime().GetExp()
   258  		})
   259  	})
   260  }
   261  
   262  func TestToken_InvalidAt(t *testing.T) {
   263  	var val bearer.Token
   264  
   265  	require.True(t, val.InvalidAt(0))
   266  	require.True(t, val.InvalidAt(1))
   267  
   268  	val.SetIat(1)
   269  	val.SetNbf(2)
   270  	val.SetExp(4)
   271  
   272  	require.True(t, val.InvalidAt(0))
   273  	require.True(t, val.InvalidAt(1))
   274  	require.False(t, val.InvalidAt(2))
   275  	require.False(t, val.InvalidAt(3))
   276  	require.False(t, val.InvalidAt(4))
   277  	require.True(t, val.InvalidAt(5))
   278  }
   279  
   280  func TestToken_AssertContainer(t *testing.T) {
   281  	var val bearer.Token
   282  	cnr := cidtest.ID()
   283  
   284  	require.True(t, val.AssertContainer(cnr))
   285  
   286  	eaclTable := *eacltest.Table()
   287  
   288  	eaclTable.SetCID(cidtest.ID())
   289  	val.SetEACLTable(eaclTable)
   290  	require.False(t, val.AssertContainer(cnr))
   291  
   292  	eaclTable.SetCID(cnr)
   293  	val.SetEACLTable(eaclTable)
   294  	require.True(t, val.AssertContainer(cnr))
   295  }
   296  
   297  func TestToken_AssertUser(t *testing.T) {
   298  	var val bearer.Token
   299  	usr := usertest.ID()
   300  
   301  	require.True(t, val.AssertUser(usr))
   302  
   303  	val.ForUser(usertest.ID())
   304  	require.False(t, val.AssertUser(usr))
   305  
   306  	val.ForUser(usr)
   307  	require.True(t, val.AssertUser(usr))
   308  }
   309  
   310  func TestToken_Sign(t *testing.T) {
   311  	var val bearer.Token
   312  
   313  	require.False(t, val.VerifySignature())
   314  
   315  	k, err := keys.NewPrivateKey()
   316  	require.NoError(t, err)
   317  
   318  	key := k.PrivateKey
   319  	val = bearertest.Token()
   320  
   321  	require.NoError(t, val.Sign(key))
   322  
   323  	require.True(t, val.VerifySignature())
   324  
   325  	var m acl.BearerToken
   326  	val.WriteToV2(&m)
   327  
   328  	require.NotZero(t, m.GetSignature().GetKey())
   329  	require.NotZero(t, m.GetSignature().GetSign())
   330  
   331  	val2 := bearertest.Token()
   332  
   333  	require.NoError(t, val2.Unmarshal(val.Marshal()))
   334  	require.True(t, val2.VerifySignature())
   335  
   336  	jd, err := val.MarshalJSON()
   337  	require.NoError(t, err)
   338  
   339  	val2 = bearertest.Token()
   340  	require.NoError(t, val2.UnmarshalJSON(jd))
   341  	require.True(t, val2.VerifySignature())
   342  }
   343  
   344  func TestToken_ReadFromV2(t *testing.T) {
   345  	var val bearer.Token
   346  	var m acl.BearerToken
   347  
   348  	require.Error(t, val.ReadFromV2(m))
   349  
   350  	var body acl.BearerTokenBody
   351  	m.SetBody(&body)
   352  
   353  	require.Error(t, val.ReadFromV2(m))
   354  
   355  	eaclTable := eacltest.Table().ToV2()
   356  	body.SetEACL(eaclTable)
   357  
   358  	require.Error(t, val.ReadFromV2(m))
   359  
   360  	var lifetime acl.TokenLifetime
   361  	body.SetLifetime(&lifetime)
   362  
   363  	require.Error(t, val.ReadFromV2(m))
   364  
   365  	const iat, nbf, exp = 1, 2, 3
   366  	lifetime.SetIat(iat)
   367  	lifetime.SetNbf(nbf)
   368  	lifetime.SetExp(exp)
   369  
   370  	body.SetLifetime(&lifetime)
   371  
   372  	require.Error(t, val.ReadFromV2(m))
   373  
   374  	var sig refs.Signature
   375  	m.SetSignature(&sig)
   376  
   377  	require.NoError(t, val.ReadFromV2(m))
   378  
   379  	body.SetEACL(nil)
   380  	body.SetImpersonate(true)
   381  	require.NoError(t, val.ReadFromV2(m))
   382  
   383  	var m2 acl.BearerToken
   384  
   385  	val.WriteToV2(&m2)
   386  	require.Equal(t, m, m2)
   387  
   388  	usr, usr2 := usertest.ID(), usertest.ID()
   389  
   390  	require.True(t, val.AssertUser(usr))
   391  	require.True(t, val.AssertUser(usr2))
   392  
   393  	var usrV2 refs.OwnerID
   394  	usr.WriteToV2(&usrV2)
   395  
   396  	body.SetOwnerID(&usrV2)
   397  
   398  	require.NoError(t, val.ReadFromV2(m))
   399  
   400  	val.WriteToV2(&m2)
   401  	require.Equal(t, m, m2)
   402  
   403  	require.True(t, val.AssertUser(usr))
   404  	require.False(t, val.AssertUser(usr2))
   405  
   406  	k, err := keys.NewPrivateKey()
   407  	require.NoError(t, err)
   408  
   409  	signer := frostfsecdsa.Signer(k.PrivateKey)
   410  
   411  	var s frostfscrypto.Signature
   412  
   413  	require.NoError(t, s.Calculate(signer, body.StableMarshal(nil)))
   414  
   415  	s.WriteToV2(&sig)
   416  
   417  	require.NoError(t, val.ReadFromV2(m))
   418  	require.True(t, val.VerifySignature())
   419  	require.Equal(t, sig.GetKey(), val.SigningKeyBytes())
   420  }
   421  
   422  func TestResolveIssuer(t *testing.T) {
   423  	k, err := keys.NewPrivateKey()
   424  	require.NoError(t, err)
   425  
   426  	var val bearer.Token
   427  
   428  	require.Zero(t, bearer.ResolveIssuer(val))
   429  
   430  	var m acl.BearerToken
   431  
   432  	var sig refs.Signature
   433  	sig.SetKey([]byte("invalid key"))
   434  
   435  	m.SetSignature(&sig)
   436  
   437  	require.NoError(t, val.Unmarshal(m.StableMarshal(nil)))
   438  
   439  	require.Zero(t, bearer.ResolveIssuer(val))
   440  
   441  	require.NoError(t, val.Sign(k.PrivateKey))
   442  
   443  	var usr user.ID
   444  	user.IDFromKey(&usr, k.PrivateKey.PublicKey)
   445  
   446  	require.Equal(t, usr, bearer.ResolveIssuer(val))
   447  }