/// <summary> /// Use locally stored refresh_token to attempt to retrieve a new access_token. /// </summary> /// <param name="targetUri"></param> /// <param name="refreshToken"></param> /// <param name="username"></param> /// <returns> /// A <see cref="Credential"/> containing the new access_token if successful, null otherwise /// </returns> private async Task <Credential> RefreshCredentials(TargetUri targetUri, string refreshToken, string username) { Credential credentials = null; AuthenticationResult result; if ((result = await BitbucketAuthority.RefreshToken(targetUri, refreshToken)) == true) { Trace.WriteLine("token refresh succeeded"); var tempCredentials = GenerateCredentials(targetUri, username, ref result); if (!await BitbucketAuthority.ValidateCredentials(targetUri, username, tempCredentials)) { // oddly our new access_token failed to work, maybe we've been revoked in the // last millisecond? return(credentials); } // the new access_token is good, so store it and store the refresh_token used to get it. await SetCredentials(targetUri, tempCredentials, null); var newRefreshCredentials = GenerateRefreshCredentials(targetUri, username, ref result); await SetCredentials(GetRefreshTokenTargetUri(targetUri), newRefreshCredentials, username); credentials = tempCredentials; } return(credentials); }
/// <inheritdoc/> public async Task <Credential> ValidateCredentials(TargetUri targetUri, string username, Credential credentials) { BaseSecureStore.ValidateTargetUri(targetUri); BaseSecureStore.ValidateCredential(credentials); var userSpecificTargetUri = GetPerUserTargetUri(targetUri, username); if (await BitbucketAuthority.ValidateCredentials(userSpecificTargetUri, username, credentials)) { return(credentials); } var userSpecificRefreshCredentials = GetCredentials(GetRefreshTokenTargetUri(userSpecificTargetUri), username); // if there are refresh credentials it suggests it might be OAuth so we can try and // refresh the access_token and try again. if (userSpecificRefreshCredentials == null) { return(null); } Credential refreshedCredentials; if ((refreshedCredentials = await RefreshCredentials(userSpecificTargetUri, userSpecificRefreshCredentials.Password, username ?? credentials.Username)) != null) { return(refreshedCredentials); } return(null); }
/// <inheritdoc/> public async Task <Credential> InteractiveLogon(TargetUri targetUri) { Credential credentials = null; string username; string password; // Ask the user for basic authentication credentials if (AcquireCredentialsCallback("Please enter your Bitbucket credentials for ", targetUri, out username, out password)) { AuthenticationResult result; credentials = new Credential(username, password); if (result = await BitbucketAuthority.AcquireToken(targetUri, credentials, AuthenticationResultType.None, TokenScope)) { Trace.WriteLine("token acquisition succeeded"); credentials = GenerateCredentials(targetUri, username, ref result); await SetCredentials(targetUri, credentials, username); // if a result callback was registered, call it if (AuthenticationResultCallback != null) { AuthenticationResultCallback(targetUri, result); } return(credentials); } else if (result == AuthenticationResultType.TwoFactor) { // Basic authentication attempt returned a result indicating the user has 2FA on so prompt // the user to run the OAuth dance. if (AcquireAuthenticationOAuthCallback("", targetUri, result, username)) { if (result = await BitbucketAuthority.AcquireToken(targetUri, credentials, AuthenticationResultType.TwoFactor, TokenScope)) { Trace.WriteLine("token acquisition succeeded"); credentials = GenerateCredentials(targetUri, username, ref result); await SetCredentials(targetUri, credentials, username); await SetCredentials(GetRefreshTokenTargetUri(targetUri), new Credential(result.RefreshToken.Type.ToString(), result.RefreshToken.Value), username); // if a result callback was registered, call it if (AuthenticationResultCallback != null) { AuthenticationResultCallback(targetUri, result); } return(credentials); } } } } Trace.WriteLine("interactive logon failed"); return(credentials); }
/// <inheritdoc/> public async Task <Credential> ValidateCredentials(TargetUri targetUri, string username, Credential credentials) { if (targetUri is null) { throw new ArgumentNullException(nameof(targetUri)); } if (credentials is null) { throw new ArgumentNullException(nameof(credentials)); } TargetUri userSpecificTargetUri; if (targetUri.TargetUriContainsUsername) { userSpecificTargetUri = targetUri; } else { userSpecificTargetUri = targetUri.GetPerUserTargetUri(username); } if (await BitbucketAuthority.ValidateCredentials(userSpecificTargetUri, username, credentials)) { return(credentials); } var userSpecificRefreshCredentials = await GetCredentials(GetRefreshTokenTargetUri(userSpecificTargetUri), username); // if there are refresh credentials it suggests it might be OAuth so we can try and // refresh the access_token and try again. if (userSpecificRefreshCredentials == null) { return(null); } Credential refreshedCredentials; if ((refreshedCredentials = await RefreshCredentials(userSpecificTargetUri, userSpecificRefreshCredentials.Password, username ?? credentials.Username)) != null) { return(refreshedCredentials); } return(null); }