Skip to content

Commit 6b4feb9

Browse files
authored
add setting to disable credential provider per package source (#701)
1 parent 5b65756 commit 6b4feb9

10 files changed

Lines changed: 85 additions & 14 deletions

src/NuGetForUnity/Editor/Configuration/NugetConfigFile.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ public class NugetConfigFile
5858

5959
private const string ProtocolVersionAttributeName = "protocolVersion";
6060

61+
private const string EnableCredentialProviderAttributeName = "enableCredentialProvider";
62+
6163
private const string PasswordAttributeName = "password";
6264

6365
private const string UpdateSearchBatchSizeAttributeName = "updateSearchBatchSize";
@@ -392,7 +394,7 @@ public static NugetConfigFile CreateDefaultFile([NotNull] string filePath)
392394
<configuration>
393395
<packageSources>
394396
<clear />
395-
<add key=""nuget.org"" value=""https://api.nuget.org/v3/index.json"" />
397+
<add key=""nuget.org"" value=""https://api.nuget.org/v3/index.json"" enableCredentialProvider=""false"" />
396398
</packageSources>
397399
<disabledPackageSources />
398400
<activePackageSource>
@@ -438,6 +440,12 @@ public void Save([NotNull] string filePath)
438440
addElement.Add(new XAttribute(ProtocolVersionAttributeName, source.SavedProtocolVersion));
439441
}
440442

443+
if (!source.EnableCredentialProvider)
444+
{
445+
addElement.Add(
446+
new XAttribute(EnableCredentialProviderAttributeName, source.EnableCredentialProvider.ToString().ToLowerInvariant()));
447+
}
448+
441449
if (source is NugetPackageSourceV3 sourceV3)
442450
{
443451
if (!string.IsNullOrEmpty(sourceV3.PackageDownloadUrlTemplateOverwrite))

src/NuGetForUnity/Editor/Helper/CredentialProviderHelper.cs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,15 @@ public static (string UserName, string Password)? GetCredentialFromProvider([Not
6060
feedUri = GetTruncatedFeedUri(feedUri);
6161
if (!CachedCredentialsByFeedUri.TryGetValue(feedUri, out var response))
6262
{
63-
response = GetCredentialFromProvider_Uncached(feedUri, true);
64-
CachedCredentialsByFeedUri[feedUri] = response;
63+
try
64+
{
65+
response = GetCredentialFromProvider_Uncached(feedUri, true);
66+
CachedCredentialsByFeedUri[feedUri] = response;
67+
}
68+
catch (Exception exception)
69+
{
70+
Debug.LogErrorFormat("Failed to get packages source credentials from the credential provider. Error: {0}", exception);
71+
}
6572
}
6673

6774
if (response == null)
@@ -356,9 +363,10 @@ private struct CredentialProviderResponse
356363
[CanBeNull]
357364
public string Password;
358365

359-
// Ignore Spelling: Username
360366
[CanBeNull]
361367
public string Username;
368+
369+
// Ignore Spelling: Username
362370
}
363371
#pragma warning restore 0649 // CS0649: Field 'field' is never assigned to, and will always have its default value 'value'
364372
}

src/NuGetForUnity/Editor/Helper/WebRequestHelper.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,15 @@ internal static class WebRequestHelper
2020
/// <param name="userName">UserName that will be passed in the Authorization header or the request. If null, authorization is omitted.</param>
2121
/// <param name="password">Password that will be passed in the Authorization header or the request. If null, authorization is omitted.</param>
2222
/// <param name="timeOut">Timeout in milliseconds or null to use the default timeout values of HttpWebRequest.</param>
23+
/// <param name="enableCredentialProvider">If true we invoke credential providers found on the system to receive the credentials for the NuGet feed.</param>
2324
/// <returns>Stream containing the result.</returns>
2425
[NotNull]
25-
internal static Stream RequestUrl([NotNull] string url, [CanBeNull] string userName, [CanBeNull] string password, int? timeOut)
26+
internal static Stream RequestUrl(
27+
[NotNull] string url,
28+
[CanBeNull] string userName,
29+
[CanBeNull] string password,
30+
int? timeOut,
31+
bool enableCredentialProvider)
2632
{
2733
// Mono doesn't have a Certificate Authority, so we have to provide all validation manually. Currently just accept anything.
2834
// See here: http://stackoverflow.com/questions/4926676/mono-webrequest-fails-with-https
@@ -35,7 +41,7 @@ internal static Stream RequestUrl([NotNull] string url, [CanBeNull] string userN
3541
getRequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.None;
3642
getRequest.Timeout = timeOut ?? ConfigurationManager.NugetConfigFile.RequestTimeoutSeconds * 1000;
3743

38-
if (string.IsNullOrEmpty(password))
44+
if (string.IsNullOrEmpty(password) && enableCredentialProvider)
3945
{
4046
var credentials = CredentialProviderHelper.GetCredentialFromProvider(getRequest.RequestUri);
4147
if (credentials.HasValue)

src/NuGetForUnity/Editor/PackageSource/INugetPackageSource.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,13 @@ public interface INugetPackageSource : IDisposable
6464
/// </summary>
6565
bool CredentialsStoredInExternalFile { get; set; }
6666

67+
/// <summary>
68+
/// Gets or sets a value indicating whether to invoke credential providers found on the system to
69+
/// receive the credentials for the NuGet feed. See here for more info on NuGet Credential Providers:
70+
/// https://docs.microsoft.com/en-us/nuget/reference/extensibility/nuget-exe-credential-providers.
71+
/// </summary>
72+
bool EnableCredentialProvider { get; set; }
73+
6774
/// <summary>
6875
/// Download the .nupkg file and store it inside a file at <paramref name="outputFilePath" />.
6976
/// </summary>

src/NuGetForUnity/Editor/PackageSource/NugetApiClientV3.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#pragma warning disable SA1512,SA1124 // Single-line comments should not be followed by blank line
22

3+
#region No ReShaper
4+
35
using System;
46
using System.Collections.Generic;
57
using System.Globalization;
@@ -18,8 +20,6 @@
1820
using UnityEditor;
1921
using UnityEngine;
2022

21-
#region No ReShaper
22-
2323
// ReSharper disable All
2424
// needed because 'JetBrains.Annotations.NotNull' and 'System.Diagnostics.CodeAnalysis.NotNull' collide if this file is compiled with a never version of Unity / C#
2525
using SuppressMessageAttribute = System.Diagnostics.CodeAnalysis.SuppressMessageAttribute;
@@ -778,7 +778,7 @@ private void AddHeadersToRequest(HttpRequestMessage request, NugetPackageSourceV
778778
var password = packageSource.ExpandedPassword;
779779
var userName = packageSource.ExpandedUserName;
780780

781-
if (string.IsNullOrEmpty(password))
781+
if (string.IsNullOrEmpty(password) && packageSource.EnableCredentialProvider)
782782
{
783783
var creds = CredentialProviderHelper.GetCredentialFromProvider(apiIndexJsonUrl);
784784
if (creds.HasValue)

src/NuGetForUnity/Editor/PackageSource/NugetPackageSourceCombined.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,17 @@ public bool CredentialsStoredInExternalFile
118118
}
119119
}
120120

121+
/// <inheritdoc />
122+
public bool EnableCredentialProvider
123+
{
124+
get => false;
125+
126+
set
127+
{
128+
// multiple sources can't have credentials
129+
}
130+
}
131+
121132
/// <inheritdoc />
122133
public List<INugetPackage> FindPackagesById(INugetPackageIdentifier package)
123134
{

src/NuGetForUnity/Editor/PackageSource/NugetPackageSourceLocal.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public string SavedProtocolVersion
4444

4545
set
4646
{
47-
// multiple sources can't have protocol version
47+
// local sources can't have protocol version
4848
}
4949
}
5050

@@ -107,6 +107,17 @@ public bool CredentialsStoredInExternalFile
107107
}
108108
}
109109

110+
/// <inheritdoc />
111+
public bool EnableCredentialProvider
112+
{
113+
get => false;
114+
115+
set
116+
{
117+
// local sources can't have credentials
118+
}
119+
}
120+
110121
/// <summary>
111122
/// Gets path, with the values of environment variables expanded.
112123
/// </summary>

src/NuGetForUnity/Editor/PackageSource/NugetPackageSourceV2.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,10 @@ public string ExpandedPath
9191
[field: SerializeField]
9292
public bool CredentialsStoredInExternalFile { get; set; }
9393

94+
/// <inheritdoc />
95+
[field: SerializeField]
96+
public bool EnableCredentialProvider { get; set; } = true;
97+
9498
/// <summary>
9599
/// Gets password, with the values of environment variables expanded.
96100
/// </summary>
@@ -400,7 +404,7 @@ public void DownloadNupkgToFile(INugetPackageIdentifier package, string outputFi
400404
throw new ArgumentNullException(nameof(downloadUrlHint));
401405
}
402406

403-
using (var objStream = WebRequestHelper.RequestUrl(downloadUrlHint, ExpandedUserName, ExpandedPassword, null))
407+
using (var objStream = WebRequestHelper.RequestUrl(downloadUrlHint, ExpandedUserName, ExpandedPassword, null, EnableCredentialProvider))
404408
{
405409
using (var fileStream = File.Create(outputFilePath))
406410
{
@@ -486,7 +490,7 @@ private List<INugetPackage> GetPackagesFromUrl([NotNull] string url)
486490
stopwatch.Start();
487491

488492
var packages = new List<INugetPackage>();
489-
using (var responseStream = WebRequestHelper.RequestUrl(url, ExpandedUserName, ExpandedPassword, 10000))
493+
using (var responseStream = WebRequestHelper.RequestUrl(url, ExpandedUserName, ExpandedPassword, 10000, EnableCredentialProvider))
490494
{
491495
using (var streamReader = new StreamReader(responseStream))
492496
{

src/NuGetForUnity/Editor/PackageSource/NugetPackageSourceV3.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,10 @@ public string PackageDownloadUrlTemplateOverwrite
145145
[field: SerializeField]
146146
public bool CredentialsStoredInExternalFile { get; set; }
147147

148+
/// <inheritdoc />
149+
[field: SerializeField]
150+
public bool EnableCredentialProvider { get; set; } = true;
151+
148152
/// <inheritdoc />
149153
[field: SerializeField]
150154
public bool IsEnabled { get; set; }

src/NuGetForUnity/Editor/Ui/NugetPreferences.cs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -443,8 +443,9 @@ public override void OnGUI([CanBeNull] string searchContext)
443443
}
444444
}
445445

446+
const string useCredentialProviderToogleLabel = "Use credential provider (if found)";
446447
biggestPackageSourceSectionLabelSize = biggestPackageSourceSectionLabelSize ??
447-
EditorStyles.label.CalcSize(new GUIContent("Force use API v3")).x;
448+
EditorStyles.label.CalcSize(new GUIContent(useCredentialProviderToogleLabel)).x;
448449
EditorGUIUtility.labelWidth = biggestPackageSourceSectionLabelSize.Value + LabelPading;
449450

450451
var currentForceUseApiV3 = source.SavedProtocolVersion?.Equals("3", StringComparison.Ordinal) == true;
@@ -453,7 +454,7 @@ public override void OnGUI([CanBeNull] string searchContext)
453454
var forceUseApiV3 = EditorGUILayout.Toggle(
454455
new GUIContent(
455456
"Force use API v3",
456-
"Normally the API version is autodetect. " +
457+
"Normally the API version is automatically detected. " +
457458
"It defaults to version \"2\" when not pointing to a package source URL ending in .json (e.g. https://api.nuget.org/v3/index.json). " +
458459
"So if a package source uses API v3 but the URL doesn't end in .json you need to enable this setting (e.g. needed when using 'Aritfactory')."),
459460
currentForceUseApiV3);
@@ -497,6 +498,17 @@ public override void OnGUI([CanBeNull] string searchContext)
497498
else
498499
{
499500
source.SavedUserName = null;
501+
502+
var enableCredentialProvider = EditorGUILayout.Toggle(
503+
new GUIContent(
504+
useCredentialProviderToogleLabel,
505+
"Whether to call the credential providers found on the system to receive the credentials for the NuGet feed. See NuGet documentation for more info on NuGet Credential Providers: https://docs.microsoft.com/en-us/nuget/reference/extensibility/nuget-exe-credential-providers."),
506+
source.EnableCredentialProvider);
507+
if (enableCredentialProvider != source.EnableCredentialProvider)
508+
{
509+
source.EnableCredentialProvider = enableCredentialProvider;
510+
preferencesChangedThisFrame = true;
511+
}
500512
}
501513
}
502514

0 commit comments

Comments
 (0)