public async Task AzureReposProvider_GetCredentialAsync_PatMode_ExistingPat_ReturnsExistingCredential() { var input = new InputArguments(new Dictionary <string, string> { ["protocol"] = "https", ["host"] = "dev.azure.com", ["path"] = "org/proj/_git/repo" }); var remoteUri = new Uri("https://dev.azure.com/org/proj/_git/repo"); var personalAccessToken = "PERSONAL-ACCESS-TOKEN"; const string service = "https://dev.azure.com/org"; const string account = "john.doe"; var context = new TestCommandContext(); context.CredentialStore.Add(service, account, personalAccessToken); var azDevOps = Mock.Of <IAzureDevOpsRestApi>(); var msAuth = Mock.Of <IMicrosoftAuthentication>(); var authorityCache = Mock.Of <IAzureDevOpsAuthorityCache>(); var userMgr = Mock.Of <IAzureReposBindingManager>(); var provider = new AzureReposHostProvider(context, azDevOps, msAuth, authorityCache, userMgr); ICredential credential = await provider.GetCredentialAsync(input); Assert.NotNull(credential); Assert.Equal(account, credential.Account); Assert.Equal(personalAccessToken, credential.Password); }
public async Task AzureReposProvider_GetCredentialAsync_JwtMode_NoCachedAuthority_NoUser_ReturnsCredential() { var orgName = "org"; var input = new InputArguments(new Dictionary <string, string> { ["protocol"] = "https", ["host"] = "dev.azure.com", ["path"] = "org/proj/_git/repo" }); var expectedOrgUri = new Uri("https://dev.azure.com/org"); var remoteUri = new Uri("https://dev.azure.com/org/proj/_git/repo"); var authorityUrl = "https://login.microsoftonline.com/common"; var expectedClientId = AzureDevOpsConstants.AadClientId; var expectedRedirectUri = AzureDevOpsConstants.AadRedirectUri; var expectedScopes = AzureDevOpsConstants.AzureDevOpsDefaultScopes; var accessToken = "ACCESS-TOKEN"; var account = "john.doe"; var authResult = CreateAuthResult(account, accessToken); var context = new TestCommandContext(); // Use OAuth Access Tokens context.Environment.Variables[AzureDevOpsConstants.EnvironmentVariables.CredentialType] = AzureDevOpsConstants.OAuthCredentialType; var azDevOpsMock = new Mock <IAzureDevOpsRestApi>(MockBehavior.Strict); azDevOpsMock.Setup(x => x.GetAuthorityAsync(expectedOrgUri)).ReturnsAsync(authorityUrl); var msAuthMock = new Mock <IMicrosoftAuthentication>(MockBehavior.Strict); msAuthMock.Setup(x => x.GetTokenAsync(authorityUrl, expectedClientId, expectedRedirectUri, expectedScopes, null)) .ReturnsAsync(authResult); var authorityCacheMock = new Mock <IAzureDevOpsAuthorityCache>(MockBehavior.Strict); authorityCacheMock.Setup(x => x.GetAuthority(It.IsAny <string>())).Returns((string)null); authorityCacheMock.Setup(x => x.UpdateAuthority(orgName, authorityUrl)); var userMgrMock = new Mock <IAzureReposBindingManager>(MockBehavior.Strict); userMgrMock.Setup(x => x.GetBinding(orgName)).Returns((AzureReposBinding)null); 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(accessToken, credential.Password); }
public void AzureReposProvider_IsSupported_NonAzureRepos_ReturnsFalse() { var input = new InputArguments(new Dictionary <string, string> { ["protocol"] = "https", ["host"] = "example.com", ["path"] = "org/proj/_git/repo", }); var provider = new AzureReposHostProvider(new TestCommandContext()); Assert.False(provider.IsSupported(input)); }
public void AzureReposProvider_IsSupported_VisualStudioHost_UnencryptedHttp_ReturnsTrue() { var input = new InputArguments(new Dictionary <string, string> { ["protocol"] = "http", ["host"] = "org.visualstudio.com", }); var provider = new AzureReposHostProvider(new TestCommandContext()); // We report that we support unencrypted HTTP here so that we can fail and // show a helpful error message in the call to `CreateCredentialAsync` instead. Assert.True(provider.IsSupported(input)); }
public async Task AzureReposHostProvider_ConfigureAsync_UseHttpPathUnset_SetsUseHttpPathTrue() { var provider = new AzureReposHostProvider(new TestCommandContext()); var environment = new TestEnvironment(); var git = new TestGit(); await provider.ConfigureAsync( environment, EnvironmentVariableTarget.User, git, GitConfigurationLevel.Global); Assert.Single(git.GlobalConfiguration.Dictionary); Assert.True(git.GlobalConfiguration.Dictionary.TryGetValue(AzDevUseHttpPathKey, out IList <string> actualValues)); Assert.Single(actualValues); Assert.Equal("true", actualValues[0]); }
public async Task AzureReposHostProvider_ConfigureAsync_UseHttpPathSetTrue_DoesNothing() { var context = new TestCommandContext(); var provider = new AzureReposHostProvider(context); context.Git.GlobalConfiguration.Dictionary[AzDevUseHttpPathKey] = new List <string> { "true" }; await provider.ConfigureAsync(ConfigurationTarget.User); Assert.Single(context.Git.GlobalConfiguration.Dictionary); Assert.True(context.Git.GlobalConfiguration.Dictionary.TryGetValue(AzDevUseHttpPathKey, out IList <string> actualValues)); Assert.Single(actualValues); Assert.Equal("true", actualValues[0]); }
public async Task AzureReposHostProvider_UnconfigureAsync_UseHttpPathSet_RemovesEntry() { var provider = new AzureReposHostProvider(new TestCommandContext()); var environment = new TestEnvironment(); var git = new TestGit(); git.GlobalConfiguration.Dictionary[AzDevUseHttpPathKey] = new List <string> { "true" }; await provider.UnconfigureAsync( environment, EnvironmentVariableTarget.User, git, GitConfigurationLevel.Global); Assert.Empty(git.GlobalConfiguration.Dictionary); }
public async Task AzureReposProvider_GetCredentialAsync_UnencryptedHttp_ThrowsException() { var input = new InputArguments(new Dictionary <string, string> { ["protocol"] = "http", ["host"] = "dev.azure.com", ["path"] = "org/proj/_git/repo" }); var context = new TestCommandContext(); var azDevOps = Mock.Of <IAzureDevOpsRestApi>(); var msAuth = Mock.Of <IMicrosoftAuthentication>(); var provider = new AzureReposHostProvider(context, azDevOps, msAuth); await Assert.ThrowsAsync <Exception>(() => provider.GetCredentialAsync(input)); }
public async Task AzureReposProvider_GetCredentialAsync_PatMode_NoExistingPat_GeneratesCredential() { var input = new InputArguments(new Dictionary <string, string> { ["protocol"] = "https", ["host"] = "dev.azure.com", ["path"] = "org/proj/_git/repo" }); var expectedOrgUri = new Uri("https://dev.azure.com/org"); var remoteUri = new Uri("https://dev.azure.com/org/proj/_git/repo"); 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 <IAzureDevOpsRestApi>(MockBehavior.Strict); azDevOpsMock.Setup(x => x.GetAuthorityAsync(expectedOrgUri)).ReturnsAsync(authorityUrl); azDevOpsMock.Setup(x => x.CreatePersonalAccessTokenAsync(expectedOrgUri, accessToken, It.IsAny <IEnumerable <string> >())) .ReturnsAsync(personalAccessToken); var msAuthMock = new Mock <IMicrosoftAuthentication>(MockBehavior.Strict); msAuthMock.Setup(x => x.GetTokenAsync(authorityUrl, expectedClientId, expectedRedirectUri, expectedScopes, null)) .ReturnsAsync(authResult); var authorityCacheMock = new Mock <IAzureDevOpsAuthorityCache>(MockBehavior.Strict); var userMgrMock = new Mock <IAzureReposBindingManager>(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); }
async Task <ICredential?> GetCredentialAsync(Uri uri) { if (credential != null) { return(credential); } var input = new InputArguments(new Dictionary <string, string> { ["protocol"] = "https", ["host"] = "dev.azure.com", ["path"] = uri.GetComponents(UriComponents.Path, UriFormat.Unescaped), }); var provider = new AzureReposHostProvider(new CommandContext(AppPath.Default)); credential = await provider.GetCredentialAsync(input); return(credential); }
public async Task AzureReposHostProvider_ConfigureAsync_UseHttpPathSetFalse_SetsUseHttpPathTrue() { var provider = new AzureReposHostProvider(new TestCommandContext()); var environment = new TestEnvironment(); var config = new TestGitConfiguration(new Dictionary <string, IList <string> > { [AzDevUseHttpPathKey] = new List <string> { "false" } }); await provider.ConfigureAsync( environment, EnvironmentVariableTarget.User, config, GitConfigurationLevel.Global); Assert.Single(config.Dictionary); Assert.True(config.Dictionary.TryGetValue(AzDevUseHttpPathKey, out IList <string> actualValues)); Assert.Single(actualValues); Assert.Equal("true", actualValues[0]); }
public async Task AzureReposProvider_GetCredentialAsync_ReturnsCredential() { var input = new InputArguments(new Dictionary <string, string> { ["protocol"] = "https", ["host"] = "dev.azure.com", ["path"] = "org/proj/_git/repo" }); var expectedOrgUri = new Uri("https://dev.azure.com/org"); var remoteUri = new Uri("https://dev.azure.com/org/proj/_git/repo"); var authorityUrl = "https://login.microsoftonline.com/common"; var expectedClientId = AzureDevOpsConstants.AadClientId; var expectedRedirectUri = AzureDevOpsConstants.AadRedirectUri; var expectedResource = AzureDevOpsConstants.AadResourceId; var accessToken = CreateJwt("john.doe"); var personalAccessToken = "PERSONAL-ACCESS-TOKEN"; var context = new TestCommandContext(); var azDevOpsMock = new Mock <IAzureDevOpsRestApi>(); azDevOpsMock.Setup(x => x.GetAuthorityAsync(expectedOrgUri)) .ReturnsAsync(authorityUrl); azDevOpsMock.Setup(x => x.CreatePersonalAccessTokenAsync(expectedOrgUri, accessToken, It.IsAny <IEnumerable <string> >())) .ReturnsAsync(personalAccessToken); var msAuthMock = new Mock <IMicrosoftAuthentication>(); msAuthMock.Setup(x => x.GetAccessTokenAsync(authorityUrl, expectedClientId, expectedRedirectUri, expectedResource, remoteUri, null)) .ReturnsAsync(accessToken); var provider = new AzureReposHostProvider(context, azDevOpsMock.Object, msAuthMock.Object); ICredential credential = await provider.GetCredentialAsync(input); Assert.NotNull(credential); Assert.Equal(personalAccessToken, credential.Password); // We don't care about the username value }