@@ -1409,6 +1409,52 @@ func TestVaultClient_RevokeTokens_PreEstablishs(t *testing.T) {
1409
1409
}
1410
1410
}
1411
1411
1412
+ // TestVaultClient_RevokeTokens_failures_TTL asserts that
1413
+ // the registered TTL doesn't get extended on retries
1414
+ func TestVaultClient_RevokeTokens_Failures_TTL (t * testing.T ) {
1415
+ t .Parallel ()
1416
+ vconfig := & config.VaultConfig {
1417
+ Enabled : helper .BoolToPtr (true ),
1418
+ Token : uuid .Generate (),
1419
+ Addr : "http://127.0.0.1:0" ,
1420
+ }
1421
+ logger := testlog .HCLogger (t )
1422
+ client , err := NewVaultClient (vconfig , logger , nil )
1423
+ if err != nil {
1424
+ t .Fatalf ("failed to build vault client: %v" , err )
1425
+ }
1426
+ client .SetActive (true )
1427
+ defer client .Stop ()
1428
+
1429
+ // Create some VaultAccessors
1430
+ vas := []* structs.VaultAccessor {
1431
+ mock .VaultAccessor (),
1432
+ mock .VaultAccessor (),
1433
+ }
1434
+
1435
+ err = client .RevokeTokens (context .Background (), vas , true )
1436
+ require .NoError (t , err )
1437
+
1438
+ // Was committed
1439
+ require .Len (t , client .revoking , 2 )
1440
+
1441
+ // set TTL
1442
+ ttl := time .Now ().Add (50 * time .Second )
1443
+ client .revoking [vas [0 ]] = ttl
1444
+ client .revoking [vas [1 ]] = ttl
1445
+
1446
+ // revoke again and ensure that TTL isn't extended
1447
+ err = client .RevokeTokens (context .Background (), vas , true )
1448
+ require .NoError (t , err )
1449
+
1450
+ require .Len (t , client .revoking , 2 )
1451
+ expected := map [* structs.VaultAccessor ]time.Time {
1452
+ vas [0 ]: ttl ,
1453
+ vas [1 ]: ttl ,
1454
+ }
1455
+ require .Equal (t , expected , client .revoking )
1456
+ }
1457
+
1412
1458
func TestVaultClient_RevokeTokens_Root (t * testing.T ) {
1413
1459
t .Parallel ()
1414
1460
v := testutil .NewTestVault (t )
@@ -1541,6 +1587,86 @@ func TestVaultClient_RevokeTokens_Role(t *testing.T) {
1541
1587
}
1542
1588
}
1543
1589
1590
+ // TestVaultClient_RevokeTokens_Idempotent asserts that token revocation
1591
+ // is idempotent, and can cope with cases if token was deleted out of band.
1592
+ func TestVaultClient_RevokeTokens_Idempotent (t * testing.T ) {
1593
+ t .Parallel ()
1594
+ v := testutil .NewTestVault (t )
1595
+ defer v .Stop ()
1596
+
1597
+ // Set the configs token in a new test role
1598
+ v .Config .Token = defaultTestVaultWhitelistRoleAndToken (v , t , 5 )
1599
+
1600
+ purged := map [string ]struct {}{}
1601
+ purge := func (accessors []* structs.VaultAccessor ) error {
1602
+ for _ , accessor := range accessors {
1603
+ purged [accessor .Accessor ] = struct {}{}
1604
+ }
1605
+ return nil
1606
+ }
1607
+
1608
+ logger := testlog .HCLogger (t )
1609
+ client , err := NewVaultClient (v .Config , logger , purge )
1610
+ if err != nil {
1611
+ t .Fatalf ("failed to build vault client: %v" , err )
1612
+ }
1613
+ client .SetActive (true )
1614
+ defer client .Stop ()
1615
+
1616
+ waitForConnection (client , t )
1617
+
1618
+ // Create some vault tokens
1619
+ auth := v .Client .Auth ().Token ()
1620
+ req := vapi.TokenCreateRequest {
1621
+ Policies : []string {"default" },
1622
+ }
1623
+ t1 , err := auth .Create (& req )
1624
+ require .NoError (t , err )
1625
+ require .NotNil (t , t1 )
1626
+ require .NotNil (t , t1 .Auth )
1627
+
1628
+ t2 , err := auth .Create (& req )
1629
+ require .NoError (t , err )
1630
+ require .NotNil (t , t2 )
1631
+ require .NotNil (t , t2 .Auth )
1632
+
1633
+ t3 , err := auth .Create (& req )
1634
+ require .NoError (t , err )
1635
+ require .NotNil (t , t3 )
1636
+ require .NotNil (t , t3 .Auth )
1637
+
1638
+ // revoke t3 out of band
1639
+ err = auth .RevokeAccessor (t3 .Auth .Accessor )
1640
+ require .NoError (t , err )
1641
+
1642
+ // Create two VaultAccessors
1643
+ vas := []* structs.VaultAccessor {
1644
+ {Accessor : t1 .Auth .Accessor },
1645
+ {Accessor : t2 .Auth .Accessor },
1646
+ {Accessor : t3 .Auth .Accessor },
1647
+ }
1648
+
1649
+ // Issue a token revocation
1650
+ err = client .RevokeTokens (context .Background (), vas , true )
1651
+ require .NoError (t , err )
1652
+ require .Empty (t , client .revoking )
1653
+
1654
+ // revoke token again
1655
+ err = client .RevokeTokens (context .Background (), vas , true )
1656
+ require .NoError (t , err )
1657
+ require .Empty (t , client .revoking )
1658
+
1659
+ // Lookup the token and make sure we get an error
1660
+ require .Len (t , purged , 3 )
1661
+ require .Contains (t , purged , t1 .Auth .Accessor )
1662
+ require .Contains (t , purged , t2 .Auth .Accessor )
1663
+ require .Contains (t , purged , t3 .Auth .Accessor )
1664
+ s , err := auth .Lookup (t1 .Auth .ClientToken )
1665
+ require .Errorf (t , err , "failed to purge token: %v" , s )
1666
+ s , err = auth .Lookup (t2 .Auth .ClientToken )
1667
+ require .Errorf (t , err , "failed to purge token: %v" , s )
1668
+ }
1669
+
1544
1670
func waitForConnection (v * vaultClient , t * testing.T ) {
1545
1671
testutil .WaitForResult (func () (bool , error ) {
1546
1672
return v .ConnectionEstablished ()
0 commit comments