From 20b63cf483f434d133bdb691f9e4ba432bed9fed Mon Sep 17 00:00:00 2001 From: Abdelrahman Shawki Hassan Date: Fri, 13 Dec 2024 10:49:38 +0100 Subject: [PATCH 01/16] refactor: separate options model from page --- .../Settings/SnykGeneralOptionsDialogPage.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralOptionsDialogPage.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralOptionsDialogPage.cs index 62586245..9ac64909 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralOptionsDialogPage.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralOptionsDialogPage.cs @@ -61,12 +61,12 @@ public void Initialize(ISnykServiceProvider provider) public async Task HandleAuthenticationSuccess(string token, string apiUrl) { - await this.GeneralSettingsUserControl.HandleAuthenticationSuccess(token, apiUrl); + await this.generalSettingsUserControl.HandleAuthenticationSuccess(token, apiUrl); } public async Task HandleFailedAuthentication(string errorMessage) { - await this.GeneralSettingsUserControl.HandleFailedAuthentication(errorMessage); + await this.generalSettingsUserControl.HandleFailedAuthentication(errorMessage); } protected override IWin32Window Window => GeneralSettingsUserControl; From ac9cdb3703f6b0d023a95e04be511c74fe88b701 Mon Sep 17 00:00:00 2001 From: Abdelrahman Shawki Hassan Date: Fri, 13 Dec 2024 13:19:27 +0100 Subject: [PATCH 02/16] fix: scrollbar in settings dialog --- .../Settings/SnykGeneralOptionsDialogPage.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralOptionsDialogPage.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralOptionsDialogPage.cs index 9ac64909..62586245 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralOptionsDialogPage.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralOptionsDialogPage.cs @@ -61,12 +61,12 @@ public void Initialize(ISnykServiceProvider provider) public async Task HandleAuthenticationSuccess(string token, string apiUrl) { - await this.generalSettingsUserControl.HandleAuthenticationSuccess(token, apiUrl); + await this.GeneralSettingsUserControl.HandleAuthenticationSuccess(token, apiUrl); } public async Task HandleFailedAuthentication(string errorMessage) { - await this.generalSettingsUserControl.HandleFailedAuthentication(errorMessage); + await this.GeneralSettingsUserControl.HandleFailedAuthentication(errorMessage); } protected override IWin32Window Window => GeneralSettingsUserControl; From fe3542f34302adc6a8bc14912142130cb652cfbd Mon Sep 17 00:00:00 2001 From: Abdelrahman Shawki Hassan Date: Mon, 16 Dec 2024 12:00:55 +0100 Subject: [PATCH 03/16] wip: cli settings page --- .../Settings/ISnykCliOptionsDialogPage.cs | 8 + .../Settings/SnykCliOptionsDialogPage.cs | 72 ++++++ .../SnykCliOptionsUserControl.Designer.cs | 238 ++++++++++++++++++ .../Settings/SnykCliOptionsUserControl.cs | 105 ++++++++ .../Settings/SnykCliOptionsUserControl.resx | 123 +++++++++ .../Settings/SnykGeneralOptionsDialogPage.cs | 24 -- ...SnykGeneralSettingsUserControl.Designer.cs | 179 +------------ .../SnykGeneralSettingsUserControl.cs | 73 +----- .../SnykGeneralSettingsUserControl.resx | 16 +- .../Snyk.VisualStudio.Extension.2022.csproj | 13 + .../SnykVSPackage.cs | 14 +- 11 files changed, 585 insertions(+), 280 deletions(-) create mode 100644 Snyk.VisualStudio.Extension.2022/Settings/ISnykCliOptionsDialogPage.cs create mode 100644 Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsDialogPage.cs create mode 100644 Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsUserControl.Designer.cs create mode 100644 Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsUserControl.cs create mode 100644 Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsUserControl.resx diff --git a/Snyk.VisualStudio.Extension.2022/Settings/ISnykCliOptionsDialogPage.cs b/Snyk.VisualStudio.Extension.2022/Settings/ISnykCliOptionsDialogPage.cs new file mode 100644 index 00000000..ddcbb5a8 --- /dev/null +++ b/Snyk.VisualStudio.Extension.2022/Settings/ISnykCliOptionsDialogPage.cs @@ -0,0 +1,8 @@ +using Snyk.VisualStudio.Extension.Service; + +namespace Snyk.VisualStudio.Extension.Settings; + +public interface ISnykCliOptionsDialogPage +{ + void Initialize(ISnykServiceProvider provider); +} \ No newline at end of file diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsDialogPage.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsDialogPage.cs new file mode 100644 index 00000000..5f8b0361 --- /dev/null +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsDialogPage.cs @@ -0,0 +1,72 @@ +using System; +using System.Runtime.InteropServices; +using System.Windows.Forms; +using Microsoft.VisualStudio.Shell; +using Snyk.VisualStudio.Extension.Service; + +namespace Snyk.VisualStudio.Extension.Settings; + +[Guid("D1D89CEB-7691-4A67-8579-4C3DDE776982")] +[ComVisible(true)] +public class SnykCliOptionsDialogPage : DialogPage, ISnykCliOptionsDialogPage +{ + private SnykCliOptionsUserControl snykCliOptionsUserControl; + private ISnykServiceProvider serviceProvider; + + public void Initialize(ISnykServiceProvider provider) + { + this.serviceProvider = provider; + this.SnykOptions = provider.Options; + } + + public ISnykOptions SnykOptions { get; set; } + + protected override IWin32Window Window => SnykCliOptionsUserControl; + public SnykCliOptionsUserControl SnykCliOptionsUserControl + { + get + { + if (snykCliOptionsUserControl == null) + { + snykCliOptionsUserControl = new SnykCliOptionsUserControl(serviceProvider); + } + return snykCliOptionsUserControl; + } + } + + // This method is used when the user clicks "Ok" + public override void SaveSettingsToStorage() + { + HandleCliDownload(); + this.SnykOptions.SaveSettings(); + this.SnykOptions.InvokeSettingsChangedEvent(); + } + + protected override void OnClosed(EventArgs e) + { + + } + + private void HandleCliDownload() + { + var releaseChannel = SnykCliOptionsUserControl.GetReleaseChannel().Trim(); + var downloadUrl = SnykCliOptionsUserControl.GetCliDownloadUrl().Trim(); + var manageBinariesAutomatically = SnykCliOptionsUserControl.GetManageBinariesAutomatically(); + if (!manageBinariesAutomatically) + { + this.SnykOptions.CurrentCliVersion = string.Empty; + this.SnykOptions.BinariesAutoUpdate = false; + serviceProvider.TasksService.CancelDownloadTask(); + // Language Server restart will happen on DownloadCancelled Event. + return; + } + if (this.SnykOptions.CliReleaseChannel != releaseChannel || this.SnykOptions.CliDownloadUrl != downloadUrl || this.SnykOptions.BinariesAutoUpdate != manageBinariesAutomatically) + { + this.SnykOptions.CliDownloadUrl = downloadUrl; + this.SnykOptions.CliReleaseChannel = releaseChannel; + this.SnykOptions.BinariesAutoUpdate = manageBinariesAutomatically; + serviceProvider.TasksService.CancelDownloadTask(); + this.serviceProvider.TasksService.Download(); + } + } +} \ No newline at end of file diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsUserControl.Designer.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsUserControl.Designer.cs new file mode 100644 index 00000000..5f61ead5 --- /dev/null +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsUserControl.Designer.cs @@ -0,0 +1,238 @@ +namespace Snyk.VisualStudio.Extension.Settings +{ + partial class SnykCliOptionsUserControl + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.mainPanel = new System.Windows.Forms.Panel(); + this.ExecutablesGroupBox = new System.Windows.Forms.GroupBox(); + this.ReleaseChannelLink = new System.Windows.Forms.LinkLabel(); + this.releaseChannel = new System.Windows.Forms.ComboBox(); + this.cliReleaseChannelLabel = new System.Windows.Forms.Label(); + this.cliBaseDownloadUrl = new System.Windows.Forms.Label(); + this.richTextBox1 = new System.Windows.Forms.RichTextBox(); + this.cliDownloadUrlTextBox = new System.Windows.Forms.TextBox(); + this.CliPathLabel = new System.Windows.Forms.Label(); + this.resetCliPathToDefaultButton = new System.Windows.Forms.Button(); + this.label1 = new System.Windows.Forms.Label(); + this.CliPathBrowseButton = new System.Windows.Forms.Button(); + this.manageBinariesAutomaticallyCheckbox = new System.Windows.Forms.CheckBox(); + this.CliPathTextBox = new System.Windows.Forms.TextBox(); + this.customCliPathFileDialog = new System.Windows.Forms.OpenFileDialog(); + this.mainPanel.SuspendLayout(); + this.ExecutablesGroupBox.SuspendLayout(); + this.SuspendLayout(); + // + // mainPanel + // + this.mainPanel.AutoScroll = true; + this.mainPanel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.mainPanel.Controls.Add(this.ExecutablesGroupBox); + this.mainPanel.Dock = System.Windows.Forms.DockStyle.Fill; + this.mainPanel.Location = new System.Drawing.Point(0, 0); + this.mainPanel.Name = "mainPanel"; + this.mainPanel.Size = new System.Drawing.Size(752, 285); + this.mainPanel.TabIndex = 0; + // + // ExecutablesGroupBox + // + this.ExecutablesGroupBox.Controls.Add(this.ReleaseChannelLink); + this.ExecutablesGroupBox.Controls.Add(this.releaseChannel); + this.ExecutablesGroupBox.Controls.Add(this.cliReleaseChannelLabel); + this.ExecutablesGroupBox.Controls.Add(this.cliBaseDownloadUrl); + this.ExecutablesGroupBox.Controls.Add(this.richTextBox1); + this.ExecutablesGroupBox.Controls.Add(this.cliDownloadUrlTextBox); + this.ExecutablesGroupBox.Controls.Add(this.CliPathLabel); + this.ExecutablesGroupBox.Controls.Add(this.resetCliPathToDefaultButton); + this.ExecutablesGroupBox.Controls.Add(this.label1); + this.ExecutablesGroupBox.Controls.Add(this.CliPathBrowseButton); + this.ExecutablesGroupBox.Controls.Add(this.manageBinariesAutomaticallyCheckbox); + this.ExecutablesGroupBox.Controls.Add(this.CliPathTextBox); + this.ExecutablesGroupBox.Location = new System.Drawing.Point(4, 4); + this.ExecutablesGroupBox.Margin = new System.Windows.Forms.Padding(4); + this.ExecutablesGroupBox.Name = "ExecutablesGroupBox"; + this.ExecutablesGroupBox.Padding = new System.Windows.Forms.Padding(4); + this.ExecutablesGroupBox.Size = new System.Drawing.Size(729, 261); + this.ExecutablesGroupBox.TabIndex = 20; + this.ExecutablesGroupBox.TabStop = false; + this.ExecutablesGroupBox.Text = "CLI Settings"; + // + // ReleaseChannelLink + // + this.ReleaseChannelLink.AutoSize = true; + this.ReleaseChannelLink.Location = new System.Drawing.Point(8, 241); + this.ReleaseChannelLink.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.ReleaseChannelLink.Name = "ReleaseChannelLink"; + this.ReleaseChannelLink.Size = new System.Drawing.Size(219, 16); + this.ReleaseChannelLink.TabIndex = 20; + this.ReleaseChannelLink.TabStop = true; + this.ReleaseChannelLink.Text = "Find out about our release channels"; + this.ReleaseChannelLink.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.ReleaseChannelLink_LinkClicked); + // + // releaseChannel + // + this.releaseChannel.FormattingEnabled = true; + this.releaseChannel.Location = new System.Drawing.Point(239, 208); + this.releaseChannel.Margin = new System.Windows.Forms.Padding(4); + this.releaseChannel.Name = "releaseChannel"; + this.releaseChannel.Size = new System.Drawing.Size(160, 24); + this.releaseChannel.TabIndex = 23; + // + // cliReleaseChannelLabel + // + this.cliReleaseChannelLabel.AutoSize = true; + this.cliReleaseChannelLabel.Location = new System.Drawing.Point(5, 212); + this.cliReleaseChannelLabel.Name = "cliReleaseChannelLabel"; + this.cliReleaseChannelLabel.Size = new System.Drawing.Size(128, 16); + this.cliReleaseChannelLabel.TabIndex = 22; + this.cliReleaseChannelLabel.Text = "CLI release channel:"; + // + // cliBaseDownloadUrl + // + this.cliBaseDownloadUrl.AutoSize = true; + this.cliBaseDownloadUrl.Location = new System.Drawing.Point(5, 27); + this.cliBaseDownloadUrl.Name = "cliBaseDownloadUrl"; + this.cliBaseDownloadUrl.Size = new System.Drawing.Size(194, 16); + this.cliBaseDownloadUrl.TabIndex = 20; + this.cliBaseDownloadUrl.Text = "Base URL to download the CLI: "; + // + // richTextBox1 + // + this.richTextBox1.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.richTextBox1.Location = new System.Drawing.Point(9, 155); + this.richTextBox1.Margin = new System.Windows.Forms.Padding(4); + this.richTextBox1.Name = "richTextBox1"; + this.richTextBox1.ReadOnly = true; + this.richTextBox1.Size = new System.Drawing.Size(684, 39); + this.richTextBox1.TabIndex = 18; + this.richTextBox1.Text = "Snyk will download, install and update the dependencies for you. If this option i" + + "s disabled, make sure valid paths to the dependencies are provided."; + // + // cliDownloadUrlTextBox + // + this.cliDownloadUrlTextBox.Location = new System.Drawing.Point(241, 23); + this.cliDownloadUrlTextBox.Margin = new System.Windows.Forms.Padding(4); + this.cliDownloadUrlTextBox.Name = "cliDownloadUrlTextBox"; + this.cliDownloadUrlTextBox.Size = new System.Drawing.Size(399, 22); + this.cliDownloadUrlTextBox.TabIndex = 21; + // + // CliPathLabel + // + this.CliPathLabel.AutoSize = true; + this.CliPathLabel.Location = new System.Drawing.Point(5, 71); + this.CliPathLabel.Name = "CliPathLabel"; + this.CliPathLabel.Size = new System.Drawing.Size(92, 16); + this.CliPathLabel.TabIndex = 14; + this.CliPathLabel.Text = "Snyk CLI Path:"; + // + // resetCliPathToDefaultButton + // + this.resetCliPathToDefaultButton.Location = new System.Drawing.Point(347, 65); + this.resetCliPathToDefaultButton.Margin = new System.Windows.Forms.Padding(4); + this.resetCliPathToDefaultButton.Name = "resetCliPathToDefaultButton"; + this.resetCliPathToDefaultButton.Size = new System.Drawing.Size(129, 28); + this.resetCliPathToDefaultButton.TabIndex = 17; + this.resetCliPathToDefaultButton.Text = "Reset to default"; + this.resetCliPathToDefaultButton.UseVisualStyleBackColor = true; + this.resetCliPathToDefaultButton.Click += new System.EventHandler(this.ClearCliCustomPathButton_Click); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(41, 132); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(320, 16); + this.label1.TabIndex = 12; + this.label1.Text = "Update and install Snyk dependencies automatically"; + // + // CliPathBrowseButton + // + this.CliPathBrowseButton.Location = new System.Drawing.Point(239, 65); + this.CliPathBrowseButton.Margin = new System.Windows.Forms.Padding(4); + this.CliPathBrowseButton.Name = "CliPathBrowseButton"; + this.CliPathBrowseButton.Size = new System.Drawing.Size(100, 28); + this.CliPathBrowseButton.TabIndex = 16; + this.CliPathBrowseButton.Text = "Browse"; + this.CliPathBrowseButton.UseVisualStyleBackColor = true; + this.CliPathBrowseButton.Click += new System.EventHandler(this.CliPathBrowseButton_Click); + // + // manageBinariesAutomaticallyCheckbox + // + this.manageBinariesAutomaticallyCheckbox.AutoSize = true; + this.manageBinariesAutomaticallyCheckbox.Location = new System.Drawing.Point(16, 132); + this.manageBinariesAutomaticallyCheckbox.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); + this.manageBinariesAutomaticallyCheckbox.Name = "manageBinariesAutomaticallyCheckbox"; + this.manageBinariesAutomaticallyCheckbox.Size = new System.Drawing.Size(18, 17); + this.manageBinariesAutomaticallyCheckbox.TabIndex = 13; + this.manageBinariesAutomaticallyCheckbox.UseVisualStyleBackColor = true; + // + // CliPathTextBox + // + this.CliPathTextBox.Location = new System.Drawing.Point(241, 96); + this.CliPathTextBox.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); + this.CliPathTextBox.Name = "CliPathTextBox"; + this.CliPathTextBox.ReadOnly = true; + this.CliPathTextBox.Size = new System.Drawing.Size(399, 22); + this.CliPathTextBox.TabIndex = 15; + // + // customCliPathFileDialog + // + this.customCliPathFileDialog.SupportMultiDottedExtensions = true; + // + // SnykCliOptionsUserControl + // + this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.mainPanel); + this.Name = "SnykCliOptionsUserControl"; + this.Size = new System.Drawing.Size(752, 285); + this.mainPanel.ResumeLayout(false); + this.ExecutablesGroupBox.ResumeLayout(false); + this.ExecutablesGroupBox.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Panel mainPanel; + private System.Windows.Forms.GroupBox ExecutablesGroupBox; + private System.Windows.Forms.LinkLabel ReleaseChannelLink; + private System.Windows.Forms.ComboBox releaseChannel; + private System.Windows.Forms.Label cliReleaseChannelLabel; + private System.Windows.Forms.Label cliBaseDownloadUrl; + private System.Windows.Forms.RichTextBox richTextBox1; + private System.Windows.Forms.TextBox cliDownloadUrlTextBox; + private System.Windows.Forms.Label CliPathLabel; + private System.Windows.Forms.Button resetCliPathToDefaultButton; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Button CliPathBrowseButton; + private System.Windows.Forms.CheckBox manageBinariesAutomaticallyCheckbox; + private System.Windows.Forms.TextBox CliPathTextBox; + private System.Windows.Forms.OpenFileDialog customCliPathFileDialog; + } +} diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsUserControl.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsUserControl.cs new file mode 100644 index 00000000..6cda1928 --- /dev/null +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsUserControl.cs @@ -0,0 +1,105 @@ +using System.Collections.Generic; +using System.Diagnostics; +using System.Windows.Forms; +using Microsoft.VisualStudio.Shell; +using Serilog; +using Snyk.VisualStudio.Extension.CLI; +using Snyk.VisualStudio.Extension.Service; + +namespace Snyk.VisualStudio.Extension.Settings +{ + public partial class SnykCliOptionsUserControl : UserControl + { + private readonly ISnykServiceProvider serviceProvider; + private readonly ISnykOptions snykOptions; + private static readonly ILogger Logger = LogManager.ForContext(); + + public SnykCliOptionsUserControl(ISnykServiceProvider serviceProvider) + { + this.serviceProvider = serviceProvider; + snykOptions = this.serviceProvider.Options; + InitializeComponent(); + this.Initialize(); + } + private void Initialize() + { + this.UpdateViewFromOptions(); + } + + private void UpdateViewFromOptions() + { + this.manageBinariesAutomaticallyCheckbox.Checked = snykOptions.BinariesAutoUpdate; + this.cliDownloadUrlTextBox.Text = snykOptions.CliDownloadUrl; + + var cliPath = string.IsNullOrEmpty(snykOptions.CliCustomPath) + ? SnykCli.GetSnykCliDefaultPath() + : snykOptions.CliCustomPath; + + this.CliPathTextBox.Text = cliPath; + if (releaseChannel.DataSource == null) + { + this.releaseChannel.DataSource = ReleaseChannelList(); + } + + this.releaseChannel.SelectedItem = snykOptions.CliReleaseChannel; + } + + private IEnumerable ReleaseChannelList() + { + var defaultList = new List() { "stable", "rc", "preview" }; + if (!defaultList.Contains(snykOptions.CliReleaseChannel)) + { + defaultList.Add(snykOptions.CliReleaseChannel); + } + return defaultList; + } + + private void CliPathBrowseButton_Click(object sender, System.EventArgs e) + { + if(this.customCliPathFileDialog.ShowDialog() == DialogResult.OK) + { + var selectedCliPath = this.customCliPathFileDialog.FileName; + this.SetCliCustomPathValue(selectedCliPath); + } + } + + private void SetCliCustomPathValue(string selectedCliPath) + { + snykOptions.CliCustomPath = selectedCliPath; + this.CliPathTextBox.Text = string.IsNullOrEmpty(snykOptions.CliCustomPath) + ? SnykCli.GetSnykCliDefaultPath() + : selectedCliPath; + } + + private void ClearCliCustomPathButton_Click(object sender, System.EventArgs e) + { + this.SetCliCustomPathValue(string.Empty); + } + + private void ReleaseChannelLink_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + this.ReleaseChannelLink.LinkVisited = true; + Process.Start("https://docs.snyk.io/snyk-cli/releases-and-channels-for-the-snyk-cli"); + } + + public string GetReleaseChannel() + { + return releaseChannel.Text; + } + + public string GetCliDownloadUrl() + { + return cliDownloadUrlTextBox.Text; + } + + public bool GetManageBinariesAutomatically() + { + return manageBinariesAutomaticallyCheckbox.Checked; + } + + public Panel GetPanel() + { + return this.mainPanel; + } + } +} diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsUserControl.resx b/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsUserControl.resx new file mode 100644 index 00000000..1e62546b --- /dev/null +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsUserControl.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + \ No newline at end of file diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralOptionsDialogPage.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralOptionsDialogPage.cs index 62586245..d944dd1c 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralOptionsDialogPage.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralOptionsDialogPage.cs @@ -86,34 +86,10 @@ public SnykGeneralSettingsUserControl GeneralSettingsUserControl // This method is used when the user clicks "Ok" public override void SaveSettingsToStorage() { - HandleCliDownload(); this.SnykOptions.SaveSettings(); this.SnykOptions.InvokeSettingsChangedEvent(); } - private void HandleCliDownload() - { - var releaseChannel = generalSettingsUserControl.GetReleaseChannel().Trim(); - var downloadUrl = generalSettingsUserControl.GetCliDownloadUrl().Trim(); - var manageBinariesAutomatically = generalSettingsUserControl.GetManageBinariesAutomatically(); - if (!manageBinariesAutomatically) - { - this.SnykOptions.CurrentCliVersion = string.Empty; - this.SnykOptions.BinariesAutoUpdate = false; - serviceProvider.TasksService.CancelDownloadTask(); - // Language Server restart will happen on DownloadCancelled Event. - return; - } - if (this.SnykOptions.CliReleaseChannel != releaseChannel || this.SnykOptions.CliDownloadUrl != downloadUrl || this.SnykOptions.BinariesAutoUpdate != manageBinariesAutomatically) - { - this.SnykOptions.CliDownloadUrl = downloadUrl; - this.SnykOptions.CliReleaseChannel = releaseChannel; - this.SnykOptions.BinariesAutoUpdate = manageBinariesAutomatically; - serviceProvider.TasksService.CancelDownloadTask(); - this.serviceProvider.TasksService.Download(); - } - } - private void SnykGeneralOptionsDialogPage_SettingsChanged(object sender, SnykSettingsChangedEventArgs e) { ThreadHelper.JoinableTaskFactory.RunAsync(async () => diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.Designer.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.Designer.cs index 0de34f58..f540adb6 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.Designer.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.Designer.cs @@ -52,13 +52,6 @@ private void InitializeComponent() this.label2 = new System.Windows.Forms.Label(); this.OrganizationInfoLink = new System.Windows.Forms.LinkLabel(); this.OrgDescriptionText = new System.Windows.Forms.Label(); - this.richTextBox1 = new System.Windows.Forms.RichTextBox(); - this.resetCliPathToDefaultButton = new System.Windows.Forms.Button(); - this.CliPathBrowseButton = new System.Windows.Forms.Button(); - this.CliPathTextBox = new System.Windows.Forms.TextBox(); - this.CliPathLabel = new System.Windows.Forms.Label(); - this.ManageBinariesAutomaticallyCheckbox = new System.Windows.Forms.CheckBox(); - this.label1 = new System.Windows.Forms.Label(); this.productSelectionGroupBox = new System.Windows.Forms.GroupBox(); this.label4 = new System.Windows.Forms.Label(); this.label3 = new System.Windows.Forms.Label(); @@ -80,19 +73,12 @@ private void InitializeComponent() this.snykCodeSecurityInfoToolTip = new System.Windows.Forms.ToolTip(this.components); this.snykCodeQualityInfoToolTip = new System.Windows.Forms.ToolTip(this.components); this.customCliPathFileDialog = new System.Windows.Forms.OpenFileDialog(); - this.ExecutablesGroupBox = new System.Windows.Forms.GroupBox(); - this.ReleaseChannelLink = new System.Windows.Forms.LinkLabel(); - this.releaseChannel = new System.Windows.Forms.ComboBox(); - this.cliReleaseChannelLabel = new System.Windows.Forms.Label(); - this.cliBaseDownloadUrl = new System.Windows.Forms.Label(); - this.cliDownloadUrlTextBox = new System.Windows.Forms.TextBox(); this.mainPanel = new System.Windows.Forms.Panel(); ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit(); this.generalSettingsGroupBox.SuspendLayout(); this.productSelectionGroupBox.SuspendLayout(); this.ignoreGroupbox.SuspendLayout(); this.userExperienceGroupBox.SuspendLayout(); - this.ExecutablesGroupBox.SuspendLayout(); this.mainPanel.SuspendLayout(); this.SuspendLayout(); // @@ -304,77 +290,6 @@ private void InitializeComponent() this.OrgDescriptionText.Text = "Specify an organization slug name to run tests for that organization.\r\nIt must ma" + "tch the URL slug as displayed in the URL of your org in the Snyk UI:\r\nhttps://ap" + "p.snyk.io/org/[OrgSlugName]"; - // - // richTextBox1 - // - this.richTextBox1.BorderStyle = System.Windows.Forms.BorderStyle.None; - this.richTextBox1.Location = new System.Drawing.Point(9, 155); - this.richTextBox1.Margin = new System.Windows.Forms.Padding(4); - this.richTextBox1.Name = "richTextBox1"; - this.richTextBox1.ReadOnly = true; - this.richTextBox1.Size = new System.Drawing.Size(684, 39); - this.richTextBox1.TabIndex = 18; - this.richTextBox1.Text = "Snyk will download, install and update the dependencies for you. If this option i" + - "s disabled, make sure valid paths to the dependencies are provided."; - // - // resetCliPathToDefaultButton - // - this.resetCliPathToDefaultButton.Location = new System.Drawing.Point(347, 65); - this.resetCliPathToDefaultButton.Margin = new System.Windows.Forms.Padding(4); - this.resetCliPathToDefaultButton.Name = "resetCliPathToDefaultButton"; - this.resetCliPathToDefaultButton.Size = new System.Drawing.Size(129, 28); - this.resetCliPathToDefaultButton.TabIndex = 17; - this.resetCliPathToDefaultButton.Text = "Reset to default"; - this.resetCliPathToDefaultButton.UseVisualStyleBackColor = true; - this.resetCliPathToDefaultButton.Click += new System.EventHandler(this.ClearCliCustomPathButton_Click); - // - // CliPathBrowseButton - // - this.CliPathBrowseButton.Location = new System.Drawing.Point(239, 65); - this.CliPathBrowseButton.Margin = new System.Windows.Forms.Padding(4); - this.CliPathBrowseButton.Name = "CliPathBrowseButton"; - this.CliPathBrowseButton.Size = new System.Drawing.Size(100, 28); - this.CliPathBrowseButton.TabIndex = 16; - this.CliPathBrowseButton.Text = "Browse"; - this.CliPathBrowseButton.UseVisualStyleBackColor = true; - this.CliPathBrowseButton.Click += new System.EventHandler(this.CliPathBrowseButton_Click); - // - // CliPathTextBox - // - this.CliPathTextBox.Location = new System.Drawing.Point(241, 96); - this.CliPathTextBox.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); - this.CliPathTextBox.Name = "CliPathTextBox"; - this.CliPathTextBox.ReadOnly = true; - this.CliPathTextBox.Size = new System.Drawing.Size(399, 22); - this.CliPathTextBox.TabIndex = 15; - // - // CliPathLabel - // - this.CliPathLabel.AutoSize = true; - this.CliPathLabel.Location = new System.Drawing.Point(5, 71); - this.CliPathLabel.Name = "CliPathLabel"; - this.CliPathLabel.Size = new System.Drawing.Size(92, 16); - this.CliPathLabel.TabIndex = 14; - this.CliPathLabel.Text = "Snyk CLI Path:"; - // - // ManageBinariesAutomaticallyCheckbox - // - this.ManageBinariesAutomaticallyCheckbox.AutoSize = true; - this.ManageBinariesAutomaticallyCheckbox.Location = new System.Drawing.Point(16, 132); - this.ManageBinariesAutomaticallyCheckbox.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); - this.ManageBinariesAutomaticallyCheckbox.Name = "ManageBinariesAutomaticallyCheckbox"; - this.ManageBinariesAutomaticallyCheckbox.Size = new System.Drawing.Size(18, 17); - this.ManageBinariesAutomaticallyCheckbox.TabIndex = 13; - this.ManageBinariesAutomaticallyCheckbox.UseVisualStyleBackColor = true; - // - // label1 - // - this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(41, 132); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(320, 16); - this.label1.TabIndex = 12; - this.label1.Text = "Update and install Snyk dependencies automatically"; // // productSelectionGroupBox // @@ -393,7 +308,7 @@ private void InitializeComponent() this.productSelectionGroupBox.Controls.Add(this.codeQualityEnabledCheckBox); this.productSelectionGroupBox.Controls.Add(this.ossEnabledCheckBox); this.productSelectionGroupBox.Controls.Add(this.codeSecurityEnabledCheckBox); - this.productSelectionGroupBox.Location = new System.Drawing.Point(29, 709); + this.productSelectionGroupBox.Location = new System.Drawing.Point(29, 424); this.productSelectionGroupBox.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); this.productSelectionGroupBox.Name = "productSelectionGroupBox"; this.productSelectionGroupBox.Padding = new System.Windows.Forms.Padding(11, 10, 11, 10); @@ -573,7 +488,7 @@ private void InitializeComponent() // userExperienceGroupBox // this.userExperienceGroupBox.Controls.Add(this.autoScanCheckBox); - this.userExperienceGroupBox.Location = new System.Drawing.Point(29, 955); + this.userExperienceGroupBox.Location = new System.Drawing.Point(29, 670); this.userExperienceGroupBox.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); this.userExperienceGroupBox.Name = "userExperienceGroupBox"; this.userExperienceGroupBox.Padding = new System.Windows.Forms.Padding(11, 10, 11, 10); @@ -615,88 +530,17 @@ private void InitializeComponent() // this.customCliPathFileDialog.SupportMultiDottedExtensions = true; // - // ExecutablesGroupBox - // - this.ExecutablesGroupBox.Controls.Add(this.ReleaseChannelLink); - this.ExecutablesGroupBox.Controls.Add(this.releaseChannel); - this.ExecutablesGroupBox.Controls.Add(this.cliReleaseChannelLabel); - this.ExecutablesGroupBox.Controls.Add(this.cliBaseDownloadUrl); - this.ExecutablesGroupBox.Controls.Add(this.richTextBox1); - this.ExecutablesGroupBox.Controls.Add(this.cliDownloadUrlTextBox); - this.ExecutablesGroupBox.Controls.Add(this.CliPathLabel); - this.ExecutablesGroupBox.Controls.Add(this.resetCliPathToDefaultButton); - this.ExecutablesGroupBox.Controls.Add(this.label1); - this.ExecutablesGroupBox.Controls.Add(this.CliPathBrowseButton); - this.ExecutablesGroupBox.Controls.Add(this.ManageBinariesAutomaticallyCheckbox); - this.ExecutablesGroupBox.Controls.Add(this.CliPathTextBox); - this.ExecutablesGroupBox.Location = new System.Drawing.Point(29, 426); - this.ExecutablesGroupBox.Margin = new System.Windows.Forms.Padding(4); - this.ExecutablesGroupBox.Name = "ExecutablesGroupBox"; - this.ExecutablesGroupBox.Padding = new System.Windows.Forms.Padding(4); - this.ExecutablesGroupBox.Size = new System.Drawing.Size(747, 277); - this.ExecutablesGroupBox.TabIndex = 19; - this.ExecutablesGroupBox.TabStop = false; - this.ExecutablesGroupBox.Text = "Executables Settings"; - // - // ReleaseChannelLink - // - this.ReleaseChannelLink.AutoSize = true; - this.ReleaseChannelLink.Location = new System.Drawing.Point(8, 241); - this.ReleaseChannelLink.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.ReleaseChannelLink.Name = "ReleaseChannelLink"; - this.ReleaseChannelLink.Size = new System.Drawing.Size(219, 16); - this.ReleaseChannelLink.TabIndex = 20; - this.ReleaseChannelLink.TabStop = true; - this.ReleaseChannelLink.Text = "Find out about our release channels"; - this.ReleaseChannelLink.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.ReleaseChannelLink_LinkClicked); - // - // releaseChannel - // - this.releaseChannel.FormattingEnabled = true; - this.releaseChannel.Location = new System.Drawing.Point(239, 208); - this.releaseChannel.Margin = new System.Windows.Forms.Padding(4); - this.releaseChannel.Name = "releaseChannel"; - this.releaseChannel.Size = new System.Drawing.Size(160, 24); - this.releaseChannel.TabIndex = 23; - // - // cliReleaseChannelLabel - // - this.cliReleaseChannelLabel.AutoSize = true; - this.cliReleaseChannelLabel.Location = new System.Drawing.Point(5, 212); - this.cliReleaseChannelLabel.Name = "cliReleaseChannelLabel"; - this.cliReleaseChannelLabel.Size = new System.Drawing.Size(128, 16); - this.cliReleaseChannelLabel.TabIndex = 22; - this.cliReleaseChannelLabel.Text = "CLI release channel:"; - // - // cliBaseDownloadUrl - // - this.cliBaseDownloadUrl.AutoSize = true; - this.cliBaseDownloadUrl.Location = new System.Drawing.Point(5, 27); - this.cliBaseDownloadUrl.Name = "cliBaseDownloadUrl"; - this.cliBaseDownloadUrl.Size = new System.Drawing.Size(194, 16); - this.cliBaseDownloadUrl.TabIndex = 20; - this.cliBaseDownloadUrl.Text = "Base URL to download the CLI: "; - // - // cliDownloadUrlTextBox - // - this.cliDownloadUrlTextBox.Location = new System.Drawing.Point(241, 23); - this.cliDownloadUrlTextBox.Margin = new System.Windows.Forms.Padding(4); - this.cliDownloadUrlTextBox.Name = "cliDownloadUrlTextBox"; - this.cliDownloadUrlTextBox.Size = new System.Drawing.Size(399, 22); - this.cliDownloadUrlTextBox.TabIndex = 21; - // // mainPanel // this.mainPanel.AutoScroll = true; this.mainPanel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; this.mainPanel.Controls.Add(this.generalSettingsGroupBox); - this.mainPanel.Controls.Add(this.ExecutablesGroupBox); this.mainPanel.Controls.Add(this.productSelectionGroupBox); this.mainPanel.Controls.Add(this.userExperienceGroupBox); this.mainPanel.Dock = System.Windows.Forms.DockStyle.Fill; this.mainPanel.Location = new System.Drawing.Point(0, 0); this.mainPanel.Name = "mainPanel"; - this.mainPanel.Size = new System.Drawing.Size(1060, 1041); + this.mainPanel.Size = new System.Drawing.Size(1060, 923); this.mainPanel.TabIndex = 20; // // SnykGeneralSettingsUserControl @@ -707,7 +551,7 @@ private void InitializeComponent() this.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); this.MinimumSize = new System.Drawing.Size(1060, 923); this.Name = "SnykGeneralSettingsUserControl"; - this.Size = new System.Drawing.Size(1060, 1041); + this.Size = new System.Drawing.Size(1060, 923); ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit(); this.generalSettingsGroupBox.ResumeLayout(false); this.generalSettingsGroupBox.PerformLayout(); @@ -717,8 +561,6 @@ private void InitializeComponent() this.ignoreGroupbox.PerformLayout(); this.userExperienceGroupBox.ResumeLayout(false); this.userExperienceGroupBox.PerformLayout(); - this.ExecutablesGroupBox.ResumeLayout(false); - this.ExecutablesGroupBox.PerformLayout(); this.mainPanel.ResumeLayout(false); this.ResumeLayout(false); @@ -752,26 +594,13 @@ private void InitializeComponent() private System.Windows.Forms.ToolTip snykCodeQualityInfoToolTip; private LinkLabel OrganizationInfoLink; private Label OrgDescriptionText; - private Label label1; - private CheckBox ManageBinariesAutomaticallyCheckbox; - private Label CliPathLabel; - private TextBox CliPathTextBox; - private Button CliPathBrowseButton; private OpenFileDialog customCliPathFileDialog; - private Button resetCliPathToDefaultButton; - private RichTextBox richTextBox1; - private GroupBox ExecutablesGroupBox; private Label label2; private ComboBox authType; private RichTextBox authMethodDescription; private CheckBox autoScanCheckBox; private Label snykIacInfoLabel; private CheckBox iacEnabledCheckbox; - private ComboBox releaseChannel; - private Label cliReleaseChannelLabel; - private Label cliBaseDownloadUrl; - private TextBox cliDownloadUrlTextBox; - private LinkLabel ReleaseChannelLink; private GroupBox ignoreGroupbox; private CheckBox cbIgnoredIssues; private CheckBox cbOpenIssues; diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.cs index 0c4eb93e..55292410 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.cs @@ -56,7 +56,7 @@ private void Initialize() { Logger.Information("Enter Initialize method"); - this.UpdateViewFromOptionsDialog(); + this.UpdateViewFromOptions(); snykOptions.SettingsChanged += this.OptionsDialogPageOnSettingsChanged; this.Load += this.SnykGeneralSettingsUserControl_Load; @@ -81,7 +81,7 @@ private async Task OnOnLanguageClientNotInitializedAsync(object sender, SnykLang authenticateButton.Enabled = false; } - private void UpdateViewFromOptionsDialog() + private void UpdateViewFromOptions() { this.authenticateButton.Enabled = LanguageClientHelper.IsLanguageServerReady(); this.customEndpointTextBox.Text = snykOptions.CustomEndpoint; @@ -89,23 +89,11 @@ private void UpdateViewFromOptionsDialog() this.ignoreUnknownCACheckBox.Checked = snykOptions.IgnoreUnknownCA; this.ossEnabledCheckBox.Checked = snykOptions.OssEnabled; this.iacEnabledCheckbox.Checked = snykOptions.IacEnabled; - this.ManageBinariesAutomaticallyCheckbox.Checked = snykOptions.BinariesAutoUpdate; this.autoScanCheckBox.Checked = snykOptions.AutoScan; - this.cliDownloadUrlTextBox.Text = snykOptions.CliDownloadUrl; this.tokenTextBox.Text = snykOptions.ApiToken.ToString(); this.cbIgnoredIssues.Checked = snykOptions.IgnoredIssuesEnabled; this.cbOpenIssues.Checked = snykOptions.OpenIssuesEnabled; - var cliPath = string.IsNullOrEmpty(snykOptions.CliCustomPath) - ? SnykCli.GetSnykCliDefaultPath() - : snykOptions.CliCustomPath; - - this.CliPathTextBox.Text = cliPath; - if (releaseChannel.DataSource == null) - { - this.releaseChannel.DataSource = ReleaseChannelList(); - } - if (cbDelta.DataSource == null) { this.cbDelta.DataSource = DeltaOptionList(); @@ -117,8 +105,7 @@ private void UpdateViewFromOptionsDialog() this.authType.DisplayMember = "Description"; this.authType.ValueMember = "Value"; } - - this.releaseChannel.SelectedItem = snykOptions.CliReleaseChannel; + this.authType.SelectedValue = snykOptions.AuthenticationMethod; this.cbDelta.SelectedItem = snykOptions.EnableDeltaFindings ? "Net new issues" : "All issues"; } @@ -136,16 +123,6 @@ private IEnumerable AuthenticationMethodList() .ToList(); } - private IEnumerable ReleaseChannelList() - { - var defaultList = new List() { "stable", "rc", "preview" }; - if (!defaultList.Contains(snykOptions.CliReleaseChannel)) - { - defaultList.Add(snykOptions.CliReleaseChannel); - } - return defaultList; - } - private IEnumerable DeltaOptionList() { var defaultList = new List { "All issues", "Net new issues"}; @@ -156,7 +133,7 @@ private void OptionsDialogPageOnSettingsChanged(object sender, SnykSettingsChang ThreadHelper.JoinableTaskFactory.RunAsync(async () => { await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); - this.UpdateViewFromOptionsDialog(); + this.UpdateViewFromOptions(); }).FireAndForget(); public async Task HandleAuthenticationSuccess(string apiToken, string apiUrl) @@ -434,28 +411,6 @@ private void OrganizationInfoLink_LinkClicked(object sender, LinkLabelLinkClicke Process.Start("https://docs.snyk.io/ide-tools/visual-studio-extension#organization-setting"); } - private void CliPathBrowseButton_Click(object sender, EventArgs e) - { - if (this.customCliPathFileDialog.ShowDialog() == DialogResult.OK) - { - var selectedCliPath = this.customCliPathFileDialog.FileName; - this.SetCliCustomPathValue(selectedCliPath); - } - } - - private void SetCliCustomPathValue(string selectedCliPath) - { - snykOptions.CliCustomPath = selectedCliPath; - this.CliPathTextBox.Text = string.IsNullOrEmpty(snykOptions.CliCustomPath) - ? SnykCli.GetSnykCliDefaultPath() - : selectedCliPath; - } - - private void ClearCliCustomPathButton_Click(object sender, EventArgs e) - { - this.SetCliCustomPathValue(string.Empty); - } - private void authType_SelectionChangeCommitted(object sender, EventArgs e) { snykOptions.AuthenticationMethod = (AuthenticationType)authType.SelectedValue; @@ -472,26 +427,6 @@ private void iacEnabledCheckbox_CheckedChanged(object sender, EventArgs e) snykOptions.IacEnabled = iacEnabledCheckbox.Checked; } - public string GetReleaseChannel() - { - return releaseChannel.Text; - } - - public string GetCliDownloadUrl() - { - return cliDownloadUrlTextBox.Text; - } - - public bool GetManageBinariesAutomatically() - { - return ManageBinariesAutomaticallyCheckbox.Checked; - } - - private void ReleaseChannelLink_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) - { - this.ReleaseChannelLink.LinkVisited = true; - Process.Start("https://docs.snyk.io/snyk-cli/releases-and-channels-for-the-snyk-cli"); - } private void cbOpenIssues_CheckedChanged(object sender, EventArgs e) { diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.resx b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.resx index e89510c3..86b2d89c 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.resx +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.resx @@ -133,9 +133,6 @@ 140, 17 - - 477, 17 - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO @@ -145,8 +142,8 @@ jZZtldeAJuTjx7SYAQYQKn7xnCU8ABJO2R9gGis+AAAAAElFTkSuQmCC - - 270, 17 + + 477, 17 @@ -157,6 +154,9 @@ jZZtldeAJuTjx7SYAQYQKn7xnCU8ABJO2R9gGis+AAAAAElFTkSuQmCC + + 270, 17 + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO @@ -166,12 +166,6 @@ jZZtldeAJuTjx7SYAQYQKn7xnCU8ABJO2R9gGis+AAAAAElFTkSuQmCC - - 270, 17 - - - 477, 17 - 680, 17 diff --git a/Snyk.VisualStudio.Extension.2022/Snyk.VisualStudio.Extension.2022.csproj b/Snyk.VisualStudio.Extension.2022/Snyk.VisualStudio.Extension.2022.csproj index 912053d7..8d21d50c 100644 --- a/Snyk.VisualStudio.Extension.2022/Snyk.VisualStudio.Extension.2022.csproj +++ b/Snyk.VisualStudio.Extension.2022/Snyk.VisualStudio.Extension.2022.csproj @@ -145,9 +145,19 @@ + + + Component + + + UserControl + + + SnykCliOptionsUserControl.cs + Component @@ -573,6 +583,9 @@ + + SnykCliOptionsUserControl.cs + SnykGeneralSettingsUserControl.cs Designer diff --git a/Snyk.VisualStudio.Extension.2022/SnykVSPackage.cs b/Snyk.VisualStudio.Extension.2022/SnykVSPackage.cs index eab48c8a..e0ea94aa 100644 --- a/Snyk.VisualStudio.Extension.2022/SnykVSPackage.cs +++ b/Snyk.VisualStudio.Extension.2022/SnykVSPackage.cs @@ -50,8 +50,9 @@ namespace Snyk.VisualStudio.Extension [ProvideService(typeof(ISnykService), IsAsyncQueryable = true)] [ProvideMenuResource("Menus.ctmenu", 1)] [ProvideToolWindow(typeof(SnykToolWindow), Style = VsDockStyle.Tabbed)] - [ProvideOptionPage(typeof(SnykGeneralOptionsDialogPage), "Snyk", "General settings", 1000, 1001, true)] + [ProvideOptionPage(typeof(SnykGeneralOptionsDialogPage), "Snyk", "General", 1000, 1001, true)] [ProvideOptionPage(typeof(SnykSolutionOptionsDialogPage), "Snyk", "Solution settings", 1000, 1002, true)] + [ProvideOptionPage(typeof(SnykCliOptionsDialogPage), "Snyk", "CLI settings", 1000, 1003, true)] public sealed class SnykVSPackage : AsyncPackage, ISnykOptionsProvider { /// @@ -102,6 +103,7 @@ public void SetServiceProvider(ISnykServiceProvider serviceProvider) /// public ISnykOptions Options { get; private set; } public ISnykGeneralOptionsDialogPage SnykGeneralOptionsDialogPage { get; private set; } + public ISnykCliOptionsDialogPage SnykCliOptionsDialogPage { get; private set; } /// /// Gets instance. @@ -328,6 +330,16 @@ private async Task InitializeGeneralOptionsAsync() Logger.Information("Call generalOptionsDialogPage.Initialize()"); SnykGeneralOptionsDialogPage.Initialize(this.serviceProvider); } + + if (SnykCliOptionsDialogPage == null) + { + await JoinableTaskFactory.SwitchToMainThreadAsync(); + + SnykCliOptionsDialogPage = + (SnykCliOptionsDialogPage)GetDialogPage(typeof(SnykCliOptionsDialogPage)); + Logger.Information("Call generalOptionsDialogPage.Initialize()"); + SnykCliOptionsDialogPage.Initialize(this.serviceProvider); + } } private async Task GetVsVersionAsync() From c6bb365e5fd770acf3532375a7e2a5fbf6cb97a3 Mon Sep 17 00:00:00 2001 From: Abdelrahman Shawki Hassan Date: Tue, 17 Dec 2024 18:56:43 +0100 Subject: [PATCH 04/16] wip: separate userStorage from options --- .../BranchSelectorDialogWindow.xaml.cs | 6 +- .../Language/LsSettings.cs | 2 +- .../Language/SnykLanguageClient.cs | 11 +- .../SnykLanguageClientCustomTarget.cs | 7 +- .../Service/ISnykServiceProvider.cs | 2 +- .../Service/SnykService.cs | 3 +- .../Service/SnykTasksService.cs | 12 +- .../Service/WorkspaceTrustService.cs | 14 +- .../Settings/IPersistableOption.cs | 78 ++++ .../Settings/ISnykOptions.cs | 93 +---- .../Settings/ISnykOptionsManager.cs | 11 + .../Settings/SnykCliOptionsDialogPage.cs | 3 +- .../Settings/SnykCliOptionsUserControl.cs | 4 +- .../Settings/SnykGeneralOptionsDialogPage.cs | 2 +- .../SnykGeneralSettingsUserControl.cs | 16 +- .../Settings/SnykOptions.cs | 346 ++---------------- .../Settings/SnykOptionsManager.cs | 100 +++++ .../SnykUserStorageSettingsService.cs | 2 + .../Snyk.VisualStudio.Extension.2022.csproj | 3 + .../SnykVSPackage.cs | 7 +- .../SnykOptionsTest.cs | 2 +- 21 files changed, 278 insertions(+), 446 deletions(-) create mode 100644 Snyk.VisualStudio.Extension.2022/Settings/IPersistableOption.cs create mode 100644 Snyk.VisualStudio.Extension.2022/Settings/ISnykOptionsManager.cs create mode 100644 Snyk.VisualStudio.Extension.2022/Settings/SnykOptionsManager.cs diff --git a/Snyk.VisualStudio.Extension.2022/BranchSelectorDialogWindow.xaml.cs b/Snyk.VisualStudio.Extension.2022/BranchSelectorDialogWindow.xaml.cs index 81a31358..99ef2391 100644 --- a/Snyk.VisualStudio.Extension.2022/BranchSelectorDialogWindow.xaml.cs +++ b/Snyk.VisualStudio.Extension.2022/BranchSelectorDialogWindow.xaml.cs @@ -51,8 +51,10 @@ private void OkButton_OnClick(object sender, RoutedEventArgs e) var currentList = folderConfigList.Where(x => x.FolderPath != FolderConfig.FolderPath).ToList(); currentList.Add(FolderConfig); - SnykVSPackage.ServiceProvider.Options.FolderConfigs = currentList; - + var options = SnykVSPackage.ServiceProvider.Options; + options.FolderConfigs = currentList; + SnykVSPackage.ServiceProvider.SnykOptionsManager.Save(options); + options.InvokeSettingsChangedEvent(); this.CloseDialog(); } diff --git a/Snyk.VisualStudio.Extension.2022/Language/LsSettings.cs b/Snyk.VisualStudio.Extension.2022/Language/LsSettings.cs index a30286f3..fb30a4e8 100644 --- a/Snyk.VisualStudio.Extension.2022/Language/LsSettings.cs +++ b/Snyk.VisualStudio.Extension.2022/Language/LsSettings.cs @@ -43,7 +43,7 @@ public SnykLsInitializationOptions GetInitializationOptions() }, ScanningMode = options.AutoScan ? "auto" : "manual", #pragma warning disable VSTHRD104 - AdditionalParams = ThreadHelper.JoinableTaskFactory.Run(() => options.GetAdditionalOptionsAsync()), + AdditionalParams = ThreadHelper.JoinableTaskFactory.Run(() => this.serviceProvider.SnykOptionsManager.GetAdditionalOptionsAsync()), #pragma warning restore VSTHRD104 AuthenticationMethod = options.AuthenticationMethod == AuthenticationType.OAuth ? "oauth" : "token", CliPath = SnykCli.GetCliFilePath(options.CliCustomPath), diff --git a/Snyk.VisualStudio.Extension.2022/Language/SnykLanguageClient.cs b/Snyk.VisualStudio.Extension.2022/Language/SnykLanguageClient.cs index b1d42cd0..aa6e73b0 100644 --- a/Snyk.VisualStudio.Extension.2022/Language/SnykLanguageClient.cs +++ b/Snyk.VisualStudio.Extension.2022/Language/SnykLanguageClient.cs @@ -73,14 +73,15 @@ public object GetInitializationOptions() public async Task ActivateAsync(CancellationToken token) { await Task.Yield(); - if (SnykVSPackage.ServiceProvider?.Options == null) + var serviceProvider = SnykVSPackage.ServiceProvider; + if (serviceProvider?.Options == null) { Logger.Error("Could not activate Language Server because ServiceProvider is null. Is the extension initialized?"); return null; } - var options = SnykVSPackage.ServiceProvider.Options; + var options = serviceProvider.Options; // ReSharper disable once RedundantAssignment - var lsDebugLevel = await GetLsDebugLevelAsync(options); + var lsDebugLevel = await GetLsDebugLevelAsync(serviceProvider.SnykOptionsManager); #if DEBUG lsDebugLevel = "debug"; #endif @@ -221,10 +222,10 @@ public Task OnServerInitializedAsync() return Task.CompletedTask; } - private async Task GetLsDebugLevelAsync(ISnykOptions options) + private async Task GetLsDebugLevelAsync(ISnykOptionsManager optionsManger) { var logLevel = "info"; - var additionalCliParameters = await options.GetAdditionalOptionsAsync(); + var additionalCliParameters = await optionsManger.GetAdditionalOptionsAsync(); if (!string.IsNullOrEmpty(additionalCliParameters) && (additionalCliParameters.Contains("-d") || additionalCliParameters.Contains("--debug"))) { logLevel = "debug"; diff --git a/Snyk.VisualStudio.Extension.2022/Language/SnykLanguageClientCustomTarget.cs b/Snyk.VisualStudio.Extension.2022/Language/SnykLanguageClientCustomTarget.cs index 99d4d9ae..aaa33b28 100644 --- a/Snyk.VisualStudio.Extension.2022/Language/SnykLanguageClientCustomTarget.cs +++ b/Snyk.VisualStudio.Extension.2022/Language/SnykLanguageClientCustomTarget.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; using Microsoft.VisualStudio.Shell; using Newtonsoft.Json.Linq; using Snyk.VisualStudio.Extension.Authentication; @@ -109,6 +110,8 @@ public async Task OnFolderConfig(JToken arg) var folderConfigs = arg.TryParse(); if (folderConfigs == null) return; serviceProvider.Options.FolderConfigs = folderConfigs.FolderConfigs; + serviceProvider.SnykOptionsManager.Save(serviceProvider.Options); + serviceProvider.Options.InvokeSettingsChangedEvent(); } [JsonRpcMethod(LsConstants.SnykHasAuthenticated)] @@ -133,6 +136,8 @@ public async Task OnHasAuthenticated(JToken arg) } serviceProvider.Options.ApiToken = new AuthenticationToken(serviceProvider.Options.AuthenticationMethod, token); + serviceProvider.SnykOptionsManager.Save(serviceProvider.Options); + serviceProvider.Options.InvokeSettingsChangedEvent(); await serviceProvider.GeneralOptionsDialogPage.HandleAuthenticationSuccess(token, apiUrl); serviceProvider.FeatureFlagService.RefreshAsync(SnykVSPackage.Instance.DisposalToken).FireAndForget(); @@ -150,7 +155,7 @@ public async Task OnAddTrustedFolders(JToken arg) if (trustedFolders == null) return; serviceProvider.Options.TrustedFolders = new HashSet(trustedFolders.TrustedFolders); - this.serviceProvider.UserStorageSettingsService?.SaveSettings(); + this.serviceProvider.SnykOptionsManager.Save(serviceProvider.Options); await serviceProvider.LanguageClientManager.DidChangeConfigurationAsync(SnykVSPackage.Instance.DisposalToken); } diff --git a/Snyk.VisualStudio.Extension.2022/Service/ISnykServiceProvider.cs b/Snyk.VisualStudio.Extension.2022/Service/ISnykServiceProvider.cs index 41fcb079..73542770 100644 --- a/Snyk.VisualStudio.Extension.2022/Service/ISnykServiceProvider.cs +++ b/Snyk.VisualStudio.Extension.2022/Service/ISnykServiceProvider.cs @@ -47,7 +47,7 @@ public interface ISnykServiceProvider /// ISnykOptions Options { get; } ISnykGeneralOptionsDialogPage GeneralOptionsDialogPage { get; } - + ISnykOptionsManager SnykOptionsManager { get; } /// /// Gets Visual Studio Settiings Manager instance. /// diff --git a/Snyk.VisualStudio.Extension.2022/Service/SnykService.cs b/Snyk.VisualStudio.Extension.2022/Service/SnykService.cs index 3112722f..506c0bef 100644 --- a/Snyk.VisualStudio.Extension.2022/Service/SnykService.cs +++ b/Snyk.VisualStudio.Extension.2022/Service/SnykService.cs @@ -60,6 +60,7 @@ public SnykService(IAsyncServiceProvider serviceProvider, string vsVersion = "") public ISnykOptions Options => this.Package.Options; public ISnykGeneralOptionsDialogPage GeneralOptionsDialogPage => this.Package.SnykGeneralOptionsDialogPage; + public ISnykOptionsManager SnykOptionsManager => this.Package.SnykOptionsManager; /// /// Gets solution service. @@ -167,7 +168,7 @@ public async Task InitializeAsync(CancellationToken cancellationToken) await SnykSolutionService.Instance.InitializeAsync(this); this.tasksService = SnykTasksService.Instance; - this.workspaceTrustService = new WorkspaceTrustService(this.UserStorageSettingsService); + this.workspaceTrustService = new WorkspaceTrustService(this); NotificationService.Initialize(this); VsStatusBar.Initialize(this); diff --git a/Snyk.VisualStudio.Extension.2022/Service/SnykTasksService.cs b/Snyk.VisualStudio.Extension.2022/Service/SnykTasksService.cs index a51b638a..c1b20bd6 100644 --- a/Snyk.VisualStudio.Extension.2022/Service/SnykTasksService.cs +++ b/Snyk.VisualStudio.Extension.2022/Service/SnykTasksService.cs @@ -727,8 +727,7 @@ private void CancelTask(CancellationTokenSource tokenSource) public bool ShouldDownloadCli() { - var userSettingsStorageService = this.serviceProvider.UserStorageSettingsService; - if (!userSettingsStorageService.BinariesAutoUpdate) + if (!this.serviceProvider.UserStorageSettingsService.BinariesAutoUpdate) { return false; } @@ -762,8 +761,7 @@ private async Task DownloadAsync(CliDownloadFinishedCallback downloadFinishedCal this.isCliDownloading = true; try { - var serviceProviderOptions = this.serviceProvider.Options; - var cliDownloader = new SnykCliDownloader(serviceProviderOptions); + var cliDownloader = new SnykCliDownloader(this.serviceProvider.Options); var downloadFinishedCallbacks = new List(); @@ -774,12 +772,12 @@ private async Task DownloadAsync(CliDownloadFinishedCallback downloadFinishedCal downloadFinishedCallbacks.Add(() => { - serviceProviderOptions.CurrentCliVersion = cliDownloader.GetLatestReleaseInfo().Name; - userSettingsStorageService.SaveSettings(); + this.serviceProvider.Options.CurrentCliVersion = cliDownloader.GetLatestReleaseInfo().Name; + this.serviceProvider.SnykOptionsManager.Save(this.serviceProvider.Options); DisposeCancellationTokenSource(this.downloadCliTokenSource); }); - var downloadPath = serviceProviderOptions.CliCustomPath; + var downloadPath = this.serviceProvider.Options.CliCustomPath; await cliDownloader.AutoUpdateCliAsync( progressWorker, downloadPath, diff --git a/Snyk.VisualStudio.Extension.2022/Service/WorkspaceTrustService.cs b/Snyk.VisualStudio.Extension.2022/Service/WorkspaceTrustService.cs index 53cdd2dc..f814da61 100644 --- a/Snyk.VisualStudio.Extension.2022/Service/WorkspaceTrustService.cs +++ b/Snyk.VisualStudio.Extension.2022/Service/WorkspaceTrustService.cs @@ -9,11 +9,11 @@ public class WorkspaceTrustService : IWorkspaceTrustService { private static readonly ILogger Logger = LogManager.ForContext(); - private readonly IUserStorageSettingsService settingsService; + private readonly ISnykServiceProvider serviceProvider; - public WorkspaceTrustService(IUserStorageSettingsService settingsService) + public WorkspaceTrustService(ISnykServiceProvider serviceProvider) { - this.settingsService = settingsService; + this.serviceProvider = serviceProvider; } public void AddFolderToTrusted(string absoluteFolderPath) @@ -30,10 +30,10 @@ public void AddFolderToTrusted(string absoluteFolderPath) try { - var trustedFolders = this.settingsService.TrustedFolders; + var trustedFolders = this.serviceProvider.Options.TrustedFolders; trustedFolders.Add(absoluteFolderPath); - this.settingsService.TrustedFolders = trustedFolders; - this.settingsService.SaveSettings(); + this.serviceProvider.Options.TrustedFolders = trustedFolders; + this.serviceProvider.SnykOptionsManager.Save(this.serviceProvider.Options); } catch (Exception e) { @@ -45,7 +45,7 @@ public bool IsFolderTrusted(string absoluteFolderPath) { if (string.IsNullOrEmpty(absoluteFolderPath)) return true; - var trustedFolders = this.settingsService.TrustedFolders; + var trustedFolders = this.serviceProvider.Options.TrustedFolders; foreach (var trustedFolder in trustedFolders) { diff --git a/Snyk.VisualStudio.Extension.2022/Settings/IPersistableOption.cs b/Snyk.VisualStudio.Extension.2022/Settings/IPersistableOption.cs new file mode 100644 index 00000000..7d74f4b3 --- /dev/null +++ b/Snyk.VisualStudio.Extension.2022/Settings/IPersistableOption.cs @@ -0,0 +1,78 @@ +using System.Collections.Generic; +using Snyk.VisualStudio.Extension.Authentication; +using Snyk.VisualStudio.Extension.Language; + +namespace Snyk.VisualStudio.Extension.Settings; + +public interface IPersistableOptions +{ + string DeviceId { get; set; } + bool AutoScan { get; set; } + + bool OpenIssuesEnabled { get; set; } + bool IgnoredIssuesEnabled { get; set; } + + /// + /// Gets or sets a value indicating whether Snyk user API token. + /// + AuthenticationToken ApiToken { get; set; } + + /// + /// Gets Value of Authentication Token Type. + /// + AuthenticationType AuthenticationMethod { get; set; } + + /// + /// Gets or sets a value indicating whether CLI custom endpoint parameter. + /// + string CustomEndpoint { get; set; } + + /// + /// Gets a value indicating whether Snyk Code settings URL. + /// + string SnykCodeSettingsUrl { get; } + + /// + /// Gets or sets a value indicating whether CLI organization parameter. + /// + string Organization { get; set; } + + /// + /// Gets or sets a value indicating whether CLI ignore unknown CA parameter. + /// + bool IgnoreUnknownCA { get; set; } + + /// + /// Gets a value indicating whether is Oss scan enabled. + /// + bool OssEnabled { get; set; } + bool IacEnabled { get; set; } + + /// + /// Gets a value indicating whether is Oss scan enabled. + /// + bool SnykCodeSecurityEnabled { get; set; } + + /// + /// Gets a value indicating whether is Oss scan enabled. + /// + bool SnykCodeQualityEnabled { get; set; } + + /// + /// Gets or sets a value indicating whether the CLI should be automatically updated. + /// + bool BinariesAutoUpdate { get; set; } + + /// + /// Gets or sets the value of the CLI custom path. If empty, the default path from AppData would be used. + /// + string CliCustomPath { get; set; } + string CliReleaseChannel { get; set; } + string CliDownloadUrl { get; set; } + ISet TrustedFolders { get; set; } + + bool EnableDeltaFindings { get; set; } + List FolderConfigs { get; set; } + string CurrentCliVersion { get; set; } + bool AnalyticsPluginInstalledSent { get; set; } +} \ No newline at end of file diff --git a/Snyk.VisualStudio.Extension.2022/Settings/ISnykOptions.cs b/Snyk.VisualStudio.Extension.2022/Settings/ISnykOptions.cs index fe1e05c7..49f71723 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/ISnykOptions.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/ISnykOptions.cs @@ -1,15 +1,11 @@ using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using Snyk.VisualStudio.Extension.Authentication; -using Snyk.VisualStudio.Extension.Language; namespace Snyk.VisualStudio.Extension.Settings { /// /// Interface for Snyk Options/Settings in Visual Studio. /// - public interface ISnykOptions + public interface ISnykOptions : IPersistableOptions { string Application { get; set; } string ApplicationVersion { get; set; } @@ -17,99 +13,14 @@ public interface ISnykOptions string IntegrationVersion { get; } string IntegrationEnvironment { get; set; } string IntegrationEnvironmentVersion { get; set; } - - string DeviceId { get; set; } - bool AutoScan { get; set; } - + SastSettings SastSettings { get; set; } bool ConsistentIgnoresEnabled { get; set; } - bool OpenIssuesEnabled { get; set; } - bool IgnoredIssuesEnabled { get; set; } - - /// - /// Gets or sets a value indicating whether Snyk user API token. - /// - AuthenticationToken ApiToken { get; set; } - - /// - /// Gets Value of Authentication Token Type. - /// - AuthenticationType AuthenticationMethod { get; set; } - - /// - /// Gets or sets a value indicating whether CLI custom endpoint parameter. - /// - string CustomEndpoint { get; set; } - - /// - /// Gets a value indicating whether Snyk Code settings URL. - /// - string SnykCodeSettingsUrl { get; } - - /// - /// Gets or sets a value indicating whether CLI organization parameter. - /// - string Organization { get; set; } - - /// - /// Gets or sets a value indicating whether CLI ignore unknown CA parameter. - /// - bool IgnoreUnknownCA { get; set; } - - /// - /// Gets a value indicating whether is Oss scan enabled. - /// - bool OssEnabled { get; set; } - bool IacEnabled { get; set; } - - /// - /// Gets a value indicating whether is Oss scan enabled. - /// - bool SnykCodeSecurityEnabled { get; set; } - - /// - /// Gets a value indicating whether is Oss scan enabled. - /// - bool SnykCodeQualityEnabled { get; set; } - - /// - /// Gets or sets a value indicating whether the CLI should be automatically updated. - /// - bool BinariesAutoUpdate { get; set; } - - /// - /// Gets or sets the value of the CLI custom path. If empty, the default path from AppData would be used. - /// - string CliCustomPath { get; set; } - string CliReleaseChannel { get; set; } - string CliDownloadUrl { get; set; } - ISet TrustedFolders { get; set; } - - bool EnableDeltaFindings { get; set; } - List FolderConfigs { get; set; } /// /// Settings changed event. /// event EventHandler SettingsChanged; - /// - /// Gets a value indicating whether additional options. - /// Get this data using . - /// - /// representing the asynchronous operation. - Task GetAdditionalOptionsAsync(); - - /// - /// Gets a value indicating whether is scan all projects enabled via . - /// Get this data using . - /// - /// representing the asynchronous operation. - Task IsScanAllProjectsAsync(); - - string CurrentCliVersion { get; set; } - SastSettings SastSettings { get; set; } - bool AnalyticsPluginInstalledSent { get; set; } void InvokeSettingsChangedEvent(); - void SaveSettings(); } } \ No newline at end of file diff --git a/Snyk.VisualStudio.Extension.2022/Settings/ISnykOptionsManager.cs b/Snyk.VisualStudio.Extension.2022/Settings/ISnykOptionsManager.cs new file mode 100644 index 00000000..91d8a189 --- /dev/null +++ b/Snyk.VisualStudio.Extension.2022/Settings/ISnykOptionsManager.cs @@ -0,0 +1,11 @@ +using System.Threading.Tasks; + +namespace Snyk.VisualStudio.Extension.Settings; + +public interface ISnykOptionsManager +{ + IPersistableOptions Load(); + void Save(IPersistableOptions options); + Task GetAdditionalOptionsAsync(); + Task IsScanAllProjectsAsync(); +} \ No newline at end of file diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsDialogPage.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsDialogPage.cs index 5f8b0361..c5d5ff0e 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsDialogPage.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsDialogPage.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Runtime.InteropServices; using System.Windows.Forms; using Microsoft.VisualStudio.Shell; @@ -38,7 +39,7 @@ public SnykCliOptionsUserControl SnykCliOptionsUserControl public override void SaveSettingsToStorage() { HandleCliDownload(); - this.SnykOptions.SaveSettings(); + this.serviceProvider.SnykOptionsManager.Save(this.SnykOptions); this.SnykOptions.InvokeSettingsChangedEvent(); } diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsUserControl.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsUserControl.cs index 6cda1928..fa5b6820 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsUserControl.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsUserControl.cs @@ -12,12 +12,14 @@ public partial class SnykCliOptionsUserControl : UserControl { private readonly ISnykServiceProvider serviceProvider; private readonly ISnykOptions snykOptions; + private readonly ISnykOptions memento; private static readonly ILogger Logger = LogManager.ForContext(); - + public SnykCliOptionsUserControl(ISnykServiceProvider serviceProvider) { this.serviceProvider = serviceProvider; snykOptions = this.serviceProvider.Options; + memento = new SnykOptions(); InitializeComponent(); this.Initialize(); } diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralOptionsDialogPage.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralOptionsDialogPage.cs index d944dd1c..f4022626 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralOptionsDialogPage.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralOptionsDialogPage.cs @@ -86,7 +86,7 @@ public SnykGeneralSettingsUserControl GeneralSettingsUserControl // This method is used when the user clicks "Ok" public override void SaveSettingsToStorage() { - this.SnykOptions.SaveSettings(); + this.serviceProvider.SnykOptionsManager.Save(this.SnykOptions); this.SnykOptions.InvokeSettingsChangedEvent(); } diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.cs index 55292410..790f7568 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.cs @@ -7,6 +7,7 @@ using System.Windows.Forms; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Threading; +using Newtonsoft.Json.Linq; using Serilog; using Snyk.VisualStudio.Extension.Authentication; using Snyk.VisualStudio.Extension.CLI; @@ -227,7 +228,8 @@ private void TokenTextBox_TextChanged(object sender, EventArgs e) { if (this.ValidateChildren(ValidationConstraints.Enabled)) { - snykOptions.ApiToken = new AuthenticationToken(snykOptions.AuthenticationMethod, this.tokenTextBox.Text); + snykOptions.ApiToken = new AuthenticationToken(snykOptions.AuthenticationMethod, this.tokenTextBox.Text); + serviceProvider.Options.InvokeSettingsChangedEvent(); } } @@ -235,13 +237,22 @@ private void CustomEndpointTextBox_LostFocus(object sender, EventArgs e) { if (this.ValidateChildren(ValidationConstraints.Enabled)) { - snykOptions.CustomEndpoint = this.customEndpointTextBox.Text; + if (!Uri.IsWellFormedUriString(this.customEndpointTextBox.Text, UriKind.Absolute)) + { + Logger.Warning("Custom endpoint value is not a well-formed URI. Setting custom endpoint to empty string"); + this.customEndpointTextBox.Text = snykOptions.CustomEndpoint = string.Empty; + return; + } + + snykOptions.CustomEndpoint = ApiEndpointResolver.TranslateOldApiToNewApiEndpoint(this.customEndpointTextBox.Text); + serviceProvider.Options.InvokeSettingsChangedEvent(); } } private void IgnoreUnknownCACheckBox_CheckedChanged(object sender, EventArgs e) { snykOptions.IgnoreUnknownCA = this.ignoreUnknownCACheckBox.Checked; + serviceProvider.Options.InvokeSettingsChangedEvent(); } private void TokenTextBox_Validating(object sender, CancelEventArgs cancelEventArgs) => @@ -414,6 +425,7 @@ private void OrganizationInfoLink_LinkClicked(object sender, LinkLabelLinkClicke private void authType_SelectionChangeCommitted(object sender, EventArgs e) { snykOptions.AuthenticationMethod = (AuthenticationType)authType.SelectedValue; + serviceProvider.Options.InvokeSettingsChangedEvent(); InvalidateApiToken(); } diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykOptions.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykOptions.cs index 6be2f72b..68bb1690 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykOptions.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykOptions.cs @@ -1,7 +1,5 @@ using System; using System.Collections.Generic; -using System.Threading.Tasks; -using Serilog; using Snyk.VisualStudio.Extension.Authentication; using Snyk.VisualStudio.Extension.Language; using Snyk.VisualStudio.Extension.Service; @@ -10,331 +8,39 @@ namespace Snyk.VisualStudio.Extension.Settings { public class SnykOptions : ISnykOptions { - private readonly ISnykServiceProvider serviceProvider; - private readonly IUserStorageSettingsService userStorageSettingsService; - private static readonly ILogger Logger = LogManager.ForContext(); - - public SnykOptions(ISnykServiceProvider provider) - { - this.serviceProvider = provider; - this.userStorageSettingsService = this.serviceProvider.UserStorageSettingsService; - } - public string Application { get; set; } public string ApplicationVersion { get; set; } public string IntegrationName { get; } = SnykExtension.IntegrationName; public string IntegrationVersion { get; } = SnykExtension.Version; public string IntegrationEnvironment { get; set; } public string IntegrationEnvironmentVersion { get; set; } - - public string DeviceId - { - get => this.userStorageSettingsService.DeviceId; - set => this.userStorageSettingsService.DeviceId = value; - } - - public bool AutoScan - { - get => this.userStorageSettingsService.AutoScan; - set - { - if (this.userStorageSettingsService == null) - return; - this.userStorageSettingsService.AutoScan = value; - } - } - public bool ConsistentIgnoresEnabled { get; set; } - public bool OpenIssuesEnabled - { - get => this.userStorageSettingsService.OpenIssuesEnabled; - set - { - if (this.userStorageSettingsService == null || this.userStorageSettingsService.OpenIssuesEnabled == value) - return; - this.userStorageSettingsService.OpenIssuesEnabled = value; - } - } - - public bool IgnoredIssuesEnabled - { - get => this.userStorageSettingsService.IgnoredIssuesEnabled; - set - { - if (this.userStorageSettingsService == null || this.userStorageSettingsService.IgnoredIssuesEnabled == value) - return; - this.userStorageSettingsService.IgnoredIssuesEnabled = value; - } - } - - public AuthenticationToken ApiToken - { - get => new AuthenticationToken(this.AuthenticationMethod, this.userStorageSettingsService.Token); - set - { - var tokenAsString = value.ToString(); - if (this.userStorageSettingsService == null || this.userStorageSettingsService.Token == tokenAsString) - return; - this.userStorageSettingsService.Token = tokenAsString; - userStorageSettingsService.SaveSettings(); - InvokeSettingsChangedEvent(); - } - } - - public AuthenticationType AuthenticationMethod - { - get => this.userStorageSettingsService.AuthenticationMethod; - set - { - if (this.userStorageSettingsService == null || this.userStorageSettingsService.AuthenticationMethod == value) - return; - this.userStorageSettingsService.AuthenticationMethod = value; - ApiToken = AuthenticationToken.EmptyToken; - userStorageSettingsService.SaveSettings(); - InvokeSettingsChangedEvent(); - } - } - public string CustomEndpoint - { - get => this.userStorageSettingsService.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; - } - - var newApiEndpoint = ApiEndpointResolver.TranslateOldApiToNewApiEndpoint(value); - if (this.userStorageSettingsService == null || this.userStorageSettingsService.CustomEndpoint == newApiEndpoint) - { - return; - } - - this.userStorageSettingsService.CustomEndpoint = newApiEndpoint; - ApiToken = AuthenticationToken.EmptyToken; - userStorageSettingsService.SaveSettings(); - InvokeSettingsChangedEvent(); - } - } + public SastSettings SastSettings { get; set; } + public string DeviceId { get; set; } + public bool AutoScan { get; set; } + public bool OpenIssuesEnabled { get; set; } + public bool IgnoredIssuesEnabled { get; set; } + public AuthenticationToken ApiToken { get; set; } + public AuthenticationType AuthenticationMethod { get; set; } + public string CustomEndpoint { get; set; } + public string Organization { get; set; } + public bool IgnoreUnknownCA { get; set; } + public bool OssEnabled { get; set; } + public bool IacEnabled { get; set; } + public bool SnykCodeSecurityEnabled { get; set; } + public bool SnykCodeQualityEnabled { get; set; } + public bool BinariesAutoUpdate { get; set; } + public string CliCustomPath { get; set; } + public string CliReleaseChannel { get; set; } + public string CliDownloadUrl { get; set; } + public ISet TrustedFolders { get; set; } + public bool EnableDeltaFindings { get; set; } + public List FolderConfigs { get; set; } + public string CurrentCliVersion { get; set; } + public bool AnalyticsPluginInstalledSent { get; set; } public string SnykCodeSettingsUrl => $"{this.GetBaseAppUrl()}/manage/snyk-code"; - - /// - /// Gets or sets a value indicating whether organization. - /// - public string Organization - { - get => this.userStorageSettingsService.Organization; - set - { - if (this.userStorageSettingsService == null || this.userStorageSettingsService.Organization == value) - { - return; - } - this.userStorageSettingsService.Organization = value; - userStorageSettingsService.SaveSettings(); - InvokeSettingsChangedEvent(); - } - } - /// - /// Gets or sets a value indicating whether ignore unknown CA. - /// - public bool IgnoreUnknownCA - { - get => this.userStorageSettingsService.IgnoreUnknownCa; - set - { - if (this.userStorageSettingsService == null || this.userStorageSettingsService.IgnoreUnknownCa == value) - { - return; - } - this.userStorageSettingsService.IgnoreUnknownCa = value; - userStorageSettingsService.SaveSettings(); - InvokeSettingsChangedEvent(); - } - } - /// - public bool OssEnabled - { - get => this.userStorageSettingsService.OssEnabled; - set - { - if (this.userStorageSettingsService == null || userStorageSettingsService.OssEnabled == value) - { - return; - } - - this.userStorageSettingsService.OssEnabled = value; - } - } - - public bool IacEnabled - { - get => this.userStorageSettingsService.IacEnabled; - set - { - if (this.userStorageSettingsService == null || userStorageSettingsService.IacEnabled == value) - { - return; - } - - this.userStorageSettingsService.IacEnabled = value; - } - } - public bool SnykCodeSecurityEnabled - { - get => this.userStorageSettingsService.SnykCodeSecurityEnabled; - set - { - if (this.userStorageSettingsService == null || userStorageSettingsService.SnykCodeSecurityEnabled == value) - { - return; - } - - this.userStorageSettingsService.SnykCodeSecurityEnabled = value; - } - } - - /// - public bool SnykCodeQualityEnabled - { - get => this.userStorageSettingsService.SnykCodeQualityEnabled; - set - { - if (this.userStorageSettingsService == null || userStorageSettingsService.SnykCodeQualityEnabled == value) - { - return; - } - - this.userStorageSettingsService.SnykCodeQualityEnabled = value; - } - } - - public bool BinariesAutoUpdate - { - get => this.userStorageSettingsService.BinariesAutoUpdate; - set - { - if (this.userStorageSettingsService == null || this.userStorageSettingsService.BinariesAutoUpdate == value) - { - return; - } - this.userStorageSettingsService.BinariesAutoUpdate = value; - } - } - - public string CliCustomPath - { - get => this.userStorageSettingsService.CliCustomPath; - set - { - if (this.userStorageSettingsService == null || this.userStorageSettingsService.CliCustomPath == value) - { - return; - } - this.userStorageSettingsService.CliCustomPath = value; - } - } - - public string CliReleaseChannel - { - get => this.userStorageSettingsService.CliReleaseChannel; - set - { - if (this.userStorageSettingsService == null || this.userStorageSettingsService.CliReleaseChannel == value) - { - return; - } - this.userStorageSettingsService.CliReleaseChannel = value; - } - } - public string CliDownloadUrl - { - get => this.userStorageSettingsService.CliDownloadUrl; - set - { - if (this.userStorageSettingsService == null || this.userStorageSettingsService.CliDownloadUrl == value) - { - return; - } - this.userStorageSettingsService.CliDownloadUrl = value; - } - } - - public ISet TrustedFolders - { - get => this.userStorageSettingsService.TrustedFolders; - set - { - if (this.userStorageSettingsService == null || this.userStorageSettingsService.TrustedFolders == value) - return; - this.userStorageSettingsService.TrustedFolders = value; - } - } - - public bool EnableDeltaFindings - { - get => this.userStorageSettingsService.EnableDeltaFindings; - set - { - if (this.userStorageSettingsService == null || this.userStorageSettingsService.EnableDeltaFindings == value) - return; - this.userStorageSettingsService.EnableDeltaFindings = value; - userStorageSettingsService.SaveSettings(); - } - } - - public List FolderConfigs - { - get => this.userStorageSettingsService.FolderConfigs; - set - { - if (this.userStorageSettingsService == null) - return; - this.userStorageSettingsService.FolderConfigs = value; - userStorageSettingsService.SaveSettings(); - this.SettingsChanged?.Invoke(this, new SnykSettingsChangedEventArgs()); - } - } - public event EventHandler SettingsChanged; - /// - /// Gets a value indicating whether additional options. - /// Get this data using . - /// - /// representing the asynchronous operation. - public async Task GetAdditionalOptionsAsync() => await this.serviceProvider.UserStorageSettingsService.GetAdditionalOptionsAsync(); - - /// - /// Gets a value indicating whether is scan all projects enabled via . - /// Get this data using . - /// - /// representing the asynchronous operation. - public async Task IsScanAllProjectsAsync() => await this.userStorageSettingsService.GetIsAllProjectsEnabledAsync(); - - - public string CurrentCliVersion - { - get => this.userStorageSettingsService.CurrentCliVersion; - set - { - if (this.userStorageSettingsService == null || this.userStorageSettingsService.CurrentCliVersion == value) - { - return; - } - this.userStorageSettingsService.CurrentCliVersion = value; - } - } - - public SastSettings SastSettings { get; set; } - - public bool AnalyticsPluginInstalledSent - { - get => this.userStorageSettingsService.AnalyticsPluginInstalledSent; - set => this.userStorageSettingsService.AnalyticsPluginInstalledSent = value; - } - public void InvokeSettingsChangedEvent() { this.SettingsChanged?.Invoke(this, new SnykSettingsChangedEventArgs()); @@ -344,7 +50,6 @@ public string GetCustomApiEndpoint() { return string.IsNullOrEmpty(CustomEndpoint) ? ApiEndpointResolver.DefaultApiEndpoint : ApiEndpointResolver.TranslateOldApiToNewApiEndpoint(CustomEndpoint); } - public string GetBaseAppUrl() { if (string.IsNullOrEmpty(CustomEndpoint)) @@ -354,10 +59,5 @@ public string GetBaseAppUrl() return string.IsNullOrEmpty(result) ? ApiEndpointResolver.DefaultAppEndpoint : result; } - - public void SaveSettings() - { - this.userStorageSettingsService.SaveSettings(); - } } } diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykOptionsManager.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykOptionsManager.cs new file mode 100644 index 00000000..b6949b26 --- /dev/null +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykOptionsManager.cs @@ -0,0 +1,100 @@ +using Snyk.VisualStudio.Extension.Authentication; +using Snyk.VisualStudio.Extension.Service; +using System.Threading.Tasks; + +namespace Snyk.VisualStudio.Extension.Settings +{ + public class SnykOptionsManager : ISnykOptionsManager + { + private readonly ISnykServiceProvider serviceProvider; + private readonly IUserStorageSettingsService userSettingsStorage; + + public SnykOptionsManager(ISnykServiceProvider serviceProvider) + { + this.serviceProvider = serviceProvider; + this.userSettingsStorage = serviceProvider.UserStorageSettingsService; + } + + public IPersistableOptions Load() + { + return new SnykOptions + { + DeviceId = userSettingsStorage.DeviceId, + TrustedFolders = userSettingsStorage.TrustedFolders, + AnalyticsPluginInstalledSent = userSettingsStorage.AnalyticsPluginInstalledSent, + AutoScan = userSettingsStorage.AutoScan, + IgnoreUnknownCA = userSettingsStorage.IgnoreUnknownCa, + + BinariesAutoUpdate = userSettingsStorage.BinariesAutoUpdate, + CliCustomPath = userSettingsStorage.CliCustomPath, + CliDownloadUrl = userSettingsStorage.CliDownloadUrl, + CliReleaseChannel = userSettingsStorage.CliReleaseChannel, + CurrentCliVersion = userSettingsStorage.CurrentCliVersion, + + AuthenticationMethod = userSettingsStorage.AuthenticationMethod, + ApiToken = new AuthenticationToken(userSettingsStorage.AuthenticationMethod, userSettingsStorage.Token), + CustomEndpoint = userSettingsStorage.CustomEndpoint, + Organization = userSettingsStorage.Organization, + + FolderConfigs = userSettingsStorage.FolderConfigs, + EnableDeltaFindings = userSettingsStorage.EnableDeltaFindings, + + OpenIssuesEnabled = userSettingsStorage.OpenIssuesEnabled, + IgnoredIssuesEnabled = userSettingsStorage.IgnoredIssuesEnabled, + + IacEnabled = userSettingsStorage.IacEnabled, + SnykCodeQualityEnabled = userSettingsStorage.SnykCodeQualityEnabled, + SnykCodeSecurityEnabled = userSettingsStorage.SnykCodeSecurityEnabled, + OssEnabled = userSettingsStorage.OssEnabled, + }; + } + + public void Save(IPersistableOptions options) + { + userSettingsStorage.DeviceId = options.DeviceId; + userSettingsStorage.TrustedFolders = options.TrustedFolders; + userSettingsStorage.AnalyticsPluginInstalledSent = options.AnalyticsPluginInstalledSent; + userSettingsStorage.AutoScan = options.AutoScan; + userSettingsStorage.IgnoreUnknownCa = options.IgnoreUnknownCA; + + userSettingsStorage.BinariesAutoUpdate = options.BinariesAutoUpdate; + userSettingsStorage.CliCustomPath = options.CliCustomPath; + userSettingsStorage.CliDownloadUrl = options.CliDownloadUrl; + userSettingsStorage.CliReleaseChannel = options.CliReleaseChannel; + userSettingsStorage.CurrentCliVersion = options.CurrentCliVersion; + + userSettingsStorage.AuthenticationMethod = options.AuthenticationMethod; + userSettingsStorage.Token = options.ApiToken.ToString(); + + userSettingsStorage.CustomEndpoint = options.CustomEndpoint; + userSettingsStorage.Organization = options.Organization; + + userSettingsStorage.FolderConfigs = options.FolderConfigs; + userSettingsStorage.EnableDeltaFindings = options.EnableDeltaFindings; + + userSettingsStorage.OpenIssuesEnabled = options.OpenIssuesEnabled; + userSettingsStorage.IgnoredIssuesEnabled = options.IgnoredIssuesEnabled; + + userSettingsStorage.IacEnabled = options.IacEnabled; + userSettingsStorage.SnykCodeQualityEnabled = options.SnykCodeQualityEnabled; + userSettingsStorage.SnykCodeSecurityEnabled = options.SnykCodeSecurityEnabled; + userSettingsStorage.OssEnabled = options.OssEnabled; + + this.userSettingsStorage.SaveSettings(); + } + + /// + /// Gets a value indicating whether additional options. + /// Get this data using . + /// + /// representing the asynchronous operation. + public async Task GetAdditionalOptionsAsync() => await this.userSettingsStorage.GetAdditionalOptionsAsync(); + + /// + /// Gets a value indicating whether is scan all projects enabled via . + /// Get this data using . + /// + /// representing the asynchronous operation. + public async Task IsScanAllProjectsAsync() => await this.userSettingsStorage.GetIsAllProjectsEnabledAsync(); + } +} diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykUserStorageSettingsService.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykUserStorageSettingsService.cs index 6fd92692..3c58a10f 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykUserStorageSettingsService.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykUserStorageSettingsService.cs @@ -233,6 +233,7 @@ public async Task GetAdditionalOptionsAsync() /// A representing the asynchronous operation. public async Task SaveAdditionalOptionsAsync(string additionalOptions) { + // TODO: Move to SnykOptionsManager Logger.Information("Enter SaveAdditionalOptions method"); var solutionPathHash = await this.GetSolutionPathHashAsync(); @@ -264,6 +265,7 @@ public async Task SaveAdditionalOptionsAsync(string additionalOptions) /// A representing the asynchronous operation. public async Task SaveIsAllProjectsScanEnabledAsync(bool isAllProjectsEnabled) { + // TODO: Move to SnykOptionsManager Logger.Information("Enter SaveIsAllProjectsScan method"); var solutionPathHash = await this.GetSolutionPathHashAsync(); diff --git a/Snyk.VisualStudio.Extension.2022/Snyk.VisualStudio.Extension.2022.csproj b/Snyk.VisualStudio.Extension.2022/Snyk.VisualStudio.Extension.2022.csproj index 8d21d50c..3638a524 100644 --- a/Snyk.VisualStudio.Extension.2022/Snyk.VisualStudio.Extension.2022.csproj +++ b/Snyk.VisualStudio.Extension.2022/Snyk.VisualStudio.Extension.2022.csproj @@ -145,9 +145,11 @@ + + Component @@ -168,6 +170,7 @@ SnykGeneralSettingsUserControl.cs + diff --git a/Snyk.VisualStudio.Extension.2022/SnykVSPackage.cs b/Snyk.VisualStudio.Extension.2022/SnykVSPackage.cs index e0ea94aa..034bae5d 100644 --- a/Snyk.VisualStudio.Extension.2022/SnykVSPackage.cs +++ b/Snyk.VisualStudio.Extension.2022/SnykVSPackage.cs @@ -102,6 +102,7 @@ public void SetServiceProvider(ISnykServiceProvider serviceProvider) /// Gets the Options /// public ISnykOptions Options { get; private set; } + public ISnykOptionsManager SnykOptionsManager { get; private set; } public ISnykGeneralOptionsDialogPage SnykGeneralOptionsDialogPage { get; private set; } public ISnykCliOptionsDialogPage SnykCliOptionsDialogPage { get; private set; } @@ -306,11 +307,15 @@ private async Task LanguageClientManagerOnLanguageClientNotInitializedAsync(obje private async Task InitializeGeneralOptionsAsync() { + if (SnykOptionsManager == null) + { + SnykOptionsManager = new SnykOptionsManager(this.serviceProvider); + } if (Options == null) { Logger.Information( "Call GetDialogPage to create. await JoinableTaskFactory.SwitchToMainThreadAsync()."); - Options = new SnykOptions(this.serviceProvider); + Options = (ISnykOptions)SnykOptionsManager.Load(); var readableVsVersion = await this.GetReadableVsVersionAsync(); var vsMajorMinorVersion = await this.GetVsMajorMinorVersionAsync(); Options.Application = readableVsVersion; diff --git a/Snyk.VisualStudio.Extension.Tests/SnykOptionsTest.cs b/Snyk.VisualStudio.Extension.Tests/SnykOptionsTest.cs index f3af7bc6..3be1196e 100644 --- a/Snyk.VisualStudio.Extension.Tests/SnykOptionsTest.cs +++ b/Snyk.VisualStudio.Extension.Tests/SnykOptionsTest.cs @@ -20,7 +20,7 @@ public SnykOptionsTest(GlobalServiceProvider sp) var serviceProvider = serviceProviderMock.Object; var settingsFilePath = Path.Combine(SnykExtension.GetExtensionDirectoryPath(), "settings.json"); serviceProviderMock.Setup(x => x.UserStorageSettingsService).Returns(new SnykUserStorageSettingsService(settingsFilePath, serviceProvider)); - cut = new SnykOptions(serviceProvider); + cut = new SnykOptions(); } [Theory] From 4f89e4e2d480d73b3982c350ed6195bb70f3799e Mon Sep 17 00:00:00 2001 From: Abdelrahman Shawki Hassan Date: Tue, 17 Dec 2024 19:12:53 +0100 Subject: [PATCH 05/16] fix: set org on text change --- ...SnykGeneralSettingsUserControl.Designer.cs | 1 + .../SnykGeneralSettingsUserControl.cs | 6 ++++ .../SnykGeneralSettingsUserControl.resx | 32 +++++++++---------- 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.Designer.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.Designer.cs index f540adb6..1a9f217b 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.Designer.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.Designer.cs @@ -117,6 +117,7 @@ private void InitializeComponent() this.organizationTextBox.Name = "organizationTextBox"; this.organizationTextBox.Size = new System.Drawing.Size(399, 22); this.organizationTextBox.TabIndex = 3; + this.organizationTextBox.TextChanged += new System.EventHandler(this.organizationTextBox_TextChanged); // // tokenLabel // diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.cs index 790f7568..a4f2fe63 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.cs @@ -457,9 +457,15 @@ private void cbDelta_SelectionChangeCommitted(object sender, EventArgs e) snykOptions.EnableDeltaFindings = enableDelta; } + private void organizationTextBox_TextChanged(object sender, EventArgs e) + { + snykOptions.Organization = organizationTextBox.Text; + } + public Panel GetPanel() { return this.mainPanel; } + } } diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.resx b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.resx index 86b2d89c..16d8542b 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.resx +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.resx @@ -124,10 +124,10 @@ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO - vAAADrwBlbxySQAAALxJREFUOE/dUzEOwjAQyz9Y+FnzAV7Aa/hHpYiFNW+AqYKhYsl6nKu4So5DgNiw - 5OV8tprUCSLSsZQSlUkphpjFoGj3V6i4VeZ0vsswTrI5XDpiBg072O0CqnneHa9PRsv96YaQmSEMyBDs - MmHnNSTTHPFpdgkkPK0eJyIgeWd+R3jgRYC7ABKeBsL7JwEvL5HwtPYSf/uNtQvZayFh512RVEfAUmWv - jZZtldeAJuTjx7SYAQYQKn7xnCU8ABJO2R9gGis+AAAAAElFTkSuQmCC + vAAADrwBlbxySQAAALlJREFUOE/dk70NAjEMhb0HDZuRBZiAadgDKaKhzQxQnaA40bzW6EF8Sny5AKLD + 0mtsv0/5sUVVpRSAACACUCfmgohU/VMAWANI8XzXzWHQ1f5SiTnW2MPeCpDN4/Z4nRm9dqcbIaNBDJBY + 8M0WPp8hycyBR/NNPQCVrxMIiK07vxM99BIwK5p6J6Do/RPA4iP2AOUj/vaNNkitKVwCVIOUF+g5yq1p + 9CpHeQIUkI+X6bUEBcDi23V+ABJO2R9zc0PSAAAAAElFTkSuQmCC @@ -136,10 +136,10 @@ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO - vAAADrwBlbxySQAAALxJREFUOE/dUzEOwjAQyz9Y+FnzAV7Aa/hHpYiFNW+AqYKhYsl6nKu4So5DgNiw - 5OV8tprUCSLSsZQSlUkphpjFoGj3V6i4VeZ0vsswTrI5XDpiBg072O0CqnneHa9PRsv96YaQmSEMyBDs - MmHnNSTTHPFpdgkkPK0eJyIgeWd+R3jgRYC7ABKeBsL7JwEvL5HwtPYSf/uNtQvZayFh512RVEfAUmWv - jZZtldeAJuTjx7SYAQYQKn7xnCU8ABJO2R9gGis+AAAAAElFTkSuQmCC + vAAADrwBlbxySQAAALlJREFUOE/dk70NAjEMhb0HDZuRBZiAadgDKaKhzQxQnaA40bzW6EF8Sny5AKLD + 0mtsv0/5sUVVpRSAACACUCfmgohU/VMAWANI8XzXzWHQ1f5SiTnW2MPeCpDN4/Z4nRm9dqcbIaNBDJBY + 8M0WPp8hycyBR/NNPQCVrxMIiK07vxM99BIwK5p6J6Do/RPA4iP2AOUj/vaNNkitKVwCVIOUF+g5yq1p + 9CpHeQIUkI+X6bUEBcDi23V+ABJO2R9zc0PSAAAAAElFTkSuQmCC @@ -148,10 +148,10 @@ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO - vAAADrwBlbxySQAAALxJREFUOE/dUzEOwjAQyz9Y+FnzAV7Aa/hHpYiFNW+AqYKhYsl6nKu4So5DgNiw - 5OV8tprUCSLSsZQSlUkphpjFoGj3V6i4VeZ0vsswTrI5XDpiBg072O0CqnneHa9PRsv96YaQmSEMyBDs - MmHnNSTTHPFpdgkkPK0eJyIgeWd+R3jgRYC7ABKeBsL7JwEvL5HwtPYSf/uNtQvZayFh512RVEfAUmWv - jZZtldeAJuTjx7SYAQYQKn7xnCU8ABJO2R9gGis+AAAAAElFTkSuQmCC + vAAADrwBlbxySQAAALlJREFUOE/dk70NAjEMhb0HDZuRBZiAadgDKaKhzQxQnaA40bzW6EF8Sny5AKLD + 0mtsv0/5sUVVpRSAACACUCfmgohU/VMAWANI8XzXzWHQ1f5SiTnW2MPeCpDN4/Z4nRm9dqcbIaNBDJBY + 8M0WPp8hycyBR/NNPQCVrxMIiK07vxM99BIwK5p6J6Do/RPA4iP2AOUj/vaNNkitKVwCVIOUF+g5yq1p + 9CpHeQIUkI+X6bUEBcDi23V+ABJO2R9zc0PSAAAAAElFTkSuQmCC @@ -160,10 +160,10 @@ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO - vAAADrwBlbxySQAAALxJREFUOE/dUzEOwjAQyz9Y+FnzAV7Aa/hHpYiFNW+AqYKhYsl6nKu4So5DgNiw - 5OV8tprUCSLSsZQSlUkphpjFoGj3V6i4VeZ0vsswTrI5XDpiBg072O0CqnneHa9PRsv96YaQmSEMyBDs - MmHnNSTTHPFpdgkkPK0eJyIgeWd+R3jgRYC7ABKeBsL7JwEvL5HwtPYSf/uNtQvZayFh512RVEfAUmWv - jZZtldeAJuTjx7SYAQYQKn7xnCU8ABJO2R9gGis+AAAAAElFTkSuQmCC + vAAADrwBlbxySQAAALlJREFUOE/dk70NAjEMhb0HDZuRBZiAadgDKaKhzQxQnaA40bzW6EF8Sny5AKLD + 0mtsv0/5sUVVpRSAACACUCfmgohU/VMAWANI8XzXzWHQ1f5SiTnW2MPeCpDN4/Z4nRm9dqcbIaNBDJBY + 8M0WPp8hycyBR/NNPQCVrxMIiK07vxM99BIwK5p6J6Do/RPA4iP2AOUj/vaNNkitKVwCVIOUF+g5yq1p + 9CpHeQIUkI+X6bUEBcDi23V+ABJO2R9zc0PSAAAAAElFTkSuQmCC From 53a5799f5877058fc03a15885c1386fefb9fb054 Mon Sep 17 00:00:00 2001 From: Abdelrahman Shawki Hassan Date: Tue, 17 Dec 2024 19:45:13 +0100 Subject: [PATCH 06/16] fix: snykCliDialog download handle --- .../Settings/SnykCliOptionsDialogPage.cs | 37 ++++++++++------ .../SnykCliOptionsUserControl.Designer.cs | 9 ++-- .../Settings/SnykCliOptionsUserControl.cs | 44 ++++++------------- .../Settings/SnykGeneralOptionsDialogPage.cs | 1 + 4 files changed, 42 insertions(+), 49 deletions(-) diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsDialogPage.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsDialogPage.cs index c5d5ff0e..2f7bea2b 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsDialogPage.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsDialogPage.cs @@ -1,8 +1,8 @@ using System; -using System.Collections.Generic; using System.Runtime.InteropServices; using System.Windows.Forms; using Microsoft.VisualStudio.Shell; +using Snyk.VisualStudio.Extension.Language; using Snyk.VisualStudio.Extension.Service; namespace Snyk.VisualStudio.Extension.Settings; @@ -50,24 +50,33 @@ protected override void OnClosed(EventArgs e) private void HandleCliDownload() { - var releaseChannel = SnykCliOptionsUserControl.GetReleaseChannel().Trim(); - var downloadUrl = SnykCliOptionsUserControl.GetCliDownloadUrl().Trim(); - var manageBinariesAutomatically = SnykCliOptionsUserControl.GetManageBinariesAutomatically(); - if (!manageBinariesAutomatically) + var memento = SnykCliOptionsUserControl.OptionsMemento; + + this.SnykOptions.CliDownloadUrl = memento.CliDownloadUrl; + this.SnykOptions.CliCustomPath = memento.CliCustomPath; + + if (!memento.BinariesAutoUpdate) { - this.SnykOptions.CurrentCliVersion = string.Empty; - this.SnykOptions.BinariesAutoUpdate = false; - serviceProvider.TasksService.CancelDownloadTask(); - // Language Server restart will happen on DownloadCancelled Event. + HandleManualBinaries(memento); return; } - if (this.SnykOptions.CliReleaseChannel != releaseChannel || this.SnykOptions.CliDownloadUrl != downloadUrl || this.SnykOptions.BinariesAutoUpdate != manageBinariesAutomatically) + + // if auto-update is enabled, check if the release channel changed: + if (this.SnykOptions.CliReleaseChannel != memento.CliReleaseChannel) { - this.SnykOptions.CliDownloadUrl = downloadUrl; - this.SnykOptions.CliReleaseChannel = releaseChannel; - this.SnykOptions.BinariesAutoUpdate = manageBinariesAutomatically; - serviceProvider.TasksService.CancelDownloadTask(); + this.SnykOptions.CliReleaseChannel = memento.CliReleaseChannel; + this.SnykOptions.BinariesAutoUpdate = true; + serviceProvider.TasksService.CancelTasks(); this.serviceProvider.TasksService.Download(); } } + + private void HandleManualBinaries(ISnykOptions memento) + { + this.SnykOptions.CurrentCliVersion = string.Empty; + this.SnykOptions.BinariesAutoUpdate = false; + this.SnykOptions.CliReleaseChannel = memento.CliReleaseChannel; + serviceProvider.TasksService.CancelTasks(); + LanguageClientHelper.LanguageClientManager().RestartServerAsync().FireAndForget(); + } } \ No newline at end of file diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsUserControl.Designer.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsUserControl.Designer.cs index 5f61ead5..74d2e459 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsUserControl.Designer.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsUserControl.Designer.cs @@ -55,7 +55,7 @@ private void InitializeComponent() this.mainPanel.Dock = System.Windows.Forms.DockStyle.Fill; this.mainPanel.Location = new System.Drawing.Point(0, 0); this.mainPanel.Name = "mainPanel"; - this.mainPanel.Size = new System.Drawing.Size(752, 285); + this.mainPanel.Size = new System.Drawing.Size(803, 339); this.mainPanel.TabIndex = 0; // // ExecutablesGroupBox @@ -72,8 +72,8 @@ private void InitializeComponent() this.ExecutablesGroupBox.Controls.Add(this.CliPathBrowseButton); this.ExecutablesGroupBox.Controls.Add(this.manageBinariesAutomaticallyCheckbox); this.ExecutablesGroupBox.Controls.Add(this.CliPathTextBox); - this.ExecutablesGroupBox.Location = new System.Drawing.Point(4, 4); - this.ExecutablesGroupBox.Margin = new System.Windows.Forms.Padding(4); + this.ExecutablesGroupBox.Location = new System.Drawing.Point(11, 10); + this.ExecutablesGroupBox.Margin = new System.Windows.Forms.Padding(11, 10, 11, 10); this.ExecutablesGroupBox.Name = "ExecutablesGroupBox"; this.ExecutablesGroupBox.Padding = new System.Windows.Forms.Padding(4); this.ExecutablesGroupBox.Size = new System.Drawing.Size(729, 261); @@ -189,6 +189,7 @@ private void InitializeComponent() this.manageBinariesAutomaticallyCheckbox.Size = new System.Drawing.Size(18, 17); this.manageBinariesAutomaticallyCheckbox.TabIndex = 13; this.manageBinariesAutomaticallyCheckbox.UseVisualStyleBackColor = true; + this.manageBinariesAutomaticallyCheckbox.CheckedChanged += new System.EventHandler(this.manageBinariesAutomaticallyCheckbox_CheckedChanged); // // CliPathTextBox // @@ -209,7 +210,7 @@ private void InitializeComponent() this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.Controls.Add(this.mainPanel); this.Name = "SnykCliOptionsUserControl"; - this.Size = new System.Drawing.Size(752, 285); + this.Size = new System.Drawing.Size(803, 339); this.mainPanel.ResumeLayout(false); this.ExecutablesGroupBox.ResumeLayout(false); this.ExecutablesGroupBox.PerformLayout(); diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsUserControl.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsUserControl.cs index fa5b6820..500c86ab 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsUserControl.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsUserControl.cs @@ -11,15 +11,13 @@ namespace Snyk.VisualStudio.Extension.Settings public partial class SnykCliOptionsUserControl : UserControl { private readonly ISnykServiceProvider serviceProvider; - private readonly ISnykOptions snykOptions; - private readonly ISnykOptions memento; + public ISnykOptions OptionsMemento { get; set; } private static readonly ILogger Logger = LogManager.ForContext(); public SnykCliOptionsUserControl(ISnykServiceProvider serviceProvider) { this.serviceProvider = serviceProvider; - snykOptions = this.serviceProvider.Options; - memento = new SnykOptions(); + OptionsMemento = (ISnykOptions)serviceProvider.SnykOptionsManager.Load(); InitializeComponent(); this.Initialize(); } @@ -30,12 +28,12 @@ private void Initialize() private void UpdateViewFromOptions() { - this.manageBinariesAutomaticallyCheckbox.Checked = snykOptions.BinariesAutoUpdate; - this.cliDownloadUrlTextBox.Text = snykOptions.CliDownloadUrl; + this.manageBinariesAutomaticallyCheckbox.Checked = OptionsMemento.BinariesAutoUpdate; + this.cliDownloadUrlTextBox.Text = OptionsMemento.CliDownloadUrl; - var cliPath = string.IsNullOrEmpty(snykOptions.CliCustomPath) + var cliPath = string.IsNullOrEmpty(OptionsMemento.CliCustomPath) ? SnykCli.GetSnykCliDefaultPath() - : snykOptions.CliCustomPath; + : OptionsMemento.CliCustomPath; this.CliPathTextBox.Text = cliPath; if (releaseChannel.DataSource == null) @@ -43,15 +41,15 @@ private void UpdateViewFromOptions() this.releaseChannel.DataSource = ReleaseChannelList(); } - this.releaseChannel.SelectedItem = snykOptions.CliReleaseChannel; + this.releaseChannel.SelectedItem = OptionsMemento.CliReleaseChannel; } private IEnumerable ReleaseChannelList() { var defaultList = new List() { "stable", "rc", "preview" }; - if (!defaultList.Contains(snykOptions.CliReleaseChannel)) + if (!defaultList.Contains(OptionsMemento.CliReleaseChannel)) { - defaultList.Add(snykOptions.CliReleaseChannel); + defaultList.Add(OptionsMemento.CliReleaseChannel); } return defaultList; } @@ -67,8 +65,8 @@ private void CliPathBrowseButton_Click(object sender, System.EventArgs e) private void SetCliCustomPathValue(string selectedCliPath) { - snykOptions.CliCustomPath = selectedCliPath; - this.CliPathTextBox.Text = string.IsNullOrEmpty(snykOptions.CliCustomPath) + OptionsMemento.CliCustomPath = selectedCliPath; + this.CliPathTextBox.Text = string.IsNullOrEmpty(OptionsMemento.CliCustomPath) ? SnykCli.GetSnykCliDefaultPath() : selectedCliPath; } @@ -83,25 +81,9 @@ private void ReleaseChannelLink_LinkClicked(object sender, LinkLabelLinkClickedE this.ReleaseChannelLink.LinkVisited = true; Process.Start("https://docs.snyk.io/snyk-cli/releases-and-channels-for-the-snyk-cli"); } - - public string GetReleaseChannel() - { - return releaseChannel.Text; - } - - public string GetCliDownloadUrl() - { - return cliDownloadUrlTextBox.Text; - } - - public bool GetManageBinariesAutomatically() - { - return manageBinariesAutomaticallyCheckbox.Checked; - } - - public Panel GetPanel() + private void manageBinariesAutomaticallyCheckbox_CheckedChanged(object sender, System.EventArgs e) { - return this.mainPanel; + OptionsMemento.BinariesAutoUpdate = manageBinariesAutomaticallyCheckbox.Checked; } } } diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralOptionsDialogPage.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralOptionsDialogPage.cs index f4022626..e59356e0 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralOptionsDialogPage.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralOptionsDialogPage.cs @@ -98,6 +98,7 @@ private void SnykGeneralOptionsDialogPage_SettingsChanged(object sender, SnykSet { await serviceProvider.LanguageClientManager.DidChangeConfigurationAsync(SnykVSPackage .Instance.DisposalToken); + // TODO: move this to ScanConfigurationDialog onSave if (this.SnykOptions.AutoScan) await serviceProvider.LanguageClientManager.InvokeWorkspaceScanAsync(SnykVSPackage .Instance.DisposalToken); From c55acb93ddb7b6f0395e32a1a67bbc5327b64d6e Mon Sep 17 00:00:00 2001 From: Abdelrahman Shawki Hassan Date: Wed, 18 Dec 2024 18:37:21 +0100 Subject: [PATCH 07/16] wip: scan options dialog --- .../Settings/ISnykOptions.cs | 1 - .../Settings/ISnykScanOptionsDialogPage.cs | 8 + .../Settings/SnykCliOptionsDialogPage.cs | 49 ++- .../Settings/SnykCliOptionsUserControl.cs | 4 +- .../Settings/SnykGeneralOptionsDialogPage.cs | 4 - ...SnykGeneralSettingsUserControl.Designer.cs | 321 +-------------- .../SnykGeneralSettingsUserControl.cs | 185 +-------- .../SnykGeneralSettingsUserControl.resx | 43 +- .../Settings/SnykOptions.cs | 1 - .../Settings/SnykScanOptionsDialogPage.cs | 60 +++ .../SnykScanOptionsUserControl.Designer.cs | 371 ++++++++++++++++++ .../Settings/SnykScanOptionsUserControl.cs | 230 +++++++++++ .../Settings/SnykScanOptionsUserControl.resx | 157 ++++++++ .../Settings/SnykSettings.cs | 1 + .../SnykUserStorageSettingsService.cs | 6 +- .../Snyk.VisualStudio.Extension.2022.csproj | 13 + .../SnykVSPackage.cs | 24 +- 17 files changed, 891 insertions(+), 587 deletions(-) create mode 100644 Snyk.VisualStudio.Extension.2022/Settings/ISnykScanOptionsDialogPage.cs create mode 100644 Snyk.VisualStudio.Extension.2022/Settings/SnykScanOptionsDialogPage.cs create mode 100644 Snyk.VisualStudio.Extension.2022/Settings/SnykScanOptionsUserControl.Designer.cs create mode 100644 Snyk.VisualStudio.Extension.2022/Settings/SnykScanOptionsUserControl.cs create mode 100644 Snyk.VisualStudio.Extension.2022/Settings/SnykScanOptionsUserControl.resx diff --git a/Snyk.VisualStudio.Extension.2022/Settings/ISnykOptions.cs b/Snyk.VisualStudio.Extension.2022/Settings/ISnykOptions.cs index 49f71723..81232e1e 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/ISnykOptions.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/ISnykOptions.cs @@ -13,7 +13,6 @@ public interface ISnykOptions : IPersistableOptions string IntegrationVersion { get; } string IntegrationEnvironment { get; set; } string IntegrationEnvironmentVersion { get; set; } - SastSettings SastSettings { get; set; } bool ConsistentIgnoresEnabled { get; set; } /// diff --git a/Snyk.VisualStudio.Extension.2022/Settings/ISnykScanOptionsDialogPage.cs b/Snyk.VisualStudio.Extension.2022/Settings/ISnykScanOptionsDialogPage.cs new file mode 100644 index 00000000..2a2024b0 --- /dev/null +++ b/Snyk.VisualStudio.Extension.2022/Settings/ISnykScanOptionsDialogPage.cs @@ -0,0 +1,8 @@ +using Snyk.VisualStudio.Extension.Service; + +namespace Snyk.VisualStudio.Extension.Settings; + +public interface ISnykScanOptionsDialogPage +{ + void Initialize(ISnykServiceProvider provider); +} \ No newline at end of file diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsDialogPage.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsDialogPage.cs index 2f7bea2b..4ff932d1 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsDialogPage.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsDialogPage.cs @@ -13,15 +13,13 @@ public class SnykCliOptionsDialogPage : DialogPage, ISnykCliOptionsDialogPage { private SnykCliOptionsUserControl snykCliOptionsUserControl; private ISnykServiceProvider serviceProvider; + private ISnykOptions snykOptions; public void Initialize(ISnykServiceProvider provider) { this.serviceProvider = provider; - this.SnykOptions = provider.Options; + this.snykOptions = provider.Options; } - - public ISnykOptions SnykOptions { get; set; } - protected override IWin32Window Window => SnykCliOptionsUserControl; public SnykCliOptionsUserControl SnykCliOptionsUserControl { @@ -39,44 +37,45 @@ public SnykCliOptionsUserControl SnykCliOptionsUserControl public override void SaveSettingsToStorage() { HandleCliDownload(); - this.serviceProvider.SnykOptionsManager.Save(this.SnykOptions); - this.SnykOptions.InvokeSettingsChangedEvent(); + this.serviceProvider.SnykOptionsManager.Save(this.snykOptions); + this.snykOptions.InvokeSettingsChangedEvent(); } protected override void OnClosed(EventArgs e) { - + // do nothing } private void HandleCliDownload() { var memento = SnykCliOptionsUserControl.OptionsMemento; - this.SnykOptions.CliDownloadUrl = memento.CliDownloadUrl; - this.SnykOptions.CliCustomPath = memento.CliCustomPath; + this.snykOptions.CliDownloadUrl = memento.CliDownloadUrl; + + var binariesAutoUpdateChanged = this.snykOptions.BinariesAutoUpdate != memento.BinariesAutoUpdate; + var releaseChannelChanged = this.snykOptions.CliReleaseChannel != memento.CliReleaseChannel; + var cliCustomPathChanged = this.snykOptions.CliCustomPath != memento.CliCustomPath; - if (!memento.BinariesAutoUpdate) + this.snykOptions.CurrentCliVersion = memento.CurrentCliVersion; + this.snykOptions.BinariesAutoUpdate = memento.BinariesAutoUpdate; + this.snykOptions.CliReleaseChannel = memento.CliReleaseChannel; + this.snykOptions.CliCustomPath = memento.CliCustomPath; + + var hasChanges = binariesAutoUpdateChanged || releaseChannelChanged || cliCustomPathChanged; + if (!hasChanges) { - HandleManualBinaries(memento); return; } - // if auto-update is enabled, check if the release channel changed: - if (this.SnykOptions.CliReleaseChannel != memento.CliReleaseChannel) + serviceProvider.TasksService.CancelTasks(); + + if (memento.BinariesAutoUpdate) { - this.SnykOptions.CliReleaseChannel = memento.CliReleaseChannel; - this.SnykOptions.BinariesAutoUpdate = true; - serviceProvider.TasksService.CancelTasks(); this.serviceProvider.TasksService.Download(); } - } - - private void HandleManualBinaries(ISnykOptions memento) - { - this.SnykOptions.CurrentCliVersion = string.Empty; - this.SnykOptions.BinariesAutoUpdate = false; - this.SnykOptions.CliReleaseChannel = memento.CliReleaseChannel; - serviceProvider.TasksService.CancelTasks(); - LanguageClientHelper.LanguageClientManager().RestartServerAsync().FireAndForget(); + else + { + LanguageClientHelper.LanguageClientManager().RestartServerAsync().FireAndForget(); + } } } \ No newline at end of file diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsUserControl.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsUserControl.cs index 500c86ab..6ddcc1e2 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsUserControl.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsUserControl.cs @@ -2,7 +2,6 @@ using System.Diagnostics; using System.Windows.Forms; using Microsoft.VisualStudio.Shell; -using Serilog; using Snyk.VisualStudio.Extension.CLI; using Snyk.VisualStudio.Extension.Service; @@ -12,8 +11,7 @@ public partial class SnykCliOptionsUserControl : UserControl { private readonly ISnykServiceProvider serviceProvider; public ISnykOptions OptionsMemento { get; set; } - private static readonly ILogger Logger = LogManager.ForContext(); - + public SnykCliOptionsUserControl(ISnykServiceProvider serviceProvider) { this.serviceProvider = serviceProvider; diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralOptionsDialogPage.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralOptionsDialogPage.cs index e59356e0..0a676fcd 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralOptionsDialogPage.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralOptionsDialogPage.cs @@ -98,10 +98,6 @@ private void SnykGeneralOptionsDialogPage_SettingsChanged(object sender, SnykSet { await serviceProvider.LanguageClientManager.DidChangeConfigurationAsync(SnykVSPackage .Instance.DisposalToken); - // TODO: move this to ScanConfigurationDialog onSave - if (this.SnykOptions.AutoScan) - await serviceProvider.LanguageClientManager.InvokeWorkspaceScanAsync(SnykVSPackage - .Instance.DisposalToken); } }).FireAndForget(); } diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.Designer.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.Designer.cs index 1a9f217b..3da1433d 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.Designer.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.Designer.cs @@ -33,7 +33,6 @@ protected override void Dispose(bool disposing) private void InitializeComponent() { this.components = new System.ComponentModel.Container(); - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SnykGeneralSettingsUserControl)); this.customEndpointTextBox = new System.Windows.Forms.TextBox(); this.customEndpointLabel = new System.Windows.Forms.Label(); this.organizationLabel = new System.Windows.Forms.Label(); @@ -43,32 +42,12 @@ private void InitializeComponent() this.ignoreUnknownCACheckBox = new System.Windows.Forms.CheckBox(); this.authenticateButton = new System.Windows.Forms.Button(); this.errorProvider = new System.Windows.Forms.ErrorProvider(this.components); - this.ossEnabledCheckBox = new System.Windows.Forms.CheckBox(); - this.codeSecurityEnabledCheckBox = new System.Windows.Forms.CheckBox(); - this.codeQualityEnabledCheckBox = new System.Windows.Forms.CheckBox(); this.generalSettingsGroupBox = new System.Windows.Forms.GroupBox(); this.authMethodDescription = new System.Windows.Forms.RichTextBox(); this.authType = new System.Windows.Forms.ComboBox(); this.label2 = new System.Windows.Forms.Label(); this.OrganizationInfoLink = new System.Windows.Forms.LinkLabel(); this.OrgDescriptionText = new System.Windows.Forms.Label(); - this.productSelectionGroupBox = new System.Windows.Forms.GroupBox(); - this.label4 = new System.Windows.Forms.Label(); - this.label3 = new System.Windows.Forms.Label(); - this.cbDelta = new System.Windows.Forms.ComboBox(); - this.ignoreGroupbox = new System.Windows.Forms.GroupBox(); - this.cbIgnoredIssues = new System.Windows.Forms.CheckBox(); - this.cbOpenIssues = new System.Windows.Forms.CheckBox(); - this.snykIacInfoLabel = new System.Windows.Forms.Label(); - this.iacEnabledCheckbox = new System.Windows.Forms.CheckBox(); - this.snykCodeQualityInfoLabel = new System.Windows.Forms.Label(); - this.snykCodeSecurityInfoLabel = new System.Windows.Forms.Label(); - this.ossInfoLabel = new System.Windows.Forms.Label(); - this.checkAgainLinkLabel = new System.Windows.Forms.LinkLabel(); - this.snykCodeSettingsLinkLabel = new System.Windows.Forms.LinkLabel(); - this.snykCodeDisabledInfoLabel = new System.Windows.Forms.Label(); - this.userExperienceGroupBox = new System.Windows.Forms.GroupBox(); - this.autoScanCheckBox = new System.Windows.Forms.CheckBox(); this.ossInfoToolTip = new System.Windows.Forms.ToolTip(this.components); this.snykCodeSecurityInfoToolTip = new System.Windows.Forms.ToolTip(this.components); this.snykCodeQualityInfoToolTip = new System.Windows.Forms.ToolTip(this.components); @@ -76,9 +55,6 @@ private void InitializeComponent() this.mainPanel = new System.Windows.Forms.Panel(); ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit(); this.generalSettingsGroupBox.SuspendLayout(); - this.productSelectionGroupBox.SuspendLayout(); - this.ignoreGroupbox.SuspendLayout(); - this.userExperienceGroupBox.SuspendLayout(); this.mainPanel.SuspendLayout(); this.SuspendLayout(); // @@ -166,48 +142,6 @@ private void InitializeComponent() // this.errorProvider.ContainerControl = this; // - // ossEnabledCheckBox - // - this.ossEnabledCheckBox.AutoSize = true; - this.ossEnabledCheckBox.Checked = true; - this.ossEnabledCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; - this.ossEnabledCheckBox.Location = new System.Drawing.Point(16, 37); - this.ossEnabledCheckBox.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); - this.ossEnabledCheckBox.Name = "ossEnabledCheckBox"; - this.ossEnabledCheckBox.Size = new System.Drawing.Size(141, 20); - this.ossEnabledCheckBox.TabIndex = 11; - this.ossEnabledCheckBox.Text = "Snyk Open Source"; - this.ossEnabledCheckBox.UseVisualStyleBackColor = true; - this.ossEnabledCheckBox.CheckedChanged += new System.EventHandler(this.OssEnabledCheckBox_CheckedChanged); - // - // codeSecurityEnabledCheckBox - // - this.codeSecurityEnabledCheckBox.AutoSize = true; - this.codeSecurityEnabledCheckBox.Checked = true; - this.codeSecurityEnabledCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; - this.codeSecurityEnabledCheckBox.Location = new System.Drawing.Point(16, 95); - this.codeSecurityEnabledCheckBox.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); - this.codeSecurityEnabledCheckBox.Name = "codeSecurityEnabledCheckBox"; - this.codeSecurityEnabledCheckBox.Size = new System.Drawing.Size(146, 20); - this.codeSecurityEnabledCheckBox.TabIndex = 12; - this.codeSecurityEnabledCheckBox.Text = "Snyk Code Security"; - this.codeSecurityEnabledCheckBox.UseVisualStyleBackColor = true; - this.codeSecurityEnabledCheckBox.CheckedChanged += new System.EventHandler(this.CodeSecurityEnabledCheckBox_CheckedChanged); - // - // codeQualityEnabledCheckBox - // - this.codeQualityEnabledCheckBox.AutoSize = true; - this.codeQualityEnabledCheckBox.Checked = true; - this.codeQualityEnabledCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; - this.codeQualityEnabledCheckBox.Location = new System.Drawing.Point(256, 96); - this.codeQualityEnabledCheckBox.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); - this.codeQualityEnabledCheckBox.Name = "codeQualityEnabledCheckBox"; - this.codeQualityEnabledCheckBox.Size = new System.Drawing.Size(139, 20); - this.codeQualityEnabledCheckBox.TabIndex = 13; - this.codeQualityEnabledCheckBox.Text = "Snyk Code Quality"; - this.codeQualityEnabledCheckBox.UseVisualStyleBackColor = true; - this.codeQualityEnabledCheckBox.CheckedChanged += new System.EventHandler(this.CodeQualityEnabledCheckBox_CheckedChanged); - // // generalSettingsGroupBox // this.generalSettingsGroupBox.Controls.Add(this.authMethodDescription); @@ -223,7 +157,7 @@ private void InitializeComponent() this.generalSettingsGroupBox.Controls.Add(this.organizationLabel); this.generalSettingsGroupBox.Controls.Add(this.ignoreUnknownCACheckBox); this.generalSettingsGroupBox.Controls.Add(this.organizationTextBox); - this.generalSettingsGroupBox.Location = new System.Drawing.Point(29, 10); + this.generalSettingsGroupBox.Location = new System.Drawing.Point(10, 10); this.generalSettingsGroupBox.Margin = new System.Windows.Forms.Padding(11, 10, 11, 10); this.generalSettingsGroupBox.Name = "generalSettingsGroupBox"; this.generalSettingsGroupBox.Padding = new System.Windows.Forms.Padding(3, 2, 3, 2); @@ -291,226 +225,6 @@ private void InitializeComponent() this.OrgDescriptionText.Text = "Specify an organization slug name to run tests for that organization.\r\nIt must ma" + "tch the URL slug as displayed in the URL of your org in the Snyk UI:\r\nhttps://ap" + "p.snyk.io/org/[OrgSlugName]"; - // - // productSelectionGroupBox - // - this.productSelectionGroupBox.Controls.Add(this.label4); - this.productSelectionGroupBox.Controls.Add(this.label3); - this.productSelectionGroupBox.Controls.Add(this.cbDelta); - this.productSelectionGroupBox.Controls.Add(this.ignoreGroupbox); - this.productSelectionGroupBox.Controls.Add(this.snykIacInfoLabel); - this.productSelectionGroupBox.Controls.Add(this.iacEnabledCheckbox); - this.productSelectionGroupBox.Controls.Add(this.snykCodeQualityInfoLabel); - this.productSelectionGroupBox.Controls.Add(this.snykCodeSecurityInfoLabel); - this.productSelectionGroupBox.Controls.Add(this.ossInfoLabel); - this.productSelectionGroupBox.Controls.Add(this.checkAgainLinkLabel); - this.productSelectionGroupBox.Controls.Add(this.snykCodeSettingsLinkLabel); - this.productSelectionGroupBox.Controls.Add(this.snykCodeDisabledInfoLabel); - this.productSelectionGroupBox.Controls.Add(this.codeQualityEnabledCheckBox); - this.productSelectionGroupBox.Controls.Add(this.ossEnabledCheckBox); - this.productSelectionGroupBox.Controls.Add(this.codeSecurityEnabledCheckBox); - this.productSelectionGroupBox.Location = new System.Drawing.Point(29, 424); - this.productSelectionGroupBox.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); - this.productSelectionGroupBox.Name = "productSelectionGroupBox"; - this.productSelectionGroupBox.Padding = new System.Windows.Forms.Padding(11, 10, 11, 10); - this.productSelectionGroupBox.Size = new System.Drawing.Size(747, 242); - this.productSelectionGroupBox.TabIndex = 18; - this.productSelectionGroupBox.TabStop = false; - this.productSelectionGroupBox.Text = "Issue view options"; - // - // label4 - // - this.label4.AutoSize = true; - this.label4.Location = new System.Drawing.Point(12, 191); - this.label4.Name = "label4"; - this.label4.Size = new System.Drawing.Size(182, 16); - this.label4.TabIndex = 26; - this.label4.Text = "All Issues Vs Net New Issues:"; - // - // label3 - // - this.label3.AutoSize = true; - this.label3.Location = new System.Drawing.Point(12, 216); - this.label3.Name = "label3"; - this.label3.Size = new System.Drawing.Size(347, 16); - this.label3.TabIndex = 24; - this.label3.Text = "Specifies whether to see only net new issues or all issues."; - // - // cbDelta - // - this.cbDelta.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.cbDelta.FormattingEnabled = true; - this.cbDelta.Location = new System.Drawing.Point(235, 183); - this.cbDelta.Margin = new System.Windows.Forms.Padding(4); - this.cbDelta.Name = "cbDelta"; - this.cbDelta.Size = new System.Drawing.Size(160, 24); - this.cbDelta.TabIndex = 25; - this.cbDelta.SelectionChangeCommitted += new System.EventHandler(this.cbDelta_SelectionChangeCommitted); - // - // ignoreGroupbox - // - this.ignoreGroupbox.Controls.Add(this.cbIgnoredIssues); - this.ignoreGroupbox.Controls.Add(this.cbOpenIssues); - this.ignoreGroupbox.Location = new System.Drawing.Point(493, 15); - this.ignoreGroupbox.Name = "ignoreGroupbox"; - this.ignoreGroupbox.Size = new System.Drawing.Size(240, 80); - this.ignoreGroupbox.TabIndex = 23; - this.ignoreGroupbox.TabStop = false; - this.ignoreGroupbox.Text = "Show the following issues"; - // - // cbIgnoredIssues - // - this.cbIgnoredIssues.AutoSize = true; - this.cbIgnoredIssues.Checked = true; - this.cbIgnoredIssues.CheckState = System.Windows.Forms.CheckState.Checked; - this.cbIgnoredIssues.Location = new System.Drawing.Point(21, 51); - this.cbIgnoredIssues.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); - this.cbIgnoredIssues.Name = "cbIgnoredIssues"; - this.cbIgnoredIssues.Size = new System.Drawing.Size(117, 20); - this.cbIgnoredIssues.TabIndex = 25; - this.cbIgnoredIssues.Text = "Ignored issues"; - this.cbIgnoredIssues.UseVisualStyleBackColor = true; - this.cbIgnoredIssues.CheckedChanged += new System.EventHandler(this.cbIgnoredIssues_CheckedChanged); - // - // cbOpenIssues - // - this.cbOpenIssues.AutoSize = true; - this.cbOpenIssues.Checked = true; - this.cbOpenIssues.CheckState = System.Windows.Forms.CheckState.Checked; - this.cbOpenIssues.Location = new System.Drawing.Point(21, 22); - this.cbOpenIssues.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); - this.cbOpenIssues.Name = "cbOpenIssues"; - this.cbOpenIssues.Size = new System.Drawing.Size(104, 20); - this.cbOpenIssues.TabIndex = 24; - this.cbOpenIssues.Text = "Open issues"; - this.cbOpenIssues.UseVisualStyleBackColor = true; - this.cbOpenIssues.CheckedChanged += new System.EventHandler(this.cbOpenIssues_CheckedChanged); - // - // snykIacInfoLabel - // - this.snykIacInfoLabel.BackColor = System.Drawing.Color.Transparent; - this.snykIacInfoLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); - this.snykIacInfoLabel.Image = ((System.Drawing.Image)(resources.GetObject("snykIacInfoLabel.Image"))); - this.snykIacInfoLabel.Location = new System.Drawing.Point(228, 66); - this.snykIacInfoLabel.Margin = new System.Windows.Forms.Padding(0); - this.snykIacInfoLabel.MaximumSize = new System.Drawing.Size(21, 20); - this.snykIacInfoLabel.MinimumSize = new System.Drawing.Size(21, 20); - this.snykIacInfoLabel.Name = "snykIacInfoLabel"; - this.snykIacInfoLabel.Size = new System.Drawing.Size(21, 20); - this.snykIacInfoLabel.TabIndex = 22; - this.snykIacInfoLabel.Text = " "; - this.ossInfoToolTip.SetToolTip(this.snykIacInfoLabel, "Find and fix insecure configurations in Terraform and Kubernetes code"); - // - // iacEnabledCheckbox - // - this.iacEnabledCheckbox.AutoSize = true; - this.iacEnabledCheckbox.Checked = true; - this.iacEnabledCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; - this.iacEnabledCheckbox.Location = new System.Drawing.Point(16, 66); - this.iacEnabledCheckbox.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); - this.iacEnabledCheckbox.Name = "iacEnabledCheckbox"; - this.iacEnabledCheckbox.Size = new System.Drawing.Size(191, 20); - this.iacEnabledCheckbox.TabIndex = 21; - this.iacEnabledCheckbox.Text = "Snyk Infrastructure as Code"; - this.iacEnabledCheckbox.UseVisualStyleBackColor = true; - this.iacEnabledCheckbox.CheckedChanged += new System.EventHandler(this.iacEnabledCheckbox_CheckedChanged); - // - // snykCodeQualityInfoLabel - // - this.snykCodeQualityInfoLabel.BackColor = System.Drawing.Color.Transparent; - this.snykCodeQualityInfoLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); - this.snykCodeQualityInfoLabel.Image = ((System.Drawing.Image)(resources.GetObject("snykCodeQualityInfoLabel.Image"))); - this.snykCodeQualityInfoLabel.Location = new System.Drawing.Point(400, 92); - this.snykCodeQualityInfoLabel.Name = "snykCodeQualityInfoLabel"; - this.snykCodeQualityInfoLabel.Size = new System.Drawing.Size(27, 25); - this.snykCodeQualityInfoLabel.TabIndex = 20; - this.snykCodeQualityInfoLabel.Text = " "; - this.snykCodeQualityInfoToolTip.SetToolTip(this.snykCodeQualityInfoLabel, "Find and fix code quality issues in your application code in real time"); - // - // snykCodeSecurityInfoLabel - // - this.snykCodeSecurityInfoLabel.BackColor = System.Drawing.Color.Transparent; - this.snykCodeSecurityInfoLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); - this.snykCodeSecurityInfoLabel.Image = ((System.Drawing.Image)(resources.GetObject("snykCodeSecurityInfoLabel.Image"))); - this.snykCodeSecurityInfoLabel.Location = new System.Drawing.Point(167, 91); - this.snykCodeSecurityInfoLabel.Margin = new System.Windows.Forms.Padding(0); - this.snykCodeSecurityInfoLabel.Name = "snykCodeSecurityInfoLabel"; - this.snykCodeSecurityInfoLabel.Size = new System.Drawing.Size(27, 25); - this.snykCodeSecurityInfoLabel.TabIndex = 20; - this.snykCodeSecurityInfoLabel.Text = " "; - this.snykCodeSecurityInfoToolTip.SetToolTip(this.snykCodeSecurityInfoLabel, "Find and fix vulnerabilities in your application code in real time"); - // - // ossInfoLabel - // - this.ossInfoLabel.BackColor = System.Drawing.Color.Transparent; - this.ossInfoLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); - this.ossInfoLabel.Image = ((System.Drawing.Image)(resources.GetObject("ossInfoLabel.Image"))); - this.ossInfoLabel.Location = new System.Drawing.Point(167, 37); - this.ossInfoLabel.Margin = new System.Windows.Forms.Padding(0); - this.ossInfoLabel.MaximumSize = new System.Drawing.Size(21, 20); - this.ossInfoLabel.MinimumSize = new System.Drawing.Size(21, 20); - this.ossInfoLabel.Name = "ossInfoLabel"; - this.ossInfoLabel.Size = new System.Drawing.Size(21, 20); - this.ossInfoLabel.TabIndex = 20; - this.ossInfoLabel.Text = " "; - this.ossInfoToolTip.SetToolTip(this.ossInfoLabel, "Find and automatically fix open source vulnerabilities"); - // - // checkAgainLinkLabel - // - this.checkAgainLinkLabel.AutoSize = true; - this.checkAgainLinkLabel.Location = new System.Drawing.Point(211, 156); - this.checkAgainLinkLabel.Name = "checkAgainLinkLabel"; - this.checkAgainLinkLabel.Size = new System.Drawing.Size(82, 16); - this.checkAgainLinkLabel.TabIndex = 16; - this.checkAgainLinkLabel.TabStop = true; - this.checkAgainLinkLabel.Text = "Check again"; - this.checkAgainLinkLabel.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.CheckAgainLinkLabel_LinkClicked); - // - // snykCodeSettingsLinkLabel - // - this.snykCodeSettingsLinkLabel.AutoSize = true; - this.snykCodeSettingsLinkLabel.Location = new System.Drawing.Point(12, 156); - this.snykCodeSettingsLinkLabel.Name = "snykCodeSettingsLinkLabel"; - this.snykCodeSettingsLinkLabel.Size = new System.Drawing.Size(177, 16); - this.snykCodeSettingsLinkLabel.TabIndex = 15; - this.snykCodeSettingsLinkLabel.TabStop = true; - this.snykCodeSettingsLinkLabel.Text = "Snyk > Settings > Snyk Code"; - this.snykCodeSettingsLinkLabel.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.SnykCodeSettingsLinkLabel_LinkClicked); - // - // snykCodeDisabledInfoLabel - // - this.snykCodeDisabledInfoLabel.AutoSize = true; - this.snykCodeDisabledInfoLabel.Location = new System.Drawing.Point(12, 134); - this.snykCodeDisabledInfoLabel.Name = "snykCodeDisabledInfoLabel"; - this.snykCodeDisabledInfoLabel.Size = new System.Drawing.Size(358, 16); - this.snykCodeDisabledInfoLabel.TabIndex = 14; - this.snykCodeDisabledInfoLabel.Text = "Snyk Code is disabled by your organisation\'s configuration:"; - // - // userExperienceGroupBox - // - this.userExperienceGroupBox.Controls.Add(this.autoScanCheckBox); - this.userExperienceGroupBox.Location = new System.Drawing.Point(29, 670); - this.userExperienceGroupBox.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); - this.userExperienceGroupBox.Name = "userExperienceGroupBox"; - this.userExperienceGroupBox.Padding = new System.Windows.Forms.Padding(11, 10, 11, 10); - this.userExperienceGroupBox.Size = new System.Drawing.Size(747, 64); - this.userExperienceGroupBox.TabIndex = 19; - this.userExperienceGroupBox.TabStop = false; - this.userExperienceGroupBox.Text = "User experience"; - // - // autoScanCheckBox - // - this.autoScanCheckBox.AutoSize = true; - this.autoScanCheckBox.Checked = true; - this.autoScanCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; - this.autoScanCheckBox.Location = new System.Drawing.Point(16, 28); - this.autoScanCheckBox.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); - this.autoScanCheckBox.Name = "autoScanCheckBox"; - this.autoScanCheckBox.Size = new System.Drawing.Size(266, 20); - this.autoScanCheckBox.TabIndex = 10; - this.autoScanCheckBox.Text = "Scan automatically on start-up and save"; - this.autoScanCheckBox.UseVisualStyleBackColor = true; - this.autoScanCheckBox.CheckedChanged += new System.EventHandler(this.autoScanCheckBox_CheckedChanged); // // ossInfoToolTip // @@ -536,12 +250,10 @@ private void InitializeComponent() this.mainPanel.AutoScroll = true; this.mainPanel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; this.mainPanel.Controls.Add(this.generalSettingsGroupBox); - this.mainPanel.Controls.Add(this.productSelectionGroupBox); - this.mainPanel.Controls.Add(this.userExperienceGroupBox); this.mainPanel.Dock = System.Windows.Forms.DockStyle.Fill; this.mainPanel.Location = new System.Drawing.Point(0, 0); this.mainPanel.Name = "mainPanel"; - this.mainPanel.Size = new System.Drawing.Size(1060, 923); + this.mainPanel.Size = new System.Drawing.Size(789, 449); this.mainPanel.TabIndex = 20; // // SnykGeneralSettingsUserControl @@ -550,18 +262,11 @@ private void InitializeComponent() this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.Controls.Add(this.mainPanel); this.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); - this.MinimumSize = new System.Drawing.Size(1060, 923); this.Name = "SnykGeneralSettingsUserControl"; - this.Size = new System.Drawing.Size(1060, 923); + this.Size = new System.Drawing.Size(789, 449); ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit(); this.generalSettingsGroupBox.ResumeLayout(false); this.generalSettingsGroupBox.PerformLayout(); - this.productSelectionGroupBox.ResumeLayout(false); - this.productSelectionGroupBox.PerformLayout(); - this.ignoreGroupbox.ResumeLayout(false); - this.ignoreGroupbox.PerformLayout(); - this.userExperienceGroupBox.ResumeLayout(false); - this.userExperienceGroupBox.PerformLayout(); this.mainPanel.ResumeLayout(false); this.ResumeLayout(false); @@ -578,20 +283,9 @@ private void InitializeComponent() private System.Windows.Forms.CheckBox ignoreUnknownCACheckBox; private System.Windows.Forms.Button authenticateButton; private System.Windows.Forms.ErrorProvider errorProvider; - private System.Windows.Forms.CheckBox codeQualityEnabledCheckBox; - private System.Windows.Forms.CheckBox codeSecurityEnabledCheckBox; - private System.Windows.Forms.CheckBox ossEnabledCheckBox; private System.Windows.Forms.GroupBox generalSettingsGroupBox; - private System.Windows.Forms.GroupBox userExperienceGroupBox; - private System.Windows.Forms.GroupBox productSelectionGroupBox; - private System.Windows.Forms.LinkLabel checkAgainLinkLabel; - private System.Windows.Forms.LinkLabel snykCodeSettingsLinkLabel; - private System.Windows.Forms.Label snykCodeDisabledInfoLabel; - private System.Windows.Forms.Label ossInfoLabel; - private System.Windows.Forms.Label snykCodeSecurityInfoLabel; private System.Windows.Forms.ToolTip ossInfoToolTip; private System.Windows.Forms.ToolTip snykCodeSecurityInfoToolTip; - private System.Windows.Forms.Label snykCodeQualityInfoLabel; private System.Windows.Forms.ToolTip snykCodeQualityInfoToolTip; private LinkLabel OrganizationInfoLink; private Label OrgDescriptionText; @@ -599,15 +293,6 @@ private void InitializeComponent() private Label label2; private ComboBox authType; private RichTextBox authMethodDescription; - private CheckBox autoScanCheckBox; - private Label snykIacInfoLabel; - private CheckBox iacEnabledCheckbox; - private GroupBox ignoreGroupbox; - private CheckBox cbIgnoredIssues; - private CheckBox cbOpenIssues; - private Label label3; - private ComboBox cbDelta; - private Label label4; private Panel mainPanel; } } diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.cs index a4f2fe63..f4d2c09c 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.cs @@ -7,16 +7,13 @@ using System.Windows.Forms; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Threading; -using Newtonsoft.Json.Linq; using Serilog; using Snyk.VisualStudio.Extension.Authentication; using Snyk.VisualStudio.Extension.CLI; using Snyk.VisualStudio.Extension.Extension; using Snyk.VisualStudio.Extension.Language; using Snyk.VisualStudio.Extension.Service; -using Snyk.VisualStudio.Extension.UI.Notifications; using Task = System.Threading.Tasks.Task; -using Timer = System.Windows.Forms.Timer; namespace Snyk.VisualStudio.Extension.Settings { @@ -32,12 +29,6 @@ public partial class SnykGeneralSettingsUserControl : UserControl /// private readonly ISnykOptions snykOptions; - private static readonly int TwoSecondsDelay = 2000; - - private const int MaxSastRequestAttempts = 20; - - private readonly Timer snykCodeEnableTimer = new Timer(); - /// /// Initializes a new instance of the class. /// @@ -59,7 +50,6 @@ private void Initialize() this.UpdateViewFromOptions(); snykOptions.SettingsChanged += this.OptionsDialogPageOnSettingsChanged; - this.Load += this.SnykGeneralSettingsUserControl_Load; if (LanguageClientHelper.LanguageClientManager() != null) { @@ -88,17 +78,7 @@ private void UpdateViewFromOptions() this.customEndpointTextBox.Text = snykOptions.CustomEndpoint; this.organizationTextBox.Text = snykOptions.Organization; this.ignoreUnknownCACheckBox.Checked = snykOptions.IgnoreUnknownCA; - this.ossEnabledCheckBox.Checked = snykOptions.OssEnabled; - this.iacEnabledCheckbox.Checked = snykOptions.IacEnabled; - this.autoScanCheckBox.Checked = snykOptions.AutoScan; this.tokenTextBox.Text = snykOptions.ApiToken.ToString(); - this.cbIgnoredIssues.Checked = snykOptions.IgnoredIssuesEnabled; - this.cbOpenIssues.Checked = snykOptions.OpenIssuesEnabled; - - if (cbDelta.DataSource == null) - { - this.cbDelta.DataSource = DeltaOptionList(); - } if (authType.SelectedIndex == -1) { @@ -108,7 +88,6 @@ private void UpdateViewFromOptions() } this.authType.SelectedValue = snykOptions.AuthenticationMethod; - this.cbDelta.SelectedItem = snykOptions.EnableDeltaFindings ? "Net new issues" : "All issues"; } @@ -124,12 +103,6 @@ private IEnumerable AuthenticationMethodList() .ToList(); } - private IEnumerable DeltaOptionList() - { - var defaultList = new List { "All issues", "Net new issues"}; - return defaultList; - } - private void OptionsDialogPageOnSettingsChanged(object sender, SnykSettingsChangedEventArgs e) => ThreadHelper.JoinableTaskFactory.RunAsync(async () => { @@ -293,129 +266,7 @@ private void CustomEndpointTextBox_Validating(object sender, CancelEventArgs can cancelEventArgs.Cancel = true; this.errorProvider.SetError(this.customEndpointTextBox, "Needs to be a full absolute well-formed URL (including protocol)"); } - - private void SnykGeneralSettingsUserControl_Load(object sender, EventArgs e) - { - this.StartSastEnablementCheckLoop(); - this.CheckForIgnores(); - } - - private void UpdateSnykCodeEnablementSettings(SastSettings sastSettings) - { - var snykCodeEnabled = sastSettings?.SnykCodeEnabled ?? false; - - if (!snykCodeEnabled) - { - this.snykCodeDisabledInfoLabel.Text = "Snyk Code is disabled by your organisation\'s configuration:"; - } - - this.codeSecurityEnabledCheckBox.Enabled = snykCodeEnabled; - this.codeQualityEnabledCheckBox.Enabled = snykCodeEnabled; - this.snykCodeDisabledInfoLabel.Visible = !snykCodeEnabled; - this.snykCodeSettingsLinkLabel.Visible = !snykCodeEnabled; - this.checkAgainLinkLabel.Visible = !snykCodeEnabled; - } - - private void CheckForIgnores() - { - ThreadHelper.JoinableTaskFactory.RunAsync(async () => - { - if (!snykOptions.ConsistentIgnoresEnabled && LanguageClientHelper.IsLanguageServerReady()) - await serviceProvider.FeatureFlagService.RefreshAsync(SnykVSPackage.Instance.DisposalToken); - await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); - this.ignoreGroupbox.Visible = snykOptions.ConsistentIgnoresEnabled; - }).FireAndForget(); - } - private void StartSastEnablementCheckLoop() - { - try - { - if (this.snykCodeEnableTimer.Enabled) - { - this.snykCodeEnableTimer.Stop(); - } - - var currentRequestAttempt = 1; - - this.snykCodeEnableTimer.Interval = TwoSecondsDelay; - - this.snykCodeEnableTimer.Tick += (sender, args) => ThreadHelper.JoinableTaskFactory.RunAsync(async () => - { - try - { - if (!LanguageClientHelper.IsLanguageServerReady()) return; - var sastSettings = await this.serviceProvider.LanguageClientManager.InvokeGetSastEnabled(SnykVSPackage.Instance.DisposalToken); - - bool snykCodeEnabled = sastSettings != null ? sastSettings.SnykCodeEnabled : false; - - this.UpdateSnykCodeEnablementSettings(sastSettings); - - if (snykCodeEnabled) - { - this.snykCodeEnableTimer.Stop(); - } - else if (currentRequestAttempt < MaxSastRequestAttempts) - { - currentRequestAttempt++; - - this.snykCodeEnableTimer.Interval = TwoSecondsDelay * currentRequestAttempt; - } - else - { - this.snykCodeEnableTimer.Stop(); - } - } - catch (Exception e) - { - this.HandleSastError(e); - } - }); - - this.snykCodeEnableTimer.Start(); - } - catch (Exception e) - { - this.HandleSastError(e); - } - } - - private void HandleSastError(Exception e) - { - this.snykCodeEnableTimer.Stop(); - - NotificationService.Instance.ShowErrorInfoBar(e.Message); - - this.codeSecurityEnabledCheckBox.Enabled = false; - this.codeQualityEnabledCheckBox.Enabled = false; - - this.snykCodeDisabledInfoLabel.Visible = false; - this.snykCodeSettingsLinkLabel.Visible = false; - this.checkAgainLinkLabel.Visible = false; - } - - private void OssEnabledCheckBox_CheckedChanged(object sender, EventArgs e) - { - snykOptions.OssEnabled = this.ossEnabledCheckBox.Checked; - } - - private void CodeSecurityEnabledCheckBox_CheckedChanged(object sender, EventArgs e) - { - snykOptions.SnykCodeSecurityEnabled = this.codeSecurityEnabledCheckBox.Checked; - } - - private void CodeQualityEnabledCheckBox_CheckedChanged(object sender, EventArgs e) - { - snykOptions.SnykCodeQualityEnabled = this.codeQualityEnabledCheckBox.Checked; - } - - private void SnykCodeSettingsLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) - => Process.Start(snykOptions.SnykCodeSettingsUrl); - - private void CheckAgainLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) - { - this.StartSastEnablementCheckLoop(); - } - + private void OrganizationInfoLink_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { this.OrganizationInfoLink.LinkVisited = true; @@ -429,43 +280,9 @@ private void authType_SelectionChangeCommitted(object sender, EventArgs e) InvalidateApiToken(); } - private void autoScanCheckBox_CheckedChanged(object sender, EventArgs e) - { - snykOptions.AutoScan = autoScanCheckBox.Checked; - } - - private void iacEnabledCheckbox_CheckedChanged(object sender, EventArgs e) - { - snykOptions.IacEnabled = iacEnabledCheckbox.Checked; - } - - - private void cbOpenIssues_CheckedChanged(object sender, EventArgs e) - { - snykOptions.OpenIssuesEnabled = this.cbOpenIssues.Checked; - } - - private void cbIgnoredIssues_CheckedChanged(object sender, EventArgs e) - { - snykOptions.IgnoredIssuesEnabled = this.cbIgnoredIssues.Checked; - } - private void cbDelta_SelectionChangeCommitted(object sender, EventArgs e) - { - if (this.cbDelta.SelectedItem == null) - return; - var enableDelta = this.cbDelta.SelectedItem.ToString() == "Net new issues"; - snykOptions.EnableDeltaFindings = enableDelta; - } - private void organizationTextBox_TextChanged(object sender, EventArgs e) { snykOptions.Organization = organizationTextBox.Text; } - - public Panel GetPanel() - { - return this.mainPanel; - } - } } diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.resx b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.resx index 16d8542b..6eaada4b 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.resx +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.resx @@ -120,52 +120,15 @@ 17, 17 - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO - vAAADrwBlbxySQAAALlJREFUOE/dk70NAjEMhb0HDZuRBZiAadgDKaKhzQxQnaA40bzW6EF8Sny5AKLD - 0mtsv0/5sUVVpRSAACACUCfmgohU/VMAWANI8XzXzWHQ1f5SiTnW2MPeCpDN4/Z4nRm9dqcbIaNBDJBY - 8M0WPp8hycyBR/NNPQCVrxMIiK07vxM99BIwK5p6J6Do/RPA4iP2AOUj/vaNNkitKVwCVIOUF+g5yq1p - 9CpHeQIUkI+X6bUEBcDi23V+ABJO2R9zc0PSAAAAAElFTkSuQmCC - - 140, 17 - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO - vAAADrwBlbxySQAAALlJREFUOE/dk70NAjEMhb0HDZuRBZiAadgDKaKhzQxQnaA40bzW6EF8Sny5AKLD - 0mtsv0/5sUVVpRSAACACUCfmgohU/VMAWANI8XzXzWHQ1f5SiTnW2MPeCpDN4/Z4nRm9dqcbIaNBDJBY - 8M0WPp8hycyBR/NNPQCVrxMIiK07vxM99BIwK5p6J6Do/RPA4iP2AOUj/vaNNkitKVwCVIOUF+g5yq1p - 9CpHeQIUkI+X6bUEBcDi23V+ABJO2R9zc0PSAAAAAElFTkSuQmCC - - - - 477, 17 - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO - vAAADrwBlbxySQAAALlJREFUOE/dk70NAjEMhb0HDZuRBZiAadgDKaKhzQxQnaA40bzW6EF8Sny5AKLD - 0mtsv0/5sUVVpRSAACACUCfmgohU/VMAWANI8XzXzWHQ1f5SiTnW2MPeCpDN4/Z4nRm9dqcbIaNBDJBY - 8M0WPp8hycyBR/NNPQCVrxMIiK07vxM99BIwK5p6J6Do/RPA4iP2AOUj/vaNNkitKVwCVIOUF+g5yq1p - 9CpHeQIUkI+X6bUEBcDi23V+ABJO2R9zc0PSAAAAAElFTkSuQmCC - - 270, 17 - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO - vAAADrwBlbxySQAAALlJREFUOE/dk70NAjEMhb0HDZuRBZiAadgDKaKhzQxQnaA40bzW6EF8Sny5AKLD - 0mtsv0/5sUVVpRSAACACUCfmgohU/VMAWANI8XzXzWHQ1f5SiTnW2MPeCpDN4/Z4nRm9dqcbIaNBDJBY - 8M0WPp8hycyBR/NNPQCVrxMIiK07vxM99BIwK5p6J6Do/RPA4iP2AOUj/vaNNkitKVwCVIOUF+g5yq1p - 9CpHeQIUkI+X6bUEBcDi23V+ABJO2R9zc0PSAAAAAElFTkSuQmCC - - + + 477, 17 + 680, 17 diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykOptions.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykOptions.cs index 68bb1690..781e54e7 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykOptions.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykOptions.cs @@ -15,7 +15,6 @@ public class SnykOptions : ISnykOptions public string IntegrationEnvironment { get; set; } public string IntegrationEnvironmentVersion { get; set; } public bool ConsistentIgnoresEnabled { get; set; } - public SastSettings SastSettings { get; set; } public string DeviceId { get; set; } public bool AutoScan { get; set; } public bool OpenIssuesEnabled { get; set; } diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykScanOptionsDialogPage.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykScanOptionsDialogPage.cs new file mode 100644 index 00000000..9573c0db --- /dev/null +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykScanOptionsDialogPage.cs @@ -0,0 +1,60 @@ +using System; +using System.Runtime.InteropServices; +using System.Windows.Forms; +using Microsoft.VisualStudio.Shell; +using Snyk.VisualStudio.Extension.Service; + +namespace Snyk.VisualStudio.Extension.Settings; + +[Guid("2AF9707D-A0A5-4D39-BC8C-6E23B4699F58")] +[ComVisible(true)] +public class SnykScanOptionsDialogPage : DialogPage, ISnykScanOptionsDialogPage +{ + private SnykScanOptionsUserControl snykScanOptionsUserControl; + private ISnykServiceProvider serviceProvider; + private ISnykOptions snykOptions; + + public void Initialize(ISnykServiceProvider provider) + { + this.serviceProvider = provider; + this.snykOptions = provider.Options; + } + + protected override IWin32Window Window => SnykCliOptionsUserControl; + public SnykScanOptionsUserControl SnykCliOptionsUserControl + { + get + { + if (snykScanOptionsUserControl == null) + { + snykScanOptionsUserControl = new SnykScanOptionsUserControl(serviceProvider); + } + return snykScanOptionsUserControl; + } + } + + // This method is used when the user clicks "Ok" + public override void SaveSettingsToStorage() + { + this.snykOptions.AutoScan = SnykCliOptionsUserControl.OptionsMemento.AutoScan; + this.snykOptions.EnableDeltaFindings = SnykCliOptionsUserControl.OptionsMemento.EnableDeltaFindings; + this.snykOptions.IgnoredIssuesEnabled = SnykCliOptionsUserControl.OptionsMemento.IgnoredIssuesEnabled; + this.snykOptions.OpenIssuesEnabled = SnykCliOptionsUserControl.OptionsMemento.OpenIssuesEnabled; + this.snykOptions.SnykCodeQualityEnabled = SnykCliOptionsUserControl.OptionsMemento.SnykCodeQualityEnabled; + this.snykOptions.SnykCodeSecurityEnabled = SnykCliOptionsUserControl.OptionsMemento.SnykCodeSecurityEnabled; + this.snykOptions.IacEnabled = SnykCliOptionsUserControl.OptionsMemento.IacEnabled; + this.snykOptions.OssEnabled = SnykCliOptionsUserControl.OptionsMemento.OssEnabled; + if (this.snykOptions.AutoScan) + serviceProvider.LanguageClientManager.InvokeWorkspaceScanAsync(SnykVSPackage + .Instance.DisposalToken).FireAndForget(); + + this.serviceProvider.SnykOptionsManager.Save(this.snykOptions); + this.snykOptions.InvokeSettingsChangedEvent(); + } + + protected override void OnClosed(EventArgs e) + { + // do nothing + } + +} \ No newline at end of file diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykScanOptionsUserControl.Designer.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykScanOptionsUserControl.Designer.cs new file mode 100644 index 00000000..f7e04a02 --- /dev/null +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykScanOptionsUserControl.Designer.cs @@ -0,0 +1,371 @@ +namespace Snyk.VisualStudio.Extension.Settings +{ + partial class SnykScanOptionsUserControl + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SnykScanOptionsUserControl)); + this.mainPanel = new System.Windows.Forms.Panel(); + this.productSelectionGroupBox = new System.Windows.Forms.GroupBox(); + this.label4 = new System.Windows.Forms.Label(); + this.label3 = new System.Windows.Forms.Label(); + this.cbDelta = new System.Windows.Forms.ComboBox(); + this.ignoreGroupbox = new System.Windows.Forms.GroupBox(); + this.cbIgnoredIssues = new System.Windows.Forms.CheckBox(); + this.cbOpenIssues = new System.Windows.Forms.CheckBox(); + this.snykIacInfoLabel = new System.Windows.Forms.Label(); + this.iacEnabledCheckbox = new System.Windows.Forms.CheckBox(); + this.snykCodeQualityInfoLabel = new System.Windows.Forms.Label(); + this.snykCodeSecurityInfoLabel = new System.Windows.Forms.Label(); + this.ossInfoLabel = new System.Windows.Forms.Label(); + this.checkAgainLinkLabel = new System.Windows.Forms.LinkLabel(); + this.snykCodeSettingsLinkLabel = new System.Windows.Forms.LinkLabel(); + this.snykCodeDisabledInfoLabel = new System.Windows.Forms.Label(); + this.codeQualityEnabledCheckBox = new System.Windows.Forms.CheckBox(); + this.ossEnabledCheckBox = new System.Windows.Forms.CheckBox(); + this.codeSecurityEnabledCheckBox = new System.Windows.Forms.CheckBox(); + this.userExperienceGroupBox = new System.Windows.Forms.GroupBox(); + this.autoScanCheckBox = new System.Windows.Forms.CheckBox(); + this.mainPanel.SuspendLayout(); + this.productSelectionGroupBox.SuspendLayout(); + this.ignoreGroupbox.SuspendLayout(); + this.userExperienceGroupBox.SuspendLayout(); + this.SuspendLayout(); + // + // mainPanel + // + this.mainPanel.AutoScroll = true; + this.mainPanel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.mainPanel.Controls.Add(this.productSelectionGroupBox); + this.mainPanel.Controls.Add(this.userExperienceGroupBox); + this.mainPanel.Dock = System.Windows.Forms.DockStyle.Fill; + this.mainPanel.Location = new System.Drawing.Point(0, 0); + this.mainPanel.Name = "mainPanel"; + this.mainPanel.Size = new System.Drawing.Size(803, 339); + this.mainPanel.TabIndex = 1; + // + // productSelectionGroupBox + // + this.productSelectionGroupBox.Controls.Add(this.label4); + this.productSelectionGroupBox.Controls.Add(this.label3); + this.productSelectionGroupBox.Controls.Add(this.cbDelta); + this.productSelectionGroupBox.Controls.Add(this.ignoreGroupbox); + this.productSelectionGroupBox.Controls.Add(this.snykIacInfoLabel); + this.productSelectionGroupBox.Controls.Add(this.iacEnabledCheckbox); + this.productSelectionGroupBox.Controls.Add(this.snykCodeQualityInfoLabel); + this.productSelectionGroupBox.Controls.Add(this.snykCodeSecurityInfoLabel); + this.productSelectionGroupBox.Controls.Add(this.ossInfoLabel); + this.productSelectionGroupBox.Controls.Add(this.checkAgainLinkLabel); + this.productSelectionGroupBox.Controls.Add(this.snykCodeSettingsLinkLabel); + this.productSelectionGroupBox.Controls.Add(this.snykCodeDisabledInfoLabel); + this.productSelectionGroupBox.Controls.Add(this.codeQualityEnabledCheckBox); + this.productSelectionGroupBox.Controls.Add(this.ossEnabledCheckBox); + this.productSelectionGroupBox.Controls.Add(this.codeSecurityEnabledCheckBox); + this.productSelectionGroupBox.Location = new System.Drawing.Point(17, 13); + this.productSelectionGroupBox.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); + this.productSelectionGroupBox.Name = "productSelectionGroupBox"; + this.productSelectionGroupBox.Padding = new System.Windows.Forms.Padding(11, 10, 11, 10); + this.productSelectionGroupBox.Size = new System.Drawing.Size(747, 242); + this.productSelectionGroupBox.TabIndex = 20; + this.productSelectionGroupBox.TabStop = false; + this.productSelectionGroupBox.Text = "Issue view options"; + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point(6, 128); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(182, 16); + this.label4.TabIndex = 26; + this.label4.Text = "All Issues Vs Net New Issues:"; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(6, 153); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(347, 16); + this.label3.TabIndex = 24; + this.label3.Text = "Specifies whether to see only net new issues or all issues."; + // + // cbDelta + // + this.cbDelta.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.cbDelta.FormattingEnabled = true; + this.cbDelta.Location = new System.Drawing.Point(229, 120); + this.cbDelta.Margin = new System.Windows.Forms.Padding(4); + this.cbDelta.Name = "cbDelta"; + this.cbDelta.Size = new System.Drawing.Size(160, 24); + this.cbDelta.TabIndex = 25; + this.cbDelta.SelectionChangeCommitted += new System.EventHandler(this.cbDelta_SelectionChangeCommitted); + // + // ignoreGroupbox + // + this.ignoreGroupbox.Controls.Add(this.cbIgnoredIssues); + this.ignoreGroupbox.Controls.Add(this.cbOpenIssues); + this.ignoreGroupbox.Location = new System.Drawing.Point(493, 15); + this.ignoreGroupbox.Name = "ignoreGroupbox"; + this.ignoreGroupbox.Size = new System.Drawing.Size(240, 80); + this.ignoreGroupbox.TabIndex = 23; + this.ignoreGroupbox.TabStop = false; + this.ignoreGroupbox.Text = "Show the following issues"; + // + // cbIgnoredIssues + // + this.cbIgnoredIssues.AutoSize = true; + this.cbIgnoredIssues.Checked = true; + this.cbIgnoredIssues.CheckState = System.Windows.Forms.CheckState.Checked; + this.cbIgnoredIssues.Location = new System.Drawing.Point(21, 51); + this.cbIgnoredIssues.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); + this.cbIgnoredIssues.Name = "cbIgnoredIssues"; + this.cbIgnoredIssues.Size = new System.Drawing.Size(117, 20); + this.cbIgnoredIssues.TabIndex = 25; + this.cbIgnoredIssues.Text = "Ignored issues"; + this.cbIgnoredIssues.UseVisualStyleBackColor = true; + this.cbIgnoredIssues.CheckedChanged += new System.EventHandler(this.cbIgnoredIssues_CheckedChanged); + // + // cbOpenIssues + // + this.cbOpenIssues.AutoSize = true; + this.cbOpenIssues.Checked = true; + this.cbOpenIssues.CheckState = System.Windows.Forms.CheckState.Checked; + this.cbOpenIssues.Location = new System.Drawing.Point(21, 22); + this.cbOpenIssues.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); + this.cbOpenIssues.Name = "cbOpenIssues"; + this.cbOpenIssues.Size = new System.Drawing.Size(104, 20); + this.cbOpenIssues.TabIndex = 24; + this.cbOpenIssues.Text = "Open issues"; + this.cbOpenIssues.UseVisualStyleBackColor = true; + this.cbOpenIssues.CheckedChanged += new System.EventHandler(this.cbOpenIssues_CheckedChanged); + // + // snykIacInfoLabel + // + this.snykIacInfoLabel.BackColor = System.Drawing.Color.Transparent; + this.snykIacInfoLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); + this.snykIacInfoLabel.Image = ((System.Drawing.Image)(resources.GetObject("snykIacInfoLabel.Image"))); + this.snykIacInfoLabel.Location = new System.Drawing.Point(228, 66); + this.snykIacInfoLabel.Margin = new System.Windows.Forms.Padding(0); + this.snykIacInfoLabel.MaximumSize = new System.Drawing.Size(21, 20); + this.snykIacInfoLabel.MinimumSize = new System.Drawing.Size(21, 20); + this.snykIacInfoLabel.Name = "snykIacInfoLabel"; + this.snykIacInfoLabel.Size = new System.Drawing.Size(21, 20); + this.snykIacInfoLabel.TabIndex = 22; + this.snykIacInfoLabel.Text = " "; + // + // iacEnabledCheckbox + // + this.iacEnabledCheckbox.AutoSize = true; + this.iacEnabledCheckbox.Checked = true; + this.iacEnabledCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; + this.iacEnabledCheckbox.Location = new System.Drawing.Point(16, 66); + this.iacEnabledCheckbox.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); + this.iacEnabledCheckbox.Name = "iacEnabledCheckbox"; + this.iacEnabledCheckbox.Size = new System.Drawing.Size(191, 20); + this.iacEnabledCheckbox.TabIndex = 21; + this.iacEnabledCheckbox.Text = "Snyk Infrastructure as Code"; + this.iacEnabledCheckbox.UseVisualStyleBackColor = true; + this.iacEnabledCheckbox.CheckedChanged += new System.EventHandler(this.iacEnabledCheckbox_CheckedChanged); + // + // snykCodeQualityInfoLabel + // + this.snykCodeQualityInfoLabel.BackColor = System.Drawing.Color.Transparent; + this.snykCodeQualityInfoLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); + this.snykCodeQualityInfoLabel.Image = ((System.Drawing.Image)(resources.GetObject("snykCodeQualityInfoLabel.Image"))); + this.snykCodeQualityInfoLabel.Location = new System.Drawing.Point(400, 92); + this.snykCodeQualityInfoLabel.Name = "snykCodeQualityInfoLabel"; + this.snykCodeQualityInfoLabel.Size = new System.Drawing.Size(27, 25); + this.snykCodeQualityInfoLabel.TabIndex = 20; + this.snykCodeQualityInfoLabel.Text = " "; + // + // snykCodeSecurityInfoLabel + // + this.snykCodeSecurityInfoLabel.BackColor = System.Drawing.Color.Transparent; + this.snykCodeSecurityInfoLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); + this.snykCodeSecurityInfoLabel.Image = ((System.Drawing.Image)(resources.GetObject("snykCodeSecurityInfoLabel.Image"))); + this.snykCodeSecurityInfoLabel.Location = new System.Drawing.Point(167, 91); + this.snykCodeSecurityInfoLabel.Margin = new System.Windows.Forms.Padding(0); + this.snykCodeSecurityInfoLabel.Name = "snykCodeSecurityInfoLabel"; + this.snykCodeSecurityInfoLabel.Size = new System.Drawing.Size(27, 25); + this.snykCodeSecurityInfoLabel.TabIndex = 20; + this.snykCodeSecurityInfoLabel.Text = " "; + // + // ossInfoLabel + // + this.ossInfoLabel.BackColor = System.Drawing.Color.Transparent; + this.ossInfoLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); + this.ossInfoLabel.Image = ((System.Drawing.Image)(resources.GetObject("ossInfoLabel.Image"))); + this.ossInfoLabel.Location = new System.Drawing.Point(167, 37); + this.ossInfoLabel.Margin = new System.Windows.Forms.Padding(0); + this.ossInfoLabel.MaximumSize = new System.Drawing.Size(21, 20); + this.ossInfoLabel.MinimumSize = new System.Drawing.Size(21, 20); + this.ossInfoLabel.Name = "ossInfoLabel"; + this.ossInfoLabel.Size = new System.Drawing.Size(21, 20); + this.ossInfoLabel.TabIndex = 20; + this.ossInfoLabel.Text = " "; + // + // checkAgainLinkLabel + // + this.checkAgainLinkLabel.AutoSize = true; + this.checkAgainLinkLabel.Location = new System.Drawing.Point(205, 217); + this.checkAgainLinkLabel.Name = "checkAgainLinkLabel"; + this.checkAgainLinkLabel.Size = new System.Drawing.Size(82, 16); + this.checkAgainLinkLabel.TabIndex = 16; + this.checkAgainLinkLabel.TabStop = true; + this.checkAgainLinkLabel.Text = "Check again"; + this.checkAgainLinkLabel.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.CheckAgainLinkLabel_LinkClicked); + // + // snykCodeSettingsLinkLabel + // + this.snykCodeSettingsLinkLabel.AutoSize = true; + this.snykCodeSettingsLinkLabel.Location = new System.Drawing.Point(6, 217); + this.snykCodeSettingsLinkLabel.Name = "snykCodeSettingsLinkLabel"; + this.snykCodeSettingsLinkLabel.Size = new System.Drawing.Size(177, 16); + this.snykCodeSettingsLinkLabel.TabIndex = 15; + this.snykCodeSettingsLinkLabel.TabStop = true; + this.snykCodeSettingsLinkLabel.Text = "Snyk > Settings > Snyk Code"; + this.snykCodeSettingsLinkLabel.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.SnykCodeSettingsLinkLabel_LinkClicked); + // + // snykCodeDisabledInfoLabel + // + this.snykCodeDisabledInfoLabel.AutoSize = true; + this.snykCodeDisabledInfoLabel.Location = new System.Drawing.Point(6, 195); + this.snykCodeDisabledInfoLabel.Name = "snykCodeDisabledInfoLabel"; + this.snykCodeDisabledInfoLabel.Size = new System.Drawing.Size(358, 16); + this.snykCodeDisabledInfoLabel.TabIndex = 14; + this.snykCodeDisabledInfoLabel.Text = "Snyk Code is disabled by your organisation\'s configuration:"; + // + // codeQualityEnabledCheckBox + // + this.codeQualityEnabledCheckBox.AutoSize = true; + this.codeQualityEnabledCheckBox.Checked = true; + this.codeQualityEnabledCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; + this.codeQualityEnabledCheckBox.Location = new System.Drawing.Point(256, 96); + this.codeQualityEnabledCheckBox.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); + this.codeQualityEnabledCheckBox.Name = "codeQualityEnabledCheckBox"; + this.codeQualityEnabledCheckBox.Size = new System.Drawing.Size(139, 20); + this.codeQualityEnabledCheckBox.TabIndex = 13; + this.codeQualityEnabledCheckBox.Text = "Snyk Code Quality"; + this.codeQualityEnabledCheckBox.UseVisualStyleBackColor = true; + this.codeQualityEnabledCheckBox.CheckedChanged += new System.EventHandler(this.CodeQualityEnabledCheckBox_CheckedChanged); + // + // ossEnabledCheckBox + // + this.ossEnabledCheckBox.AutoSize = true; + this.ossEnabledCheckBox.Checked = true; + this.ossEnabledCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; + this.ossEnabledCheckBox.Location = new System.Drawing.Point(16, 37); + this.ossEnabledCheckBox.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); + this.ossEnabledCheckBox.Name = "ossEnabledCheckBox"; + this.ossEnabledCheckBox.Size = new System.Drawing.Size(141, 20); + this.ossEnabledCheckBox.TabIndex = 11; + this.ossEnabledCheckBox.Text = "Snyk Open Source"; + this.ossEnabledCheckBox.UseVisualStyleBackColor = true; + this.ossEnabledCheckBox.CheckedChanged += new System.EventHandler(this.OssEnabledCheckBox_CheckedChanged); + // + // codeSecurityEnabledCheckBox + // + this.codeSecurityEnabledCheckBox.AutoSize = true; + this.codeSecurityEnabledCheckBox.Checked = true; + this.codeSecurityEnabledCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; + this.codeSecurityEnabledCheckBox.Location = new System.Drawing.Point(16, 95); + this.codeSecurityEnabledCheckBox.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); + this.codeSecurityEnabledCheckBox.Name = "codeSecurityEnabledCheckBox"; + this.codeSecurityEnabledCheckBox.Size = new System.Drawing.Size(146, 20); + this.codeSecurityEnabledCheckBox.TabIndex = 12; + this.codeSecurityEnabledCheckBox.Text = "Snyk Code Security"; + this.codeSecurityEnabledCheckBox.UseVisualStyleBackColor = true; + this.codeSecurityEnabledCheckBox.CheckedChanged += new System.EventHandler(this.CodeSecurityEnabledCheckBox_CheckedChanged); + // + // userExperienceGroupBox + // + this.userExperienceGroupBox.Controls.Add(this.autoScanCheckBox); + this.userExperienceGroupBox.Location = new System.Drawing.Point(17, 259); + this.userExperienceGroupBox.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); + this.userExperienceGroupBox.Name = "userExperienceGroupBox"; + this.userExperienceGroupBox.Padding = new System.Windows.Forms.Padding(11, 10, 11, 10); + this.userExperienceGroupBox.Size = new System.Drawing.Size(747, 64); + this.userExperienceGroupBox.TabIndex = 21; + this.userExperienceGroupBox.TabStop = false; + this.userExperienceGroupBox.Text = "User experience"; + // + // autoScanCheckBox + // + this.autoScanCheckBox.AutoSize = true; + this.autoScanCheckBox.Checked = true; + this.autoScanCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; + this.autoScanCheckBox.Location = new System.Drawing.Point(16, 28); + this.autoScanCheckBox.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); + this.autoScanCheckBox.Name = "autoScanCheckBox"; + this.autoScanCheckBox.Size = new System.Drawing.Size(266, 20); + this.autoScanCheckBox.TabIndex = 10; + this.autoScanCheckBox.Text = "Scan automatically on start-up and save"; + this.autoScanCheckBox.UseVisualStyleBackColor = true; + this.autoScanCheckBox.CheckedChanged += new System.EventHandler(this.autoScanCheckBox_CheckedChanged); + // + // SnykScanOptionsUserControl + // + this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.mainPanel); + this.Name = "SnykScanOptionsUserControl"; + this.Size = new System.Drawing.Size(803, 339); + this.mainPanel.ResumeLayout(false); + this.productSelectionGroupBox.ResumeLayout(false); + this.productSelectionGroupBox.PerformLayout(); + this.ignoreGroupbox.ResumeLayout(false); + this.ignoreGroupbox.PerformLayout(); + this.userExperienceGroupBox.ResumeLayout(false); + this.userExperienceGroupBox.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Panel mainPanel; + private System.Windows.Forms.GroupBox productSelectionGroupBox; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.ComboBox cbDelta; + private System.Windows.Forms.GroupBox ignoreGroupbox; + private System.Windows.Forms.CheckBox cbIgnoredIssues; + private System.Windows.Forms.CheckBox cbOpenIssues; + private System.Windows.Forms.Label snykIacInfoLabel; + private System.Windows.Forms.CheckBox iacEnabledCheckbox; + private System.Windows.Forms.Label snykCodeQualityInfoLabel; + private System.Windows.Forms.Label snykCodeSecurityInfoLabel; + private System.Windows.Forms.Label ossInfoLabel; + private System.Windows.Forms.LinkLabel checkAgainLinkLabel; + private System.Windows.Forms.LinkLabel snykCodeSettingsLinkLabel; + private System.Windows.Forms.Label snykCodeDisabledInfoLabel; + private System.Windows.Forms.CheckBox codeQualityEnabledCheckBox; + private System.Windows.Forms.CheckBox ossEnabledCheckBox; + private System.Windows.Forms.CheckBox codeSecurityEnabledCheckBox; + private System.Windows.Forms.GroupBox userExperienceGroupBox; + private System.Windows.Forms.CheckBox autoScanCheckBox; + } +} diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykScanOptionsUserControl.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykScanOptionsUserControl.cs new file mode 100644 index 00000000..f312c0bb --- /dev/null +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykScanOptionsUserControl.cs @@ -0,0 +1,230 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Windows.Forms; +using Microsoft.VisualStudio.Shell; +using Serilog; +using Snyk.VisualStudio.Extension.Language; +using Snyk.VisualStudio.Extension.Service; +using Snyk.VisualStudio.Extension.UI.Notifications; + +namespace Snyk.VisualStudio.Extension.Settings +{ + public partial class SnykScanOptionsUserControl : UserControl + { + private readonly ISnykServiceProvider serviceProvider; + private static readonly ILogger Logger = LogManager.ForContext(); + public ISnykOptions OptionsMemento { get; set; } + + private static readonly int TwoSecondsDelay = 2000; + + private const int MaxSastRequestAttempts = 20; + + private readonly Timer snykCodeEnableTimer = new Timer(); + + public SnykScanOptionsUserControl(ISnykServiceProvider serviceProvider) + { + this.serviceProvider = serviceProvider; + OptionsMemento = (ISnykOptions)serviceProvider.SnykOptionsManager.Load(); + serviceProvider.Options.SettingsChanged += OptionsOnSettingsChanged; + InitializeComponent(); + Initialize(); + } + + private void OptionsOnSettingsChanged(object sender, SnykSettingsChangedEventArgs e) + { + CheckForIgnores(); + } + + private void Initialize() + { + Logger.Information("Enter Initialize method"); + + this.UpdateViewFromOptions(); + OptionsMemento.SettingsChanged += this.OptionsDialogPageOnSettingsChanged; + this.Load += this.SnykScanOptionsUserControl_Load; + this.serviceProvider.ToolWindow.Show(); + Logger.Information("Leave Initialize method"); + } + + private void SnykScanOptionsUserControl_Load(object sender, EventArgs e) + { + this.StartSastEnablementCheckLoop(); + this.CheckForIgnores(); + } + + private void CheckForIgnores() + { + ThreadHelper.JoinableTaskFactory.RunAsync(async () => + { + if (!serviceProvider.Options.ConsistentIgnoresEnabled && LanguageClientHelper.IsLanguageServerReady()) + await serviceProvider.FeatureFlagService.RefreshAsync(SnykVSPackage.Instance.DisposalToken); + await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); + this.ignoreGroupbox.Visible = serviceProvider.Options.ConsistentIgnoresEnabled; + }).FireAndForget(); + } + + private void StartSastEnablementCheckLoop() + { + try + { + if (this.snykCodeEnableTimer.Enabled) + { + this.snykCodeEnableTimer.Stop(); + } + + var currentRequestAttempt = 1; + + this.snykCodeEnableTimer.Interval = TwoSecondsDelay; + + this.snykCodeEnableTimer.Tick += (sender, args) => ThreadHelper.JoinableTaskFactory.RunAsync(async () => + { + try + { + if (!LanguageClientHelper.IsLanguageServerReady()) return; + var sastSettings = await this.serviceProvider.LanguageClientManager.InvokeGetSastEnabled(SnykVSPackage.Instance.DisposalToken); + + bool snykCodeEnabled = sastSettings != null ? sastSettings.SnykCodeEnabled : false; + + this.UpdateSnykCodeEnablementSettings(sastSettings); + + if (snykCodeEnabled) + { + this.snykCodeEnableTimer.Stop(); + } + else if (currentRequestAttempt < MaxSastRequestAttempts) + { + currentRequestAttempt++; + + this.snykCodeEnableTimer.Interval = TwoSecondsDelay * currentRequestAttempt; + } + else + { + this.snykCodeEnableTimer.Stop(); + } + } + catch (Exception e) + { + this.HandleSastError(e); + } + }); + + this.snykCodeEnableTimer.Start(); + } + catch (Exception e) + { + this.HandleSastError(e); + } + } + + private void HandleSastError(Exception e) + { + this.snykCodeEnableTimer.Stop(); + + NotificationService.Instance.ShowErrorInfoBar(e.Message); + + this.codeSecurityEnabledCheckBox.Enabled = false; + this.codeQualityEnabledCheckBox.Enabled = false; + + this.snykCodeDisabledInfoLabel.Visible = false; + this.snykCodeSettingsLinkLabel.Visible = false; + this.checkAgainLinkLabel.Visible = false; + } + + private void UpdateSnykCodeEnablementSettings(SastSettings sastSettings) + { + var snykCodeEnabled = sastSettings?.SnykCodeEnabled ?? false; + + if (!snykCodeEnabled) + { + this.snykCodeDisabledInfoLabel.Text = "Snyk Code is disabled by your organisation\'s configuration:"; + } + + this.codeSecurityEnabledCheckBox.Enabled = snykCodeEnabled; + this.codeQualityEnabledCheckBox.Enabled = snykCodeEnabled; + this.snykCodeDisabledInfoLabel.Visible = !snykCodeEnabled; + this.snykCodeSettingsLinkLabel.Visible = !snykCodeEnabled; + this.checkAgainLinkLabel.Visible = !snykCodeEnabled; + } + + private void UpdateViewFromOptions() + { + this.ossEnabledCheckBox.Checked = OptionsMemento.OssEnabled; + this.iacEnabledCheckbox.Checked = OptionsMemento.IacEnabled; + this.autoScanCheckBox.Checked = OptionsMemento.AutoScan; + this.cbIgnoredIssues.Checked = OptionsMemento.IgnoredIssuesEnabled; + this.cbOpenIssues.Checked = OptionsMemento.OpenIssuesEnabled; + + if (cbDelta.DataSource == null) + { + this.cbDelta.DataSource = DeltaOptionList(); + } + this.cbDelta.SelectedItem = OptionsMemento.EnableDeltaFindings ? "Net new issues" : "All issues"; + } + + private IEnumerable DeltaOptionList() + { + var defaultList = new List { "All issues", "Net new issues" }; + return defaultList; + } + + private void OptionsDialogPageOnSettingsChanged(object sender, SnykSettingsChangedEventArgs e) => + ThreadHelper.JoinableTaskFactory.RunAsync(async () => + { + await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); + this.UpdateViewFromOptions(); + }).FireAndForget(); + + private void OssEnabledCheckBox_CheckedChanged(object sender, EventArgs e) + { + OptionsMemento.OssEnabled = this.ossEnabledCheckBox.Checked; + } + + private void iacEnabledCheckbox_CheckedChanged(object sender, EventArgs e) + { + OptionsMemento.IacEnabled = iacEnabledCheckbox.Checked; + } + + private void CodeSecurityEnabledCheckBox_CheckedChanged(object sender, EventArgs e) + { + OptionsMemento.SnykCodeSecurityEnabled = this.codeSecurityEnabledCheckBox.Checked; + } + + private void CodeQualityEnabledCheckBox_CheckedChanged(object sender, EventArgs e) + { + OptionsMemento.SnykCodeQualityEnabled = this.codeQualityEnabledCheckBox.Checked; + } + + private void cbOpenIssues_CheckedChanged(object sender, EventArgs e) + { + OptionsMemento.OpenIssuesEnabled = this.cbOpenIssues.Checked; + } + + private void cbIgnoredIssues_CheckedChanged(object sender, EventArgs e) + { + OptionsMemento.IgnoredIssuesEnabled = this.cbIgnoredIssues.Checked; + } + + private void cbDelta_SelectionChangeCommitted(object sender, EventArgs e) + { + if (this.cbDelta.SelectedItem == null) + return; + var enableDelta = this.cbDelta.SelectedItem.ToString() == "Net new issues"; + OptionsMemento.EnableDeltaFindings = enableDelta; + } + + private void autoScanCheckBox_CheckedChanged(object sender, EventArgs e) + { + OptionsMemento.AutoScan = autoScanCheckBox.Checked; + } + + private void SnykCodeSettingsLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + => Process.Start(OptionsMemento.SnykCodeSettingsUrl); + + private void CheckAgainLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + this.StartSastEnablementCheckLoop(); + } + + } +} diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykScanOptionsUserControl.resx b/Snyk.VisualStudio.Extension.2022/Settings/SnykScanOptionsUserControl.resx new file mode 100644 index 00000000..a82683b1 --- /dev/null +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykScanOptionsUserControl.resx @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + vAAADrwBlbxySQAAALlJREFUOE/dk70NAjEMhb0HDZuRBZiAadgDKaKhzQxQnaA40bzW6EF8Sny5AKLD + 0mtsv0/5sUVVpRSAACACUCfmgohU/VMAWANI8XzXzWHQ1f5SiTnW2MPeCpDN4/Z4nRm9dqcbIaNBDJBY + 8M0WPp8hycyBR/NNPQCVrxMIiK07vxM99BIwK5p6J6Do/RPA4iP2AOUj/vaNNkitKVwCVIOUF+g5yq1p + 9CpHeQIUkI+X6bUEBcDi23V+ABJO2R9zc0PSAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + vAAADrwBlbxySQAAALlJREFUOE/dk70NAjEMhb0HDZuRBZiAadgDKaKhzQxQnaA40bzW6EF8Sny5AKLD + 0mtsv0/5sUVVpRSAACACUCfmgohU/VMAWANI8XzXzWHQ1f5SiTnW2MPeCpDN4/Z4nRm9dqcbIaNBDJBY + 8M0WPp8hycyBR/NNPQCVrxMIiK07vxM99BIwK5p6J6Do/RPA4iP2AOUj/vaNNkitKVwCVIOUF+g5yq1p + 9CpHeQIUkI+X6bUEBcDi23V+ABJO2R9zc0PSAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + vAAADrwBlbxySQAAALlJREFUOE/dk70NAjEMhb0HDZuRBZiAadgDKaKhzQxQnaA40bzW6EF8Sny5AKLD + 0mtsv0/5sUVVpRSAACACUCfmgohU/VMAWANI8XzXzWHQ1f5SiTnW2MPeCpDN4/Z4nRm9dqcbIaNBDJBY + 8M0WPp8hycyBR/NNPQCVrxMIiK07vxM99BIwK5p6J6Do/RPA4iP2AOUj/vaNNkitKVwCVIOUF+g5yq1p + 9CpHeQIUkI+X6bUEBcDi23V+ABJO2R9zc0PSAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + vAAADrwBlbxySQAAALlJREFUOE/dk70NAjEMhb0HDZuRBZiAadgDKaKhzQxQnaA40bzW6EF8Sny5AKLD + 0mtsv0/5sUVVpRSAACACUCfmgohU/VMAWANI8XzXzWHQ1f5SiTnW2MPeCpDN4/Z4nRm9dqcbIaNBDJBY + 8M0WPp8hycyBR/NNPQCVrxMIiK07vxM99BIwK5p6J6Do/RPA4iP2AOUj/vaNNkitKVwCVIOUF+g5yq1p + 9CpHeQIUkI+X6bUEBcDi23V+ABJO2R9zc0PSAAAAAElFTkSuQmCC + + + \ No newline at end of file diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykSettings.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykSettings.cs index b6b14507..af270a9f 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykSettings.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykSettings.cs @@ -75,5 +75,6 @@ public SnykSettings() public bool IgnoredIssuesEnabled { get; set; } = true; public List FolderConfigs { get; set; } public bool EnableDeltaFindings { get; set; } + public bool AnalyticsPluginInstalledSent { get; set; } } } \ No newline at end of file diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykUserStorageSettingsService.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykUserStorageSettingsService.cs index 3c58a10f..b084d854 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykUserStorageSettingsService.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykUserStorageSettingsService.cs @@ -162,7 +162,11 @@ public string DeviceId set => snykSettings.DeviceId = value; } - public bool AnalyticsPluginInstalledSent { get; set; } + public bool AnalyticsPluginInstalledSent + { + get => snykSettings.AnalyticsPluginInstalledSent; + set => snykSettings.AnalyticsPluginInstalledSent = value; + } public bool OpenIssuesEnabled { diff --git a/Snyk.VisualStudio.Extension.2022/Snyk.VisualStudio.Extension.2022.csproj b/Snyk.VisualStudio.Extension.2022/Snyk.VisualStudio.Extension.2022.csproj index 3638a524..50e6cb3b 100644 --- a/Snyk.VisualStudio.Extension.2022/Snyk.VisualStudio.Extension.2022.csproj +++ b/Snyk.VisualStudio.Extension.2022/Snyk.VisualStudio.Extension.2022.csproj @@ -150,6 +150,7 @@ + Component @@ -171,6 +172,15 @@ + + Component + + + UserControl + + + SnykScanOptionsUserControl.cs + @@ -593,6 +603,9 @@ SnykGeneralSettingsUserControl.cs Designer + + SnykScanOptionsUserControl.cs + SnykSolutionOptionsUserControl.cs diff --git a/Snyk.VisualStudio.Extension.2022/SnykVSPackage.cs b/Snyk.VisualStudio.Extension.2022/SnykVSPackage.cs index 034bae5d..2c9b690f 100644 --- a/Snyk.VisualStudio.Extension.2022/SnykVSPackage.cs +++ b/Snyk.VisualStudio.Extension.2022/SnykVSPackage.cs @@ -53,6 +53,7 @@ namespace Snyk.VisualStudio.Extension [ProvideOptionPage(typeof(SnykGeneralOptionsDialogPage), "Snyk", "General", 1000, 1001, true)] [ProvideOptionPage(typeof(SnykSolutionOptionsDialogPage), "Snyk", "Solution settings", 1000, 1002, true)] [ProvideOptionPage(typeof(SnykCliOptionsDialogPage), "Snyk", "CLI settings", 1000, 1003, true)] + [ProvideOptionPage(typeof(SnykScanOptionsDialogPage), "Snyk", "Scan settings", 1000, 1004, true)] public sealed class SnykVSPackage : AsyncPackage, ISnykOptionsProvider { /// @@ -105,6 +106,7 @@ public void SetServiceProvider(ISnykServiceProvider serviceProvider) public ISnykOptionsManager SnykOptionsManager { get; private set; } public ISnykGeneralOptionsDialogPage SnykGeneralOptionsDialogPage { get; private set; } public ISnykCliOptionsDialogPage SnykCliOptionsDialogPage { get; private set; } + public ISnykScanOptionsDialogPage SnykScanOptionsDialogPage { get; private set; } /// /// Gets instance. @@ -185,7 +187,7 @@ protected override async Task InitializeAsync(CancellationToken cancellationToke Logger.Information("Get SnykService as ServiceProvider."); Logger.Information("Start InitializeGeneralOptionsAsync."); - await InitializeGeneralOptionsAsync(); + await InitializeOptionsAsync(); // Initialize LS @@ -305,16 +307,17 @@ private async Task LanguageClientManagerOnLanguageClientNotInitializedAsync(obje }).FireAndForget(); } - private async Task InitializeGeneralOptionsAsync() + private async Task InitializeOptionsAsync() { + await JoinableTaskFactory.SwitchToMainThreadAsync(); + if (SnykOptionsManager == null) { SnykOptionsManager = new SnykOptionsManager(this.serviceProvider); } + if (Options == null) { - Logger.Information( - "Call GetDialogPage to create. await JoinableTaskFactory.SwitchToMainThreadAsync()."); Options = (ISnykOptions)SnykOptionsManager.Load(); var readableVsVersion = await this.GetReadableVsVersionAsync(); var vsMajorMinorVersion = await this.GetVsMajorMinorVersionAsync(); @@ -326,13 +329,8 @@ private async Task InitializeGeneralOptionsAsync() if (SnykGeneralOptionsDialogPage == null) { - await JoinableTaskFactory.SwitchToMainThreadAsync(); - - Logger.Information("GeneralOptionsDialogPage not created yet. Call GetDialogPage to create."); - SnykGeneralOptionsDialogPage = (SnykGeneralOptionsDialogPage)GetDialogPage(typeof(SnykGeneralOptionsDialogPage)); - Logger.Information("Call generalOptionsDialogPage.Initialize()"); SnykGeneralOptionsDialogPage.Initialize(this.serviceProvider); } @@ -342,9 +340,15 @@ private async Task InitializeGeneralOptionsAsync() SnykCliOptionsDialogPage = (SnykCliOptionsDialogPage)GetDialogPage(typeof(SnykCliOptionsDialogPage)); - Logger.Information("Call generalOptionsDialogPage.Initialize()"); SnykCliOptionsDialogPage.Initialize(this.serviceProvider); } + + if (SnykScanOptionsDialogPage == null) + { + SnykScanOptionsDialogPage = + (SnykScanOptionsDialogPage)GetDialogPage(typeof(SnykScanOptionsDialogPage)); + SnykScanOptionsDialogPage.Initialize(this.serviceProvider); + } } private async Task GetVsVersionAsync() From d78e58afd99fb6210acaa60cddb1a8da673d0116 Mon Sep 17 00:00:00 2001 From: Abdelrahman Shawki Hassan Date: Thu, 19 Dec 2024 06:48:02 +0100 Subject: [PATCH 08/16] fix: delete duplicate settingsProvider --- .../Service/ISnykServiceProvider.cs | 5 - .../Service/SnykService.cs | 16 +- .../Service/SnykTasksService.cs | 6 +- .../Settings/ISnykOptionsManager.cs | 28 +- .../Settings/IUserStorageSettingsService.cs | 74 ----- .../SnykGeneralSettingsUserControl.cs | 5 + .../Settings/SnykOptionsManager.cs | 235 ++++++++++---- .../SnykSolutionOptionsUserControl.cs | 13 +- .../SnykUserStorageSettingsService.cs | 300 ------------------ .../Snyk.VisualStudio.Extension.2022.csproj | 2 - .../SnykVSPackage.cs | 16 +- .../Language/LsSettingsTest.cs | 4 + .../SnykLanguageClientCustomTargetTests.cs | 8 +- .../Language/SnykLanguageClientTest.cs | 1 + .../PackageBaseTest.cs | 6 +- .../Service/WorkspaceTrustServiceTest.cs | 81 ++--- .../SnykOptionsTest.cs | 2 +- .../SnykUserStorageSettingsServiceTest.cs | 8 +- .../TestUtils.cs | 7 +- 19 files changed, 280 insertions(+), 537 deletions(-) delete mode 100644 Snyk.VisualStudio.Extension.2022/Settings/IUserStorageSettingsService.cs delete mode 100644 Snyk.VisualStudio.Extension.2022/Settings/SnykUserStorageSettingsService.cs diff --git a/Snyk.VisualStudio.Extension.2022/Service/ISnykServiceProvider.cs b/Snyk.VisualStudio.Extension.2022/Service/ISnykServiceProvider.cs index 73542770..01d16dda 100644 --- a/Snyk.VisualStudio.Extension.2022/Service/ISnykServiceProvider.cs +++ b/Snyk.VisualStudio.Extension.2022/Service/ISnykServiceProvider.cs @@ -58,11 +58,6 @@ public interface ISnykServiceProvider /// SnykVsThemeService VsThemeService { get; } - /// - /// Gets user storage settings service instance. - /// - IUserStorageSettingsService UserStorageSettingsService { get; } - /// /// Gets instance. /// diff --git a/Snyk.VisualStudio.Extension.2022/Service/SnykService.cs b/Snyk.VisualStudio.Extension.2022/Service/SnykService.cs index 506c0bef..54ae7ee1 100644 --- a/Snyk.VisualStudio.Extension.2022/Service/SnykService.cs +++ b/Snyk.VisualStudio.Extension.2022/Service/SnykService.cs @@ -4,8 +4,6 @@ using System.Threading.Tasks; using EnvDTE; using EnvDTE80; -using Microsoft; -using Microsoft.VisualStudio.ComponentModelHost; using Microsoft.VisualStudio.Settings; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell.Settings; @@ -36,7 +34,7 @@ public class SnykService : ISnykServiceProvider, ISnykService private DTE2 dte; - private SnykUserStorageSettingsService userStorageSettingsService; + private SnykOptionsManager snykOptionsManager; private SnykFeatureFlagService featureFlagService; private IWorkspaceTrustService workspaceTrustService; @@ -60,7 +58,6 @@ public SnykService(IAsyncServiceProvider serviceProvider, string vsVersion = "") public ISnykOptions Options => this.Package.Options; public ISnykGeneralOptionsDialogPage GeneralOptionsDialogPage => this.Package.SnykGeneralOptionsDialogPage; - public ISnykOptionsManager SnykOptionsManager => this.Package.SnykOptionsManager; /// /// Gets solution service. @@ -102,21 +99,18 @@ public SnykService(IAsyncServiceProvider serviceProvider, string vsVersion = "") /// public SnykVsThemeService VsThemeService => this.vsThemeService; - /// - /// Gets user storage settings service instance. - /// - public IUserStorageSettingsService UserStorageSettingsService + public ISnykOptionsManager SnykOptionsManager { get { - if (this.userStorageSettingsService == null) + if (this.snykOptionsManager == null) { string settingsFilePath = Path.Combine(SnykExtension.GetExtensionDirectoryPath(), "settings.json"); - this.userStorageSettingsService = new SnykUserStorageSettingsService(settingsFilePath, this); + this.snykOptionsManager = new SnykOptionsManager(settingsFilePath, this); } - return this.userStorageSettingsService; + return this.snykOptionsManager; } } diff --git a/Snyk.VisualStudio.Extension.2022/Service/SnykTasksService.cs b/Snyk.VisualStudio.Extension.2022/Service/SnykTasksService.cs index c1b20bd6..6a9c4b25 100644 --- a/Snyk.VisualStudio.Extension.2022/Service/SnykTasksService.cs +++ b/Snyk.VisualStudio.Extension.2022/Service/SnykTasksService.cs @@ -727,7 +727,7 @@ private void CancelTask(CancellationTokenSource tokenSource) public bool ShouldDownloadCli() { - if (!this.serviceProvider.UserStorageSettingsService.BinariesAutoUpdate) + if (!this.serviceProvider.Options.BinariesAutoUpdate) { return false; } @@ -750,8 +750,8 @@ public bool ShouldDownloadCli() private async Task DownloadAsync(CliDownloadFinishedCallback downloadFinishedCallback, ISnykProgressWorker progressWorker) { - var userSettingsStorageService = this.serviceProvider.UserStorageSettingsService; - if (!userSettingsStorageService.BinariesAutoUpdate) + var options = this.serviceProvider.Options; + if (!options.BinariesAutoUpdate) { Logger.Information("CLI auto-update is disabled, CLI download is skipped."); this.DownloadCancelled?.Invoke(this, new SnykCliDownloadEventArgs()); diff --git a/Snyk.VisualStudio.Extension.2022/Settings/ISnykOptionsManager.cs b/Snyk.VisualStudio.Extension.2022/Settings/ISnykOptionsManager.cs index 91d8a189..d0d6696b 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/ISnykOptionsManager.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/ISnykOptionsManager.cs @@ -4,8 +4,34 @@ namespace Snyk.VisualStudio.Extension.Settings; public interface ISnykOptionsManager { + void LoadSettingsFromFile(); + void SaveSettingsToFile(); IPersistableOptions Load(); void Save(IPersistableOptions options); + + /// + /// Get is all projects enabled. + /// + /// Bool. + Task GetIsAllProjectsEnabledAsync(); + + /// + /// Get CLI additional options string. + /// + /// string. Task GetAdditionalOptionsAsync(); - Task IsScanAllProjectsAsync(); + + /// + /// Save additional options string. + /// + /// CLI options string. + /// A representing the asynchronous operation. + Task SaveAdditionalOptionsAsync(string additionalOptions); + + /// + /// Sace is all projects scan enabled. + /// + /// Bool param. + /// A representing the asynchronous operation. + Task SaveIsAllProjectsScanEnabledAsync(bool isAllProjectsEnabled); } \ No newline at end of file diff --git a/Snyk.VisualStudio.Extension.2022/Settings/IUserStorageSettingsService.cs b/Snyk.VisualStudio.Extension.2022/Settings/IUserStorageSettingsService.cs deleted file mode 100644 index b2c66c73..00000000 --- a/Snyk.VisualStudio.Extension.2022/Settings/IUserStorageSettingsService.cs +++ /dev/null @@ -1,74 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; -using Snyk.VisualStudio.Extension.Authentication; -using Snyk.VisualStudio.Extension.Language; - -namespace Snyk.VisualStudio.Extension.Settings; - -public interface IUserStorageSettingsService -{ - void SaveSettings(); - bool BinariesAutoUpdate { get; set; } - string CliCustomPath { get; set; } - AuthenticationType AuthenticationMethod { get; set; } - - /// - /// Gets or sets trusted folders list. - /// - ISet TrustedFolders { get; set; } - - /// - /// Get Auto Scan option - /// - /// bool. - bool AutoScan { get; set; } - - /// - /// Get Or Set Auth Token - /// - /// string. - string Token { get; set; } - - string CliReleaseChannel { get; set; } - string CliDownloadUrl { get; set; } - bool IgnoreUnknownCa { get; set; } - string Organization { get; set; } - string CustomEndpoint { get; set; } - bool SnykCodeSecurityEnabled { get; set; } - bool SnykCodeQualityEnabled { get; set; } - bool OssEnabled { get; set; } - bool IacEnabled { get; set; } - string CurrentCliVersion { get; set; } - string DeviceId { get; set; } - bool AnalyticsPluginInstalledSent { get; set; } - bool OpenIssuesEnabled { get; set; } - bool IgnoredIssuesEnabled { get; set; } - List FolderConfigs { get; set; } - bool EnableDeltaFindings { get; set; } - - /// - /// Get is all projects enabled. - /// - /// Bool. - Task GetIsAllProjectsEnabledAsync(); - - /// - /// Get CLI additional options string. - /// - /// string. - Task GetAdditionalOptionsAsync(); - - /// - /// Save additional options string. - /// - /// CLI options string. - /// A representing the asynchronous operation. - Task SaveAdditionalOptionsAsync(string additionalOptions); - - /// - /// Sace is all projects scan enabled. - /// - /// Bool param. - /// A representing the asynchronous operation. - Task SaveIsAllProjectsScanEnabledAsync(bool isAllProjectsEnabled); -} \ No newline at end of file diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.cs index f4d2c09c..91922e83 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.cs @@ -284,5 +284,10 @@ private void organizationTextBox_TextChanged(object sender, EventArgs e) { snykOptions.Organization = organizationTextBox.Text; } + + public System.Windows.Forms.Panel GetPanel() + { + return this.mainPanel; + } } } diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykOptionsManager.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykOptionsManager.cs index b6949b26..11447a51 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykOptionsManager.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykOptionsManager.cs @@ -1,100 +1,211 @@ -using Snyk.VisualStudio.Extension.Authentication; +using System.IO; +using Snyk.VisualStudio.Extension.Authentication; using Snyk.VisualStudio.Extension.Service; using System.Threading.Tasks; +using Serilog; namespace Snyk.VisualStudio.Extension.Settings { public class SnykOptionsManager : ISnykOptionsManager { private readonly ISnykServiceProvider serviceProvider; - private readonly IUserStorageSettingsService userSettingsStorage; + private readonly SnykSettingsLoader settingsLoader; + private SnykSettings snykSettings; + private static readonly ILogger Logger = LogManager.ForContext(); - public SnykOptionsManager(ISnykServiceProvider serviceProvider) + public SnykOptionsManager(string settingsFilePath, ISnykServiceProvider serviceProvider) { this.serviceProvider = serviceProvider; - this.userSettingsStorage = serviceProvider.UserStorageSettingsService; + this.settingsLoader = new SnykSettingsLoader(settingsFilePath); + LoadSettingsFromFile(); + } + + public void LoadSettingsFromFile() + { + this.snykSettings = this.settingsLoader.Load(); + + if (this.snykSettings != null) return; + + this.snykSettings = new SnykSettings(); + SaveSettingsToFile(); + } + + public void SaveSettingsToFile() + { + this.settingsLoader.Save(snykSettings); } public IPersistableOptions Load() { return new SnykOptions { - DeviceId = userSettingsStorage.DeviceId, - TrustedFolders = userSettingsStorage.TrustedFolders, - AnalyticsPluginInstalledSent = userSettingsStorage.AnalyticsPluginInstalledSent, - AutoScan = userSettingsStorage.AutoScan, - IgnoreUnknownCA = userSettingsStorage.IgnoreUnknownCa, - - BinariesAutoUpdate = userSettingsStorage.BinariesAutoUpdate, - CliCustomPath = userSettingsStorage.CliCustomPath, - CliDownloadUrl = userSettingsStorage.CliDownloadUrl, - CliReleaseChannel = userSettingsStorage.CliReleaseChannel, - CurrentCliVersion = userSettingsStorage.CurrentCliVersion, - - AuthenticationMethod = userSettingsStorage.AuthenticationMethod, - ApiToken = new AuthenticationToken(userSettingsStorage.AuthenticationMethod, userSettingsStorage.Token), - CustomEndpoint = userSettingsStorage.CustomEndpoint, - Organization = userSettingsStorage.Organization, - - FolderConfigs = userSettingsStorage.FolderConfigs, - EnableDeltaFindings = userSettingsStorage.EnableDeltaFindings, - - OpenIssuesEnabled = userSettingsStorage.OpenIssuesEnabled, - IgnoredIssuesEnabled = userSettingsStorage.IgnoredIssuesEnabled, - - IacEnabled = userSettingsStorage.IacEnabled, - SnykCodeQualityEnabled = userSettingsStorage.SnykCodeQualityEnabled, - SnykCodeSecurityEnabled = userSettingsStorage.SnykCodeSecurityEnabled, - OssEnabled = userSettingsStorage.OssEnabled, + DeviceId = snykSettings.DeviceId, + TrustedFolders = snykSettings.TrustedFolders, + AnalyticsPluginInstalledSent = snykSettings.AnalyticsPluginInstalledSent, + AutoScan = snykSettings.AutoScan, + IgnoreUnknownCA = snykSettings.IgnoreUnknownCa, + + BinariesAutoUpdate = snykSettings.BinariesAutoUpdateEnabled, + CliCustomPath = snykSettings.CustomCliPath, + CliDownloadUrl = snykSettings.CliDownloadUrl, + CliReleaseChannel = snykSettings.CliReleaseChannel, + CurrentCliVersion = snykSettings.CurrentCliVersion, + + AuthenticationMethod = snykSettings.AuthenticationMethod, + ApiToken = new AuthenticationToken(snykSettings.AuthenticationMethod, snykSettings.Token), + CustomEndpoint = snykSettings.CustomEndpoint, + Organization = snykSettings.Organization, + + FolderConfigs = snykSettings.FolderConfigs, + EnableDeltaFindings = snykSettings.EnableDeltaFindings, + + OpenIssuesEnabled = snykSettings.OpenIssuesEnabled, + IgnoredIssuesEnabled = snykSettings.IgnoredIssuesEnabled, + + IacEnabled = snykSettings.IacEnabled, + SnykCodeQualityEnabled = snykSettings.SnykCodeQualityEnabled, + SnykCodeSecurityEnabled = snykSettings.SnykCodeSecurityEnabled, + OssEnabled = snykSettings.OssEnabled, }; } public void Save(IPersistableOptions options) { - userSettingsStorage.DeviceId = options.DeviceId; - userSettingsStorage.TrustedFolders = options.TrustedFolders; - userSettingsStorage.AnalyticsPluginInstalledSent = options.AnalyticsPluginInstalledSent; - userSettingsStorage.AutoScan = options.AutoScan; - userSettingsStorage.IgnoreUnknownCa = options.IgnoreUnknownCA; + snykSettings.DeviceId = options.DeviceId; + snykSettings.TrustedFolders = options.TrustedFolders; + snykSettings.AnalyticsPluginInstalledSent = options.AnalyticsPluginInstalledSent; + snykSettings.AutoScan = options.AutoScan; + snykSettings.IgnoreUnknownCa = options.IgnoreUnknownCA; - userSettingsStorage.BinariesAutoUpdate = options.BinariesAutoUpdate; - userSettingsStorage.CliCustomPath = options.CliCustomPath; - userSettingsStorage.CliDownloadUrl = options.CliDownloadUrl; - userSettingsStorage.CliReleaseChannel = options.CliReleaseChannel; - userSettingsStorage.CurrentCliVersion = options.CurrentCliVersion; + snykSettings.BinariesAutoUpdateEnabled = options.BinariesAutoUpdate; + snykSettings.CustomCliPath = options.CliCustomPath; + snykSettings.CliDownloadUrl = options.CliDownloadUrl; + snykSettings.CliReleaseChannel = options.CliReleaseChannel; + snykSettings.CurrentCliVersion = options.CurrentCliVersion; - userSettingsStorage.AuthenticationMethod = options.AuthenticationMethod; - userSettingsStorage.Token = options.ApiToken.ToString(); + snykSettings.AuthenticationMethod = options.AuthenticationMethod; + snykSettings.Token = options.ApiToken.ToString(); - userSettingsStorage.CustomEndpoint = options.CustomEndpoint; - userSettingsStorage.Organization = options.Organization; + snykSettings.CustomEndpoint = options.CustomEndpoint; + snykSettings.Organization = options.Organization; - userSettingsStorage.FolderConfigs = options.FolderConfigs; - userSettingsStorage.EnableDeltaFindings = options.EnableDeltaFindings; + snykSettings.FolderConfigs = options.FolderConfigs; + snykSettings.EnableDeltaFindings = options.EnableDeltaFindings; - userSettingsStorage.OpenIssuesEnabled = options.OpenIssuesEnabled; - userSettingsStorage.IgnoredIssuesEnabled = options.IgnoredIssuesEnabled; + snykSettings.OpenIssuesEnabled = options.OpenIssuesEnabled; + snykSettings.IgnoredIssuesEnabled = options.IgnoredIssuesEnabled; - userSettingsStorage.IacEnabled = options.IacEnabled; - userSettingsStorage.SnykCodeQualityEnabled = options.SnykCodeQualityEnabled; - userSettingsStorage.SnykCodeSecurityEnabled = options.SnykCodeSecurityEnabled; - userSettingsStorage.OssEnabled = options.OssEnabled; + snykSettings.IacEnabled = options.IacEnabled; + snykSettings.SnykCodeQualityEnabled = options.SnykCodeQualityEnabled; + snykSettings.SnykCodeSecurityEnabled = options.SnykCodeSecurityEnabled; + snykSettings.OssEnabled = options.OssEnabled; - this.userSettingsStorage.SaveSettings(); + this.SaveSettingsToFile(); } /// - /// Gets a value indicating whether additional options. - /// Get this data using . + /// Get is all projects enabled. /// - /// representing the asynchronous operation. - public async Task GetAdditionalOptionsAsync() => await this.userSettingsStorage.GetAdditionalOptionsAsync(); + /// Bool. + public async Task GetIsAllProjectsEnabledAsync() + { + Logger.Information("Enter GetIsAllProjectsEnabled method"); + + var solutionPathHash = await this.GetSolutionPathHashAsync(); + + if (snykSettings == null || !snykSettings.SolutionSettingsDict.ContainsKey(solutionPathHash)) + { + return true; + } + else + { + return snykSettings.SolutionSettingsDict[solutionPathHash].IsAllProjectsScanEnabled; + } + } + + /// + /// Get CLI additional options string. + /// + /// string. + public async Task GetAdditionalOptionsAsync() + { + Logger.Information("Enter GetAdditionalOptions method"); + + var solutionPathHash = await this.GetSolutionPathHashAsync(); + + if (snykSettings == null || !snykSettings.SolutionSettingsDict.ContainsKey(solutionPathHash)) + { + return string.Empty; + } + + return snykSettings.SolutionSettingsDict[solutionPathHash].AdditionalOptions; + } /// - /// Gets a value indicating whether is scan all projects enabled via . - /// Get this data using . + /// Save additional options string. /// - /// representing the asynchronous operation. - public async Task IsScanAllProjectsAsync() => await this.userSettingsStorage.GetIsAllProjectsEnabledAsync(); + /// CLI options string. + /// A representing the asynchronous operation. + public async Task SaveAdditionalOptionsAsync(string additionalOptions) + { + // TODO: Move to SnykOptionsManager + Logger.Information("Enter SaveAdditionalOptions method"); + + var solutionPathHash = await this.GetSolutionPathHashAsync(); + + SnykSolutionSettings projectSettings; + + if (snykSettings.SolutionSettingsDict.ContainsKey(solutionPathHash)) + { + projectSettings = snykSettings.SolutionSettingsDict[solutionPathHash]; + } + else + { + projectSettings = new SnykSolutionSettings(); + } + + projectSettings.AdditionalOptions = additionalOptions; + + snykSettings.SolutionSettingsDict[solutionPathHash] = projectSettings; + + this.SaveSettingsToFile(); + + Logger.Information("Leave SaveAdditionalOptions method"); + } + + /// + /// Sace is all projects scan enabled. + /// + /// Bool param. + /// A representing the asynchronous operation. + public async Task SaveIsAllProjectsScanEnabledAsync(bool isAllProjectsEnabled) + { + // TODO: Move to SnykOptionsManager + Logger.Information("Enter SaveIsAllProjectsScan method"); + + var solutionPathHash = await this.GetSolutionPathHashAsync(); + + SnykSolutionSettings projectSettings; + + if (snykSettings.SolutionSettingsDict.ContainsKey(solutionPathHash)) + { + projectSettings = snykSettings.SolutionSettingsDict[solutionPathHash]; + } + else + { + projectSettings = new SnykSolutionSettings(); + } + + projectSettings.IsAllProjectsScanEnabled = isAllProjectsEnabled; + + snykSettings.SolutionSettingsDict[solutionPathHash] = projectSettings; + + this.SaveSettingsToFile(); + + Logger.Information("Leave SaveIsAllProjectsScan method"); + } + + private async Task GetSolutionPathHashAsync() => + (await this.serviceProvider.SolutionService.GetSolutionFolderAsync()).ToLower().GetHashCode(); } } diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykSolutionOptionsUserControl.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykSolutionOptionsUserControl.cs index 2d6ba8a0..0d88cd49 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykSolutionOptionsUserControl.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykSolutionOptionsUserControl.cs @@ -15,8 +15,6 @@ public partial class SnykSolutionOptionsUserControl : UserControl private ISnykServiceProvider serviceProvider; - private IUserStorageSettingsService userStorageSettingsService; - /// /// Initializes a new instance of the class. /// @@ -26,7 +24,6 @@ public SnykSolutionOptionsUserControl(ISnykServiceProvider serviceProvider) this.InitializeComponent(); this.serviceProvider = serviceProvider; - this.userStorageSettingsService = serviceProvider.UserStorageSettingsService; } private void CheckOptionConflicts() @@ -49,7 +46,7 @@ private void AdditionalOptionsTextBox_TextChanged(object sender, EventArgs e) { string additionalOptions = this.additionalOptionsTextBox.Text; - this.userStorageSettingsService.SaveAdditionalOptionsAsync(additionalOptions).FireAndForget(); + this.serviceProvider.SnykOptionsManager.SaveAdditionalOptionsAsync(additionalOptions).FireAndForget(); this.CheckOptionConflicts(); } @@ -59,7 +56,7 @@ private void AllProjectsCheckBox_CheckedChanged(object sender, EventArgs e) { if (this.serviceProvider.SolutionService.IsSolutionOpen()) { - this.userStorageSettingsService.SaveIsAllProjectsScanEnabledAsync(this.allProjectsCheckBox.Checked).FireAndForget(); + this.serviceProvider.SnykOptionsManager.SaveIsAllProjectsScanEnabledAsync(this.allProjectsCheckBox.Checked).FireAndForget(); this.CheckOptionConflicts(); } @@ -81,7 +78,7 @@ private void SnykProjectOptionsUserControl_Load(object sender, EventArgs eventAr try { - string additionalOptions = await this.userStorageSettingsService.GetAdditionalOptionsAsync(); + string additionalOptions = await this.serviceProvider.SnykOptionsManager.GetAdditionalOptionsAsync(); if (!string.IsNullOrEmpty(additionalOptions)) { @@ -101,7 +98,7 @@ private void SnykProjectOptionsUserControl_Load(object sender, EventArgs eventAr try { - bool isChecked = await this.userStorageSettingsService.GetIsAllProjectsEnabledAsync(); + bool isChecked = await this.serviceProvider.SnykOptionsManager.GetIsAllProjectsEnabledAsync(); this.allProjectsCheckBox.Checked = isChecked; } @@ -111,7 +108,7 @@ private void SnykProjectOptionsUserControl_Load(object sender, EventArgs eventAr this.allProjectsCheckBox.Checked = false; - await this.userStorageSettingsService.SaveIsAllProjectsScanEnabledAsync(false); + await this.serviceProvider.SnykOptionsManager.SaveIsAllProjectsScanEnabledAsync(false); } this.CheckOptionConflicts(); diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykUserStorageSettingsService.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykUserStorageSettingsService.cs deleted file mode 100644 index b084d854..00000000 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykUserStorageSettingsService.cs +++ /dev/null @@ -1,300 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; -using Serilog; -using Snyk.VisualStudio.Extension.Authentication; -using Snyk.VisualStudio.Extension.Language; -using Snyk.VisualStudio.Extension.Service; - -namespace Snyk.VisualStudio.Extension.Settings -{ - /// - /// Service for solution settings. - /// - public class SnykUserStorageSettingsService : IUserStorageSettingsService - { - private static readonly ILogger Logger = LogManager.ForContext(); - - private readonly ISolutionService solutionService; - - private readonly SnykSettingsLoader settingsLoader; - - private SnykSettings snykSettings; - - /// - /// Initializes a new instance of the class. - /// - /// File path to settings file. - /// Snyk service provider. - public SnykUserStorageSettingsService(string settingsPath, ISnykServiceProvider serviceProvider) - { - this.solutionService = serviceProvider.SolutionService; - - this.settingsLoader = new SnykSettingsLoader(settingsPath); - LoadSettings(); - } - - private void LoadSettings() - { - this.snykSettings = this.settingsLoader.Load(); - - if (this.snykSettings == null) - { - this.snykSettings = new SnykSettings(); - SaveSettings(); - } - } - - public void SaveSettings() - { - this.settingsLoader.Save(snykSettings); - } - - public bool BinariesAutoUpdate - { - get => snykSettings.BinariesAutoUpdateEnabled; - set => snykSettings.BinariesAutoUpdateEnabled = value; - } - - public string CliCustomPath - { - get => snykSettings.CustomCliPath; - set => snykSettings.CustomCliPath = value; - } - - public AuthenticationType AuthenticationMethod - { - get => snykSettings.AuthenticationMethod; - set => snykSettings.AuthenticationMethod = value; - } - - /// - /// Gets or sets trusted folders list. - /// - public ISet TrustedFolders - { - get => snykSettings.TrustedFolders; - set => snykSettings.TrustedFolders = value; - } - - /// - /// Get Auto Scan option - /// - /// bool. - public bool AutoScan - { - get => snykSettings.AutoScan; - set => snykSettings.AutoScan = value; - } - - /// - /// Get Or Set Auth Token - /// - /// string. - public string Token - { - get => snykSettings.Token; - set => snykSettings.Token = value; - } - - public string CliReleaseChannel - { - get => snykSettings.CliReleaseChannel; - set => snykSettings.CliReleaseChannel = value; - } - - public string CliDownloadUrl - { - get => snykSettings.CliDownloadUrl; - set => snykSettings.CliDownloadUrl = value; - } - - public bool IgnoreUnknownCa - { - get => snykSettings.IgnoreUnknownCa; - set => snykSettings.IgnoreUnknownCa = value; - } - - public string Organization - { - get => snykSettings.Organization; - set => snykSettings.Organization = value; - } - - public string CustomEndpoint - { - get => snykSettings.CustomEndpoint; - set => snykSettings.CustomEndpoint = value; - } - - public bool SnykCodeSecurityEnabled - { - get => snykSettings.SnykCodeSecurityEnabled; - set => snykSettings.SnykCodeSecurityEnabled = value; - } - - public bool SnykCodeQualityEnabled - { - get => snykSettings.SnykCodeQualityEnabled; - set => snykSettings.SnykCodeQualityEnabled = value; - } - - public bool OssEnabled - { - get => snykSettings.OssEnabled; - set => snykSettings.OssEnabled = value; - } - - public bool IacEnabled - { - get => snykSettings.IacEnabled; - set => snykSettings.IacEnabled = value; - } - - public string CurrentCliVersion - { - get => snykSettings.CurrentCliVersion; - set => snykSettings.CurrentCliVersion = value; - } - - public string DeviceId - { - get => snykSettings.DeviceId; - set => snykSettings.DeviceId = value; - } - - public bool AnalyticsPluginInstalledSent - { - get => snykSettings.AnalyticsPluginInstalledSent; - set => snykSettings.AnalyticsPluginInstalledSent = value; - } - - public bool OpenIssuesEnabled - { - get => snykSettings.OpenIssuesEnabled; - set => snykSettings.OpenIssuesEnabled = value; - } - - public bool IgnoredIssuesEnabled - { - get => snykSettings.IgnoredIssuesEnabled; - set => snykSettings.IgnoredIssuesEnabled = value; - } - - public List FolderConfigs - { - get => snykSettings.FolderConfigs; - set => snykSettings.FolderConfigs = value; - } - - public bool EnableDeltaFindings - { - get => snykSettings.EnableDeltaFindings; - set => snykSettings.EnableDeltaFindings = value; - } - - /// - /// Get is all projects enabled. - /// - /// Bool. - public async Task GetIsAllProjectsEnabledAsync() - { - Logger.Information("Enter GetIsAllProjectsEnabled method"); - - var solutionPathHash = await this.GetSolutionPathHashAsync(); - - if (snykSettings == null || !snykSettings.SolutionSettingsDict.ContainsKey(solutionPathHash)) - { - return true; - } - else - { - return snykSettings.SolutionSettingsDict[solutionPathHash].IsAllProjectsScanEnabled; - } - } - - /// - /// Get CLI additional options string. - /// - /// string. - public async Task GetAdditionalOptionsAsync() - { - Logger.Information("Enter GetAdditionalOptions method"); - - var solutionPathHash = await this.GetSolutionPathHashAsync(); - - if (snykSettings == null || !snykSettings.SolutionSettingsDict.ContainsKey(solutionPathHash)) - { - return string.Empty; - } - - return snykSettings.SolutionSettingsDict[solutionPathHash].AdditionalOptions; - } - - /// - /// Save additional options string. - /// - /// CLI options string. - /// A representing the asynchronous operation. - public async Task SaveAdditionalOptionsAsync(string additionalOptions) - { - // TODO: Move to SnykOptionsManager - Logger.Information("Enter SaveAdditionalOptions method"); - - var solutionPathHash = await this.GetSolutionPathHashAsync(); - - SnykSolutionSettings projectSettings; - - if (snykSettings.SolutionSettingsDict.ContainsKey(solutionPathHash)) - { - projectSettings = snykSettings.SolutionSettingsDict[solutionPathHash]; - } - else - { - projectSettings = new SnykSolutionSettings(); - } - - projectSettings.AdditionalOptions = additionalOptions; - - snykSettings.SolutionSettingsDict[solutionPathHash] = projectSettings; - - this.SaveSettings(); - - Logger.Information("Leave SaveAdditionalOptions method"); - } - - /// - /// Sace is all projects scan enabled. - /// - /// Bool param. - /// A representing the asynchronous operation. - public async Task SaveIsAllProjectsScanEnabledAsync(bool isAllProjectsEnabled) - { - // TODO: Move to SnykOptionsManager - Logger.Information("Enter SaveIsAllProjectsScan method"); - - var solutionPathHash = await this.GetSolutionPathHashAsync(); - - SnykSolutionSettings projectSettings; - - if (snykSettings.SolutionSettingsDict.ContainsKey(solutionPathHash)) - { - projectSettings = snykSettings.SolutionSettingsDict[solutionPathHash]; - } - else - { - projectSettings = new SnykSolutionSettings(); - } - - projectSettings.IsAllProjectsScanEnabled = isAllProjectsEnabled; - - snykSettings.SolutionSettingsDict[solutionPathHash] = projectSettings; - - this.SaveSettings(); - - Logger.Information("Leave SaveIsAllProjectsScan method"); - } - - private async Task GetSolutionPathHashAsync() => - (await this.solutionService.GetSolutionFolderAsync()).ToLower().GetHashCode(); - } -} \ No newline at end of file diff --git a/Snyk.VisualStudio.Extension.2022/Snyk.VisualStudio.Extension.2022.csproj b/Snyk.VisualStudio.Extension.2022/Snyk.VisualStudio.Extension.2022.csproj index 50e6cb3b..b82fa275 100644 --- a/Snyk.VisualStudio.Extension.2022/Snyk.VisualStudio.Extension.2022.csproj +++ b/Snyk.VisualStudio.Extension.2022/Snyk.VisualStudio.Extension.2022.csproj @@ -151,7 +151,6 @@ - Component @@ -194,7 +193,6 @@ SnykSolutionOptionsUserControl.cs - SnykIcons.resx diff --git a/Snyk.VisualStudio.Extension.2022/SnykVSPackage.cs b/Snyk.VisualStudio.Extension.2022/SnykVSPackage.cs index 2c9b690f..9fb5b1ec 100644 --- a/Snyk.VisualStudio.Extension.2022/SnykVSPackage.cs +++ b/Snyk.VisualStudio.Extension.2022/SnykVSPackage.cs @@ -54,7 +54,7 @@ namespace Snyk.VisualStudio.Extension [ProvideOptionPage(typeof(SnykSolutionOptionsDialogPage), "Snyk", "Solution settings", 1000, 1002, true)] [ProvideOptionPage(typeof(SnykCliOptionsDialogPage), "Snyk", "CLI settings", 1000, 1003, true)] [ProvideOptionPage(typeof(SnykScanOptionsDialogPage), "Snyk", "Scan settings", 1000, 1004, true)] - public sealed class SnykVSPackage : AsyncPackage, ISnykOptionsProvider + public sealed class SnykVSPackage : AsyncPackage { /// /// SnykVSPackage GUID string. @@ -103,7 +103,6 @@ public void SetServiceProvider(ISnykServiceProvider serviceProvider) /// Gets the Options /// public ISnykOptions Options { get; private set; } - public ISnykOptionsManager SnykOptionsManager { get; private set; } public ISnykGeneralOptionsDialogPage SnykGeneralOptionsDialogPage { get; private set; } public ISnykCliOptionsDialogPage SnykCliOptionsDialogPage { get; private set; } public ISnykScanOptionsDialogPage SnykScanOptionsDialogPage { get; private set; } @@ -311,14 +310,9 @@ private async Task InitializeOptionsAsync() { await JoinableTaskFactory.SwitchToMainThreadAsync(); - if (SnykOptionsManager == null) - { - SnykOptionsManager = new SnykOptionsManager(this.serviceProvider); - } - if (Options == null) { - Options = (ISnykOptions)SnykOptionsManager.Load(); + Options = (ISnykOptions)serviceProvider.SnykOptionsManager.Load(); var readableVsVersion = await this.GetReadableVsVersionAsync(); var vsMajorMinorVersion = await this.GetVsMajorMinorVersionAsync(); Options.Application = readableVsVersion; @@ -407,10 +401,4 @@ private async Task GetReadableVsVersionAsync() } } } - - // Interface to enable testing with mocks - public interface ISnykOptionsProvider - { - ISnykOptions Options { get; } - } } \ No newline at end of file diff --git a/Snyk.VisualStudio.Extension.Tests/Language/LsSettingsTest.cs b/Snyk.VisualStudio.Extension.Tests/Language/LsSettingsTest.cs index d9440a57..6397d7f3 100644 --- a/Snyk.VisualStudio.Extension.Tests/Language/LsSettingsTest.cs +++ b/Snyk.VisualStudio.Extension.Tests/Language/LsSettingsTest.cs @@ -12,13 +12,16 @@ public class LsSettingsTest { private LsSettings cut; private readonly Mock optionsMock; + private readonly Mock optionsManagerMock; public LsSettingsTest(GlobalServiceProvider sp) { sp.Reset(); optionsMock = new Mock(); + optionsManagerMock = new Mock(); var serviceProviderMock = new Mock(); serviceProviderMock.Setup(x => x.Options).Returns(optionsMock.Object); + serviceProviderMock.Setup(x => x.SnykOptionsManager).Returns(optionsManagerMock.Object); cut = new LsSettings(serviceProviderMock.Object); } @@ -27,6 +30,7 @@ public void GetInitializationOptions_ShouldReturnValidOptions_WhenServiceProvide { // Arrange TestUtils.SetupOptionsMock(optionsMock); + TestUtils.SetupOptionsManagerMock(optionsManagerMock); // Act var initOptions = cut.GetInitializationOptions(); diff --git a/Snyk.VisualStudio.Extension.Tests/Language/SnykLanguageClientCustomTargetTests.cs b/Snyk.VisualStudio.Extension.Tests/Language/SnykLanguageClientCustomTargetTests.cs index 9d68a4e6..fe971a5b 100644 --- a/Snyk.VisualStudio.Extension.Tests/Language/SnykLanguageClientCustomTargetTests.cs +++ b/Snyk.VisualStudio.Extension.Tests/Language/SnykLanguageClientCustomTargetTests.cs @@ -17,7 +17,7 @@ public class SnykLanguageClientCustomTargetTests : PackageBaseTest { private readonly Mock tasksServiceMock; private readonly Mock optionsMock; - private readonly Mock userStorageSettingsServiceMock; + private readonly Mock snykOptionsManagerMock; private readonly Mock languageClientManagerMock; private readonly Mock generalSettingsPageMock; private readonly SnykLanguageClientCustomTarget cut; @@ -28,7 +28,7 @@ public SnykLanguageClientCustomTargetTests(GlobalServiceProvider gsp) : base(gsp tasksServiceMock = new Mock(); optionsMock = new Mock(); generalSettingsPageMock = new Mock(); - userStorageSettingsServiceMock = new Mock(); + snykOptionsManagerMock = new Mock(); languageClientManagerMock = new Mock(); var featureFlagServiceMock = new Mock(); @@ -39,7 +39,7 @@ public SnykLanguageClientCustomTargetTests(GlobalServiceProvider gsp) : base(gsp serviceProviderMock.SetupGet(sp => sp.TasksService).Returns(tasksServiceMock.Object); serviceProviderMock.SetupGet(sp => sp.Options).Returns(optionsMock.Object); serviceProviderMock.SetupGet(sp => sp.GeneralOptionsDialogPage).Returns(generalSettingsPageMock.Object); - serviceProviderMock.SetupGet(sp => sp.UserStorageSettingsService).Returns(userStorageSettingsServiceMock.Object); + serviceProviderMock.SetupGet(sp => sp.SnykOptionsManager).Returns(snykOptionsManagerMock.Object); serviceProviderMock.SetupGet(sp => sp.FeatureFlagService).Returns(featureFlagServiceMock.Object); serviceProviderMock.SetupGet(sp => sp.LanguageClientManager).Returns(languageClientManagerMock.Object); @@ -156,7 +156,7 @@ public async Task OnAddTrustedFolders_ShouldUpdateTrustedFolders() Assert.Equal(2, optionsMock.Object.TrustedFolders.Count); Assert.Contains("/folder1", optionsMock.Object.TrustedFolders); Assert.Contains("/folder2", optionsMock.Object.TrustedFolders); - userStorageSettingsServiceMock.Verify(s => s.SaveSettings(), Times.Once); + snykOptionsManagerMock.Verify(s => s.Save(It.IsAny()), Times.Once); languageClientManagerMock.Verify(s => s.DidChangeConfigurationAsync(It.IsAny()), Times.Once); } diff --git a/Snyk.VisualStudio.Extension.Tests/Language/SnykLanguageClientTest.cs b/Snyk.VisualStudio.Extension.Tests/Language/SnykLanguageClientTest.cs index 65cc28d5..5c448217 100644 --- a/Snyk.VisualStudio.Extension.Tests/Language/SnykLanguageClientTest.cs +++ b/Snyk.VisualStudio.Extension.Tests/Language/SnykLanguageClientTest.cs @@ -69,6 +69,7 @@ public async Task DidChangeConfigurationAsync_ShouldInvoke() // Arrange cut.IsReady = true; TestUtils.SetupOptionsMock(OptionsMock); + TestUtils.SetupOptionsManagerMock(OptionsManagerMock); // Act var result = await cut.DidChangeConfigurationAsync(CancellationToken.None); diff --git a/Snyk.VisualStudio.Extension.Tests/PackageBaseTest.cs b/Snyk.VisualStudio.Extension.Tests/PackageBaseTest.cs index 872c809d..75d0e3b5 100644 --- a/Snyk.VisualStudio.Extension.Tests/PackageBaseTest.cs +++ b/Snyk.VisualStudio.Extension.Tests/PackageBaseTest.cs @@ -13,6 +13,7 @@ public class PackageBaseTest { protected SnykVSPackage VsPackage; protected readonly Mock OptionsMock; + protected readonly Mock OptionsManagerMock; protected readonly Mock ServiceProviderMock; protected readonly Mock TasksServiceMock; @@ -20,13 +21,16 @@ public PackageBaseTest(GlobalServiceProvider sp) { sp.Reset(); OptionsMock = new Mock(); + OptionsManagerMock = new Mock(); ServiceProviderMock = new Mock(); TasksServiceMock = new Mock(); var loggerMock = new Mock(); Log.Logger = loggerMock.Object; - + + ServiceProviderMock.Setup(x => x.SnykOptionsManager).Returns(OptionsManagerMock.Object); ServiceProviderMock.Setup(x => x.Options).Returns(OptionsMock.Object); ServiceProviderMock.Setup(x => x.TasksService).Returns(TasksServiceMock.Object); + sp.AddService(typeof(ISnykService), ServiceProviderMock.Object); VsPackage = new SnykVSPackage(); diff --git a/Snyk.VisualStudio.Extension.Tests/Service/WorkspaceTrustServiceTest.cs b/Snyk.VisualStudio.Extension.Tests/Service/WorkspaceTrustServiceTest.cs index 1b7d9e00..58c43695 100644 --- a/Snyk.VisualStudio.Extension.Tests/Service/WorkspaceTrustServiceTest.cs +++ b/Snyk.VisualStudio.Extension.Tests/Service/WorkspaceTrustServiceTest.cs @@ -10,17 +10,25 @@ namespace Snyk.VisualStudio.Extension.Tests.Service { public class WorkspaceTrustServiceTest { + private readonly Mock optionsMock; + private readonly Mock serviceProviderMock; + private readonly WorkspaceTrustService cut; + + public WorkspaceTrustServiceTest() + { + optionsMock = new Mock(); + + serviceProviderMock = new Mock(); + serviceProviderMock.Setup(x => x.Options).Returns(optionsMock.Object); + + cut = new WorkspaceTrustService(serviceProviderMock.Object); + } + [Fact] public void WorkspaceTrustServiceTest_IsFolderTrusted_NotTrusted() { - var trustedFolders = new HashSet(); - var settingsServiceMock = new Mock(); - settingsServiceMock.Setup(s => s.TrustedFolders).Returns(trustedFolders); - - var service = new WorkspaceTrustService(settingsServiceMock.Object); var folderPath = "C:\\Users\\Project"; - - Assert.False(service.IsFolderTrusted(folderPath)); + Assert.False(cut.IsFolderTrusted(folderPath)); } [Fact] @@ -28,28 +36,23 @@ public void WorkspaceTrustServiceTest_IsFolderTrusted_Trusted() { var trustedFolders = new HashSet(); trustedFolders.Add("C:\\Users\\Project"); - var settingsServiceMock = new Mock(); - settingsServiceMock.Setup(s => s.TrustedFolders).Returns(trustedFolders); + optionsMock.Setup(s => s.TrustedFolders).Returns(trustedFolders); - var service = new WorkspaceTrustService(settingsServiceMock.Object); var folderPath = "C:\\Users\\Project"; - Assert.True(service.IsFolderTrusted(folderPath)); + Assert.True(cut.IsFolderTrusted(folderPath)); } [Fact] public void WorkspaceTrustServiceTest_IsFolderTrusted_SubfolderTrusted() { - var trustedFolders = new HashSet(); - trustedFolders.Add("C:\\Users\\Project"); + var trustedFolders = new HashSet { "C:\\Users\\Project" }; - var settingsServiceMock = new Mock(); - settingsServiceMock.Setup(s => s.TrustedFolders).Returns(trustedFolders); + optionsMock.Setup(s => s.TrustedFolders).Returns(trustedFolders); - var service = new WorkspaceTrustService(settingsServiceMock.Object); var folderPath = "C:\\Users\\Project\\subfolder"; - Assert.True(service.IsFolderTrusted(folderPath)); + Assert.True(cut.IsFolderTrusted(folderPath)); } [Fact] @@ -58,84 +61,70 @@ public void WorkspaceTrustServiceTest_IsFolderTrusted_ParentFolderNotTrusted() var trustedFolders = new HashSet(); trustedFolders.Add("C:\\Users\\Project\\subfolder"); - var settingsServiceMock = new Mock(); - settingsServiceMock.Setup(s => s.TrustedFolders).Returns(trustedFolders); + optionsMock.Setup(s => s.TrustedFolders).Returns(trustedFolders); - var service = new WorkspaceTrustService(settingsServiceMock.Object); var folderPath = "C:\\Users\\Project"; - Assert.False(service.IsFolderTrusted(folderPath)); + Assert.False(cut.IsFolderTrusted(folderPath)); } [Fact] public void WorkspaceTrustServiceTest_AddFolderToTrusted_NonExistingFolder() { - var settingsServiceMock = new Mock(); - - var service = new WorkspaceTrustService(settingsServiceMock.Object); var folderPath = "C:\\Users\\Project"; - Assert.Throws(() => service.AddFolderToTrusted(folderPath)); + Assert.Throws(() => cut.AddFolderToTrusted(folderPath)); } [Fact] public void WorkspaceTrustServiceTest_AddFolderToTrusted_RelativeFolder() { - var settingsServiceMock = new Mock(); - - var service = new WorkspaceTrustService(settingsServiceMock.Object); var folderPath = "\\Users\\Project"; - Assert.Throws(() => service.AddFolderToTrusted(folderPath)); + Assert.Throws(() => cut.AddFolderToTrusted(folderPath)); } [Fact] public void WorkspaceTrustServiceTest_AddFolderToTrusted_ExistingFolder() { - var settingsServiceMock = new Mock(); - settingsServiceMock.Setup(s => s.TrustedFolders).Returns(new HashSet()); + optionsMock.Setup(s => s.TrustedFolders).Returns(new HashSet()); - var service = new WorkspaceTrustService(settingsServiceMock.Object); var folderPath = Path.GetDirectoryName(Path.GetTempFileName()); - service.AddFolderToTrusted(folderPath); + cut.AddFolderToTrusted(folderPath); - settingsServiceMock.VerifySet(s => s.TrustedFolders = new HashSet { folderPath }, Times.Once); + optionsMock.VerifySet(s => s.TrustedFolders = new HashSet { folderPath }, Times.Once); } [Fact] public void WorkspaceTrustServiceTest_AddFolderToTrusted_MultipleFolders() { - var settingsServiceMock = new Mock(); var presentFolder = "C:\\Users\\Project"; - settingsServiceMock.Setup(s => s.TrustedFolders).Returns(new HashSet { presentFolder }); + optionsMock.Setup(s => s.TrustedFolders).Returns(new HashSet { presentFolder }); - var service = new WorkspaceTrustService(settingsServiceMock.Object); var newFolderPath = this.CreateTempDirectory(); - service.AddFolderToTrusted(newFolderPath); + cut.AddFolderToTrusted(newFolderPath); - settingsServiceMock.VerifySet(s => s.TrustedFolders = new HashSet { presentFolder, newFolderPath }); + optionsMock.VerifySet(s => s.TrustedFolders = new HashSet { presentFolder, newFolderPath }); } [Fact] public void WorkspaceTrustServiceTest_AddFolderToTrusted_SameFolderTwice() { - var settingsServiceMock = new Mock(); - settingsServiceMock.Setup(s => s.TrustedFolders).Returns(new HashSet()); - var service = new WorkspaceTrustService(settingsServiceMock.Object); + optionsMock.Setup(s => s.TrustedFolders).Returns(new HashSet()); var folderPath1 = this.CreateTempDirectory(); var folderPath2 = folderPath1; - service.AddFolderToTrusted(folderPath1); - settingsServiceMock.VerifySet(s => s.TrustedFolders = new HashSet { folderPath1 }, Times.Once); + cut.AddFolderToTrusted(folderPath1); + optionsMock.VerifySet(s => s.TrustedFolders = new HashSet { folderPath1 }, Times.Once); - service.AddFolderToTrusted(folderPath2); + cut.AddFolderToTrusted(folderPath2); // Must not append new entry to collection - settingsServiceMock.VerifySet(s => s.TrustedFolders = new HashSet { folderPath1 }, Times.Exactly(2)); + optionsMock.VerifySet(s => s.TrustedFolders = new HashSet { folderPath1 }, Times.Exactly(2)); } private string CreateTempDirectory() diff --git a/Snyk.VisualStudio.Extension.Tests/SnykOptionsTest.cs b/Snyk.VisualStudio.Extension.Tests/SnykOptionsTest.cs index 3be1196e..b2c72417 100644 --- a/Snyk.VisualStudio.Extension.Tests/SnykOptionsTest.cs +++ b/Snyk.VisualStudio.Extension.Tests/SnykOptionsTest.cs @@ -19,7 +19,7 @@ public SnykOptionsTest(GlobalServiceProvider sp) serviceProviderMock.Setup(x => x.SolutionService).Returns(snykSolutionService); var serviceProvider = serviceProviderMock.Object; var settingsFilePath = Path.Combine(SnykExtension.GetExtensionDirectoryPath(), "settings.json"); - serviceProviderMock.Setup(x => x.UserStorageSettingsService).Returns(new SnykUserStorageSettingsService(settingsFilePath, serviceProvider)); + serviceProviderMock.Setup(x => x.SnykOptionsManager).Returns(new SnykOptionsManager(settingsFilePath, serviceProvider)); cut = new SnykOptions(); } diff --git a/Snyk.VisualStudio.Extension.Tests/SnykUserStorageSettingsServiceTest.cs b/Snyk.VisualStudio.Extension.Tests/SnykUserStorageSettingsServiceTest.cs index 6d798089..e7ceb347 100644 --- a/Snyk.VisualStudio.Extension.Tests/SnykUserStorageSettingsServiceTest.cs +++ b/Snyk.VisualStudio.Extension.Tests/SnykUserStorageSettingsServiceTest.cs @@ -8,12 +8,12 @@ namespace Snyk.VisualStudio.Extension.Tests { /// - /// Test case for . + /// Test case for . /// - public class SnykUserStorageSettingsServiceTest + public class SnykOptionsManagerTest { [Fact] - public async Task SnykUserStorageSettingsService_ProjectNameNotExists_SaveAdditionalOptionsSuccessfullAsync() + public async Task ProjectNameNotExists_SaveAdditionalOptionsSuccessfullAsync() { var serviceProviderMock = new Mock(); var solutionServiceMock = new Mock(); @@ -28,7 +28,7 @@ public async Task SnykUserStorageSettingsService_ProjectNameNotExists_SaveAdditi string settingsFilePath = Path.GetTempFileName(); - var userStorageSettingsService = new SnykUserStorageSettingsService(settingsFilePath, serviceProviderMock.Object); + var userStorageSettingsService = new SnykOptionsManager(settingsFilePath, serviceProviderMock.Object); await userStorageSettingsService.SaveAdditionalOptionsAsync("--test-command"); diff --git a/Snyk.VisualStudio.Extension.Tests/TestUtils.cs b/Snyk.VisualStudio.Extension.Tests/TestUtils.cs index bd2db8e4..37e2b502 100644 --- a/Snyk.VisualStudio.Extension.Tests/TestUtils.cs +++ b/Snyk.VisualStudio.Extension.Tests/TestUtils.cs @@ -2,12 +2,18 @@ using Moq; using Snyk.VisualStudio.Extension.Authentication; using Snyk.VisualStudio.Extension.Language; +using Snyk.VisualStudio.Extension.Service; using Snyk.VisualStudio.Extension.Settings; namespace Snyk.VisualStudio.Extension.Tests { public class TestUtils { + public static void SetupOptionsManagerMock(Mock snykOptionsManager) + { + snykOptionsManager.Setup(o => o.GetAdditionalOptionsAsync()).ReturnsAsync("--debug"); + } + public static void SetupOptionsMock(Mock optionsMock) { optionsMock.SetupGet(o => o.SnykCodeSecurityEnabled).Returns(true); @@ -29,7 +35,6 @@ public static void SetupOptionsMock(Mock optionsMock) optionsMock.SetupGet(o => o.IgnoreUnknownCA).Returns(false); optionsMock.SetupGet(o => o.EnableDeltaFindings).Returns(true); optionsMock.SetupGet(o => o.FolderConfigs).Returns(new List()); - optionsMock.Setup(o => o.GetAdditionalOptionsAsync()).ReturnsAsync("--debug"); optionsMock.SetupProperty(o => o.DeviceId, "device-id-123"); } } From 025d223bcb14f50bedca10b564f7d64fc804d9aa Mon Sep 17 00:00:00 2001 From: Abdelrahman Shawki Hassan Date: Thu, 19 Dec 2024 07:05:46 +0100 Subject: [PATCH 09/16] feat: options manager tests --- .../Service/WorkspaceTrustServiceTest.cs | 2 +- .../SnykUserStorageSettingsServiceTest.cs | 125 ++++++++++++++++-- 2 files changed, 117 insertions(+), 10 deletions(-) diff --git a/Snyk.VisualStudio.Extension.Tests/Service/WorkspaceTrustServiceTest.cs b/Snyk.VisualStudio.Extension.Tests/Service/WorkspaceTrustServiceTest.cs index 58c43695..82e70c31 100644 --- a/Snyk.VisualStudio.Extension.Tests/Service/WorkspaceTrustServiceTest.cs +++ b/Snyk.VisualStudio.Extension.Tests/Service/WorkspaceTrustServiceTest.cs @@ -17,7 +17,7 @@ public class WorkspaceTrustServiceTest public WorkspaceTrustServiceTest() { optionsMock = new Mock(); - + optionsMock.Setup(x => x.TrustedFolders).Returns(new HashSet()); serviceProviderMock = new Mock(); serviceProviderMock.Setup(x => x.Options).Returns(optionsMock.Object); diff --git a/Snyk.VisualStudio.Extension.Tests/SnykUserStorageSettingsServiceTest.cs b/Snyk.VisualStudio.Extension.Tests/SnykUserStorageSettingsServiceTest.cs index e7ceb347..af289bde 100644 --- a/Snyk.VisualStudio.Extension.Tests/SnykUserStorageSettingsServiceTest.cs +++ b/Snyk.VisualStudio.Extension.Tests/SnykUserStorageSettingsServiceTest.cs @@ -1,6 +1,7 @@ using System.IO; using System.Threading.Tasks; using Moq; +using Snyk.VisualStudio.Extension.Authentication; using Snyk.VisualStudio.Extension.Service; using Snyk.VisualStudio.Extension.Settings; using Xunit; @@ -12,27 +13,133 @@ namespace Snyk.VisualStudio.Extension.Tests /// public class SnykOptionsManagerTest { - [Fact] - public async Task ProjectNameNotExists_SaveAdditionalOptionsSuccessfullAsync() - { - var serviceProviderMock = new Mock(); - var solutionServiceMock = new Mock(); + private SnykOptionsManager cut; + private readonly string settingsFilePath; + private readonly Mock serviceProviderMock; + private readonly Mock solutionServiceMock; + public SnykOptionsManagerTest() + { + this.settingsFilePath = Path.GetTempFileName(); + this.serviceProviderMock = new Mock(); + this.solutionServiceMock = new Mock(); + cut = new SnykOptionsManager(settingsFilePath, serviceProviderMock.Object); serviceProviderMock .Setup(serviceProvider => serviceProvider.SolutionService) .Returns(solutionServiceMock.Object); + } + [Fact] + public async Task ProjectNameNotExists_SaveAdditionalOptionsSuccessfullAsync() + { solutionServiceMock .Setup(solutionService => solutionService.GetSolutionFolderAsync()) .ReturnsAsync("C:\\Projects\\TestProj"); - string settingsFilePath = Path.GetTempFileName(); - var userStorageSettingsService = new SnykOptionsManager(settingsFilePath, serviceProviderMock.Object); + await cut.SaveAdditionalOptionsAsync("--test-command"); + + Assert.Equal("--test-command", await cut.GetAdditionalOptionsAsync()); + } - await userStorageSettingsService.SaveAdditionalOptionsAsync("--test-command"); + [Fact] + public void LoadAndSaveGeneralOptions_PersistsChanges() + { + // Load default + var options = cut.Load() as SnykOptions; + Assert.NotNull(options); + // Set some values + options.AutoScan = true; + options.IgnoreUnknownCA = true; + options.Organization = "my-org"; + options.CustomEndpoint = "https://custom.endpoint"; + options.AuthenticationMethod = AuthenticationType.OAuth; + options.ApiToken = new AuthenticationToken(AuthenticationType.OAuth, "dummy-token"); + options.BinariesAutoUpdate = true; + options.CliCustomPath = "C:\\cli\\snyk.exe"; + options.CliDownloadUrl = "https://cli.download.url"; + options.CliReleaseChannel = "stable"; + options.CurrentCliVersion = "1.2.3"; + options.IacEnabled = true; + options.SnykCodeSecurityEnabled = true; + options.SnykCodeQualityEnabled = true; + options.OssEnabled = true; - Assert.Equal("--test-command", await userStorageSettingsService.GetAdditionalOptionsAsync()); + cut.Save(options); + + // Reload to confirm persistence + var reloadedOptions = cut.Load() as SnykOptions; + Assert.NotNull(reloadedOptions); + + Assert.True(reloadedOptions.AutoScan); + Assert.True(reloadedOptions.IgnoreUnknownCA); + Assert.Equal("my-org", reloadedOptions.Organization); + Assert.Equal("https://custom.endpoint", reloadedOptions.CustomEndpoint); + Assert.Equal(AuthenticationType.OAuth, reloadedOptions.AuthenticationMethod); + Assert.Equal("dummy-token", reloadedOptions.ApiToken.ToString()); + Assert.True(reloadedOptions.BinariesAutoUpdate); + Assert.Equal("C:\\cli\\snyk.exe", reloadedOptions.CliCustomPath); + Assert.Equal("https://cli.download.url", reloadedOptions.CliDownloadUrl); + Assert.Equal("stable", reloadedOptions.CliReleaseChannel); + Assert.Equal("1.2.3", reloadedOptions.CurrentCliVersion); + Assert.True(reloadedOptions.IacEnabled); + Assert.True(reloadedOptions.SnykCodeSecurityEnabled); + Assert.True(reloadedOptions.SnykCodeQualityEnabled); + Assert.True(reloadedOptions.OssEnabled); } + + [Fact] + public async Task GetAdditionalOptions_EmptyIfNoExistingSettings() + { + solutionServiceMock + .Setup(solutionService => solutionService.GetSolutionFolderAsync()) + .ReturnsAsync("C:\\Projects\\NonExistentProj"); + + Assert.Equal(string.Empty, await cut.GetAdditionalOptionsAsync()); + } + + [Fact] + public async Task OverwriteAdditionalOptionsSuccessfully() + { + solutionServiceMock + .Setup(solutionService => solutionService.GetSolutionFolderAsync()) + .ReturnsAsync("C:\\Projects\\NonExistentProj"); + + // Save initial options + await cut.SaveAdditionalOptionsAsync("--first-command"); + Assert.Equal("--first-command", await cut.GetAdditionalOptionsAsync()); + + // Overwrite with new options + await cut.SaveAdditionalOptionsAsync("--second-command"); + Assert.Equal("--second-command", await cut.GetAdditionalOptionsAsync()); + } + + [Fact] + public async Task GetIsAllProjectsEnabledAsync_DefaultTrueIfNotSet() + { + solutionServiceMock + .Setup(solutionService => solutionService.GetSolutionFolderAsync()) + .ReturnsAsync("C:\\Projects\\NonExistentProj"); + Assert.True(await cut.GetIsAllProjectsEnabledAsync()); + } + + [Fact] + public async Task SaveIsAllProjectsScanEnabledAsync_ChangesValue() + { + solutionServiceMock + .Setup(solutionService => solutionService.GetSolutionFolderAsync()) + .ReturnsAsync("C:\\Projects\\NonExistentProj"); + // Default is true + Assert.True(await cut.GetIsAllProjectsEnabledAsync()); + + await cut.SaveIsAllProjectsScanEnabledAsync(false); + Assert.False(await cut.GetIsAllProjectsEnabledAsync()); + + // Change back to true + await cut.SaveIsAllProjectsScanEnabledAsync(true); + Assert.True(await cut.GetIsAllProjectsEnabledAsync()); + } + + } } From edfe1f113f5e04c0ab9de3e13fad698ac02fb5ac Mon Sep 17 00:00:00 2001 From: Abdelrahman Shawki Hassan Date: Thu, 19 Dec 2024 15:30:31 +0100 Subject: [PATCH 10/16] fix: call settingsChanged on save --- .../BranchSelectorDialogWindow.xaml.cs | 1 - .../Language/SnykLanguageClientCustomTarget.cs | 11 ++++------- .../Settings/ISnykOptionsManager.cs | 2 +- .../Settings/SnykCliOptionsDialogPage.cs | 1 - .../Settings/SnykCliOptionsUserControl.cs | 3 +-- .../Settings/SnykGeneralOptionsDialogPage.cs | 3 --- .../Settings/SnykGeneralSettingsUserControl.cs | 11 ----------- .../Settings/SnykOptionsManager.cs | 3 ++- .../Settings/SnykScanOptionsDialogPage.cs | 4 ++-- .../Settings/SnykScanOptionsUserControl.cs | 4 ++-- Snyk.VisualStudio.Extension.2022/SnykVSPackage.cs | 2 +- .../SnykUserStorageSettingsServiceTest.cs | 8 +++----- 12 files changed, 16 insertions(+), 37 deletions(-) diff --git a/Snyk.VisualStudio.Extension.2022/BranchSelectorDialogWindow.xaml.cs b/Snyk.VisualStudio.Extension.2022/BranchSelectorDialogWindow.xaml.cs index 99ef2391..e801508d 100644 --- a/Snyk.VisualStudio.Extension.2022/BranchSelectorDialogWindow.xaml.cs +++ b/Snyk.VisualStudio.Extension.2022/BranchSelectorDialogWindow.xaml.cs @@ -54,7 +54,6 @@ private void OkButton_OnClick(object sender, RoutedEventArgs e) var options = SnykVSPackage.ServiceProvider.Options; options.FolderConfigs = currentList; SnykVSPackage.ServiceProvider.SnykOptionsManager.Save(options); - options.InvokeSettingsChangedEvent(); this.CloseDialog(); } diff --git a/Snyk.VisualStudio.Extension.2022/Language/SnykLanguageClientCustomTarget.cs b/Snyk.VisualStudio.Extension.2022/Language/SnykLanguageClientCustomTarget.cs index aaa33b28..6b58f341 100644 --- a/Snyk.VisualStudio.Extension.2022/Language/SnykLanguageClientCustomTarget.cs +++ b/Snyk.VisualStudio.Extension.2022/Language/SnykLanguageClientCustomTarget.cs @@ -111,7 +111,6 @@ public async Task OnFolderConfig(JToken arg) if (folderConfigs == null) return; serviceProvider.Options.FolderConfigs = folderConfigs.FolderConfigs; serviceProvider.SnykOptionsManager.Save(serviceProvider.Options); - serviceProvider.Options.InvokeSettingsChangedEvent(); } [JsonRpcMethod(LsConstants.SnykHasAuthenticated)] @@ -124,10 +123,6 @@ public async Task OnHasAuthenticated(JToken arg) } var token = arg["token"].ToString(); - if (string.IsNullOrEmpty(token)) - { - return; - } var apiUrl = arg["apiUrl"]?.ToString(); if (!string.IsNullOrEmpty(apiUrl)) @@ -137,11 +132,13 @@ public async Task OnHasAuthenticated(JToken arg) serviceProvider.Options.ApiToken = new AuthenticationToken(serviceProvider.Options.AuthenticationMethod, token); serviceProvider.SnykOptionsManager.Save(serviceProvider.Options); - serviceProvider.Options.InvokeSettingsChangedEvent(); + + if (!serviceProvider.Options.ApiToken.IsValid()) + return; await serviceProvider.GeneralOptionsDialogPage.HandleAuthenticationSuccess(token, apiUrl); + serviceProvider.FeatureFlagService.RefreshAsync(SnykVSPackage.Instance.DisposalToken).FireAndForget(); - if (serviceProvider.Options.AutoScan) { await serviceProvider.TasksService.ScanAsync(); diff --git a/Snyk.VisualStudio.Extension.2022/Settings/ISnykOptionsManager.cs b/Snyk.VisualStudio.Extension.2022/Settings/ISnykOptionsManager.cs index d0d6696b..2b579b6d 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/ISnykOptionsManager.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/ISnykOptionsManager.cs @@ -6,7 +6,7 @@ public interface ISnykOptionsManager { void LoadSettingsFromFile(); void SaveSettingsToFile(); - IPersistableOptions Load(); + ISnykOptions Load(); void Save(IPersistableOptions options); /// diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsDialogPage.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsDialogPage.cs index 4ff932d1..276fe837 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsDialogPage.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsDialogPage.cs @@ -38,7 +38,6 @@ public override void SaveSettingsToStorage() { HandleCliDownload(); this.serviceProvider.SnykOptionsManager.Save(this.snykOptions); - this.snykOptions.InvokeSettingsChangedEvent(); } protected override void OnClosed(EventArgs e) diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsUserControl.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsUserControl.cs index 6ddcc1e2..77c8a185 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsUserControl.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsUserControl.cs @@ -1,7 +1,6 @@ using System.Collections.Generic; using System.Diagnostics; using System.Windows.Forms; -using Microsoft.VisualStudio.Shell; using Snyk.VisualStudio.Extension.CLI; using Snyk.VisualStudio.Extension.Service; @@ -15,7 +14,7 @@ public partial class SnykCliOptionsUserControl : UserControl public SnykCliOptionsUserControl(ISnykServiceProvider serviceProvider) { this.serviceProvider = serviceProvider; - OptionsMemento = (ISnykOptions)serviceProvider.SnykOptionsManager.Load(); + OptionsMemento = serviceProvider.SnykOptionsManager.Load(); InitializeComponent(); this.Initialize(); } diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralOptionsDialogPage.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralOptionsDialogPage.cs index 0a676fcd..7a3ac8d2 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralOptionsDialogPage.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralOptionsDialogPage.cs @@ -87,7 +87,6 @@ public SnykGeneralSettingsUserControl GeneralSettingsUserControl public override void SaveSettingsToStorage() { this.serviceProvider.SnykOptionsManager.Save(this.SnykOptions); - this.SnykOptions.InvokeSettingsChangedEvent(); } private void SnykGeneralOptionsDialogPage_SettingsChanged(object sender, SnykSettingsChangedEventArgs e) @@ -123,8 +122,6 @@ public void Authenticate() ThreadHelper.JoinableTaskFactory.RunAsync(async () => { - await serviceProvider.LanguageClientManager.InvokeLogout(SnykVSPackage.Instance - .DisposalToken); await serviceProvider.LanguageClientManager.InvokeLogin(SnykVSPackage.Instance .DisposalToken); }).FireAndForget(); diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.cs index 91922e83..1e27c0d1 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.cs @@ -143,16 +143,6 @@ public async Task HandleAuthenticationSuccess(string apiToken, string apiUrl) await this.serviceProvider.ToolWindow.UpdateScreenStateAsync(); } - public void InvalidateApiToken() - { - this.tokenTextBox.Text = string.Empty; - if(LanguageClientHelper.IsLanguageServerReady()) - ThreadHelper.JoinableTaskFactory.RunAsync(async () => - { - await serviceProvider.LanguageClientManager.InvokeLogout(SnykVSPackage.Instance.DisposalToken); - }).FireAndForget(); - } - public async Task HandleFailedAuthentication(string errorMessage) { Logger.Information("Enter authenticate errorCallback"); @@ -277,7 +267,6 @@ private void authType_SelectionChangeCommitted(object sender, EventArgs e) { snykOptions.AuthenticationMethod = (AuthenticationType)authType.SelectedValue; serviceProvider.Options.InvokeSettingsChangedEvent(); - InvalidateApiToken(); } private void organizationTextBox_TextChanged(object sender, EventArgs e) diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykOptionsManager.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykOptionsManager.cs index 11447a51..39a3da11 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykOptionsManager.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykOptionsManager.cs @@ -35,7 +35,7 @@ public void SaveSettingsToFile() this.settingsLoader.Save(snykSettings); } - public IPersistableOptions Load() + public ISnykOptions Load() { return new SnykOptions { @@ -101,6 +101,7 @@ public void Save(IPersistableOptions options) snykSettings.OssEnabled = options.OssEnabled; this.SaveSettingsToFile(); + serviceProvider.Options.InvokeSettingsChangedEvent(); } /// diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykScanOptionsDialogPage.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykScanOptionsDialogPage.cs index 9573c0db..66ebac53 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykScanOptionsDialogPage.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykScanOptionsDialogPage.cs @@ -2,6 +2,7 @@ using System.Runtime.InteropServices; using System.Windows.Forms; using Microsoft.VisualStudio.Shell; +using Snyk.VisualStudio.Extension.Language; using Snyk.VisualStudio.Extension.Service; namespace Snyk.VisualStudio.Extension.Settings; @@ -44,12 +45,11 @@ public override void SaveSettingsToStorage() this.snykOptions.SnykCodeSecurityEnabled = SnykCliOptionsUserControl.OptionsMemento.SnykCodeSecurityEnabled; this.snykOptions.IacEnabled = SnykCliOptionsUserControl.OptionsMemento.IacEnabled; this.snykOptions.OssEnabled = SnykCliOptionsUserControl.OptionsMemento.OssEnabled; - if (this.snykOptions.AutoScan) + if (LanguageClientHelper.IsLanguageServerReady() && this.snykOptions.AutoScan) serviceProvider.LanguageClientManager.InvokeWorkspaceScanAsync(SnykVSPackage .Instance.DisposalToken).FireAndForget(); this.serviceProvider.SnykOptionsManager.Save(this.snykOptions); - this.snykOptions.InvokeSettingsChangedEvent(); } protected override void OnClosed(EventArgs e) diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykScanOptionsUserControl.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykScanOptionsUserControl.cs index f312c0bb..2558d018 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykScanOptionsUserControl.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykScanOptionsUserControl.cs @@ -25,7 +25,7 @@ public partial class SnykScanOptionsUserControl : UserControl public SnykScanOptionsUserControl(ISnykServiceProvider serviceProvider) { this.serviceProvider = serviceProvider; - OptionsMemento = (ISnykOptions)serviceProvider.SnykOptionsManager.Load(); + OptionsMemento = serviceProvider.SnykOptionsManager.Load(); serviceProvider.Options.SettingsChanged += OptionsOnSettingsChanged; InitializeComponent(); Initialize(); @@ -81,7 +81,7 @@ private void StartSastEnablementCheckLoop() { try { - if (!LanguageClientHelper.IsLanguageServerReady()) return; + if (!LanguageClientHelper.IsLanguageServerReady() || !serviceProvider.Options.ApiToken.IsValid()) return; var sastSettings = await this.serviceProvider.LanguageClientManager.InvokeGetSastEnabled(SnykVSPackage.Instance.DisposalToken); bool snykCodeEnabled = sastSettings != null ? sastSettings.SnykCodeEnabled : false; diff --git a/Snyk.VisualStudio.Extension.2022/SnykVSPackage.cs b/Snyk.VisualStudio.Extension.2022/SnykVSPackage.cs index 9fb5b1ec..890fee0f 100644 --- a/Snyk.VisualStudio.Extension.2022/SnykVSPackage.cs +++ b/Snyk.VisualStudio.Extension.2022/SnykVSPackage.cs @@ -312,7 +312,7 @@ private async Task InitializeOptionsAsync() if (Options == null) { - Options = (ISnykOptions)serviceProvider.SnykOptionsManager.Load(); + Options = serviceProvider.SnykOptionsManager.Load(); var readableVsVersion = await this.GetReadableVsVersionAsync(); var vsMajorMinorVersion = await this.GetVsMajorMinorVersionAsync(); Options.Application = readableVsVersion; diff --git a/Snyk.VisualStudio.Extension.Tests/SnykUserStorageSettingsServiceTest.cs b/Snyk.VisualStudio.Extension.Tests/SnykUserStorageSettingsServiceTest.cs index af289bde..b4e0050d 100644 --- a/Snyk.VisualStudio.Extension.Tests/SnykUserStorageSettingsServiceTest.cs +++ b/Snyk.VisualStudio.Extension.Tests/SnykUserStorageSettingsServiceTest.cs @@ -46,8 +46,7 @@ public async Task ProjectNameNotExists_SaveAdditionalOptionsSuccessfullAsync() public void LoadAndSaveGeneralOptions_PersistsChanges() { // Load default - var options = cut.Load() as SnykOptions; - Assert.NotNull(options); + var options = cut.Load(); // Set some values options.AutoScan = true; options.IgnoreUnknownCA = true; @@ -68,9 +67,8 @@ public void LoadAndSaveGeneralOptions_PersistsChanges() cut.Save(options); // Reload to confirm persistence - var reloadedOptions = cut.Load() as SnykOptions; - Assert.NotNull(reloadedOptions); - + var reloadedOptions = cut.Load(); + Assert.True(reloadedOptions.AutoScan); Assert.True(reloadedOptions.IgnoreUnknownCA); Assert.Equal("my-org", reloadedOptions.Organization); From 19820457133f6f4c6a610ad17c17894b75896060 Mon Sep 17 00:00:00 2001 From: Abdelrahman Shawki Hassan Date: Fri, 20 Dec 2024 10:02:41 +0100 Subject: [PATCH 11/16] fix: UI freeze when changing auth method --- .../SnykLanguageClientCustomTarget.cs | 4 +-- .../SnykGeneralSettingsUserControl.cs | 29 +++++++------------ 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/Snyk.VisualStudio.Extension.2022/Language/SnykLanguageClientCustomTarget.cs b/Snyk.VisualStudio.Extension.2022/Language/SnykLanguageClientCustomTarget.cs index 6b58f341..fed705e9 100644 --- a/Snyk.VisualStudio.Extension.2022/Language/SnykLanguageClientCustomTarget.cs +++ b/Snyk.VisualStudio.Extension.2022/Language/SnykLanguageClientCustomTarget.cs @@ -133,11 +133,11 @@ public async Task OnHasAuthenticated(JToken arg) serviceProvider.Options.ApiToken = new AuthenticationToken(serviceProvider.Options.AuthenticationMethod, token); serviceProvider.SnykOptionsManager.Save(serviceProvider.Options); + await serviceProvider.GeneralOptionsDialogPage.HandleAuthenticationSuccess(token, apiUrl); + if (!serviceProvider.Options.ApiToken.IsValid()) return; - await serviceProvider.GeneralOptionsDialogPage.HandleAuthenticationSuccess(token, apiUrl); - serviceProvider.FeatureFlagService.RefreshAsync(SnykVSPackage.Instance.DisposalToken).FireAndForget(); if (serviceProvider.Options.AutoScan) { diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.cs index 1e27c0d1..887b9447 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.cs @@ -189,33 +189,25 @@ private async Task AuthenticateButtonClickAsync() private void TokenTextBox_TextChanged(object sender, EventArgs e) { - if (this.ValidateChildren(ValidationConstraints.Enabled)) - { - snykOptions.ApiToken = new AuthenticationToken(snykOptions.AuthenticationMethod, this.tokenTextBox.Text); - serviceProvider.Options.InvokeSettingsChangedEvent(); - } + snykOptions.ApiToken = new AuthenticationToken(snykOptions.AuthenticationMethod, this.tokenTextBox.Text); } private void CustomEndpointTextBox_LostFocus(object sender, EventArgs e) { - if (this.ValidateChildren(ValidationConstraints.Enabled)) + if (!Uri.IsWellFormedUriString(this.customEndpointTextBox.Text, UriKind.Absolute)) { - if (!Uri.IsWellFormedUriString(this.customEndpointTextBox.Text, UriKind.Absolute)) - { - Logger.Warning("Custom endpoint value is not a well-formed URI. Setting custom endpoint to empty string"); - this.customEndpointTextBox.Text = snykOptions.CustomEndpoint = string.Empty; - return; - } - - snykOptions.CustomEndpoint = ApiEndpointResolver.TranslateOldApiToNewApiEndpoint(this.customEndpointTextBox.Text); - serviceProvider.Options.InvokeSettingsChangedEvent(); + Logger.Warning("Custom endpoint value is not a well-formed URI. Setting custom endpoint to empty string"); + this.customEndpointTextBox.Text = snykOptions.CustomEndpoint = string.Empty; + return; } + + snykOptions.CustomEndpoint = ApiEndpointResolver.TranslateOldApiToNewApiEndpoint(this.customEndpointTextBox.Text); + serviceProvider.Options.InvokeSettingsChangedEvent(); } private void IgnoreUnknownCACheckBox_CheckedChanged(object sender, EventArgs e) { snykOptions.IgnoreUnknownCA = this.ignoreUnknownCACheckBox.Checked; - serviceProvider.Options.InvokeSettingsChangedEvent(); } private void TokenTextBox_Validating(object sender, CancelEventArgs cancelEventArgs) => @@ -266,7 +258,8 @@ private void OrganizationInfoLink_LinkClicked(object sender, LinkLabelLinkClicke private void authType_SelectionChangeCommitted(object sender, EventArgs e) { snykOptions.AuthenticationMethod = (AuthenticationType)authType.SelectedValue; - serviceProvider.Options.InvokeSettingsChangedEvent(); + if(LanguageClientHelper.IsLanguageServerReady()) + LanguageClientHelper.LanguageClientManager().DidChangeConfigurationAsync(SnykVSPackage.Instance.DisposalToken).FireAndForget(); } private void organizationTextBox_TextChanged(object sender, EventArgs e) @@ -274,7 +267,7 @@ private void organizationTextBox_TextChanged(object sender, EventArgs e) snykOptions.Organization = organizationTextBox.Text; } - public System.Windows.Forms.Panel GetPanel() + public Panel GetPanel() { return this.mainPanel; } From 4aaa29a5553972106028b2c8f943a916c009e8ec Mon Sep 17 00:00:00 2001 From: Abdelrahman Shawki Hassan Date: Fri, 20 Dec 2024 11:39:07 +0100 Subject: [PATCH 12/16] fix: added additional sections --- .../Settings/ISnykExperimentalDialogPage.cs | 8 ++ .../Settings/ISnykOptionsManager.cs | 7 - .../Settings/ISnykUserExperienceDialogPage.cs | 8 ++ .../Settings/SnykExperimentalDialogPage.cs | 51 +++++++ .../SnykExperimentalUserControl.Designer.cs | 126 ++++++++++++++++++ .../Settings/SnykExperimentalUserControl.cs | 54 ++++++++ .../Settings/SnykExperimentalUserControl.resx | 120 +++++++++++++++++ .../Settings/SnykGeneralOptionsDialogPage.cs | 2 + .../Settings/SnykOptionsManager.cs | 3 +- .../Settings/SnykScanOptionsDialogPage.cs | 6 - .../SnykScanOptionsUserControl.Designer.cs | 83 ------------ .../Settings/SnykScanOptionsUserControl.cs | 36 ----- ...SnykSolutionOptionsUserControl.Designer.cs | 31 ++--- .../SnykSolutionOptionsUserControl.cs | 46 +------ .../Settings/SnykUserExperienceDialogPage.cs | 52 ++++++++ .../SnykUserExperienceUserControl.Designer.cs | 95 +++++++++++++ .../Settings/SnykUserExperienceUserControl.cs | 29 ++++ .../SnykUserExperienceUserControl.resx | 120 +++++++++++++++++ .../Snyk.VisualStudio.Extension.2022.csproj | 26 ++++ .../SnykVSPackage.cs | 26 +++- .../SnykLanguageClientCustomTargetTests.cs | 2 +- .../SnykUserStorageSettingsServiceTest.cs | 3 + 22 files changed, 732 insertions(+), 202 deletions(-) create mode 100644 Snyk.VisualStudio.Extension.2022/Settings/ISnykExperimentalDialogPage.cs create mode 100644 Snyk.VisualStudio.Extension.2022/Settings/ISnykUserExperienceDialogPage.cs create mode 100644 Snyk.VisualStudio.Extension.2022/Settings/SnykExperimentalDialogPage.cs create mode 100644 Snyk.VisualStudio.Extension.2022/Settings/SnykExperimentalUserControl.Designer.cs create mode 100644 Snyk.VisualStudio.Extension.2022/Settings/SnykExperimentalUserControl.cs create mode 100644 Snyk.VisualStudio.Extension.2022/Settings/SnykExperimentalUserControl.resx create mode 100644 Snyk.VisualStudio.Extension.2022/Settings/SnykUserExperienceDialogPage.cs create mode 100644 Snyk.VisualStudio.Extension.2022/Settings/SnykUserExperienceUserControl.Designer.cs create mode 100644 Snyk.VisualStudio.Extension.2022/Settings/SnykUserExperienceUserControl.cs create mode 100644 Snyk.VisualStudio.Extension.2022/Settings/SnykUserExperienceUserControl.resx diff --git a/Snyk.VisualStudio.Extension.2022/Settings/ISnykExperimentalDialogPage.cs b/Snyk.VisualStudio.Extension.2022/Settings/ISnykExperimentalDialogPage.cs new file mode 100644 index 00000000..557cbbdb --- /dev/null +++ b/Snyk.VisualStudio.Extension.2022/Settings/ISnykExperimentalDialogPage.cs @@ -0,0 +1,8 @@ +using Snyk.VisualStudio.Extension.Service; + +namespace Snyk.VisualStudio.Extension.Settings; + +public interface ISnykExperimentalDialogPage +{ + void Initialize(ISnykServiceProvider provider); +} \ No newline at end of file diff --git a/Snyk.VisualStudio.Extension.2022/Settings/ISnykOptionsManager.cs b/Snyk.VisualStudio.Extension.2022/Settings/ISnykOptionsManager.cs index 2b579b6d..5b8311cf 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/ISnykOptionsManager.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/ISnykOptionsManager.cs @@ -27,11 +27,4 @@ public interface ISnykOptionsManager /// CLI options string. /// A representing the asynchronous operation. Task SaveAdditionalOptionsAsync(string additionalOptions); - - /// - /// Sace is all projects scan enabled. - /// - /// Bool param. - /// A representing the asynchronous operation. - Task SaveIsAllProjectsScanEnabledAsync(bool isAllProjectsEnabled); } \ No newline at end of file diff --git a/Snyk.VisualStudio.Extension.2022/Settings/ISnykUserExperienceDialogPage.cs b/Snyk.VisualStudio.Extension.2022/Settings/ISnykUserExperienceDialogPage.cs new file mode 100644 index 00000000..f1549866 --- /dev/null +++ b/Snyk.VisualStudio.Extension.2022/Settings/ISnykUserExperienceDialogPage.cs @@ -0,0 +1,8 @@ +using Snyk.VisualStudio.Extension.Service; + +namespace Snyk.VisualStudio.Extension.Settings; + +public interface ISnykUserExperienceDialogPage +{ + void Initialize(ISnykServiceProvider provider); +} \ No newline at end of file diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykExperimentalDialogPage.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykExperimentalDialogPage.cs new file mode 100644 index 00000000..57bb8276 --- /dev/null +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykExperimentalDialogPage.cs @@ -0,0 +1,51 @@ +using System; +using System.Runtime.InteropServices; +using System.Windows.Forms; +using Microsoft.VisualStudio.Shell; +using Snyk.VisualStudio.Extension.Language; +using Snyk.VisualStudio.Extension.Service; + +namespace Snyk.VisualStudio.Extension.Settings; + +[Guid("EB160D8D-C73F-4907-A9CA-4D287FACA36B")] +[ComVisible(true)] +public class SnykExperimentalDialogPage : DialogPage, ISnykExperimentalDialogPage +{ + private SnykExperimentalUserControl snykExperimentalUserControl; + private ISnykServiceProvider serviceProvider; + private ISnykOptions snykOptions; + + public void Initialize(ISnykServiceProvider provider) + { + this.serviceProvider = provider; + this.snykOptions = provider.Options; + } + protected override IWin32Window Window => SnykExperimentalUserControl; + public SnykExperimentalUserControl SnykExperimentalUserControl + { + get + { + if (snykExperimentalUserControl == null) + { + snykExperimentalUserControl = new SnykExperimentalUserControl(serviceProvider); + } + return snykExperimentalUserControl; + } + } + + // This method is used when the user clicks "Ok" + public override void SaveSettingsToStorage() + { + this.snykOptions.IgnoredIssuesEnabled = SnykExperimentalUserControl.OptionsMemento.IgnoredIssuesEnabled; + this.snykOptions.OpenIssuesEnabled = SnykExperimentalUserControl.OptionsMemento.OpenIssuesEnabled; + this.serviceProvider.SnykOptionsManager.Save(this.snykOptions); + + if (LanguageClientHelper.IsLanguageServerReady()) + LanguageClientHelper.LanguageClientManager().InvokeWorkspaceScanAsync(SnykVSPackage.Instance.DisposalToken).FireAndForget(); + } + + protected override void OnClosed(EventArgs e) + { + // do nothing + } +} \ No newline at end of file diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykExperimentalUserControl.Designer.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykExperimentalUserControl.Designer.cs new file mode 100644 index 00000000..58d8eb31 --- /dev/null +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykExperimentalUserControl.Designer.cs @@ -0,0 +1,126 @@ +namespace Snyk.VisualStudio.Extension.Settings +{ + partial class SnykExperimentalUserControl + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.experimentalGroupBox = new System.Windows.Forms.GroupBox(); + this.mainPanel = new System.Windows.Forms.Panel(); + this.ignoreGroupbox = new System.Windows.Forms.GroupBox(); + this.cbIgnoredIssues = new System.Windows.Forms.CheckBox(); + this.cbOpenIssues = new System.Windows.Forms.CheckBox(); + this.experimentalGroupBox.SuspendLayout(); + this.mainPanel.SuspendLayout(); + this.ignoreGroupbox.SuspendLayout(); + this.SuspendLayout(); + // + // experimentalGroupBox + // + this.experimentalGroupBox.Controls.Add(this.ignoreGroupbox); + this.experimentalGroupBox.Location = new System.Drawing.Point(3, 14); + this.experimentalGroupBox.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); + this.experimentalGroupBox.Name = "experimentalGroupBox"; + this.experimentalGroupBox.Padding = new System.Windows.Forms.Padding(11, 10, 11, 10); + this.experimentalGroupBox.Size = new System.Drawing.Size(747, 180); + this.experimentalGroupBox.TabIndex = 21; + this.experimentalGroupBox.TabStop = false; + this.experimentalGroupBox.Text = "Experimental"; + // + // mainPanel + // + this.mainPanel.AutoScroll = true; + this.mainPanel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.mainPanel.Controls.Add(this.experimentalGroupBox); + this.mainPanel.Dock = System.Windows.Forms.DockStyle.Fill; + this.mainPanel.Location = new System.Drawing.Point(0, 0); + this.mainPanel.Name = "mainPanel"; + this.mainPanel.Size = new System.Drawing.Size(832, 527); + this.mainPanel.TabIndex = 2; + // + // ignoreGroupbox + // + this.ignoreGroupbox.Controls.Add(this.cbIgnoredIssues); + this.ignoreGroupbox.Controls.Add(this.cbOpenIssues); + this.ignoreGroupbox.Location = new System.Drawing.Point(14, 28); + this.ignoreGroupbox.Name = "ignoreGroupbox"; + this.ignoreGroupbox.Size = new System.Drawing.Size(240, 80); + this.ignoreGroupbox.TabIndex = 24; + this.ignoreGroupbox.TabStop = false; + this.ignoreGroupbox.Text = "Show the following issues"; + // + // cbIgnoredIssues + // + this.cbIgnoredIssues.AutoSize = true; + this.cbIgnoredIssues.Checked = true; + this.cbIgnoredIssues.CheckState = System.Windows.Forms.CheckState.Checked; + this.cbIgnoredIssues.Location = new System.Drawing.Point(21, 51); + this.cbIgnoredIssues.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); + this.cbIgnoredIssues.Name = "cbIgnoredIssues"; + this.cbIgnoredIssues.Size = new System.Drawing.Size(117, 20); + this.cbIgnoredIssues.TabIndex = 25; + this.cbIgnoredIssues.Text = "Ignored issues"; + this.cbIgnoredIssues.UseVisualStyleBackColor = true; + this.cbIgnoredIssues.CheckedChanged += new System.EventHandler(this.cbIgnoredIssues_CheckedChanged); + // + // cbOpenIssues + // + this.cbOpenIssues.AutoSize = true; + this.cbOpenIssues.Checked = true; + this.cbOpenIssues.CheckState = System.Windows.Forms.CheckState.Checked; + this.cbOpenIssues.Location = new System.Drawing.Point(21, 22); + this.cbOpenIssues.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); + this.cbOpenIssues.Name = "cbOpenIssues"; + this.cbOpenIssues.Size = new System.Drawing.Size(104, 20); + this.cbOpenIssues.TabIndex = 24; + this.cbOpenIssues.Text = "Open issues"; + this.cbOpenIssues.UseVisualStyleBackColor = true; + this.cbOpenIssues.CheckedChanged += new System.EventHandler(this.cbOpenIssues_CheckedChanged); + // + // SnykExperimentalUserControl + // + this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.mainPanel); + this.Name = "SnykExperimentalUserControl"; + this.Size = new System.Drawing.Size(832, 527); + this.experimentalGroupBox.ResumeLayout(false); + this.mainPanel.ResumeLayout(false); + this.ignoreGroupbox.ResumeLayout(false); + this.ignoreGroupbox.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.GroupBox experimentalGroupBox; + private System.Windows.Forms.Panel mainPanel; + private System.Windows.Forms.GroupBox ignoreGroupbox; + private System.Windows.Forms.CheckBox cbIgnoredIssues; + private System.Windows.Forms.CheckBox cbOpenIssues; + } +} diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykExperimentalUserControl.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykExperimentalUserControl.cs new file mode 100644 index 00000000..08903966 --- /dev/null +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykExperimentalUserControl.cs @@ -0,0 +1,54 @@ +using System; +using System.Windows.Forms; +using Microsoft.VisualStudio.Shell; +using Snyk.VisualStudio.Extension.Language; +using Snyk.VisualStudio.Extension.Service; + +namespace Snyk.VisualStudio.Extension.Settings +{ + public partial class SnykExperimentalUserControl : UserControl + { + private readonly ISnykServiceProvider serviceProvider; + public ISnykOptions OptionsMemento { get; set; } + + public SnykExperimentalUserControl(ISnykServiceProvider serviceProvider) + { + this.serviceProvider = serviceProvider; + OptionsMemento = serviceProvider.SnykOptionsManager.Load(); + this.Load += OnLoad; + InitializeComponent(); + this.UpdateViewFromOptions(); + } + + private void UpdateViewFromOptions() + { + this.cbIgnoredIssues.Checked = OptionsMemento.IgnoredIssuesEnabled; + this.cbOpenIssues.Checked = OptionsMemento.OpenIssuesEnabled; + } + + private void OnLoad(object sender, EventArgs e) + { + CheckForIgnores(); + } + + private void CheckForIgnores() + { + ThreadHelper.JoinableTaskFactory.RunAsync(async () => + { + if (!serviceProvider.Options.ConsistentIgnoresEnabled && LanguageClientHelper.IsLanguageServerReady()) + await serviceProvider.FeatureFlagService.RefreshAsync(SnykVSPackage.Instance.DisposalToken); + await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); + }).FireAndForget(); + } + + private void cbOpenIssues_CheckedChanged(object sender, System.EventArgs e) + { + OptionsMemento.OpenIssuesEnabled = cbOpenIssues.Checked; + } + + private void cbIgnoredIssues_CheckedChanged(object sender, System.EventArgs e) + { + OptionsMemento.IgnoredIssuesEnabled = cbIgnoredIssues.Checked; + } + } +} diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykExperimentalUserControl.resx b/Snyk.VisualStudio.Extension.2022/Settings/SnykExperimentalUserControl.resx new file mode 100644 index 00000000..1af7de15 --- /dev/null +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykExperimentalUserControl.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralOptionsDialogPage.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralOptionsDialogPage.cs index 7a3ac8d2..756b85d2 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralOptionsDialogPage.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralOptionsDialogPage.cs @@ -122,6 +122,8 @@ public void Authenticate() ThreadHelper.JoinableTaskFactory.RunAsync(async () => { + await serviceProvider.LanguageClientManager.InvokeLogout(SnykVSPackage.Instance + .DisposalToken); await serviceProvider.LanguageClientManager.InvokeLogin(SnykVSPackage.Instance .DisposalToken); }).FireAndForget(); diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykOptionsManager.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykOptionsManager.cs index 39a3da11..01279b6b 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykOptionsManager.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykOptionsManager.cs @@ -1,5 +1,4 @@ -using System.IO; -using Snyk.VisualStudio.Extension.Authentication; +using Snyk.VisualStudio.Extension.Authentication; using Snyk.VisualStudio.Extension.Service; using System.Threading.Tasks; using Serilog; diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykScanOptionsDialogPage.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykScanOptionsDialogPage.cs index 66ebac53..958120c5 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykScanOptionsDialogPage.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykScanOptionsDialogPage.cs @@ -37,17 +37,11 @@ public SnykScanOptionsUserControl SnykCliOptionsUserControl // This method is used when the user clicks "Ok" public override void SaveSettingsToStorage() { - this.snykOptions.AutoScan = SnykCliOptionsUserControl.OptionsMemento.AutoScan; this.snykOptions.EnableDeltaFindings = SnykCliOptionsUserControl.OptionsMemento.EnableDeltaFindings; - this.snykOptions.IgnoredIssuesEnabled = SnykCliOptionsUserControl.OptionsMemento.IgnoredIssuesEnabled; - this.snykOptions.OpenIssuesEnabled = SnykCliOptionsUserControl.OptionsMemento.OpenIssuesEnabled; this.snykOptions.SnykCodeQualityEnabled = SnykCliOptionsUserControl.OptionsMemento.SnykCodeQualityEnabled; this.snykOptions.SnykCodeSecurityEnabled = SnykCliOptionsUserControl.OptionsMemento.SnykCodeSecurityEnabled; this.snykOptions.IacEnabled = SnykCliOptionsUserControl.OptionsMemento.IacEnabled; this.snykOptions.OssEnabled = SnykCliOptionsUserControl.OptionsMemento.OssEnabled; - if (LanguageClientHelper.IsLanguageServerReady() && this.snykOptions.AutoScan) - serviceProvider.LanguageClientManager.InvokeWorkspaceScanAsync(SnykVSPackage - .Instance.DisposalToken).FireAndForget(); this.serviceProvider.SnykOptionsManager.Save(this.snykOptions); } diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykScanOptionsUserControl.Designer.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykScanOptionsUserControl.Designer.cs index f7e04a02..7c872a38 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykScanOptionsUserControl.Designer.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykScanOptionsUserControl.Designer.cs @@ -34,9 +34,6 @@ private void InitializeComponent() this.label4 = new System.Windows.Forms.Label(); this.label3 = new System.Windows.Forms.Label(); this.cbDelta = new System.Windows.Forms.ComboBox(); - this.ignoreGroupbox = new System.Windows.Forms.GroupBox(); - this.cbIgnoredIssues = new System.Windows.Forms.CheckBox(); - this.cbOpenIssues = new System.Windows.Forms.CheckBox(); this.snykIacInfoLabel = new System.Windows.Forms.Label(); this.iacEnabledCheckbox = new System.Windows.Forms.CheckBox(); this.snykCodeQualityInfoLabel = new System.Windows.Forms.Label(); @@ -48,12 +45,8 @@ private void InitializeComponent() this.codeQualityEnabledCheckBox = new System.Windows.Forms.CheckBox(); this.ossEnabledCheckBox = new System.Windows.Forms.CheckBox(); this.codeSecurityEnabledCheckBox = new System.Windows.Forms.CheckBox(); - this.userExperienceGroupBox = new System.Windows.Forms.GroupBox(); - this.autoScanCheckBox = new System.Windows.Forms.CheckBox(); this.mainPanel.SuspendLayout(); this.productSelectionGroupBox.SuspendLayout(); - this.ignoreGroupbox.SuspendLayout(); - this.userExperienceGroupBox.SuspendLayout(); this.SuspendLayout(); // // mainPanel @@ -61,7 +54,6 @@ private void InitializeComponent() this.mainPanel.AutoScroll = true; this.mainPanel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; this.mainPanel.Controls.Add(this.productSelectionGroupBox); - this.mainPanel.Controls.Add(this.userExperienceGroupBox); this.mainPanel.Dock = System.Windows.Forms.DockStyle.Fill; this.mainPanel.Location = new System.Drawing.Point(0, 0); this.mainPanel.Name = "mainPanel"; @@ -73,7 +65,6 @@ private void InitializeComponent() this.productSelectionGroupBox.Controls.Add(this.label4); this.productSelectionGroupBox.Controls.Add(this.label3); this.productSelectionGroupBox.Controls.Add(this.cbDelta); - this.productSelectionGroupBox.Controls.Add(this.ignoreGroupbox); this.productSelectionGroupBox.Controls.Add(this.snykIacInfoLabel); this.productSelectionGroupBox.Controls.Add(this.iacEnabledCheckbox); this.productSelectionGroupBox.Controls.Add(this.snykCodeQualityInfoLabel); @@ -123,45 +114,6 @@ private void InitializeComponent() this.cbDelta.TabIndex = 25; this.cbDelta.SelectionChangeCommitted += new System.EventHandler(this.cbDelta_SelectionChangeCommitted); // - // ignoreGroupbox - // - this.ignoreGroupbox.Controls.Add(this.cbIgnoredIssues); - this.ignoreGroupbox.Controls.Add(this.cbOpenIssues); - this.ignoreGroupbox.Location = new System.Drawing.Point(493, 15); - this.ignoreGroupbox.Name = "ignoreGroupbox"; - this.ignoreGroupbox.Size = new System.Drawing.Size(240, 80); - this.ignoreGroupbox.TabIndex = 23; - this.ignoreGroupbox.TabStop = false; - this.ignoreGroupbox.Text = "Show the following issues"; - // - // cbIgnoredIssues - // - this.cbIgnoredIssues.AutoSize = true; - this.cbIgnoredIssues.Checked = true; - this.cbIgnoredIssues.CheckState = System.Windows.Forms.CheckState.Checked; - this.cbIgnoredIssues.Location = new System.Drawing.Point(21, 51); - this.cbIgnoredIssues.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); - this.cbIgnoredIssues.Name = "cbIgnoredIssues"; - this.cbIgnoredIssues.Size = new System.Drawing.Size(117, 20); - this.cbIgnoredIssues.TabIndex = 25; - this.cbIgnoredIssues.Text = "Ignored issues"; - this.cbIgnoredIssues.UseVisualStyleBackColor = true; - this.cbIgnoredIssues.CheckedChanged += new System.EventHandler(this.cbIgnoredIssues_CheckedChanged); - // - // cbOpenIssues - // - this.cbOpenIssues.AutoSize = true; - this.cbOpenIssues.Checked = true; - this.cbOpenIssues.CheckState = System.Windows.Forms.CheckState.Checked; - this.cbOpenIssues.Location = new System.Drawing.Point(21, 22); - this.cbOpenIssues.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); - this.cbOpenIssues.Name = "cbOpenIssues"; - this.cbOpenIssues.Size = new System.Drawing.Size(104, 20); - this.cbOpenIssues.TabIndex = 24; - this.cbOpenIssues.Text = "Open issues"; - this.cbOpenIssues.UseVisualStyleBackColor = true; - this.cbOpenIssues.CheckedChanged += new System.EventHandler(this.cbOpenIssues_CheckedChanged); - // // snykIacInfoLabel // this.snykIacInfoLabel.BackColor = System.Drawing.Color.Transparent; @@ -300,32 +252,6 @@ private void InitializeComponent() this.codeSecurityEnabledCheckBox.UseVisualStyleBackColor = true; this.codeSecurityEnabledCheckBox.CheckedChanged += new System.EventHandler(this.CodeSecurityEnabledCheckBox_CheckedChanged); // - // userExperienceGroupBox - // - this.userExperienceGroupBox.Controls.Add(this.autoScanCheckBox); - this.userExperienceGroupBox.Location = new System.Drawing.Point(17, 259); - this.userExperienceGroupBox.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); - this.userExperienceGroupBox.Name = "userExperienceGroupBox"; - this.userExperienceGroupBox.Padding = new System.Windows.Forms.Padding(11, 10, 11, 10); - this.userExperienceGroupBox.Size = new System.Drawing.Size(747, 64); - this.userExperienceGroupBox.TabIndex = 21; - this.userExperienceGroupBox.TabStop = false; - this.userExperienceGroupBox.Text = "User experience"; - // - // autoScanCheckBox - // - this.autoScanCheckBox.AutoSize = true; - this.autoScanCheckBox.Checked = true; - this.autoScanCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; - this.autoScanCheckBox.Location = new System.Drawing.Point(16, 28); - this.autoScanCheckBox.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); - this.autoScanCheckBox.Name = "autoScanCheckBox"; - this.autoScanCheckBox.Size = new System.Drawing.Size(266, 20); - this.autoScanCheckBox.TabIndex = 10; - this.autoScanCheckBox.Text = "Scan automatically on start-up and save"; - this.autoScanCheckBox.UseVisualStyleBackColor = true; - this.autoScanCheckBox.CheckedChanged += new System.EventHandler(this.autoScanCheckBox_CheckedChanged); - // // SnykScanOptionsUserControl // this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F); @@ -336,10 +262,6 @@ private void InitializeComponent() this.mainPanel.ResumeLayout(false); this.productSelectionGroupBox.ResumeLayout(false); this.productSelectionGroupBox.PerformLayout(); - this.ignoreGroupbox.ResumeLayout(false); - this.ignoreGroupbox.PerformLayout(); - this.userExperienceGroupBox.ResumeLayout(false); - this.userExperienceGroupBox.PerformLayout(); this.ResumeLayout(false); } @@ -351,9 +273,6 @@ private void InitializeComponent() private System.Windows.Forms.Label label4; private System.Windows.Forms.Label label3; private System.Windows.Forms.ComboBox cbDelta; - private System.Windows.Forms.GroupBox ignoreGroupbox; - private System.Windows.Forms.CheckBox cbIgnoredIssues; - private System.Windows.Forms.CheckBox cbOpenIssues; private System.Windows.Forms.Label snykIacInfoLabel; private System.Windows.Forms.CheckBox iacEnabledCheckbox; private System.Windows.Forms.Label snykCodeQualityInfoLabel; @@ -365,7 +284,5 @@ private void InitializeComponent() private System.Windows.Forms.CheckBox codeQualityEnabledCheckBox; private System.Windows.Forms.CheckBox ossEnabledCheckBox; private System.Windows.Forms.CheckBox codeSecurityEnabledCheckBox; - private System.Windows.Forms.GroupBox userExperienceGroupBox; - private System.Windows.Forms.CheckBox autoScanCheckBox; } } diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykScanOptionsUserControl.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykScanOptionsUserControl.cs index 2558d018..fed4776f 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykScanOptionsUserControl.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykScanOptionsUserControl.cs @@ -26,16 +26,10 @@ public SnykScanOptionsUserControl(ISnykServiceProvider serviceProvider) { this.serviceProvider = serviceProvider; OptionsMemento = serviceProvider.SnykOptionsManager.Load(); - serviceProvider.Options.SettingsChanged += OptionsOnSettingsChanged; InitializeComponent(); Initialize(); } - private void OptionsOnSettingsChanged(object sender, SnykSettingsChangedEventArgs e) - { - CheckForIgnores(); - } - private void Initialize() { Logger.Information("Enter Initialize method"); @@ -50,18 +44,6 @@ private void Initialize() private void SnykScanOptionsUserControl_Load(object sender, EventArgs e) { this.StartSastEnablementCheckLoop(); - this.CheckForIgnores(); - } - - private void CheckForIgnores() - { - ThreadHelper.JoinableTaskFactory.RunAsync(async () => - { - if (!serviceProvider.Options.ConsistentIgnoresEnabled && LanguageClientHelper.IsLanguageServerReady()) - await serviceProvider.FeatureFlagService.RefreshAsync(SnykVSPackage.Instance.DisposalToken); - await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); - this.ignoreGroupbox.Visible = serviceProvider.Options.ConsistentIgnoresEnabled; - }).FireAndForget(); } private void StartSastEnablementCheckLoop() @@ -151,9 +133,6 @@ private void UpdateViewFromOptions() { this.ossEnabledCheckBox.Checked = OptionsMemento.OssEnabled; this.iacEnabledCheckbox.Checked = OptionsMemento.IacEnabled; - this.autoScanCheckBox.Checked = OptionsMemento.AutoScan; - this.cbIgnoredIssues.Checked = OptionsMemento.IgnoredIssuesEnabled; - this.cbOpenIssues.Checked = OptionsMemento.OpenIssuesEnabled; if (cbDelta.DataSource == null) { @@ -195,16 +174,6 @@ private void CodeQualityEnabledCheckBox_CheckedChanged(object sender, EventArgs OptionsMemento.SnykCodeQualityEnabled = this.codeQualityEnabledCheckBox.Checked; } - private void cbOpenIssues_CheckedChanged(object sender, EventArgs e) - { - OptionsMemento.OpenIssuesEnabled = this.cbOpenIssues.Checked; - } - - private void cbIgnoredIssues_CheckedChanged(object sender, EventArgs e) - { - OptionsMemento.IgnoredIssuesEnabled = this.cbIgnoredIssues.Checked; - } - private void cbDelta_SelectionChangeCommitted(object sender, EventArgs e) { if (this.cbDelta.SelectedItem == null) @@ -213,11 +182,6 @@ private void cbDelta_SelectionChangeCommitted(object sender, EventArgs e) OptionsMemento.EnableDeltaFindings = enableDelta; } - private void autoScanCheckBox_CheckedChanged(object sender, EventArgs e) - { - OptionsMemento.AutoScan = autoScanCheckBox.Checked; - } - private void SnykCodeSettingsLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) => Process.Start(OptionsMemento.SnykCodeSettingsUrl); diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykSolutionOptionsUserControl.Designer.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykSolutionOptionsUserControl.Designer.cs index 2c7ff8ff..baa5da0e 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykSolutionOptionsUserControl.Designer.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykSolutionOptionsUserControl.Designer.cs @@ -30,8 +30,8 @@ private void InitializeComponent() { this.components = new System.ComponentModel.Container(); this.additionalOptionsTextBox = new System.Windows.Forms.TextBox(); - this.allProjectsCheckBox = new System.Windows.Forms.CheckBox(); this.errorProvider = new System.Windows.Forms.ErrorProvider(this.components); + this.label1 = new System.Windows.Forms.Label(); ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit(); this.SuspendLayout(); // @@ -39,7 +39,7 @@ private void InitializeComponent() // this.additionalOptionsTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.additionalOptionsTextBox.Location = new System.Drawing.Point(9, 14); + this.additionalOptionsTextBox.Location = new System.Drawing.Point(8, 41); this.additionalOptionsTextBox.Multiline = true; this.additionalOptionsTextBox.Name = "additionalOptionsTextBox"; this.additionalOptionsTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Both; @@ -47,30 +47,25 @@ private void InitializeComponent() this.additionalOptionsTextBox.TabIndex = 0; this.additionalOptionsTextBox.TextChanged += new System.EventHandler(this.AdditionalOptionsTextBox_TextChanged); // - // allProjectsCheckBox - // - this.allProjectsCheckBox.AutoSize = true; - this.allProjectsCheckBox.Checked = true; - this.allProjectsCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; - this.allProjectsCheckBox.Location = new System.Drawing.Point(9, 162); - this.allProjectsCheckBox.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2); - this.allProjectsCheckBox.Name = "allProjectsCheckBox"; - this.allProjectsCheckBox.Size = new System.Drawing.Size(253, 20); - this.allProjectsCheckBox.TabIndex = 1; - this.allProjectsCheckBox.Text = "Scan all projects (--all-projects option)"; - this.allProjectsCheckBox.UseVisualStyleBackColor = true; - this.allProjectsCheckBox.CheckedChanged += new System.EventHandler(this.AllProjectsCheckBox_CheckedChanged); - // // errorProvider // this.errorProvider.ContainerControl = this; // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(8, 22); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(143, 16); + this.label1.TabIndex = 2; + this.label1.Text = "Additional Parameters:"; + // // SnykSolutionOptionsUserControl // this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.AutoSize = true; - this.Controls.Add(this.allProjectsCheckBox); + this.Controls.Add(this.label1); this.Controls.Add(this.additionalOptionsTextBox); this.Name = "SnykSolutionOptionsUserControl"; this.Padding = new System.Windows.Forms.Padding(5, 4, 5, 4); @@ -85,7 +80,7 @@ private void InitializeComponent() #endregion private System.Windows.Forms.TextBox additionalOptionsTextBox; - private System.Windows.Forms.CheckBox allProjectsCheckBox; private System.Windows.Forms.ErrorProvider errorProvider; + private System.Windows.Forms.Label label1; } } diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykSolutionOptionsUserControl.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykSolutionOptionsUserControl.cs index 0d88cd49..a30ef05c 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykSolutionOptionsUserControl.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykSolutionOptionsUserControl.cs @@ -13,7 +13,7 @@ public partial class SnykSolutionOptionsUserControl : UserControl { private static readonly ILogger Logger = LogManager.ForContext(); - private ISnykServiceProvider serviceProvider; + private readonly ISnykServiceProvider serviceProvider; /// /// Initializes a new instance of the class. @@ -26,20 +26,6 @@ public SnykSolutionOptionsUserControl(ISnykServiceProvider serviceProvider) this.serviceProvider = serviceProvider; } - private void CheckOptionConflicts() - { - if (this.allProjectsCheckBox.Checked && this.additionalOptionsTextBox.Text.Contains("--file=")) - { - this.errorProvider.SetError( - this.additionalOptionsTextBox, - "The following option combination is not currently supported: file + all-projects"); - } - else - { - this.errorProvider.SetError(this.additionalOptionsTextBox, string.Empty); - } - } - private void AdditionalOptionsTextBox_TextChanged(object sender, EventArgs e) { if (this.serviceProvider.SolutionService.IsSolutionOpen()) @@ -47,18 +33,6 @@ private void AdditionalOptionsTextBox_TextChanged(object sender, EventArgs e) string additionalOptions = this.additionalOptionsTextBox.Text; this.serviceProvider.SnykOptionsManager.SaveAdditionalOptionsAsync(additionalOptions).FireAndForget(); - - this.CheckOptionConflicts(); - } - } - - private void AllProjectsCheckBox_CheckedChanged(object sender, EventArgs e) - { - if (this.serviceProvider.SolutionService.IsSolutionOpen()) - { - this.serviceProvider.SnykOptionsManager.SaveIsAllProjectsScanEnabledAsync(this.allProjectsCheckBox.Checked).FireAndForget(); - - this.CheckOptionConflicts(); } } @@ -69,7 +43,6 @@ private void SnykProjectOptionsUserControl_Load(object sender, EventArgs eventAr bool isProjectOpened = this.serviceProvider.SolutionService.IsSolutionOpen(); this.additionalOptionsTextBox.Enabled = isProjectOpened; - this.allProjectsCheckBox.Enabled = isProjectOpened; if (!isProjectOpened) { @@ -95,23 +68,6 @@ private void SnykProjectOptionsUserControl_Load(object sender, EventArgs eventAr this.additionalOptionsTextBox.Text = string.Empty; } - - try - { - bool isChecked = await this.serviceProvider.SnykOptionsManager.GetIsAllProjectsEnabledAsync(); - - this.allProjectsCheckBox.Checked = isChecked; - } - catch (Exception e) - { - Logger.Error(e, "Error on load is all projects enabled"); - - this.allProjectsCheckBox.Checked = false; - - await this.serviceProvider.SnykOptionsManager.SaveIsAllProjectsScanEnabledAsync(false); - } - - this.CheckOptionConflicts(); }); } } diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykUserExperienceDialogPage.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykUserExperienceDialogPage.cs new file mode 100644 index 00000000..73951f59 --- /dev/null +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykUserExperienceDialogPage.cs @@ -0,0 +1,52 @@ +using System; +using System.Runtime.InteropServices; +using System.Windows.Forms; +using Microsoft.VisualStudio.Shell; +using Snyk.VisualStudio.Extension.Language; +using Snyk.VisualStudio.Extension.Service; + +namespace Snyk.VisualStudio.Extension.Settings; + +[Guid("6A88ADAA-CA31-4146-8410-A340F8AA7E92")] +[ComVisible(true)] +public class SnykUserExperienceDialogPage : DialogPage, ISnykUserExperienceDialogPage +{ + private SnykUserExperienceUserControl snykUserExperienceUserControl; + private ISnykServiceProvider serviceProvider; + private ISnykOptions snykOptions; + + public void Initialize(ISnykServiceProvider provider) + { + this.serviceProvider = provider; + this.snykOptions = provider.Options; + } + + protected override IWin32Window Window => SnykUserExperienceUserControl; + public SnykUserExperienceUserControl SnykUserExperienceUserControl + { + get + { + if (snykUserExperienceUserControl == null) + { + snykUserExperienceUserControl = new SnykUserExperienceUserControl(serviceProvider); + } + return snykUserExperienceUserControl; + } + } + + // This method is used when the user clicks "Ok" + public override void SaveSettingsToStorage() + { + this.snykOptions.AutoScan = SnykUserExperienceUserControl.OptionsMemento.AutoScan; + this.serviceProvider.SnykOptionsManager.Save(this.snykOptions); + + if (LanguageClientHelper.IsLanguageServerReady() && this.snykOptions.AutoScan) + serviceProvider.LanguageClientManager.InvokeWorkspaceScanAsync(SnykVSPackage + .Instance.DisposalToken).FireAndForget(); + } + + protected override void OnClosed(EventArgs e) + { + // do nothing + } +} \ No newline at end of file diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykUserExperienceUserControl.Designer.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykUserExperienceUserControl.Designer.cs new file mode 100644 index 00000000..990b72f0 --- /dev/null +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykUserExperienceUserControl.Designer.cs @@ -0,0 +1,95 @@ +namespace Snyk.VisualStudio.Extension.Settings +{ + partial class SnykUserExperienceUserControl + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.autoScanCheckBox = new System.Windows.Forms.CheckBox(); + this.userExperienceGroupBox = new System.Windows.Forms.GroupBox(); + this.mainPanel = new System.Windows.Forms.Panel(); + this.userExperienceGroupBox.SuspendLayout(); + this.mainPanel.SuspendLayout(); + this.SuspendLayout(); + // + // autoScanCheckBox + // + this.autoScanCheckBox.AutoSize = true; + this.autoScanCheckBox.Checked = true; + this.autoScanCheckBox.CheckState = System.Windows.Forms.CheckState.Checked; + this.autoScanCheckBox.Location = new System.Drawing.Point(16, 28); + this.autoScanCheckBox.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); + this.autoScanCheckBox.Name = "autoScanCheckBox"; + this.autoScanCheckBox.Size = new System.Drawing.Size(266, 20); + this.autoScanCheckBox.TabIndex = 10; + this.autoScanCheckBox.Text = "Scan automatically on start-up and save"; + this.autoScanCheckBox.UseVisualStyleBackColor = true; + this.autoScanCheckBox.CheckedChanged += new System.EventHandler(this.autoScanCheckBox_CheckedChanged); + // + // userExperienceGroupBox + // + this.userExperienceGroupBox.Controls.Add(this.autoScanCheckBox); + this.userExperienceGroupBox.Location = new System.Drawing.Point(3, 14); + this.userExperienceGroupBox.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); + this.userExperienceGroupBox.Name = "userExperienceGroupBox"; + this.userExperienceGroupBox.Padding = new System.Windows.Forms.Padding(11, 10, 11, 10); + this.userExperienceGroupBox.Size = new System.Drawing.Size(747, 64); + this.userExperienceGroupBox.TabIndex = 21; + this.userExperienceGroupBox.TabStop = false; + this.userExperienceGroupBox.Text = "User experience"; + // + // mainPanel + // + this.mainPanel.AutoScroll = true; + this.mainPanel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.mainPanel.Controls.Add(this.userExperienceGroupBox); + this.mainPanel.Dock = System.Windows.Forms.DockStyle.Fill; + this.mainPanel.Location = new System.Drawing.Point(0, 0); + this.mainPanel.Name = "mainPanel"; + this.mainPanel.Size = new System.Drawing.Size(862, 347); + this.mainPanel.TabIndex = 3; + // + // SnykUserExperienceUserControl + // + this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add(this.mainPanel); + this.Name = "SnykUserExperienceUserControl"; + this.Size = new System.Drawing.Size(862, 347); + this.userExperienceGroupBox.ResumeLayout(false); + this.userExperienceGroupBox.PerformLayout(); + this.mainPanel.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.CheckBox autoScanCheckBox; + private System.Windows.Forms.GroupBox userExperienceGroupBox; + private System.Windows.Forms.Panel mainPanel; + } +} diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykUserExperienceUserControl.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykUserExperienceUserControl.cs new file mode 100644 index 00000000..dcace701 --- /dev/null +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykUserExperienceUserControl.cs @@ -0,0 +1,29 @@ +using System.Windows.Forms; +using Snyk.VisualStudio.Extension.Service; + +namespace Snyk.VisualStudio.Extension.Settings +{ + public partial class SnykUserExperienceUserControl : UserControl + { + private readonly ISnykServiceProvider serviceProvider; + public ISnykOptions OptionsMemento { get; set; } + + public SnykUserExperienceUserControl(ISnykServiceProvider serviceProvider) + { + this.serviceProvider = serviceProvider; + OptionsMemento = serviceProvider.SnykOptionsManager.Load(); + InitializeComponent(); + this.UpdateViewFromOptions(); + } + + private void UpdateViewFromOptions() + { + this.autoScanCheckBox.Checked = OptionsMemento.AutoScan; + } + + private void autoScanCheckBox_CheckedChanged(object sender, System.EventArgs e) + { + OptionsMemento.AutoScan = autoScanCheckBox.Checked; + } + } +} diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykUserExperienceUserControl.resx b/Snyk.VisualStudio.Extension.2022/Settings/SnykUserExperienceUserControl.resx new file mode 100644 index 00000000..1af7de15 --- /dev/null +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykUserExperienceUserControl.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Snyk.VisualStudio.Extension.2022/Snyk.VisualStudio.Extension.2022.csproj b/Snyk.VisualStudio.Extension.2022/Snyk.VisualStudio.Extension.2022.csproj index b82fa275..3e18ec98 100644 --- a/Snyk.VisualStudio.Extension.2022/Snyk.VisualStudio.Extension.2022.csproj +++ b/Snyk.VisualStudio.Extension.2022/Snyk.VisualStudio.Extension.2022.csproj @@ -147,10 +147,12 @@ + + Component @@ -160,6 +162,15 @@ SnykCliOptionsUserControl.cs + + Component + + + UserControl + + + SnykExperimentalUserControl.cs + Component @@ -193,6 +204,15 @@ SnykSolutionOptionsUserControl.cs + + Component + + + UserControl + + + SnykUserExperienceUserControl.cs + SnykIcons.resx @@ -597,6 +617,9 @@ SnykCliOptionsUserControl.cs + + SnykExperimentalUserControl.cs + SnykGeneralSettingsUserControl.cs Designer @@ -607,6 +630,9 @@ SnykSolutionOptionsUserControl.cs + + SnykUserExperienceUserControl.cs + SnykIcons.Designer.cs ResXFileCodeGenerator diff --git a/Snyk.VisualStudio.Extension.2022/SnykVSPackage.cs b/Snyk.VisualStudio.Extension.2022/SnykVSPackage.cs index 890fee0f..18c0598e 100644 --- a/Snyk.VisualStudio.Extension.2022/SnykVSPackage.cs +++ b/Snyk.VisualStudio.Extension.2022/SnykVSPackage.cs @@ -50,10 +50,12 @@ namespace Snyk.VisualStudio.Extension [ProvideService(typeof(ISnykService), IsAsyncQueryable = true)] [ProvideMenuResource("Menus.ctmenu", 1)] [ProvideToolWindow(typeof(SnykToolWindow), Style = VsDockStyle.Tabbed)] - [ProvideOptionPage(typeof(SnykGeneralOptionsDialogPage), "Snyk", "General", 1000, 1001, true)] - [ProvideOptionPage(typeof(SnykSolutionOptionsDialogPage), "Snyk", "Solution settings", 1000, 1002, true)] - [ProvideOptionPage(typeof(SnykCliOptionsDialogPage), "Snyk", "CLI settings", 1000, 1003, true)] - [ProvideOptionPage(typeof(SnykScanOptionsDialogPage), "Snyk", "Scan settings", 1000, 1004, true)] + [ProvideOptionPage(typeof(SnykGeneralOptionsDialogPage), "Snyk", "Account", 1000, 1001, true)] + [ProvideOptionPage(typeof(SnykScanOptionsDialogPage), "Snyk", "Scan Configuration", 1000, 1002, true)] + [ProvideOptionPage(typeof(SnykSolutionOptionsDialogPage), "Snyk", "Solution settings", 1000, 1003, true)] + [ProvideOptionPage(typeof(SnykCliOptionsDialogPage), "Snyk", "CLI settings", 1000, 1004, true)] + [ProvideOptionPage(typeof(SnykExperimentalDialogPage), "Snyk", "Experimental", 1000, 1005, true)] + [ProvideOptionPage(typeof(SnykUserExperienceDialogPage), "Snyk", "User Experience", 1000, 1006, true)] public sealed class SnykVSPackage : AsyncPackage { /// @@ -106,6 +108,8 @@ public void SetServiceProvider(ISnykServiceProvider serviceProvider) public ISnykGeneralOptionsDialogPage SnykGeneralOptionsDialogPage { get; private set; } public ISnykCliOptionsDialogPage SnykCliOptionsDialogPage { get; private set; } public ISnykScanOptionsDialogPage SnykScanOptionsDialogPage { get; private set; } + public ISnykExperimentalDialogPage SnykExperimentalDialogPage { get; private set; } + public ISnykUserExperienceDialogPage SnykUserExperienceDialogPage { get; private set; } /// /// Gets instance. @@ -343,6 +347,20 @@ private async Task InitializeOptionsAsync() (SnykScanOptionsDialogPage)GetDialogPage(typeof(SnykScanOptionsDialogPage)); SnykScanOptionsDialogPage.Initialize(this.serviceProvider); } + + if (SnykUserExperienceDialogPage == null) + { + SnykUserExperienceDialogPage = + (SnykUserExperienceDialogPage)GetDialogPage(typeof(SnykUserExperienceDialogPage)); + SnykUserExperienceDialogPage.Initialize(this.serviceProvider); + } + + if (SnykExperimentalDialogPage == null) + { + SnykExperimentalDialogPage = + (SnykExperimentalDialogPage)GetDialogPage(typeof(SnykExperimentalDialogPage)); + SnykExperimentalDialogPage.Initialize(this.serviceProvider); + } } private async Task GetVsVersionAsync() diff --git a/Snyk.VisualStudio.Extension.Tests/Language/SnykLanguageClientCustomTargetTests.cs b/Snyk.VisualStudio.Extension.Tests/Language/SnykLanguageClientCustomTargetTests.cs index fe971a5b..780d2a44 100644 --- a/Snyk.VisualStudio.Extension.Tests/Language/SnykLanguageClientCustomTargetTests.cs +++ b/Snyk.VisualStudio.Extension.Tests/Language/SnykLanguageClientCustomTargetTests.cs @@ -42,7 +42,7 @@ public SnykLanguageClientCustomTargetTests(GlobalServiceProvider gsp) : base(gsp serviceProviderMock.SetupGet(sp => sp.SnykOptionsManager).Returns(snykOptionsManagerMock.Object); serviceProviderMock.SetupGet(sp => sp.FeatureFlagService).Returns(featureFlagServiceMock.Object); serviceProviderMock.SetupGet(sp => sp.LanguageClientManager).Returns(languageClientManagerMock.Object); - + optionsMock.SetupAllProperties(); cut = new SnykLanguageClientCustomTarget(serviceProviderMock.Object); } diff --git a/Snyk.VisualStudio.Extension.Tests/SnykUserStorageSettingsServiceTest.cs b/Snyk.VisualStudio.Extension.Tests/SnykUserStorageSettingsServiceTest.cs index b4e0050d..ba420495 100644 --- a/Snyk.VisualStudio.Extension.Tests/SnykUserStorageSettingsServiceTest.cs +++ b/Snyk.VisualStudio.Extension.Tests/SnykUserStorageSettingsServiceTest.cs @@ -27,6 +27,9 @@ public SnykOptionsManagerTest() serviceProviderMock .Setup(serviceProvider => serviceProvider.SolutionService) .Returns(solutionServiceMock.Object); + var optionsMock = new Mock(); + optionsMock.Setup(x => x.InvokeSettingsChangedEvent()); + serviceProviderMock.Setup(x => x.Options).Returns(optionsMock.Object); } [Fact] From 3c8df6fcec90bc2b09030efed22cac38310855be Mon Sep 17 00:00:00 2001 From: Abdelrahman Shawki Hassan Date: Fri, 20 Dec 2024 16:24:02 +0100 Subject: [PATCH 13/16] fix: pr comments --- .../Settings/ISnykOptionsManager.cs | 7 +-- .../ISnykSolutionOptionsDialogPage.cs | 8 +++ .../Settings/SnykCliOptionsDialogPage.cs | 1 + .../Settings/SnykExperimentalDialogPage.cs | 2 +- .../Settings/SnykExperimentalUserControl.cs | 2 +- .../Settings/SnykOptionsManager.cs | 52 ------------------- .../Settings/SnykSolutionOptionsDialogPage.cs | 38 ++++++++++++-- .../SnykSolutionOptionsUserControl.cs | 6 +-- .../Snyk.VisualStudio.Extension.2022.csproj | 1 + .../SnykVSPackage.cs | 7 +++ .../SnykUserStorageSettingsServiceTest.cs | 28 ---------- 11 files changed, 57 insertions(+), 95 deletions(-) create mode 100644 Snyk.VisualStudio.Extension.2022/Settings/ISnykSolutionOptionsDialogPage.cs diff --git a/Snyk.VisualStudio.Extension.2022/Settings/ISnykOptionsManager.cs b/Snyk.VisualStudio.Extension.2022/Settings/ISnykOptionsManager.cs index 5b8311cf..fba33fa5 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/ISnykOptionsManager.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/ISnykOptionsManager.cs @@ -9,12 +9,6 @@ public interface ISnykOptionsManager ISnykOptions Load(); void Save(IPersistableOptions options); - /// - /// Get is all projects enabled. - /// - /// Bool. - Task GetIsAllProjectsEnabledAsync(); - /// /// Get CLI additional options string. /// @@ -27,4 +21,5 @@ public interface ISnykOptionsManager /// CLI options string. /// A representing the asynchronous operation. Task SaveAdditionalOptionsAsync(string additionalOptions); + } \ No newline at end of file diff --git a/Snyk.VisualStudio.Extension.2022/Settings/ISnykSolutionOptionsDialogPage.cs b/Snyk.VisualStudio.Extension.2022/Settings/ISnykSolutionOptionsDialogPage.cs new file mode 100644 index 00000000..61fcc6fc --- /dev/null +++ b/Snyk.VisualStudio.Extension.2022/Settings/ISnykSolutionOptionsDialogPage.cs @@ -0,0 +1,8 @@ +using Snyk.VisualStudio.Extension.Service; + +namespace Snyk.VisualStudio.Extension.Settings; + +public interface ISnykSolutionOptionsDialogPage +{ + void Initialize(ISnykServiceProvider provider); +} \ No newline at end of file diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsDialogPage.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsDialogPage.cs index 276fe837..3861d404 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsDialogPage.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsDialogPage.cs @@ -70,6 +70,7 @@ private void HandleCliDownload() if (memento.BinariesAutoUpdate) { + // DownloadStarted event stops language server and DownloadFinished starts it automatically this.serviceProvider.TasksService.Download(); } else diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykExperimentalDialogPage.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykExperimentalDialogPage.cs index 57bb8276..3038a3ca 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykExperimentalDialogPage.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykExperimentalDialogPage.cs @@ -40,7 +40,7 @@ public override void SaveSettingsToStorage() this.snykOptions.OpenIssuesEnabled = SnykExperimentalUserControl.OptionsMemento.OpenIssuesEnabled; this.serviceProvider.SnykOptionsManager.Save(this.snykOptions); - if (LanguageClientHelper.IsLanguageServerReady()) + if (LanguageClientHelper.IsLanguageServerReady() && snykOptions.AutoScan) LanguageClientHelper.LanguageClientManager().InvokeWorkspaceScanAsync(SnykVSPackage.Instance.DisposalToken).FireAndForget(); } diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykExperimentalUserControl.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykExperimentalUserControl.cs index 08903966..0752b129 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykExperimentalUserControl.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykExperimentalUserControl.cs @@ -35,7 +35,7 @@ private void CheckForIgnores() { ThreadHelper.JoinableTaskFactory.RunAsync(async () => { - if (!serviceProvider.Options.ConsistentIgnoresEnabled && LanguageClientHelper.IsLanguageServerReady()) + if (serviceProvider.Options.ApiToken.IsValid() && !serviceProvider.Options.ConsistentIgnoresEnabled && LanguageClientHelper.IsLanguageServerReady()) await serviceProvider.FeatureFlagService.RefreshAsync(SnykVSPackage.Instance.DisposalToken); await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); }).FireAndForget(); diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykOptionsManager.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykOptionsManager.cs index 01279b6b..ca29139a 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykOptionsManager.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykOptionsManager.cs @@ -103,26 +103,6 @@ public void Save(IPersistableOptions options) serviceProvider.Options.InvokeSettingsChangedEvent(); } - /// - /// Get is all projects enabled. - /// - /// Bool. - public async Task GetIsAllProjectsEnabledAsync() - { - Logger.Information("Enter GetIsAllProjectsEnabled method"); - - var solutionPathHash = await this.GetSolutionPathHashAsync(); - - if (snykSettings == null || !snykSettings.SolutionSettingsDict.ContainsKey(solutionPathHash)) - { - return true; - } - else - { - return snykSettings.SolutionSettingsDict[solutionPathHash].IsAllProjectsScanEnabled; - } - } - /// /// Get CLI additional options string. /// @@ -173,38 +153,6 @@ public async Task SaveAdditionalOptionsAsync(string additionalOptions) Logger.Information("Leave SaveAdditionalOptions method"); } - /// - /// Sace is all projects scan enabled. - /// - /// Bool param. - /// A representing the asynchronous operation. - public async Task SaveIsAllProjectsScanEnabledAsync(bool isAllProjectsEnabled) - { - // TODO: Move to SnykOptionsManager - Logger.Information("Enter SaveIsAllProjectsScan method"); - - var solutionPathHash = await this.GetSolutionPathHashAsync(); - - SnykSolutionSettings projectSettings; - - if (snykSettings.SolutionSettingsDict.ContainsKey(solutionPathHash)) - { - projectSettings = snykSettings.SolutionSettingsDict[solutionPathHash]; - } - else - { - projectSettings = new SnykSolutionSettings(); - } - - projectSettings.IsAllProjectsScanEnabled = isAllProjectsEnabled; - - snykSettings.SolutionSettingsDict[solutionPathHash] = projectSettings; - - this.SaveSettingsToFile(); - - Logger.Information("Leave SaveIsAllProjectsScan method"); - } - private async Task GetSolutionPathHashAsync() => (await this.serviceProvider.SolutionService.GetSolutionFolderAsync()).ToLower().GetHashCode(); } diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykSolutionOptionsDialogPage.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykSolutionOptionsDialogPage.cs index 1bda1a11..dcd5abd2 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykSolutionOptionsDialogPage.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykSolutionOptionsDialogPage.cs @@ -1,6 +1,8 @@ -using System.Runtime.InteropServices; +using System; +using System.Runtime.InteropServices; using System.Windows.Forms; using Microsoft.VisualStudio.Shell; +using Snyk.VisualStudio.Extension.Service; namespace Snyk.VisualStudio.Extension.Settings { @@ -9,11 +11,41 @@ namespace Snyk.VisualStudio.Extension.Settings /// [Guid("6558dc66-aad3-41d6-84ed-8bea01fc852d")] [ComVisible(true)] - public class SnykSolutionOptionsDialogPage : DialogPage + public class SnykSolutionOptionsDialogPage : DialogPage, ISnykSolutionOptionsDialogPage { + public void Initialize(ISnykServiceProvider provider) + { + this.serviceProvider = provider; + } + /// /// Gets a value indicating whether . /// - protected override IWin32Window Window => new SnykSolutionOptionsUserControl(SnykVSPackage.ServiceProvider); + protected override IWin32Window Window => SnykSolutionOptionsUserControl; + + private SnykSolutionOptionsUserControl snykSolutionOptionsUserControl; + private ISnykServiceProvider serviceProvider; + + public SnykSolutionOptionsUserControl SnykSolutionOptionsUserControl + { + get + { + if (snykSolutionOptionsUserControl == null) + { + snykSolutionOptionsUserControl = new SnykSolutionOptionsUserControl(serviceProvider); + } + return snykSolutionOptionsUserControl; + } + } + + public override void SaveSettingsToStorage() + { + this.serviceProvider.SnykOptionsManager.SaveAdditionalOptionsAsync(SnykSolutionOptionsUserControl.AdditionalOptions).FireAndForget(); + } + + protected override void OnClosed(EventArgs e) + { + // do nothing + } } } diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykSolutionOptionsUserControl.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykSolutionOptionsUserControl.cs index a30ef05c..bef56ea4 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykSolutionOptionsUserControl.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykSolutionOptionsUserControl.cs @@ -14,7 +14,7 @@ public partial class SnykSolutionOptionsUserControl : UserControl private static readonly ILogger Logger = LogManager.ForContext(); private readonly ISnykServiceProvider serviceProvider; - + public string AdditionalOptions { get; set; } /// /// Initializes a new instance of the class. /// @@ -30,9 +30,7 @@ private void AdditionalOptionsTextBox_TextChanged(object sender, EventArgs e) { if (this.serviceProvider.SolutionService.IsSolutionOpen()) { - string additionalOptions = this.additionalOptionsTextBox.Text; - - this.serviceProvider.SnykOptionsManager.SaveAdditionalOptionsAsync(additionalOptions).FireAndForget(); + AdditionalOptions = this.additionalOptionsTextBox.Text; } } diff --git a/Snyk.VisualStudio.Extension.2022/Snyk.VisualStudio.Extension.2022.csproj b/Snyk.VisualStudio.Extension.2022/Snyk.VisualStudio.Extension.2022.csproj index 3e18ec98..441f1c30 100644 --- a/Snyk.VisualStudio.Extension.2022/Snyk.VisualStudio.Extension.2022.csproj +++ b/Snyk.VisualStudio.Extension.2022/Snyk.VisualStudio.Extension.2022.csproj @@ -152,6 +152,7 @@ + Component diff --git a/Snyk.VisualStudio.Extension.2022/SnykVSPackage.cs b/Snyk.VisualStudio.Extension.2022/SnykVSPackage.cs index 18c0598e..6e8bbbff 100644 --- a/Snyk.VisualStudio.Extension.2022/SnykVSPackage.cs +++ b/Snyk.VisualStudio.Extension.2022/SnykVSPackage.cs @@ -110,6 +110,7 @@ public void SetServiceProvider(ISnykServiceProvider serviceProvider) public ISnykScanOptionsDialogPage SnykScanOptionsDialogPage { get; private set; } public ISnykExperimentalDialogPage SnykExperimentalDialogPage { get; private set; } public ISnykUserExperienceDialogPage SnykUserExperienceDialogPage { get; private set; } + public ISnykSolutionOptionsDialogPage SnykSolutionOptionsDialogPage { get; private set; } /// /// Gets instance. @@ -361,6 +362,12 @@ private async Task InitializeOptionsAsync() (SnykExperimentalDialogPage)GetDialogPage(typeof(SnykExperimentalDialogPage)); SnykExperimentalDialogPage.Initialize(this.serviceProvider); } + if (SnykSolutionOptionsDialogPage == null) + { + SnykSolutionOptionsDialogPage = + (SnykSolutionOptionsDialogPage)GetDialogPage(typeof(SnykSolutionOptionsDialogPage)); + SnykSolutionOptionsDialogPage.Initialize(this.serviceProvider); + } } private async Task GetVsVersionAsync() diff --git a/Snyk.VisualStudio.Extension.Tests/SnykUserStorageSettingsServiceTest.cs b/Snyk.VisualStudio.Extension.Tests/SnykUserStorageSettingsServiceTest.cs index ba420495..60e84e93 100644 --- a/Snyk.VisualStudio.Extension.Tests/SnykUserStorageSettingsServiceTest.cs +++ b/Snyk.VisualStudio.Extension.Tests/SnykUserStorageSettingsServiceTest.cs @@ -114,33 +114,5 @@ public async Task OverwriteAdditionalOptionsSuccessfully() await cut.SaveAdditionalOptionsAsync("--second-command"); Assert.Equal("--second-command", await cut.GetAdditionalOptionsAsync()); } - - [Fact] - public async Task GetIsAllProjectsEnabledAsync_DefaultTrueIfNotSet() - { - solutionServiceMock - .Setup(solutionService => solutionService.GetSolutionFolderAsync()) - .ReturnsAsync("C:\\Projects\\NonExistentProj"); - Assert.True(await cut.GetIsAllProjectsEnabledAsync()); - } - - [Fact] - public async Task SaveIsAllProjectsScanEnabledAsync_ChangesValue() - { - solutionServiceMock - .Setup(solutionService => solutionService.GetSolutionFolderAsync()) - .ReturnsAsync("C:\\Projects\\NonExistentProj"); - // Default is true - Assert.True(await cut.GetIsAllProjectsEnabledAsync()); - - await cut.SaveIsAllProjectsScanEnabledAsync(false); - Assert.False(await cut.GetIsAllProjectsEnabledAsync()); - - // Change back to true - await cut.SaveIsAllProjectsScanEnabledAsync(true); - Assert.True(await cut.GetIsAllProjectsEnabledAsync()); - } - - } } From ef9cdde882748a6a4e060849b6c816faa6870eaf Mon Sep 17 00:00:00 2001 From: Abdelrahman Shawki Hassan Date: Fri, 20 Dec 2024 19:21:13 +0100 Subject: [PATCH 14/16] fix: invoke ls ready after serverInitalizedEvent --- .../Language/SnykLanguageClient.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Snyk.VisualStudio.Extension.2022/Language/SnykLanguageClient.cs b/Snyk.VisualStudio.Extension.2022/Language/SnykLanguageClient.cs index aa6e73b0..15d5007f 100644 --- a/Snyk.VisualStudio.Extension.2022/Language/SnykLanguageClient.cs +++ b/Snyk.VisualStudio.Extension.2022/Language/SnykLanguageClient.cs @@ -218,6 +218,9 @@ public Task OnServerInitializeFailedAsync(ILanguag public Task OnServerInitializedAsync() { + IsReady = true; + FireOnLanguageServerReadyAsyncEvent(); + SendPluginInstalledEvent(); Rpc.Disconnected += Rpc_Disconnected; return Task.CompletedTask; } @@ -246,9 +249,6 @@ public async Task AttachForCustomMessageAsync(JsonRpc rpc) Rpc.AllowModificationWhileListening = true; Rpc.ActivityTracingStrategy = null; Rpc.AllowModificationWhileListening = false; - IsReady = true; - FireOnLanguageServerReadyAsyncEvent(); - SendPluginInstalledEvent(); } protected void OnStopping() { } From d69b7b44917b68ca9acac4b507e74903e420e569 Mon Sep 17 00:00:00 2001 From: Abdelrahman Shawki Hassan Date: Fri, 20 Dec 2024 19:21:55 +0100 Subject: [PATCH 15/16] fix: handle persistence only in general dialog page --- .../Settings/ISnykCliOptionsDialogPage.cs | 1 + .../Settings/ISnykExperimentalDialogPage.cs | 1 + .../Settings/ISnykScanOptionsDialogPage.cs | 1 + .../ISnykSolutionOptionsDialogPage.cs | 1 + .../Settings/ISnykUserExperienceDialogPage.cs | 1 + .../Settings/SnykCliOptionsDialogPage.cs | 37 +-------- .../Settings/SnykExperimentalDialogPage.cs | 8 +- .../Settings/SnykGeneralOptionsDialogPage.cs | 83 +++++++++++++++++++ .../SnykGeneralSettingsUserControl.cs | 18 +++- .../Settings/SnykScanOptionsDialogPage.cs | 12 +-- .../Settings/SnykSolutionOptionsDialogPage.cs | 2 +- .../Settings/SnykUserExperienceDialogPage.cs | 7 +- .../SnykVSPackage.cs | 4 +- 13 files changed, 114 insertions(+), 62 deletions(-) diff --git a/Snyk.VisualStudio.Extension.2022/Settings/ISnykCliOptionsDialogPage.cs b/Snyk.VisualStudio.Extension.2022/Settings/ISnykCliOptionsDialogPage.cs index ddcbb5a8..f62a704d 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/ISnykCliOptionsDialogPage.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/ISnykCliOptionsDialogPage.cs @@ -5,4 +5,5 @@ namespace Snyk.VisualStudio.Extension.Settings; public interface ISnykCliOptionsDialogPage { void Initialize(ISnykServiceProvider provider); + SnykCliOptionsUserControl SnykCliOptionsUserControl { get; } } \ No newline at end of file diff --git a/Snyk.VisualStudio.Extension.2022/Settings/ISnykExperimentalDialogPage.cs b/Snyk.VisualStudio.Extension.2022/Settings/ISnykExperimentalDialogPage.cs index 557cbbdb..5a5c7452 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/ISnykExperimentalDialogPage.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/ISnykExperimentalDialogPage.cs @@ -5,4 +5,5 @@ namespace Snyk.VisualStudio.Extension.Settings; public interface ISnykExperimentalDialogPage { void Initialize(ISnykServiceProvider provider); + SnykExperimentalUserControl SnykExperimentalUserControl { get; } } \ No newline at end of file diff --git a/Snyk.VisualStudio.Extension.2022/Settings/ISnykScanOptionsDialogPage.cs b/Snyk.VisualStudio.Extension.2022/Settings/ISnykScanOptionsDialogPage.cs index 2a2024b0..af335949 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/ISnykScanOptionsDialogPage.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/ISnykScanOptionsDialogPage.cs @@ -5,4 +5,5 @@ namespace Snyk.VisualStudio.Extension.Settings; public interface ISnykScanOptionsDialogPage { void Initialize(ISnykServiceProvider provider); + SnykScanOptionsUserControl SnykScanOptionsUserControl { get; } } \ No newline at end of file diff --git a/Snyk.VisualStudio.Extension.2022/Settings/ISnykSolutionOptionsDialogPage.cs b/Snyk.VisualStudio.Extension.2022/Settings/ISnykSolutionOptionsDialogPage.cs index 61fcc6fc..a7441512 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/ISnykSolutionOptionsDialogPage.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/ISnykSolutionOptionsDialogPage.cs @@ -5,4 +5,5 @@ namespace Snyk.VisualStudio.Extension.Settings; public interface ISnykSolutionOptionsDialogPage { void Initialize(ISnykServiceProvider provider); + SnykSolutionOptionsUserControl SnykSolutionOptionsUserControl { get; } } \ No newline at end of file diff --git a/Snyk.VisualStudio.Extension.2022/Settings/ISnykUserExperienceDialogPage.cs b/Snyk.VisualStudio.Extension.2022/Settings/ISnykUserExperienceDialogPage.cs index f1549866..c9d996e0 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/ISnykUserExperienceDialogPage.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/ISnykUserExperienceDialogPage.cs @@ -5,4 +5,5 @@ namespace Snyk.VisualStudio.Extension.Settings; public interface ISnykUserExperienceDialogPage { void Initialize(ISnykServiceProvider provider); + SnykUserExperienceUserControl SnykUserExperienceUserControl { get; } } \ No newline at end of file diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsDialogPage.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsDialogPage.cs index 3861d404..cdb106f8 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsDialogPage.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsDialogPage.cs @@ -36,46 +36,11 @@ public SnykCliOptionsUserControl SnykCliOptionsUserControl // This method is used when the user clicks "Ok" public override void SaveSettingsToStorage() { - HandleCliDownload(); - this.serviceProvider.SnykOptionsManager.Save(this.snykOptions); + // do nothing } protected override void OnClosed(EventArgs e) { // do nothing } - - private void HandleCliDownload() - { - var memento = SnykCliOptionsUserControl.OptionsMemento; - - this.snykOptions.CliDownloadUrl = memento.CliDownloadUrl; - - var binariesAutoUpdateChanged = this.snykOptions.BinariesAutoUpdate != memento.BinariesAutoUpdate; - var releaseChannelChanged = this.snykOptions.CliReleaseChannel != memento.CliReleaseChannel; - var cliCustomPathChanged = this.snykOptions.CliCustomPath != memento.CliCustomPath; - - this.snykOptions.CurrentCliVersion = memento.CurrentCliVersion; - this.snykOptions.BinariesAutoUpdate = memento.BinariesAutoUpdate; - this.snykOptions.CliReleaseChannel = memento.CliReleaseChannel; - this.snykOptions.CliCustomPath = memento.CliCustomPath; - - var hasChanges = binariesAutoUpdateChanged || releaseChannelChanged || cliCustomPathChanged; - if (!hasChanges) - { - return; - } - - serviceProvider.TasksService.CancelTasks(); - - if (memento.BinariesAutoUpdate) - { - // DownloadStarted event stops language server and DownloadFinished starts it automatically - this.serviceProvider.TasksService.Download(); - } - else - { - LanguageClientHelper.LanguageClientManager().RestartServerAsync().FireAndForget(); - } - } } \ No newline at end of file diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykExperimentalDialogPage.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykExperimentalDialogPage.cs index 3038a3ca..5cc46421 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykExperimentalDialogPage.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykExperimentalDialogPage.cs @@ -2,7 +2,6 @@ using System.Runtime.InteropServices; using System.Windows.Forms; using Microsoft.VisualStudio.Shell; -using Snyk.VisualStudio.Extension.Language; using Snyk.VisualStudio.Extension.Service; namespace Snyk.VisualStudio.Extension.Settings; @@ -36,12 +35,7 @@ public SnykExperimentalUserControl SnykExperimentalUserControl // This method is used when the user clicks "Ok" public override void SaveSettingsToStorage() { - this.snykOptions.IgnoredIssuesEnabled = SnykExperimentalUserControl.OptionsMemento.IgnoredIssuesEnabled; - this.snykOptions.OpenIssuesEnabled = SnykExperimentalUserControl.OptionsMemento.OpenIssuesEnabled; - this.serviceProvider.SnykOptionsManager.Save(this.snykOptions); - - if (LanguageClientHelper.IsLanguageServerReady() && snykOptions.AutoScan) - LanguageClientHelper.LanguageClientManager().InvokeWorkspaceScanAsync(SnykVSPackage.Instance.DisposalToken).FireAndForget(); + // do nothing } protected override void OnClosed(EventArgs e) diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralOptionsDialogPage.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralOptionsDialogPage.cs index 756b85d2..4046b712 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralOptionsDialogPage.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralOptionsDialogPage.cs @@ -86,7 +86,90 @@ public SnykGeneralSettingsUserControl GeneralSettingsUserControl // This method is used when the user clicks "Ok" public override void SaveSettingsToStorage() { + HandleScanConfiguration(); + HandleExperimentalConfiguration(); + HandleUserExperienceConfiguration(); + HandleSolutionOptionsConfiguration(); + + var hasCliChanges = HandleCliConfiguration(); + this.serviceProvider.SnykOptionsManager.Save(this.SnykOptions); + + if (hasCliChanges) + { + HandleCliChange(); + return; + } + + if (LanguageClientHelper.IsLanguageServerReady() && this.SnykOptions.AutoScan) + LanguageClientHelper.LanguageClientManager().InvokeWorkspaceScanAsync(SnykVSPackage.Instance.DisposalToken).FireAndForget(); + } + + private void HandleSolutionOptionsConfiguration() + { + var memento = this.serviceProvider.Package.SnykSolutionOptionsDialogPage.SnykSolutionOptionsUserControl.AdditionalOptions; + if(memento != null) + this.serviceProvider.SnykOptionsManager.SaveAdditionalOptionsAsync(memento).FireAndForget(); + } + + private void HandleUserExperienceConfiguration() + { + var memento = this.serviceProvider.Package.SnykUserExperienceDialogPage.SnykUserExperienceUserControl.OptionsMemento; + + this.SnykOptions.AutoScan = memento.AutoScan; + } + + private void HandleExperimentalConfiguration() + { + var memento = this.serviceProvider.Package.SnykExperimentalDialogPage.SnykExperimentalUserControl.OptionsMemento; + + this.SnykOptions.IgnoredIssuesEnabled = memento.IgnoredIssuesEnabled; + this.SnykOptions.OpenIssuesEnabled = memento.OpenIssuesEnabled; + } + + private void HandleScanConfiguration() + { + var memento = this.serviceProvider.Package.SnykScanOptionsDialogPage.SnykScanOptionsUserControl.OptionsMemento; + + this.SnykOptions.EnableDeltaFindings = memento.EnableDeltaFindings; + this.SnykOptions.SnykCodeQualityEnabled = memento.SnykCodeQualityEnabled; + this.SnykOptions.SnykCodeSecurityEnabled = memento.SnykCodeSecurityEnabled; + this.SnykOptions.IacEnabled = memento.IacEnabled; + this.SnykOptions.OssEnabled = memento.OssEnabled; + } + + private bool HandleCliConfiguration() + { + var memento = this.serviceProvider.Package.SnykCliOptionsDialogPage.SnykCliOptionsUserControl.OptionsMemento; + + this.SnykOptions.CliDownloadUrl = memento.CliDownloadUrl; + + var binariesAutoUpdateChanged = this.SnykOptions.BinariesAutoUpdate != memento.BinariesAutoUpdate; + var releaseChannelChanged = this.SnykOptions.CliReleaseChannel != memento.CliReleaseChannel; + var cliCustomPathChanged = this.SnykOptions.CliCustomPath != memento.CliCustomPath; + + this.SnykOptions.CurrentCliVersion = memento.CurrentCliVersion; + this.SnykOptions.BinariesAutoUpdate = memento.BinariesAutoUpdate; + this.SnykOptions.CliReleaseChannel = memento.CliReleaseChannel; + this.SnykOptions.CliCustomPath = memento.CliCustomPath; + + var hasChanges = binariesAutoUpdateChanged || releaseChannelChanged || cliCustomPathChanged; + return hasChanges; + } + + private void HandleCliChange() + { + serviceProvider.TasksService.CancelTasks(); + + if (this.SnykOptions.BinariesAutoUpdate) + { + // DownloadStarted event stops language server and DownloadFinished starts it automatically + this.serviceProvider.TasksService.Download(); + } + else + { + LanguageClientHelper.LanguageClientManager().RestartServerAsync().FireAndForget(); + } } private void SnykGeneralOptionsDialogPage_SettingsChanged(object sender, SnykSettingsChangedEventArgs e) diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.cs index 887b9447..44ee39a6 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.cs @@ -37,10 +37,26 @@ public SnykGeneralSettingsUserControl(ISnykServiceProvider serviceProvider) { this.serviceProvider = serviceProvider; snykOptions = this.serviceProvider.Options; + this.Load += OnLoad; this.InitializeComponent(); this.Initialize(); } - + + private void OnLoad(object sender, EventArgs e) + { + CheckForIgnores(); + } + + private void CheckForIgnores() + { + ThreadHelper.JoinableTaskFactory.RunAsync(async () => + { + if (serviceProvider.Options.ApiToken.IsValid() && !serviceProvider.Options.ConsistentIgnoresEnabled && LanguageClientHelper.IsLanguageServerReady()) + await serviceProvider.FeatureFlagService.RefreshAsync(SnykVSPackage.Instance.DisposalToken); + await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); + }).FireAndForget(); + } + /// /// Initialize elements and actions. /// diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykScanOptionsDialogPage.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykScanOptionsDialogPage.cs index 958120c5..66ccf8ea 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykScanOptionsDialogPage.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykScanOptionsDialogPage.cs @@ -21,8 +21,8 @@ public void Initialize(ISnykServiceProvider provider) this.snykOptions = provider.Options; } - protected override IWin32Window Window => SnykCliOptionsUserControl; - public SnykScanOptionsUserControl SnykCliOptionsUserControl + protected override IWin32Window Window => SnykScanOptionsUserControl; + public SnykScanOptionsUserControl SnykScanOptionsUserControl { get { @@ -37,13 +37,7 @@ public SnykScanOptionsUserControl SnykCliOptionsUserControl // This method is used when the user clicks "Ok" public override void SaveSettingsToStorage() { - this.snykOptions.EnableDeltaFindings = SnykCliOptionsUserControl.OptionsMemento.EnableDeltaFindings; - this.snykOptions.SnykCodeQualityEnabled = SnykCliOptionsUserControl.OptionsMemento.SnykCodeQualityEnabled; - this.snykOptions.SnykCodeSecurityEnabled = SnykCliOptionsUserControl.OptionsMemento.SnykCodeSecurityEnabled; - this.snykOptions.IacEnabled = SnykCliOptionsUserControl.OptionsMemento.IacEnabled; - this.snykOptions.OssEnabled = SnykCliOptionsUserControl.OptionsMemento.OssEnabled; - - this.serviceProvider.SnykOptionsManager.Save(this.snykOptions); + // do nothing } protected override void OnClosed(EventArgs e) diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykSolutionOptionsDialogPage.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykSolutionOptionsDialogPage.cs index dcd5abd2..27f07c7e 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykSolutionOptionsDialogPage.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykSolutionOptionsDialogPage.cs @@ -40,7 +40,7 @@ public SnykSolutionOptionsUserControl SnykSolutionOptionsUserControl public override void SaveSettingsToStorage() { - this.serviceProvider.SnykOptionsManager.SaveAdditionalOptionsAsync(SnykSolutionOptionsUserControl.AdditionalOptions).FireAndForget(); + // do nothing } protected override void OnClosed(EventArgs e) diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykUserExperienceDialogPage.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykUserExperienceDialogPage.cs index 73951f59..2c7b4471 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykUserExperienceDialogPage.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykUserExperienceDialogPage.cs @@ -37,12 +37,7 @@ public SnykUserExperienceUserControl SnykUserExperienceUserControl // This method is used when the user clicks "Ok" public override void SaveSettingsToStorage() { - this.snykOptions.AutoScan = SnykUserExperienceUserControl.OptionsMemento.AutoScan; - this.serviceProvider.SnykOptionsManager.Save(this.snykOptions); - - if (LanguageClientHelper.IsLanguageServerReady() && this.snykOptions.AutoScan) - serviceProvider.LanguageClientManager.InvokeWorkspaceScanAsync(SnykVSPackage - .Instance.DisposalToken).FireAndForget(); + // do nothing } protected override void OnClosed(EventArgs e) diff --git a/Snyk.VisualStudio.Extension.2022/SnykVSPackage.cs b/Snyk.VisualStudio.Extension.2022/SnykVSPackage.cs index 6e8bbbff..9e6733ee 100644 --- a/Snyk.VisualStudio.Extension.2022/SnykVSPackage.cs +++ b/Snyk.VisualStudio.Extension.2022/SnykVSPackage.cs @@ -241,7 +241,7 @@ private async Task InitializeLanguageClientAsync() try { this.serviceProvider.LanguageClientManager.OnLanguageClientNotInitializedAsync += LanguageClientManagerOnLanguageClientNotInitializedAsync; - this.serviceProvider.LanguageClientManager.OnLanguageServerReadyAsync += LanguageClientManagerOnOnLanguageServerReadyAsync; + this.serviceProvider.LanguageClientManager.OnLanguageServerReadyAsync += LanguageClientManagerOnLanguageServerReadyAsync; if (!LanguageClientHelper.IsLanguageServerReady()) { // If CLI download is necessary, Skip initializing. @@ -258,7 +258,7 @@ private async Task InitializeLanguageClientAsync() } } - private async Task LanguageClientManagerOnOnLanguageServerReadyAsync(object sender, SnykLanguageServerEventArgs args) + private async Task LanguageClientManagerOnLanguageServerReadyAsync(object sender, SnykLanguageServerEventArgs args) { this.serviceProvider.FeatureFlagService.RefreshAsync(DisposalToken).FireAndForget(); // Sleep for three seconds before closing the temp window From 77ff37007a998102c792c948b033e82f2a6c4b24 Mon Sep 17 00:00:00 2001 From: Abdelrahman Shawki Hassan Date: Fri, 20 Dec 2024 19:23:23 +0100 Subject: [PATCH 16/16] fix: test --- .../Language/SnykLanguageClientTest.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Snyk.VisualStudio.Extension.Tests/Language/SnykLanguageClientTest.cs b/Snyk.VisualStudio.Extension.Tests/Language/SnykLanguageClientTest.cs index 5c448217..ff6dd6fb 100644 --- a/Snyk.VisualStudio.Extension.Tests/Language/SnykLanguageClientTest.cs +++ b/Snyk.VisualStudio.Extension.Tests/Language/SnykLanguageClientTest.cs @@ -99,7 +99,7 @@ public void Rpc_Disconnected_ShouldSetIsReadyToFalse() } [Fact] - public async Task AttachForCustomMessageAsync_ShouldSetRpcAndIsReady() + public async Task AttachForCustomMessageAsync_ShouldSetRpc() { // Arrange var rpc = new JsonRpc(new MemoryStream(), new MemoryStream()); @@ -108,7 +108,6 @@ public async Task AttachForCustomMessageAsync_ShouldSetRpcAndIsReady() await cut.AttachForCustomMessageAsync(rpc); // Assert - Assert.True(cut.IsReady); Assert.NotNull(cut.Rpc); Assert.Null(cut.Rpc.ActivityTracingStrategy); }