Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 19 additions & 26 deletions src/Atlassian.Bitbucket/BitbucketHostProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,9 @@ private async Task<ICredential> GetRefreshedCredentials(GitRequest request, Auth
Uri remoteUri = request.GetRemoteUri();
var refreshTokenService = GetRefreshTokenServiceName(remoteUri);

_context.Trace.WriteLine("Checking for refresh token...");
_context.Trace.WriteLine($"Checking for refresh token stored against user: '{request.UserName}'...");

// The refresh token now always gets stored using the request.UserName
ICredential refreshToken = SupportsOAuth(authModes)
? _context.CredentialStore.Get(refreshTokenService, request.UserName)
: null;
Expand Down Expand Up @@ -203,51 +205,42 @@ private async Task<ICredential> GetRefreshedCredentials(GitRequest request, Auth

private async Task<ICredential> GetOAuthCredentialsViaRefreshFlow(GitRequest request, ICredential refreshToken)
{
Uri remoteUri = request.GetRemoteUri();

var refreshTokenService = GetRefreshTokenServiceName(remoteUri);
_context.Trace.WriteLine("Refreshing OAuth credentials using refresh token...");

OAuth2TokenResult refreshResult = await _bitbucketAuth.RefreshOAuthCredentialsAsync(request, refreshToken.Password);

// Resolve the username
_context.Trace.WriteLine("Resolving username for refreshed OAuth credential...");
string refreshUserName = await ResolveOAuthUserNameAsync(request, refreshResult.AccessToken);
_context.Trace.WriteLine($"Username for refreshed OAuth credential is '{refreshUserName}'");

// Store the refreshed RT
_context.Trace.WriteLine("Storing new refresh token...");
_context.CredentialStore.AddOrUpdate(refreshTokenService, remoteUri.GetUserName(), refreshResult.RefreshToken);

// Return new access token
return new GitCredential(refreshUserName, refreshResult.AccessToken);
return await ResolveCredsAndStoreRefreshToken(request, refreshResult);
}

private async Task<ICredential> GetOAuthCredentialsViaInteractiveBrowserFlow(GitRequest request)
{
Uri remoteUri = request.GetRemoteUri();

var refreshTokenService = GetRefreshTokenServiceName(remoteUri);

// We failed to use the refresh token either because it didn't exist, or because the refresh token is no
// longer valid. Either way we must now try authenticating using OAuth interactively.

// Start OAuth authentication flow
_context.Trace.WriteLine("Starting OAuth authentication flow...");
OAuth2TokenResult oauthResult = await _bitbucketAuth.CreateOAuthCredentialsAsync(request);
return await ResolveCredsAndStoreRefreshToken(request, oauthResult);
}

// Resolve the username
private async Task<ICredential> ResolveCredsAndStoreRefreshToken(GitRequest request, OAuth2TokenResult tokenSet)
{
Uri remoteUri = request.GetRemoteUri();

var refreshTokenService = GetRefreshTokenServiceName(remoteUri);
// Resolve the username to authenticate the git call
_context.Trace.WriteLine("Resolving username for OAuth credential...");
string newUserName = await ResolveOAuthUserNameAsync(request, oauthResult.AccessToken);
string newUserName = await ResolveOAuthUserNameAsync(request, tokenSet.AccessToken);
_context.Trace.WriteLine($"Username for OAuth credential is '{newUserName}'");

// Store the new RT
_context.Trace.WriteLine("Storing new refresh token...");
_context.CredentialStore.AddOrUpdate(refreshTokenService, newUserName, oauthResult.RefreshToken);
_context.Trace.WriteLine($"Storing new refresh token against user: '{request.UserName}'...");
// Store the refresh token against the username configured in git as this is how the access_token and
// refresh_token retrieval is wired - This ensures that the next refresh operation will be able to retrieve
// the stored refresh token.
_context.CredentialStore.AddOrUpdate(refreshTokenService, request.UserName, tokenSet.RefreshToken);
_context.Trace.WriteLine("Refresh token was successfully stored.");

// Return the new AT as the credential
return new GitCredential(newUserName, oauthResult.AccessToken);
return new GitCredential(newUserName, tokenSet.AccessToken);
}

private static bool SupportsOAuth(AuthenticationModes authModes)
Expand Down