Skip to content

Commit

Permalink
chore: disable analytics & sentry when fedramp [HEAD-677] (#245)
Browse files Browse the repository at this point in the history
* chore: disable analytics & sentry when fedramp [HEAD-677]

* fix: tests

* chore: add isFedramp() check to Welcome Screen initialization.

* chore: only check for snykgov.io in isFedramp()

* chore: add tests for CreateProcess and its environment priming

* fix: stupid negation

* fix: remove update of analytics settings in customendpoint setting
  • Loading branch information
bastiandoetsch authored Sep 29, 2023
1 parent 85247e2 commit b004ef0
Show file tree
Hide file tree
Showing 10 changed files with 185 additions and 54 deletions.
2 changes: 2 additions & 0 deletions Snyk.Common/Settings/ISnykOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ public interface ISnykOptions
/// </summary>
AuthenticationToken ApiToken { get; }

bool IsFedramp();

/// <summary>
/// Gets or sets a value indicating whether CLI custom endpoint parameter.
/// </summary>
Expand Down
7 changes: 1 addition & 6 deletions Snyk.VisualStudio.Extension.Shared/CLI/SnykCli.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public class SnykCli : ICli
/// </summary>
public SnykCli(ISnykOptions options, string ideVersion = "")
{
this.ConsoleRunner = new SnykConsoleRunner(ideVersion);
this.ConsoleRunner = new SnykConsoleRunner(options, ideVersion);
this.options = options;
}

Expand Down Expand Up @@ -275,11 +275,6 @@ public async Task<string> BuildScanArgumentsAsync()
arguments.Add("--all-projects");
}

if (!this.Options.UsageAnalyticsEnabled)
{
arguments.Add("--DISABLE_ANALYTICS");
}

string cliOptions = string.Join(" ", arguments.ToArray());

Logger.Information("Result CLI options {CliOptions}", cliOptions);
Expand Down
13 changes: 11 additions & 2 deletions Snyk.VisualStudio.Extension.Shared/CLI/SnykConsoleRunner.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace Snyk.VisualStudio.Extension.Shared.CLI
using Snyk.Common.Settings;

namespace Snyk.VisualStudio.Extension.Shared.CLI
{
using System;
using System.Collections;
Expand All @@ -17,10 +19,12 @@ public class SnykConsoleRunner

private bool isStopped = false;
private readonly string ideVersion;
private readonly ISnykOptions options;

public SnykConsoleRunner(string ideVersion = "")
public SnykConsoleRunner(ISnykOptions options, string ideVersion = "")
{
this.ideVersion = ideVersion;
this.options = options;
}

/// <summary>
Expand Down Expand Up @@ -74,6 +78,11 @@ public virtual Process CreateProcess(string fileName, string arguments, StringDi
}
}

if (!this.options.UsageAnalyticsEnabled || this.options.IsFedramp())
{
processStartInfo.EnvironmentVariables["SNYK_CFG_DISABLE_ANALYTICS"] = "1";
}

processStartInfo.EnvironmentVariables["SNYK_INTEGRATION_NAME"] = SnykExtension.IntegrationName;
processStartInfo.EnvironmentVariables["SNYK_INTEGRATION_VERSION"] = SnykExtension.Version;
processStartInfo.EnvironmentVariables["SNYK_INTEGRATION_ENVIRONMENT_NAME"] = SnykExtension.IntegrationName;
Expand Down
25 changes: 21 additions & 4 deletions Snyk.VisualStudio.Extension.Shared/Service/SentryService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,34 @@ public async Task SetupAsync()
scope.SetTag("vs.version", vsVersion.ToString());
scope.SetTag("vs.edition", this.serviceProvider.DTE.Edition);
});

// disable sentry if no usage analytics or fedramp
if (!this.serviceProvider.Options.UsageAnalyticsEnabled || this.serviceProvider.Options.IsFedramp())
{
DiscardEventCallback();
}
}

/// <inheritdoc/>
public void SetSolutionType(SolutionType solutionType)
{
LogManager.SentryConfiguration.BeforeSend = sentryEvent =>
if (!this.serviceProvider.Options.UsageAnalyticsEnabled || this.serviceProvider.Options.IsFedramp())
{
DiscardEventCallback();
}
else
{
sentryEvent.SetTag("vs.project.type", solutionType.ToString());
LogManager.SentryConfiguration.BeforeSend = sentryEvent =>
{
sentryEvent.SetTag("vs.project.type", solutionType.ToString());
return sentryEvent;
};
}
}

return sentryEvent;
};
private static void DiscardEventCallback()
{
LogManager.SentryConfiguration.BeforeSend = _ => { return null; };
}
}
}
3 changes: 1 addition & 2 deletions Snyk.VisualStudio.Extension.Shared/Service/SnykService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,6 @@ private void SetupSnykCodeService()
Logger.Error(e, string.Empty);
}
}

private void InitializeAnalyticsService()
{
Logger.Information("Initialize Analytics Service...");
Expand All @@ -314,7 +313,7 @@ private void InitializeAnalyticsService()
this.Options.AnonymousId = anonymousId;
}

var enabled = this.Options.UsageAnalyticsEnabled;
var enabled = this.Options.UsageAnalyticsEnabled && !this.Options.IsFedramp();
var endpoint = this.ApiEndpointResolver.UserMeEndpoint;

Logger.Information("analytics enabled = {Enabled}, endpoint = {Endpoint}", enabled, endpoint);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,22 @@ private AuthenticationToken CreateAuthenticationToken(string token)
tokenObj.TokenRefresher = RefreshToken;
return tokenObj;
}

/// <summary>
/// Checks if the current endpoint is a fedramp endpoint
/// </summary>
/// <returns></returns>
public bool IsFedramp()
{
var endpoint = this.customEndpoint;
if (endpoint.IsNullOrEmpty())
{
return false;
}

var endpointUri = new Uri(endpoint);
return endpointUri.Host.ToLower().EndsWith("snykgov.io");
}

/// <summary>
/// Gets or sets a value indicating whether Custom endpoint.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -687,9 +687,11 @@ private void SnykToolWindow_Loaded(object sender, RoutedEventArgs e)
/// </summary>
private void ShowWelcomeOrRunScanScreen()
{
this.serviceProvider.AnalyticsService.AnalyticsEnabledOption = this.serviceProvider.Options.UsageAnalyticsEnabled;
var options = this.serviceProvider.Options;
this.serviceProvider.AnalyticsService.AnalyticsEnabledOption =
options.UsageAnalyticsEnabled && !options.IsFedramp();

if (this.serviceProvider.Options.ApiToken.IsValid())
if (options.ApiToken.IsValid())
{
this.context.TransitionTo(RunScanState.Instance);

Expand Down
66 changes: 31 additions & 35 deletions Snyk.VisualStudio.Extension.Tests/SnykCliTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ public SnykCliTest()
.Setup(options => options.UsageAnalyticsEnabled)
.Returns(true);

this.optionsMock
.Setup(options => options.IsFedramp())
.Returns(false);

this.optionsMock
.Setup(options => options.ApiToken)
.Returns(AuthenticationToken.EmptyToken);
Expand All @@ -33,7 +37,7 @@ public void SnykCliTest_CliReturnError_GetApiTokenThrowException()
{
var cli = new SnykCli(this.optionsMock.Object)
{
ConsoleRunner = new SnykMockConsoleRunner(""),
ConsoleRunner = new SnykMockConsoleRunner(this.optionsMock.Object, ""),
};

Assert.Throws<InvalidTokenException>(() => cli.GetApiTokenOrThrowException());
Expand Down Expand Up @@ -62,8 +66,8 @@ public async Task SnykCliTest_RunScan_SuccessfulCliResultAsync()
{
var cli = new SnykCli(this.optionsMock.Object)
{

ConsoleRunner = new SnykMockConsoleRunner(this.GetFileContent("VulnerabilitiesSingleObject.json")),
ConsoleRunner = new SnykMockConsoleRunner(optionsMock.Object,
this.GetFileContent("VulnerabilitiesSingleObject.json")),
};

var cliResult = await cli.ScanAsync(string.Empty);
Expand All @@ -78,8 +82,7 @@ public void SnykCliTest_GetApiToken_Successful()

var cli = new SnykCli(this.optionsMock.Object)
{

ConsoleRunner = new SnykMockConsoleRunner(testGuid),
ConsoleRunner = new SnykMockConsoleRunner(this.optionsMock.Object, testGuid),
};

Assert.Equal(testGuid, cli.GetApiToken());
Expand Down Expand Up @@ -177,28 +180,16 @@ public async Task SnykCliTest_BuildArguments_WithAllOptionsAsync()
.ReturnsAsync("--ignore-policy");

this.optionsMock
.Setup(options => options.IsScanAllProjectsAsync())
.ReturnsAsync(true);
.Setup(options => options.IsScanAllProjectsAsync())
.ReturnsAsync(true);

var cli = new SnykCli(this.optionsMock.Object);

Assert.Equal(
"--json test --insecure --org=test-snyk-organization --ignore-policy --all-projects --DISABLE_ANALYTICS",
"--json test --insecure --org=test-snyk-organization --ignore-policy --all-projects",
await cli.BuildScanArgumentsAsync());
}

[Fact]
public async Task SnykCliTest_BuildArguments_WithDisableAnalyticsAsync()
{
this.optionsMock
.Setup(options => options.UsageAnalyticsEnabled)
.Returns(false);

var cli = new SnykCli(this.optionsMock.Object);

Assert.Equal("--json test --DISABLE_ANALYTICS", await cli.BuildScanArgumentsAsync());
}

[Fact]
public void SnykCliTest_BuildEnvironmentVariables_WithAllOptions()
{
Expand All @@ -223,13 +214,13 @@ public void SnykCliTest_BuildEnvironmentVariables_WithAllOptions()
.ReturnsAsync("--ignore-policy");

this.optionsMock
.Setup(options => options.IsScanAllProjectsAsync())
.ReturnsAsync(true);
.Setup(options => options.IsScanAllProjectsAsync())
.ReturnsAsync(true);

var tokenMock = new AuthenticationToken(AuthenticationType.Token, Guid.NewGuid().ToString());
this.optionsMock
.Setup(options => options.ApiToken)
.Returns(tokenMock);
.Setup(options => options.ApiToken)
.Returns(tokenMock);

var cli = new SnykCli(this.optionsMock.Object);

Expand All @@ -243,8 +234,8 @@ public void SnykCliTest_BuildEnvironmentVariables_WithAllOptions()
public void SnykCliTest_BuildEnvironmentVariables_InvalidToken()
{
this.optionsMock
.Setup(options => options.ApiToken)
.Returns(AuthenticationToken.EmptyToken);
.Setup(options => options.ApiToken)
.Returns(AuthenticationToken.EmptyToken);

var cli = new SnykCli(this.optionsMock.Object);

Expand All @@ -256,10 +247,11 @@ public void SnykCliTest_BuildEnvironmentVariables_InvalidToken()
[Fact]
public void SnykCliTest_BuildEnvironmentVariables_OAuthToken()
{
var tokenMock = new AuthenticationToken(AuthenticationType.OAuth, "{\"access_token\":\"at\",\"token_type\":\"Bearer\",\"refresh_token\":\"rt\",\"expiry\":\"3023-04-13T19:07:08.8871+02:00\"}");
var tokenMock = new AuthenticationToken(AuthenticationType.OAuth,
"{\"access_token\":\"at\",\"token_type\":\"Bearer\",\"refresh_token\":\"rt\",\"expiry\":\"3023-04-13T19:07:08.8871+02:00\"}");
this.optionsMock
.Setup(options => options.ApiToken)
.Returns(tokenMock);
.Setup(options => options.ApiToken)
.Returns(tokenMock);

var cli = new SnykCli(this.optionsMock.Object);

Expand All @@ -273,8 +265,8 @@ public void SnykCliTest_BuildEnvironmentVariables_Token()
{
var tokenMock = new AuthenticationToken(AuthenticationType.Token, Guid.NewGuid().ToString());
this.optionsMock
.Setup(options => options.ApiToken)
.Returns(tokenMock);
.Setup(options => options.ApiToken)
.Returns(tokenMock);

var cli = new SnykCli(this.optionsMock.Object);

Expand Down Expand Up @@ -306,7 +298,8 @@ public void ConvertRawCliStringToCliResult_VulnerabilitiesArrayJson()
[Fact]
public void ConvertRawCliStringToCliResult_VulnerabilitiesSingleJson()
{
var cliResult = SnykCli.ConvertRawCliStringToCliResult(this.GetFileContent("VulnerabilitiesSingleObject.json"));
var cliResult =
SnykCli.ConvertRawCliStringToCliResult(this.GetFileContent("VulnerabilitiesSingleObject.json"));

Assert.Single(cliResult.CliVulnerabilitiesList);
}
Expand All @@ -318,7 +311,9 @@ public void ConvertRawCliStringToCliResult_ErrorJson()

Assert.NotNull(cliResult.Error);
Assert.False(cliResult.Error.IsSuccess);
Assert.Contains("Could not detect supported target files in C:\\Users\\Test\\Documents\\MultiProjectConsoleApplication.", cliResult.Error.Message);
Assert.Contains(
"Could not detect supported target files in C:\\Users\\Test\\Documents\\MultiProjectConsoleApplication.",
cliResult.Error.Message);
Assert.Equal("C:\\Users\\Test\\Documents\\MultiProjectConsoleApplication", cliResult.Error.Path);
}

Expand All @@ -331,7 +326,8 @@ public void SnykCliTest_ConvertRawCliStringToCliResult_PlainTextError()

Assert.NotNull(cliResult.Error);
Assert.False(cliResult.Error.IsSuccess);
Assert.Contains("Please see our documentation for supported languages and target files:", cliResult.Error.Message);
Assert.Contains("Please see our documentation for supported languages and target files:",
cliResult.Error.Message);
Assert.Equal(string.Empty, cliResult.Error.Path);
}

Expand Down Expand Up @@ -361,4 +357,4 @@ class MockServiceProvider : IServiceProvider
{
public object GetService(Type serviceType) => throw new NotImplementedException();
}
}
}
Loading

0 comments on commit b004ef0

Please sign in to comment.