diff --git a/src/shared/Microsoft.AzureRepos.Tests/AzureReposHostProviderTests.cs b/src/shared/Microsoft.AzureRepos.Tests/AzureReposHostProviderTests.cs index e8da8d79c..e65674825 100644 --- a/src/shared/Microsoft.AzureRepos.Tests/AzureReposHostProviderTests.cs +++ b/src/shared/Microsoft.AzureRepos.Tests/AzureReposHostProviderTests.cs @@ -239,14 +239,17 @@ public async Task AzureReposProvider_GetCredentialAsync_JwtMode_CachedAuthority_ [Fact] public async Task AzureReposProvider_GetCredentialAsync_JwtMode_CachedAuthority_DevAzureUrlOrgName_ReturnsCredential() { + var input = new InputArguments(new Dictionary { ["protocol"] = "https", ["host"] = "dev.azure.com", + ["path"] = "org/project/_git/repo", ["username"] = "org" }); var expectedOrgUri = new Uri("https://dev.azure.com/org"); + var remoteUri = new Uri("https://dev.azure.com/org/project/_git/repo"); var authorityUrl = "https://login.microsoftonline.com/common"; var expectedClientId = AzureDevOpsConstants.AadClientId; var expectedRedirectUri = AzureDevOpsConstants.AadRedirectUri; @@ -382,6 +385,7 @@ public async Task AzureReposProvider_GetCredentialAsync_JwtMode_CachedAuthority_ [Fact] public async Task AzureReposProvider_GetCredentialAsync_JwtMode_NoCachedAuthority_NoUser_ReturnsCredential() { + var input = new InputArguments(new Dictionary { ["protocol"] = "https", @@ -428,53 +432,10 @@ public async Task AzureReposProvider_GetCredentialAsync_JwtMode_NoCachedAuthorit Assert.Equal(accessToken, credential.Password); } - [Fact] - public async Task AzureReposProvider_GetCredentialAsync_PatMode_OrgInUserName_NoExistingPat_GeneratesCredential() - { - var input = new InputArguments(new Dictionary - { - ["protocol"] = "https", - ["host"] = "dev.azure.com", - ["username"] = "org" - }); - - var expectedOrgUri = new Uri("https://dev.azure.com/org"); - var authorityUrl = "https://login.microsoftonline.com/common"; - var expectedClientId = AzureDevOpsConstants.AadClientId; - var expectedRedirectUri = AzureDevOpsConstants.AadRedirectUri; - var expectedScopes = AzureDevOpsConstants.AzureDevOpsDefaultScopes; - var accessToken = "ACCESS-TOKEN"; - var personalAccessToken = "PERSONAL-ACCESS-TOKEN"; - var account = "john.doe"; - var authResult = CreateAuthResult(account, accessToken); - - var context = new TestCommandContext(); - - var azDevOpsMock = new Mock(MockBehavior.Strict); - azDevOpsMock.Setup(x => x.GetAuthorityAsync(expectedOrgUri)).ReturnsAsync(authorityUrl); - azDevOpsMock.Setup(x => x.CreatePersonalAccessTokenAsync(expectedOrgUri, accessToken, It.IsAny>())) - .ReturnsAsync(personalAccessToken); - - var msAuthMock = new Mock(MockBehavior.Strict); - msAuthMock.Setup(x => x.GetTokenForUserAsync(authorityUrl, expectedClientId, expectedRedirectUri, expectedScopes, null, true)) - .ReturnsAsync(authResult); - - var authorityCacheMock = new Mock(MockBehavior.Strict); - - var userMgrMock = new Mock(MockBehavior.Strict); - - var provider = new AzureReposHostProvider(context, azDevOpsMock.Object, msAuthMock.Object, authorityCacheMock.Object, userMgrMock.Object); - - ICredential credential = await provider.GetCredentialAsync(input); - - Assert.NotNull(credential); - Assert.Equal(account, credential.Account); - Assert.Equal(personalAccessToken, credential.Password); - } - [Fact] public async Task AzureReposProvider_GetCredentialAsync_PatMode_NoExistingPat_GeneratesCredential() { + var input = new InputArguments(new Dictionary { ["protocol"] = "https", diff --git a/src/shared/Microsoft.AzureRepos/AzureReposHostProvider.cs b/src/shared/Microsoft.AzureRepos/AzureReposHostProvider.cs index 55b1449d7..941b2bd53 100644 --- a/src/shared/Microsoft.AzureRepos/AzureReposHostProvider.cs +++ b/src/shared/Microsoft.AzureRepos/AzureReposHostProvider.cs @@ -92,8 +92,8 @@ public async Task GetCredentialAsync(InputArguments input) if (UsePersonalAccessTokens()) { - Uri remoteWithUserUri = input.GetRemoteUri(includeUser: true); - string service = GetServiceName(remoteWithUserUri); + Uri remoteUri = input.GetRemoteUri(); + string service = GetServiceName(remoteUri); string account = GetAccountNameForCredentialQuery(input); _context.Trace.WriteLine($"Looking for existing credential in store with service={service} account={account}..."); @@ -219,8 +219,8 @@ private async Task GeneratePersonalAccessTokenAsync(InputArguments "Unencrypted HTTP is not supported for Azure Repos. Ensure the repository remote URL is using HTTPS."); } - Uri remoteUserUri = input.GetRemoteUri(includeUser: true); - Uri orgUri = UriHelpers.CreateOrganizationUri(remoteUserUri, out _); + Uri remoteUri = input.GetRemoteUri(); + Uri orgUri = UriHelpers.CreateOrganizationUri(remoteUri, out _); // Determine the MS authentication authority for this organization _context.Trace.WriteLine("Determining Microsoft Authentication Authority..."); @@ -257,17 +257,17 @@ private async Task GeneratePersonalAccessTokenAsync(InputArguments private async Task GetAzureAccessTokenAsync(InputArguments input) { - Uri remoteWithUserUri = input.GetRemoteUri(includeUser: true); + Uri remoteUri = input.GetRemoteUri(); string userName = input.UserName; // We should not allow unencrypted communication and should inform the user - if (StringComparer.OrdinalIgnoreCase.Equals(remoteWithUserUri.Scheme, "http")) + if (StringComparer.OrdinalIgnoreCase.Equals(remoteUri.Scheme, "http")) { throw new Trace2Exception(_context.Trace2, "Unencrypted HTTP is not supported for Azure Repos. Ensure the repository remote URL is using HTTPS."); } - Uri orgUri = UriHelpers.CreateOrganizationUri(remoteWithUserUri, out string orgName); + Uri orgUri = UriHelpers.CreateOrganizationUri(remoteUri, out string orgName); _context.Trace.WriteLine($"Determining Microsoft Authentication authority for Azure DevOps organization '{orgName}'..."); if (TryGetAuthorityFromHeaders(input.WwwAuth, out string authAuthority)) @@ -306,8 +306,8 @@ private async Task GetAzureAccessTokenAsync(Inpu // var icmp = StringComparer.OrdinalIgnoreCase; if (!string.IsNullOrWhiteSpace(userName) && - (UriHelpers.IsVisualStudioComHost(remoteWithUserUri.Host) || - (UriHelpers.IsAzureDevOpsHost(remoteWithUserUri.Host) && !icmp.Equals(orgName, userName)))) + (UriHelpers.IsVisualStudioComHost(remoteUri.Host) || + (UriHelpers.IsAzureDevOpsHost(remoteUri.Host) && !icmp.Equals(orgName, userName)))) { _context.Trace.WriteLine("Using username as specified in remote."); } @@ -422,7 +422,7 @@ private static string GetServiceName(Uri remoteUri) { // If we're given the full path for an older *.visualstudio.com-style URL then we should // respect that in the service name. - return remoteUri.WithoutUserInfo().AbsoluteUri.TrimEnd('/'); + return remoteUri.AbsoluteUri.TrimEnd('/'); } throw new InvalidOperationException("Host is not Azure DevOps.");