From eb2de634799cc6f761bf73a98410b82c13f01e04 Mon Sep 17 00:00:00 2001 From: Matthew John Cheetham Date: Tue, 11 Apr 2023 09:56:00 -0700 Subject: [PATCH] generic: catch OAuth refresh token errors In case we have an existing refresh token, but it has expired or been revoked, we should gracefully fall back to performing an interactive OAuth flow. --- src/shared/Core/GenericHostProvider.cs | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/shared/Core/GenericHostProvider.cs b/src/shared/Core/GenericHostProvider.cs index 7514658f3..cdba0ba8a 100644 --- a/src/shared/Core/GenericHostProvider.cs +++ b/src/shared/Core/GenericHostProvider.cs @@ -143,16 +143,26 @@ private async Task GetOAuthAccessToken(Uri remoteUri, string userNa ICredential refreshToken = Context.CredentialStore.Get(refreshService, userName); if (refreshToken != null) { - var refreshResult = await client.GetTokenByRefreshTokenAsync(refreshToken.Password, CancellationToken.None); + try + { + var refreshResult = await client.GetTokenByRefreshTokenAsync(refreshToken.Password, CancellationToken.None); - // Store new refresh token if we have been given one - if (!string.IsNullOrWhiteSpace(refreshResult.RefreshToken)) - { - Context.CredentialStore.AddOrUpdate(refreshService, refreshToken.Account, refreshToken.Password); - } + // Store new refresh token if we have been given one + if (!string.IsNullOrWhiteSpace(refreshResult.RefreshToken)) + { + Context.CredentialStore.AddOrUpdate(refreshService, refreshToken.Account, refreshToken.Password); + } - // Return the new access token - return new GitCredential(oauthUser,refreshResult.AccessToken); + // Return the new access token + return new GitCredential(oauthUser,refreshResult.AccessToken); + } + catch (OAuth2Exception ex) + { + // Failed to use refresh token. It may have expired or been revoked. + // Fall through to an interactive OAuth flow. + Context.Trace.WriteLine("Failed to use refresh token."); + Context.Trace.WriteException(ex); + } } // Determine which interactive OAuth mode to use. Start by checking for mode preference in config