Skip to content
This repository was archived by the owner on Jul 15, 2023. It is now read-only.

Commit 19c8a10

Browse files
author
J Wyman
authored
Merge pull request #720 from Foda/BitbucketBasicLoginFix-1.17
bitbucket: Fixed basic auth with new username
2 parents fd2cb28 + 5139cb6 commit 19c8a10

File tree

3 files changed

+54
-8
lines changed

3 files changed

+54
-8
lines changed

Bitbucket.Authentication/Src/Authentication.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -411,11 +411,12 @@ private Credential GenerateCredentials(TargetUri targetUri, string username,
411411
{
412412
Credential credentials = (Credential)result.Token;
413413

414-
var realUsername = GetRealUsername(result.RemoteUsername, username);
415414

416-
if (!targetUri.ContainsUserInfo)
415+
// No user info in Uri, or it's a basic login so we need to personalize the credentials.
416+
if (!targetUri.ContainsUserInfo || result.Token.Type == TokenType.Personal)
417417
{
418418
// No user info in Uri so personalize the credentials.
419+
var realUsername = GetRealUsername(result.RemoteUsername, username);
419420
credentials = new Credential(realUsername, credentials.Password);
420421
}
421422

Bitbucket.Authentication/Src/OAuth/SimpleServer.cs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,19 @@ public static async Task<string> WaitForURLAsync(string url, CancellationToken c
5656
var context = await listener.GetContextAsync().RunWithCancellation(cancellationToken);
5757
rawUrl = context.Request.RawUrl;
5858

59-
//Serve back a simple auth message.
59+
Thread.Sleep(100); // Wait 100ms without this the server closes before the complete response has been written
60+
61+
// Serve back a simple authentication message.
6062
var html = GetSuccessString();
61-
context.Response.ContentType = "text/html";
62-
context.Response.OutputStream.WriteStringUtf8(html);
63-
64-
await Task.Delay(100); //Wait 100ms without this the server closes before the complete response has been written
63+
var buffer = System.Text.Encoding.UTF8.GetBytes(html);
64+
context.Response.ContentLength64 = buffer.Length;
65+
Task responseTask = context.Response.OutputStream.WriteAsync(buffer, 0, buffer.Length).ContinueWith((task) =>
66+
{
67+
context.Response.OutputStream.Close();
68+
listener.Stop();
69+
});
6570

66-
context.Response.Close();
71+
Thread.Sleep(100);
6772
}
6873
catch (TimeoutException ex)
6974
{

Bitbucket.Authentication/Test/AuthenticationTest.cs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,46 @@ public async void VerifyInteractiveLoginDoesNotAquireInvalidBasicAuthCredentials
473473
credentialStore.Verify(c => c.WriteCredentials(It.IsAny<TargetUri>(), It.IsAny<Credential>()), Times.Never);
474474
}
475475

476+
[Fact]
477+
public async void VerifyInteractiveLoginDoesNotAquireInvalidBasicAuthCredentialsWithUsername()
478+
{
479+
var bitbucketUrl = "https://bitbucket.org";
480+
var credentialStore = new Mock<ICredentialStore>();
481+
482+
// mock the result that normally causes issues
483+
var validAuthenticationResult = new AuthenticationResult(AuthenticationResultType.Success)
484+
{
485+
Token = new Token(_validPassword, TokenType.Personal),
486+
RemoteUsername = _validUsername
487+
};
488+
489+
var targetUri = new TargetUri(bitbucketUrl);
490+
491+
// Mock the behaviour of IAuthority.AcquireToken() to basically mimic BasicAuthAuthenticator.GetAuthAsync() validating the useername/password
492+
var authority = new Mock<IAuthority>();
493+
authority
494+
.Setup(a => a.AcquireToken(It.IsAny<TargetUri>(), It.IsAny<Credential>(), It.IsAny<AuthenticationResultType>(), It.IsAny<TokenScope>()))
495+
// return 'success' with the validated credentials
496+
.Returns(Task.FromResult(validAuthenticationResult));
497+
498+
var bbAuth = new Authentication(RuntimeContext.Default, credentialStore.Object,
499+
MockInvalidBasicAuthCredentialsAquireCredentialsCallback, MockValidAquireAuthenticationOAuthCallback, authority.Object);
500+
501+
// perform login with username
502+
var credentials = await bbAuth.InteractiveLogon(targetUri, _validUsername);
503+
504+
Assert.NotNull(credentials);
505+
Assert.Equal(_validUsername, credentials.Username);
506+
Assert.Equal(_validPassword, credentials.Password);
507+
508+
// attempted to validate credentials
509+
authority.Verify(a => a.AcquireToken(It.IsAny<TargetUri>(), It.IsAny<Credential>(), It.IsAny<AuthenticationResultType>(),
510+
It.IsAny<TokenScope>()), Times.Once);
511+
512+
// must have a valid attempt to store the valid credentials
513+
credentialStore.Verify(c => c.WriteCredentials(It.IsAny<TargetUri>(), credentials), Times.Once);
514+
}
515+
476516
[Fact]
477517
public async void VerifyInteractiveLoginDoesNothingIfUserDoesNotEnterCredentials()
478518
{

0 commit comments

Comments
 (0)