@@ -747,7 +747,7 @@ func TestTokenEndpointTokenExchange(t *testing.T) { // tests for grant_type "urn
747
747
require .Len (t , parts , 2 )
748
748
// Find the storage Secret for the access token by using its signature to compute the Secret name.
749
749
accessTokenSignature := parts [1 ]
750
- accessTokenSecretName := getSecretNameFromSignature (t , accessTokenSignature , "access-token" )
750
+ accessTokenSecretName := getSecretNameFromSignature (t , accessTokenSignature , "access-token" ) // "access-token" is the storage type used in the Secret's name
751
751
accessTokenSecret , err := secrets .Get (context .Background (), accessTokenSecretName , metav1.GetOptions {})
752
752
require .NoError (t , err )
753
753
// Parse the session from the storage Secret.
@@ -1143,7 +1143,7 @@ func TestRefreshGrant(t *testing.T) {
1143
1143
idps * oidctestutil.UpstreamIDPListerBuilder
1144
1144
authcodeExchange authcodeExchangeInputs
1145
1145
refreshRequest refreshRequestInputs
1146
- modifyRefreshTokenStorage func (t * testing.T , oauthStore * oidc.KubeStorage , refreshToken string )
1146
+ modifyRefreshTokenStorage func (t * testing.T , oauthStore * oidc.KubeStorage , secrets v1. SecretInterface , refreshToken string )
1147
1147
}{
1148
1148
{
1149
1149
name : "happy path refresh grant with openid scope granted (id token returned)" ,
@@ -1595,6 +1595,59 @@ func TestRefreshGrant(t *testing.T) {
1595
1595
),
1596
1596
},
1597
1597
},
1598
+ {
1599
+ name : "when a valid refresh token is sent in the refresh request, but the token has already expired" ,
1600
+ idps : oidctestutil .NewUpstreamIDPListerBuilder ().WithOIDC (upstreamOIDCIdentityProviderBuilder ().Build ()),
1601
+ authcodeExchange : authcodeExchangeInputs {
1602
+ customSessionData : initialUpstreamOIDCRefreshTokenCustomSessionData (),
1603
+ modifyAuthRequest : func (r * http.Request ) { r .Form .Set ("scope" , "openid offline_access" ) },
1604
+ want : happyAuthcodeExchangeTokenResponseForOpenIDAndOfflineAccess (initialUpstreamOIDCRefreshTokenCustomSessionData ()),
1605
+ },
1606
+ modifyRefreshTokenStorage : func (t * testing.T , oauthStore * oidc.KubeStorage , secrets v1.SecretInterface , refreshToken string ) {
1607
+ // The fosite storage APIs don't offer a way to update a refresh token, so we will instead find the underlying
1608
+ // storage Secret and update it in a more manual way. First get the refresh token's signature.
1609
+ refreshTokenSignature := getFositeDataSignature (t , refreshToken )
1610
+ // Find the storage Secret for the refresh token by using its signature to compute the Secret name.
1611
+ refreshTokenSecretName := getSecretNameFromSignature (t , refreshTokenSignature , "refresh-token" ) // "refresh-token" is the storage type used in the Secret's name
1612
+ refreshTokenSecret , err := secrets .Get (context .Background (), refreshTokenSecretName , metav1.GetOptions {})
1613
+ require .NoError (t , err )
1614
+ // Parse the session from the storage Secret.
1615
+ savedSessionJSON := refreshTokenSecret .Data ["pinniped-storage-data" ]
1616
+ // Declare the appropriate empty struct, similar to how our kubestorage implementation
1617
+ // of GetRefreshTokenSession() does when parsing a session from a storage Secret.
1618
+ refreshTokenSession := & refreshtoken.Session {
1619
+ Request : & fosite.Request {
1620
+ Client : & clientregistry.Client {},
1621
+ Session : & psession.PinnipedSession {},
1622
+ },
1623
+ }
1624
+ // Parse the session JSON and fill the empty struct with its data.
1625
+ err = json .Unmarshal (savedSessionJSON , refreshTokenSession )
1626
+ require .NoError (t , err )
1627
+ // Change the refresh token's expiration time to be one hour ago, so it will be considered already expired.
1628
+ oneHourAgoInUTC := time .Now ().UTC ().Add (- 1 * time .Hour )
1629
+ refreshTokenSession .Request .Session .(* psession.PinnipedSession ).Fosite .SetExpiresAt (fosite .RefreshToken , oneHourAgoInUTC )
1630
+ // Write the updated session back to the refresh token's storage Secret.
1631
+ updatedSessionJSON , err := json .Marshal (refreshTokenSession )
1632
+ require .NoError (t , err )
1633
+ refreshTokenSecret .Data ["pinniped-storage-data" ] = updatedSessionJSON
1634
+ _ , err = secrets .Update (context .Background (), refreshTokenSecret , metav1.UpdateOptions {})
1635
+ require .NoError (t , err )
1636
+ // Just to be sure that this test setup is valid, confirm that the code above correctly updated the
1637
+ // refresh token's expiration time by reading it again, this time performing the read using the
1638
+ // kubestorage API instead of the manual/direct approach used above.
1639
+ session , err := oauthStore .GetRefreshTokenSession (context .Background (), refreshTokenSignature , nil )
1640
+ require .NoError (t , err )
1641
+ expiresAt := session .GetSession ().GetExpiresAt (fosite .RefreshToken )
1642
+ require .Equal (t , oneHourAgoInUTC , expiresAt )
1643
+ },
1644
+ refreshRequest : refreshRequestInputs {
1645
+ want : tokenEndpointResponseExpectedValues {
1646
+ wantStatus : http .StatusBadRequest ,
1647
+ wantErrorResponseBody : fositeInvalidAuthCodeErrorBody ,
1648
+ },
1649
+ },
1650
+ },
1598
1651
{
1599
1652
name : "when a bad refresh token is sent in the refresh request" ,
1600
1653
idps : oidctestutil .NewUpstreamIDPListerBuilder ().WithOIDC (upstreamOIDCIdentityProviderBuilder ().Build ()),
@@ -2393,7 +2446,7 @@ func TestRefreshGrant(t *testing.T) {
2393
2446
happyLDAPCustomSessionData ,
2394
2447
),
2395
2448
},
2396
- modifyRefreshTokenStorage : func (t * testing.T , oauthStore * oidc.KubeStorage , refreshToken string ) {
2449
+ modifyRefreshTokenStorage : func (t * testing.T , oauthStore * oidc.KubeStorage , secrets v1. SecretInterface , refreshToken string ) {
2397
2450
refreshTokenSignature := getFositeDataSignature (t , refreshToken )
2398
2451
firstRequester , err := oauthStore .GetRefreshTokenSession (context .Background (), refreshTokenSignature , nil )
2399
2452
require .NoError (t , err )
@@ -2431,7 +2484,7 @@ func TestRefreshGrant(t *testing.T) {
2431
2484
happyLDAPCustomSessionData ,
2432
2485
),
2433
2486
},
2434
- modifyRefreshTokenStorage : func (t * testing.T , oauthStore * oidc.KubeStorage , refreshToken string ) {
2487
+ modifyRefreshTokenStorage : func (t * testing.T , oauthStore * oidc.KubeStorage , secrets v1. SecretInterface , refreshToken string ) {
2435
2488
refreshTokenSignature := getFositeDataSignature (t , refreshToken )
2436
2489
firstRequester , err := oauthStore .GetRefreshTokenSession (context .Background (), refreshTokenSignature , nil )
2437
2490
require .NoError (t , err )
@@ -2473,7 +2526,7 @@ func TestRefreshGrant(t *testing.T) {
2473
2526
happyLDAPCustomSessionData ,
2474
2527
),
2475
2528
},
2476
- modifyRefreshTokenStorage : func (t * testing.T , oauthStore * oidc.KubeStorage , refreshToken string ) {
2529
+ modifyRefreshTokenStorage : func (t * testing.T , oauthStore * oidc.KubeStorage , secrets v1. SecretInterface , refreshToken string ) {
2477
2530
refreshTokenSignature := getFositeDataSignature (t , refreshToken )
2478
2531
firstRequester , err := oauthStore .GetRefreshTokenSession (context .Background (), refreshTokenSignature , nil )
2479
2532
require .NoError (t , err )
@@ -2515,7 +2568,7 @@ func TestRefreshGrant(t *testing.T) {
2515
2568
happyLDAPCustomSessionData ,
2516
2569
),
2517
2570
},
2518
- modifyRefreshTokenStorage : func (t * testing.T , oauthStore * oidc.KubeStorage , refreshToken string ) {
2571
+ modifyRefreshTokenStorage : func (t * testing.T , oauthStore * oidc.KubeStorage , secrets v1. SecretInterface , refreshToken string ) {
2519
2572
refreshTokenSignature := getFositeDataSignature (t , refreshToken )
2520
2573
firstRequester , err := oauthStore .GetRefreshTokenSession (context .Background (), refreshTokenSignature , nil )
2521
2574
require .NoError (t , err )
@@ -2652,7 +2705,7 @@ func TestRefreshGrant(t *testing.T) {
2652
2705
happyLDAPCustomSessionData ,
2653
2706
),
2654
2707
},
2655
- modifyRefreshTokenStorage : func (t * testing.T , oauthStore * oidc.KubeStorage , refreshToken string ) {
2708
+ modifyRefreshTokenStorage : func (t * testing.T , oauthStore * oidc.KubeStorage , secrets v1. SecretInterface , refreshToken string ) {
2656
2709
refreshTokenSignature := getFositeDataSignature (t , refreshToken )
2657
2710
firstRequester , err := oauthStore .GetRefreshTokenSession (context .Background (), refreshTokenSignature , nil )
2658
2711
require .NoError (t , err )
@@ -2689,7 +2742,7 @@ func TestRefreshGrant(t *testing.T) {
2689
2742
happyLDAPCustomSessionData ,
2690
2743
),
2691
2744
},
2692
- modifyRefreshTokenStorage : func (t * testing.T , oauthStore * oidc.KubeStorage , refreshToken string ) {
2745
+ modifyRefreshTokenStorage : func (t * testing.T , oauthStore * oidc.KubeStorage , secrets v1. SecretInterface , refreshToken string ) {
2693
2746
refreshTokenSignature := getFositeDataSignature (t , refreshToken )
2694
2747
firstRequester , err := oauthStore .GetRefreshTokenSession (context .Background (), refreshTokenSignature , nil )
2695
2748
require .NoError (t , err )
@@ -2730,7 +2783,7 @@ func TestRefreshGrant(t *testing.T) {
2730
2783
happyLDAPCustomSessionData ,
2731
2784
),
2732
2785
},
2733
- modifyRefreshTokenStorage : func (t * testing.T , oauthStore * oidc.KubeStorage , refreshToken string ) {
2786
+ modifyRefreshTokenStorage : func (t * testing.T , oauthStore * oidc.KubeStorage , secrets v1. SecretInterface , refreshToken string ) {
2734
2787
refreshTokenSignature := getFositeDataSignature (t , refreshToken )
2735
2788
firstRequester , err := oauthStore .GetRefreshTokenSession (context .Background (), refreshTokenSignature , nil )
2736
2789
require .NoError (t , err )
@@ -2836,7 +2889,7 @@ func TestRefreshGrant(t *testing.T) {
2836
2889
require .NotEmpty (t , firstRefreshToken )
2837
2890
2838
2891
if test .modifyRefreshTokenStorage != nil {
2839
- test .modifyRefreshTokenStorage (t , oauthStore , firstRefreshToken )
2892
+ test .modifyRefreshTokenStorage (t , oauthStore , secrets , firstRefreshToken )
2840
2893
}
2841
2894
reqContext := context .WithValue (context .Background (), struct { name string }{name : "test" }, "request-context" )
2842
2895
req := httptest .NewRequest ("POST" , "/path/shouldn't/matter" ,
0 commit comments