Skip to content

Commit

Permalink
feat: OSS via LS [HEAD-78] (#393)
Browse files Browse the repository at this point in the history
* chore: read OSS settings for LS initialisation options
* feat: Language Server based OSS tree view (#386)
* feat: add new OSS (LS) panel in Snyk UI
* feat: configure new views and activation events for LS OSS treeview
* feat: Derive Vulnerability Count from LS results [HEAD-942] (#388)
* feat: enable LS based Vulnerability Count Service
* chore: remove dependency to old OSSService
* chore: cleanup redundant files [HEAD-1020] (#390)
* fix: show most severe vulnerability action is displayed (#402)

---------

Signed-off-by: Bastian Doetsch <[email protected]>
Co-authored-by: Peter Schäfer <[email protected]>
Co-authored-by: Bastian Doetsch <[email protected]>
  • Loading branch information
3 people authored Nov 29, 2023
1 parent 8c19751 commit 85c1a4c
Show file tree
Hide file tree
Showing 61 changed files with 1,403 additions and 1,989 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: CI
on:
pull_request:
branches:
- main
- '**'
workflow_call:
secrets:
ITERATIVELY_KEY:
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/release-preview.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ jobs:
- name: Verify analytics events
run: npm run ampli:verify -- -t ${{ secrets.ITERATIVELY_KEY }}

# Naming convention for the preview version means we can only release one preview per hour
- name: Patch to preview version
run: npm run patch-preview
env:
Expand Down
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
# Snyk Security - Code and Open Source Dependencies Changelog

## [2.1.0]

### Added

- Snyk LS: Snyk Open Source Security features now use Language Server backend
- Snyk OSS: Squiggly warning underlines for direct and transitive vulnerabilities
- Snyk OSS: Squiggly underlines colour coded based on severity
- Snyk OSS: Vulnerability count text includes transitive vulnerabilities
- Snyk OSS: Vulnerability count text includes breakdown of vulnerabilities by severity
- Snyk OSS: Hovers lists vulnerabilities and shows summary (without typo)
- Snyk OSS: Hovers show information from security.snyk.io/vuln database
- Snyk OSS: CodeActions shows actions available for all vulnerabilities

## [1.26.1]

### Fixed
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## Run extension and debug

Clone the repository, then run `npm install` in the directory.
Clone the repository, then run `npm install && npm run build` in the directory.

- Open repository directory in VS Code and press `F5` to run extension in a new VS Code window.
- This allows extension debugging within VS Code.
Expand Down
30 changes: 21 additions & 9 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,7 @@
"@types/babel__traverse": "^7.12.2",
"@types/find-package-json": "^1.2.2",
"@types/glob": "^7.1.3",
"@types/he": "^1.2.3",
"@types/lodash": "^4.14.161",
"@types/marked": "^3.0.0",
"@types/mocha": "^8.0.3",
Expand Down Expand Up @@ -441,6 +442,7 @@
"analytics-node": "^4.0.1",
"axios": "^0.27.2",
"glob": "^7.2.0",
"he": "^1.2.0",
"htmlparser2": "^7.2.0",
"http-proxy-agent": "^5.0.0",
"https-proxy-agent": "^5.0.0",
Expand Down
4 changes: 1 addition & 3 deletions src/snyk/base/modules/baseSnykModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { IMarkdownStringAdapter, MarkdownStringAdapter } from '../../common/vsco
import { IWatcher } from '../../common/watchers/interfaces';
import { ICodeSettings } from '../../snykCode/codeSettings';
import SnykEditorsWatcher from '../../snykCode/watchers/editorsWatcher';
import { OssService } from '../../snykOss/services/ossService';
import { OssService } from '../../snykOss/ossService';
import { OssVulnerabilityCountService } from '../../snykOss/services/vulnerabilityCount/ossVulnerabilityCountService';
import { IAuthenticationService } from '../services/authenticationService';
import { ScanModeService } from '../services/scanModeService';
Expand Down Expand Up @@ -85,6 +85,4 @@ export default abstract class BaseSnykModule implements IBaseSnykModule {
}

abstract runScan(): Promise<void>;

abstract runOssScan(): Promise<void>;
}
1 change: 0 additions & 1 deletion src/snyk/base/modules/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ export interface IBaseSnykModule {

// Abstract methods
runScan(): Promise<void>;
runOssScan(manual?: boolean): Promise<void>;
}

export interface ISnykLib {
Expand Down
34 changes: 1 addition & 33 deletions src/snyk/base/modules/snykLib.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import * as _ from 'lodash';
import { firstValueFrom } from 'rxjs';
import { CliError } from '../../cli/services/cliService';
import { SupportedAnalysisProperties } from '../../common/analytics/itly';
import { configuration } from '../../common/configuration/instance';
import { DEFAULT_SCAN_DEBOUNCE_INTERVAL, IDE_NAME, OSS_SCAN_DEBOUNCE_INTERVAL } from '../../common/constants/general';
import { DEFAULT_SCAN_DEBOUNCE_INTERVAL, IDE_NAME } from '../../common/constants/general';
import { SNYK_CONTEXT } from '../../common/constants/views';
import { ErrorHandler } from '../../common/error/errorHandler';
import { Logger } from '../../common/logger/logger';
Expand All @@ -23,7 +21,6 @@ export default class SnykLib extends BaseSnykModule implements ISnykLib {
return;
}

// Only starts OSS scan. Code & IaC scans are managed by LS
Logger.info('Starting full scan');

await this.contextService.setContext(SNYK_CONTEXT.AUTHENTICATING, false);
Expand All @@ -39,7 +36,6 @@ export default class SnykLib extends BaseSnykModule implements ISnykLib {
const workspacePaths = vsCodeWorkspace.getWorkspaceFolders();
if (workspacePaths.length) {
this.logFullAnalysisIsTriggered(manual);
void this.startOssAnalysis(manual, false);
}
} catch (err) {
await ErrorHandler.handleGlobal(err, Logger, this.contextService, this.loadingBadge);
Expand All @@ -48,11 +44,8 @@ export default class SnykLib extends BaseSnykModule implements ISnykLib {

// This function is called by commands, error handlers, etc.
// We should avoid having duplicate parallel executions.
// Only starts OSS scan. Code & IaC scans are managed by LS
public runScan = _.debounce(this.runFullScan_.bind(this), DEFAULT_SCAN_DEBOUNCE_INTERVAL, { leading: true });

public runOssScan = _.debounce(this.startOssAnalysis.bind(this), OSS_SCAN_DEBOUNCE_INTERVAL, { leading: true });

async enableCode(): Promise<void> {
Logger.info('Enabling Snyk Code');
const wasEnabled = await this.codeSettings.enable();
Expand All @@ -66,12 +59,6 @@ export default class SnykLib extends BaseSnykModule implements ISnykLib {
}
}

onDidChangeOssTreeVisibility(visible: boolean): void {
if (this.ossService) {
this.ossService.setVulnerabilityTreeVisibility(visible);
}
}

async checkAdvancedMode(): Promise<void> {
await this.contextService.setContext(SNYK_CONTEXT.ADVANCED, configuration.shouldShowAdvancedView);
}
Expand All @@ -81,25 +68,6 @@ export default class SnykLib extends BaseSnykModule implements ISnykLib {
await this.contextService.setContext(SNYK_CONTEXT.WORKSPACE_FOUND, workspaceFound);
}

private async startOssAnalysis(manual = false, reportTriggeredEvent = true): Promise<void> {
if (!configuration.getFeaturesConfiguration()?.ossEnabled) return;
if (!this.ossService) throw new Error('OSS service is not initialized.');

// wait until Snyk Language Server is downloaded
await firstValueFrom(this.downloadService.downloadReady$);

try {
const result = await this.ossService.test(manual, reportTriggeredEvent);

if (result instanceof CliError || !result) {
return;
}
} catch (err) {
// catch unhandled error cases by reporting test failure
this.ossService.finalizeTest(new CliError(err));
}
}

private isSnykCodeAutoscanSuspended(manual: boolean) {
return !manual && !this.scanModeService.isCodeAutoScanAllowed();
}
Expand Down
3 changes: 2 additions & 1 deletion src/snyk/cli/process.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { ChildProcessWithoutNullStreams, spawn } from 'child_process';
import { OAuthToken } from '../base/services/authenticationService';
import { Configuration, IConfiguration } from '../common/configuration/configuration';
import { ILog } from '../common/logger/interfaces';
import { getVsCodeProxy } from '../common/proxy';
import { IVSCodeWorkspace } from '../common/vscode/workspace';
import { CLI_INTEGRATION_NAME } from './contants/integration';
import { CliError } from './services/cliService';
import { OAuthToken } from '../base/services/authenticationService';

export class CliProcess {
private runningProcess: ChildProcessWithoutNullStreams | null;
Expand All @@ -25,6 +25,7 @@ export class CliProcess {
return new Promise((resolve, reject) => {
let output = '';

// file deepcode ignore ArrayMethodOnNonArray: readonly string[] is an array of strings
this.logger.info(`Running "${cliPath} ${args.join(' ')}".`);

this.runningProcess = spawn(cliPath, args, { env: { ...process.env, ...processEnv }, cwd });
Expand Down
30 changes: 21 additions & 9 deletions src/snyk/common/commands/commandController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@
import _ from 'lodash';
import { IAuthenticationService } from '../../base/services/authenticationService';
import { ScanModeService } from '../../base/services/scanModeService';
import { createDCIgnore } from '../../snykCode/utils/ignoreFileUtils';
import { createDCIgnore as createDCIgnoreUtil } from '../../snykCode/utils/ignoreFileUtils';
import { IssueUtils } from '../../snykCode/utils/issueUtils';
import { CodeIssueCommandArg } from '../../snykCode/views/interfaces';
import { IacIssueCommandArg } from '../../snykIac/views/interfaces';
import { capitalizeOssSeverity } from '../../snykOss/ossResult';
import { OssService } from '../../snykOss/services/ossService';
import { OssIssueCommandArg } from '../../snykOss/views/ossVulnerabilityTreeProvider';
import { OssService } from '../../snykOss/ossService';
import { IAnalytics } from '../analytics/itly';
import {
SNYK_INITIATE_LOGIN_COMMAND,
Expand Down Expand Up @@ -90,11 +88,11 @@ export class CommandController {
const paths = this.workspace.getWorkspaceFolders();
const promises = [];
for (const p of paths) {
promises.push(createDCIgnore(p, custom, this.workspace, this.window, uriAdapter));
promises.push(createDCIgnoreUtil(p, custom, this.workspace, this.window, uriAdapter));
}
await Promise.all(promises);
} else {
await createDCIgnore(path, custom, this.workspace, this.window, uriAdapter);
await createDCIgnoreUtil(path, custom, this.workspace, this.window, uriAdapter);
}
}

Expand Down Expand Up @@ -122,14 +120,28 @@ export class CommandController {
severity: IssueUtils.issueSeverityAsText(issue.severity),
});
} else if (arg.issueType == OpenCommandIssueType.OssVulnerability) {
const issue = arg.issue as OssIssueCommandArg;
void this.ossService.showSuggestionProvider(issue);
const issueArgs = arg.issue as CodeIssueCommandArg;
const folderPath = issueArgs.folderPath;
const issue = this.ossService.getIssue(folderPath, issueArgs.id);

if (!issue) {
this.logger.warn(`Failed to find the issue ${issueArgs.id}.`);
return;
}

await this.openLocalFile(issue.filePath, issueArgs.range);

try {
await this.ossService.showSuggestionProvider(folderPath, issueArgs.id);
} catch (e) {
ErrorHandler.handle(e, this.logger);
}

this.analytics.logIssueInTreeIsClicked({
ide: IDE_NAME,
issueId: issue.id,
issueType: 'Open Source Vulnerability',
severity: capitalizeOssSeverity(issue.severity),
severity: IssueUtils.issueSeverityAsText(issue.severity),
});
} else if (arg.issueType == OpenCommandIssueType.IacIssue) {
const issueArgs = arg.issue as IacIssueCommandArg;
Expand Down
11 changes: 2 additions & 9 deletions src/snyk/common/commands/types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { completeFileSuggestionType } from '../../snykCode/interfaces';
import { CodeIssueCommandArg } from '../../snykCode/views/interfaces';
import { IacIssueCommandArg } from '../../snykIac/views/interfaces';
import { OssIssueCommandArg } from '../../snykOss/views/ossVulnerabilityTreeProvider';
import { OssIssueCommandArg } from '../../snykOss/interfaces';
import { CodeIssueData, Issue } from '../languageServer/types';

export enum OpenCommandIssueType {
Expand All @@ -11,7 +11,7 @@ export enum OpenCommandIssueType {
}

export type OpenIssueCommandArg = {
issue: CodeIssueCommandArg | OssIssueCommandArg | IacIssueCommandArg;
issue: CodeIssueCommandArg | IacIssueCommandArg | OssIssueCommandArg;
issueType: OpenCommandIssueType;
};

Expand All @@ -21,10 +21,3 @@ export const isCodeIssue = (
): _issue is Issue<CodeIssueData> => {
return issueType === OpenCommandIssueType.CodeIssue;
};

export const isOssIssue = (
_issue: completeFileSuggestionType | Issue<CodeIssueData> | OssIssueCommandArg,
issueType: OpenCommandIssueType,
): _issue is OssIssueCommandArg => {
return issueType === OpenCommandIssueType.OssVulnerability;
};
1 change: 0 additions & 1 deletion src/snyk/common/constants/general.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ export const IDE_NAME_SHORT = 'vscode';
export const COMMAND_DEBOUNCE_INTERVAL = 200; // 200 milliseconds
export const DEFAULT_SCAN_DEBOUNCE_INTERVAL = 1000; // 1 second
export const DEFAULT_LS_DEBOUNCE_INTERVAL = 1000; // 1 second
export const OSS_SCAN_DEBOUNCE_INTERVAL = 10000; // 10 seconds
export const EXECUTION_THROTTLING_INTERVAL = 1000 * 10; // * 60 * 30; // 30 minutes
export const EXECUTION_PAUSE_INTERVAL = 1000 * 60 * 30; // 30 minutes
export const REFRESH_VIEW_DEBOUNCE_INTERVAL = 200; // 200 milliseconds
Expand Down
Loading

0 comments on commit 85c1a4c

Please sign in to comment.