diff options
author | Matt Ward <matt.ward@microsoft.com> | 2020-01-15 15:27:15 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-01-15 15:27:15 +0300 |
commit | 5f722f649899330589c6c71f63dd69a9e368312e (patch) | |
tree | bf85d60ca357879d1e9c269f74eb996df0d3c5f5 /main/src/addins/MonoDevelop.PackageManagement | |
parent | b1386c7000353386f7d7bf101b1efdee57304eb2 (diff) | |
parent | 85c263ed83c1faa63c506bf457edadc5f213b31e (diff) |
Merge pull request #9518 from mono/nuget-barebonecredentialproviders-take-two
[NuGet] Register credential providers coming from secure plugins
Diffstat (limited to 'main/src/addins/MonoDevelop.PackageManagement')
7 files changed, 150 insertions, 3 deletions
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/ManagePackagesDialogRunner.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/ManagePackagesDialogRunner.cs index e766df17e2..67d3035ae0 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/ManagePackagesDialogRunner.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.Gui/ManagePackagesDialogRunner.cs @@ -38,6 +38,7 @@ namespace MonoDevelop.PackageManagement public void Run (IDotNetProject project = null, string initialSearch = null) { try { + PackageManagementCredentialService.Reset (); bool configurePackageSources = false; do { using (ManagePackagesDialog dialog = CreateDialog (initialSearch, project)) { diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.csproj b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.csproj index 1065766e15..bd9be153c4 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.csproj +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement.csproj @@ -368,6 +368,7 @@ <Compile Include="MonoDevelop.PackageManagement\PackageManagementCanReferenceProjectExtension.cs" /> <Compile Include="MonoDevelop.PackageManagement\UpdateMultipleNuGetPackagesAction.cs" /> <Compile Include="MonoDevelop.PackageManagement\ProjectReferenceMaintainerCollection.cs" /> + <Compile Include="MonoDevelop.PackageManagement\MonoDevelopPluginFactory.cs" /> </ItemGroup> <ItemGroup> <EmbeddedResource Include="MonoDevelop.PackageManagement.addin.xml" /> diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/MonoDevelopPluginFactory.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/MonoDevelopPluginFactory.cs new file mode 100644 index 0000000000..9d8ce28c58 --- /dev/null +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/MonoDevelopPluginFactory.cs @@ -0,0 +1,100 @@ +// +// MonoDevelopPluginFactory.cs +// +// Author: +// Matt Ward <matt.ward@microsoft.com> +// +// Copyright (c) 2020 Microsoft Corporation +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using MonoDevelop.Core; +using MonoDevelop.Core.Assemblies; +using NuGet.Protocol.Plugins; + +namespace MonoDevelop.PackageManagement +{ + sealed class MonoDevelopPluginFactory : IPluginFactory + { + readonly PluginFactory pluginFactory; + + public MonoDevelopPluginFactory (TimeSpan idleTimeout) + { + pluginFactory = new PluginFactory (idleTimeout); + } + + public void Dispose () + { + pluginFactory.Dispose (); + } + + public Task<IPlugin> GetOrCreateAsync ( + string filePath, + IEnumerable<string> arguments, + IRequestHandlers requestHandlers, + ConnectionOptions options, + CancellationToken sessionCancellationToken) + { + if (!Platform.IsWindows) { + var modifiedCommandLine = GetModifiedCommandLine (filePath, arguments); + if (modifiedCommandLine != null) { + filePath = modifiedCommandLine.FilePath; + arguments = modifiedCommandLine.Arguments; + } + } + + return pluginFactory.GetOrCreateAsync (filePath, arguments, requestHandlers, options, sessionCancellationToken); + } + + ModifiedCommandLineArguments GetModifiedCommandLine (string filePath, IEnumerable<string> arguments) + { + string extension = Path.GetExtension (filePath); + if (!StringComparer.OrdinalIgnoreCase.Equals (".exe", extension)) { + return null; + } + + var runtime = MonoRuntimeInfo.FromCurrentRuntime (); + if (runtime == null) { + return null; + } + + string monoPath = Path.Combine (runtime.Prefix, "bin", "mono"); + + List<string> updatedArguments = arguments.ToList (); + updatedArguments.Insert (0, "\"" + filePath + "\""); + + return new ModifiedCommandLineArguments { + FilePath = monoPath, + Arguments = updatedArguments + }; + } + + sealed class ModifiedCommandLineArguments + { + public string FilePath { get; set; } + public List<string> Arguments { get; set; } + } + } +} diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/PackageManagementCredentialService.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/PackageManagementCredentialService.cs index 44a38d885b..18b4936515 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/PackageManagementCredentialService.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/PackageManagementCredentialService.cs @@ -32,6 +32,7 @@ using MonoDevelop.Core; using NuGet.CommandLine; using NuGet.Credentials; using NuGet.Protocol; +using NuGet.Protocol.Plugins; namespace MonoDevelop.PackageManagement { @@ -60,6 +61,7 @@ namespace MonoDevelop.PackageManagement var credentialProviders = new List<ICredentialProvider>(); credentialProviders.Add (CreateSettingsCredentialProvider ()); + credentialProviders.AddRange (GetPluginsCredentialProviders ()); credentialProviders.Add (new MonoDevelopCredentialProvider ()); return credentialProviders; @@ -72,6 +74,17 @@ namespace MonoDevelop.PackageManagement return new SettingsCredentialProvider (packageSourceProvider); } + static IEnumerable<ICredentialProvider> GetPluginsCredentialProviders () + { + var builder = new SecurePluginCredentialProviderBuilder ( + PackageManagementServices.PluginManager, + canShowDialog: false, + logger: NuGet.Common.NullLogger.Instance + ); + var providers = builder.BuildAllAsync ().Result; + return providers; + } + /// <summary> /// The credential service puts itself in a retry mode if a credential provider /// is checked. This results in credentials stored in the key chain being ignored diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/PackageManagementServices.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/PackageManagementServices.cs index d095f7f9ae..72cfb0e590 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/PackageManagementServices.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/PackageManagementServices.cs @@ -28,7 +28,10 @@ using System;
using System.IO;
-
+using NuGet.Common; +using NuGet.Configuration; +using NuGet.Protocol.Plugins; + namespace MonoDevelop.PackageManagement
{
public static class PackageManagementServices
@@ -47,6 +50,7 @@ namespace MonoDevelop.PackageManagement //static readonly AnalyzerPackageMonitor analyzerPackageMonitor;
static readonly MonoDevelopHttpUserAgent userAgent = new MonoDevelopHttpUserAgent ();
static readonly NuGetConfigFileChangedMonitor nuGetConfigFileChangedMonitor = new NuGetConfigFileChangedMonitor ();
+ static readonly PluginManager pluginManager;
static PackageManagementServices()
{
@@ -65,6 +69,8 @@ namespace MonoDevelop.PackageManagement workspace = new PackageManagementWorkspace ();
+ pluginManager = CreatePluginManager ();
+
credentialService = new PackageManagementCredentialService ();
credentialService.Initialize ();
@@ -76,6 +82,23 @@ namespace MonoDevelop.PackageManagement MonoDevelop.Refactoring.PackageInstaller.PackageInstallerServiceFactory.PackageServices = new MonoDevelop.PackageManagement.Refactoring.NuGetPackageServicesProxy (); }
+ static PluginManager CreatePluginManager ()
+ {
+ return new PluginManager (
+ EnvironmentVariableWrapper.Instance,
+ new Lazy<IPluginDiscoverer> (InitializeDiscoverer),
+ (TimeSpan idleTimeout) => new MonoDevelopPluginFactory (idleTimeout),
+ new Lazy<string> (() => SettingsUtility.GetPluginsCacheFolder ()));
+ }
+
+ static PluginDiscoverer InitializeDiscoverer ()
+ {
+ var verifier = EmbeddedSignatureVerifier.Create ();
+
+ string pluginPaths = EnvironmentVariableWrapper.Instance.GetEnvironmentVariable ("NUGET_PLUGIN_PATHS");
+ return new PluginDiscoverer (pluginPaths, verifier);
+ }
+
internal static void InitializeCredentialService ()
{
credentialService.Initialize ();
@@ -116,5 +139,9 @@ namespace MonoDevelop.PackageManagement internal static ProjectTargetFrameworkMonitor ProjectTargetFrameworkMonitor { get { return projectTargetFrameworkMonitor; } }
+
+ internal static IPluginManager PluginManager {
+ get { return pluginManager; }
+ }
}
}
diff --git a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/RepositoryProviderFactoryExtensions.cs b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/RepositoryProviderFactoryExtensions.cs index c106bcf839..4f9569a233 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/RepositoryProviderFactoryExtensions.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/MonoDevelop.PackageManagement/RepositoryProviderFactoryExtensions.cs @@ -58,7 +58,7 @@ namespace MonoDevelop.PackageManagement yield return new Lazy<INuGetResourceProvider> (() => new PackageMetadataResourceV3Provider ()); yield return new Lazy<INuGetResourceProvider> (() => new AutoCompleteResourceV2FeedProvider ()); yield return new Lazy<INuGetResourceProvider> (() => new AutoCompleteResourceV3Provider ()); - yield return new Lazy<INuGetResourceProvider> (() => new PluginResourceProvider ()); + yield return new Lazy<INuGetResourceProvider> (() => new PluginResourceProvider (PackageManagementServices.PluginManager)); yield return new Lazy<INuGetResourceProvider> (() => new FindLocalPackagesResourceUnzippedProvider ()); yield return new Lazy<INuGetResourceProvider> (() => new FindLocalPackagesResourceV2Provider ()); yield return new Lazy<INuGetResourceProvider> (() => new FindLocalPackagesResourceV3Provider ()); diff --git a/main/src/addins/MonoDevelop.PackageManagement/NuGet.Credentials/CredentialService.cs b/main/src/addins/MonoDevelop.PackageManagement/NuGet.Credentials/CredentialService.cs index f189f62439..f4c412ff14 100644 --- a/main/src/addins/MonoDevelop.PackageManagement/NuGet.Credentials/CredentialService.cs +++ b/main/src/addins/MonoDevelop.PackageManagement/NuGet.Credentials/CredentialService.cs @@ -103,13 +103,18 @@ namespace NuGet.Credentials CredentialResponse response; if (!TryFromCredentialCache (uri, type, isRetry, provider, out response)) { + /* Temporarily disable interactive-ness with secure plugin provider + * to avoid them blocking on requesting user-input for device flow auth + */ + var nonInteractive = _nonInteractive || provider is SecurePluginCredentialProvider; + response = await provider.GetAsync ( uri, proxy, type, message, isRetry, - _nonInteractive, + nonInteractive, cancellationToken); // Check that the provider gave us a valid response. |