token_test.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. package management
  2. import (
  3. "crypto/ecdsa"
  4. "crypto/elliptic"
  5. "crypto/rand"
  6. "errors"
  7. "testing"
  8. "github.com/go-jose/go-jose/v4"
  9. "github.com/stretchr/testify/require"
  10. )
  11. const (
  12. validToken = "eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiIsImtpZCI6IjEifQ.eyJ0dW4iOnsiaWQiOiI3YjA5ODE0OS01MWZlLTRlZTUtYTY4Ny0zZTM3NDQ2NmVmYzciLCJhY2NvdW50X3RhZyI6ImNkMzkxZTljMDYyNmE4Zjc2Y2IxZjY3MGY2NTkxYjA1In0sImFjdG9yIjp7ImlkIjoiZGNhcnJAY2xvdWRmbGFyZS5jb20iLCJzdXBwb3J0IjpmYWxzZX0sInJlcyI6WyJsb2dzIl0sImV4cCI6MTY3NzExNzY5NiwiaWF0IjoxNjc3MTE0MDk2LCJpc3MiOiJ0dW5uZWxzdG9yZSJ9.mKenOdOy3Xi4O-grldFnAAemdlE9WajEpTDC_FwezXQTstWiRTLwU65P5jt4vNsIiZA4OJRq7bH-QYID9wf9NA"
  13. accountTag = "cd391e9c0626a8f76cb1f670f6591b05"
  14. tunnelID = "7b098149-51fe-4ee5-a687-3e374466efc7"
  15. actorID = "45d2751e-6b59-45a9-814d-f630786bd0cd"
  16. )
  17. type invalidManagementTokenClaims struct {
  18. Invalid string `json:"invalid"`
  19. }
  20. func TestParseToken(t *testing.T) {
  21. key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
  22. require.NoError(t, err)
  23. for _, test := range []struct {
  24. name string
  25. claims any
  26. err error
  27. }{
  28. {
  29. name: "Valid",
  30. claims: managementTokenClaims{
  31. Tunnel: tunnel{
  32. ID: tunnelID,
  33. AccountTag: accountTag,
  34. },
  35. Actor: actor{
  36. ID: actorID,
  37. },
  38. },
  39. },
  40. {
  41. name: "Invalid claims",
  42. claims: invalidManagementTokenClaims{Invalid: "invalid"},
  43. err: errors.New("invalid management token format provided"),
  44. },
  45. {
  46. name: "Missing Tunnel",
  47. claims: managementTokenClaims{
  48. Actor: actor{
  49. ID: actorID,
  50. },
  51. },
  52. err: errors.New("invalid management token format provided"),
  53. },
  54. {
  55. name: "Missing Tunnel ID",
  56. claims: managementTokenClaims{
  57. Tunnel: tunnel{
  58. AccountTag: accountTag,
  59. },
  60. Actor: actor{
  61. ID: actorID,
  62. },
  63. },
  64. err: errors.New("invalid management token format provided"),
  65. },
  66. {
  67. name: "Missing Account Tag",
  68. claims: managementTokenClaims{
  69. Tunnel: tunnel{
  70. ID: tunnelID,
  71. },
  72. Actor: actor{
  73. ID: actorID,
  74. },
  75. },
  76. err: errors.New("invalid management token format provided"),
  77. },
  78. {
  79. name: "Missing Actor",
  80. claims: managementTokenClaims{
  81. Tunnel: tunnel{
  82. ID: tunnelID,
  83. AccountTag: accountTag,
  84. },
  85. },
  86. err: errors.New("invalid management token format provided"),
  87. },
  88. {
  89. name: "Missing Actor ID",
  90. claims: managementTokenClaims{
  91. Tunnel: tunnel{
  92. ID: tunnelID,
  93. },
  94. Actor: actor{},
  95. },
  96. err: errors.New("invalid management token format provided"),
  97. },
  98. } {
  99. t.Run(test.name, func(t *testing.T) {
  100. jwt := signToken(t, test.claims, key)
  101. claims, err := parseToken(jwt)
  102. if test.err != nil {
  103. require.EqualError(t, err, test.err.Error())
  104. return
  105. }
  106. require.Nil(t, err)
  107. require.Equal(t, test.claims, *claims)
  108. })
  109. }
  110. }
  111. func signToken(t *testing.T, token any, key *ecdsa.PrivateKey) string {
  112. opts := (&jose.SignerOptions{}).WithType("JWT").WithHeader("kid", "1")
  113. signer, err := jose.NewSigner(jose.SigningKey{Algorithm: jose.ES256, Key: key}, opts)
  114. require.NoError(t, err)
  115. payload, err := json.Marshal(token)
  116. require.NoError(t, err)
  117. jws, err := signer.Sign(payload)
  118. require.NoError(t, err)
  119. jwt, err := jws.CompactSerialize()
  120. require.NoError(t, err)
  121. return jwt
  122. }