コード例 #1
0
        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);
        }
コード例 #2
0
        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);
        }
コード例 #3
0
        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));
        }
コード例 #4
0
        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));
        }
コード例 #5
0
        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]);
        }
コード例 #7
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);
        }
コード例 #8
0
        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));
        }
コード例 #9
0
        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);
        }
コード例 #10
0
        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);
        }
コード例 #11
0
        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]);
        }
コード例 #12
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
        }