Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to reuse nuget credentials for choco #2221

Open
tapika opened this issue Mar 27, 2021 · 2 comments
Open

Allow to reuse nuget credentials for choco #2221

tapika opened this issue Mar 27, 2021 · 2 comments

Comments

@tapika
Copy link

tapika commented Mar 27, 2021

It's possible to host nuget/choco packages on private feed in azure devops.

Private means that it also requires authentication to list, download or install any package from that feed.

Theoretically you can use choco's approach to configure credentials to azure devops -

https://docs.chocolatey.org/en-us/create/commands/api-key

and provide user name as login and azure devops Personal Authentication Token (PAT) as password.

From software developer perspective however - it's easier just to configure credentials once for both - nuget packages and for choco packages in one place and use them for all eternity (that is 1 year as long as PAT is valid).

You can configure and store nuget credentials in centralized manner - that is using %APPDATA%\NuGet\nuget.config folder.

(Instructions can be found from here for example: https://mallibone.com/post/private-nuget-feed-azure-devops )

It would simplify whole picture if choco could re-use same kind of credentials as nuget uses - that is same config file.

Based on my brief analysis there needs to be implemented two features:

  1. Url translation

https://....azure.com/.../nuget/v3/index.json => https://....azure.com/.../nuget/v2

Azure devops supports older communication protocols, which is used by choco - v2. Maybe choco can translate those url automatically (throw away v3... part and put v2 instead) - this is needed not only for command line, but also for url stored in nuget.config.

  1. Get user / password (PAT) from %APPDATA%\NuGet\nuget.config - if that file exists.

Using this approach it's possible to configure nuget and choco in centralized manner and use both as necessary.

@tapika tapika changed the title Allow to reuse credentials from %APPDATA%\NuGet\nuget.config Allow to reuse nuget credentials from choco (%APPDATA%\NuGet\nuget.config) Mar 27, 2021
@tapika tapika changed the title Allow to reuse nuget credentials from choco (%APPDATA%\NuGet\nuget.config) Allow to reuse nuget credentials for choco Mar 27, 2021
@tapika
Copy link
Author

tapika commented Mar 27, 2021

Related tickets:

#2146
#1721

@tapika
Copy link
Author

tapika commented Mar 27, 2021

Patch should be trivial, e.g.

src/chocolatey/infrastructure.app/nuget/ChocolateyNugetCredentialProvider.cs

....

            // Fetch login / password from %APPDATA%\NuGet\nuget.config file
            if (source == null)
            {
                string nugetConfigDir = Environment.ExpandEnvironmentVariables(@"%APPDATA%\NuGet");
                string nugetConfig = System.IO.Path.Combine(nugetConfigDir, "nuget.config");

                if (System.IO.File.Exists(nugetConfig))
                {
                    try
                    {
                        var pfs = new PhysicalFileSystem(nugetConfigDir);
                        var settings = Settings.LoadDefaultSettings(pfs, nugetConfig, null);
                        var packageSourceProvider = new PackageSourceProvider(settings);
                        var sources = packageSourceProvider.LoadPackageSources().ToArray();

                        foreach (var configSource in sources)
                        {
                            string url = NugetCommon.UriBackwardsCompatibleSimplify(configSource.Source);
                            if (url == uri.ToString() && 
                                !String.IsNullOrEmpty(configSource.UserName) && 
                                !String.IsNullOrEmpty(configSource.Password))
                            { 
                                return new NetworkCredential(configSource.UserName, configSource.Password);
                            }
                        }
                    }
                    catch (Exception ex)
                    { 
                        this.Log().Debug($"Failed to load config file '{nugetConfig}': {ex.Message}");
                    }
                }
            }

            if (source == null)
            {
                this.Log().Debug("Asking user for credentials for '{0}'".format_with(uri.OriginalString));
                return get_credentials_from_user(uri, proxy, credentialType);
            }
            else
            {
                this.Log().Debug("Using saved credentials");
            }
....


src/chocolatey/infrastructure.app/nuget/NugetCommon.cs

       public static string UriBackwardsCompatibleSimplify(string originalUri)
        {
            var r = new System.Text.RegularExpressions.Regex("/v3/.*");
            if (!r.Match(originalUri).Success)
            {
                return originalUri;
            }
            
            var s = r.Replace(originalUri, "/v2");
            return s;
        }

...
                try
                {
                    var uri = new Uri(source);
                    if (uri.IsFile || uri.IsUnc)
                    {
                        repositories.Add(new ChocolateyLocalPackageRepository(uri.LocalPath) { Logger = nugetLogger });
                    }
                    else
                    {
                        //added line
                        uri = new Uri(UriBackwardsCompatibleSimplify(source));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant