1
1
package tailnet_test
2
2
3
3
import (
4
- "context"
5
- "encoding/hex"
6
4
"testing"
7
5
"time"
8
6
7
+ "github.com/go-jose/go-jose/v4"
8
+ "github.com/go-jose/go-jose/v4/jwt"
9
9
"github.com/google/uuid"
10
- "github.com/stretchr/testify/assert"
11
10
"github.com/stretchr/testify/require"
12
- "go.uber.org/mock/gomock"
13
11
14
- "github.com/coder/coder/v2/coderd/database/dbmock"
15
- "github.com/coder/coder/v2/coderd/database/dbtestutil"
16
12
"github.com/coder/coder/v2/coderd/jwtutils"
17
13
"github.com/coder/coder/v2/tailnet"
18
14
"github.com/coder/coder/v2/testutil"
19
15
"github.com/coder/quartz"
20
16
)
21
17
22
- func TestResumeTokenSigningKeyFromDatabase (t * testing.T ) {
23
- t .Parallel ()
24
-
25
- assertRandomKey := func (t * testing.T , key tailnet.ResumeTokenSigningKey ) {
26
- t .Helper ()
27
- assert .NotEqual (t , tailnet.ResumeTokenSigningKey {}, key , "key should not be empty" )
28
- assert .NotEqualValues (t , [64 ]byte {1 }, key , "key should not be all 1s" )
29
- }
30
-
31
- t .Run ("GenerateRetrieve" , func (t * testing.T ) {
32
- t .Parallel ()
33
-
34
- db , _ := dbtestutil .NewDB (t )
35
- ctx := testutil .Context (t , testutil .WaitShort )
36
- key1 , err := tailnet .ResumeTokenSigningKeyFromDatabase (ctx , db )
37
- require .NoError (t , err )
38
- assertRandomKey (t , key1 )
39
-
40
- key2 , err := tailnet .ResumeTokenSigningKeyFromDatabase (ctx , db )
41
- require .NoError (t , err )
42
- require .Equal (t , key1 , key2 , "keys should not be different" )
43
- })
44
-
45
- t .Run ("GetError" , func (t * testing.T ) {
46
- t .Parallel ()
47
-
48
- db := dbmock .NewMockStore (gomock .NewController (t ))
49
- db .EXPECT ().GetCoordinatorResumeTokenSigningKey (gomock .Any ()).Return ("" , assert .AnError )
50
-
51
- ctx := testutil .Context (t , testutil .WaitShort )
52
- _ , err := tailnet .ResumeTokenSigningKeyFromDatabase (ctx , db )
53
- require .ErrorIs (t , err , assert .AnError )
54
- })
55
-
56
- t .Run ("UpsertError" , func (t * testing.T ) {
57
- t .Parallel ()
58
-
59
- db := dbmock .NewMockStore (gomock .NewController (t ))
60
- db .EXPECT ().GetCoordinatorResumeTokenSigningKey (gomock .Any ()).Return ("" , nil )
61
- db .EXPECT ().UpsertCoordinatorResumeTokenSigningKey (gomock .Any (), gomock .Any ()).Return (assert .AnError )
62
-
63
- ctx := testutil .Context (t , testutil .WaitShort )
64
- _ , err := tailnet .ResumeTokenSigningKeyFromDatabase (ctx , db )
65
- require .ErrorIs (t , err , assert .AnError )
66
- })
67
-
68
- t .Run ("DecodeErrorShouldRegenerate" , func (t * testing.T ) {
69
- t .Parallel ()
70
-
71
- db := dbmock .NewMockStore (gomock .NewController (t ))
72
- db .EXPECT ().GetCoordinatorResumeTokenSigningKey (gomock .Any ()).Return ("invalid" , nil )
73
-
74
- var storedKey tailnet.ResumeTokenSigningKey
75
- db .EXPECT ().UpsertCoordinatorResumeTokenSigningKey (gomock .Any (), gomock .Any ()).Do (func (_ context.Context , value string ) error {
76
- keyBytes , err := hex .DecodeString (value )
77
- require .NoError (t , err )
78
- require .Len (t , keyBytes , len (storedKey ))
79
- copy (storedKey [:], keyBytes )
80
- return nil
81
- })
82
-
83
- ctx := testutil .Context (t , testutil .WaitShort )
84
- key , err := tailnet .ResumeTokenSigningKeyFromDatabase (ctx , db )
85
- require .NoError (t , err )
86
- assertRandomKey (t , key )
87
- require .Equal (t , storedKey , key , "key should match stored value" )
88
- })
89
-
90
- t .Run ("LengthErrorShouldRegenerate" , func (t * testing.T ) {
91
- t .Parallel ()
92
-
93
- db := dbmock .NewMockStore (gomock .NewController (t ))
94
- db .EXPECT ().GetCoordinatorResumeTokenSigningKey (gomock .Any ()).Return ("deadbeef" , nil )
95
- db .EXPECT ().UpsertCoordinatorResumeTokenSigningKey (gomock .Any (), gomock .Any ()).Return (nil )
96
-
97
- ctx := testutil .Context (t , testutil .WaitShort )
98
- key , err := tailnet .ResumeTokenSigningKeyFromDatabase (ctx , db )
99
- require .NoError (t , err )
100
- assertRandomKey (t , key )
101
- })
102
-
103
- t .Run ("EmptyError" , func (t * testing.T ) {
104
- t .Parallel ()
105
-
106
- db := dbmock .NewMockStore (gomock .NewController (t ))
107
- emptyKey := hex .EncodeToString (make ([]byte , 64 ))
108
- db .EXPECT ().GetCoordinatorResumeTokenSigningKey (gomock .Any ()).Return (emptyKey , nil )
109
-
110
- ctx := testutil .Context (t , testutil .WaitShort )
111
- _ , err := tailnet .ResumeTokenSigningKeyFromDatabase (ctx , db )
112
- require .ErrorContains (t , err , "is empty" )
113
- })
114
- }
115
-
116
18
func TestResumeTokenKeyProvider (t * testing.T ) {
117
19
t .Parallel ()
118
20
@@ -156,7 +58,7 @@ func TestResumeTokenKeyProvider(t *testing.T) {
156
58
_ = clock .Advance (tailnet .DefaultResumeTokenExpiry + time .Second )
157
59
158
60
_ , err = provider .VerifyResumeToken (ctx , token .Token )
159
- require .ErrorContains (t , err , "expired" )
61
+ require .ErrorIs (t , err , jwt . ErrExpired )
160
62
})
161
63
162
64
t .Run ("InvalidToken" , func (t * testing.T ) {
@@ -175,17 +77,20 @@ func TestResumeTokenKeyProvider(t *testing.T) {
175
77
// Generate a resume token with a different key
176
78
otherKey , err := tailnet .GenerateResumeTokenSigningKey ()
177
79
require .NoError (t , err )
178
- otherProvider := tailnet .NewResumeTokenKeyProvider (newKeySigner (otherKey ), quartz .NewMock (t ), tailnet .DefaultResumeTokenExpiry )
80
+ otherSigner := newKeySigner (otherKey )
81
+ otherProvider := tailnet .NewResumeTokenKeyProvider (otherSigner , quartz .NewMock (t ), tailnet .DefaultResumeTokenExpiry )
179
82
token , err := otherProvider .GenerateResumeToken (ctx , uuid .New ())
180
83
require .NoError (t , err )
181
84
182
- provider := tailnet .NewResumeTokenKeyProvider (newKeySigner (key ), quartz .NewMock (t ), tailnet .DefaultResumeTokenExpiry )
85
+ signer := newKeySigner (key )
86
+ signer .ID = otherSigner .ID
87
+ provider := tailnet .NewResumeTokenKeyProvider (signer , quartz .NewMock (t ), tailnet .DefaultResumeTokenExpiry )
183
88
_ , err = provider .VerifyResumeToken (ctx , token .Token )
184
- require .ErrorContains (t , err , "verify JWS" )
89
+ require .ErrorIs (t , err , jose . ErrCryptoFailure )
185
90
})
186
91
}
187
92
188
- func newKeySigner (key tailnet.ResumeTokenSigningKey ) jwtutils.SigningKeyManager {
93
+ func newKeySigner (key tailnet.ResumeTokenSigningKey ) jwtutils.StaticKeyManager {
189
94
return jwtutils.StaticKeyManager {
190
95
ID : uuid .New ().String (),
191
96
Key : key [:],
0 commit comments