public void Bind(string orgName, string userName, bool local)
        {
            EnsureArgument.NotNullOrWhiteSpace(orgName, nameof(orgName));

            IGitConfiguration config = _git.GetConfiguration();

            string key = GetOrgUserKey(orgName);

            if (local)
            {
                _trace.WriteLine(userName == AzureReposBinding.NoInherit
                    ? $"Setting binding to 'do not inherit' for organization '{orgName}' in local repository..."
                    : $"Binding user '{userName}' to organization '{orgName}' in local repository...");

                if (_git.IsInsideRepository())
                {
                    config.Set(GitConfigurationLevel.Local, key, userName);
                }
                else
                {
                    _trace.WriteLine("Cannot set local configuration binding - not inside a repository!");
                }
            }
            else
            {
                EnsureArgument.NotNullOrWhiteSpace(userName, nameof(userName));

                _trace.WriteLine($"Binding user '{userName}' to organization '{orgName}' in global configuration...");
                config.Set(GitConfigurationLevel.Global, key, userName);
            }
        }
        public void UpdateAuthority(string orgName, string authority)
        {
            EnsureArgument.NotNullOrWhiteSpace(orgName, nameof(orgName));

            _trace.WriteLine($"Updating cached authority for '{orgName}' to '{authority}'...");

            IGitConfiguration config = _git.GetConfiguration();

            config.Set(GitConfigurationLevel.Global, GetAuthorityKey(orgName), authority);
        }
        public void GitConfiguration_Set_All_ThrowsException()
        {
            string repoPath = CreateRepository(out _);

            string            gitPath = GetGitPath();
            var               trace   = new NullTrace();
            var               git     = new GitProcess(trace, gitPath, repoPath);
            IGitConfiguration config  = git.GetConfiguration(GitConfigurationLevel.All);

            Assert.Throws <InvalidOperationException>(() => config.Set("core.foobar", "test123"));
        }
        public void GitConfiguration_Set_Local_SetsLocalConfig()
        {
            string repoPath = CreateRepository(out string workDirPath);

            string            gitPath = GetGitPath();
            var               trace   = new NullTrace();
            var               git     = new GitProcess(trace, gitPath, repoPath);
            IGitConfiguration config  = git.GetConfiguration(GitConfigurationLevel.Local);

            config.Set("core.foobar", "foo123");

            GitResult localResult = Git(repoPath, workDirPath, "config --local core.foobar");

            Assert.Equal("foo123", localResult.StandardOutput.Trim());
        }
        public Task ConfigureAsync(ConfigurationTarget target)
        {
            string useHttpPathKey = $"{KnownGitCfg.Credential.SectionName}.https://dev.azure.com.{KnownGitCfg.Credential.UseHttpPath}";

            GitConfigurationLevel configurationLevel = target == ConfigurationTarget.System
                ? GitConfigurationLevel.System
                : GitConfigurationLevel.Global;

            IGitConfiguration targetConfig = _context.Git.GetConfiguration();

            if (targetConfig.TryGet(useHttpPathKey, false, out string currentValue) && currentValue.IsTruthy())
            {
                _context.Trace.WriteLine("Git configuration 'credential.useHttpPath' is already set to 'true' for https://dev.azure.com.");
            }
            else
            {
                _context.Trace.WriteLine("Setting Git configuration 'credential.useHttpPath' to 'true' for https://dev.azure.com...");
                targetConfig.Set(configurationLevel, useHttpPathKey, "true");
            }

            return(Task.CompletedTask);
        }
Example #6
0
        public async Task <IHostProvider> GetProviderAsync(InputArguments input)
        {
            IHostProvider provider;

            //
            // Try and locate a specified provider
            //
            if (_context.Settings.ProviderOverride is string providerId)
            {
                _context.Trace.WriteLine($"Host provider override was set id='{providerId}'");

                if (!StringComparer.OrdinalIgnoreCase.Equals(Constants.ProviderIdAuto, providerId))
                {
                    provider = _hostProviders
                               .SelectMany(x => x.Value)
                               .FirstOrDefault(x => StringComparer.OrdinalIgnoreCase.Equals(x.Id, providerId));

                    if (provider is null)
                    {
                        _context.Trace.WriteLine($"No host provider was found with ID '{providerId}'.. falling back to auto-detection.");
                        _context.Streams.Error.WriteLine($"warning: a host provider override was set but no such provider '{providerId}' was found. Falling back to auto-detection.");
                    }
                    else
                    {
                        return(provider);
                    }
                }
            }
            //
            // Try and locate a provider by supported authorities
            //
            else if (_context.Settings.LegacyAuthorityOverride is string authority)
            {
                _context.Trace.WriteLine($"Host provider authority override was set authority='{authority}'");
                _context.Streams.Error.WriteLine("warning: the `credential.authority` and `GCM_AUTHORITY` settings are deprecated.");
                _context.Streams.Error.WriteLine($"warning: see {Constants.HelpUrls.GcmAuthorityDeprecated} for more information.");

                if (!StringComparer.OrdinalIgnoreCase.Equals(Constants.AuthorityIdAuto, authority))
                {
                    provider = _hostProviders
                               .SelectMany(x => x.Value)
                               .FirstOrDefault(x => x.SupportedAuthorityIds.Contains(authority, StringComparer.OrdinalIgnoreCase));

                    if (provider is null)
                    {
                        _context.Trace.WriteLine($"No host provider was found with authority '{authority}'.. falling back to auto-detection.");
                        _context.Streams.Error.WriteLine($"warning: a supported authority override was set but no such provider supporting authority '{authority}' was found. Falling back to auto-detection.");
                    }
                    else
                    {
                        return(provider);
                    }
                }
            }

            //
            // Auto-detection
            // Perform auto-detection network probe and remember the result
            //
            _context.Trace.WriteLine("Performing auto-detection of host provider.");

            var uri = input.GetRemoteUri();

            if (uri is null)
            {
                throw new Exception("Unable to detect host provider without a remote URL");
            }

            var probeTimeout = TimeSpan.FromMilliseconds(_context.Settings.AutoDetectProviderTimeout);

            _context.Trace.WriteLine($"Auto-detect probe timeout is {probeTimeout.TotalSeconds} ms.");

            HttpResponseMessage probeResponse = null;

            async Task <IHostProvider> MatchProviderAsync(HostProviderPriority priority)
            {
                if (_hostProviders.TryGetValue(priority, out ICollection <IHostProvider> providers))
                {
                    _context.Trace.WriteLine($"Checking against {providers.Count} host providers registered with priority '{priority}'.");

                    // Try matching using the static Git input arguments first (cheap)
                    if (providers.TryGetFirst(x => x.IsSupported(input), out IHostProvider match))
                    {
                        return(match);
                    }

                    // Try matching using the HTTP response from a query to the remote URL (expensive).
                    // The user may have disabled this feature with a zero or negative timeout for performance reasons.
                    // We only probe the remote once and reuse the same response for all providers.
                    if (probeTimeout.TotalMilliseconds > 0)
                    {
                        if (probeResponse is null)
                        {
                            _context.Trace.WriteLine("Querying remote URL for host provider auto-detection.");

                            using (HttpClient client = _context.HttpClientFactory.CreateClient())
                            {
                                client.Timeout = probeTimeout;

                                try
                                {
                                    probeResponse = await client.HeadAsync(uri);
                                }
                                catch (TaskCanceledException)
                                {
                                    _context.Streams.Error.WriteLine($"warning: auto-detection of host provider took too long (>{probeTimeout.TotalMilliseconds}ms)");
                                    _context.Streams.Error.WriteLine($"warning: see {Constants.HelpUrls.GcmAutoDetect} for more information.");
                                }
                                catch (Exception ex)
                                {
                                    // The auto detect probing failed for some other reason.
                                    // We don't particular care why, but we should not crash!
                                    _context.Streams.Error.WriteLine($"warning: failed to probe '{uri}' to detect provider");
                                    _context.Streams.Error.WriteLine($"warning: {ex.Message}");
                                    _context.Streams.Error.WriteLine($"warning: see {Constants.HelpUrls.GcmAutoDetect} for more information.");
                                }
                            }
                        }

                        if (providers.TryGetFirst(x => x.IsSupported(probeResponse), out match))
                        {
                            return(match);
                        }
                    }
                }

                return(null);
            }

            // Match providers starting with the highest priority
            IHostProvider match = await MatchProviderAsync(HostProviderPriority.High) ??
                                  await MatchProviderAsync(HostProviderPriority.Normal) ??
                                  await MatchProviderAsync(HostProviderPriority.Low) ??
                                  throw new Exception("No host provider available to service this request.");

            // If we ended up making a network call then set the host provider explicitly
            // to avoid future calls!
            if (probeResponse != null)
            {
                IGitConfiguration gitConfig = _context.Git.GetConfiguration();
                var keyName = string.Format(CultureInfo.InvariantCulture, "{0}.{1}.{2}",
                                            Constants.GitConfiguration.Credential.SectionName, uri.ToString().TrimEnd('/'),
                                            Constants.GitConfiguration.Credential.Provider);

                try
                {
                    _context.Trace.WriteLine($"Remembering host provider for '{uri}' as '{match.Id}'...");
                    gitConfig.Set(GitConfigurationLevel.Global, keyName, match.Id);
                }
                catch (Exception ex)
                {
                    _context.Trace.WriteLine("Failed to set host provider!");
                    _context.Trace.WriteException(ex);

                    _context.Streams.Error.WriteLine("warning: failed to remember result of host provider detection!");
                    _context.Streams.Error.WriteLine($"warning: try setting this manually: `git config --global {keyName} {match.Id}`");
                }
            }

            return(match);
        }