diff --git a/src/NuGet.Clients/NuGet.CommandLine/Commands/SearchCommand.cs b/src/NuGet.Clients/NuGet.CommandLine/Commands/SearchCommand.cs index 75b04aff37a..82ae0114475 100644 --- a/src/NuGet.Clients/NuGet.CommandLine/Commands/SearchCommand.cs +++ b/src/NuGet.Clients/NuGet.CommandLine/Commands/SearchCommand.cs @@ -66,7 +66,8 @@ public override async Task ExecuteCommandAsync() var taskList = new List<(Task>, PackageSource)>(); IList listEndpoints = GetEndpointsAsync(); - WarnForHTTPSources(listEndpoints); + AvoidHttpSources(listEndpoints); + foreach (PackageSource source in listEndpoints) { SourceRepository repository = Repository.Factory.GetCoreV3(source); @@ -126,7 +127,7 @@ public override async Task ExecuteCommandAsync() } } - private void WarnForHTTPSources(IList packageSources) + private static void AvoidHttpSources(IList packageSources) { List httpPackageSources = null; foreach (PackageSource packageSource in packageSources) @@ -145,17 +146,17 @@ private void WarnForHTTPSources(IList packageSources) { if (httpPackageSources.Count == 1) { - Console.LogWarning( + throw new ArgumentException( string.Format(CultureInfo.CurrentCulture, - NuGetResources.Warning_HttpServerUsage, + NuGetResources.Error_HttpSource_Single, "search", httpPackageSources[0])); } else { - Console.LogWarning( + throw new ArgumentException( string.Format(CultureInfo.CurrentCulture, - NuGetResources.Warning_HttpSources_Multiple, + NuGetResources.Error_HttpSources_Multiple, "search", Environment.NewLine + string.Join(Environment.NewLine, httpPackageSources.Select(e => e.Name)))); } diff --git a/src/NuGet.Clients/NuGet.CommandLine/Commands/SourcesCommand.cs b/src/NuGet.Clients/NuGet.CommandLine/Commands/SourcesCommand.cs index 80556ba6657..a4267471270 100644 --- a/src/NuGet.Clients/NuGet.CommandLine/Commands/SourcesCommand.cs +++ b/src/NuGet.Clients/NuGet.CommandLine/Commands/SourcesCommand.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using System.Globalization; using System.Linq; using NuGet.Commands; @@ -36,6 +35,9 @@ public class SourcesCommand : Command [Option(typeof(NuGetCommand), "SourcesCommandFormatDescription")] public SourcesListFormat Format { get; set; } + [Option(typeof(NuGetCommand), "SourcesCommandAllowInsecureConnectionsDescription")] + public bool AllowInsecureConnections { get; set; } + public override void ExecuteCommand() { @@ -61,11 +63,33 @@ public override void ExecuteCommand() switch (action) { case SourcesAction.Add: - var addArgs = new AddSourceArgs() { Name = Name, Source = Source, Username = Username, Password = Password, StorePasswordInClearText = StorePasswordInClearText, ValidAuthenticationTypes = ValidAuthenticationTypes, Configfile = ConfigFile, ProtocolVersion = ProtocolVersion }; + var addArgs = new AddSourceArgs() + { + Name = Name, + Source = Source, + Username = Username, + Password = Password, + StorePasswordInClearText = StorePasswordInClearText, + ValidAuthenticationTypes = ValidAuthenticationTypes, + Configfile = ConfigFile, + ProtocolVersion = ProtocolVersion, + AllowInsecureConnections = AllowInsecureConnections + }; AddSourceRunner.Run(addArgs, () => Console); break; case SourcesAction.Update: - var updateSourceArgs = new UpdateSourceArgs() { Name = Name, Source = Source, Username = Username, Password = Password, StorePasswordInClearText = StorePasswordInClearText, ValidAuthenticationTypes = ValidAuthenticationTypes, Configfile = ConfigFile, ProtocolVersion = ProtocolVersion }; + var updateSourceArgs = new UpdateSourceArgs() + { + Name = Name, + Source = Source, + Username = Username, + Password = Password, + StorePasswordInClearText = StorePasswordInClearText, + ValidAuthenticationTypes = ValidAuthenticationTypes, + Configfile = ConfigFile, + ProtocolVersion = ProtocolVersion, + AllowInsecureConnections = AllowInsecureConnections + }; UpdateSourceRunner.Run(updateSourceArgs, () => Console); break; case SourcesAction.Remove: diff --git a/src/NuGet.Clients/NuGet.CommandLine/NuGetCommand.Designer.cs b/src/NuGet.Clients/NuGet.CommandLine/NuGetCommand.Designer.cs index 34622e72656..bee91c3680d 100644 --- a/src/NuGet.Clients/NuGet.CommandLine/NuGetCommand.Designer.cs +++ b/src/NuGet.Clients/NuGet.CommandLine/NuGetCommand.Designer.cs @@ -1737,6 +1737,15 @@ internal static string SignCommandUsageSummary { } } + /// + /// Looks up a localized string similar to Allows HTTP connections for adding or updating packages. Note: This method is not secure. For secure options, see https://aka.ms/nuget-https-everywhere for more information.. + /// + internal static string SourcesCommandAllowInsecureConnectionsDescription { + get { + return ResourceManager.GetString("SourcesCommandAllowInsecureConnectionsDescription", resourceCulture); + } + } + /// /// Looks up a localized string similar to Provides the ability to manage list of sources located in NuGet.config files.. /// diff --git a/src/NuGet.Clients/NuGet.CommandLine/NuGetCommand.resx b/src/NuGet.Clients/NuGet.CommandLine/NuGetCommand.resx index 9a33e45f0d0..95d63f5fc8c 100644 --- a/src/NuGet.Clients/NuGet.CommandLine/NuGetCommand.resx +++ b/src/NuGet.Clients/NuGet.CommandLine/NuGetCommand.resx @@ -931,6 +931,9 @@ nuget client-certs List The NuGet server protocol version to be used. Currently supported versions are 2 and 3. See https://learn.microsoft.com/nuget/api/overview for information about the version 3 protocol. Defaults to 2 if not specified. + + Allows HTTP connections for adding or updating packages. Note: This method is not secure. For secure options, see https://aka.ms/nuget-https-everywhere for more information. + Display NuGet.exe's End User Liscence Agreement (EULA) diff --git a/src/NuGet.Clients/NuGet.CommandLine/NuGetResources.Designer.cs b/src/NuGet.Clients/NuGet.CommandLine/NuGetResources.Designer.cs index fcfc4e569e2..8d7a6841cae 100644 --- a/src/NuGet.Clients/NuGet.CommandLine/NuGetResources.Designer.cs +++ b/src/NuGet.Clients/NuGet.CommandLine/NuGetResources.Designer.cs @@ -366,6 +366,24 @@ public static string Error_FailedToCreateRandomFileForP2P { } } + /// + /// Looks up a localized string similar to You are running the '{0}' operation with an 'HTTP' source: {1}. NuGet requires HTTPS sources. To use an HTTP source, you must explicitly set 'allowInsecureConnections' to true in your NuGet.Config file. Please refer to https://aka.ms/nuget-https-everywhere.. + /// + public static string Error_HttpSource_Single { + get { + return ResourceManager.GetString("Error_HttpSource_Single", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to You are running the '{0}' operation with 'HTTP' sources: {1}. NuGet requires HTTPS sources. To use HTTP sources, you must explicitly set 'allowInsecureConnections' to true in your NuGet.Config file. Please refer to https://aka.ms/nuget-https-everywhere.. + /// + public static string Error_HttpSources_Multiple { + get { + return ResourceManager.GetString("Error_HttpSources_Multiple", resourceCulture); + } + } + /// /// Looks up a localized string similar to Invalid characters in one of the following path segments: '{0}'. /// @@ -1728,25 +1746,6 @@ public static string Warning_FileDoesNotExist { } } - /// - /// Looks up a localized string similar to You are running the '{0}' operation with an 'HTTP' source, '{1}'. Non-HTTPS access will be removed in a future version. Consider migrating to an 'HTTPS' source.. - /// - public static string Warning_HttpServerUsage { - get { - return ResourceManager.GetString("Warning_HttpServerUsage", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to You are running the '{0}' operation with 'HTTP' sources: {1} - ///Non-HTTPS access will be removed in a future version. Consider migrating to 'HTTPS' sources.. - /// - public static string Warning_HttpSources_Multiple { - get { - return ResourceManager.GetString("Warning_HttpSources_Multiple", resourceCulture); - } - } - /// /// Looks up a localized string similar to Invalid PackageSaveMode value '{0}'.. /// diff --git a/src/NuGet.Clients/NuGet.CommandLine/NuGetResources.resx b/src/NuGet.Clients/NuGet.CommandLine/NuGetResources.resx index ec5e9458bb6..09baf005c16 100644 --- a/src/NuGet.Clients/NuGet.CommandLine/NuGetResources.resx +++ b/src/NuGet.Clients/NuGet.CommandLine/NuGetResources.resx @@ -714,14 +714,6 @@ You can set the '{1}' environment variable to 'true' to temporarily reenable thi NuGet.exe file on path {0} needs to be unblocked after downloading. - - You are running the '{0}' operation with an 'HTTP' source, '{1}'. Non-HTTPS access will be removed in a future version. Consider migrating to an 'HTTPS' source. - 0 - The command name. Ex. Push/Delete. 1 - server uri. - - - You are running the '{0}' operation with 'HTTP' sources: {1} -Non-HTTPS access will be removed in a future version. Consider migrating to 'HTTPS' sources. - Property SourceProvider is null. Don't localize 'SourceProvider' @@ -747,4 +739,10 @@ Do not localize `SDK`, `dotnet pack`, msbuild -t:pack` and 'true'. {1} - current command marked as deprecated, e.g., list {2} - replacement command. For example, search + + You are running the '{0}' operation with 'HTTP' sources: {1}. NuGet requires HTTPS sources. To use HTTP sources, you must explicitly set 'allowInsecureConnections' to true in your NuGet.Config file. Please refer to https://aka.ms/nuget-https-everywhere. + + + You are running the '{0}' operation with an 'HTTP' source: {1}. NuGet requires HTTPS sources. To use an HTTP source, you must explicitly set 'allowInsecureConnections' to true in your NuGet.Config file. Please refer to https://aka.ms/nuget-https-everywhere. + \ No newline at end of file diff --git a/src/NuGet.Clients/NuGet.PackageManagement.UI/Options/CheckedListBoxAccessibleObject.cs b/src/NuGet.Clients/NuGet.PackageManagement.UI/Options/CheckedListBoxAccessibleObject.cs index e26f367d0c5..818a5d38687 100644 --- a/src/NuGet.Clients/NuGet.PackageManagement.UI/Options/CheckedListBoxAccessibleObject.cs +++ b/src/NuGet.Clients/NuGet.PackageManagement.UI/Options/CheckedListBoxAccessibleObject.cs @@ -1,6 +1,7 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System.Globalization; using System.Windows.Forms; using NuGet.Configuration; using NuGet.VisualStudio.Internal.Contracts; @@ -36,12 +37,22 @@ public override AccessibleObject GetChild(int index) PackageSource packageSource = new PackageSource(item.Source, item.Name); if (packageSource.IsHttp && !packageSource.IsHttps && !packageSource.AllowInsecureConnections) { - var sourceMessage = string.Concat( - Resources.Warning_HTTPSource, + var sourceMessage = string.Format( + CultureInfo.CurrentCulture, + Resources.Error_HttpSource_Single, packageSource.Source); return new CheckedListBoxItemAccessibleObject(this, packageSource.Name, index, sourceMessage); } + if (packageSource.AllowInsecureConnections) + { + var insecureConnectionMessage = string.Format( + CultureInfo.CurrentCulture, + Resources.Warning_HTTPSource, + packageSource.Source); + return new CheckedListBoxItemAccessibleObject(this, packageSource.Name, index, insecureConnectionMessage); + } + return new CheckedListBoxItemAccessibleObject(this, packageSource.Name, index, packageSource.Source); } else diff --git a/src/NuGet.Clients/NuGet.PackageManagement.UI/Options/PackageSourceCheckedListBox.cs b/src/NuGet.Clients/NuGet.PackageManagement.UI/Options/PackageSourceCheckedListBox.cs index 1f43314f532..4e0e85b12e7 100644 --- a/src/NuGet.Clients/NuGet.PackageManagement.UI/Options/PackageSourceCheckedListBox.cs +++ b/src/NuGet.Clients/NuGet.PackageManagement.UI/Options/PackageSourceCheckedListBox.cs @@ -20,6 +20,8 @@ internal class PackageSourceCheckedListBox : CheckedListBox { public Size CheckBoxSize { get; set; } + private static Icon ErrorIcon { get; set; } + private static Icon WarningIcon { get; set; } private Icon GetWarningIcon() @@ -47,6 +49,31 @@ private Icon GetWarningIcon() return WarningIcon; } + private static Icon GetErrorIcon() + { + ThreadHelper.ThrowIfNotOnUIThread(); + + if (ErrorIcon == null) + { + ImageAttributes attributes = new ImageAttributes + { + StructSize = Marshal.SizeOf(typeof(ImageAttributes)), + ImageType = (uint)_UIImageType.IT_Icon, + Format = (uint)_UIDataFormat.DF_WinForms, + LogicalWidth = 16, + LogicalHeight = 16, + Flags = (uint)_ImageAttributesFlags.IAF_RequiredFlags + }; + + IVsImageService2 imageService = (IVsImageService2)Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(SVsImageService)); + IVsUIObject uIObj = imageService.GetImage(KnownMonikers.StatusError, attributes); + + ErrorIcon = (Icon)GelUtilities.GetObjectData(uIObj); + } + + return ErrorIcon; + } + public override int ItemHeight { get @@ -137,23 +164,37 @@ protected override void OnDrawItem(DrawItemEventArgs e) var packageSource = new PackageSource(currentItem.Source, currentItem.Name); packageSource.AllowInsecureConnections = currentItem.AllowInsecureConnections; - var shouldShowHttpWarningIcon = packageSource.IsHttp && !packageSource.IsHttps && !packageSource.AllowInsecureConnections; - Rectangle warningBounds = default; + var shouldShowHttpErrorIcon = packageSource.IsHttp && !packageSource.IsHttps && !packageSource.AllowInsecureConnections; + Rectangle bounds = default; - if (shouldShowHttpWarningIcon) + if (shouldShowHttpErrorIcon) + { + var errorIcon = GetErrorIcon(); + + bounds = new Rectangle( + nameBounds.Left, + nameBounds.Bottom, + errorIcon.Width, + errorIcon.Height); + graphics.DrawIcon(errorIcon, bounds); + } + + if (packageSource.AllowInsecureConnections) { var warningIcon = GetWarningIcon(); - warningBounds = new Rectangle( + bounds = new Rectangle( nameBounds.Left, nameBounds.Bottom, warningIcon.Width, warningIcon.Height); - graphics.DrawIcon(warningIcon, warningBounds); + graphics.DrawIcon(warningIcon, bounds); } + bool showWarningOrError = shouldShowHttpErrorIcon || packageSource.AllowInsecureConnections; + var sourceBounds = new Rectangle( - shouldShowHttpWarningIcon ? warningBounds.Right : nameBounds.Left, + showWarningOrError ? bounds.Right : nameBounds.Left, nameBounds.Bottom, textWidth, e.Bounds.Bottom - nameBounds.Bottom); diff --git a/src/NuGet.Clients/NuGet.PackageManagement.UI/Options/PackageSourcesOptionsControl.Designer.cs b/src/NuGet.Clients/NuGet.PackageManagement.UI/Options/PackageSourcesOptionsControl.Designer.cs index 80117e90bbd..a3d9aad19f1 100644 --- a/src/NuGet.Clients/NuGet.PackageManagement.UI/Options/PackageSourcesOptionsControl.Designer.cs +++ b/src/NuGet.Clients/NuGet.PackageManagement.UI/Options/PackageSourcesOptionsControl.Designer.cs @@ -1,3 +1,4 @@ +using System.Diagnostics; using System.Windows.Forms; namespace NuGet.PackageManagement.UI.Options @@ -22,6 +23,15 @@ protected override void Dispose(bool disposing) base.Dispose(disposing); } + private void LinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + Process.Start(new ProcessStartInfo + { + FileName = "https://aka.ms/nuget/how-settings-are-applied", + UseShellExecute = true + }); + } + #region Component Designer generated code /// @@ -52,8 +62,9 @@ private void InitializeComponent() this.MachineWidePackageSourcesListBox = new NuGet.PackageManagement.UI.Options.PackageSourceCheckedListBox(); this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel(); this.tableLayoutPanel4 = new System.Windows.Forms.TableLayoutPanel(); - this.HttpWarning = new System.Windows.Forms.Label(); - this.HttpWarningIcon = new System.Windows.Forms.PictureBox(); + this.HttpErrorOrWarning = new System.Windows.Forms.Label(); + this.HttpErrorOrWarningIcon = new System.Windows.Forms.PictureBox(); + this.configurationLink = new System.Windows.Forms.LinkLabel(); this.images32px = new System.Windows.Forms.ImageList(this.components); this.images64px = new System.Windows.Forms.ImageList(this.components); this.PackageSourcesContextMenu.SuspendLayout(); @@ -61,7 +72,7 @@ private void InitializeComponent() this.tableLayoutPanel2.SuspendLayout(); this.tableLayoutPanel3.SuspendLayout(); this.tableLayoutPanel4.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.HttpWarningIcon)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.HttpErrorOrWarningIcon)).BeginInit(); this.SuspendLayout(); // // HeaderLabel @@ -208,25 +219,33 @@ private void InitializeComponent() this.tableLayoutPanel3.Controls.Add(this.tableLayoutPanel4, 0, 0); this.tableLayoutPanel3.GrowStyle = System.Windows.Forms.TableLayoutPanelGrowStyle.FixedSize; this.tableLayoutPanel3.Name = "tableLayoutPanel3"; + tableLayoutPanel3.AutoSize = true; // // tableLayoutPanel4 // resources.ApplyResources(this.tableLayoutPanel4, "tableLayoutPanel4"); - this.tableLayoutPanel4.Controls.Add(this.HttpWarning, 1, 0); - this.tableLayoutPanel4.Controls.Add(this.HttpWarningIcon, 0, 0); + this.tableLayoutPanel4.Controls.Add(this.HttpErrorOrWarning, 1, 0); + this.tableLayoutPanel4.Controls.Add(this.HttpErrorOrWarningIcon, 0, 0); + this.tableLayoutPanel4.Controls.Add(this.configurationLink, 1, 1); this.tableLayoutPanel4.Name = "tableLayoutPanel4"; // - // HttpWarning + // HttpErrorOrWarning // - resources.ApplyResources(this.HttpWarning, "HttpWarning"); - this.HttpWarning.Name = "HttpWarning"; + resources.ApplyResources(this.HttpErrorOrWarning, "HttpWarning"); + this.HttpErrorOrWarning.Name = "HttpWarning"; // - // HttpWarningIcon + // HttpErrorOrWarningIcon // - resources.ApplyResources(this.HttpWarningIcon, "HttpWarningIcon"); - this.HttpWarningIcon.AccessibleRole = System.Windows.Forms.AccessibleRole.Alert; - this.HttpWarningIcon.Name = "HttpWarningIcon"; - this.HttpWarningIcon.TabStop = false; + resources.ApplyResources(this.HttpErrorOrWarningIcon, "HttpWarningIcon"); + this.HttpErrorOrWarningIcon.AccessibleRole = System.Windows.Forms.AccessibleRole.Alert; + this.HttpErrorOrWarningIcon.Name = "HttpWarningIcon"; + this.HttpErrorOrWarningIcon.TabStop = false; + // + // Configuration link + // + this.configurationLink.Text = Resources.Link_configuration; + this.configurationLink.LinkClicked += new LinkLabelLinkClickedEventHandler(LinkLabel_LinkClicked); + this.configurationLink.AutoSize = true; // // images32px // @@ -261,7 +280,7 @@ private void InitializeComponent() this.tableLayoutPanel3.PerformLayout(); this.tableLayoutPanel4.ResumeLayout(false); this.tableLayoutPanel4.PerformLayout(); - ((System.ComponentModel.ISupportInitialize)(this.HttpWarningIcon)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.HttpErrorOrWarningIcon)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); @@ -291,7 +310,8 @@ private void InitializeComponent() private ImageList images64px; private TableLayoutPanel tableLayoutPanel3; private TableLayoutPanel tableLayoutPanel4; - private Label HttpWarning; - private PictureBox HttpWarningIcon; + private Label HttpErrorOrWarning; + private PictureBox HttpErrorOrWarningIcon; + private LinkLabel configurationLink; } } diff --git a/src/NuGet.Clients/NuGet.PackageManagement.UI/Options/PackageSourcesOptionsControl.cs b/src/NuGet.Clients/NuGet.PackageManagement.UI/Options/PackageSourcesOptionsControl.cs index 5b8643b99df..4199b795e70 100644 --- a/src/NuGet.Clients/NuGet.PackageManagement.UI/Options/PackageSourcesOptionsControl.cs +++ b/src/NuGet.Clients/NuGet.PackageManagement.UI/Options/PackageSourcesOptionsControl.cs @@ -60,27 +60,9 @@ private static IVsImageService2 ImageService } } - public static Image WarningIcon - { - get - { - ThreadHelper.ThrowIfNotOnUIThread(); - - ImageAttributes attributes = new ImageAttributes - { - StructSize = Marshal.SizeOf(typeof(ImageAttributes)), - ImageType = (uint)_UIImageType.IT_Bitmap, - Format = (uint)_UIDataFormat.DF_WinForms, - LogicalWidth = 16, - LogicalHeight = 16, - Flags = (uint)_ImageAttributesFlags.IAF_RequiredFlags - }; - - IVsUIObject uIObj = ImageService.GetImage(KnownMonikers.StatusWarning, attributes); + public static Image WarningIcon { get; private set; } - return (Image)GelUtilities.GetObjectData(uIObj); - } - } + public static Image ErrorIcon { get; private set; } public PackageSourcesOptionsControl(IAsyncServiceProvider asyncServiceProvider) { @@ -94,8 +76,22 @@ public PackageSourcesOptionsControl(IAsyncServiceProvider asyncServiceProvider) UpdateDPI(); - HttpWarningIcon.Image = WarningIcon; - HttpWarning.Text = Resources.Warning_NewHTTPSource_VSOptions; + ThreadHelper.ThrowIfNotOnUIThread(); + + ImageAttributes attributes = new ImageAttributes + { + StructSize = Marshal.SizeOf(typeof(ImageAttributes)), + ImageType = (uint)_UIImageType.IT_Bitmap, + Format = (uint)_UIDataFormat.DF_WinForms, + LogicalWidth = 16, + LogicalHeight = 16, + Flags = (uint)_ImageAttributesFlags.IAF_RequiredFlags + }; + + IVsUIObject uIObj = ImageService.GetImage(KnownMonikers.StatusWarning, attributes); + WarningIcon = (Image)GelUtilities.GetObjectData(uIObj); + uIObj = ImageService.GetImage(KnownMonikers.StatusError, attributes); + ErrorIcon = (Image)GelUtilities.GetObjectData(uIObj); } private void UpdateDPI() @@ -153,14 +149,14 @@ private void UpdateUI() addButton.Enabled = true; } - // Show HttpWarning for the selected source if needed + // Show HttpError for the selected source if needed if (selectedSource != null) { - SetHttpWarningVisibilityForSelectSource(selectedSource); + SetHttpErrorVisibilityForSelectedSource(selectedSource); } else if (selectedMachineSource != null) { - SetHttpWarningVisibilityForSelectSource(selectedMachineSource); + SetHttpErrorVisibilityForSelectedSource(selectedMachineSource); } } @@ -483,13 +479,37 @@ private TryUpdateSourceResults TryUpdateSource() return TryUpdateSourceResults.SourceConflicted; } - selectedPackageSource.Name = name; - selectedPackageSource.Source = source; - _packageSources.ResetCurrentItem(); + PackageSource packageSource = new PackageSource(source, name); - SetHttpWarningVisibilityForSelectSource(selectedPackageSource); + if (packageSource.IsHttp && !packageSource.IsHttps) + { + // Updating to an http source. Request user confirmation + bool? addHttpSource = MessageHelper.ShowQueryMessage(Resources.Warn_Adding_HttpSource, Resources.DialogTitle_HttpSource, true); + + if (addHttpSource == true) + { + selectedPackageSource.Name = name; + selectedPackageSource.Source = source; + selectedPackageSource.AllowInsecureConnections = true; + _packageSources.ResetCurrentItem(); + SetHttpErrorVisibilityForSelectedSource(selectedPackageSource); + + return TryUpdateSourceResults.Successful; + } + else + { + return TryUpdateSourceResults.Unchanged; + } + } + else + { + selectedPackageSource.Name = name; + selectedPackageSource.Source = source; + _packageSources.ResetCurrentItem(); + SetHttpErrorVisibilityForSelectedSource(selectedPackageSource); - return TryUpdateSourceResults.Successful; + return TryUpdateSourceResults.Successful; + } } private static void SelectAndFocus(TextBox textBox) @@ -715,21 +735,34 @@ private static bool IsPathRootedSafe(string path) return path.IndexOfAny(Path.GetInvalidPathChars()) == -1 && Path.IsPathRooted(path); } - private void SetHttpWarningVisibilityForSelectSource(PackageSourceContextInfo selectedSource) + private void SetHttpErrorVisibilityForSelectedSource(PackageSourceContextInfo selectedSource) { var source = new PackageSource(selectedSource.Source, selectedSource.Name); source.AllowInsecureConnections = selectedSource.AllowInsecureConnections; - // Warn if the selected source is http, and the AllowInsecureConnections for this source is set to false. if (source.IsHttp && !source.IsHttps && !source.AllowInsecureConnections) { - HttpWarning.Visible = true; - HttpWarningIcon.Visible = true; + // Error if the selected source is http, and the AllowInsecureConnections for this source is set to false. + HttpErrorOrWarning.Visible = true; + HttpErrorOrWarningIcon.Visible = true; + configurationLink.Visible = true; + HttpErrorOrWarningIcon.Image = ErrorIcon; + HttpErrorOrWarning.Text = Resources.Error_HttpSource_Single; + } + else if (source.AllowInsecureConnections) + { + // Warn if AllowInsecureConnections for this source is set to true. + HttpErrorOrWarning.Visible = true; + HttpErrorOrWarningIcon.Visible = true; + configurationLink.Visible = true; + HttpErrorOrWarningIcon.Image = WarningIcon; + HttpErrorOrWarning.Text = Resources.Warning_HTTPSource; } else { - HttpWarning.Visible = false; - HttpWarningIcon.Visible = false; + HttpErrorOrWarning.Visible = false; + HttpErrorOrWarningIcon.Visible = false; + configurationLink.Visible = false; } } } diff --git a/src/NuGet.Clients/NuGet.PackageManagement.UI/Resources.Designer.cs b/src/NuGet.Clients/NuGet.PackageManagement.UI/Resources.Designer.cs index 90b7640d75d..81c96225d26 100644 --- a/src/NuGet.Clients/NuGet.PackageManagement.UI/Resources.Designer.cs +++ b/src/NuGet.Clients/NuGet.PackageManagement.UI/Resources.Designer.cs @@ -744,6 +744,15 @@ public static string Description_LearnMore { } } + /// + /// Looks up a localized string similar to HTTP Source. + /// + public static string DialogTitle_HttpSource { + get { + return ResourceManager.GetString("DialogTitle_HttpSource", resourceCulture); + } + } + /// /// Looks up a localized string similar to _Don't show this again. /// @@ -753,6 +762,15 @@ public static string DoNotShowThisAgain { } } + /// + /// Looks up a localized string similar to NuGet requires HTTPS sources. To use an HTTP source, you must explicitly set 'allowInsecureConnections' to true in your NuGet.Config file.. + /// + public static string Error_HttpSource_Single { + get { + return ResourceManager.GetString("Error_HttpSource_Single", resourceCulture); + } + } + /// /// Looks up a localized string similar to Unable to find metadata of {0}. /// @@ -1383,6 +1401,15 @@ public static string LicenseTerm_LinkName { } } + /// + /// Looks up a localized string similar to Common NuGet configurations; How settings are applied.. + /// + public static string Link_configuration { + get { + return ResourceManager.GetString("Link_configuration", resourceCulture); + } + } + /// /// Looks up a localized string similar to Don't show again. /// @@ -2619,20 +2646,20 @@ public static string VulnerabilitySeverity_Moderate { } /// - /// Looks up a localized string similar to Warning: Non-HTTPS access will be removed in a future version. Consider migrating to an 'HTTPS' source.. + /// Looks up a localized string similar to You are attempting to add an HTTP source, which is insecure. Would you like to proceed with adding this insecure HTTP source?. /// - public static string Warning_HTTPSource { + public static string Warn_Adding_HttpSource { get { - return ResourceManager.GetString("Warning_HTTPSource", resourceCulture); + return ResourceManager.GetString("Warn_Adding_HttpSource", resourceCulture); } } /// - /// Looks up a localized string similar to Non-HTTPS access will be removed in a future version. Consider migrating to an 'HTTPS' source.. + /// Looks up a localized string similar to AllowInsecureConnections is enabled and allows http access. Note: This method is not secure. For secure options, see https://aka.ms/nuget-https-everywhere.. /// - public static string Warning_NewHTTPSource_VSOptions { + public static string Warning_HTTPSource { get { - return ResourceManager.GetString("Warning_NewHTTPSource_VSOptions", resourceCulture); + return ResourceManager.GetString("Warning_HTTPSource", resourceCulture); } } diff --git a/src/NuGet.Clients/NuGet.PackageManagement.UI/Resources.resx b/src/NuGet.Clients/NuGet.PackageManagement.UI/Resources.resx index 8331fb7d290..e88b442b969 100644 --- a/src/NuGet.Clients/NuGet.PackageManagement.UI/Resources.resx +++ b/src/NuGet.Clients/NuGet.PackageManagement.UI/Resources.resx @@ -933,10 +933,7 @@ Please see https://aka.ms/troubleshoot_nuget_cache for more help. {0} is a version number - Warning: Non-HTTPS access will be removed in a future version. Consider migrating to an 'HTTPS' source. - - - Non-HTTPS access will be removed in a future version. Consider migrating to an 'HTTPS' source. + AllowInsecureConnections is enabled and allows http access. Note: This method is not secure. For secure options, see https://aka.ms/nuget-https-everywhere. Add @@ -1048,4 +1045,16 @@ Please see https://aka.ms/troubleshoot_nuget_cache for more help. by + + NuGet requires HTTPS sources. To use an HTTP source, you must explicitly set 'allowInsecureConnections' to true in your NuGet.Config file. + + + You are attempting to add an HTTP source, which is insecure. Would you like to proceed with adding this insecure HTTP source? + + + Common NuGet configurations; How settings are applied. + + + HTTP Source + \ No newline at end of file diff --git a/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Services/NuGetSourcesService.cs b/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Services/NuGetSourcesService.cs index 9134c1c453a..18e0acbff14 100644 --- a/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Services/NuGetSourcesService.cs +++ b/src/NuGet.Clients/NuGet.PackageManagement.VisualStudio/Services/NuGetSourcesService.cs @@ -131,6 +131,7 @@ private IReadOnlyList GetPackageSourcesToUpdate(IReadOnlyList @@ -65,6 +69,7 @@ internal static void Register(CommandLineApplication app, ValidAuthenticationTypes = validAuthenticationTypes.Value(), ProtocolVersion = protocolVersion.Value(), Configfile = configfile.Value(), + AllowInsecureConnections = allowInsecureConnections.HasValue(), }; AddSourceRunner.Run(args, getLogger); @@ -390,6 +395,10 @@ internal static void Register(CommandLineApplication app, "--configfile", Strings.Option_ConfigFile, CommandOptionType.SingleValue); + CommandOption allowInsecureConnections = SourceCmd.Option( + "--allow-insecure-connections", + Strings.SourcesCommandAllowInsecureConnectionsDescription, + CommandOptionType.NoValue); SourceCmd.HelpOption("-h|--help"); SourceCmd.Description = Strings.UpdateSourceCommandDescription; SourceCmd.OnExecute(() => @@ -404,6 +413,7 @@ internal static void Register(CommandLineApplication app, ValidAuthenticationTypes = validAuthenticationTypes.Value(), ProtocolVersion = protocolVersion.Value(), Configfile = configfile.Value(), + AllowInsecureConnections = allowInsecureConnections.HasValue(), }; UpdateSourceRunner.Run(args, getLogger); diff --git a/src/NuGet.Core/NuGet.CommandLine.XPlat/Strings.Designer.cs b/src/NuGet.Core/NuGet.CommandLine.XPlat/Strings.Designer.cs index f2b948463aa..0fc2447754d 100644 --- a/src/NuGet.Core/NuGet.CommandLine.XPlat/Strings.Designer.cs +++ b/src/NuGet.Core/NuGet.CommandLine.XPlat/Strings.Designer.cs @@ -1862,6 +1862,15 @@ internal static string Sources_Redirect { } } + /// + /// Looks up a localized string similar to Allows HTTP connections for adding or updating packages. Note: This method is not secure. For secure options, see https://aka.ms/nuget-https-everywhere for more information.. + /// + internal static string SourcesCommandAllowInsecureConnectionsDescription { + get { + return ResourceManager.GetString("SourcesCommandAllowInsecureConnectionsDescription", resourceCulture); + } + } + /// /// Looks up a localized string similar to The format of the list command output: `Detailed` (the default) and `Short`.. /// diff --git a/src/NuGet.Core/NuGet.CommandLine.XPlat/Strings.resx b/src/NuGet.Core/NuGet.CommandLine.XPlat/Strings.resx index 5b11702cafa..da9d230ef56 100644 --- a/src/NuGet.Core/NuGet.CommandLine.XPlat/Strings.resx +++ b/src/NuGet.Core/NuGet.CommandLine.XPlat/Strings.resx @@ -966,4 +966,7 @@ Non-HTTPS access will be removed in a future version. Consider migrating to 'HTT No dependency graph(s) found for this target framework. + + Allows HTTP connections for adding or updating packages. Note: This method is not secure. For secure options, see https://aka.ms/nuget-https-everywhere for more information. + diff --git a/src/NuGet.Core/NuGet.Commands/CommandArgs/VerbArgs.cs b/src/NuGet.Core/NuGet.Commands/CommandArgs/VerbArgs.cs index f9cad6b8226..a5e8d5c513f 100644 --- a/src/NuGet.Core/NuGet.Commands/CommandArgs/VerbArgs.cs +++ b/src/NuGet.Core/NuGet.Commands/CommandArgs/VerbArgs.cs @@ -5,10 +5,6 @@ // instead modify the neighboring .tt file (text template) and/or NuGet.CommandLine.Xplat\Commands\Commands.xml (data file), // then re-execute the text template via "run custom tool" on VS context menu for .tt file, or via dotnet-t4 global tool. -using System; -using System.Threading.Tasks; -using NuGet.Common; - namespace NuGet.Commands { public partial class AddSourceArgs @@ -21,6 +17,7 @@ public partial class AddSourceArgs public string ValidAuthenticationTypes { get; set; } public string ProtocolVersion { get; set; } public string Configfile { get; set; } + public bool AllowInsecureConnections { get; set; } } public partial class AddClientCertArgs @@ -82,6 +79,7 @@ public partial class UpdateSourceArgs public string ValidAuthenticationTypes { get; set; } public string ProtocolVersion { get; set; } public string Configfile { get; set; } + public bool AllowInsecureConnections { get; set; } } public partial class UpdateClientCertArgs diff --git a/src/NuGet.Core/NuGet.Commands/CommandRunners/DeleteRunner.cs b/src/NuGet.Core/NuGet.Commands/CommandRunners/DeleteRunner.cs index 0ed600086e0..276450cc477 100644 --- a/src/NuGet.Core/NuGet.Commands/CommandRunners/DeleteRunner.cs +++ b/src/NuGet.Core/NuGet.Commands/CommandRunners/DeleteRunner.cs @@ -29,11 +29,10 @@ public static async Task Run( { source = CommandRunnerUtility.ResolveSource(sourceProvider, source); PackageSource packageSource = CommandRunnerUtility.GetOrCreatePackageSource(sourceProvider, source); - // Only warn for V3 style sources because they have a service index which is different from the final push url. - if (packageSource.IsHttp && !packageSource.IsHttps && !packageSource.AllowInsecureConnections && - (packageSource.ProtocolVersion == 3 || packageSource.Source.EndsWith("json", StringComparison.OrdinalIgnoreCase))) + // Throw an error if an http source is used without setting AllowInsecureConnections + if (packageSource.IsHttp && !packageSource.IsHttps && !packageSource.AllowInsecureConnections) { - logger.LogWarning(string.Format(CultureInfo.CurrentCulture, Strings.Warning_HttpServerUsage, "delete", packageSource.Source)); + throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Strings.Error_HttpSource_Single, "delete", packageSource.Source)); } var packageUpdateResource = await CommandRunnerUtility.GetPackageUpdateResource(sourceProvider, packageSource, CancellationToken.None); diff --git a/src/NuGet.Core/NuGet.Commands/CommandRunners/PushRunner.cs b/src/NuGet.Core/NuGet.Commands/CommandRunners/PushRunner.cs index eccf2e72b0f..a1f495fccea 100644 --- a/src/NuGet.Core/NuGet.Commands/CommandRunners/PushRunner.cs +++ b/src/NuGet.Core/NuGet.Commands/CommandRunners/PushRunner.cs @@ -42,11 +42,10 @@ public static async Task Run( PackageSource packageSource = CommandRunnerUtility.GetOrCreatePackageSource(sourceProvider, source); var packageUpdateResource = await CommandRunnerUtility.GetPackageUpdateResource(sourceProvider, packageSource, CancellationToken.None); - // Only warn for V3 style sources because they have a service index which is different from the final push url. - if (packageSource.IsHttp && !packageSource.IsHttps && !packageSource.AllowInsecureConnections && - (packageSource.ProtocolVersion == 3 || packageSource.Source.EndsWith("json", StringComparison.OrdinalIgnoreCase))) + // Throw an error if an http source is used without setting AllowInsecureConnections + if (packageSource.IsHttp && !packageSource.IsHttps && !packageSource.AllowInsecureConnections) { - logger.LogWarning(string.Format(CultureInfo.CurrentCulture, Strings.Warning_HttpServerUsage, "push", packageSource.Source)); + throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Strings.Error_HttpSource_Single, "push", packageSource.Source)); } packageUpdateResource.Settings = settings; diff --git a/src/NuGet.Core/NuGet.Commands/ListCommand/ListCommandRunner.cs b/src/NuGet.Core/NuGet.Commands/ListCommand/ListCommandRunner.cs index 5ecabb4b142..1119fbb0f72 100644 --- a/src/NuGet.Core/NuGet.Commands/ListCommand/ListCommandRunner.cs +++ b/src/NuGet.Core/NuGet.Commands/ListCommand/ListCommandRunner.cs @@ -49,7 +49,7 @@ public async Task ExecuteCommand(ListArgs listArgs) } } - WarnForHTTPSources(listArgs); + AvoidHttpSources(listArgs); var allPackages = new List>(); var log = listArgs.IsDetailed ? listArgs.Logger : NullLogger.Instance; @@ -64,7 +64,7 @@ await feed.ListAsync(listArgs.Arguments.FirstOrDefault(), listArgs.Prerelease, l await PrintPackages(listArgs, new AggregateEnumerableAsync(allPackages, comparer, comparer).GetEnumeratorAsync()); } - private static void WarnForHTTPSources(ListArgs listArgs) + private static void AvoidHttpSources(ListArgs listArgs) { List httpPackageSources = null; foreach (PackageSource packageSource in listArgs.ListEndpoints) @@ -83,17 +83,17 @@ private static void WarnForHTTPSources(ListArgs listArgs) { if (httpPackageSources.Count == 1) { - listArgs.Logger.LogWarning( + throw new ArgumentException( string.Format(CultureInfo.CurrentCulture, - Strings.Warning_HttpServerUsage, + Strings.Error_HttpSource_Single, "list", httpPackageSources[0])); } else { - listArgs.Logger.LogWarning( + throw new ArgumentException( string.Format(CultureInfo.CurrentCulture, - Strings.Warning_HttpServerUsage_MultipleSources, + Strings.Error_HttpSources_Multiple, "list", Environment.NewLine + string.Join(Environment.NewLine, httpPackageSources.Select(e => e.Name)))); } diff --git a/src/NuGet.Core/NuGet.Commands/NuGet.Commands.csproj b/src/NuGet.Core/NuGet.Commands/NuGet.Commands.csproj index 58a2360054e..f1218f75a2d 100644 --- a/src/NuGet.Core/NuGet.Commands/NuGet.Commands.csproj +++ b/src/NuGet.Core/NuGet.Commands/NuGet.Commands.csproj @@ -64,5 +64,6 @@ + diff --git a/src/NuGet.Core/NuGet.Commands/PublicAPI/net472/PublicAPI.Unshipped.txt b/src/NuGet.Core/NuGet.Commands/PublicAPI/net472/PublicAPI.Unshipped.txt index e2a7384b13d..063bd3459d9 100644 --- a/src/NuGet.Core/NuGet.Commands/PublicAPI/net472/PublicAPI.Unshipped.txt +++ b/src/NuGet.Core/NuGet.Commands/PublicAPI/net472/PublicAPI.Unshipped.txt @@ -1,2 +1,6 @@ #nullable enable ~static NuGet.Commands.MSBuildRestoreUtility.GetRestoreAuditProperties(NuGet.Commands.IMSBuildItem specItem, System.Collections.Generic.HashSet suppressionItems) -> NuGet.ProjectModel.RestoreAuditProperties +NuGet.Commands.UpdateSourceArgs.AllowInsecureConnections.set -> void +NuGet.Commands.UpdateSourceArgs.AllowInsecureConnections.get -> bool +NuGet.Commands.AddSourceArgs.AllowInsecureConnections.set -> void +NuGet.Commands.AddSourceArgs.AllowInsecureConnections.get -> bool diff --git a/src/NuGet.Core/NuGet.Commands/PublicAPI/netcoreapp5.0/PublicAPI.Unshipped.txt b/src/NuGet.Core/NuGet.Commands/PublicAPI/netcoreapp5.0/PublicAPI.Unshipped.txt index e2a7384b13d..063bd3459d9 100644 --- a/src/NuGet.Core/NuGet.Commands/PublicAPI/netcoreapp5.0/PublicAPI.Unshipped.txt +++ b/src/NuGet.Core/NuGet.Commands/PublicAPI/netcoreapp5.0/PublicAPI.Unshipped.txt @@ -1,2 +1,6 @@ #nullable enable ~static NuGet.Commands.MSBuildRestoreUtility.GetRestoreAuditProperties(NuGet.Commands.IMSBuildItem specItem, System.Collections.Generic.HashSet suppressionItems) -> NuGet.ProjectModel.RestoreAuditProperties +NuGet.Commands.UpdateSourceArgs.AllowInsecureConnections.set -> void +NuGet.Commands.UpdateSourceArgs.AllowInsecureConnections.get -> bool +NuGet.Commands.AddSourceArgs.AllowInsecureConnections.set -> void +NuGet.Commands.AddSourceArgs.AllowInsecureConnections.get -> bool diff --git a/src/NuGet.Core/NuGet.Commands/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt b/src/NuGet.Core/NuGet.Commands/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt index e2a7384b13d..063bd3459d9 100644 --- a/src/NuGet.Core/NuGet.Commands/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/NuGet.Core/NuGet.Commands/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,2 +1,6 @@ #nullable enable ~static NuGet.Commands.MSBuildRestoreUtility.GetRestoreAuditProperties(NuGet.Commands.IMSBuildItem specItem, System.Collections.Generic.HashSet suppressionItems) -> NuGet.ProjectModel.RestoreAuditProperties +NuGet.Commands.UpdateSourceArgs.AllowInsecureConnections.set -> void +NuGet.Commands.UpdateSourceArgs.AllowInsecureConnections.get -> bool +NuGet.Commands.AddSourceArgs.AllowInsecureConnections.set -> void +NuGet.Commands.AddSourceArgs.AllowInsecureConnections.get -> bool diff --git a/src/NuGet.Core/NuGet.Commands/RestoreCommand/RestoreCommand.cs b/src/NuGet.Core/NuGet.Commands/RestoreCommand/RestoreCommand.cs index f80ddb2a372..55d70a12a95 100644 --- a/src/NuGet.Core/NuGet.Commands/RestoreCommand/RestoreCommand.cs +++ b/src/NuGet.Core/NuGet.Commands/RestoreCommand/RestoreCommand.cs @@ -254,8 +254,8 @@ public async Task ExecuteAsync(CancellationToken token) var source = remoteProvider.Source; if (source.IsHttp && !source.IsHttps && !source.AllowInsecureConnections) { - await _logger.LogAsync(RestoreLogMessage.CreateWarning(NuGetLogCode.NU1803, - string.Format(CultureInfo.CurrentCulture, Strings.Warning_HttpServerUsage, "restore", source.Source))); + await _logger.LogAsync(RestoreLogMessage.CreateError(NuGetLogCode.NU1302, + string.Format(CultureInfo.CurrentCulture, Strings.Error_HttpSource_Single, "restore", source.Source))); } } } diff --git a/src/NuGet.Core/NuGet.Commands/SourcesCommands/SourceRunners.cs b/src/NuGet.Core/NuGet.Commands/SourcesCommands/SourceRunners.cs index 75f673e5110..743b5d8587d 100644 --- a/src/NuGet.Core/NuGet.Commands/SourcesCommands/SourceRunners.cs +++ b/src/NuGet.Core/NuGet.Commands/SourcesCommands/SourceRunners.cs @@ -62,12 +62,13 @@ public static void Run(AddSourceArgs args, Func getLogger) } var newPackageSource = new Configuration.PackageSource(args.Source, args.Name); + newPackageSource.AllowInsecureConnections = args.AllowInsecureConnections; if (newPackageSource.IsHttp && !newPackageSource.IsHttps && !newPackageSource.AllowInsecureConnections) { - getLogger().LogWarning( + throw new ArgumentException( string.Format(CultureInfo.CurrentCulture, - Strings.Warning_HttpServerUsage, + Strings.Error_HttpSource_Single_Short, "add source", args.Source)); } @@ -187,8 +188,6 @@ public static void Run(ListSourceArgs args, Func getLogger) legend += " "; getLogger().LogMinimal(legend + source.Source); } - - WarnForHttpSources(sourcesList, getLogger); } break; case SourcesListFormat.None: @@ -218,16 +217,14 @@ private static void WarnForHttpSources(IEnumerable sources, Func< { getLogger().LogWarning( string.Format(CultureInfo.CurrentCulture, - Strings.Warning_HttpServerUsage, - "list source", + Strings.Warning_List_HttpSource, httpPackageSources[0])); } else { getLogger().LogWarning( string.Format(CultureInfo.CurrentCulture, - Strings.Warning_HttpServerUsage_MultipleSources, - "list source", + Strings.Warning_List_HttpSources, Environment.NewLine + string.Join(Environment.NewLine, httpPackageSources.Select(e => e.Name)))); } } @@ -262,6 +259,7 @@ public static void Run(UpdateSourceArgs args, Func getLogger) var sourceProvider = RunnerHelper.GetSourceProvider(settings); var existingSource = sourceProvider.GetPackageSourceByName(args.Name); + existingSource.AllowInsecureConnections = args.AllowInsecureConnections; if (existingSource == null) { throw new CommandException(Strings.SourcesCommandNoMatchingSourcesFound, args.Name); @@ -282,11 +280,12 @@ public static void Run(UpdateSourceArgs args, Func getLogger) } existingSource = new Configuration.PackageSource(args.Source, existingSource.Name); + existingSource.AllowInsecureConnections = args.AllowInsecureConnections; - // If the existing source is not http, warn the user + // If the new source is not http, throw an error if (existingSource.IsHttp && !existingSource.IsHttps && !existingSource.AllowInsecureConnections) { - getLogger().LogWarning(string.Format(CultureInfo.CurrentCulture, Strings.Warning_HttpServerUsage, "update source", args.Source)); + throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Strings.Error_HttpSource_Single, "update source", args.Source)); } } @@ -380,7 +379,7 @@ public static void EnableOrDisableSource(PackageSourceProvider sourceProvider, s Strings.SourcesCommandSourceEnabledSuccessfully, name)); if (packageSource.IsHttp && !packageSource.IsHttps && !packageSource.AllowInsecureConnections) { - getLogger().LogWarning(string.Format(CultureInfo.CurrentCulture, Strings.Warning_HttpServerUsage, "enable source", packageSource.Source)); + throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Strings.Error_HttpSource_Single, "enable source", packageSource.Source)); } } else diff --git a/src/NuGet.Core/NuGet.Commands/Strings.Designer.cs b/src/NuGet.Core/NuGet.Commands/Strings.Designer.cs index 7631761519e..b5068d34e18 100644 --- a/src/NuGet.Core/NuGet.Commands/Strings.Designer.cs +++ b/src/NuGet.Core/NuGet.Commands/Strings.Designer.cs @@ -384,6 +384,33 @@ internal static string Error_EmptySourceFileProjectDirectory { } } + /// + /// Looks up a localized string similar to You are running the '{0}' operation with an 'HTTP' source: {1}. NuGet requires HTTPS sources. To use an HTTP source, you must explicitly set 'allowInsecureConnections' to true in your NuGet.Config file. Please refer to https://aka.ms/nuget-https-everywhere for more information.. + /// + internal static string Error_HttpSource_Single { + get { + return ResourceManager.GetString("Error_HttpSource_Single", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to You are running the '{0}' operation with an 'HTTP' source: {1}. NuGet requires HTTPS sources. Please refer to https://aka.ms/nuget-https-everywhere for more information.. + /// + internal static string Error_HttpSource_Single_Short { + get { + return ResourceManager.GetString("Error_HttpSource_Single_Short", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to You are running the '{0}' operation with 'HTTP' sources: {1}. NuGet requires HTTPS sources. To use HTTP sources, you must explicitly set 'allowInsecureConnections' to true in your NuGet.Config file. Please refer to https://aka.ms/nuget-https-everywhere for more information.. + /// + internal static string Error_HttpSources_Multiple { + get { + return ResourceManager.GetString("Error_HttpSources_Multiple", resourceCulture); + } + } + /// /// Looks up a localized string similar to The package {0} {1} has a package type {2} that is incompatible with this project.. /// @@ -2474,6 +2501,26 @@ internal static string Warning_HttpServerUsage_MultipleSources { } } + /// + /// Looks up a localized string similar to The following is a 'Non-HTTPS' source: {0} + ///NuGet requires HTTPS sources. Please refer to https://aka.ms/nuget-https-everywhere for more information.. + /// + internal static string Warning_List_HttpSource { + get { + return ResourceManager.GetString("Warning_List_HttpSource", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The following are 'Non-HTTPS' sources: {0} + ///NuGet requires HTTPS sources. Please refer to https://aka.ms/nuget-https-everywhere for more information.. + /// + internal static string Warning_List_HttpSources { + get { + return ResourceManager.GetString("Warning_List_HttpSources", resourceCulture); + } + } + /// /// Looks up a localized string similar to {0} depends on {1} but {2} was not found. An approximate best match of {3} was resolved.. /// diff --git a/src/NuGet.Core/NuGet.Commands/Strings.resx b/src/NuGet.Core/NuGet.Commands/Strings.resx index bfb5e540f6a..4644e6ce331 100644 --- a/src/NuGet.Core/NuGet.Commands/Strings.resx +++ b/src/NuGet.Core/NuGet.Commands/Strings.resx @@ -1099,4 +1099,26 @@ Non-HTTPS access will be removed in a future version. Consider migrating to 'HTT The protocol version specified is invalid. Valid protocol versions are from {0} to {1}. + + You are running the '{0}' operation with 'HTTP' sources: {1}. NuGet requires HTTPS sources. To use HTTP sources, you must explicitly set 'allowInsecureConnections' to true in your NuGet.Config file. Please refer to https://aka.ms/nuget-https-everywhere for more information. + 0 - The command name. Ex. Push/Delete. 1 - list of server URIs + + + You are running the '{0}' operation with an 'HTTP' source: {1}. NuGet requires HTTPS sources. To use an HTTP source, you must explicitly set 'allowInsecureConnections' to true in your NuGet.Config file. Please refer to https://aka.ms/nuget-https-everywhere for more information. + 0 - The command name. Ex. Push/Delete. 1 - server URI. + + + You are running the '{0}' operation with an 'HTTP' source: {1}. NuGet requires HTTPS sources. Please refer to https://aka.ms/nuget-https-everywhere for more information. + 0 - The command name. Ex. Push/Delete. 1 - server URI. + + + The following is a 'Non-HTTPS' source: {0} +NuGet requires HTTPS sources. Please refer to https://aka.ms/nuget-https-everywhere for more information. + {0} - list of server URIs + + + The following are 'Non-HTTPS' sources: {0} +NuGet requires HTTPS sources. Please refer to https://aka.ms/nuget-https-everywhere for more information. + {0} - list of server URIs + \ No newline at end of file diff --git a/src/NuGet.Core/NuGet.Common/Errors/NuGetLogCode.cs b/src/NuGet.Core/NuGet.Common/Errors/NuGetLogCode.cs index 29856954da2..d9d178456a9 100644 --- a/src/NuGet.Core/NuGet.Common/Errors/NuGetLogCode.cs +++ b/src/NuGet.Core/NuGet.Common/Errors/NuGetLogCode.cs @@ -222,6 +222,11 @@ public enum NuGetLogCode /// NU1301 = 1301, + /// + /// Insecure Source specified. + /// + NU1302 = 1302, + /// /// Package MinClientVersion did not match. /// @@ -342,7 +347,7 @@ public enum NuGetLogCode NU1802 = 1802, /// - /// HTTP Source specified, but HTTP sources will be deprecated. + /// HTTPHTTP Source specified, but HTTP sources will be deprecated. /// NU1803 = 1803, diff --git a/src/NuGet.Core/NuGet.Common/PublicAPI.Unshipped.txt b/src/NuGet.Core/NuGet.Common/PublicAPI.Unshipped.txt index 7dc5c58110b..33acf936083 100644 --- a/src/NuGet.Core/NuGet.Common/PublicAPI.Unshipped.txt +++ b/src/NuGet.Core/NuGet.Common/PublicAPI.Unshipped.txt @@ -1 +1,2 @@ #nullable enable +NuGet.Common.NuGetLogCode.NU1302 = 1302 -> NuGet.Common.NuGetLogCode diff --git a/src/NuGet.Core/NuGet.PackageManagement/IDE/PackageRestoreManager.cs b/src/NuGet.Core/NuGet.PackageManagement/IDE/PackageRestoreManager.cs index 4c15ad006b0..ed52a974458 100644 --- a/src/NuGet.Core/NuGet.PackageManagement/IDE/PackageRestoreManager.cs +++ b/src/NuGet.Core/NuGet.PackageManagement/IDE/PackageRestoreManager.cs @@ -429,7 +429,8 @@ public static async Task RestoreMissingPackagesAsync( PackageSource source = enabledSource.PackageSource; if (source.IsHttp && !source.IsHttps && !source.AllowInsecureConnections) { - packageRestoreContext.Logger.Log(LogLevel.Warning, string.Format(CultureInfo.CurrentCulture, Strings.Warning_HttpServerUsage, "restore", source.Source)); + packageRestoreContext.Logger.Log(LogLevel.Error, string.Format(CultureInfo.CurrentCulture, Strings.Error_HttpSource_Single, "restore", source.Source)); + return new PackageRestoreResult(false, []); } } diff --git a/src/NuGet.Core/NuGet.PackageManagement/NuGet.PackageManagement.csproj b/src/NuGet.Core/NuGet.PackageManagement/NuGet.PackageManagement.csproj index b6934db6572..34ed91085f7 100644 --- a/src/NuGet.Core/NuGet.PackageManagement/NuGet.PackageManagement.csproj +++ b/src/NuGet.Core/NuGet.PackageManagement/NuGet.PackageManagement.csproj @@ -55,5 +55,8 @@ + + + diff --git a/src/NuGet.Core/NuGet.PackageManagement/NuGetPackageManager.cs b/src/NuGet.Core/NuGet.PackageManagement/NuGetPackageManager.cs index 382b94ac4d6..a0a795c2cc1 100644 --- a/src/NuGet.Core/NuGet.PackageManagement/NuGetPackageManager.cs +++ b/src/NuGet.Core/NuGet.PackageManagement/NuGetPackageManager.cs @@ -1125,7 +1125,7 @@ private async Task> PreviewUpdatePackagesForClas PackageSource source = enabledSource.PackageSource; if (source.IsHttp && !source.IsHttps && !source.AllowInsecureConnections) { - nuGetProjectContext.Log(MessageLevel.Warning, Strings.Warning_HttpServerUsage, "update", source.Source); + nuGetProjectContext.Log(MessageLevel.Error, Strings.Error_HttpSource_Single, "update", source.Source); } } @@ -1817,7 +1817,7 @@ await PreviewBuildIntegratedProjectActionsAsync(buildIntegratedProject, actions, PackageSource source = enabledSource.PackageSource; if (source.IsHttp && !source.IsHttps && !source.AllowInsecureConnections) { - nuGetProjectContext.Log(MessageLevel.Warning, Strings.Warning_HttpServerUsage, "install", source.Source); + nuGetProjectContext.Log(MessageLevel.Error, Strings.Error_HttpSource_Single, "install", source.Source); } } diff --git a/src/NuGet.Core/NuGet.PackageManagement/Strings.Designer.cs b/src/NuGet.Core/NuGet.PackageManagement/Strings.Designer.cs index 885a738fba8..3f256b127cf 100644 --- a/src/NuGet.Core/NuGet.PackageManagement/Strings.Designer.cs +++ b/src/NuGet.Core/NuGet.PackageManagement/Strings.Designer.cs @@ -267,6 +267,15 @@ internal static string Error_FileDoesNotExist { } } + /// + /// Looks up a localized string similar to You are running the '{0}' operation with an 'HTTP' source: {1}. NuGet requires HTTPS sources. To use an HTTP source, you must explicitly set 'allowInsecureConnections' to true in your NuGet.Config file. Please refer to https://aka.ms/nuget-https-everywhere.. + /// + internal static string Error_HttpSource_Single { + get { + return ResourceManager.GetString("Error_HttpSource_Single", resourceCulture); + } + } + /// /// Looks up a localized string similar to Invalid restore input where RestorePackagesWithLockFile property is set to false but a packages lock file exists at {0}.. /// diff --git a/src/NuGet.Core/NuGet.PackageManagement/Strings.resx b/src/NuGet.Core/NuGet.PackageManagement/Strings.resx index d5972060f6f..ca45c39b48b 100644 --- a/src/NuGet.Core/NuGet.PackageManagement/Strings.resx +++ b/src/NuGet.Core/NuGet.PackageManagement/Strings.resx @@ -443,4 +443,8 @@ {2} - severity, for example low, moderate, high, or critical {3} - URL for more info on the known vulnerability + + You are running the '{0}' operation with an 'HTTP' source: {1}. NuGet requires HTTPS sources. To use an HTTP source, you must explicitly set 'allowInsecureConnections' to true in your NuGet.Config file. Please refer to https://aka.ms/nuget-https-everywhere. + 0 - The command name. Ex. Push/Delete. 1 - server uri. + \ No newline at end of file diff --git a/test/NuGet.Clients.FuncTests/NuGet.CommandLine.FuncTest/Caching/CachingTestContext.cs b/test/NuGet.Clients.FuncTests/NuGet.CommandLine.FuncTest/Caching/CachingTestContext.cs index 56e7927714f..3d1f6c816bc 100644 --- a/test/NuGet.Clients.FuncTests/NuGet.CommandLine.FuncTest/Caching/CachingTestContext.cs +++ b/test/NuGet.Clients.FuncTests/NuGet.CommandLine.FuncTest/Caching/CachingTestContext.cs @@ -252,18 +252,18 @@ private void InitializeFiles() ProjectPath = Path.Combine(WorkingPath, "project.csproj"); OutputPackagesPath = Path.Combine(WorkingPath, "packages"); - CreateNuGetConfig(WorkingPath); Directory.CreateDirectory(OutputPackagesPath); } - private void CreateNuGetConfig(string workingDirectory) + internal void CreateNuGetConfig(string workingDirectory, string source) { string nugetConfigContent = - @" + $@" + diff --git a/test/NuGet.Clients.FuncTests/NuGet.CommandLine.FuncTest/Caching/CachingTestRunner.cs b/test/NuGet.Clients.FuncTests/NuGet.CommandLine.FuncTest/Caching/CachingTestRunner.cs index a995601c024..ae622c6f7b0 100644 --- a/test/NuGet.Clients.FuncTests/NuGet.CommandLine.FuncTest/Caching/CachingTestRunner.cs +++ b/test/NuGet.Clients.FuncTests/NuGet.CommandLine.FuncTest/Caching/CachingTestRunner.cs @@ -26,7 +26,7 @@ public static async Task> ExecuteAsync(ICachingT tc.NoCache = caching.HasFlag(CachingType.NoCache); tc.DirectDownload = caching.HasFlag(CachingType.DirectDownload); tc.CurrentSource = server == ServerType.V2 ? tc.V2Source : tc.V3Source; - + tc.CreateNuGetConfig(tc.WorkingPath, tc.CurrentSource); tc.ClearHttpCache(); var validations = new List(); for (var i = 0; i < test.IterationCount; i++) diff --git a/test/NuGet.Clients.FuncTests/NuGet.CommandLine.FuncTest/Commands/PushCommandTest.cs b/test/NuGet.Clients.FuncTests/NuGet.CommandLine.FuncTest/Commands/PushCommandTest.cs index 74dcb6127e2..62834686ba7 100644 --- a/test/NuGet.Clients.FuncTests/NuGet.CommandLine.FuncTest/Commands/PushCommandTest.cs +++ b/test/NuGet.Clients.FuncTests/NuGet.CommandLine.FuncTest/Commands/PushCommandTest.cs @@ -40,11 +40,11 @@ public PushCommandTest(ITestOutputHelper testOutputHelper) public void PushCommand_AllowsTimeoutToBeSpecifiedHigherThan100Seconds() { // Arrange - using (var packageDirectory = TestDirectory.Create()) + using (SimpleTestPathContext pathContext = new SimpleTestPathContext()) { var nuget = Util.GetNuGetExePath(); - var sourcePath = Util.CreateTestPackage("PackageA", "1.1.0", packageDirectory); - var outputPath = Path.Combine(packageDirectory, "pushed.nupkg"); + var sourcePath = Util.CreateTestPackage("PackageA", "1.1.0", pathContext.WorkingDirectory); + var outputPath = Path.Combine(pathContext.WorkingDirectory, "pushed.nupkg"); CommandRunnerResult result = null; using (var server = new MockServer()) @@ -61,13 +61,13 @@ public void PushCommand_AllowsTimeoutToBeSpecifiedHigherThan100Seconds() return HttpStatusCode.Created; }); - + pathContext.Settings.AddSource("http-feed", $"{server.Uri}push", "true"); server.Start(); // Act result = CommandRunner.Run( nuget, - packageDirectory, + pathContext.WorkingDirectory, $"push {sourcePath} -Source {server.Uri}push -Timeout 110", timeOutInMilliseconds: 120 * 1000, testOutputHelper: _testOutputHelper); // 120 seconds @@ -84,11 +84,11 @@ public void PushCommand_AllowsTimeoutToBeSpecifiedHigherThan100Seconds() public void PushCommand_AllowsTimeoutToBeSpecifiedLowerThan100Seconds() { // Arrange - using (var packageDirectory = TestDirectory.Create()) + using (SimpleTestPathContext pathContext = new SimpleTestPathContext()) { var nuget = Util.GetNuGetExePath(); - var sourcePath = Util.CreateTestPackage("PackageA", "1.1.0", packageDirectory); - var outputPath = Path.Combine(packageDirectory, "pushed.nupkg"); + var sourcePath = Util.CreateTestPackage("PackageA", "1.1.0", pathContext.WorkingDirectory); + var outputPath = Path.Combine(pathContext.WorkingDirectory, "pushed.nupkg"); CommandRunnerResult result = null; using (var server = new MockServer()) @@ -105,13 +105,13 @@ public void PushCommand_AllowsTimeoutToBeSpecifiedLowerThan100Seconds() return HttpStatusCode.Created; }); - + pathContext.Settings.AddSource("http-feed", $"{server.Uri}push", "true"); server.Start(); // Act result = CommandRunner.Run( nuget, - packageDirectory, + pathContext.WorkingDirectory, $"push {sourcePath} -Source {server.Uri}push -Timeout 1", timeOutInMilliseconds: 20 * 1000, testOutputHelper: _testOutputHelper); // 20 seconds @@ -128,14 +128,14 @@ public void PushCommand_AllowsTimeoutToBeSpecifiedLowerThan100Seconds() public void PushCommand_Server_SkipDuplicate_NotSpecified_PushHalts() { // Arrange - using (var packageDirectory = TestDirectory.Create()) + using (SimpleTestPathContext pathContext = new SimpleTestPathContext()) { var nuget = Util.GetNuGetExePath(); - var sourcePath = Util.CreateTestPackage("PackageA", "1.1.0", packageDirectory); - var outputPath = Path.Combine(packageDirectory, "pushed.nupkg"); + var sourcePath = Util.CreateTestPackage("PackageA", "1.1.0", pathContext.WorkingDirectory); + var outputPath = Path.Combine(pathContext.WorkingDirectory, "pushed.nupkg"); - var sourcePath2 = Util.CreateTestPackage("PackageB", "1.1.0", packageDirectory); - var outputPath2 = Path.Combine(packageDirectory, "pushed2.nupkg"); + var sourcePath2 = Util.CreateTestPackage("PackageB", "1.1.0", pathContext.WorkingDirectory); + var outputPath2 = Path.Combine(pathContext.WorkingDirectory, "pushed2.nupkg"); CommandRunnerResult result = null; CommandRunnerResult result2 = null; @@ -148,11 +148,11 @@ public void PushCommand_Server_SkipDuplicate_NotSpecified_PushHalts() FuncStatusDuplicate_OccursOnSecondPush()); server.Start(); - + pathContext.Settings.AddSource("http-feed", $"{server.Uri}push", "true"); // Act result = CommandRunner.Run( nuget, - packageDirectory, + pathContext.WorkingDirectory, $"push {sourcePath} -Source {server.Uri}push -Timeout 110", timeOutInMilliseconds: 120 * 1000, testOutputHelper: _testOutputHelper); // 120 seconds @@ -160,14 +160,14 @@ public void PushCommand_Server_SkipDuplicate_NotSpecified_PushHalts() //Run again so that it will be a duplicate push. result2 = CommandRunner.Run( nuget, - packageDirectory, + pathContext.WorkingDirectory, $"push {sourcePath} -Source {server.Uri}push -Timeout 110", timeOutInMilliseconds: 120 * 1000, testOutputHelper: _testOutputHelper); // 120 seconds result3 = CommandRunner.Run( nuget, - packageDirectory, + pathContext.WorkingDirectory, $"push {sourcePath2} -Source {server.Uri}push -Timeout 110", timeOutInMilliseconds: 120 * 1000, testOutputHelper: _testOutputHelper); // 120 seconds @@ -194,14 +194,14 @@ public void PushCommand_Server_SkipDuplicate_NotSpecified_PushHalts() public void PushCommand_Server_SkipDuplicate_IsSpecified_PushProceeds() { // Arrange - using (var packageDirectory = TestDirectory.Create()) + using (SimpleTestPathContext pathContext = new SimpleTestPathContext()) { var nuget = Util.GetNuGetExePath(); - var sourcePath = Util.CreateTestPackage("PackageA", "1.1.0", packageDirectory); - var outputPath = Path.Combine(packageDirectory, "pushed.nupkg"); + var sourcePath = Util.CreateTestPackage("PackageA", "1.1.0", pathContext.WorkingDirectory); + var outputPath = Path.Combine(pathContext.WorkingDirectory, "pushed.nupkg"); - var sourcePath2 = Util.CreateTestPackage("PackageB", "1.1.0", packageDirectory); - var outputPath2 = Path.Combine(packageDirectory, "pushed2.nupkg"); + var sourcePath2 = Util.CreateTestPackage("PackageB", "1.1.0", pathContext.WorkingDirectory); + var outputPath2 = Path.Combine(pathContext.WorkingDirectory, "pushed2.nupkg"); CommandRunnerResult result = null; CommandRunnerResult result2 = null; @@ -212,13 +212,13 @@ public void PushCommand_Server_SkipDuplicate_IsSpecified_PushProceeds() SetupMockServerForSkipDuplicate(server, FuncOutputPath_SwitchesOnThirdPush(outputPath, outputPath2), FuncStatusDuplicate_OccursOnSecondPush()); - + pathContext.Settings.AddSource("http-feed", $"{server.Uri}push", "true"); server.Start(); // Act result = CommandRunner.Run( nuget, - packageDirectory, + pathContext.WorkingDirectory, $"push {sourcePath} -Source {server.Uri}push -Timeout 110 -SkipDuplicate", timeOutInMilliseconds: 120 * 1000, testOutputHelper: _testOutputHelper); // 120 seconds @@ -226,7 +226,7 @@ public void PushCommand_Server_SkipDuplicate_IsSpecified_PushProceeds() //Run again so that it will be a duplicate push but use the option to skip duplicate packages. result2 = CommandRunner.Run( nuget, - packageDirectory, + pathContext.WorkingDirectory, $"push {sourcePath} -Source {server.Uri}push -Timeout 110 -SkipDuplicate", timeOutInMilliseconds: 120 * 1000, testOutputHelper: _testOutputHelper); // 120 seconds @@ -234,7 +234,7 @@ public void PushCommand_Server_SkipDuplicate_IsSpecified_PushProceeds() //Third run with a different package. result3 = CommandRunner.Run( nuget, - packageDirectory, + pathContext.WorkingDirectory, $"push {sourcePath2} -Source {server.Uri}push -Timeout 110 -SkipDuplicate", timeOutInMilliseconds: 120 * 1000, testOutputHelper: _testOutputHelper); // 120 seconds @@ -269,18 +269,19 @@ public void PushCommand_Server_SkipDuplicate_IsSpecified_PushProceeds() public void PushCommand_Server_Snupkg_ByFilename_DoesNotExist_FileNotFoundError() { // Arrange - using (var packageDirectory = TestDirectory.Create()) + using (SimpleTestPathContext pathContext = new SimpleTestPathContext()) { var nuget = Util.GetNuGetExePath(); string snupkgToPush = "nonExistingPackage.snupkg"; CommandRunnerResult result = null; - using (var server = CreateAndStartMockV3Server(packageDirectory, out string sourceName)) + using (var server = CreateAndStartMockV3Server(pathContext.WorkingDirectory, out string sourceName)) { + pathContext.Settings.AddSource(sourceName, sourceName, "true"); // Act result = CommandRunner.Run( nuget, - packageDirectory, + pathContext.WorkingDirectory, $"push {snupkgToPush} -Source {sourceName} -Timeout 110", timeOutInMilliseconds: 120000, testOutputHelper: _testOutputHelper); // 120 seconds @@ -303,7 +304,7 @@ public void PushCommand_Server_Snupkg_ByFilename_DoesNotExist_FileNotFoundError( public void PushCommand_Server_Snupkg_ByWildcard_FindsNothing_FileNotFoundError() { // Arrange - using (var packageDirectory = TestDirectory.Create()) + using (SimpleTestPathContext pathContext = new SimpleTestPathContext()) { var nuget = Util.GetNuGetExePath(); @@ -311,12 +312,13 @@ public void PushCommand_Server_Snupkg_ByWildcard_FindsNothing_FileNotFoundError( CommandRunnerResult result = null; - using (var server = CreateAndStartMockV3Server(packageDirectory, out string sourceName)) + using (var server = CreateAndStartMockV3Server(pathContext.WorkingDirectory, out string sourceName)) { + pathContext.Settings.AddSource(sourceName, sourceName, "true"); // Act result = CommandRunner.Run( nuget, - packageDirectory, + pathContext.WorkingDirectory, $"push {snupkgToPush} -Source {sourceName} -Timeout 110", timeOutInMilliseconds: 120000, testOutputHelper: _testOutputHelper); // 120 seconds @@ -337,7 +339,7 @@ public void PushCommand_Server_Snupkg_ByWildcard_FindsNothing_FileNotFoundError( public void PushCommand_Server_Nupkg_ByFilename_FindsNothing_FileNotFoundError() { // Arrange - using (var packageDirectory = TestDirectory.Create()) + using (SimpleTestPathContext pathContext = new SimpleTestPathContext()) { var nuget = Util.GetNuGetExePath(); @@ -345,12 +347,13 @@ public void PushCommand_Server_Nupkg_ByFilename_FindsNothing_FileNotFoundError() CommandRunnerResult result = null; - using (var server = CreateAndStartMockV3Server(packageDirectory, out string sourceName)) + using (var server = CreateAndStartMockV3Server(pathContext.WorkingDirectory, out string sourceName)) { + pathContext.Settings.AddSource(sourceName, sourceName, "true"); // Act result = CommandRunner.Run( nuget, - packageDirectory, + pathContext.WorkingDirectory, $"push {nupkgToPush} -Source {sourceName} -Timeout 110", timeOutInMilliseconds: 120000, testOutputHelper: _testOutputHelper); // 120 seconds @@ -371,7 +374,7 @@ public void PushCommand_Server_Nupkg_ByFilename_FindsNothing_FileNotFoundError() public void PushCommand_Server_Nupkg_ByWildcard_FindsNothing_FileNotFoundError() { // Arrange - using (var packageDirectory = TestDirectory.Create()) + using (SimpleTestPathContext pathContext = new SimpleTestPathContext()) { var nuget = Util.GetNuGetExePath(); @@ -379,12 +382,13 @@ public void PushCommand_Server_Nupkg_ByWildcard_FindsNothing_FileNotFoundError() CommandRunnerResult result = null; - using (var server = CreateAndStartMockV3Server(packageDirectory, out string sourceName)) + using (var server = CreateAndStartMockV3Server(pathContext.WorkingDirectory, out string sourceName)) { + pathContext.Settings.AddSource(sourceName, sourceName, "true"); // Act result = CommandRunner.Run( nuget, - packageDirectory, + pathContext.WorkingDirectory, $"push {nupkgToPush} -Source {sourceName} -Timeout 110", timeOutInMilliseconds: 120000, testOutputHelper: _testOutputHelper); // 120 seconds @@ -405,7 +409,7 @@ public void PushCommand_Server_Nupkg_ByWildcard_FindsNothing_FileNotFoundError() public void PushCommand_Server_Nupkg_ByFilename_SnupkgDoesNotExist_NoFileNotFoundError() { // Arrange - using (var packageDirectory = TestDirectory.Create()) + using (SimpleTestPathContext pathContext = new SimpleTestPathContext()) { var nuget = Util.GetNuGetExePath(); @@ -413,22 +417,22 @@ public void PushCommand_Server_Nupkg_ByFilename_SnupkgDoesNotExist_NoFileNotFoun string version = "1.1.0"; //Create Nupkg in test directory. - string nupkgFullPath = Util.CreateTestPackage(packageId, version, packageDirectory); + string nupkgFullPath = Util.CreateTestPackage(packageId, version, pathContext.WorkingDirectory); string nupkgFileName = Util.BuildPackageString(packageId, version, NuGetConstants.PackageExtension); string snupkgFileName = Util.BuildPackageString(packageId, version, NuGetConstants.SnupkgExtension); - string snupkgFullPath = Path.Combine(packageDirectory, snupkgFileName); + string snupkgFullPath = Path.Combine(pathContext.WorkingDirectory, snupkgFileName); CommandRunnerResult result = null; - using (var server = CreateAndStartMockV3Server(packageDirectory, out string sourceName)) + using (var server = CreateAndStartMockV3Server(pathContext.WorkingDirectory, out string sourceName)) { SetupMockServerAlwaysCreate(server); - + pathContext.Settings.AddSource(sourceName, sourceName, "true"); // Act result = CommandRunner.Run( nuget, - packageDirectory, + pathContext.WorkingDirectory, $"push {nupkgFullPath} -Source {sourceName} -Timeout 110", timeOutInMilliseconds: 120000, testOutputHelper: _testOutputHelper); // 120 seconds @@ -449,7 +453,7 @@ public void PushCommand_Server_Nupkg_ByFilename_SnupkgDoesNotExist_NoFileNotFoun public void PushCommand_Server_Nupkg_ByWildcard_SnupkgDoesNotExist_NoFileNotFoundError() { // Arrange - using (var packageDirectory = TestDirectory.Create()) + using (SimpleTestPathContext pathContext = new SimpleTestPathContext()) { var nuget = Util.GetNuGetExePath(); @@ -457,19 +461,19 @@ public void PushCommand_Server_Nupkg_ByWildcard_SnupkgDoesNotExist_NoFileNotFoun string version = "1.1.0"; //Create Nupkg in test directory. - string nupkgFullPath = Util.CreateTestPackage(packageId, version, packageDirectory); + string nupkgFullPath = Util.CreateTestPackage(packageId, version, pathContext.WorkingDirectory); string pushArgument = "*.nupkg"; CommandRunnerResult result = null; - using (var server = CreateAndStartMockV3Server(packageDirectory, out string sourceName)) + using (var server = CreateAndStartMockV3Server(pathContext.WorkingDirectory, out string sourceName)) { SetupMockServerAlwaysCreate(server); - + pathContext.Settings.AddSource(sourceName, sourceName, "true"); // Act result = CommandRunner.Run( nuget, - packageDirectory, + pathContext.WorkingDirectory, $"push {pushArgument} -Source {sourceName} -Timeout 110", timeOutInMilliseconds: 120000, testOutputHelper: _testOutputHelper); // 120 seconds @@ -493,7 +497,7 @@ public void PushCommand_Server_Nupkg_ByWildcard_SnupkgDoesNotExist_NoFileNotFoun public void PushCommand_Server_Nupkg_ByFilename_SnupkgExists_Conflict() { // Arrange - using (var packageDirectory = TestDirectory.Create()) + using (SimpleTestPathContext pathContext = new SimpleTestPathContext()) { var nuget = Util.GetNuGetExePath(); @@ -501,27 +505,27 @@ public void PushCommand_Server_Nupkg_ByFilename_SnupkgExists_Conflict() //Create nupkg in test directory. string version = "1.1.0"; - string nupkgFullPath = Util.CreateTestPackage(packageId, version, packageDirectory); + string nupkgFullPath = Util.CreateTestPackage(packageId, version, pathContext.WorkingDirectory); string nupkgFileName = Util.BuildPackageString(packageId, version, NuGetConstants.PackageExtension); string snupkgFileName = Util.BuildPackageString(packageId, version, NuGetConstants.SnupkgExtension); - string snupkgFullPath = Path.Combine(packageDirectory, snupkgFileName); + string snupkgFullPath = Path.Combine(pathContext.WorkingDirectory, snupkgFileName); //Create snupkg in test directory. WriteSnupkgFile(snupkgFullPath); CommandRunnerResult result = null; CommandRunnerResult result2 = null; - using (var server = CreateAndStartMockV3Server(packageDirectory, out string sourceName)) + using (var server = CreateAndStartMockV3Server(pathContext.WorkingDirectory, out string sourceName)) { //Configure push to alternate returning Created and Conflict responses, which correspond to pushing the nupkg and snupkg, respectively. - SetupMockServerCreateNupkgDuplicateSnupkg(server, packageDirectory, FuncStatus_Alternates_CreatedAndDuplicate()); - + SetupMockServerCreateNupkgDuplicateSnupkg(server, pathContext.WorkingDirectory, FuncStatus_Alternates_CreatedAndDuplicate()); + pathContext.Settings.AddSource(sourceName, sourceName, "true"); // Act //Since this is V3, this will trigger 2 pushes: one for nupkgs, and one for snupkgs. result = CommandRunner.Run( nuget, - packageDirectory, + pathContext.WorkingDirectory, $"push {nupkgFullPath} -Source {sourceName} -Timeout 110", timeOutInMilliseconds: 120000, testOutputHelper: _testOutputHelper); // 120 seconds @@ -529,7 +533,7 @@ public void PushCommand_Server_Nupkg_ByFilename_SnupkgExists_Conflict() //Second run with SkipDuplicate result2 = CommandRunner.Run( nuget, - packageDirectory, + pathContext.WorkingDirectory, $"push {nupkgFullPath} -Source {sourceName} -Timeout 110 -SkipDuplicate", timeOutInMilliseconds: 120000, testOutputHelper: _testOutputHelper); // 120 seconds @@ -563,7 +567,7 @@ public void PushCommand_Server_Nupkg_ByFilename_SnupkgExists_Conflict() public void PushCommand_Server_Nupkg_ByWildcard_FindsMatchingSnupkgs_Conflict() { // Arrange - using (var packageDirectory = TestDirectory.Create()) + using (SimpleTestPathContext pathContext = new SimpleTestPathContext()) { var nuget = Util.GetNuGetExePath(); @@ -571,10 +575,10 @@ public void PushCommand_Server_Nupkg_ByWildcard_FindsMatchingSnupkgs_Conflict() //Create a nupkg in test directory. string version = "1.1.0"; - Util.CreateTestPackage(packageId, version, packageDirectory); + Util.CreateTestPackage(packageId, version, pathContext.WorkingDirectory); string nupkgFileName = Util.BuildPackageString(packageId, version, NuGetConstants.PackageExtension); string snupkgFileName = Util.BuildPackageString(packageId, version, NuGetConstants.SnupkgExtension); - string snupkgFullPath = Path.Combine(packageDirectory, snupkgFileName); + string snupkgFullPath = Path.Combine(pathContext.WorkingDirectory, snupkgFileName); //Create snupkg in test directory. WriteSnupkgFile(snupkgFullPath); @@ -582,17 +586,17 @@ public void PushCommand_Server_Nupkg_ByWildcard_FindsMatchingSnupkgs_Conflict() CommandRunnerResult result = null; - using (var server = CreateAndStartMockV3Server(packageDirectory, out string sourceName)) + using (var server = CreateAndStartMockV3Server(pathContext.WorkingDirectory, out string sourceName)) { //Configure push to return a Conflict for the first push, then Created for all remaining pushes. - SetupMockServerCreateNupkgDuplicateSnupkg(server, packageDirectory, FuncStatus_Duplicate_ThenAlwaysCreated()); - + SetupMockServerCreateNupkgDuplicateSnupkg(server, pathContext.WorkingDirectory, FuncStatus_Duplicate_ThenAlwaysCreated()); + pathContext.Settings.AddSource(sourceName, sourceName, "true"); // Act //Since this is V3, this will trigger 2 pushes: one for nupkgs, and one for snupkgs. result = CommandRunner.Run( nuget, - packageDirectory, + pathContext.WorkingDirectory, $"push {wildcardPush} -Source {sourceName} -SymbolSource {sourceName} -Timeout 110", timeOutInMilliseconds: 120000, testOutputHelper: _testOutputHelper); // 120 seconds @@ -619,7 +623,7 @@ public void PushCommand_Server_Nupkg_ByWildcard_FindsMatchingSnupkgs_Conflict() public void PushCommand_Server_Nupkg_ByWildcard_FindsMatchingSnupkgs_SkipDuplicate() { // Arrange - using (var packageDirectory = TestDirectory.Create()) + using (SimpleTestPathContext pathContext = new SimpleTestPathContext()) { var nuget = Util.GetNuGetExePath(); @@ -627,19 +631,19 @@ public void PushCommand_Server_Nupkg_ByWildcard_FindsMatchingSnupkgs_SkipDuplica //Create a nupkg in test directory. string version = "1.1.0"; - Util.CreateTestPackage(packageId, version, packageDirectory); + Util.CreateTestPackage(packageId, version, pathContext.WorkingDirectory); string nupkgFileName = Util.BuildPackageString(packageId, version, NuGetConstants.PackageExtension); string snupkgFileName = Util.BuildPackageString(packageId, version, NuGetConstants.SnupkgExtension); - string snupkgFullPath = Path.Combine(packageDirectory, snupkgFileName); + string snupkgFullPath = Path.Combine(pathContext.WorkingDirectory, snupkgFileName); //Create snupkg in test directory. WriteSnupkgFile(snupkgFullPath); //Create another nupkg in test directory. version = "2.12.1"; - Util.CreateTestPackage(packageId, version, packageDirectory); + Util.CreateTestPackage(packageId, version, pathContext.WorkingDirectory); string nupkgFileName2 = Util.BuildPackageString(packageId, version, NuGetConstants.PackageExtension); string snupkgFileName2 = Util.BuildPackageString(packageId, version, NuGetConstants.SnupkgExtension); - string snupkgFullPath2 = Path.Combine(packageDirectory, snupkgFileName2); + string snupkgFullPath2 = Path.Combine(pathContext.WorkingDirectory, snupkgFileName2); //Create another snupkg in test directory. WriteSnupkgFile(snupkgFullPath2); @@ -647,16 +651,16 @@ public void PushCommand_Server_Nupkg_ByWildcard_FindsMatchingSnupkgs_SkipDuplica CommandRunnerResult result = null; - using (var server = CreateAndStartMockV3Server(packageDirectory, out string sourceName)) + using (var server = CreateAndStartMockV3Server(pathContext.WorkingDirectory, out string sourceName)) { SetupMockServerAlwaysDuplicate(server); - + pathContext.Settings.AddSource(sourceName, sourceName, "true"); // Act //Since this is V3, this will trigger 2 pushes: one for nupkgs, and one for snupkgs. result = CommandRunner.Run( nuget, - packageDirectory, + pathContext.WorkingDirectory, $"push {wildcardPush} -Source {sourceName} -Timeout 110 -SkipDuplicate", timeOutInMilliseconds: 120000, testOutputHelper: _testOutputHelper); // 120 seconds @@ -686,7 +690,7 @@ public void PushCommand_Server_Nupkg_ByWildcard_FindsMatchingSnupkgs_SkipDuplica public void PushCommand_Server_Snupkg_ByWildcard_FindsMatchingSnupkgs_Conflict() { // Arrange - using (var packageDirectory = TestDirectory.Create()) + using (SimpleTestPathContext pathContext = new SimpleTestPathContext()) { var nuget = Util.GetNuGetExePath(); @@ -694,10 +698,10 @@ public void PushCommand_Server_Snupkg_ByWildcard_FindsMatchingSnupkgs_Conflict() //Create a nupkg in test directory. string version = "1.1.0"; - Util.CreateTestPackage(packageId, version, packageDirectory); + Util.CreateTestPackage(packageId, version, pathContext.WorkingDirectory); string nupkgFileName = Util.BuildPackageString(packageId, version, NuGetConstants.PackageExtension); string snupkgFileName = Util.BuildPackageString(packageId, version, NuGetConstants.SnupkgExtension); - string snupkgFullPath = Path.Combine(packageDirectory, snupkgFileName); + string snupkgFullPath = Path.Combine(pathContext.WorkingDirectory, snupkgFileName); //Create snupkg in test directory. WriteSnupkgFile(snupkgFullPath); @@ -706,17 +710,17 @@ public void PushCommand_Server_Snupkg_ByWildcard_FindsMatchingSnupkgs_Conflict() CommandRunnerResult result = null; - using (var server = CreateAndStartMockV3Server(packageDirectory, out string sourceName)) + using (var server = CreateAndStartMockV3Server(pathContext.WorkingDirectory, out string sourceName)) { //Configure push to return a Conflict for the first push, then Created for all remaining pushes. - SetupMockServerCreateNupkgDuplicateSnupkg(server, packageDirectory, FuncStatus_Duplicate_ThenAlwaysCreated()); - + SetupMockServerCreateNupkgDuplicateSnupkg(server, pathContext.WorkingDirectory, FuncStatus_Duplicate_ThenAlwaysCreated()); + pathContext.Settings.AddSource(sourceName, sourceName, "true"); // Act //Since this is V3, this will trigger 2 pushes: one for nupkgs, and one for snupkgs. result = CommandRunner.Run( nuget, - packageDirectory, + pathContext.WorkingDirectory, $"push {wildcardPush} -Source {sourceName} -Timeout 110", timeOutInMilliseconds: 120000, testOutputHelper: _testOutputHelper); // 120 seconds @@ -743,7 +747,7 @@ public void PushCommand_Server_Snupkg_ByWildcard_FindsMatchingSnupkgs_Conflict() public void PushCommand_Server_Snupkg_ByWildcard_FindsMatchingSnupkgs_SkipDuplicate() { // Arrange - using (var packageDirectory = TestDirectory.Create()) + using (SimpleTestPathContext pathContext = new SimpleTestPathContext()) { var nuget = Util.GetNuGetExePath(); @@ -751,19 +755,19 @@ public void PushCommand_Server_Snupkg_ByWildcard_FindsMatchingSnupkgs_SkipDuplic //Create a nupkg in test directory. string version = "1.1.0"; - Util.CreateTestPackage(packageId, version, packageDirectory); + Util.CreateTestPackage(packageId, version, pathContext.WorkingDirectory); string nupkgFileName = Util.BuildPackageString(packageId, version, NuGetConstants.PackageExtension); string snupkgFileName = Util.BuildPackageString(packageId, version, NuGetConstants.SnupkgExtension); - string snupkgFullPath = Path.Combine(packageDirectory, snupkgFileName); + string snupkgFullPath = Path.Combine(pathContext.WorkingDirectory, snupkgFileName); //Create snupkg in test directory. WriteSnupkgFile(snupkgFullPath); //Create another nupkg in test directory. version = "2.12.1"; - Util.CreateTestPackage(packageId, version, packageDirectory); + Util.CreateTestPackage(packageId, version, pathContext.WorkingDirectory); string nupkgFileName2 = Util.BuildPackageString(packageId, version, NuGetConstants.PackageExtension); string snupkgFileName2 = Util.BuildPackageString(packageId, version, NuGetConstants.SnupkgExtension); - string snupkgFullPath2 = Path.Combine(packageDirectory, snupkgFileName2); + string snupkgFullPath2 = Path.Combine(pathContext.WorkingDirectory, snupkgFileName2); //Create another snupkg in test directory. WriteSnupkgFile(snupkgFullPath2); @@ -771,15 +775,15 @@ public void PushCommand_Server_Snupkg_ByWildcard_FindsMatchingSnupkgs_SkipDuplic CommandRunnerResult result = null; - using (var server = CreateAndStartMockV3Server(packageDirectory, out string sourceName)) + using (var server = CreateAndStartMockV3Server(pathContext.WorkingDirectory, out string sourceName)) { SetupMockServerAlwaysDuplicate(server); - + pathContext.Settings.AddSource(sourceName, sourceName, "true"); // Act result = CommandRunner.Run( nuget, - packageDirectory, + pathContext.WorkingDirectory, $"push {wildcardPush} -Source {sourceName} -Timeout 110 -SkipDuplicate", timeOutInMilliseconds: 120000, testOutputHelper: _testOutputHelper); // 120 seconds @@ -812,34 +816,34 @@ public void PushCommand_Server_Snupkg_ByWildcard_FindsMatchingSnupkgs_SkipDuplic public void PushCommand_Server_Snupkg_ByFilename_SnupkgExists_Conflict_ServerMessage() { // Arrange - using (var packageDirectory = TestDirectory.Create()) + using (SimpleTestPathContext pathContext = new SimpleTestPathContext()) { var nuget = Util.GetNuGetExePath(); string snupkgFileName = "fileName.snupkg"; - string snupkgFullPath = Path.Combine(packageDirectory, snupkgFileName); + string snupkgFullPath = Path.Combine(pathContext.WorkingDirectory, snupkgFileName); //Create snupkg in test directory. WriteSnupkgFile(snupkgFullPath); CommandRunnerResult result = null; CommandRunnerResult result2 = null; - using (var server = CreateAndStartMockV3Server(packageDirectory, out string sourceName)) + using (var server = CreateAndStartMockV3Server(pathContext.WorkingDirectory, out string sourceName)) { SetupMockServerAlwaysDuplicate(server); - + pathContext.Settings.AddSource(sourceName, sourceName, "true"); // Act result = CommandRunner.Run( nuget, - packageDirectory, + pathContext.WorkingDirectory, $"push {snupkgFileName} -Source {sourceName} -Timeout 110 -Verbosity detailed", timeOutInMilliseconds: 120000, testOutputHelper: _testOutputHelper); // 120 seconds result2 = CommandRunner.Run( nuget, - packageDirectory, + pathContext.WorkingDirectory, $"push {snupkgFileName} -Source {sourceName} -Timeout 110 -SkipDuplicate -Verbosity detailed", timeOutInMilliseconds: 120000, testOutputHelper: _testOutputHelper); // 120 seconds @@ -855,7 +859,7 @@ public void PushCommand_Server_Snupkg_ByFilename_SnupkgExists_Conflict_ServerMes } [Fact] - public void PushCommand_WhenPushingToAnHttpServerV3_WithSymbols_Warns() + public void PushCommand_WhenPushingToAnHttpServerV3_WithSymbols_Errors() { // Arrange using var packageDirectory = TestDirectory.Create(); @@ -867,7 +871,6 @@ public void PushCommand_WhenPushingToAnHttpServerV3_WithSymbols_Warns() CommandRunnerResult result = null; using var server = CreateAndStartMockV3Server(packageDirectory, out string sourceName); - SetupMockServerAlwaysCreate(server); // Act result = CommandRunner.Run( @@ -878,8 +881,8 @@ public void PushCommand_WhenPushingToAnHttpServerV3_WithSymbols_Warns() testOutputHelper: _testOutputHelper); // 120 seconds // Assert - Assert.True(result.Success, result.AllOutput); - Assert.Contains("WARNING: You are running the 'push' operation with an 'HTTP' source", result.AllOutput); + Assert.False(result.Success, result.AllOutput); + Assert.Contains(sourceName, result.Errors); } #region Helpers diff --git a/test/NuGet.Clients.FuncTests/NuGet.CommandLine.FuncTest/Commands/RestoreCommandTests.cs b/test/NuGet.Clients.FuncTests/NuGet.CommandLine.FuncTest/Commands/RestoreCommandTests.cs index 2298483bd5c..62e27403ece 100644 --- a/test/NuGet.Clients.FuncTests/NuGet.CommandLine.FuncTest/Commands/RestoreCommandTests.cs +++ b/test/NuGet.Clients.FuncTests/NuGet.CommandLine.FuncTest/Commands/RestoreCommandTests.cs @@ -1184,7 +1184,7 @@ await SimpleTestPackageUtility.CreateFolderFeedV3Async( [Fact] - public async Task Restore_WithHttpSource_Warns() + public async Task Restore_WithHttpSource_Fails() { // Arrange using var pathContext = new SimpleTestPathContext(); @@ -1212,22 +1212,18 @@ public async Task Restore_WithHttpSource_Warns() solution.Create(pathContext.SolutionRoot); // Act - var result = RunRestore(pathContext, _successExitCode); + var result = RunRestore(pathContext, _failureExitCode); // Assert - result.Success.Should().BeTrue(); - Assert.Contains($"Added package 'A.1.0.0' to folder '{projectAPackages}'", result.Output); - Assert.Contains("You are running the 'restore' operation with an 'HTTP' source, 'http://api.source/index.json'. Non-HTTPS access will be removed in a future version. Consider migrating to an 'HTTPS' source.", result.Output); + result.Success.Should().BeFalse(); + string errorForHttpSource = string.Format(PackageManagement.Strings.Error_HttpSource_Single, "restore", "http://api.source/index.json"); + Assert.Contains(errorForHttpSource, result.AllOutput); } [Theory] - [InlineData("false", true)] - [InlineData("FALSE", true)] - [InlineData("invalidString", true)] - [InlineData("", true)] - [InlineData("true", false)] - [InlineData("TRUE", false)] - public async Task Restore_WithHttpSourceAndFalseAllowInsecureConnections_WarnsCorrectly(string allowInsecureConnections, bool hasHttpWarning) + [InlineData("true")] + [InlineData("TRUE")] + public async Task Restore_WithHttpSourceAndAllowInsecureConnectionsAttributeSetTrue_DoesNotFail(string allowInsecureConnections) { // Arrange using var pathContext = new SimpleTestPathContext(); @@ -1258,21 +1254,57 @@ public async Task Restore_WithHttpSourceAndFalseAllowInsecureConnections_WarnsCo CommandRunnerResult result = RunRestore(pathContext, _successExitCode); // Assert - string formatString = "You are running the 'restore' operation with an 'HTTP' source, '{0}'. Non-HTTPS access will be removed in a future version. Consider migrating to an 'HTTPS'"; - string warningForHttpSource = string.Format(formatString, "http://api.source/index.json"); - string warningForHttpsSource = string.Format(formatString, "https://api.source/index.json"); + string errorForHttpSource = string.Format(PackageManagement.Strings.Error_HttpSource_Single, "restore", "http://api.source/index.json"); + string errorForHttpsSource = string.Format(PackageManagement.Strings.Error_HttpSource_Single, "restore", "https://api.source/index.json"); result.Success.Should().BeTrue(); - Assert.Contains($"Added package 'A.1.0.0' to folder '{projectBPackages}'", result.Output); - Assert.DoesNotContain(warningForHttpsSource, result.Output); - if (hasHttpWarning) - { - Assert.Contains(warningForHttpSource, result.Output); - } - else - { - Assert.DoesNotContain(warningForHttpSource, result.Output); - } + Assert.Contains($"Added package 'A.1.0.0' to folder '{projectBPackages}'", result.AllOutput); + Assert.DoesNotContain(errorForHttpSource, result.AllOutput); + Assert.DoesNotContain(errorForHttpsSource, result.AllOutput); + } + + [Theory] + [InlineData("false")] + [InlineData("FALSE")] + [InlineData("invalidString")] + [InlineData("")] + public async Task Restore_WithHttpSourceAndAllowInsecureConnectionsAttributeSetFalse_Fails(string allowInsecureConnections) + { + // Arrange + using var pathContext = new SimpleTestPathContext(); + // Set up solution, project, and packages + var solution = new SimpleTestSolutionContext(pathContext.SolutionRoot); + var packageA = new SimpleTestPackageContext("a", "1.0.0"); + await SimpleTestPackageUtility.CreateFolderFeedV3Async(pathContext.PackageSource, packageA); + pathContext.Settings.AddSource("http-feed", "http://api.source/index.json", allowInsecureConnections); + pathContext.Settings.AddSource("https-feed", "https://api.source/index.json", allowInsecureConnections); + + var net461 = NuGetFramework.Parse("net461"); + var projectB = new SimpleTestProjectContext( + "b", + ProjectStyle.PackagesConfig, + pathContext.SolutionRoot); + projectB.Frameworks.Add(new SimpleTestProjectFrameworkContext(net461)); + var projectBPackages = Path.Combine(pathContext.SolutionRoot, "packages"); + + Util.CreateFile(Path.GetDirectoryName(projectB.ProjectPath), "packages.config", +@" + +"); + + solution.Projects.Add(projectB); + solution.Create(pathContext.SolutionRoot); + + // Act + CommandRunnerResult result = RunRestore(pathContext, _failureExitCode); + + // Assert + string errorForHttpSource = string.Format(PackageManagement.Strings.Error_HttpSource_Single, "restore", "http://api.source/index.json"); + string errorForHttpsSource = string.Format(PackageManagement.Strings.Error_HttpSource_Single, "restore", "https://api.source/index.json"); + + result.Success.Should().BeFalse(); + Assert.Contains(errorForHttpSource, result.AllOutput); + Assert.DoesNotContain(errorForHttpsSource, result.AllOutput); } public static string GetResource(string name) diff --git a/test/NuGet.Clients.FuncTests/NuGet.CommandLine.FuncTest/Commands/SearchCommandTests.cs b/test/NuGet.Clients.FuncTests/NuGet.CommandLine.FuncTest/Commands/SearchCommandTests.cs index 196466271cf..2353fe5d776 100644 --- a/test/NuGet.Clients.FuncTests/NuGet.CommandLine.FuncTest/Commands/SearchCommandTests.cs +++ b/test/NuGet.Clients.FuncTests/NuGet.CommandLine.FuncTest/Commands/SearchCommandTests.cs @@ -1,9 +1,12 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using System.IO; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; using NuGet.CommandLine.Test; -using NuGet.Configuration.Test; +using NuGet.Configuration; using NuGet.Test.Utility; using Test.Utility; using Xunit; @@ -29,11 +32,8 @@ public void SearchCommand_TargetEndpointTest() using (MockServer server = new MockServer()) using (SimpleTestPathContext config = new SimpleTestPathContext()) { - CommandRunner.Run( - nugetexe, - config.WorkingDirectory, - $"source add -name mockSource -source {server.Uri}v3/index.json -configfile {config.NuGetConfig}", - testOutputHelper: _testOutputHelper); + // Arrange the NuGet.Config file + config.Settings.AddSource("mockSource", $"{server.Uri}v3/index.json", allowInsecureConnectionsValue: "true"); string index = $@" {{ @@ -140,11 +140,8 @@ public void SearchCommand_VerbosityDetailedTest() using (MockServer server = new MockServer()) using (SimpleTestPathContext config = new SimpleTestPathContext()) { - CommandRunner.Run( - nugetexe, - config.WorkingDirectory, - $"source add -name mockSource -source {server.Uri}v3/index.json -configfile {config.NuGetConfig}", - testOutputHelper: _testOutputHelper); + // Arrange the NuGet.Config file + config.Settings.AddSource("mockSource", $"{server.Uri}v3/index.json", allowInsecureConnectionsValue: "true"); string index = $@" {{ @@ -257,11 +254,8 @@ public void SearchCommand_VerbosityNormalTest() using (MockServer server = new MockServer()) using (SimpleTestPathContext config = new SimpleTestPathContext()) { - CommandRunner.Run( - nugetexe, - config.WorkingDirectory, - $"source add -name mockSource -source {server.Uri}v3/index.json -configfile {config.NuGetConfig}", - testOutputHelper: _testOutputHelper); + // Arrange the NuGet.Config file + config.Settings.AddSource("mockSource", $"{server.Uri}v3/index.json", allowInsecureConnectionsValue: "true"); string index = $@" {{ @@ -374,11 +368,8 @@ public void SearchCommand_VerbosityQuietTest() using (MockServer server = new MockServer()) using (SimpleTestPathContext config = new SimpleTestPathContext()) { - CommandRunner.Run( - nugetexe, - config.WorkingDirectory, - $"source add -name mockSource -source {server.Uri}v3/index.json -configfile {config.NuGetConfig}", - testOutputHelper: _testOutputHelper); + // Arrange the NuGet.Config file + config.Settings.AddSource("mockSource", $"{server.Uri}v3/index.json", allowInsecureConnectionsValue: "true"); string index = $@" {{ @@ -491,11 +482,8 @@ public void SearchCommand_TakeOptionTest() using (MockServer server = new MockServer()) using (SimpleTestPathContext config = new SimpleTestPathContext()) { - CommandRunner.Run( - nugetexe, - config.WorkingDirectory, - $"source add -name mockSource -source {server.Uri}v3/index.json -configfile {config.NuGetConfig}", - testOutputHelper: _testOutputHelper); + // Arrange the NuGet.Config file + config.Settings.AddSource("mockSource", $"{server.Uri}v3/index.json", allowInsecureConnectionsValue: "true"); string index = $@" {{ @@ -656,11 +644,8 @@ public void SearchCommand_SourceOptionTest() using (MockServer server = new MockServer()) using (SimpleTestPathContext config = new SimpleTestPathContext()) { - CommandRunner.Run( - nugetexe, - config.WorkingDirectory, - $"source add -name mockSource -source {server.Uri}v3/index.json -configfile {config.NuGetConfig}", - testOutputHelper: _testOutputHelper); + // Arrange the NuGet.Config file + config.Settings.AddSource("mockSource", $"{server.Uri}v3/index.json", allowInsecureConnectionsValue: "true"); string index = $@" {{ @@ -769,11 +754,8 @@ public void SearchCommand_MultipleSearchTermsTest() using (MockServer server = new MockServer()) using (SimpleTestPathContext config = new SimpleTestPathContext()) { - CommandRunner.Run( - nugetexe, - config.WorkingDirectory, - $"source add -name mockSource -source {server.Uri}v3/index.json -configfile {config.NuGetConfig}", - testOutputHelper: _testOutputHelper); + // Arrange the NuGet.Config file + config.Settings.AddSource("mockSource", $"{server.Uri}v3/index.json", allowInsecureConnectionsValue: "true"); string index = $@" {{ @@ -882,11 +864,8 @@ public void SearchCommand_NoResultsFoundTest() using (MockServer server = new MockServer()) using (SimpleTestPathContext config = new SimpleTestPathContext()) { - CommandRunner.Run( - nugetexe, - config.WorkingDirectory, - $"source add -name mockSource -source {server.Uri}v3/index.json -configfile {config.NuGetConfig}", - testOutputHelper: _testOutputHelper); + // Arrange the NuGet.Config file + config.Settings.AddSource("mockSource", $"{server.Uri}v3/index.json", allowInsecureConnectionsValue: "true"); string index = $@" {{ @@ -947,19 +926,15 @@ public void SearchCommand_NoResultsFoundTest() } [Fact] - public void SearchCommand_WhenSearchWithHttpSource_Warns() + public void SearchCommand_WhenSearchWithHttpSource_DisplaysAnErrorMessage() { // Arrange string nugetexe = Util.GetNuGetExePath(); using MockServer server = new MockServer(); + PackageSource source = new PackageSource(server.Uri + "v3/index.json", "mockSource"); using SimpleTestPathContext config = new SimpleTestPathContext(); - CommandRunner.Run( - nugetexe, - config.WorkingDirectory, - $"source add -name mockSource -source {server.Uri}v3/index.json -configfile {config.NuGetConfig}", - testOutputHelper: _testOutputHelper); - + config.Settings.AddSource("mockSource", $"{server.Uri}v3/index.json"); string index = $@" {{ ""version"": ""3.0.0"", @@ -993,7 +968,7 @@ public void SearchCommand_WhenSearchWithHttpSource_Warns() }}"; server.Get.Add("/search/query?q=json&skip=0&take=20&prerelease=false&semVerLevel=2.0.0", r => queryResult); - + string expectedErrorMessage = string.Format(NuGetResources.Error_HttpSource_Single, "search", source); server.Start(); // Act @@ -1012,34 +987,28 @@ public void SearchCommand_WhenSearchWithHttpSource_Warns() server.Stop(); // Assert - Assert.True(result.Success, $"{result.AllOutput}"); - Assert.Contains("No results found.", $"{result.AllOutput}"); - Assert.DoesNotContain(">", $"{result.AllOutput}"); - Assert.Contains("WARNING: You are running the 'search' operation with an 'HTTP' source", result.AllOutput); + Assert.False(result.Success); + Assert.Contains(expectedErrorMessage, result.AllOutput); } [Theory] [InlineData("true", false)] [InlineData("false", true)] - public void SearchCommand_WhenSearchWithHttpSourcesWithAllowInsecureConnections_WarnsCorrectly(string allowInsecureConnections, bool isHttpWarningExpected) + public void SearchCommand_WhenSearchWithHttpSourcesWithAllowInsecureConnections_DisplaysErrorCorrectly(string allowInsecureConnections, bool isHttpWarningExpected) { // Arrange string nugetexe = Util.GetNuGetExePath(); using MockServer server1 = new MockServer(); + PackageSource source1 = new PackageSource(server1.Uri + "v3/index.json", "http-feed1"); using MockServer server2 = new MockServer(); + PackageSource source2 = new PackageSource(server2.Uri + "v3/index.json", "http-feed2"); + List sources = new List() { source1, source2 }; using SimpleTestPathContext config = new SimpleTestPathContext(); // Arrange the NuGet.Config file - string nugetConfigContent = -$@" - - - - - -"; - File.WriteAllText(config.NuGetConfig, nugetConfigContent); + config.Settings.AddSource("http-feed1", $"{server1.Uri}v3/index.json", allowInsecureConnectionsValue: allowInsecureConnections); + config.Settings.AddSource("http-feed2", $"{server2.Uri}v3/index.json", allowInsecureConnectionsValue: allowInsecureConnections); string index = $@" {{ @@ -1130,23 +1099,18 @@ public void SearchCommand_WhenSearchWithHttpSourcesWithAllowInsecureConnections_ server2.Stop(); // Assert - Assert.True(result.Success, $"{result.AllOutput}"); - Assert.Contains("No results found.", $"{result.AllOutput}"); - Assert.DoesNotContain(">", $"{result.AllOutput}"); - - string actualOutputWithoutSpace = SettingsTestUtils.RemoveWhitespace(result.Output); - string expectedWarningWithoutSpace = SettingsTestUtils.RemoveWhitespace($@" -WARNING: You are running the 'search' operation with 'HTTP' sources: -http-feed1 -http-feed2 -Non-HTTPS access will be removed in a future version. Consider migrating to 'HTTPS' sources."); + string expectedError = string.Format(CultureInfo.CurrentCulture, NuGetResources.Error_HttpSources_Multiple, "search", Environment.NewLine + string.Join(Environment.NewLine, sources.Select(e => e.Name))); + if (isHttpWarningExpected) { - Assert.Contains(expectedWarningWithoutSpace, actualOutputWithoutSpace); + Assert.False(result.Success); + Assert.Contains(expectedError, result.AllOutput); } else { - Assert.DoesNotContain(expectedWarningWithoutSpace, actualOutputWithoutSpace); + Assert.True(result.Success); + Assert.Contains("No results found.", $"{result.AllOutput}"); + Assert.DoesNotContain(expectedError, result.AllOutput); } } } diff --git a/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/FeedPackagePruningTests.cs b/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/FeedPackagePruningTests.cs index 61ecb77ca94..bb21c168ec8 100644 --- a/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/FeedPackagePruningTests.cs +++ b/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/FeedPackagePruningTests.cs @@ -74,7 +74,7 @@ await SimpleTestPackageUtility.CreatePackagesAsync( server.Start(); var feedUrl = server.Uri + "index.json"; - + pathContext.Settings.AddSource(feedUrl, feedUrl, allowInsecureConnectionsValue: "true"); // Restore x 2.0.0 and populate the http cache var r = Util.Restore(pathContext, projectA.ProjectPath, 0, _testOutputHelper, "-Source", feedUrl); diff --git a/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/NetworkCallCountTest.cs b/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/NetworkCallCountTest.cs index c28b7f8fd9d..5aed7e58086 100644 --- a/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/NetworkCallCountTest.cs +++ b/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/NetworkCallCountTest.cs @@ -100,7 +100,7 @@ public void NetworkCallCount_RestoreLargePackagesConfigWithMultipleSourcesWithAl var section = SimpleTestSettingsContext.GetOrAddSection(settings.XML, "packageSources"); for (int i = 0; i < sources.Count; i++) { - SimpleTestSettingsContext.AddEntry(section, $"source{i}", sources[i]); + SimpleTestSettingsContext.AddEntry(section, $"source{i}", sources[i], "allowInsecureConnections", "true"); } settings.Save(); @@ -236,7 +236,7 @@ public void NetworkCallCount_RestoreLargePackagesConfigWithMultipleSourcesWithPa var section = SimpleTestSettingsContext.GetOrAddSection(settings.XML, "packageSources"); for (int i = 0; i < sources.Count; i++) { - SimpleTestSettingsContext.AddEntry(section, $"source{i}", sources[i]); + SimpleTestSettingsContext.AddEntry(section, $"source{i}", sources[i], "allowInsecureConnections", "true"); } settings.Save(); @@ -368,7 +368,7 @@ public void NetworkCallCount_RestoreLargePackagesConfigWithMultipleSourcesMainly var section = SimpleTestSettingsContext.GetOrAddSection(settings.XML, "packageSources"); for (int i = 0; i < sources.Count; i++) { - SimpleTestSettingsContext.AddEntry(section, $"source{i}", sources[i]); + SimpleTestSettingsContext.AddEntry(section, $"source{i}", sources[i], "allowInsecureConnections", "true"); } settings.Save(); @@ -497,7 +497,7 @@ public void NetworkCallCount_RestoreLargePackagesConfigWithMultipleSourcesMainly var section = SimpleTestSettingsContext.GetOrAddSection(settings.XML, "packageSources"); for (int i = 0; i < sources.Count; i++) { - SimpleTestSettingsContext.AddEntry(section, $"source{i}", sources[i]); + SimpleTestSettingsContext.AddEntry(section, $"source{i}", sources[i], "allowInsecureConnections", "true"); } settings.Save(); @@ -584,7 +584,7 @@ public void NetworkCallCount_CancelPackageDownloadForV3() var section = SimpleTestSettingsContext.GetOrAddSection(settings.XML, "packageSources"); for (int i = 0; i < sources.Count; i++) { - SimpleTestSettingsContext.AddEntry(section, $"source{i}", sources[i]); + SimpleTestSettingsContext.AddEntry(section, $"source{i}", sources[i], "allowInsecureConnections", "true"); } settings.Save(); @@ -680,7 +680,7 @@ public void NetworkCallCount_CancelPackageDownloadForV2() var section = SimpleTestSettingsContext.GetOrAddSection(settings.XML, "packageSources"); for (int i = 0; i < sources.Count; i++) { - SimpleTestSettingsContext.AddEntry(section, $"source{i}", sources[i]); + SimpleTestSettingsContext.AddEntry(section, $"source{i}", sources[i], "allowInsecureConnections", "true"); } settings.Save(); @@ -775,7 +775,7 @@ public void NetworkCallCount_RestoreSolutionMultipleSourcesV2V3AndLocal() var section = SimpleTestSettingsContext.GetOrAddSection(settings.XML, "packageSources"); for (int i = 0; i < sources.Count; i++) { - SimpleTestSettingsContext.AddEntry(section, $"source{i}", sources[i]); + SimpleTestSettingsContext.AddEntry(section, $"source{i}", sources[i], "allowInsecureConnections", "true"); } settings.Save(); @@ -849,7 +849,7 @@ public void NetworkCallCount_InstallVersionFromV2() var section = SimpleTestSettingsContext.GetOrAddSection(settings.XML, "packageSources"); for (int i = 0; i < sources.Count; i++) { - SimpleTestSettingsContext.AddEntry(section, $"source{i}", sources[i]); + SimpleTestSettingsContext.AddEntry(section, $"source{i}", sources[i], "allowInsecureConnections", "true"); } settings.Save(); @@ -921,7 +921,7 @@ public void NetworkCallCount_InstallVersionFromV3() var section = SimpleTestSettingsContext.GetOrAddSection(settings.XML, "packageSources"); for (int i = 0; i < sources.Count; i++) { - SimpleTestSettingsContext.AddEntry(section, $"source{i}", sources[i]); + SimpleTestSettingsContext.AddEntry(section, $"source{i}", sources[i], "allowInsecureConnections", "true"); } settings.Save(); @@ -995,7 +995,7 @@ public void NetworkCallCount_InstallLatestFromV2() var section = SimpleTestSettingsContext.GetOrAddSection(settings.XML, "packageSources"); for (int i = 0; i < sources.Count; i++) { - SimpleTestSettingsContext.AddEntry(section, $"source{i}", sources[i]); + SimpleTestSettingsContext.AddEntry(section, $"source{i}", sources[i], "allowInsecureConnections", "true"); } settings.Save(); @@ -1065,7 +1065,7 @@ public void NetworkCallCount_InstallLatestFromV3() var section = SimpleTestSettingsContext.GetOrAddSection(settings.XML, "packageSources"); for (int i = 0; i < sources.Count; i++) { - SimpleTestSettingsContext.AddEntry(section, $"source{i}", sources[i]); + SimpleTestSettingsContext.AddEntry(section, $"source{i}", sources[i], "allowInsecureConnections", "true"); } settings.Save(); @@ -1139,7 +1139,7 @@ public void NetworkCallCount_RestoreSolutionMultipleSourcesV2V3() var section = SimpleTestSettingsContext.GetOrAddSection(settings.XML, "packageSources"); for (int i = 0; i < sources.Count; i++) { - SimpleTestSettingsContext.AddEntry(section, $"source{i}", sources[i]); + SimpleTestSettingsContext.AddEntry(section, $"source{i}", sources[i], "allowInsecureConnections", "true"); } settings.Save(); @@ -1207,7 +1207,7 @@ public void NetworkCallCount_RestoreSolutionMultipleSourcesTwoV2() var section = SimpleTestSettingsContext.GetOrAddSection(settings.XML, "packageSources"); for (int i = 0; i < sources.Count; i++) { - SimpleTestSettingsContext.AddEntry(section, $"source{i}", sources[i]); + SimpleTestSettingsContext.AddEntry(section, $"source{i}", sources[i], "allowInsecureConnections", "true"); } settings.Save(); @@ -1288,7 +1288,7 @@ public void NetworkCallCount_RestoreSolutionMultipleSourcesTwoV3() var section = SimpleTestSettingsContext.GetOrAddSection(settings.XML, "packageSources"); for (int i = 0; i < sources.Count; i++) { - SimpleTestSettingsContext.AddEntry(section, $"source{i}", sources[i]); + SimpleTestSettingsContext.AddEntry(section, $"source{i}", sources[i], "allowInsecureConnections", "true"); } settings.Save(); @@ -1355,7 +1355,7 @@ public void NetworkCallCount_RestoreSolutionV3WithoutFlatContainer() var section = SimpleTestSettingsContext.GetOrAddSection(settings.XML, "packageSources"); for (int i = 0; i < sources.Count; i++) { - SimpleTestSettingsContext.AddEntry(section, $"source{i}", sources[i]); + SimpleTestSettingsContext.AddEntry(section, $"source{i}", sources[i], "allowInsecureConnections", "true"); } settings.Save(); @@ -1421,7 +1421,7 @@ public void NetworkCallCount_RestoreSolutionWithPackagesConfigAndProjectJsonV3() var section = SimpleTestSettingsContext.GetOrAddSection(settings.XML, "packageSources"); for (int i = 0; i < sources.Count; i++) { - SimpleTestSettingsContext.AddEntry(section, $"source{i}", sources[i]); + SimpleTestSettingsContext.AddEntry(section, $"source{i}", sources[i], "allowInsecureConnections", "true"); } settings.Save(); @@ -1486,7 +1486,7 @@ public void NetworkCallCount_RestoreSolutionWithPackagesConfigAndProjectJsonV2() var section = SimpleTestSettingsContext.GetOrAddSection(settings.XML, "packageSources"); for (int i = 0; i < sources.Count; i++) { - SimpleTestSettingsContext.AddEntry(section, $"source{i}", sources[i]); + SimpleTestSettingsContext.AddEntry(section, $"source{i}", sources[i], "allowInsecureConnections", "true"); } settings.Save(); diff --git a/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/NuGetDeleteCommandTest.cs b/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/NuGetDeleteCommandTest.cs index e0cafe2df25..04b8d5a54f4 100644 --- a/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/NuGetDeleteCommandTest.cs +++ b/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/NuGetDeleteCommandTest.cs @@ -181,11 +181,15 @@ public void DeleteCommand_DeleteFromHttpSource() deleteRequestIsCalled = true; return HttpStatusCode.OK; }); + using SimpleTestPathContext pathContext = new SimpleTestPathContext(); + pathContext.Settings.AddSource("http-feed", $"{server.Uri}nuget", allowInsecureConnectionsValue: "true"); + var configFileName = "nuget.config"; + var configFilePath = Path.Combine(pathContext.WorkingDirectory, configFileName); // Act string[] args = new string[] { "delete", "testPackage1", "1.1.0", - "-Source", server.Uri + "nuget", "-NonInteractive" }; + "-Source", server.Uri + "nuget", "-NonInteractive", "-ConfigFile " + configFilePath }; var r = CommandRunner.Run( nugetexe, @@ -218,6 +222,10 @@ public void DeleteCommand_WithApiKeyAsThirdArgument() }); server.Start(); + using SimpleTestPathContext pathContext = new SimpleTestPathContext(); + pathContext.Settings.AddSource("http-feed", $"{server.Uri}nuget", allowInsecureConnectionsValue: "true"); + var configFileName = "nuget.config"; + var configFilePath = Path.Combine(pathContext.WorkingDirectory, configFileName); // Act var args = new[] { @@ -227,7 +235,8 @@ public void DeleteCommand_WithApiKeyAsThirdArgument() testApiKey, "-Source", server.Uri + "nuget", - "-NonInteractive" + "-NonInteractive", + "-ConfigFile " + configFilePath }; var result = CommandRunner.Run( @@ -263,6 +272,10 @@ public void DeleteCommand_WithApiKeyAsNamedArgument() }); server.Start(); + using SimpleTestPathContext pathContext = new SimpleTestPathContext(); + pathContext.Settings.AddSource("http-feed", $"{server.Uri}nuget", allowInsecureConnectionsValue: "true"); + var configFileName = "nuget.config"; + var configFilePath = Path.Combine(pathContext.WorkingDirectory, configFileName); // Act var args = new[] @@ -275,7 +288,8 @@ public void DeleteCommand_WithApiKeyAsNamedArgument() testApiKey, "-Source", server.Uri + "nuget", - "-NonInteractive" + "-NonInteractive", + "-ConfigFIle " + configFilePath }; var result = CommandRunner.Run( @@ -336,7 +350,7 @@ public void DeleteCommand_WithApiKeyFromConfig(string configKeyFormatString) var source = server.Uri + "index.json"; var packageSourcesSection = SimpleTestSettingsContext.GetOrAddSection(settings.XML, "packageSources"); - SimpleTestSettingsContext.AddEntry(packageSourcesSection, $"MockServer", source); + SimpleTestSettingsContext.AddEntry(packageSourcesSection, $"MockServer", source, "AllowInsecureConnections", "true"); var configKey = string.Format(configKeyFormatString, server.Uri); var configValue = Configuration.EncryptionUtility.EncryptString(testApiKey); @@ -380,7 +394,10 @@ public void DeleteCommand_ShowsServerWarnings(string firstServerWarning, string using (var server = new MockServer()) { server.Start(); - + using SimpleTestPathContext pathContext = new SimpleTestPathContext(); + pathContext.Settings.AddSource("http-feed", $"{server.Uri}nuget", allowInsecureConnectionsValue: "true"); + var configFileName = "nuget.config"; + var configFilePath = Path.Combine(pathContext.WorkingDirectory, configFileName); server.Delete.Add("/nuget/testPackage1/1.1", request => HttpStatusCode.OK); server.AddServerWarnings(serverWarnings); @@ -388,7 +405,7 @@ public void DeleteCommand_ShowsServerWarnings(string firstServerWarning, string // Act string[] args = new string[] { "delete", "testPackage1", "1.1.0", - "-Source", server.Uri + "nuget", "-NonInteractive" }; + "-Source", server.Uri + "nuget", "-NonInteractive", "-ConfigFile " + configFilePath }; var r = CommandRunner.Run( nugetexe, @@ -414,10 +431,52 @@ public void DeleteCommand_Failure_InvalidArguments(string args) Util.TestCommandInvalidArguments(args); } - [Theory] - [InlineData("true", false)] - [InlineData("false", true)] - public void DeleteCommand_WhenDeleteWithHttpSourceAndAllowInsecureConnections_WarnsCorrectly(string allowInsecureConnections, bool isHttpWarningExpected) + [Fact] + public void DeleteCommand_WhenDeleteWithHttpSourceAndAllowInsecureConnectionsFalse_Errors() + { + var nugetexe = Util.GetNuGetExePath(); + + // Arrange + using (var server = new MockServer()) + { + server.Start(); + + server.Delete.Add("/nuget/testPackage1/1.1", request => + { + return HttpStatusCode.OK; + }); + + using SimpleTestPathContext config = new SimpleTestPathContext(); + + // Arrange the NuGet.Config file + string nugetConfigContent = + $@" + + + + +"; + File.WriteAllText(config.NuGetConfig, nugetConfigContent); + + // Act + string[] args = new string[] { + "delete", "testPackage1", "1.1.0", + "-Source", server.Uri + "nuget", + "-ConfigFile", config.NuGetConfig, "-NonInteractive" }; + + var result = CommandRunner.Run( + nugetexe, + Directory.GetCurrentDirectory(), + string.Join(" ", args)); + + // Assert + Assert.Equal(1, result.ExitCode); + Assert.Contains($"{server.Uri}nuget", result.Errors); + } + } + + [Fact] + public void DeleteCommand_WhenDeleteWithHttpSourceAndAllowInsecureConnectionsTrue_Succeeds() { var nugetexe = Util.GetNuGetExePath(); @@ -440,7 +499,7 @@ public void DeleteCommand_WhenDeleteWithHttpSourceAndAllowInsecureConnections_Wa $@" - + "; File.WriteAllText(config.NuGetConfig, nugetConfigContent); @@ -451,24 +510,15 @@ public void DeleteCommand_WhenDeleteWithHttpSourceAndAllowInsecureConnections_Wa "-Source", server.Uri + "nuget", "-ConfigFile", config.NuGetConfig, "-NonInteractive" }; - var r = CommandRunner.Run( + var result = CommandRunner.Run( nugetexe, Directory.GetCurrentDirectory(), string.Join(" ", args)); // Assert - Assert.Equal(0, r.ExitCode); + Assert.Equal(0, result.ExitCode); Assert.True(deleteRequestIsCalled); - - string expectedWarning = "WARNING: You are running the 'delete' operation with an 'HTTP' source"; - if (isHttpWarningExpected) - { - Assert.Contains(expectedWarning, r.AllOutput); - } - else - { - Assert.DoesNotContain(expectedWarning, r.AllOutput); - } + Assert.DoesNotContain($"{server.Uri}nuget", result.Errors); } } diff --git a/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/NuGetInstallCommandTest.cs b/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/NuGetInstallCommandTest.cs index b0a6356ce47..cfb43ae05df 100644 --- a/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/NuGetInstallCommandTest.cs +++ b/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/NuGetInstallCommandTest.cs @@ -2042,7 +2042,7 @@ public void InstallCommand_PackageSourceMappingFilter_Cli_FromPackagesConfigFile } [Fact] - public async Task Install_WithPackagesConfigAndHttpSource_Warns() + public async Task Install_WithPackagesConfigAndHttpSource_Errors() { // Arrange using var pathContext = new SimpleTestPathContext(); @@ -2080,18 +2080,15 @@ public async Task Install_WithPackagesConfigAndHttpSource_Warns() // Assert result.Success.Should().BeTrue(); - result.AllOutput.Should().Contain($"Added package 'A.1.0.0' to folder '{pathContext.PackagesV2}'"); - result.AllOutput.Should().Contain("You are running the 'restore' operation with an 'HTTP' source, 'http://api.source/api/v2'. Non-HTTPS access will be removed in a future version. Consider migrating to an 'HTTPS' source."); + result.Errors.Should().Contain("http://api.source/api/v2"); } [Theory] - [InlineData("false", true)] - [InlineData("FALSE", true)] - [InlineData("invalidString", true)] - [InlineData("", true)] - [InlineData("true", false)] - [InlineData("TRUE", false)] - public async Task Install_PackagesConfigWithHttpSourceAndAllowInsecureConnections_WarnsCorrectly(string allowInsecureConnections, bool hasHttpWarning) + [InlineData("false")] + [InlineData("FALSE")] + [InlineData("invalidString")] + [InlineData("")] + public async Task Install_PackagesConfigWithHttpSourceAndAllowInsecureConnectionsFalse_Errors(string allowInsecureConnections) { // Arrange using var pathContext = new SimpleTestPathContext(); @@ -2128,21 +2125,60 @@ public async Task Install_PackagesConfigWithHttpSourceAndAllowInsecureConnection CommandRunnerResult result = RunInstall(pathContext, config, expectedExitCode: 0, additionalArgs: args); // Assert - string formatString = "You are running the 'restore' operation with an 'HTTP' source, '{0}'. Non-HTTPS access will be removed in a future version. Consider migrating to an 'HTTPS'"; - string warningForHttpSource = string.Format(formatString, "http://api.source/index.json"); - string warningForHttpsSource = string.Format(formatString, "https://api.source/index.json"); result.Success.Should().BeTrue(); - result.AllOutput.Should().Contain($"Added package 'A.1.0.0' to folder '{pathContext.PackagesV2}'"); - Assert.DoesNotContain(warningForHttpsSource, result.Output); - if (hasHttpWarning) - { - Assert.Contains(warningForHttpSource, result.Output); - } - else + + Assert.DoesNotContain("https://api.source/index.json", result.Errors); + + Assert.Contains("http://api.source/index.json", result.Errors); + + } + + [Theory] + [InlineData("true")] + [InlineData("TRUE")] + public async Task Install_PackagesConfigWithHttpSourceAndAllowInsecureConnections_WarnsCorrectly(string allowInsecureConnections) + { + // Arrange + using var pathContext = new SimpleTestPathContext(); + // Set up solution, project, and packages + var solution = new SimpleTestSolutionContext(pathContext.SolutionRoot); + var packageA = new SimpleTestPackageContext("a", "1.0.0"); + await SimpleTestPackageUtility.CreateFolderFeedV3Async(pathContext.PackageSource, packageA); + var packageAPath = Path.Combine(pathContext.PackageSource, packageA.Id, packageA.Version, packageA.PackageName); + + pathContext.Settings.AddSource("http-feed", "http://api.source/index.json", allowInsecureConnections); + pathContext.Settings.AddSource("https-feed", "https://api.source/index.json", allowInsecureConnections); + + var projectB = new SimpleTestProjectContext( + "b", + ProjectStyle.PackagesConfig, + pathContext.SolutionRoot); + + Util.CreateFile(Path.GetDirectoryName(projectB.ProjectPath), "packages.config", +@" + +"); + + solution.Projects.Add(projectB); + solution.Create(pathContext.SolutionRoot); + + var config = Path.Combine(Path.GetDirectoryName(projectB.ProjectPath), "packages.config"); + var args = new string[] { - Assert.DoesNotContain(warningForHttpSource, result.Output); ; - } + "-OutputDirectory", + pathContext.PackagesV2 + }; + + // Act + CommandRunnerResult result = RunInstall(pathContext, config, expectedExitCode: 0, additionalArgs: args); + + // Assert + + result.Success.Should().BeTrue(); + result.AllOutput.Should().Contain($"Added package 'A.1.0.0' to folder '{pathContext.PackagesV2}'"); + Assert.DoesNotContain("http://api.source/index.json", result.Errors); + Assert.DoesNotContain("https://api.source/index.json", result.Errors); ; } [Fact] diff --git a/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/NuGetListCommandTest.cs b/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/NuGetListCommandTest.cs index 9dcf366dde3..7d6b808ce1f 100644 --- a/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/NuGetListCommandTest.cs +++ b/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/NuGetListCommandTest.cs @@ -9,6 +9,7 @@ using System.Text; using FluentAssertions; using NuGet.Common; +using NuGet.Configuration; using NuGet.Packaging; using NuGet.Test.Utility; using Test.Utility; @@ -183,7 +184,7 @@ public void ListCommand_Simple() var nugetexe = Util.GetNuGetExePath(); using (var packageDirectory = TestDirectory.Create()) - using (var randomTestFolder = TestDirectory.Create()) + using (SimpleTestPathContext config = new SimpleTestPathContext()) { // Arrange var packageFileName1 = Util.CreateTestPackage("testPackage1", "1.1.0", packageDirectory); @@ -208,12 +209,13 @@ public void ListCommand_Simple() server.Get.Add("/nuget", r => "OK"); server.Start(); + config.Settings.AddSource("mockServer", $"{server.Uri}nuget", allowInsecureConnectionsValue: "true"); // Act var args = "list test -Source " + server.Uri + "nuget"; var result = CommandRunner.Run( nugetexe, - randomTestFolder, + config.WorkingDirectory, args); server.Stop(); @@ -223,7 +225,7 @@ public void ListCommand_Simple() // verify that only package id & version is displayed var expectedOutput = "testPackage1 1.1.0" + Environment.NewLine + "testPackage2 2.1.0" + Environment.NewLine; - Assert.Equal(expectedOutput, RemoveDeprecationWarning(RemoveHttpWarning(result.Output))); + Assert.Equal(expectedOutput, RemoveDeprecationWarning(result.Output)); Assert.Contains("$filter=IsLatestVersion", searchRequest); Assert.Contains("searchTerm='test", searchRequest); @@ -239,7 +241,7 @@ public void ListCommand_OnlyShowListed() var nugetexe = Util.GetNuGetExePath(); using (var packageDirectory = TestDirectory.Create()) - using (var randomTestFolder = TestDirectory.Create()) + using (SimpleTestPathContext config = new SimpleTestPathContext()) { // Arrange var packageFileName1 = Util.CreateTestPackage("testPackage1", "1.1.0", packageDirectory); @@ -264,12 +266,13 @@ public void ListCommand_OnlyShowListed() server.Get.Add("/nuget", r => "OK"); server.Start(); + config.Settings.AddSource("mockServer", $"{server.Uri}nuget", allowInsecureConnectionsValue: "true"); // Act var args = "list test -Source " + server.Uri + "nuget"; var r1 = CommandRunner.Run( nugetexe, - randomTestFolder, + config.WorkingDirectory, args); server.Stop(); @@ -279,7 +282,7 @@ public void ListCommand_OnlyShowListed() // verify that only testPackage2 is listed since the package testPackage1 // is not listed. var expectedOutput = "testPackage2 2.1.0" + Environment.NewLine; - Assert.Equal(expectedOutput, RemoveDeprecationWarning(RemoveHttpWarning(r1.Output))); + Assert.Equal(expectedOutput, RemoveDeprecationWarning(r1.Output)); Assert.Contains("$filter=IsLatestVersion", searchRequest); Assert.Contains("searchTerm='test", searchRequest); @@ -299,7 +302,7 @@ public void ListCommand_IncludeDelisted() var nugetexe = Util.GetNuGetExePath(); using (var packageDirectory = TestDirectory.Create()) - using (var randomTestFolder = TestDirectory.Create()) + using (SimpleTestPathContext config = new SimpleTestPathContext()) { // Arrange var packageFileName1 = Util.CreateTestPackage("testPackage1", "1.1.0", packageDirectory); @@ -324,12 +327,13 @@ public void ListCommand_IncludeDelisted() server.Get.Add("/nuget", r => "OK"); server.Start(); + config.Settings.AddSource("mockServer", $"{server.Uri}nuget", allowInsecureConnectionsValue: "true"); // Act var args = "list test -IncludeDelisted -Source " + server.Uri + "nuget"; var r1 = CommandRunner.Run( nugetexe, - randomTestFolder, + config.WorkingDirectory, args); server.Stop(); @@ -340,7 +344,7 @@ public void ListCommand_IncludeDelisted() var expectedOutput = "testPackage1 1.1.0" + Environment.NewLine + "testPackage2 2.1.0" + Environment.NewLine; - Assert.Equal(expectedOutput, RemoveDeprecationWarning(RemoveHttpWarning(r1.Output))); + Assert.Equal(expectedOutput, RemoveDeprecationWarning(r1.Output)); Assert.Contains("$filter=IsLatestVersion", searchRequest); Assert.Contains("searchTerm='test", searchRequest); @@ -356,7 +360,7 @@ public void ListCommand_VerboseOutput() var nugetexe = Util.GetNuGetExePath(); using (var packageDirectory = TestDirectory.Create()) - using (var randomTestFolder = TestDirectory.Create()) + using (SimpleTestPathContext config = new SimpleTestPathContext()) { // Arrange var packageFileName1 = Util.CreateTestPackage("testPackage1", "1.1.0", packageDirectory); @@ -381,12 +385,13 @@ public void ListCommand_VerboseOutput() server.Get.Add("/nuget", r => "OK"); server.Start(); + config.Settings.AddSource("mockServer", $"{server.Uri}nuget", allowInsecureConnectionsValue: "true"); // Act var args = "list test -Verbosity detailed -Source " + server.Uri + "nuget"; var r1 = CommandRunner.Run( nugetexe, - randomTestFolder, + config.WorkingDirectory, args); server.Stop(); @@ -412,7 +417,7 @@ public void ListCommand_AllVersions() var nugetexe = Util.GetNuGetExePath(); using (var packageDirectory = TestDirectory.Create()) - using (var randomTestFolder = TestDirectory.Create()) + using (SimpleTestPathContext config = new SimpleTestPathContext()) { // Arrange var packageFileName1 = Util.CreateTestPackage("testPackage1", "1.1.0", packageDirectory); @@ -437,12 +442,13 @@ public void ListCommand_AllVersions() server.Get.Add("/nuget", r => "OK"); server.Start(); + config.Settings.AddSource("mockServer", $"{server.Uri}nuget", allowInsecureConnectionsValue: "true"); // Act var args = "list test -AllVersions -Source " + server.Uri + "nuget"; var r1 = CommandRunner.Run( nugetexe, - randomTestFolder, + config.WorkingDirectory, args); server.Stop(); @@ -452,7 +458,7 @@ public void ListCommand_AllVersions() // verify that the output is detailed var expectedOutput = "testPackage1 1.1.0" + Environment.NewLine + "testPackage2 2.1.0" + Environment.NewLine; - Assert.Equal(expectedOutput, RemoveDeprecationWarning(RemoveHttpWarning(r1.Output))); + Assert.Equal(expectedOutput, RemoveDeprecationWarning(r1.Output)); Assert.DoesNotContain("$filter", searchRequest); Assert.Contains("searchTerm='test", searchRequest); @@ -496,6 +502,7 @@ public void ListCommand_Prerelease() server.Get.Add("/nuget", r => "OK"); server.Start(); + pathContext.Settings.AddSource("mockServer", $"{server.Uri}nuget", allowInsecureConnectionsValue: "true"); // Act var args = "list test -Prerelease -Source " + server.Uri + "nuget"; @@ -511,7 +518,7 @@ public void ListCommand_Prerelease() // verify that the output is detailed var expectedOutput = "testPackage1 1.1.0" + Environment.NewLine + "testPackage2 2.1.0" + Environment.NewLine; - Assert.Equal(expectedOutput, RemoveDeprecationWarning(RemoveHttpWarning(r1.Output))); + Assert.Equal(expectedOutput, RemoveDeprecationWarning(r1.Output)); Assert.Contains("$filter=IsAbsoluteLatestVersion", searchRequest); Assert.Contains("searchTerm='test", searchRequest); @@ -555,6 +562,7 @@ public void ListCommand_AllVersionsPrerelease() server.Get.Add("/nuget", r => "OK"); server.Start(); + pathContext.Settings.AddSource("mockServer", $"{server.Uri}nuget", allowInsecureConnectionsValue: "true"); // Act var args = "list test -AllVersions -Prerelease -Source " + server.Uri + "nuget"; @@ -570,7 +578,7 @@ public void ListCommand_AllVersionsPrerelease() // verify that the output is detailed var expectedOutput = "testPackage1 1.1.0" + Environment.NewLine + "testPackage2 2.1.0" + Environment.NewLine; - RemoveDeprecationWarning(RemoveHttpWarning(r1.Output)).Should().Be(expectedOutput); + RemoveDeprecationWarning(r1.Output).Should().Be(expectedOutput); Assert.DoesNotContain("$filter", searchRequest); Assert.Contains("searchTerm='test", searchRequest); @@ -652,6 +660,7 @@ public void ListCommand_SimpleV3() serverV3.Start(); serverV2.Start(); + pathContext.Settings.AddSource("mockServer", $"{serverV3.Uri}index.json", allowInsecureConnectionsValue: "true"); // Act var args = "list test -Source " + serverV3.Uri + "index.json"; @@ -669,7 +678,7 @@ public void ListCommand_SimpleV3() // verify that only package id & version is displayed var expectedOutput = "testPackage1 1.1.0" + Environment.NewLine + "testPackage2 2.1.0" + Environment.NewLine; - Assert.Equal(expectedOutput, RemoveDeprecationWarning(RemoveHttpWarning(result.Output))); + Assert.Equal(expectedOutput, RemoveDeprecationWarning(result.Output)); Assert.Contains("$filter=IsLatestVersion", searchRequest); Assert.Contains("searchTerm='test", searchRequest); @@ -712,6 +721,7 @@ public void ListCommand_SimpleV3_NoListEndpoint() }); serverV3.Start(); + pathContext.Settings.AddSource("mockServer", $"{serverV3.Uri}index.json", allowInsecureConnectionsValue: "true"); // Act var args = "list test -Source " + serverV3.Uri + "index.json"; @@ -766,6 +776,7 @@ public void ListCommand_UnavailableV3() }); serverV3.Start(); + pathContext.Settings.AddSource("mockServer", $"{serverV3.Uri}index.json", allowInsecureConnectionsValue: "true"); // Act var args = "list test -Source " + serverV3.Uri + "index.json"; @@ -1001,7 +1012,7 @@ public void ListCommand_WithAuthenticatedSource_AppliesCredentialsFromSettings() var source = serverV3.Uri + "index.json"; var packageSourcesSection = SimpleTestSettingsContext.GetOrAddSection(settings.XML, "packageSources"); - SimpleTestSettingsContext.AddEntry(packageSourcesSection, "vsts", source, additionalAtrributeName: "protocolVersion", additionalAttributeValue: "3"); + SimpleTestSettingsContext.AddEntry(packageSourcesSection, "vsts", source, additionalAtrributeName: "protocolVersion", additionalAttributeValue: "3", additionalAtrributeName2: "allowInsecureConnections", additionalAttributeValue2: "true"); //var packageSourceCredentialsSection = SimpleTestSettingsContext.GetOrAddSection(settings.XML, "packageSourceCredentials"); SimpleTestSettingsContext.AddPackageSourceCredentialsSection(settings.XML, "vsts", "user", "password", clearTextPassword: true); @@ -1103,7 +1114,7 @@ public void ListCommand_WithAuthenticatedSourceV2_AppliesCredentialsFromSettings var source = $"{serverV3.Uri}api/v2"; var packageSourcesSection = SimpleTestSettingsContext.GetOrAddSection(settings.XML, "packageSources"); - SimpleTestSettingsContext.AddEntry(packageSourcesSection, "vsts", source, additionalAtrributeName: "protocolVersion", additionalAttributeValue: "2"); + SimpleTestSettingsContext.AddEntry(packageSourcesSection, "vsts", source, additionalAtrributeName: "protocolVersion", additionalAttributeValue: "2", additionalAtrributeName2: "allowInsecureConnections", additionalAttributeValue2: "true"); SimpleTestSettingsContext.AddPackageSourceCredentialsSection(settings.XML, "vsts", "user", "password", clearTextPassword: true); settings.Save(); @@ -1128,17 +1139,15 @@ public void ListCommand_WithAuthenticatedSourceV2_AppliesCredentialsFromSettings } } - [PlatformTheory(Platform.Windows)] - [InlineData("true", false)] - [InlineData("false", true)] - public void ListCommand_WhenListWithHttpSourceAndAllowInsecureConnections_WarnsCorrectly(string allowInsecureConnections, bool isHttpWarningExpected) + [PlatformFact(Platform.Windows)] + public void ListCommand_WhenListWithHttpSourceAndAllowInsecureConnectionsFalse_Errors() { var nugetexe = Util.GetNuGetExePath(); // Arrange - using var packageDirectory = TestDirectory.Create(); + using var pathContext = new SimpleTestPathContext(); using var server = new MockServer(); - var packageFileName1 = Util.CreateTestPackage("testPackage1", "1.1.0", packageDirectory); + var packageFileName1 = Util.CreateTestPackage("testPackage1", "1.1.0", pathContext.WorkingDirectory); server.Get.Add("/nuget/$metadata", r => Util.GetMockServerResource()); @@ -1155,40 +1164,72 @@ public void ListCommand_WhenListWithHttpSourceAndAllowInsecureConnections_WarnsC server.Start(); // create the config file - Util.CreateFile(packageDirectory, "nuget.config", $@" - - - - -"); - var configFile = Path.Combine(packageDirectory, "nuget.config"); + pathContext.Settings.AddSource("http-feed", $"{server.Uri}nuget", allowInsecureConnectionsValue: "False"); + + var configFile = Path.Combine(pathContext.WorkingDirectory, "nuget.config"); + PackageSource source = new PackageSource(server.Uri + "nuget", "http-feed"); // Act var args = "list test -ConfigFile " + configFile; var result = CommandRunner.Run( nugetexe, - packageDirectory, + pathContext.WorkingDirectory, args); server.Stop(); // Assert - Assert.Equal(0, result.ExitCode); + Assert.False(result.Success); + Assert.Contains($"{server.Uri}nuget", result.Errors); + } + + [PlatformFact(Platform.Windows)] + public void ListCommand_WhenListWithHttpSourceAndAllowInsecureConnectionsTrue_Succeeds() + { + var nugetexe = Util.GetNuGetExePath(); + + // Arrange + using var pathContext = new SimpleTestPathContext(); + using var server = new MockServer(); + var packageFileName1 = Util.CreateTestPackage("testPackage1", "1.1.0", pathContext.WorkingDirectory); + + server.Get.Add("/nuget/$metadata", r => + Util.GetMockServerResource()); + server.Get.Add("/nuget/Search()", r => + new Action(response => + { + string searchRequest = r.Url.ToString(); + response.ContentType = "application/atom+xml;type=feed;charset=utf-8"; + string feed = server.ToODataFeed(new[] { new FileInfo(packageFileName1) }, "Search"); + MockServer.SetResponseContent(response, feed); + })); + server.Get.Add("/nuget", r => "OK"); + + server.Start(); + + // create the config file + pathContext.Settings.AddSource("http-feed", $"{server.Uri}nuget", allowInsecureConnectionsValue: "True"); + var configFile = Path.Combine(pathContext.WorkingDirectory, "nuget.config"); + PackageSource source = new PackageSource(server.Uri + "nuget", "http-feed"); + + // Act + var args = "list test -ConfigFile " + configFile; + var result = CommandRunner.Run( + nugetexe, + pathContext.WorkingDirectory, + args); + server.Stop(); + + // Assert + Assert.Equal(0, result.ExitCode); + Assert.DoesNotContain($"{server.Uri}nuget", result.Errors); // verify that only package id & version is displayed var expectedOutput = "testPackage1 1.1.0"; Assert.Contains(expectedOutput, result.Output); - if (isHttpWarningExpected) - { - Assert.Contains("WARNING: You are running the 'list' operation with an 'HTTP' source", result.AllOutput); - } - else - { - Assert.DoesNotContain("WARNING: You are running the 'list' operation with an 'HTTP' source", result.AllOutput); - } } [Fact] - public void ListCommand_WhenListWithHttpSources_Warns() + public void ListCommand_WhenListWithHttpSources_DisplaysAnError() { var nugetexe = Util.GetNuGetExePath(); @@ -1226,8 +1267,11 @@ public void ListCommand_WhenListWithHttpSources_Warns() server2.Start(); + PackageSource source1 = new PackageSource(server1.Uri + "nuget", "http-feed1"); + PackageSource source2 = new PackageSource(server2.Uri + "nuget", "http-feed2"); + // Act - var args = "list test -Source " + server1.Uri + "nuget" + " -Source " + server1.Uri + "nuget"; + var args = "list test -Source " + server1.Uri + "nuget" + " -Source " + server2.Uri + "nuget"; var result = CommandRunner.Run( nugetexe, packageDirectory, @@ -1236,12 +1280,11 @@ public void ListCommand_WhenListWithHttpSources_Warns() server2.Stop(); // Assert - Assert.Equal(0, result.ExitCode); + Assert.Equal(1, result.ExitCode); + + Assert.Contains(source1.Source, result.Errors); + Assert.Contains(source2.Source, result.Errors); - // verify that only package id & version is displayed - var expectedOutput = "testPackage1 1.1.0"; - Assert.Contains(expectedOutput, result.Output); - Assert.Contains("WARNING: You are running the 'list' operation with 'HTTP' sources", result.AllOutput); } [Fact] @@ -1270,16 +1313,6 @@ public void ListCommand_CheckDeprecationMessage() } } - private static string RemoveHttpWarning(string input) - { - string[] lines = input.Split( - new string[] { "\r\n", "\r", "\n" }, - StringSplitOptions.None - ); - - return string.Join(Environment.NewLine, lines.Select(e => e).Where(e => !e.StartsWith("WARNING: You are running the"))); - } - private static string RemoveDeprecationWarning(string input) { string[] lines = input.Split( diff --git a/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/NuGetMockServerTests.cs b/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/NuGetMockServerTests.cs index ece10268f09..a0dc28e67d0 100644 --- a/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/NuGetMockServerTests.cs +++ b/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/NuGetMockServerTests.cs @@ -68,7 +68,7 @@ public void MockServer_VerifySessionId(ProjectStyle projectStyle) { ids.Add(context.Request.Headers.Get(ProtocolConstants.SessionId)); }; - + pathContext.Settings.AddSource("http-feed", server.Uri + "nuget", allowInsecureConnectionsValue: "true"); server.Start(); var result = Util.Restore(pathContext, inputPath, 0, _testOutputHelper, "-Source", server.Uri + "nuget"); diff --git a/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/NuGetPushCommandTest.cs b/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/NuGetPushCommandTest.cs index 315725d9618..b7442b082b1 100644 --- a/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/NuGetPushCommandTest.cs +++ b/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/NuGetPushCommandTest.cs @@ -259,6 +259,7 @@ public void PushCommand_PushToServer() using (var packageDirectory = TestDirectory.Create()) { // Arrange + using SimpleTestPathContext pathContext = new SimpleTestPathContext(); var packageFileName = Util.CreateTestPackage("testPackage1", "1.1.0", packageDirectory); string outputFileName = Path.Combine(packageDirectory, "t1.nupkg"); @@ -275,12 +276,13 @@ public void PushCommand_PushToServer() return HttpStatusCode.Created; }); + pathContext.Settings.AddSource("http-feed", $"{server.Uri}push", allowInsecureConnectionsValue: "true"); server.Start(); // Act var result = CommandRunner.Run( nugetexe, - Directory.GetCurrentDirectory(), + pathContext.WorkingDirectory, $"push {packageFileName} -Source {server.Uri}push"); server.Stop(); @@ -303,6 +305,7 @@ public void PushCommand_LogsServerWarningsWhenPresent(string firstServerWarning, // Arrange using (var packageDirectory = TestDirectory.Create()) { + using SimpleTestPathContext pathContext = new SimpleTestPathContext(); var packageFileName = Util.CreateTestPackage("testPackage1", "1.1.0", packageDirectory); using (var server = new MockServer()) { @@ -310,7 +313,7 @@ public void PushCommand_LogsServerWarningsWhenPresent(string firstServerWarning, server.Put.Add("/push", r => HttpStatusCode.Created); server.AddServerWarnings(serverWarnings); - + pathContext.Settings.AddSource("http-feed", $"{server.Uri}push", allowInsecureConnectionsValue: "true"); server.Start(); // Act @@ -318,7 +321,7 @@ public void PushCommand_LogsServerWarningsWhenPresent(string firstServerWarning, {"push", packageFileName, "-Source", server.Uri + "push", "-Apikey", "token"}; var result = CommandRunner.Run( nugetexe, - Directory.GetCurrentDirectory(), + pathContext.WorkingDirectory, string.Join(" ", args)); server.Stop(); @@ -346,18 +349,20 @@ public void PushCommand_PushToServerNoSymbols() using (MockServer server = new MockServer()) { // Arrange + using SimpleTestPathContext pathContext = new SimpleTestPathContext(); string packageFileName = Util.CreateTestPackage("testPackage1", "1.1.0", packageDirectory); string symbolFileName = packageFileName.Replace(".nupkg", ".symbols.nupkg"); File.WriteAllText(symbolFileName, "This must be invalid so symbols would fail if they were actually pushed"); server.Get.Add("/push", r => "OK"); server.Put.Add("/push", r => HttpStatusCode.Created); + pathContext.Settings.AddSource("http-feed", $"{server.Uri}push", allowInsecureConnectionsValue: "true"); server.Start(); // Act CommandRunnerResult result = CommandRunner.Run( Util.GetNuGetExePath(), - Directory.GetCurrentDirectory(), + pathContext.WorkingDirectory, $"push {packageFileName} -Source {server.Uri}push -NoSymbols"); // Assert @@ -374,6 +379,7 @@ public void PushCommand_PushToServerWithSymbols() using (var server = new MockServer()) { // Arrange + using SimpleTestPathContext pathContext = new SimpleTestPathContext(); var packageFileName = Util.CreateTestPackage("testPackage1", "1.1.0", packageDirectory); var symbolFileName = packageFileName.Replace(".nupkg", ".symbols.nupkg"); File.Copy(packageFileName, symbolFileName); @@ -393,7 +399,7 @@ public void PushCommand_PushToServerWithSymbols() ? HttpStatusCode.Created : HttpStatusCode.Unauthorized; }); - + pathContext.Settings.AddSource("http-feed", $"{server.Uri}push", allowInsecureConnectionsValue: "true"); server.Start(); var pushUri = $"{server.Uri}push"; @@ -402,7 +408,7 @@ public void PushCommand_PushToServerWithSymbols() // Act CommandRunnerResult result = CommandRunner.Run( Util.GetNuGetExePath(), - Directory.GetCurrentDirectory(), + pathContext.WorkingDirectory, $"push {packageFileName} -Source {pushUri} -SymbolSource {pushSymbolsUri} -ApiKey PushKey -SymbolApiKey PushSymbolsKey"); // Assert @@ -491,6 +497,7 @@ public void PushCommand_PushTimeoutErrorMessage() using (MockServer server = new MockServer()) { // Arrange + using SimpleTestPathContext pathContext = new SimpleTestPathContext(); string packageFileName = Util.CreateTestPackage("testPackage1", "1.1.0", packageDirectory); server.Get.Add("/push", r => "OK"); server.Put.Add("/push", r => @@ -498,12 +505,13 @@ public void PushCommand_PushTimeoutErrorMessage() System.Threading.Thread.Sleep(2000); return HttpStatusCode.Created; }); + pathContext.Settings.AddSource("http-feed", $"{server.Uri}push", allowInsecureConnectionsValue: "true"); server.Start(); // Act CommandRunnerResult result = CommandRunner.Run( Util.GetNuGetExePath(), - Directory.GetCurrentDirectory(), + pathContext.WorkingDirectory, $"push {packageFileName} -Source {server.Uri}push -Timeout 1"); // Assert @@ -521,6 +529,7 @@ public void PushCommand_PushToServerFollowRedirection() using (var packageDirectory = TestDirectory.Create()) { // Arrange + using SimpleTestPathContext pathContext = new SimpleTestPathContext(); var packageFileName = Util.CreateTestPackage("testPackage1", "1.1.0", packageDirectory); string outputFileName = Path.Combine(packageDirectory, "t1.nupkg"); @@ -543,13 +552,14 @@ public void PushCommand_PushToServerFollowRedirection() return HttpStatusCode.Created; }); + pathContext.Settings.AddSource("http-feed", $"{server.Uri}redirect", allowInsecureConnectionsValue: "true"); server.Start(); // Act string[] args = new string[] { "push", packageFileName, "-Source", server.Uri + "redirect" }; var result = CommandRunner.Run( nugetexe, - Directory.GetCurrentDirectory(), + pathContext.WorkingDirectory, string.Join(" ", args)); server.Stop(); @@ -687,6 +697,7 @@ public void PushCommand_PushToServerBasicAuth() using (var packageDirectory = TestDirectory.Create()) { // Arrange + using SimpleTestPathContext pathContext = new SimpleTestPathContext(); var packageFileName = Util.CreateTestPackage("testPackage1", "1.1.0", packageDirectory); string outputFileName = Path.Combine(packageDirectory, "t1.nupkg"); @@ -708,6 +719,7 @@ public void PushCommand_PushToServerBasicAuth() res.StatusCode = (int)HttpStatusCode.Unauthorized; } })); + pathContext.Settings.AddSource("http-feed", $"{server.Uri}nuget", allowInsecureConnectionsValue: "true"); server.Start(); // Act @@ -715,7 +727,7 @@ public void PushCommand_PushToServerBasicAuth() " -Source " + server.Uri + "nuget"; var r1 = CommandRunner.Run( nugetexe, - packageDirectory, + pathContext.WorkingDirectory, args, timeOutInMilliseconds: 10000, inputAction: (w) => @@ -842,6 +854,7 @@ public void PushCommand_PushToServerIntegratedWindowsAuthentication() using (var packageDirectory = TestDirectory.Create()) { // Arrange + using SimpleTestPathContext pathContext = new SimpleTestPathContext(); var packageFileName = Util.CreateTestPackage("testPackage1", "1.1.0", packageDirectory); string outputFileName = Path.Combine(packageDirectory, "t1.nupkg"); @@ -852,6 +865,7 @@ public void PushCommand_PushToServerIntegratedWindowsAuthentication() putUser = user; res.StatusCode = (int)HttpStatusCode.OK; })); + pathContext.Settings.AddSource("http-feed", $"{server.Uri}nuget", allowInsecureConnectionsValue: "true"); server.Start(); // Act @@ -859,7 +873,7 @@ public void PushCommand_PushToServerIntegratedWindowsAuthentication() " -Source " + server.Uri + "nuget"; var r1 = CommandRunner.Run( nugetexe, - packageDirectory, + pathContext.WorkingDirectory, args, timeOutInMilliseconds: 10000); server.Stop(); @@ -886,7 +900,7 @@ public void PushCommand_PushToServerIntegratedWindowsAuthenticationDisableBuffer { var packageFileName = Util.CreateTestPackage("testPackage1", "1.1.0", packageDirectory); string outputFileName = Path.Combine(packageDirectory, "t1.nupkg"); - + using SimpleTestPathContext pathContext = new SimpleTestPathContext(); using (var server = new MockServer(AuthenticationSchemes.IntegratedWindowsAuthentication)) { server.Put.Add("/nuget", r => new Action((res, user) => @@ -894,6 +908,7 @@ public void PushCommand_PushToServerIntegratedWindowsAuthenticationDisableBuffer putUser = user; res.StatusCode = (int)HttpStatusCode.OK; })); + pathContext.Settings.AddSource("http-feed", $"{server.Uri}nuget", allowInsecureConnectionsValue: "true"); server.Start(); // Act @@ -901,7 +916,7 @@ public void PushCommand_PushToServerIntegratedWindowsAuthenticationDisableBuffer " -Source " + server.Uri + "nuget -DisableBuffering"; var r1 = CommandRunner.Run( nugetexe, - packageDirectory, + pathContext.WorkingDirectory, args, timeOutInMilliseconds: 10000); server.Stop(); @@ -929,6 +944,7 @@ public void PushCommand_PushToServer_GetCredentialFromPlugin() using (var packageDirectory = TestDirectory.Create()) { // Arrange + using SimpleTestPathContext pathContext = new SimpleTestPathContext(); var packageFileName = Util.CreateTestPackage("testPackage1", "1.1.0", packageDirectory); string outputFileName = Path.Combine(packageDirectory, "t1.nupkg"); @@ -951,13 +967,14 @@ public void PushCommand_PushToServer_GetCredentialFromPlugin() res.StatusCode = (int)HttpStatusCode.Unauthorized; } })); + pathContext.Settings.AddSource("http-feed", $"{server.Uri}nuget", allowInsecureConnectionsValue: "true"); server.Start(); // Act var args = $"push {packageFileName} -Source {server.Uri}nuget"; var r1 = CommandRunner.Run( nugetexe, - packageDirectory, + pathContext.WorkingDirectory, args, timeOutInMilliseconds: 10000, inputAction: (w) => @@ -1059,6 +1076,7 @@ public void PushCommand_PushToServer_DoesNotDeadLockWhenSTDOutLarge() using (var packageDirectory = TestDirectory.Create()) { // Arrange + using SimpleTestPathContext pathContext = new SimpleTestPathContext(); var packageFileName = Util.CreateTestPackage("testPackage1", "1.1.0", packageDirectory); string outputFileName = Path.Combine(packageDirectory, "t1.nupkg"); @@ -1080,6 +1098,7 @@ public void PushCommand_PushToServer_DoesNotDeadLockWhenSTDOutLarge() res.StatusCode = (int)HttpStatusCode.Unauthorized; } })); + pathContext.Settings.AddSource("http-feed", $"{server.Uri}nuget", allowInsecureConnectionsValue: "true"); server.Start(); var longPassword = new string('a', 10000); @@ -1087,7 +1106,7 @@ public void PushCommand_PushToServer_DoesNotDeadLockWhenSTDOutLarge() var args = $"push {packageFileName} -Source {server.Uri}nuget"; var r1 = CommandRunner.Run( nugetexe, - packageDirectory, + pathContext.WorkingDirectory, args, timeOutInMilliseconds: 10000, inputAction: (w) => @@ -1301,7 +1320,7 @@ public void PushCommand_PushToServerV3() return HttpStatusCode.Created; }); - + pathContext.Settings.AddSource("http-feed", $"{serverV3.Uri}index.json", allowInsecureConnectionsValue: "true"); serverV3.Start(); serverV2.Start(); @@ -1364,14 +1383,15 @@ public void PushCommand_PushToServerV3_NoPushEndpoint() throw new Exception("This test needs to be updated to support: " + path); }); - + PackageSource source = new PackageSource($"{serverV3.Uri}index.json", "http-feed"); + pathContext.Settings.AddSource(source.Name, source.Source, allowInsecureConnectionsValue: "true"); serverV3.Start(); // Act var result = CommandRunner.Run( nugetexe, - pathContext.SolutionRoot, - $"push {packageFileName} -Source {serverV3.Uri}index.json"); + pathContext.WorkingDirectory, + $"push {packageFileName} -Source {source.Source}"); serverV3.Stop(); @@ -1380,8 +1400,7 @@ public void PushCommand_PushToServerV3_NoPushEndpoint() var expectedOutput = string.Format( - "ERROR: This version of nuget.exe does not support updating packages to package source '{0}'.", - serverV3.Uri + "index.json"); + "ERROR: This version of nuget.exe does not support updating packages to package source '{0}'.", source.Name); // Verify that the output contains the expected output Assert.True(result.Errors.Contains(expectedOutput)); @@ -1422,7 +1441,7 @@ public void PushCommand_PushToServerV3_Unavailable() throw new Exception("This test needs to be updated to support: " + path); }); - + pathContext.Settings.AddSource("http-feed", $"{serverV3.Uri}index.json", allowInsecureConnectionsValue: "true"); serverV3.Start(); // Act @@ -1478,7 +1497,7 @@ public void PushCommand_PushToServer_ApiKeyAsThirdArgument() return HttpStatusCode.Created; }); - + pathContext.Settings.AddSource("http-feed", $"{server.Uri}nuget", allowInsecureConnectionsValue: "true"); server.Start(); // Act @@ -1540,7 +1559,7 @@ public void PushCommand_PushToServer_ApiKeyAsNamedArgument() return HttpStatusCode.Created; }); - + pathContext.Settings.AddSource("http-feed", $"{serverV3.Uri}index.json", allowInsecureConnectionsValue: "true"); serverV3.Start(); // Act @@ -1623,7 +1642,7 @@ public void PushCommand_PushToServerV3_ApiKeyFromConfig(string configKeyFormatSt var settings = pathContext.Settings; var source = serverV3.Uri + "index.json"; var packageSourcesSection = SimpleTestSettingsContext.GetOrAddSection(settings.XML, "packageSources"); - SimpleTestSettingsContext.AddEntry(packageSourcesSection, $"nuget.org", source); + SimpleTestSettingsContext.AddEntry(packageSourcesSection, $"nuget.org", source, "allowInsecureConnections", "true"); var configKey = string.Format(configKeyFormatString, serverV3.Uri); var configValue = Configuration.EncryptionUtility.EncryptString(testApiKey); @@ -1723,7 +1742,7 @@ public void PushCommand_PushToServerV3_WithSymbols_ApiKey_SymbolApiKey_BothFromC var settings = pathContext.Settings; var source = serverV3.Uri + "index.json"; var packageSourcesSection = SimpleTestSettingsContext.GetOrAddSection(settings.XML, ConfigurationConstants.PackageSources); - SimpleTestSettingsContext.AddEntry(packageSourcesSection, $"contoso.org", source); + SimpleTestSettingsContext.AddEntry(packageSourcesSection, $"contoso.org", source, "allowInsecureConnections", "true"); // set api key var configKey = string.Format(configKeyFormatString, serverV3.Uri); @@ -1821,7 +1840,7 @@ public void PushCommand_PushToServerV3_ApiKeyFromCli_WithSymbols_SymbolApiKeyFro var settings = pathContext.Settings; var source = serverV3.Uri + "index.json"; var packageSourcesSection = SimpleTestSettingsContext.GetOrAddSection(settings.XML, ConfigurationConstants.PackageSources); - SimpleTestSettingsContext.AddEntry(packageSourcesSection, $"contoso.org", source); + SimpleTestSettingsContext.AddEntry(packageSourcesSection, $"contoso.org", source, "allowInsecureConnections", "true"); settings.Save(); // set symbol api key @@ -1917,7 +1936,7 @@ public void PushCommand_PushToServerV3_ApiKeyFromConfig_WithSymbols_SymbolApiKey var settings = pathContext.Settings; var source = serverV3.Uri + "index.json"; var packageSourcesSection = SimpleTestSettingsContext.GetOrAddSection(settings.XML, ConfigurationConstants.PackageSources); - SimpleTestSettingsContext.AddEntry(packageSourcesSection, $"contoso.org", source); + SimpleTestSettingsContext.AddEntry(packageSourcesSection, $"contoso.org", source, "allowInsecureConnections", "true"); settings.Save(); // set api key @@ -2008,7 +2027,7 @@ public void PushCommand_PushToServerV3_ApiKeyFromConfig_WithSymbols_FallbackToAp var settings = pathContext.Settings; var source = serverV3.Uri + "index.json"; var packageSourcesSection = SimpleTestSettingsContext.GetOrAddSection(settings.XML, ConfigurationConstants.PackageSources); - SimpleTestSettingsContext.AddEntry(packageSourcesSection, $"contoso.org", source); + SimpleTestSettingsContext.AddEntry(packageSourcesSection, $"contoso.org", source, "allowInsecureConnections", "true"); settings.Save(); // set api key @@ -2100,7 +2119,7 @@ public void PushCommand_PushToServerV3_WithSymbols_ApiKey_SymbolApiKey_BothFromC var settings = pathContext.Settings; var source = serverV3.Uri + "index.json"; var packageSourcesSection = SimpleTestSettingsContext.GetOrAddSection(settings.XML, ConfigurationConstants.PackageSources); - SimpleTestSettingsContext.AddEntry(packageSourcesSection, $"contoso.org", source); + SimpleTestSettingsContext.AddEntry(packageSourcesSection, $"contoso.org", source, "allowInsecureConnections", "true"); settings.Save(); // Act @@ -2160,11 +2179,11 @@ public void PushCommand_APIV2Package_Endpoint() { var nugetexe = Util.GetNuGetExePath(); - using (var packageDirectory = TestDirectory.Create()) + using (SimpleTestPathContext pathContext = new SimpleTestPathContext()) { // Arrange - var packageFileName = Util.CreateTestPackage("testPackage1", "1.1.0", packageDirectory); - string outputFileName = Path.Combine(packageDirectory, "t1.nupkg"); + var packageFileName = Util.CreateTestPackage("testPackage1", "1.1.0", pathContext.WorkingDirectory); + string outputFileName = Path.Combine(pathContext.WorkingDirectory, "t1.nupkg"); using (var server = new MockServer()) { @@ -2210,6 +2229,7 @@ public void PushCommand_APIV2Package_Endpoint() throw new Exception("This test needs to be updated to support PUT for: " + path); }); + pathContext.Settings.AddSource("http-feed", $"{server.Uri}api/v2/Package", allowInsecureConnectionsValue: "true"); server.Start(); // Act @@ -2223,7 +2243,7 @@ public void PushCommand_APIV2Package_Endpoint() var result = CommandRunner.Run( nugetexe, - Directory.GetCurrentDirectory(), + pathContext.WorkingDirectory, string.Join(" ", args)); server.Stop(); @@ -2456,10 +2476,8 @@ public void PushCommand_Failure_InvalidArguments(string cmd) Util.TestCommandInvalidArguments(cmd); } - [Theory] - [InlineData("true", false)] - [InlineData("false", true)] - public void PushCommand_WhenPushingToAnHttpServerWithAllowInsecureConnections_WarnsCorrectly(string allowInsecureConnections, bool isHttpWarningExpected) + [Fact] + public void PushCommand_WhenPushingToAnHttpServerWithAllowInsecureConnectionsFalse_Errors() { var nugetexe = Util.GetNuGetExePath(); @@ -2485,7 +2503,53 @@ public void PushCommand_WhenPushingToAnHttpServerWithAllowInsecureConnections_Wa $@" - + + +"; + string configPath = Path.Combine(packageDirectory, "NuGet.Config"); + File.WriteAllText(configPath, nugetConfigContent); + + server.Start(); + + // Act + var result = CommandRunner.Run( + nugetexe, + Directory.GetCurrentDirectory(), + $"push {packageFileName} -ConfigFile {configPath} -Source {server.Uri}push"); + + // Assert + result.Success.Should().BeFalse(result.AllOutput); + Assert.Contains($"{server.Uri}push", result.Errors); + } + + [Fact] + public void PushCommand_WhenPushingToAnHttpServerWithAllowInsecureConnectionsTrue_Succeeds() + { + var nugetexe = Util.GetNuGetExePath(); + + using var packageDirectory = TestDirectory.Create(); + var packageFileName = Util.CreateTestPackage("test", "1.1.0", packageDirectory); + var outputFileName = Path.Combine(packageDirectory, "t1.nupkg"); + + using var server = new MockServer(); + server.Get.Add("/push", r => "OK"); + server.Put.Add("/push", r => + { + byte[] buffer = MockServer.GetPushedPackage(r); + using (var of = new FileStream(outputFileName, FileMode.Create)) + { + of.Write(buffer, 0, buffer.Length); + } + + return HttpStatusCode.Created; + }); + + // Arrange the NuGet.Config file + string nugetConfigContent = +$@" + + + "; string configPath = Path.Combine(packageDirectory, "NuGet.Config"); @@ -2501,21 +2565,64 @@ public void PushCommand_WhenPushingToAnHttpServerWithAllowInsecureConnections_Wa // Assert result.Success.Should().BeTrue(result.AllOutput); - string expectedWarning = "WARNING: You are running the 'push' operation with an 'HTTP' source"; - if (isHttpWarningExpected) + Assert.DoesNotContain($"{server.Uri}push", result.Errors); + } + + [Fact] + public void PushCommand_WhenPushingToAnHttpServerWithSymbolsAndAllowInsecureConnectionsFalse_Errors() + { + using var packageDirectory = TestDirectory.Create(); + using var server = new MockServer(); + // Arrange + var packageFileName = Util.CreateTestPackage("testPackage1", "1.1.0", packageDirectory); + var symbolFileName = packageFileName.Replace(".nupkg", ".symbols.nupkg"); + File.Copy(packageFileName, symbolFileName); + + server.Get.Add("/push", r => "OK"); + server.Put.Add("/push", r => { - Assert.Contains(expectedWarning, result.AllOutput); - } - else + return r.Headers["X-NuGet-ApiKey"] == "PushKey" + ? HttpStatusCode.Created + : HttpStatusCode.Unauthorized; + }); + + server.Get.Add("/symbols", r => "OK"); + server.Put.Add("/symbols", r => { - Assert.DoesNotContain(expectedWarning, result.AllOutput); - } + return r.Headers["X-NuGet-ApiKey"] == "PushSymbolsKey" + ? HttpStatusCode.Created + : HttpStatusCode.Unauthorized; + }); + + // Arrange the NuGet.Config file + string nugetConfigContent = +$@" + + + + +"; + string configPath = Path.Combine(packageDirectory, "NuGet.Config"); + File.WriteAllText(configPath, nugetConfigContent); + + server.Start(); + + var pushUri = $"{server.Uri}push"; + var pushSymbolsUri = $"{server.Uri}symbols"; + + // Act + CommandRunnerResult result = CommandRunner.Run( + Util.GetNuGetExePath(), + Directory.GetCurrentDirectory(), + $"push {packageFileName} -Source {pushUri} -SymbolSource {pushSymbolsUri} -ConfigFile {configPath} -ApiKey PushKey -SymbolApiKey PushSymbolsKey"); + + // Assert + Assert.False(result.Success); + Assert.Contains(pushUri, result.Errors); } - [Theory] - [InlineData("true", false)] - [InlineData("false", true)] - public void PushCommand_WhenPushingToAnHttpServerWithSymbolsAndAllowInsecureConnections_WarnsCorrectly(string allowInsecureConnections, bool isHttpWarningExpected) + [Fact] + public void PushCommand_WhenPushingToAnHttpServerWithSymbolsAndAllowInsecureConnectionsTrue_Succeeds() { using var packageDirectory = TestDirectory.Create(); using var server = new MockServer(); @@ -2545,7 +2652,7 @@ public void PushCommand_WhenPushingToAnHttpServerWithSymbolsAndAllowInsecureConn $@" - + "; string configPath = Path.Combine(packageDirectory, "NuGet.Config"); @@ -2569,23 +2676,10 @@ public void PushCommand_WhenPushingToAnHttpServerWithSymbolsAndAllowInsecureConn Assert.Contains($"Pushing testPackage1.1.1.0.symbols.nupkg to '{pushSymbolsUri}'", result.Output); Assert.Contains($"Created {pushSymbolsUri}", result.Output); Assert.Contains("Your package was pushed.", result.Output); - - string expectedWarning = $"WARNING: You are running the 'push' operation with an 'HTTP' source, '{pushUri}/'"; - string expectedSymbolWarning = $"WARNING: You are running the 'push' operation with an 'HTTP' source, '{pushSymbolsUri}/'"; - - if (isHttpWarningExpected) - { - Assert.Contains(expectedWarning, result.AllOutput); - Assert.Contains(expectedSymbolWarning, result.AllOutput); - } - else - { - Assert.DoesNotContain(expectedWarning, result.AllOutput); - Assert.DoesNotContain(expectedSymbolWarning, result.AllOutput); - } } + [Fact] - public void PushCommand_WhenPushingToAnHttpServerV3_Warns() + public void PushCommand_WhenPushingToAnHttpServerV3_ThrowsAnException() { var nugetexe = Util.GetNuGetExePath(); @@ -2652,11 +2746,8 @@ public void PushCommand_WhenPushingToAnHttpServerV3_Warns() string.Join(" ", args)); // Assert - result.Success.Should().BeTrue(result.AllOutput); - result.AllOutput.Should().Contain("Your package was pushed"); - result.AllOutput.Should().Contain($"WARNING: You are running the 'push' operation with an 'HTTP' source, '{serverV3.Uri}index.json'"); - result.AllOutput.Should().Contain($"WARNING: You are running the 'push' operation with an 'HTTP' source, '{serverV2.Uri}push/'"); - AssertFileEqual(packageFileName, outputFileName); + result.Success.Should().BeFalse(result.AllOutput); + result.Errors.Should().Contain($"{serverV3.Uri}index.json"); } } } diff --git a/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/NuGetRestoreCommandTest.cs b/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/NuGetRestoreCommandTest.cs index d697fdf335c..dd10d4053e7 100644 --- a/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/NuGetRestoreCommandTest.cs +++ b/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/NuGetRestoreCommandTest.cs @@ -1246,7 +1246,7 @@ public void RestoreCommand_FromHttpSource() MockServer.SetResponseContent(response, content); } })); - + pathContext.Settings.AddSource("http-source", $"{server.Uri}nuget", allowInsecureConnectionsValue: "True"); server.Get.Add("/nuget", r => "OK"); server.Start(); @@ -3305,7 +3305,7 @@ public void RestoreCommand_WithPackagesConfig_PackageWithVulnerabilities_RaisesW (new Uri("https://contoso.com/advisories/12345"), PackageVulnerabilitySeverity.High, VersionRange.Parse("[1.0.0, 2.0.0)")) }); pathContext.Settings.RemoveSource("source"); - pathContext.Settings.AddSource("source", mockServer.ServiceIndexUri); + pathContext.Settings.AddSource("source", mockServer.ServiceIndexUri, allowInsecureConnectionsValue: "True"); var workingPath = pathContext.WorkingDirectory; Util.CreateTestPackage("packageA", "1.1.0", pathContext.PackageSource); @@ -3351,7 +3351,7 @@ public void RestoreCommand_WithProjectWithPackagesConfig_DefaultSettings_Package }); pathContext.Settings.RemoveSource("source"); - pathContext.Settings.AddSource("source", mockServer.ServiceIndexUri); + pathContext.Settings.AddSource("source", mockServer.ServiceIndexUri, allowInsecureConnectionsValue: "True"); Util.CreateTestPackage("packageA", "1.1.0", pathContext.PackageSource); Util.CreateTestPackage("packageB", "2.2.0", pathContext.PackageSource); @@ -3404,7 +3404,7 @@ public void RestoreCommand_WithProjectWithPackagesConfig_WithNuGetAuditFalse_Pac (new Uri("https://contoso.com/advisories/12345"), PackageVulnerabilitySeverity.High, VersionRange.Parse("[1.0.0, 2.0.0)")) }); pathContext.Settings.RemoveSource("source"); - pathContext.Settings.AddSource("source", mockServer.ServiceIndexUri); + pathContext.Settings.AddSource("source", mockServer.ServiceIndexUri, allowInsecureConnectionsValue: "True"); Util.CreateTestPackage("packageA", "1.1.0", pathContext.PackageSource); Util.CreateTestPackage("packageB", "2.2.0", pathContext.PackageSource); @@ -3459,7 +3459,7 @@ public void RestoreCommand_WithProjectWithPackagesConfig_WithNuGetAuditLevel_Pac (new Uri("https://contoso.com/advisories/12346"), PackageVulnerabilitySeverity.Critical, VersionRange.Parse("[1.0.0, 2.0.0)")) }); pathContext.Settings.RemoveSource("source"); - pathContext.Settings.AddSource("source", mockServer.ServiceIndexUri); + pathContext.Settings.AddSource("source", mockServer.ServiceIndexUri, allowInsecureConnectionsValue: "True"); Util.CreateTestPackage("packageA", "1.1.0", pathContext.PackageSource); Util.CreateTestPackage("packageB", "2.2.0", pathContext.PackageSource); @@ -3515,7 +3515,7 @@ public void RestoreCommand_WithSolutionFile_PackageWithVulnerabilities_RaisesApp (new Uri("https://contoso.com/advisories/12346"), PackageVulnerabilitySeverity.Critical, VersionRange.Parse("[1.2.0, 2.0.0)")) }); pathContext.Settings.RemoveSource("source"); - pathContext.Settings.AddSource("source", mockServer.ServiceIndexUri); + pathContext.Settings.AddSource("source", mockServer.ServiceIndexUri, allowInsecureConnectionsValue: "True"); Util.CreateTestPackage("packageA", "1.1.0", pathContext.PackageSource); Util.CreateTestPackage("packageA", "1.2.0", pathContext.PackageSource); @@ -3588,7 +3588,7 @@ public void RestoreCommand_WithMultipleProjectsInSameDirectory_RaisesAppropriate (new Uri("https://contoso.com/advisories/12346"), PackageVulnerabilitySeverity.Critical, VersionRange.Parse("[1.2.0, 2.0.0)")) }); pathContext.Settings.RemoveSource("source"); - pathContext.Settings.AddSource("source", mockServer.ServiceIndexUri); + pathContext.Settings.AddSource("source", mockServer.ServiceIndexUri, allowInsecureConnectionsValue: "true"); Util.CreateTestPackage("packageA", "1.1.0", pathContext.PackageSource); Util.CreateTestPackage("packageA", "1.2.0", pathContext.PackageSource); diff --git a/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/NuGetSourcesCommandTest.cs b/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/NuGetSourcesCommandTest.cs index 6d6a475cf94..27ddb4f8bc2 100644 --- a/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/NuGetSourcesCommandTest.cs +++ b/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/NuGetSourcesCommandTest.cs @@ -2,11 +2,11 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Collections.Generic; using System.IO; using System.Linq; using NuGet.Common; using NuGet.Configuration; -using NuGet.Configuration.Test; using NuGet.Test.Utility; using Xunit; @@ -14,11 +14,42 @@ namespace NuGet.CommandLine.Test { public class NuGetSourcesCommandTest { - [Theory] - [InlineData("http://test_source", true)] - [InlineData("https://test_source", false)] - public void SourcesCommandTest_AddSource(string source, bool shouldWarn) + + [Fact] + public void SourcesCommandTest_AddSourceWithHTTPSource_ShouldFail() + { + string source = "http://test_source"; + using (var pathContext = new SimpleTestPathContext()) + { + TestDirectory workingPath = pathContext.WorkingDirectory; + SimpleTestSettingsContext settings = pathContext.Settings; + + // Arrange + var nugetexe = Util.GetNuGetExePath(); + var args = new string[] { + "sources", + "Add", + "-Name", + "test_source", + "-Source", + source, + "-ConfigFile", + settings.ConfigPath + }; + + // Act + CommandRunnerResult result = CommandRunner.Run(nugetexe, workingPath, string.Join(" ", args)); + + // Assert + Assert.Equal(1, result.ExitCode); + Assert.Contains(source, result.Errors); + } + } + + [Fact] + public void SourcesCommandTest_AddSourceWithHTTPSSource_ShouldSucceed() { + string source = "https://test_source"; using (var pathContext = new SimpleTestPathContext()) { TestDirectory workingPath = pathContext.WorkingDirectory; @@ -46,26 +77,177 @@ public void SourcesCommandTest_AddSource(string source, bool shouldWarn) SettingSection packageSourcesSection = loadedSettings.GetSection("packageSources"); SourceItem sourceItem = packageSourcesSection?.GetFirstItemWithAttribute("key", "test_source"); Assert.Equal(source, sourceItem.GetValueAsPath()); - Assert.Equal(shouldWarn, result.Output.Contains("WARNING: You are running the 'add source' operation with an 'HTTP' source")); } } [Theory] - [InlineData("http://source.test", true)] - [InlineData("https://source.test", false)] - public void SourcesCommandTest_UpdateSource(string source, bool shouldWarn) + [InlineData("http://test_source")] + [InlineData("https://test_source")] + public void SourcesCommandTest_AddSource_AllowInsecureConnections(string source) + { + using (var pathContext = new SimpleTestPathContext()) + { + TestDirectory workingPath = pathContext.WorkingDirectory; + SimpleTestSettingsContext settings = pathContext.Settings; + + // Arrange + var nugetexe = Util.GetNuGetExePath(); + var args = new string[] { + "sources", + "Add", + "-Name", + "test_source", + "-Source", + source, + "-ConfigFile", + settings.ConfigPath, + "-AllowInsecureConnections" + }; + + // Act + CommandRunnerResult result = CommandRunner.Run(nugetexe, workingPath, string.Join(" ", args)); + + // Assert + Assert.Equal(0, result.ExitCode); + ISettings loadedSettings = Configuration.Settings.LoadDefaultSettings(workingPath, null, null); + SettingSection packageSourcesSection = loadedSettings.GetSection("packageSources"); + SourceItem sourceItem = packageSourcesSection?.GetFirstItemWithAttribute("key", "test_source"); + Assert.Equal(source, sourceItem.GetValueAsPath()); + Assert.Equal("True", sourceItem.AllowInsecureConnections); + Assert.False(result.Errors.Contains(source)); + } + } + + [Fact] + public void SourcesCommandTest_UpdateSourceWithHTTPSource_ShouldFail() + { + using (SimpleTestPathContext pathContext = new SimpleTestPathContext()) + { + string source = "http://source.test"; + var nugetexe = Util.GetNuGetExePath(); + var configFileName = "nuget.config"; + var configFilePath = Path.Combine(pathContext.WorkingDirectory, configFileName); + + pathContext.Settings.AddSource("test_source", "http://source.test.initial"); + + // Arrange + var args = new string[] { + "sources", + "Update", + "-Name", + "test_source", + "-Source", + source, + "-ConfigFile", + configFilePath + }; + + // Act + CommandRunnerResult result = CommandRunner.Run( + nugetexe, + pathContext.WorkingDirectory, + string.Join(" ", args)); + + // Assert + Assert.Equal(1, result.ExitCode); + Assert.Contains(source, result.Errors); + } + } + + [Fact] + public void SourcesCommandTest_UpdateSourceWithHTTPSSource_ShouldSucceed() + { + string source = "https://source.test"; + using (SimpleTestPathContext pathContext = new SimpleTestPathContext()) + { + var nugetexe = Util.GetNuGetExePath(); + var configFileName = "nuget.config"; + var configFilePath = Path.Combine(pathContext.WorkingDirectory, configFileName); + + pathContext.Settings.AddSource("test_source", "http://source.test.initial"); + + // Arrange + var args = new string[] { + "sources", + "Update", + "-Name", + "test_source", + "-Source", + source, + "-ConfigFile", + configFilePath + }; + + // Act + CommandRunnerResult result = CommandRunner.Run( + nugetexe, + pathContext.WorkingDirectory, + string.Join(" ", args)); + + // Assert + Assert.Equal(0, result.ExitCode); + ISettings loadedSettings = Configuration.Settings.LoadDefaultSettings(pathContext.WorkingDirectory, configFileName, null); + SettingSection packageSourcesSection = loadedSettings.GetSection("packageSources"); + SourceItem sourceItem = packageSourcesSection?.GetFirstItemWithAttribute("key", "test_source"); + Assert.Equal(source, sourceItem.GetValueAsPath()); + } + } + + [Fact] + public void SourcesCommandTest_RemoveAllowInsecureConnectionsOfHttpSource_Fails() { + string source = "http://source.test"; using (TestDirectory configFileDirectory = TestDirectory.Create()) { var nugetexe = Util.GetNuGetExePath(); var configFileName = "nuget.config"; var configFilePath = Path.Combine(configFileDirectory, configFileName); + var nugetConfig = string.Format( + @" + + + + +", source); + Util.CreateFile(configFileDirectory, configFileName, nugetConfig); + + // Arrange + var args = new string[] { + "sources", + "Update", + "-Name", + "test_source", + "-Source", + source, + "-ConfigFile", + configFilePath + }; + + // Act + CommandRunnerResult result = CommandRunner.Run( + nugetexe, + configFileDirectory, + string.Join(" ", args)); + // Assert + Assert.Equal(1, result.ExitCode); + Assert.Contains(source, result.Errors); + } + } + [Fact] + public void SourcesCommandTest_RemoveAllowInsecureConnectionsOfHttpsSource_Succeeds() + { + string source = "https://source.test"; + using (TestDirectory configFileDirectory = TestDirectory.Create()) + { + var nugetexe = Util.GetNuGetExePath(); + var configFileName = "nuget.config"; + var configFilePath = Path.Combine(configFileDirectory, configFileName); var nugetConfig = string.Format( @" - + ", source); Util.CreateFile(configFileDirectory, configFileName, nugetConfig); @@ -94,12 +276,62 @@ public void SourcesCommandTest_UpdateSource(string source, bool shouldWarn) SettingSection packageSourcesSection = loadedSettings.GetSection("packageSources"); SourceItem sourceItem = packageSourcesSection?.GetFirstItemWithAttribute("key", "test_source"); Assert.Equal(source, sourceItem.GetValueAsPath()); - Assert.Equal(shouldWarn, result.Output.Contains("WARNING: You are running the 'update source' operation with an 'HTTP' source")); + Assert.Null(sourceItem.AllowInsecureConnections); + } + } + + [Theory] + [InlineData("http://source.test")] + [InlineData("https://source.test")] + public void SourcesCommandTest_UpdateSource_AddAllowInsecureConnections(string source) + { + using (TestDirectory configFileDirectory = TestDirectory.Create()) + { + var nugetexe = Util.GetNuGetExePath(); + var configFileName = "nuget.config"; + var configFilePath = Path.Combine(configFileDirectory, configFileName); + + var nugetConfig = string.Format( + @" + + + + +", source); + Util.CreateFile(configFileDirectory, configFileName, nugetConfig); + + // Arrange + var args = new string[] { + "sources", + "Update", + "-Name", + "test_source", + "-Source", + source, + "-ConfigFile", + configFilePath, + "-AllowInsecureConnections" + }; + + // Act + CommandRunnerResult result = CommandRunner.Run( + nugetexe, + configFileDirectory, + string.Join(" ", args)); + + // Assert + Assert.Equal(0, result.ExitCode); + ISettings loadedSettings = Configuration.Settings.LoadDefaultSettings(configFileDirectory, configFileName, null); + SettingSection packageSourcesSection = loadedSettings.GetSection("packageSources"); + SourceItem sourceItem = packageSourcesSection?.GetFirstItemWithAttribute("key", "test_source"); + Assert.Equal(source, sourceItem.GetValueAsPath()); + Assert.Equal("True", sourceItem.AllowInsecureConnections); + Assert.False(result.Errors.Contains(source)); } } [Fact] - public void SourcesCommandTest_EnableSource_WarnWhenUsingHttp() + public void SourcesCommandTest_EnableSource_ThrowsAnExceptionWhenUsingHTTP() { // Arrange string nugetexe = Util.GetNuGetExePath(); @@ -137,29 +369,13 @@ public void SourcesCommandTest_EnableSource_WarnWhenUsingHttp() string.Join(" ", args)); // Assert - Util.VerifyResultSuccess(result); - - ISettings settings = Configuration.Settings.LoadDefaultSettings( - configFileDirectory, - configFileName, - null); - - PackageSourceProvider packageSourceProvider = new Configuration.PackageSourceProvider(settings); - var sources = packageSourceProvider.LoadPackageSources().ToList(); - - var testSources = sources.Where(s => s.Name == "test_source"); - Assert.Single(testSources); - PackageSource source = testSources.Single(); - - Assert.Equal("test_source", source.Name); - Assert.Equal("http://test_source", source.Source); - Assert.True(source.IsEnabled, "Source is not enabled"); - Assert.True(result.Output.Contains("WARNING: You are running the 'enable source' operation with an 'HTTP' source, 'http://test_source'. Non-HTTPS access will be removed in a future version. Consider migrating to an 'HTTPS' source.")); + Assert.Equal(1, result.ExitCode); + Assert.Contains("http://test_source", result.Errors); } } [Fact] - public void SourcesCommandTest_DisableSource_NoWarnWhenUsingHttp() + public void SourcesCommandTest_DisableSource_NoErrorWhenUsingHttp() { // Arrange var nugetexe = Util.GetNuGetExePath(); @@ -210,15 +426,15 @@ public void SourcesCommandTest_DisableSource_NoWarnWhenUsingHttp() Assert.Equal("test_source", source.Name); Assert.Equal("http://test_source", source.Source); Assert.False(source.IsEnabled, "Source is not disabled"); - Assert.False(result.Output.Contains("WARNING:")); + Assert.False(result.Errors.Contains("http://test_source")); } } [Theory] - [InlineData("http://source.test", "http://source.test.2", true, "WARNING: You are running the 'list source' operation with 'HTTP' source")] - [InlineData("https://source.test", "http://source.test.2", true, "WARNING: You are running the 'list source' operation with an 'HTTP' source")] - [InlineData("https://source.test", "https://source.test.2", false, "WARNING")] - public void SourcesList_WithDefaultFormat_UsesDetailedFormat(string source, string secondSource, bool shouldWarn, string warningMessage) + [InlineData("http://source.test", "http://source.test.2")] + [InlineData("https://source.test", "http://source.test.2")] + [InlineData("https://source.test", "https://source.test.2")] + public void SourcesList_WithDefaultFormat_UsesDetailedFormat(string source, string secondSource) { // Arrange var nugetexe = Util.GetNuGetExePath(); @@ -255,7 +471,54 @@ public void SourcesList_WithDefaultFormat_UsesDetailedFormat(string source, stri // test to ensure detailed format is the default Assert.True(result.Output.StartsWith("Registered Sources:")); - Assert.Equal(shouldWarn, result.Output.Contains(warningMessage)); + } + } + + [Fact] + public void SourcesCommandTest_AddWithUserNamePassword() + { + using (var pathContext = new SimpleTestPathContext()) + { + var workingPath = pathContext.WorkingDirectory; + var settings = pathContext.Settings; + + // Arrange + var nugetexe = Util.GetNuGetExePath(); + var args = new string[] { + "sources", + "Add", + "-Name", + "test_source", + "-Source", + "https://test_source", + "-UserName", + "test_user_name", + "-Password", + "test_password", + "-ConfigFile", + settings.ConfigPath + }; + + // Act + CommandRunnerResult result = CommandRunner.Run(nugetexe, workingPath, string.Join(" ", args)); + + // Assert + Assert.True(0 == result.ExitCode, result.Output + " " + result.Errors); + + var loadedSettings = Configuration.Settings.LoadDefaultSettings(workingPath, null, null); + + var packageSourcesSection = loadedSettings.GetSection("packageSources"); + var sourceItem = packageSourcesSection?.GetFirstItemWithAttribute("key", "test_source"); + Assert.Equal("https://test_source", sourceItem.GetValueAsPath()); + + var sourceCredentialsSection = loadedSettings.GetSection("packageSourceCredentials"); + var credentialItem = sourceCredentialsSection?.Items.First(c => string.Equals(c.ElementName, "test_source", StringComparison.OrdinalIgnoreCase)) as CredentialsItem; + Assert.NotNull(credentialItem); + + Assert.Equal("test_user_name", credentialItem.Username); + + var password = Configuration.EncryptionUtility.DecryptString(credentialItem.Password); + Assert.Equal("test_password", password); } } @@ -285,6 +548,14 @@ public void SourcesList_WithAllowInsecureConnections_WarnsCorrectly() "); + List httpPackageSources = + [ + new PackageSource("http://source.test1", "source1"), + new PackageSource("http://source.test2", "source2"), + new PackageSource("http://source.test3", "source3"), + new PackageSource("http://source.test4", "source4"), + new PackageSource("http://source.test5", "source5") + ]; var args = new string[] { "sources", @@ -303,63 +574,12 @@ public void SourcesList_WithAllowInsecureConnections_WarnsCorrectly() Util.VerifyResultSuccess(result); // http source with false allowInsecureConnections have warnings. - string expectedWarning = SettingsTestUtils.RemoveWhitespace(@" -WARNING: You are running the 'list source' operation with 'HTTP' sources: -source1 -source2 -source3 -source4 -source5 -Non-HTTPS access will be removed in a future version. Consider migrating to 'HTTPS' sources."); - Assert.Contains(expectedWarning, SettingsTestUtils.RemoveWhitespace(result.Output)); - } - } - - [Fact] - public void SourcesCommandTest_AddWithUserNamePassword() - { - using (var pathContext = new SimpleTestPathContext()) - { - var workingPath = pathContext.WorkingDirectory; - var settings = pathContext.Settings; - // Arrange - var nugetexe = Util.GetNuGetExePath(); - var args = new string[] { - "sources", - "Add", - "-Name", - "test_source", - "-Source", - "http://test_source", - "-UserName", - "test_user_name", - "-Password", - "test_password", - "-ConfigFile", - settings.ConfigPath - }; - - // Act - CommandRunnerResult result = CommandRunner.Run(nugetexe, workingPath, string.Join(" ", args)); - - // Assert - Assert.True(0 == result.ExitCode, result.Output + " " + result.Errors); - - var loadedSettings = Configuration.Settings.LoadDefaultSettings(workingPath, null, null); - - var packageSourcesSection = loadedSettings.GetSection("packageSources"); - var sourceItem = packageSourcesSection?.GetFirstItemWithAttribute("key", "test_source"); - Assert.Equal("http://test_source", sourceItem.GetValueAsPath()); - - var sourceCredentialsSection = loadedSettings.GetSection("packageSourceCredentials"); - var credentialItem = sourceCredentialsSection?.Items.First(c => string.Equals(c.ElementName, "test_source", StringComparison.OrdinalIgnoreCase)) as CredentialsItem; - Assert.NotNull(credentialItem); - - Assert.Equal("test_user_name", credentialItem.Username); - - var password = Configuration.EncryptionUtility.DecryptString(credentialItem.Password); - Assert.Equal("test_password", password); + Assert.Contains("http://source.test1", result.AllOutput); + Assert.Contains("http://source.test2", result.AllOutput); + Assert.Contains("http://source.test3", result.AllOutput); + Assert.Contains("http://source.test4", result.AllOutput); + Assert.Contains("http://source.test5", result.AllOutput); } } @@ -379,7 +599,7 @@ public void SourcesCommandTest_AddWithUserNamePasswordInClearText() "-Name", "test_source", "-Source", - "http://test_source", + "https://test_source", "-UserName", "test_user_name", "-Password", @@ -399,7 +619,7 @@ public void SourcesCommandTest_AddWithUserNamePasswordInClearText() var packageSourcesSection = loadedSettings.GetSection("packageSources"); var sourceItem = packageSourcesSection?.GetFirstItemWithAttribute("key", "test_source"); - Assert.Equal("http://test_source", sourceItem.GetValueAsPath()); + Assert.Equal("https://test_source", sourceItem.GetValueAsPath()); var sourceCredentialsSection = loadedSettings.GetSection("packageSourceCredentials"); var credentialItem = sourceCredentialsSection?.Items.First(c => string.Equals(c.ElementName, "test_source", StringComparison.OrdinalIgnoreCase)) as CredentialsItem; @@ -431,7 +651,7 @@ public void SourcesCommandTest_AddWithUserNamePassword_UserDefinedConfigFile() "-Name", "test_source", "-Source", - "http://test_source", + "https://test_source", "-UserName", "test_user_name", "-Password", @@ -456,7 +676,7 @@ public void SourcesCommandTest_AddWithUserNamePassword_UserDefinedConfigFile() var packageSourcesSection = settings.GetSection("packageSources"); var sourceItem = packageSourcesSection?.GetFirstItemWithAttribute("key", "test_source"); - Assert.Equal("http://test_source", sourceItem.GetValueAsPath()); + Assert.Equal("https://test_source", sourceItem.GetValueAsPath()); var sourceCredentialsSection = settings.GetSection("packageSourceCredentials"); var credentialItem = sourceCredentialsSection?.Items.First(c => string.Equals(c.ElementName, "test_source", StringComparison.OrdinalIgnoreCase)) as CredentialsItem; @@ -765,7 +985,7 @@ public void SourcesCommandTest_EnableSource() @" - + @@ -793,7 +1013,7 @@ public void SourcesCommandTest_EnableSource() var source = sources.Single(); Assert.Equal("test_source", source.Name); - Assert.Equal("http://test_source", source.Source); + Assert.Equal("https://test_source", source.Source); Assert.False(source.IsEnabled); // Main Act @@ -824,7 +1044,7 @@ public void SourcesCommandTest_EnableSource() source = testSources.Single(); Assert.Equal("test_source", source.Name); - Assert.Equal("http://test_source", source.Source); + Assert.Equal("https://test_source", source.Source); Assert.True(source.IsEnabled, "Source is not enabled"); } } diff --git a/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/NuGetUpdateCommandTests.cs b/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/NuGetUpdateCommandTests.cs index 4706a2a337d..3965e0e3bf0 100644 --- a/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/NuGetUpdateCommandTests.cs +++ b/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/NuGetUpdateCommandTests.cs @@ -1888,7 +1888,8 @@ public async Task UpdateCommand_WithHttpSource_Warns() server.Start(); var sourceUri = $"{server.Uri}nuget"; - + // Allow Insecure connections for restore + pathContext.Settings.AddSource("http-source", sourceUri, allowInsecureConnectionsValue: "True"); var projectA = new SimpleTestProjectContext( "a", ProjectStyle.PackagesConfig, @@ -1923,6 +1924,7 @@ public async Task UpdateCommand_WithHttpSource_Warns() sourceUri }; + pathContext.Settings.RemoveSource("http-source"); // Act var r = CommandRunner.Run( Util.GetNuGetExePath(), @@ -1958,7 +1960,8 @@ public async Task UpdateCommand_WithHttpSourceAndAllowInsecureConnections_WarnsC server.Start(); var sourceUri = $"{server.Uri}nuget"; - pathContext.Settings.AddSource("http-feed", $"{server.Uri}nuget", allowInsecureConnections); + // allow Insecure connections for restore + pathContext.Settings.AddSource("http-feed", $"{server.Uri}nuget", allowInsecureConnectionsValue: "True"); var projectB = new SimpleTestProjectContext( "b", @@ -1990,6 +1993,9 @@ public async Task UpdateCommand_WithHttpSourceAndAllowInsecureConnections_WarnsC solution.SolutionPath, }; + pathContext.Settings.RemoveSource("http-feed"); + pathContext.Settings.AddSource("http-feed", $"{server.Uri}nuget", allowInsecureConnectionsValue: allowInsecureConnections); + // Act CommandRunnerResult r = CommandRunner.Run( Util.GetNuGetExePath(), diff --git a/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/RestoreRetryTests.cs b/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/RestoreRetryTests.cs index 28dad9ee45e..8ccc6770cb5 100644 --- a/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/RestoreRetryTests.cs +++ b/test/NuGet.Clients.Tests/NuGet.CommandLine.Test/RestoreRetryTests.cs @@ -98,7 +98,7 @@ public void RestoreRetry_PackagesConfigRetryOnFailingV2Source() throw new Exception("This test needs to be updated to support: " + path); }); - + pathContext.Settings.AddSource("http-feed", $"{server.Uri}nuget", allowInsecureConnectionsValue: "true"); server.Start(); // Act @@ -211,7 +211,7 @@ public void RestoreRetry_ProjectJsonRetryOnFailingV2Source() throw new Exception("This test needs to be updated to support: " + path); }); - + pathContext.Settings.AddSource("http-feed", $"{server.Uri}nuget", allowInsecureConnectionsValue: "true"); server.Start(); // Act @@ -349,7 +349,7 @@ public void RestoreRetry_ProjectJsonRetryOnFailingV3Source() throw new Exception("This test needs to be updated to support: " + path); }); - + pathContext.Settings.AddSource("http-feed", $"{server.Uri}index.json", allowInsecureConnectionsValue: "true"); server.Start(); // The minimum time is the number of urls x 3 waits x 200ms @@ -534,7 +534,7 @@ public void RestoreRetry_PackagesConfigRetryOnFailingV3Source() throw new Exception("This test needs to be updated to support: " + path); }); - + pathContext.Settings.AddSource("http-feed", $"{server.Uri}index.json", allowInsecureConnectionsValue: "true"); server.Start(); // The minimum time is the number of urls x 3 waits x 200ms diff --git a/test/NuGet.Core.FuncTests/Dotnet.Integration.Test/DotnetSourcesTests.cs b/test/NuGet.Core.FuncTests/Dotnet.Integration.Test/DotnetSourcesTests.cs index 5fa87b11140..be9f3d395a1 100644 --- a/test/NuGet.Core.FuncTests/Dotnet.Integration.Test/DotnetSourcesTests.cs +++ b/test/NuGet.Core.FuncTests/Dotnet.Integration.Test/DotnetSourcesTests.cs @@ -2,12 +2,14 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Linq; using System.Xml.Linq; +using NuGet.Commands; using NuGet.Common; using NuGet.Configuration; -using NuGet.Configuration.Test; using NuGet.Test.Utility; using Xunit; using Xunit.Abstractions; @@ -54,6 +56,41 @@ public void Sources_WhenAddingSource_GotAdded() var loadedSettings = Settings.LoadDefaultSettings(root: workingPath, configFileName: null, machineWideSettings: null); var packageSourcesSection = loadedSettings.GetSection("packageSources"); var sourceItem = packageSourcesSection?.GetFirstItemWithAttribute("key", "test_source"); + Assert.Null(sourceItem.AllowInsecureConnections); + Assert.Equal("https://source.test", sourceItem.GetValueAsPath()); + } + } + + [PlatformFact(Platform.Windows)] + public void Sources_WhenAddingSource_GotAddedWithAllowInsecureConnections() + { + using (SimpleTestPathContext pathContext = _fixture.CreateSimpleTestPathContext()) + { + var workingPath = pathContext.WorkingDirectory; + var settings = pathContext.Settings; + + // Arrange + var args = new string[] + { + "nuget", + "add", + "source", + "https://source.test", + "--name", + "test_source", + "--configfile", + settings.ConfigPath, + "--allow-insecure-connections" + }; + + // Act + var result = _fixture.RunDotnetExpectSuccess(workingPath, string.Join(" ", args)); + + // Assert + var loadedSettings = Settings.LoadDefaultSettings(root: workingPath, configFileName: null, machineWideSettings: null); + var packageSourcesSection = loadedSettings.GetSection("packageSources"); + var sourceItem = packageSourcesSection?.GetFirstItemWithAttribute("key", "test_source"); + Assert.Equal("True", sourceItem.AllowInsecureConnections); Assert.Equal("https://source.test", sourceItem.GetValueAsPath()); } } @@ -105,11 +142,42 @@ public void Sources_WhenAddingSourceWithCredentials_CredentialsWereAddedAndEncry } } - [PlatformTheory(Platform.Windows)] - [InlineData("http://source.test", true)] - [InlineData("https://source.test", false)] - public void Sources_WarnWhenAdding(string source, bool shouldWarn) + [PlatformFact(Platform.Windows)] + public void Sources_WhenAddingHttpSource_Error() + { + string source = "http://source.test"; + using (SimpleTestPathContext pathContext = _fixture.CreateSimpleTestPathContext()) + { + TestDirectory workingPath = pathContext.WorkingDirectory; + SimpleTestSettingsContext settings = pathContext.Settings; + + // Arrange + var args = new string[] + { + "nuget", + "add", + "source", + source, + "--name", + "test_source", + "--configfile", + settings.ConfigPath + }; + + // Act + CommandRunnerResult result = _fixture.RunDotnetExpectFailure(workingPath, string.Join(" ", args)); + + // Assert + string expectedError = string.Format(CultureInfo.CurrentCulture, Strings.Error_HttpSource_Single_Short, "add source", source); + Assert.Contains(expectedError, result.AllOutput); + } + } + + [PlatformFact(Platform.Windows)] + public void Sources_WhenAddingHttpsSource_NoError() { + string source = "https://source.test"; + using (SimpleTestPathContext pathContext = _fixture.CreateSimpleTestPathContext()) { TestDirectory workingPath = pathContext.WorkingDirectory; @@ -137,20 +205,69 @@ public void Sources_WarnWhenAdding(string source, bool shouldWarn) SettingSection packageSourcesSection = loadedSettings.GetSection("packageSources"); SourceItem sourceItem = packageSourcesSection?.GetFirstItemWithAttribute("key", "test_source"); Assert.Equal(source, sourceItem.GetValueAsPath()); - Assert.Equal(shouldWarn, result.Output.Contains("warn : You are running the 'add source' operation with an 'HTTP' source")); } } - [PlatformTheory(Platform.Windows)] - [InlineData("http://source.test", true)] - [InlineData("https://source.test", false)] - public void Sources_WarnWhenUpdatingHttpSource(string updateSource, bool shouldWarn) + [PlatformFact(Platform.Windows)] + public void Sources_WhenUpdatingHttpSource_Errors() { using (TestDirectory configFileDirectory = _fixture.CreateTestDirectory()) { string configFileName = "nuget.config"; string configFilePath = Path.Combine(configFileDirectory, configFileName); + string updateSource = "http://source.test"; + var nugetConfig = + @" + + + + +"; + CreateXmlFile(configFilePath, nugetConfig); + + ISettings settings = Settings.LoadDefaultSettings( + configFileDirectory, + configFileName, + null); + PackageSourceProvider packageSourceProvider = new PackageSourceProvider(settings); + var sources = packageSourceProvider.LoadPackageSources().ToList(); + Assert.Single(sources); + + PackageSource source = sources.Single(); + Assert.Equal("test_source", source.Name); + Assert.Equal("http://source.test.initial", source.Source); + + // Arrange + var args = new string[] + { + "nuget", + "update", + "source", + "test_source", + "--source", + updateSource, + "--configfile", + configFilePath + }; + + // Act + CommandRunnerResult result = _fixture.RunDotnetExpectFailure(configFileDirectory, string.Join(" ", args)); + + // Assert + string expectedError = string.Format(CultureInfo.CurrentCulture, Strings.Error_HttpSource_Single, "update source", updateSource); + Assert.Contains(expectedError, result.AllOutput); + } + } + + [PlatformFact(Platform.Windows)] + public void Sources_WhenUpdatingHttpsSource_Succeeds() + { + using (TestDirectory configFileDirectory = _fixture.CreateTestDirectory()) + { + string configFileName = "nuget.config"; + string configFilePath = Path.Combine(configFileDirectory, configFileName); + string updateSource = "https://source.test"; var nugetConfig = @" @@ -191,19 +308,17 @@ public void Sources_WarnWhenUpdatingHttpSource(string updateSource, bool shouldW // Assert ISettings loadedSettings = Settings.LoadDefaultSettings(root: configFileDirectory, configFileName: null, machineWideSettings: null); - SettingSection packageSourcesSection = loadedSettings.GetSection("packageSources"); SourceItem sourceItem = packageSourcesSection?.GetFirstItemWithAttribute("key", "test_source"); Assert.Equal(updateSource, sourceItem.GetValueAsPath()); - Assert.Equal(shouldWarn, result.Output.Contains("warn : You are running the 'update source' operation with an 'HTTP' source")); } } [PlatformTheory(Platform.Windows)] - [InlineData("http://source.test", "http://source.test.2", true, "warn : You are running the 'list source' operation with 'HTTP' source")] - [InlineData("https://source.test", "http://source.test.2", true, "warn : You are running the 'list source' operation with an 'HTTP' source")] - [InlineData("https://source.test", "https://source.test.2", false, "warn")] - public void Sources_WarnWhenListHttpSource(string initialSource, string secondSource, bool shouldWarn, string warningMessage) + [InlineData("http://source.test", "http://source.test.2", new[] { "http://source.test", "http://source.test.2" })] + [InlineData("https://source.test", "http://source.test.2", new[] { "http://source.test.2" })] + [InlineData("http://source.test", "https://source.test.2", new[] { "http://source.test" })] + public void ListSources_WhenHttpSources_ErrorsForEachHttpSource(string initialSource, string secondSource, string[] httpSources) { using (TestDirectory configFileDirectory = _fixture.CreateTestDirectory()) { @@ -214,8 +329,8 @@ public void Sources_WarnWhenListHttpSource(string initialSource, string secondSo @" - - + + ", initialSource, secondSource); CreateXmlFile(configFilePath, nugetConfig); @@ -227,7 +342,23 @@ public void Sources_WarnWhenListHttpSource(string initialSource, string secondSo "list", "source", }; + List httpPackageSources = new List(); + string expectedError = ""; + + for (int i = 0; i < httpSources.Count(); i++) + { + var source = httpSources[i]; + httpPackageSources.Add(new PackageSource(source, $"source{i}")); + } + if (httpPackageSources.Count == 1) + { + expectedError = string.Format(Strings.Warning_List_HttpSource, httpPackageSources.First().Source); + } + else + { + expectedError = string.Format(Strings.Warning_List_HttpSources, httpPackageSources.Select(e => e.Name)); + } // Act ISettings settings = Settings.LoadDefaultSettings( configFileDirectory, @@ -238,31 +369,28 @@ public void Sources_WarnWhenListHttpSource(string initialSource, string secondSo CommandRunnerResult result = _fixture.RunDotnetExpectSuccess(configFileDirectory, string.Join(" ", args), testOutputHelper: _testOutputHelper); // Assert - Assert.Equal(shouldWarn, result.Output.Contains(warningMessage)); + Assert.Contains(initialSource, result.AllOutput); + Assert.Contains(secondSource, result.AllOutput); } } - [Fact] - public void SourcesList_WithAllowInsecureConnections_WarnsCorrectly() + [PlatformFact(Platform.Windows)] + public void Sources_WhenEnableHttpSource() { using (TestDirectory configFileDirectory = _fixture.CreateTestDirectory()) { string configFileName = "nuget.config"; string configFilePath = Path.Combine(configFileDirectory, configFileName); - string nugetConfig = + + var nugetConfig = @" - - - - - - - - - + + + + "; CreateXmlFile(configFilePath, nugetConfig); @@ -270,8 +398,9 @@ public void SourcesList_WithAllowInsecureConnections_WarnsCorrectly() var args = new string[] { "nuget", - "list", + "enable", "source", + "test_source", }; // Act @@ -280,25 +409,39 @@ public void SourcesList_WithAllowInsecureConnections_WarnsCorrectly() configFileName, null); + PackageSourceProvider packageSourceProvider = new PackageSourceProvider(settings); + var sources = packageSourceProvider.LoadPackageSources().ToList(); + Assert.Single(sources); + + PackageSource source = sources.Single(); + Assert.Equal("test_source", source.Name); + Assert.Equal("https://source.test", source.Source); + Assert.False(source.IsEnabled); + // Act CommandRunnerResult result = _fixture.RunDotnetExpectSuccess(configFileDirectory, string.Join(" ", args), testOutputHelper: _testOutputHelper); // Assert - // http source with false allowInsecureConnections have warnings. - string expectedWarning = SettingsTestUtils.RemoveWhitespace(@" -warn : You are running the 'list source' operation with 'HTTP' sources: -warn : source1 -warn : source2 -warn : source3 -warn : source4 -warn : source5 -warn : Non-HTTPS access will be removed in a future version. Consider migrating to 'HTTPS' sources."); - Assert.Contains(expectedWarning, SettingsTestUtils.RemoveWhitespace(result.Output)); + settings = Settings.LoadDefaultSettings( + configFileDirectory, + configFileName, + null); + + packageSourceProvider = new PackageSourceProvider(settings); + sources = packageSourceProvider.LoadPackageSources().ToList(); + + var testSources = sources.Where(s => s.Name == "test_source"); + Assert.Single(testSources); + source = testSources.Single(); + + Assert.Equal("test_source", source.Name); + Assert.Equal("https://source.test", source.Source); + Assert.True(source.IsEnabled); } } [PlatformFact(Platform.Windows)] - public void Sources_WarnWhenEnableHttpSource() + public void Sources_ErrorWhenEnableHttpSource() { using (TestDirectory configFileDirectory = _fixture.CreateTestDirectory()) { @@ -342,24 +485,12 @@ public void Sources_WarnWhenEnableHttpSource() Assert.False(source.IsEnabled); // Act - CommandRunnerResult result = _fixture.RunDotnetExpectSuccess(configFileDirectory, string.Join(" ", args), testOutputHelper: _testOutputHelper); + CommandRunnerResult result = _fixture.RunDotnetExpectFailure(configFileDirectory, string.Join(" ", args)); // Assert - settings = Settings.LoadDefaultSettings( - configFileDirectory, - configFileName, - null); - - packageSourceProvider = new PackageSourceProvider(settings); - sources = packageSourceProvider.LoadPackageSources().ToList(); - - var testSources = sources.Where(s => s.Name == "test_source"); - Assert.Single(testSources); - source = testSources.Single(); - - Assert.Equal("test_source", source.Name); - Assert.Equal("http://source.test", source.Source); - Assert.True(result.Output.Contains("warn : You are running the 'enable source' operation with an 'HTTP' source, 'http://source.test'. Non-HTTPS access will be removed in a future version. Consider migrating to an 'HTTPS' source.")); + string expectedError = string.Format(CultureInfo.CurrentCulture, Strings.Error_HttpSource_Single, "enable source", "http://source.test"); + Assert.Equal(1, result.ExitCode); + Assert.Contains(expectedError, result.AllOutput); } } diff --git a/test/NuGet.Core.FuncTests/Msbuild.Integration.Test/MsbuildRestoreTaskTests.cs b/test/NuGet.Core.FuncTests/Msbuild.Integration.Test/MsbuildRestoreTaskTests.cs index 1f25fee3c7d..77d6ebda4f2 100644 --- a/test/NuGet.Core.FuncTests/Msbuild.Integration.Test/MsbuildRestoreTaskTests.cs +++ b/test/NuGet.Core.FuncTests/Msbuild.Integration.Test/MsbuildRestoreTaskTests.cs @@ -1146,7 +1146,7 @@ public void MsbuildRestore_WithCPPCliVcxproj_WithProjectReferenceAndWindowsWindo [PlatformTheory(Platform.Windows)] [InlineData(true)] [InlineData(false)] - public async Task MsbuildRestore_PackagesConfigDependency_WithHttpSource_Warns(bool useStaticGraphEvaluation) + public async Task MsbuildRestore_PackagesConfigDependency_WithHttpSource_Errors(bool useStaticGraphEvaluation) { // Arrange using (var pathContext = new SimpleTestPathContext()) @@ -1188,24 +1188,20 @@ await SimpleTestPackageUtility.CreateFolderFeedV3Async( packageX); // Act + string errorForHttpSource = string.Format(NuGet.PackageManagement.Strings.Error_HttpSource_Single, "restore", "http://api.source/index.json"); string args = $"/t:restore {pathContext.SolutionRoot} /p:RestorePackagesConfig=true /p:RestoreUseStaticGraphEvaluation={useStaticGraphEvaluation}"; var result = _msbuildFixture.RunMsBuild(pathContext.WorkingDirectory, args, ignoreExitCode: true, testOutputHelper: _testOutputHelper); // Assert - Assert.True(result.ExitCode == 0, result.AllOutput); - Assert.Contains("Added package 'x.1.0.0' to folder", result.AllOutput); - Assert.Contains("You are running the 'restore' operation with an 'HTTP' source, 'http://api.source/index.json'. Non-HTTPS access will be removed in a future version. Consider migrating to an 'HTTPS' source.", result.Output); + Assert.Equal(1, result.ExitCode); + Assert.Contains(errorForHttpSource, result.AllOutput); } } [PlatformTheory(Platform.Windows)] - [InlineData("false", true)] - [InlineData("FALSE", true)] - [InlineData("invalidString", true)] - [InlineData("", true)] - [InlineData("true", false)] - [InlineData("TRUE", false)] - public async Task MsbuildRestore_PackagesConfigDependency_WithHttpSourceAndAllowInsecureConnections_WarnsCorrectly(string allowInsecureConnections, bool hasHttpWarning) + [InlineData("true")] + [InlineData("TRUE")] + public async Task MsbuildRestore_PackagesConfigDependency_WithHttpSourceAndAllowInsecureConnectionsTrue_ShouldNotError(string allowInsecureConnections) { // Arrange using (var pathContext = new SimpleTestPathContext()) @@ -1248,24 +1244,74 @@ await SimpleTestPackageUtility.CreateFolderFeedV3Async( var result = _msbuildFixture.RunMsBuild(pathContext.WorkingDirectory, $"/t:restore {pathContext.SolutionRoot} /p:RestorePackagesConfig=true", ignoreExitCode: true, testOutputHelper: _testOutputHelper); // Assert - string formatString = "You are running the 'restore' operation with an 'HTTP' source, '{0}'. Non-HTTPS access will be removed in a future version. Consider migrating to an 'HTTPS'"; - string warningForHttpSource = string.Format(formatString, "http://api.source/index.json"); - string warningForHttpsSource = string.Format(formatString, "https://api.source/index.json"); + string errorForHttpSource = string.Format(NuGet.PackageManagement.Strings.Error_HttpSource_Single, "restore", "http://api.source/index.json"); + string errorForHttpsSource = string.Format(NuGet.PackageManagement.Strings.Error_HttpSource_Single, "restore", "https://api.source/index.json"); Assert.True(result.ExitCode == 0, result.AllOutput); Assert.Contains("Added package 'x.1.0.0' to folder", result.AllOutput); - Assert.DoesNotContain(warningForHttpsSource, result.Output); - if (hasHttpWarning) + Assert.DoesNotContain(errorForHttpsSource, result.Output); + Assert.DoesNotContain(errorForHttpSource, result.Output); + } + } + + [PlatformTheory(Platform.Windows)] + [InlineData("false")] + [InlineData("FALSE")] + [InlineData("invalidString")] + [InlineData("")] + public async Task MsbuildRestore_PackagesConfigDependency_WithHttpSourceAndAllowInsecureConnectionsFalse_ShouldError(string allowInsecureConnections) + { + // Arrange + using (var pathContext = new SimpleTestPathContext()) + { + // Set up solution, project, and packages + pathContext.Settings.AddSource("http-feed", "http://api.source/index.json", allowInsecureConnections); + pathContext.Settings.AddSource("https-feed", "https://api.source/index.json", allowInsecureConnections); + + var solution = new SimpleTestSolutionContext(pathContext.SolutionRoot); + var net461 = NuGetFramework.Parse("net472"); + var projectA = new SimpleTestProjectContext( + "a", + ProjectStyle.PackagesConfig, + pathContext.SolutionRoot); + projectA.Frameworks.Add(new SimpleTestProjectFrameworkContext(net461)); + + var packageX = new SimpleTestPackageContext() { - Assert.Contains(warningForHttpSource, result.Output); - } - else + Id = "x", + Version = "1.0.0" + }; + packageX.AddFile("lib/net472/a.dll"); + + solution.Projects.Add(projectA); + solution.Create(pathContext.SolutionRoot); + + using (var writer = new StreamWriter(Path.Combine(Path.GetDirectoryName(projectA.ProjectPath), "packages.config"))) { - Assert.DoesNotContain(warningForHttpSource, result.Output); + writer.Write( +@" + +"); } + + await SimpleTestPackageUtility.CreateFolderFeedV3Async( + pathContext.PackageSource, + packageX); + + // Act + var result = _msbuildFixture.RunMsBuild(pathContext.WorkingDirectory, $"/t:restore {pathContext.SolutionRoot} /p:RestorePackagesConfig=true", ignoreExitCode: true); + + // Assert + string errorForHttpSource = string.Format(NuGet.PackageManagement.Strings.Error_HttpSource_Single, "restore", "http://api.source/index.json"); + string errorForHttpsSource = string.Format(NuGet.PackageManagement.Strings.Error_HttpSource_Single, "restore", "https://api.source/index.json"); + + Assert.True(result.ExitCode == 1, result.AllOutput); + Assert.DoesNotContain(errorForHttpsSource, result.Output); + Assert.Contains(errorForHttpSource, result.Output); } } + [PlatformTheory(Platform.Windows)] [InlineData(true)] [InlineData(false)] @@ -1455,7 +1501,7 @@ public async Task MsbuildRestore_PackagesConfigProject_PackagesWithVulnerabiliti (new Uri("https://contoso.com/advisories/12346"), PackageVulnerabilitySeverity.Critical, VersionRange.Parse("[1.2.0, 2.0.0)")) }); pathContext.Settings.RemoveSource("source"); - pathContext.Settings.AddSource("source", mockServer.ServiceIndexUri); + pathContext.Settings.AddSource("source", mockServer.ServiceIndexUri, allowInsecureConnectionsValue: "true"); // set up solution, projects and packages var solution = new SimpleTestSolutionContext(pathContext.SolutionRoot); @@ -1547,7 +1593,7 @@ public async Task MsbuildRestore_WithMultipleProjectsInSameDirectory_RaisesAppro (new Uri("https://contoso.com/advisories/12346"), PackageVulnerabilitySeverity.Critical, VersionRange.Parse("[1.2.0, 2.0.0)")) }); pathContext.Settings.RemoveSource("source"); - pathContext.Settings.AddSource("source", mockServer.ServiceIndexUri); + pathContext.Settings.AddSource("source", mockServer.ServiceIndexUri, allowInsecureConnectionsValue: "true"); var packageA1 = new SimpleTestPackageContext() { diff --git a/test/NuGet.Core.FuncTests/NuGet.Commands.FuncTest/RestoreCommandTests.cs b/test/NuGet.Core.FuncTests/NuGet.Commands.FuncTest/RestoreCommandTests.cs index 2599ab1c64f..18e62903cb7 100644 --- a/test/NuGet.Core.FuncTests/NuGet.Commands.FuncTest/RestoreCommandTests.cs +++ b/test/NuGet.Core.FuncTests/NuGet.Commands.FuncTest/RestoreCommandTests.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Linq; using System.Threading; @@ -4065,10 +4066,8 @@ await SimpleTestPackageUtility.CreateFolderFeedV3Async( } } - [Theory] - [InlineData("true", false)] - [InlineData("false", true)] - public async Task Restore_WithHttpSource_Warns(string allowInsecureConnections, bool isHttpWarningExpected) + [Fact] + public async Task Restore_WithHttpSourceAndAllowInsecureConnectionsFalse_ThrowsError() { // Arrange using var pathContext = new SimpleTestPathContext(); @@ -4076,8 +4075,8 @@ public async Task Restore_WithHttpSource_Warns(string allowInsecureConnections, await SimpleTestPackageUtility.CreateFolderFeedV3Async(pathContext.PackageSource, packageA); string httpSourceUrl = "http://api.source/index.json"; string httpsSourceUrl = "https://api.source/index.json"; - pathContext.Settings.AddSource("http-feed", httpSourceUrl, allowInsecureConnections); - pathContext.Settings.AddSource("https-feed", httpsSourceUrl, allowInsecureConnections); + pathContext.Settings.AddSource("http-feed", httpSourceUrl, "False"); + pathContext.Settings.AddSource("https-feed", httpsSourceUrl, "False"); var logger = new TestLogger(); ISettings settings = Settings.LoadDefaultSettings(pathContext.SolutionRoot); @@ -4089,22 +4088,39 @@ public async Task Restore_WithHttpSource_Warns(string allowInsecureConnections, var result = await command.ExecuteAsync(); // Assert - result.Success.Should().BeTrue(because: logger.ShowMessages()); - result.LockFile.Libraries.Should().HaveCount(0); + result.Success.Should().BeFalse(because: logger.ShowMessages()); + result.LockFile.LogMessages.Should().HaveCount(1); + IAssetsLogMessage logMessage = result.LockFile.LogMessages[0]; + logMessage.Code.Should().Be(NuGetLogCode.NU1302); + Assert.Contains(httpSourceUrl, logMessage.Message); + } - string expectedWarning = $"You are running the 'restore' operation with an 'HTTP' source, '{httpSourceUrl}'. Non-HTTPS access will be removed in a future version. Consider migrating to an 'HTTPS' source."; + [Fact] + public async Task Restore_WithHttpSourceAndAllowInsecureConnectionsTrue_Succeeds() + { + // Arrange + using var pathContext = new SimpleTestPathContext(); + var packageA = new SimpleTestPackageContext("a", "1.0.0"); + await SimpleTestPackageUtility.CreateFolderFeedV3Async(pathContext.PackageSource, packageA); + string httpSourceUrl = "http://api.source/index.json"; + string httpsSourceUrl = "https://api.source/index.json"; + pathContext.Settings.AddSource("http-feed", httpSourceUrl, "True"); + pathContext.Settings.AddSource("https-feed", httpsSourceUrl, "True"); - if (isHttpWarningExpected) - { - result.LockFile.LogMessages.Should().HaveCount(1); - IAssetsLogMessage logMessage = result.LockFile.LogMessages[0]; - logMessage.Code.Should().Be(NuGetLogCode.NU1803); - Assert.Equal(expectedWarning, logMessage.Message); - } - else - { - result.LockFile.LogMessages.Should().HaveCount(0); - } + var logger = new TestLogger(); + ISettings settings = Settings.LoadDefaultSettings(pathContext.SolutionRoot); + var project1Spec = ProjectTestHelpers.GetPackageSpec(settings, "Project1", pathContext.SolutionRoot, framework: "net5.0"); + var request = ProjectTestHelpers.CreateRestoreRequest(pathContext, logger, project1Spec); + var command = new RestoreCommand(request); + + // Act + var result = await command.ExecuteAsync(); + + // Assert + string expectedError = string.Format(CultureInfo.CurrentCulture, NuGet.PackageManagement.Strings.Error_HttpSource_Single, "restore", httpSourceUrl); + + result.Success.Should().BeTrue(because: logger.ShowMessages()); + result.LockFile.LogMessages.Should().HaveCount(0); } [Fact] diff --git a/test/TestUtilities/Test.Utility/SimpleTestSetup/SimpleTestSettingsContext.cs b/test/TestUtilities/Test.Utility/SimpleTestSetup/SimpleTestSettingsContext.cs index ba28839f557..36ecf241bdd 100644 --- a/test/TestUtilities/Test.Utility/SimpleTestSetup/SimpleTestSettingsContext.cs +++ b/test/TestUtilities/Test.Utility/SimpleTestSetup/SimpleTestSettingsContext.cs @@ -164,6 +164,16 @@ public static void AddEntry(XElement section, string key, string value, string a section.Add(setting); } + public static void AddEntry(XElement section, string key, string value, string additionalAtrributeName, string additionalAttributeValue, string additionalAtrributeName2, string additionalAttributeValue2) + { + var setting = new XElement(XName.Get("add")); + setting.Add(new XAttribute(XName.Get("key"), key)); + setting.Add(new XAttribute(XName.Get("value"), value)); + setting.Add(new XAttribute(XName.Get(additionalAtrributeName), additionalAttributeValue)); + setting.Add(new XAttribute(XName.Get(additionalAtrributeName2), additionalAttributeValue2)); + section.Add(setting); + } + public static void AddSetting(XDocument doc, string key, string value) { RemoveSetting(doc, key);