diff --git a/Snyk.VisualStudio.Extension.2022/BranchSelectorDialogWindow.xaml.cs b/Snyk.VisualStudio.Extension.2022/BranchSelectorDialogWindow.xaml.cs index 81a313581..e801508d3 100644 --- a/Snyk.VisualStudio.Extension.2022/BranchSelectorDialogWindow.xaml.cs +++ b/Snyk.VisualStudio.Extension.2022/BranchSelectorDialogWindow.xaml.cs @@ -51,8 +51,9 @@ 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); this.CloseDialog(); } diff --git a/Snyk.VisualStudio.Extension.2022/Language/LsSettings.cs b/Snyk.VisualStudio.Extension.2022/Language/LsSettings.cs index a30286f3f..fb30a4e8d 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 b1d42cd0c..15d5007f8 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 @@ -217,14 +218,17 @@ public Task OnServerInitializeFailedAsync(ILanguag public Task OnServerInitializedAsync() { + IsReady = true; + FireOnLanguageServerReadyAsyncEvent(); + SendPluginInstalledEvent(); Rpc.Disconnected += Rpc_Disconnected; 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"; @@ -245,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() { } diff --git a/Snyk.VisualStudio.Extension.2022/Language/SnykLanguageClientCustomTarget.cs b/Snyk.VisualStudio.Extension.2022/Language/SnykLanguageClientCustomTarget.cs index 99d4d9aeb..fed705e9e 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,7 @@ public async Task OnFolderConfig(JToken arg) var folderConfigs = arg.TryParse(); if (folderConfigs == null) return; serviceProvider.Options.FolderConfigs = folderConfigs.FolderConfigs; + serviceProvider.SnykOptionsManager.Save(serviceProvider.Options); } [JsonRpcMethod(LsConstants.SnykHasAuthenticated)] @@ -121,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)) @@ -133,10 +131,14 @@ 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); - serviceProvider.FeatureFlagService.RefreshAsync(SnykVSPackage.Instance.DisposalToken).FireAndForget(); + if (!serviceProvider.Options.ApiToken.IsValid()) + return; + + serviceProvider.FeatureFlagService.RefreshAsync(SnykVSPackage.Instance.DisposalToken).FireAndForget(); if (serviceProvider.Options.AutoScan) { await serviceProvider.TasksService.ScanAsync(); @@ -150,7 +152,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 41fcb0790..01d16dda3 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. /// @@ -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 3112722f0..54ae7ee1b 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; @@ -101,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; } } @@ -167,7 +162,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 a51b638ad..6a9c4b251 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.Options.BinariesAutoUpdate) { return false; } @@ -751,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()); @@ -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 53cdd2dc5..f814da61a 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/IUserStorageSettingsService.cs b/Snyk.VisualStudio.Extension.2022/Settings/IPersistableOption.cs similarity index 53% rename from Snyk.VisualStudio.Extension.2022/Settings/IUserStorageSettingsService.cs rename to Snyk.VisualStudio.Extension.2022/Settings/IPersistableOption.cs index b2c66c738..7d74f4b3a 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/IUserStorageSettingsService.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/IPersistableOption.cs @@ -1,74 +1,78 @@ 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 +public interface IPersistableOptions { - void SaveSettings(); - bool BinariesAutoUpdate { get; set; } - string CliCustomPath { get; set; } - AuthenticationType AuthenticationMethod { get; set; } + string DeviceId { get; set; } + bool AutoScan { get; set; } + + bool OpenIssuesEnabled { get; set; } + bool IgnoredIssuesEnabled { get; set; } /// - /// Gets or sets trusted folders list. + /// Gets or sets a value indicating whether Snyk user API token. /// - ISet TrustedFolders { get; set; } + AuthenticationToken ApiToken { get; set; } /// - /// Get Auto Scan option + /// Gets Value of Authentication Token Type. /// - /// bool. - bool AutoScan { get; set; } + AuthenticationType AuthenticationMethod { get; set; } + + /// + /// Gets or sets a value indicating whether CLI custom endpoint parameter. + /// + string CustomEndpoint { get; set; } /// - /// Get Or Set Auth Token + /// Gets a value indicating whether Snyk Code settings URL. /// - /// string. - string Token { get; set; } + string SnykCodeSettingsUrl { get; } - string CliReleaseChannel { get; set; } - string CliDownloadUrl { get; set; } - bool IgnoreUnknownCa { get; set; } + /// + /// Gets or sets a value indicating whether CLI organization parameter. + /// string Organization { get; set; } - string CustomEndpoint { get; set; } - bool SnykCodeSecurityEnabled { get; set; } - bool SnykCodeQualityEnabled { 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; } - 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. + /// Gets a value indicating whether is Oss scan enabled. /// - /// Bool. - Task GetIsAllProjectsEnabledAsync(); + bool SnykCodeSecurityEnabled { get; set; } /// - /// Get CLI additional options string. + /// Gets a value indicating whether is Oss scan enabled. /// - /// string. - Task GetAdditionalOptionsAsync(); + bool SnykCodeQualityEnabled { get; set; } /// - /// Save additional options string. + /// Gets or sets a value indicating whether the CLI should be automatically updated. /// - /// CLI options string. - /// A representing the asynchronous operation. - Task SaveAdditionalOptionsAsync(string additionalOptions); + bool BinariesAutoUpdate { get; set; } /// - /// Sace is all projects scan enabled. + /// Gets or sets the value of the CLI custom path. If empty, the default path from AppData would be used. /// - /// Bool param. - /// A representing the asynchronous operation. - Task SaveIsAllProjectsScanEnabledAsync(bool isAllProjectsEnabled); + 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/ISnykCliOptionsDialogPage.cs b/Snyk.VisualStudio.Extension.2022/Settings/ISnykCliOptionsDialogPage.cs new file mode 100644 index 000000000..f62a704dc --- /dev/null +++ b/Snyk.VisualStudio.Extension.2022/Settings/ISnykCliOptionsDialogPage.cs @@ -0,0 +1,9 @@ +using Snyk.VisualStudio.Extension.Service; + +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 new file mode 100644 index 000000000..5a5c74527 --- /dev/null +++ b/Snyk.VisualStudio.Extension.2022/Settings/ISnykExperimentalDialogPage.cs @@ -0,0 +1,9 @@ +using Snyk.VisualStudio.Extension.Service; + +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/ISnykOptions.cs b/Snyk.VisualStudio.Extension.2022/Settings/ISnykOptions.cs index fe1e05c76..81232e1e6 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,13 @@ public interface ISnykOptions string IntegrationVersion { get; } string IntegrationEnvironment { get; set; } string IntegrationEnvironmentVersion { get; set; } - - string DeviceId { get; set; } - bool AutoScan { 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 000000000..fba33fa57 --- /dev/null +++ b/Snyk.VisualStudio.Extension.2022/Settings/ISnykOptionsManager.cs @@ -0,0 +1,25 @@ +using System.Threading.Tasks; + +namespace Snyk.VisualStudio.Extension.Settings; + +public interface ISnykOptionsManager +{ + void LoadSettingsFromFile(); + void SaveSettingsToFile(); + ISnykOptions Load(); + void Save(IPersistableOptions options); + + /// + /// Get CLI additional options string. + /// + /// string. + Task GetAdditionalOptionsAsync(); + + /// + /// Save additional options string. + /// + /// 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/ISnykScanOptionsDialogPage.cs b/Snyk.VisualStudio.Extension.2022/Settings/ISnykScanOptionsDialogPage.cs new file mode 100644 index 000000000..af3359492 --- /dev/null +++ b/Snyk.VisualStudio.Extension.2022/Settings/ISnykScanOptionsDialogPage.cs @@ -0,0 +1,9 @@ +using Snyk.VisualStudio.Extension.Service; + +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 new file mode 100644 index 000000000..a74415121 --- /dev/null +++ b/Snyk.VisualStudio.Extension.2022/Settings/ISnykSolutionOptionsDialogPage.cs @@ -0,0 +1,9 @@ +using Snyk.VisualStudio.Extension.Service; + +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 new file mode 100644 index 000000000..c9d996e00 --- /dev/null +++ b/Snyk.VisualStudio.Extension.2022/Settings/ISnykUserExperienceDialogPage.cs @@ -0,0 +1,9 @@ +using Snyk.VisualStudio.Extension.Service; + +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 new file mode 100644 index 000000000..cdb106f87 --- /dev/null +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsDialogPage.cs @@ -0,0 +1,46 @@ +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("D1D89CEB-7691-4A67-8579-4C3DDE776982")] +[ComVisible(true)] +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; + } + 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() + { + // do nothing + } + + protected override void OnClosed(EventArgs e) + { + // do nothing + } +} \ 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 000000000..74d2e4594 --- /dev/null +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsUserControl.Designer.cs @@ -0,0 +1,239 @@ +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(803, 339); + 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(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); + 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; + this.manageBinariesAutomaticallyCheckbox.CheckedChanged += new System.EventHandler(this.manageBinariesAutomaticallyCheckbox_CheckedChanged); + // + // 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(803, 339); + 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 000000000..77c8a1855 --- /dev/null +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsUserControl.cs @@ -0,0 +1,86 @@ +using System.Collections.Generic; +using System.Diagnostics; +using System.Windows.Forms; +using Snyk.VisualStudio.Extension.CLI; +using Snyk.VisualStudio.Extension.Service; + +namespace Snyk.VisualStudio.Extension.Settings +{ + public partial class SnykCliOptionsUserControl : UserControl + { + private readonly ISnykServiceProvider serviceProvider; + public ISnykOptions OptionsMemento { get; set; } + + public SnykCliOptionsUserControl(ISnykServiceProvider serviceProvider) + { + this.serviceProvider = serviceProvider; + OptionsMemento = serviceProvider.SnykOptionsManager.Load(); + InitializeComponent(); + this.Initialize(); + } + private void Initialize() + { + this.UpdateViewFromOptions(); + } + + private void UpdateViewFromOptions() + { + this.manageBinariesAutomaticallyCheckbox.Checked = OptionsMemento.BinariesAutoUpdate; + this.cliDownloadUrlTextBox.Text = OptionsMemento.CliDownloadUrl; + + var cliPath = string.IsNullOrEmpty(OptionsMemento.CliCustomPath) + ? SnykCli.GetSnykCliDefaultPath() + : OptionsMemento.CliCustomPath; + + this.CliPathTextBox.Text = cliPath; + if (releaseChannel.DataSource == null) + { + this.releaseChannel.DataSource = ReleaseChannelList(); + } + + this.releaseChannel.SelectedItem = OptionsMemento.CliReleaseChannel; + } + + private IEnumerable ReleaseChannelList() + { + var defaultList = new List() { "stable", "rc", "preview" }; + if (!defaultList.Contains(OptionsMemento.CliReleaseChannel)) + { + defaultList.Add(OptionsMemento.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) + { + OptionsMemento.CliCustomPath = selectedCliPath; + this.CliPathTextBox.Text = string.IsNullOrEmpty(OptionsMemento.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"); + } + private void manageBinariesAutomaticallyCheckbox_CheckedChanged(object sender, System.EventArgs e) + { + OptionsMemento.BinariesAutoUpdate = manageBinariesAutomaticallyCheckbox.Checked; + } + } +} diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsUserControl.resx b/Snyk.VisualStudio.Extension.2022/Settings/SnykCliOptionsUserControl.resx new file mode 100644 index 000000000..1e62546b3 --- /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/SnykExperimentalDialogPage.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykExperimentalDialogPage.cs new file mode 100644 index 000000000..5cc464215 --- /dev/null +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykExperimentalDialogPage.cs @@ -0,0 +1,45 @@ +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("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() + { + // do nothing + } + + 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 000000000..58d8eb31f --- /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 000000000..0752b1295 --- /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.ApiToken.IsValid() && !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 000000000..1af7de150 --- /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 625862459..4046b7124 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralOptionsDialogPage.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralOptionsDialogPage.cs @@ -86,32 +86,90 @@ public SnykGeneralSettingsUserControl GeneralSettingsUserControl // This method is used when the user clicks "Ok" public override void SaveSettingsToStorage() { - HandleCliDownload(); - this.SnykOptions.SaveSettings(); - this.SnykOptions.InvokeSettingsChangedEvent(); - } + HandleScanConfiguration(); + HandleExperimentalConfiguration(); + HandleUserExperienceConfiguration(); + HandleSolutionOptionsConfiguration(); - private void HandleCliDownload() - { - var releaseChannel = generalSettingsUserControl.GetReleaseChannel().Trim(); - var downloadUrl = generalSettingsUserControl.GetCliDownloadUrl().Trim(); - var manageBinariesAutomatically = generalSettingsUserControl.GetManageBinariesAutomatically(); - if (!manageBinariesAutomatically) + var hasCliChanges = HandleCliConfiguration(); + + this.serviceProvider.SnykOptionsManager.Save(this.SnykOptions); + + if (hasCliChanges) { - this.SnykOptions.CurrentCliVersion = string.Empty; - this.SnykOptions.BinariesAutoUpdate = false; - serviceProvider.TasksService.CancelDownloadTask(); - // Language Server restart will happen on DownloadCancelled Event. + HandleCliChange(); return; } - if (this.SnykOptions.CliReleaseChannel != releaseChannel || this.SnykOptions.CliDownloadUrl != downloadUrl || this.SnykOptions.BinariesAutoUpdate != manageBinariesAutomatically) + + 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) { - this.SnykOptions.CliDownloadUrl = downloadUrl; - this.SnykOptions.CliReleaseChannel = releaseChannel; - this.SnykOptions.BinariesAutoUpdate = manageBinariesAutomatically; - serviceProvider.TasksService.CancelDownloadTask(); + // 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) @@ -122,9 +180,6 @@ private void SnykGeneralOptionsDialogPage_SettingsChanged(object sender, SnykSet { await serviceProvider.LanguageClientManager.DidChangeConfigurationAsync(SnykVSPackage .Instance.DisposalToken); - 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 0de34f581..3da1433dc 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,56 +42,19 @@ 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.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(); - 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); 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(); // @@ -131,6 +93,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 // @@ -179,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); @@ -236,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); @@ -304,297 +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]"; - // - // 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 - // - 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, 709); - 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, 955); - 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 // @@ -615,88 +245,15 @@ 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(789, 449); this.mainPanel.TabIndex = 20; // // SnykGeneralSettingsUserControl @@ -705,20 +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, 1041); + 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.ExecutablesGroupBox.ResumeLayout(false); - this.ExecutablesGroupBox.PerformLayout(); this.mainPanel.ResumeLayout(false); this.ResumeLayout(false); @@ -735,49 +283,16 @@ 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; - 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; - 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 0c4eb93e6..44ee39a64 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.cs @@ -13,9 +13,7 @@ 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 { @@ -31,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. /// @@ -45,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. /// @@ -56,9 +64,8 @@ private void Initialize() { Logger.Information("Enter Initialize method"); - this.UpdateViewFromOptionsDialog(); + this.UpdateViewFromOptions(); snykOptions.SettingsChanged += this.OptionsDialogPageOnSettingsChanged; - this.Load += this.SnykGeneralSettingsUserControl_Load; if (LanguageClientHelper.LanguageClientManager() != null) { @@ -81,35 +88,13 @@ 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; this.organizationTextBox.Text = snykOptions.Organization; 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(); - } if (authType.SelectedIndex == -1) { @@ -117,10 +102,8 @@ 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,27 +119,11 @@ 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"}; - return defaultList; - } - private void OptionsDialogPageOnSettingsChanged(object sender, SnykSettingsChangedEventArgs e) => ThreadHelper.JoinableTaskFactory.RunAsync(async () => { await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); - this.UpdateViewFromOptionsDialog(); + this.UpdateViewFromOptions(); }).FireAndForget(); public async Task HandleAuthenticationSuccess(string apiToken, string apiUrl) @@ -192,16 +159,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"); @@ -248,18 +205,20 @@ 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); - } + 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)) { - snykOptions.CustomEndpoint = this.customEndpointTextBox.Text; + 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) @@ -305,209 +264,23 @@ 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; 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; - 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; - } - - 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) - { - snykOptions.OpenIssuesEnabled = this.cbOpenIssues.Checked; + if(LanguageClientHelper.IsLanguageServerReady()) + LanguageClientHelper.LanguageClientManager().DidChangeConfigurationAsync(SnykVSPackage.Instance.DisposalToken).FireAndForget(); } - private void cbIgnoredIssues_CheckedChanged(object sender, EventArgs e) - { - snykOptions.IgnoredIssuesEnabled = this.cbIgnoredIssues.Checked; - } - private void cbDelta_SelectionChangeCommitted(object sender, EventArgs e) + private void organizationTextBox_TextChanged(object sender, EventArgs e) { - if (this.cbDelta.SelectedItem == null) - return; - var enableDelta = this.cbDelta.SelectedItem.ToString() == "Net new issues"; - snykOptions.EnableDeltaFindings = enableDelta; + snykOptions.Organization = organizationTextBox.Text; } public Panel GetPanel() diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.resx b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.resx index e89510c3e..6eaada4b8 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.resx +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykGeneralSettingsUserControl.resx @@ -120,52 +120,9 @@ 17, 17 - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO - vAAADrwBlbxySQAAALxJREFUOE/dUzEOwjAQyz9Y+FnzAV7Aa/hHpYiFNW+AqYKhYsl6nKu4So5DgNiw - 5OV8tprUCSLSsZQSlUkphpjFoGj3V6i4VeZ0vsswTrI5XDpiBg072O0CqnneHa9PRsv96YaQmSEMyBDs - MmHnNSTTHPFpdgkkPK0eJyIgeWd+R3jgRYC7ABKeBsL7JwEvL5HwtPYSf/uNtQvZayFh512RVEfAUmWv - jZZtldeAJuTjx7SYAQYQKn7xnCU8ABJO2R9gGis+AAAAAElFTkSuQmCC - - 140, 17 - - 477, 17 - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO - vAAADrwBlbxySQAAALxJREFUOE/dUzEOwjAQyz9Y+FnzAV7Aa/hHpYiFNW+AqYKhYsl6nKu4So5DgNiw - 5OV8tprUCSLSsZQSlUkphpjFoGj3V6i4VeZ0vsswTrI5XDpiBg072O0CqnneHa9PRsv96YaQmSEMyBDs - MmHnNSTTHPFpdgkkPK0eJyIgeWd+R3jgRYC7ABKeBsL7JwEvL5HwtPYSf/uNtQvZayFh512RVEfAUmWv - jZZtldeAJuTjx7SYAQYQKn7xnCU8ABJO2R9gGis+AAAAAElFTkSuQmCC - - - - 270, 17 - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO - vAAADrwBlbxySQAAALxJREFUOE/dUzEOwjAQyz9Y+FnzAV7Aa/hHpYiFNW+AqYKhYsl6nKu4So5DgNiw - 5OV8tprUCSLSsZQSlUkphpjFoGj3V6i4VeZ0vsswTrI5XDpiBg072O0CqnneHa9PRsv96YaQmSEMyBDs - MmHnNSTTHPFpdgkkPK0eJyIgeWd+R3jgRYC7ABKeBsL7JwEvL5HwtPYSf/uNtQvZayFh512RVEfAUmWv - jZZtldeAJuTjx7SYAQYQKn7xnCU8ABJO2R9gGis+AAAAAElFTkSuQmCC - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO - vAAADrwBlbxySQAAALxJREFUOE/dUzEOwjAQyz9Y+FnzAV7Aa/hHpYiFNW+AqYKhYsl6nKu4So5DgNiw - 5OV8tprUCSLSsZQSlUkphpjFoGj3V6i4VeZ0vsswTrI5XDpiBg072O0CqnneHa9PRsv96YaQmSEMyBDs - MmHnNSTTHPFpdgkkPK0eJyIgeWd+R3jgRYC7ABKeBsL7JwEvL5HwtPYSf/uNtQvZayFh512RVEfAUmWv - jZZtldeAJuTjx7SYAQYQKn7xnCU8ABJO2R9gGis+AAAAAElFTkSuQmCC - - 270, 17 diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykOptions.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykOptions.cs index 6be2f72b4..781e54e77 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,38 @@ 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 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 +49,6 @@ public string GetCustomApiEndpoint() { return string.IsNullOrEmpty(CustomEndpoint) ? ApiEndpointResolver.DefaultApiEndpoint : ApiEndpointResolver.TranslateOldApiToNewApiEndpoint(CustomEndpoint); } - public string GetBaseAppUrl() { if (string.IsNullOrEmpty(CustomEndpoint)) @@ -354,10 +58,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 000000000..ca29139ae --- /dev/null +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykOptionsManager.cs @@ -0,0 +1,159 @@ +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 SnykSettingsLoader settingsLoader; + private SnykSettings snykSettings; + private static readonly ILogger Logger = LogManager.ForContext(); + + public SnykOptionsManager(string settingsFilePath, ISnykServiceProvider serviceProvider) + { + this.serviceProvider = serviceProvider; + 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 ISnykOptions Load() + { + return new SnykOptions + { + 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) + { + snykSettings.DeviceId = options.DeviceId; + snykSettings.TrustedFolders = options.TrustedFolders; + snykSettings.AnalyticsPluginInstalledSent = options.AnalyticsPluginInstalledSent; + snykSettings.AutoScan = options.AutoScan; + snykSettings.IgnoreUnknownCa = options.IgnoreUnknownCA; + + snykSettings.BinariesAutoUpdateEnabled = options.BinariesAutoUpdate; + snykSettings.CustomCliPath = options.CliCustomPath; + snykSettings.CliDownloadUrl = options.CliDownloadUrl; + snykSettings.CliReleaseChannel = options.CliReleaseChannel; + snykSettings.CurrentCliVersion = options.CurrentCliVersion; + + snykSettings.AuthenticationMethod = options.AuthenticationMethod; + snykSettings.Token = options.ApiToken.ToString(); + + snykSettings.CustomEndpoint = options.CustomEndpoint; + snykSettings.Organization = options.Organization; + + snykSettings.FolderConfigs = options.FolderConfigs; + snykSettings.EnableDeltaFindings = options.EnableDeltaFindings; + + snykSettings.OpenIssuesEnabled = options.OpenIssuesEnabled; + snykSettings.IgnoredIssuesEnabled = options.IgnoredIssuesEnabled; + + snykSettings.IacEnabled = options.IacEnabled; + snykSettings.SnykCodeQualityEnabled = options.SnykCodeQualityEnabled; + snykSettings.SnykCodeSecurityEnabled = options.SnykCodeSecurityEnabled; + snykSettings.OssEnabled = options.OssEnabled; + + this.SaveSettingsToFile(); + serviceProvider.Options.InvokeSettingsChangedEvent(); + } + + /// + /// 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.SaveSettingsToFile(); + + Logger.Information("Leave SaveAdditionalOptions method"); + } + + private async Task GetSolutionPathHashAsync() => + (await this.serviceProvider.SolutionService.GetSolutionFolderAsync()).ToLower().GetHashCode(); + } +} diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykScanOptionsDialogPage.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykScanOptionsDialogPage.cs new file mode 100644 index 000000000..66ccf8ea0 --- /dev/null +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykScanOptionsDialogPage.cs @@ -0,0 +1,48 @@ +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("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 => SnykScanOptionsUserControl; + public SnykScanOptionsUserControl SnykScanOptionsUserControl + { + get + { + if (snykScanOptionsUserControl == null) + { + snykScanOptionsUserControl = new SnykScanOptionsUserControl(serviceProvider); + } + return snykScanOptionsUserControl; + } + } + + // This method is used when the user clicks "Ok" + public override void SaveSettingsToStorage() + { + // do nothing + } + + 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 000000000..7c872a38f --- /dev/null +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykScanOptionsUserControl.Designer.cs @@ -0,0 +1,288 @@ +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.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.mainPanel.SuspendLayout(); + this.productSelectionGroupBox.SuspendLayout(); + this.SuspendLayout(); + // + // mainPanel + // + this.mainPanel.AutoScroll = true; + this.mainPanel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.mainPanel.Controls.Add(this.productSelectionGroupBox); + 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.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); + // + // 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); + // + // 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.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.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; + } +} diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykScanOptionsUserControl.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykScanOptionsUserControl.cs new file mode 100644 index 000000000..fed4776fc --- /dev/null +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykScanOptionsUserControl.cs @@ -0,0 +1,194 @@ +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 = serviceProvider.SnykOptionsManager.Load(); + InitializeComponent(); + Initialize(); + } + + 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(); + } + + 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() || !serviceProvider.Options.ApiToken.IsValid()) 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; + + 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 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 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 000000000..a82683b1b --- /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 b6b145070..af270a9f0 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/SnykSolutionOptionsDialogPage.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykSolutionOptionsDialogPage.cs index 1bda1a112..27f07c7e3 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() + { + // do nothing + } + + protected override void OnClosed(EventArgs e) + { + // do nothing + } } } diff --git a/Snyk.VisualStudio.Extension.2022/Settings/SnykSolutionOptionsUserControl.Designer.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykSolutionOptionsUserControl.Designer.cs index 2c7ff8ffb..baa5da0e3 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 2d6ba8a08..bef56ea48 100644 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykSolutionOptionsUserControl.cs +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykSolutionOptionsUserControl.cs @@ -13,10 +13,8 @@ public partial class SnykSolutionOptionsUserControl : UserControl { private static readonly ILogger Logger = LogManager.ForContext(); - private ISnykServiceProvider serviceProvider; - - private IUserStorageSettingsService userStorageSettingsService; - + private readonly ISnykServiceProvider serviceProvider; + public string AdditionalOptions { get; set; } /// /// Initializes a new instance of the class. /// @@ -26,42 +24,13 @@ public SnykSolutionOptionsUserControl(ISnykServiceProvider serviceProvider) this.InitializeComponent(); this.serviceProvider = serviceProvider; - this.userStorageSettingsService = serviceProvider.UserStorageSettingsService; - } - - 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()) { - string additionalOptions = this.additionalOptionsTextBox.Text; - - this.userStorageSettingsService.SaveAdditionalOptionsAsync(additionalOptions).FireAndForget(); - - this.CheckOptionConflicts(); - } - } - - private void AllProjectsCheckBox_CheckedChanged(object sender, EventArgs e) - { - if (this.serviceProvider.SolutionService.IsSolutionOpen()) - { - this.userStorageSettingsService.SaveIsAllProjectsScanEnabledAsync(this.allProjectsCheckBox.Checked).FireAndForget(); - - this.CheckOptionConflicts(); + AdditionalOptions = this.additionalOptionsTextBox.Text; } } @@ -72,7 +41,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) { @@ -81,7 +49,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)) { @@ -98,23 +66,6 @@ private void SnykProjectOptionsUserControl_Load(object sender, EventArgs eventAr this.additionalOptionsTextBox.Text = string.Empty; } - - try - { - bool isChecked = await this.userStorageSettingsService.GetIsAllProjectsEnabledAsync(); - - this.allProjectsCheckBox.Checked = isChecked; - } - catch (Exception e) - { - Logger.Error(e, "Error on load is all projects enabled"); - - this.allProjectsCheckBox.Checked = false; - - await this.userStorageSettingsService.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 000000000..2c7b44713 --- /dev/null +++ b/Snyk.VisualStudio.Extension.2022/Settings/SnykUserExperienceDialogPage.cs @@ -0,0 +1,47 @@ +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() + { + // do nothing + } + + 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 000000000..990b72f0b --- /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 000000000..dcace701a --- /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 000000000..1af7de150 --- /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/Settings/SnykUserStorageSettingsService.cs b/Snyk.VisualStudio.Extension.2022/Settings/SnykUserStorageSettingsService.cs deleted file mode 100644 index 6fd92692c..000000000 --- a/Snyk.VisualStudio.Extension.2022/Settings/SnykUserStorageSettingsService.cs +++ /dev/null @@ -1,294 +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; set; } - - 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) - { - 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) - { - 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 912053d75..441f1c30c 100644 --- a/Snyk.VisualStudio.Extension.2022/Snyk.VisualStudio.Extension.2022.csproj +++ b/Snyk.VisualStudio.Extension.2022/Snyk.VisualStudio.Extension.2022.csproj @@ -145,9 +145,33 @@ + + + - + + + + + + Component + + + UserControl + + + SnykCliOptionsUserControl.cs + + + Component + + + UserControl + + + SnykExperimentalUserControl.cs + Component @@ -158,6 +182,16 @@ SnykGeneralSettingsUserControl.cs + + + Component + + + UserControl + + + SnykScanOptionsUserControl.cs + @@ -171,7 +205,15 @@ SnykSolutionOptionsUserControl.cs - + + Component + + + UserControl + + + SnykUserExperienceUserControl.cs + SnykIcons.resx @@ -573,13 +615,25 @@ + + SnykCliOptionsUserControl.cs + + + SnykExperimentalUserControl.cs + SnykGeneralSettingsUserControl.cs Designer + + SnykScanOptionsUserControl.cs + 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 eab48c8a8..9e6733ee6 100644 --- a/Snyk.VisualStudio.Extension.2022/SnykVSPackage.cs +++ b/Snyk.VisualStudio.Extension.2022/SnykVSPackage.cs @@ -50,9 +50,13 @@ 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(SnykSolutionOptionsDialogPage), "Snyk", "Solution settings", 1000, 1002, true)] - public sealed class SnykVSPackage : AsyncPackage, ISnykOptionsProvider + [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 { /// /// SnykVSPackage GUID string. @@ -102,6 +106,11 @@ public void SetServiceProvider(ISnykServiceProvider serviceProvider) /// public ISnykOptions Options { get; private set; } 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; } + public ISnykSolutionOptionsDialogPage SnykSolutionOptionsDialogPage { get; private set; } /// /// Gets instance. @@ -182,7 +191,7 @@ protected override async Task InitializeAsync(CancellationToken cancellationToke Logger.Information("Get SnykService as ServiceProvider."); Logger.Information("Start InitializeGeneralOptionsAsync."); - await InitializeGeneralOptionsAsync(); + await InitializeOptionsAsync(); // Initialize LS @@ -232,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. @@ -249,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 @@ -302,13 +311,13 @@ private async Task LanguageClientManagerOnLanguageClientNotInitializedAsync(obje }).FireAndForget(); } - private async Task InitializeGeneralOptionsAsync() + private async Task InitializeOptionsAsync() { + await JoinableTaskFactory.SwitchToMainThreadAsync(); + if (Options == null) { - Logger.Information( - "Call GetDialogPage to create. await JoinableTaskFactory.SwitchToMainThreadAsync()."); - Options = new SnykOptions(this.serviceProvider); + Options = serviceProvider.SnykOptionsManager.Load(); var readableVsVersion = await this.GetReadableVsVersionAsync(); var vsMajorMinorVersion = await this.GetVsMajorMinorVersionAsync(); Options.Application = readableVsVersion; @@ -319,15 +328,46 @@ 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); } + + if (SnykCliOptionsDialogPage == null) + { + await JoinableTaskFactory.SwitchToMainThreadAsync(); + + SnykCliOptionsDialogPage = + (SnykCliOptionsDialogPage)GetDialogPage(typeof(SnykCliOptionsDialogPage)); + SnykCliOptionsDialogPage.Initialize(this.serviceProvider); + } + + if (SnykScanOptionsDialogPage == null) + { + SnykScanOptionsDialogPage = + (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); + } + if (SnykSolutionOptionsDialogPage == null) + { + SnykSolutionOptionsDialogPage = + (SnykSolutionOptionsDialogPage)GetDialogPage(typeof(SnykSolutionOptionsDialogPage)); + SnykSolutionOptionsDialogPage.Initialize(this.serviceProvider); + } } private async Task GetVsVersionAsync() @@ -386,10 +426,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 d9440a57e..6397d7f33 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 9d68a4e63..780d2a446 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,10 +39,10 @@ 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); - + optionsMock.SetupAllProperties(); cut = new SnykLanguageClientCustomTarget(serviceProviderMock.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 65cc28d5c..ff6dd6fba 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); @@ -98,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()); @@ -107,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); } diff --git a/Snyk.VisualStudio.Extension.Tests/PackageBaseTest.cs b/Snyk.VisualStudio.Extension.Tests/PackageBaseTest.cs index 872c809d9..75d0e3b5e 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 1b7d9e000..82e70c310 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(); + optionsMock.Setup(x => x.TrustedFolders).Returns(new HashSet()); + 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 f3af7bc62..b2c72417c 100644 --- a/Snyk.VisualStudio.Extension.Tests/SnykOptionsTest.cs +++ b/Snyk.VisualStudio.Extension.Tests/SnykOptionsTest.cs @@ -19,8 +19,8 @@ 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)); - cut = new SnykOptions(serviceProvider); + serviceProviderMock.Setup(x => x.SnykOptionsManager).Returns(new SnykOptionsManager(settingsFilePath, serviceProvider)); + cut = new SnykOptions(); } [Theory] diff --git a/Snyk.VisualStudio.Extension.Tests/SnykUserStorageSettingsServiceTest.cs b/Snyk.VisualStudio.Extension.Tests/SnykUserStorageSettingsServiceTest.cs index 6d798089b..60e84e932 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; @@ -8,31 +9,110 @@ namespace Snyk.VisualStudio.Extension.Tests { /// - /// Test case for . + /// Test case for . /// - public class SnykUserStorageSettingsServiceTest + public class SnykOptionsManagerTest { - [Fact] - public async Task SnykUserStorageSettingsService_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); + var optionsMock = new Mock(); + optionsMock.Setup(x => x.InvokeSettingsChangedEvent()); + serviceProviderMock.Setup(x => x.Options).Returns(optionsMock.Object); + } + [Fact] + public async Task ProjectNameNotExists_SaveAdditionalOptionsSuccessfullAsync() + { solutionServiceMock .Setup(solutionService => solutionService.GetSolutionFolderAsync()) .ReturnsAsync("C:\\Projects\\TestProj"); - string settingsFilePath = Path.GetTempFileName(); - var userStorageSettingsService = new SnykUserStorageSettingsService(settingsFilePath, serviceProviderMock.Object); + await cut.SaveAdditionalOptionsAsync("--test-command"); + + Assert.Equal("--test-command", await cut.GetAdditionalOptionsAsync()); + } + + [Fact] + public void LoadAndSaveGeneralOptions_PersistsChanges() + { + // Load default + var options = cut.Load(); + // 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; + + cut.Save(options); + + // Reload to confirm persistence + var reloadedOptions = cut.Load(); + + 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"); - await userStorageSettingsService.SaveAdditionalOptionsAsync("--test-command"); + // Save initial options + await cut.SaveAdditionalOptionsAsync("--first-command"); + Assert.Equal("--first-command", await cut.GetAdditionalOptionsAsync()); - Assert.Equal("--test-command", await userStorageSettingsService.GetAdditionalOptionsAsync()); + // Overwrite with new options + await cut.SaveAdditionalOptionsAsync("--second-command"); + Assert.Equal("--second-command", await cut.GetAdditionalOptionsAsync()); } } } diff --git a/Snyk.VisualStudio.Extension.Tests/TestUtils.cs b/Snyk.VisualStudio.Extension.Tests/TestUtils.cs index bd2db8e49..37e2b502c 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"); } }