Skip to content

Commit

Permalink
feat: only send analytics when connected to an MT US environment
Browse files Browse the repository at this point in the history
Co-authored-by: acke <[email protected]>
  • Loading branch information
chdorner-snyk and acke committed Jan 5, 2024
1 parent 19eaecf commit b0f4a16
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 10 deletions.
4 changes: 2 additions & 2 deletions src/snyk/common/analytics/itly.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export class Iteratively implements IAnalytics {
private readonly user: User,
private logger: ILog,
private shouldReportEvents: boolean,
private isFedramp: boolean,
private analyticsPermitted: boolean,
private isDevelopment: boolean,
private snykConfiguration?: SnykConfiguration,
) {}
Expand All @@ -75,7 +75,7 @@ export class Iteratively implements IAnalytics {
}

load(): Iteratively | null {
if (!this.shouldReportEvents || this.isFedramp) {
if (!this.shouldReportEvents || !this.analyticsPermitted) {
this.logger.debug(`Analytics are disabled. No analytics will be collected.`);
return null;
}
Expand Down
10 changes: 10 additions & 0 deletions src/snyk/common/configuration/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ export interface IConfiguration {

isFedramp: boolean;

analyticsPermitted: boolean;

severityFilter: SeverityFilter;

scanningMode: string | undefined;
Expand All @@ -120,6 +122,7 @@ export class Configuration implements IConfiguration {
private readonly defaultAuthHost = 'https://snyk.io';
private readonly defaultOssApiEndpoint = `${this.defaultAuthHost}/api/v1`;
private readonly defaultBaseApiHost = 'https://api.snyk.io';
private readonly analyticsPermittedEnvironments = { 'app.snyk.io': true, 'app.us.snyk.io': true };

constructor(private processEnv: NodeJS.ProcessEnv = process.env, private workspace: IVSCodeWorkspace) {}

Expand Down Expand Up @@ -206,6 +209,13 @@ export class Configuration implements IConfiguration {
return isFedrampDomain;
}

get analyticsPermitted(): boolean {
if (!this.customEndpoint) return true;

const hostname = new URL(this.customEndpoint).hostname;
return hostname in this.analyticsPermittedEnvironments

Check failure on line 216 in src/snyk/common/configuration/configuration.ts

View workflow job for this annotation

GitHub Actions / Build and Test (ubuntu-latest)

Insert `;`
}

get snykOssApiEndpoint(): string {
if (this.customEndpoint) {
return this.customEndpoint; // E.g. https://app.eu.snyk.io/api
Expand Down
2 changes: 1 addition & 1 deletion src/snyk/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ class SnykExtension extends SnykLib implements IExtension {
this.user,
Logger,
configuration.shouldReportEvents,
configuration.isFedramp,
configuration.analyticsPermitted,
configuration.isDevelopment,
snykConfiguration,
);
Expand Down
28 changes: 21 additions & 7 deletions src/test/unit/common/analytics/itly.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ suite('Iteratively', () => {
const isDevelopment = false;

suite('.load()', () => {
suite('when connecting to FEDRAMP endpoints', () => {
const isFedramp = true;
suite('when analytics are not permitted', () => {
const analyticsPermitted = false;
[true, false].forEach(shouldReportEvents => {
test(`Returns "null" when shouldReportEvents == ${shouldReportEvents}`, () => {
const iteratively = new Iteratively(
new User(),
new LoggerMock(),
shouldReportEvents,
isFedramp,
analyticsPermitted,
isDevelopment,
snykConfig,
);
Expand All @@ -29,19 +29,33 @@ suite('Iteratively', () => {
});
});

suite('when connecting to non-FEDRAMP endpoints', () => {
const isFedramp = false;
suite('when analytics are permitted', () => {
const analyticsPermitted = true;

test('Returns "null" when shouldReportEvents == false', () => {
const iteratively = new Iteratively(new User(), new LoggerMock(), false, isFedramp, isDevelopment, snykConfig);
const iteratively = new Iteratively(
new User(),
new LoggerMock(),
false,
analyticsPermitted,
isDevelopment,
snykConfig,
);

const result = iteratively.load();

strictEqual(result, null);
});

test('Returns "Iteratively" when shouldReportEvents == true', () => {
const iteratively = new Iteratively(new User(), new LoggerMock(), true, isFedramp, isDevelopment, snykConfig);
const iteratively = new Iteratively(
new User(),
new LoggerMock(),
true,
analyticsPermitted,
isDevelopment,
snykConfig,
);

const result = iteratively.load();

Expand Down
41 changes: 41 additions & 0 deletions src/test/unit/common/configuration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -229,4 +229,45 @@ suite('Configuration', () => {
strictEqual(configuration.isFedramp, false);
});
});

suite('.analyticsPermitted()', () => {
test('returns true when no custom endpoint configured', () => {
const workspace = stubWorkspaceConfiguration(ADVANCED_CUSTOM_ENDPOINT, undefined);

const configuration = new Configuration({}, workspace);
strictEqual(configuration.analyticsPermitted, true);
});

test('returns true for app.snyk.io', () => {
const customEndpoint = 'https://app.snyk.io';
const workspace = stubWorkspaceConfiguration(ADVANCED_CUSTOM_ENDPOINT, customEndpoint);

const configuration = new Configuration({}, workspace);
strictEqual(configuration.analyticsPermitted, true);
});

test('returns true for app.us.snyk.io', () => {
const customEndpoint = 'https://app.us.snyk.io';
const workspace = stubWorkspaceConfiguration(ADVANCED_CUSTOM_ENDPOINT, customEndpoint);

const configuration = new Configuration({}, workspace);
strictEqual(configuration.analyticsPermitted, true);
});

test('returns false for app.snykgov.io', () => {
const customEndpoint = 'https://app.snykgov.io';
const workspace = stubWorkspaceConfiguration(ADVANCED_CUSTOM_ENDPOINT, customEndpoint);

const configuration = new Configuration({}, workspace);
strictEqual(configuration.analyticsPermitted, false);
});

test('returns false for app.eu.snyk.io', () => {
const customEndpoint = 'https://app.eu.snyk.io';
const workspace = stubWorkspaceConfiguration(ADVANCED_CUSTOM_ENDPOINT, customEndpoint);

const configuration = new Configuration({}, workspace);
strictEqual(configuration.analyticsPermitted, false);
});
});
});

0 comments on commit b0f4a16

Please sign in to comment.