@@ -6,9 +6,40 @@ package http
6
6
import (
7
7
"strings"
8
8
"testing"
9
+ "time"
9
10
11
+ "github.com/hashicorp/go-hclog"
10
12
"github.com/hashicorp/vault/api"
13
+ "github.com/hashicorp/vault/sdk/helper/logging"
14
+ "github.com/hashicorp/vault/sdk/logical"
11
15
"github.com/hashicorp/vault/vault"
16
+ "github.com/stretchr/testify/require"
17
+ )
18
+
19
+ const (
20
+ rootLeasePolicies = `
21
+ path "sys/internal/ui/*" {
22
+ capabilities = ["create", "read", "update", "delete", "list"]
23
+ }
24
+
25
+ path "auth/token/*" {
26
+ capabilities = ["create", "update", "read", "list"]
27
+ }
28
+
29
+ path "kv/foo*" {
30
+ capabilities = ["create", "read", "update", "delete", "list"]
31
+ }
32
+ `
33
+
34
+ dummy = `
35
+ path "/ns1/sys/leases/*" {
36
+ capabilities = ["sudo", "create", "read", "update", "delete", "list"]
37
+ }
38
+
39
+ path "/ns1/auth/token/*" {
40
+ capabilities = ["sudo", "create", "read", "update", "delete", "list"]
41
+ }
42
+ `
12
43
)
13
44
14
45
func TestAuthTokenCreate (t * testing.T ) {
@@ -207,3 +238,106 @@ func TestAuthTokenRenew(t *testing.T) {
207
238
t .Error ("expected lease to be renewable" )
208
239
}
209
240
}
241
+
242
+ // TestToken_InvalidTokenError checks that an InvalidToken error is only returned
243
+ // for tokens that have (1) exceeded the token TTL and (2) exceeded the number of uses
244
+ func TestToken_InvalidTokenError (t * testing.T ) {
245
+ coreConfig := & vault.CoreConfig {
246
+ DisableMlock : true ,
247
+ DisableCache : true ,
248
+ Logger : logging .NewVaultLogger (hclog .Trace ),
249
+ }
250
+
251
+ // Init new test cluster
252
+ cluster := vault .NewTestCluster (t , coreConfig , & vault.TestClusterOptions {
253
+ HandlerFunc : Handler ,
254
+ })
255
+
256
+ cluster .Start ()
257
+ defer cluster .Cleanup ()
258
+
259
+ cores := cluster .Cores
260
+ vault .TestWaitActive (t , cores [0 ].Core )
261
+
262
+ client := cores [0 ].Client
263
+
264
+ // Add policy
265
+ if err := client .Sys ().PutPolicy ("root-lease-policy" , rootLeasePolicies ); err != nil {
266
+ t .Fatal (err )
267
+ }
268
+ // Add a dummy policy
269
+ if err := client .Sys ().PutPolicy ("dummy" , dummy ); err != nil {
270
+ t .Fatal (err )
271
+ }
272
+
273
+ rootToken := client .Token ()
274
+
275
+ // Enable kv secrets and mount initial secrets
276
+ err := client .Sys ().Mount ("kv" , & api.MountInput {Type : "kv" })
277
+ require .NoError (t , err )
278
+
279
+ writeSecretsToMount (t , client , "kv/foo" , map [string ]interface {}{
280
+ "user" : "admin" ,
281
+ "password" : "password" ,
282
+ })
283
+
284
+ // Create a token that has a TTL of 5s
285
+ tokenCreateRequest := & api.TokenCreateRequest {
286
+ Policies : []string {"root-lease-policy" },
287
+ TTL : "5s" ,
288
+ }
289
+ secret , err := client .Auth ().Token ().CreateOrphan (tokenCreateRequest )
290
+ token := secret .Auth .ClientToken
291
+ client .SetToken (token )
292
+
293
+ // Verify that token works to read from kv mount
294
+ _ , err = client .Logical ().Read ("kv/foo" )
295
+ require .NoError (t , err )
296
+
297
+ time .Sleep (time .Second * 5 )
298
+
299
+ // Verify that token is expired and shows an "invalid token" error
300
+ _ , err = client .Logical ().Read ("kv/foo" )
301
+ require .ErrorContains (t , err , logical .ErrInvalidToken .Error ())
302
+ require .ErrorContains (t , err , logical .ErrPermissionDenied .Error ())
303
+
304
+ // Create a second approle token with a token use limit
305
+ client .SetToken (rootToken )
306
+ tokenCreateRequest = & api.TokenCreateRequest {
307
+ Policies : []string {"root-lease-policy" },
308
+ NumUses : 5 ,
309
+ }
310
+
311
+ secret , err = client .Auth ().Token ().CreateOrphan (tokenCreateRequest )
312
+ token = secret .Auth .ClientToken
313
+ client .SetToken (token )
314
+
315
+ for i := 0 ; i < 5 ; i ++ {
316
+ _ , err = client .Logical ().Read ("kv/foo" )
317
+ require .NoError (t , err )
318
+ }
319
+ // Verify that the number of uses is exceeded so the "invalid token" error is displayed
320
+ _ , err = client .Logical ().Read ("kv/foo" )
321
+ require .ErrorContains (t , err , logical .ErrInvalidToken .Error ())
322
+ require .ErrorContains (t , err , logical .ErrPermissionDenied .Error ())
323
+
324
+ // Create a third approle token that will have incorrect policy access to the subsequent request
325
+ client .SetToken (rootToken )
326
+ tokenCreateRequest = & api.TokenCreateRequest {
327
+ Policies : []string {"dummy" },
328
+ }
329
+
330
+ secret , err = client .Auth ().Token ().CreateOrphan (tokenCreateRequest )
331
+ token = secret .Auth .ClientToken
332
+ client .SetToken (token )
333
+
334
+ // Incorrect policy access should only return an ErrPermissionDenied error
335
+ _ , err = client .Logical ().Read ("kv/foo" )
336
+ require .ErrorContains (t , err , logical .ErrPermissionDenied .Error ())
337
+ require .NotContains (t , err .Error (), logical .ErrInvalidToken )
338
+ }
339
+
340
+ func writeSecretsToMount (t * testing.T , client * api.Client , mountPath string , data map [string ]interface {}) {
341
+ _ , err := client .Logical ().Write (mountPath , data )
342
+ require .NoError (t , err )
343
+ }
0 commit comments