@@ -128,6 +128,33 @@ private async Task<ICredential> GetOAuthAccessToken(Uri remoteUri, string userNa
128
128
Context . Trace ,
129
129
config . UseAuthHeader ) ;
130
130
131
+ //
132
+ // Prepend "refresh_token" to the hostname to get a (hopefully) unique service name that
133
+ // doesn't clash with an existing credential service.
134
+ //
135
+ // Appending "/refresh_token" to the end of the remote URI may not always result in a unique
136
+ // service because users may set credential.useHttpPath and include "/refresh_token" as a
137
+ // path name.
138
+ //
139
+ string refreshService = new UriBuilder ( remoteUri ) { Host = $ "refresh_token.{ remoteUri . Host } " }
140
+ . Uri . AbsoluteUri . TrimEnd ( '/' ) ;
141
+
142
+ // Try to use a refresh token if we have one
143
+ ICredential refreshToken = Context . CredentialStore . Get ( refreshService , userName ) ;
144
+ if ( refreshToken != null )
145
+ {
146
+ var refreshResult = await client . GetTokenByRefreshTokenAsync ( refreshToken . Password , CancellationToken . None ) ;
147
+
148
+ // Store new refresh token if we have been given one
149
+ if ( ! string . IsNullOrWhiteSpace ( refreshResult . RefreshToken ) )
150
+ {
151
+ Context . CredentialStore . AddOrUpdate ( refreshService , refreshToken . Account , refreshToken . Password ) ;
152
+ }
153
+
154
+ // Return the new access token
155
+ return new GitCredential ( oauthUser , refreshResult . AccessToken ) ;
156
+ }
157
+
131
158
// Determine which interactive OAuth mode to use. Start by checking for mode preference in config
132
159
var supportedModes = OAuthAuthenticationModes . All ;
133
160
if ( Context . Settings . TryGetSetting (
@@ -170,6 +197,12 @@ private async Task<ICredential> GetOAuthAccessToken(Uri remoteUri, string userNa
170
197
throw new Exception ( "No authentication mode selected!" ) ;
171
198
}
172
199
200
+ // Store the refresh token if we have one
201
+ if ( ! string . IsNullOrWhiteSpace ( tokenResult . RefreshToken ) )
202
+ {
203
+ Context . CredentialStore . AddOrUpdate ( refreshService , oauthUser , tokenResult . RefreshToken ) ;
204
+ }
205
+
173
206
return new GitCredential ( oauthUser , tokenResult . AccessToken ) ;
174
207
}
175
208
0 commit comments