File tree Expand file tree Collapse file tree 2 files changed +65
-5
lines changed
Expand file tree Collapse file tree 2 files changed +65
-5
lines changed Original file line number Diff line number Diff line change 1+ using System ;
2+ using System . Text . Json ;
3+ using System . Text . Json . Serialization ;
4+
5+ namespace GitCredentialManager . Authentication
6+ {
7+ public abstract class StructuredToken
8+ {
9+ private class JwtHeader
10+ {
11+ [ JsonRequired ]
12+ [ JsonInclude ]
13+ [ JsonPropertyName ( "typ" ) ]
14+ public string Type { get ; private set ; }
15+ }
16+ private class JwtPayload : StructuredToken
17+ {
18+ [ JsonRequired ]
19+ [ JsonInclude ]
20+ [ JsonPropertyName ( "exp" ) ]
21+ public long Expiry { get ; private set ; }
22+
23+ public override bool IsExpired
24+ {
25+ get
26+ {
27+ return Expiry < DateTimeOffset . Now . ToUnixTimeSeconds ( ) ;
28+ }
29+ }
30+ }
31+
32+ public abstract bool IsExpired { get ; }
33+
34+ public static bool TryCreate ( string value , out StructuredToken token )
35+ {
36+ try
37+ {
38+ // elements of JWT structure "<header>.<payload>.<signature>"
39+ var parts = value . Split ( '.' ) ;
40+ if ( parts . Length == 3 )
41+ {
42+ var header = JsonSerializer . Deserialize < JwtHeader > ( Base64UrlConvert . Decode ( parts [ 0 ] ) ) ;
43+ if ( "JWT" . Equals ( header . Type , StringComparison . OrdinalIgnoreCase ) )
44+ {
45+ token = JsonSerializer . Deserialize < JwtPayload > ( Base64UrlConvert . Decode ( parts [ 1 ] ) ) ;
46+ return true ;
47+ }
48+ }
49+ }
50+ catch { }
51+
52+ // invalid token data on content mismatch or deserializer exception
53+ token = null ;
54+ return false ;
55+ }
56+ }
57+ }
Original file line number Diff line number Diff line change @@ -74,17 +74,20 @@ public async Task<GetCredentialResult> GetCredentialAsync(InputArguments input)
7474 if ( credential == null )
7575 {
7676 _context . Trace . WriteLine ( "No existing credentials found." ) ;
77-
78- // No existing credential was found, create a new one
79- _context . Trace . WriteLine ( "Creating new credential..." ) ;
80- return await GenerateCredentialAsync ( input ) ;
77+ }
78+ else if ( StructuredToken . TryCreate ( credential . Password , out var token ) && token . IsExpired )
79+ {
80+ _context . Trace . WriteLine ( "Credential is expired token." ) ;
8181 }
8282 else
8383 {
8484 _context . Trace . WriteLine ( "Existing credential found." ) ;
85+ return new GetCredentialResult ( credential ) ;
8586 }
8687
87- return new GetCredentialResult ( credential ) ;
88+ // No valid credential was found, create a new one
89+ _context . Trace . WriteLine ( "Creating new credential..." ) ;
90+ return await GenerateCredentialAsync ( input ) ;
8891 }
8992
9093 public Task StoreCredentialAsync ( InputArguments input )
You can’t perform that action at this time.
0 commit comments