diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ef63f5b8..03ef98977 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Snyk Changelog +## [1.1.38] + +### Fixed +- Custom endpoints validation in the settings page did not work correctly and led to crashes. + ## [1.1.37] ### Fixed diff --git a/Snyk.VisualStudio.Extension.Shared/CLI/SnykCli.cs b/Snyk.VisualStudio.Extension.Shared/CLI/SnykCli.cs index 2a4fc3ce5..b5e089f17 100644 --- a/Snyk.VisualStudio.Extension.Shared/CLI/SnykCli.cs +++ b/Snyk.VisualStudio.Extension.Shared/CLI/SnykCli.cs @@ -81,7 +81,7 @@ public string GetApiToken() } catch (InvalidTokenException e) { - Logger.Error(e, "Error on get api token via cli for settings"); + Logger.Warning(e, "Failed to retrieve api token from CLI configuration"); apiToken = string.Empty; } diff --git a/Snyk.VisualStudio.Extension.Shared/Settings/ErrorProviderExtensions.cs b/Snyk.VisualStudio.Extension.Shared/Settings/ErrorProviderExtensions.cs new file mode 100644 index 000000000..1d6665e8b --- /dev/null +++ b/Snyk.VisualStudio.Extension.Shared/Settings/ErrorProviderExtensions.cs @@ -0,0 +1,11 @@ +using System.Data.SqlClient; + +namespace Snyk.VisualStudio.Extension.Shared.Settings; + +using System.Windows.Forms; + +public static class ErrorProviderExtensions +{ + public static void SetNoError(this ErrorProvider errorProvider, Control control) => + errorProvider.SetError(control, string.Empty); +} \ No newline at end of file diff --git a/Snyk.VisualStudio.Extension.Shared/Settings/SnykGeneralOptionsDialogPage.cs b/Snyk.VisualStudio.Extension.Shared/Settings/SnykGeneralOptionsDialogPage.cs index 65c6ff2c7..d92e6fd93 100644 --- a/Snyk.VisualStudio.Extension.Shared/Settings/SnykGeneralOptionsDialogPage.cs +++ b/Snyk.VisualStudio.Extension.Shared/Settings/SnykGeneralOptionsDialogPage.cs @@ -93,6 +93,12 @@ public string CustomEndpoint get => this.customEndpoint; set { + if (!Uri.IsWellFormedUriString(value, UriKind.Absolute)) + { + Logger.Warning("Custom endpoint value is not a well-formed URI. Setting custom endpoint to empty string"); + value = string.Empty; + } + if (this.customEndpoint == value) { return; diff --git a/Snyk.VisualStudio.Extension.Shared/Settings/SnykGeneralSettingsUserControl.Designer.cs b/Snyk.VisualStudio.Extension.Shared/Settings/SnykGeneralSettingsUserControl.Designer.cs index 62bca0846..1ab940804 100644 --- a/Snyk.VisualStudio.Extension.Shared/Settings/SnykGeneralSettingsUserControl.Designer.cs +++ b/Snyk.VisualStudio.Extension.Shared/Settings/SnykGeneralSettingsUserControl.Designer.cs @@ -83,7 +83,7 @@ private void InitializeComponent() this.customEndpointTextBox.Location = new System.Drawing.Point(100, 86); this.customEndpointTextBox.Margin = new System.Windows.Forms.Padding(2); this.customEndpointTextBox.Name = "customEndpointTextBox"; - this.customEndpointTextBox.Size = new System.Drawing.Size(420, 20); + this.customEndpointTextBox.Size = new System.Drawing.Size(300, 20); this.customEndpointTextBox.TabIndex = 0; this.customEndpointTextBox.LostFocus += new System.EventHandler(this.CustomEndpointTextBox_LostFocus); this.customEndpointTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.CustomEndpointTextBox_Validating); @@ -113,7 +113,7 @@ private void InitializeComponent() this.organizationTextBox.Location = new System.Drawing.Point(100, 134); this.organizationTextBox.Margin = new System.Windows.Forms.Padding(2); this.organizationTextBox.Name = "organizationTextBox"; - this.organizationTextBox.Size = new System.Drawing.Size(420, 20); + this.organizationTextBox.Size = new System.Drawing.Size(300, 20); this.organizationTextBox.TabIndex = 3; this.organizationTextBox.TextChanged += new System.EventHandler(this.OrganizationTextBox_TextChanged); // @@ -132,7 +132,7 @@ private void InitializeComponent() this.tokenTextBox.Location = new System.Drawing.Point(100, 54); this.tokenTextBox.Name = "tokenTextBox"; this.tokenTextBox.PasswordChar = '*'; - this.tokenTextBox.Size = new System.Drawing.Size(420, 20); + this.tokenTextBox.Size = new System.Drawing.Size(300, 20); this.tokenTextBox.TabIndex = 5; this.tokenTextBox.TextChanged += new System.EventHandler(this.TokenTextBox_TextChanged); this.tokenTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.TokenTextBox_Validating); @@ -165,7 +165,7 @@ private void InitializeComponent() this.authProgressBar.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3); this.authProgressBar.MarqueeAnimationSpeed = 10; this.authProgressBar.Name = "authProgressBar"; - this.authProgressBar.Size = new System.Drawing.Size(420, 5); + this.authProgressBar.Size = new System.Drawing.Size(300, 5); this.authProgressBar.Style = System.Windows.Forms.ProgressBarStyle.Marquee; this.authProgressBar.TabIndex = 8; this.authProgressBar.Visible = false; @@ -311,7 +311,7 @@ private void InitializeComponent() this.CliPathTextBox.Margin = new System.Windows.Forms.Padding(2); this.CliPathTextBox.Name = "CliPathTextBox"; this.CliPathTextBox.ReadOnly = true; - this.CliPathTextBox.Size = new System.Drawing.Size(420, 20); + this.CliPathTextBox.Size = new System.Drawing.Size(300, 20); this.CliPathTextBox.TabIndex = 15; // // CliPathLabel diff --git a/Snyk.VisualStudio.Extension.Shared/Settings/SnykGeneralSettingsUserControl.cs b/Snyk.VisualStudio.Extension.Shared/Settings/SnykGeneralSettingsUserControl.cs index 266623563..6f5b4aa13 100644 --- a/Snyk.VisualStudio.Extension.Shared/Settings/SnykGeneralSettingsUserControl.cs +++ b/Snyk.VisualStudio.Extension.Shared/Settings/SnykGeneralSettingsUserControl.cs @@ -231,20 +231,22 @@ private async Task AuthenticateButtonClickAsync() } } - private bool IsValidUrl(string url) => Uri.IsWellFormedUriString(url, UriKind.RelativeOrAbsolute); + private bool IsValidUrl(string url) => Uri.IsWellFormedUriString(url, UriKind.Absolute); private void TokenTextBox_TextChanged(object sender, EventArgs e) { - this.ValidateChildren(ValidationConstraints.Enabled); - - this.OptionsDialogPage.SetApiToken(this.tokenTextBox.Text); + if (this.ValidateChildren(ValidationConstraints.Enabled)) + { + this.OptionsDialogPage.SetApiToken(this.tokenTextBox.Text); + } } private void CustomEndpointTextBox_LostFocus(object sender, EventArgs e) { - this.ValidateChildren(ValidationConstraints.Enabled); - - this.OptionsDialogPage.CustomEndpoint = this.customEndpointTextBox.Text; + if (this.ValidateChildren(ValidationConstraints.Enabled)) + { + this.OptionsDialogPage.CustomEndpoint = this.customEndpointTextBox.Text; + } } private void OrganizationTextBox_TextChanged(object sender, EventArgs e) @@ -286,27 +288,15 @@ private void TokenTextBox_Validating(object sender, System.ComponentModel.Cancel private void CustomEndpointTextBox_Validating(object sender, System.ComponentModel.CancelEventArgs cancelEventArgs) { - if (string.IsNullOrEmpty(this.tokenTextBox.Text)) + if (string.IsNullOrWhiteSpace(this.customEndpointTextBox.Text) || this.IsValidUrl(this.customEndpointTextBox.Text)) { - this.errorProvider.SetError(this.tokenTextBox, string.Empty); - + this.errorProvider.SetNoError(this.customEndpointTextBox); return; } - if (!string.IsNullOrWhiteSpace(this.customEndpointTextBox.Text) && !this.IsValidUrl(this.customEndpointTextBox.Text)) - { - cancelEventArgs.Cancel = true; - - this.customEndpointTextBox.Focus(); - - this.errorProvider.SetError(this.customEndpointTextBox, "Not valid URL."); - } - else - { - cancelEventArgs.Cancel = false; - - this.errorProvider.SetError(this.customEndpointTextBox, string.Empty); - } + cancelEventArgs.Cancel = true; + //this.customEndpointTextBox.Focus(); + this.errorProvider.SetError(this.customEndpointTextBox, "Needs to be a full absolute well-formed URL (including protocol)"); } private void SnykGeneralSettingsUserControl_Load(object sender, EventArgs e) diff --git a/Snyk.VisualStudio.Extension.Shared/Snyk.VisualStudio.Extension.Shared.projitems b/Snyk.VisualStudio.Extension.Shared/Snyk.VisualStudio.Extension.Shared.projitems index 997803cec..35b01e9d4 100644 --- a/Snyk.VisualStudio.Extension.Shared/Snyk.VisualStudio.Extension.Shared.projitems +++ b/Snyk.VisualStudio.Extension.Shared/Snyk.VisualStudio.Extension.Shared.projitems @@ -36,6 +36,7 @@ + Component