LibGit2Sharp и интерфейс аутентификации - PullRequest
0 голосов
/ 25 апреля 2018

Я работаю с LibGit2Sharp, чтобы добавить ряд операций Git в приложение.Я добавил Microsoft.Alm.Authentication, чтобы помочь с аутентификацией и доступом к диспетчеру учетных данных.Это прекрасно работает для получения учетных данных, которые уже введены из командной строки.

Однако есть ли способ также подключиться к интерфейсу входа в систему диспетчера учетных данных, который запрашивает имя пользователя и пароль для Github,BitBucket и VSTS.Этот пользовательский интерфейс автоматически появляется из командной строки, но не запускается при использовании LibGit2Sharp.

Я посмотрел на проект GitCredentialManager на Github и вижу компоненты, предоставляющие пользовательский интерфейс, но перед тем, как попытатьсявыяснить, как подключить их в явном виде, есть ли какой-то способ, по которому мне не хватает, что это предусмотрено как часть Microsoft.Alm.Authentication (или связанного пакета)?Или кто-нибудь может указать на пример или руководство о том, как лучше всего это подключить?

Ответы [ 2 ]

0 голосов
/ 27 марта 2019

Мне удалось заставить ваше решение работать с некоторыми незначительными изменениями. Я вставляю здесь пример кода для отправки с использованием учетных данных git. Он работает с использованием учетных данных, уже хранящихся на компьютере, и запрашивает учетные данные в первый раз с помощью пользовательского интерфейса.

Единственная проблема, с которой я столкнулся на данный момент, заключается в том, что у пользователя запрашиваются учетные данные, и они вводят неверный логин / пароль. Git пишет в консоль с просьбой указать пользователя / пароль, и процесс не завершится, пока вы не введете это. Пытался контролировать StandardError / Output безуспешно. Я получаю текст ошибки в stderror, но только после его заполнения вручную.

public void PushLibGit2Sharp(string repositoryFolder, string branch)
{
    using (var repo = new Repository(repositoryFolder))
    {
        var options = new PushOptions
        {
            CredentialsProvider = (url, usernameFromUrl, types) =>
            {
                ProcessStartInfo startInfo = new ProcessStartInfo
                {
                    FileName = "git.exe",
                    Arguments = "credential fill",
                    UseShellExecute = false,
                    WindowStyle = ProcessWindowStyle.Hidden,
                    CreateNoWindow = true,
                    RedirectStandardInput = true,
                    RedirectStandardOutput = true,
                    RedirectStandardError = true
                };

                Process process = new Process
                {
                    StartInfo = startInfo
                };

                process.Start();

                // Write query to stdin. 
                // For stdin to work we need to send \n instead of WriteLine
                // We need to send empty line at the end
                var uri = new Uri(url);
                process.StandardInput.NewLine = "\n";       
                process.StandardInput.WriteLine($"protocol={uri.Scheme}");
                process.StandardInput.WriteLine($"host={uri.Host}");
                process.StandardInput.WriteLine($"path={uri.AbsolutePath}");
                process.StandardInput.WriteLine();

                // Get user/pass from stdout
                string username = null;
                string password = null;
                string line;
                while ((line = process.StandardOutput.ReadLine()) != null)
                {
                    string[] details = line.Split('=');
                    if (details[0] == "username")
                    {
                        username = details[1];
                    }
                    else if (details[0] == "password")
                    {
                        password = details[1];
                    }
                }

                return new UsernamePasswordCredentials()
                {
                    Username = username,
                    Password = password
                };
            }
        };

        repo.Network.Push(repo.Branches[branch], options);
    }
}
0 голосов
/ 25 апреля 2018

К сожалению, в libgit2 (или LibGit2Sharp) нет функциональности, позволяющей напрямую взаимодействовать с функциональностью git-credential-helper, которая используется самим git для выполнения этого действия.

Вместо этого вы можете установить CredentialsHandlerна вашем PushOptions (или FetchOptions), например:

options.CredentialsProvider = (url, usernameFromUrl, types) => {
    string username, password;

    Uri uri = new Uri(url);   
    string hostname = uri.Host;

    ProcessStartInfo startInfo = new ProcessStartInfo();
    startInfo.UseShellExecute = false;

    startInfo.RedirectStandardInput = true;
    startInfo.RedirectStandardOutput = true;
    startInfo.RedirectStandardError = true;

    startInfo.FileName = "git.exe";
    startInfo.Arguments = "credential fill";

    Process process = new Process();
    process.StartInfo = startInfo;
    process.Start();

    process.StandardInput.WriteLine("hostname={0}", hostname);
    process.StandardInput.WriteLine("username={0}", usernameFromUrl);

    while ((line = process.StandardOutput.ReadLine()) != null)
    {
        string[] details = line.Split('=', 2);
        if (details[0] == "username")
        {
            username = details[1];
        }
        else if (details[0] == "password")
        {
            password = details[1];
        }
    }

    return new UsernamePasswordCredentials(username, password);
};
...