Skip to content

Commit

Permalink
refactor: use issues from diagnostics [IDE-538] (#506)
Browse files Browse the repository at this point in the history
* refactor: use issues from diagnostics
  • Loading branch information
ShawkyZ authored Aug 8, 2024
1 parent a73d3ee commit 167062f
Show file tree
Hide file tree
Showing 14 changed files with 86 additions and 5 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# Snyk Security Changelog

## [2.17.0]
## [2.16.2]
- updated the language server protocol version to 14 to support new communication model.

## [2.16.1]
- updated the language server protocol version to 13 to support delta findings.
- added setting for choosing authentication method
- renamed vulnerabilities to issues
Expand Down
2 changes: 1 addition & 1 deletion src/snyk/common/constants/languageServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Language Server name, used e.g. for the output channel
export const SNYK_LANGUAGE_SERVER_NAME = 'Snyk Language Server';
// The internal language server protocol version for custom messages and configuration
export const PROTOCOL_VERSION = 13;
export const PROTOCOL_VERSION = 14;

// LS protocol methods (needed for not having to rely on vscode dependencies in testing)
export const DID_CHANGE_CONFIGURATION_METHOD = 'workspace/didChangeConfiguration';
Expand Down
7 changes: 7 additions & 0 deletions src/snyk/common/languageServer/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ export enum ScanProduct {
InfrastructureAsCode = 'iac',
}

export enum LsScanProduct {
Code = 'Snyk Code',
OpenSource = 'Snyk Open Source',
InfrastructureAsCode = 'Snyk IaC',
Unknown = '',
}

export type InProgress = 'inProgress';

export enum ScanStatus {
Expand Down
44 changes: 44 additions & 0 deletions src/snyk/common/services/diagnosticsService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import * as vscode from 'vscode';
import { Issue, LsScanProduct, ScanProduct } from '../languageServer/types';

// This is a workaround until the LanguageClient package adds data to the Diagnostic type
// according to https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic
// Since 3.16 the property data was introduced
class Diagnostic316<T> extends vscode.Diagnostic {
data: Issue<T>;
}

export interface IDiagnosticsIssueProvider<T> {
getIssuesFromDiagnostics(product: ScanProduct): Issue<T>[];
}

export class DiagnosticsIssueProvider<T> implements IDiagnosticsIssueProvider<T> {
getIssuesFromDiagnostics(product: ScanProduct): Issue<T>[] {
const allDiagnostics = vscode.languages.getDiagnostics();
const diagnosticsSource = this.productToLsProduct(product);

// Filter and flatten the diagnostics list
// Also filter only when diagnostic.data exists
const filteredDiagnostics = allDiagnostics.flatMap(([_, diagnostics]) => {
return diagnostics.filter(
(diagnostic): diagnostic is Diagnostic316<T> =>
diagnostic.source === diagnosticsSource && diagnostic.hasOwnProperty('data'),
);
});
const issues = filteredDiagnostics.map(diagnostic => diagnostic.data);
return issues;
}

private productToLsProduct(product: ScanProduct): LsScanProduct {
switch (product) {
case ScanProduct.Code:
return LsScanProduct.Code;
case ScanProduct.InfrastructureAsCode:
return LsScanProduct.InfrastructureAsCode;
case ScanProduct.OpenSource:
return LsScanProduct.OpenSource;
default:
return LsScanProduct.Unknown;
}
}
}
5 changes: 4 additions & 1 deletion src/snyk/common/services/productService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { ExtensionContext } from '../vscode/extensionContext';
import { IVSCodeLanguages } from '../vscode/languages';
import { Disposable } from '../vscode/types';
import { IVSCodeWorkspace } from '../vscode/workspace';
import { IDiagnosticsIssueProvider } from './diagnosticsService';

export type WorkspaceFolderResult<T> = Issue<T>[] | Error;
export type ProductResult<T> = Map<string, WorkspaceFolderResult<T>>; // map of a workspace folder to results array or an error occurred in this folder
Expand Down Expand Up @@ -50,6 +51,7 @@ export abstract class ProductService<T> extends AnalysisStatusProvider implement
private readonly workspaceTrust: IWorkspaceTrust,
readonly languageServer: ILanguageServer,
readonly languages: IVSCodeLanguages,
readonly diagnosticsIssueProvider: IDiagnosticsIssueProvider<T>,
private readonly logger: ILog,
) {
super();
Expand Down Expand Up @@ -166,7 +168,8 @@ export abstract class ProductService<T> extends AnalysisStatusProvider implement
this.runningScanCount--;

if (scanMsg.status == ScanStatus.Success) {
this._result.set(scanMsg.folderPath, scanMsg.issues);
const issues = this.diagnosticsIssueProvider.getIssuesFromDiagnostics(scanMsg.product);
this._result.set(scanMsg.folderPath, issues);
} else {
this._result.set(scanMsg.folderPath, new Error('Failed to analyze.'));
}
Expand Down
5 changes: 5 additions & 0 deletions src/snyk/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ import { OssVulnerabilityCountProvider } from './snykOss/providers/ossVulnerabil
import OssIssueTreeProvider from './snykOss/providers/ossVulnerabilityTreeProvider';
import { OssVulnerabilityCountService } from './snykOss/services/vulnerabilityCount/ossVulnerabilityCountService';
import { FeatureFlagService } from './common/services/featureFlagService';
import { DiagnosticsIssueProvider } from './common/services/diagnosticsService';
import { CodeIssueData, IacIssueData, OssIssueData, ScanProduct } from './common/languageServer/types';

Check warning on line 80 in src/snyk/extension.ts

View workflow job for this annotation

GitHub Actions / build / Build and Test (ubuntu-latest)

'ScanProduct' is defined but never used. Allowed unused vars must match /^_/u

Check warning on line 80 in src/snyk/extension.ts

View workflow job for this annotation

GitHub Actions / build / Build and Test (macos-latest)

'ScanProduct' is defined but never used. Allowed unused vars must match /^_/u

Check warning on line 80 in src/snyk/extension.ts

View workflow job for this annotation

GitHub Actions / build / Build and Test (windows-latest)

'ScanProduct' is defined but never used. Allowed unused vars must match /^_/u

class SnykExtension extends SnykLib implements IExtension {
public async activate(vscodeContext: vscode.ExtensionContext): Promise<void> {
Expand Down Expand Up @@ -183,6 +185,7 @@ class SnykExtension extends SnykLib implements IExtension {
this.workspaceTrust,
this.languageServer,
vsCodeLanguages,
new DiagnosticsIssueProvider<CodeIssueData>(),
Logger,
);

Expand All @@ -205,6 +208,7 @@ class SnykExtension extends SnykLib implements IExtension {
this.workspaceTrust,
this.languageServer,
vsCodeLanguages,
new DiagnosticsIssueProvider<OssIssueData>(),
Logger,
);

Expand All @@ -227,6 +231,7 @@ class SnykExtension extends SnykLib implements IExtension {
this.workspaceTrust,
this.languageServer,
vsCodeLanguages,
new DiagnosticsIssueProvider<IacIssueData>(),
Logger,
);

Expand Down
3 changes: 3 additions & 0 deletions src/snyk/snykCode/codeService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { IVSCodeLanguages } from '../common/vscode/languages';
import { IVSCodeWorkspace } from '../common/vscode/workspace';
import { SnykCodeActionsProvider } from './codeActions/codeIssuesActionsProvider';
import { ICodeSuggestionWebviewProvider } from './views/interfaces';
import { IDiagnosticsIssueProvider } from '../common/services/diagnosticsService';

export class SnykCodeService extends ProductService<CodeIssueData> {
public readonly productType = ScanProduct.Code;
Expand All @@ -27,6 +28,7 @@ export class SnykCodeService extends ProductService<CodeIssueData> {
workspaceTrust: IWorkspaceTrust,
languageServer: ILanguageServer,
languages: IVSCodeLanguages,
readonly diagnosticsIssueProvider: IDiagnosticsIssueProvider<CodeIssueData>,
logger: ILog,
) {
super(
Expand All @@ -38,6 +40,7 @@ export class SnykCodeService extends ProductService<CodeIssueData> {
workspaceTrust,
languageServer,
languages,
diagnosticsIssueProvider,
logger,
);

Expand Down
3 changes: 3 additions & 0 deletions src/snyk/snykIac/iacService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { IVSCodeLanguages } from '../common/vscode/languages';
import { IVSCodeWorkspace } from '../common/vscode/workspace';
import { IacCodeActionsProvider } from './codeActions/iacCodeActionsProvider';
import { IIacSuggestionWebviewProvider } from './views/interfaces';
import { IDiagnosticsIssueProvider } from '../common/services/diagnosticsService';

export class IacService extends ProductService<IacIssueData> {
public readonly productType = ScanProduct.InfrastructureAsCode;
Expand All @@ -27,6 +28,7 @@ export class IacService extends ProductService<IacIssueData> {
workspaceTrust: IWorkspaceTrust,
languageServer: ILanguageServer,
languages: IVSCodeLanguages,
readonly diagnosticsIssueProvider: IDiagnosticsIssueProvider<IacIssueData>,
logger: ILog,
) {
super(
Expand All @@ -38,6 +40,7 @@ export class IacService extends ProductService<IacIssueData> {
workspaceTrust,
languageServer,
languages,
diagnosticsIssueProvider,
logger,
);

Expand Down
5 changes: 4 additions & 1 deletion src/snyk/snykOss/ossService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Subscription } from 'rxjs';
import { IConfiguration } from '../common/configuration/configuration';
import { IWorkspaceTrust } from '../common/configuration/trustedFolders';
import { ILanguageServer } from '../common/languageServer/languageServer';
import { OssIssueData, Scan, ScanProduct } from '../common/languageServer/types';
import { CodeIssueData, OssIssueData, Scan, ScanProduct } from '../common/languageServer/types';
import { ILog } from '../common/logger/interfaces';
import { ProductService } from '../common/services/productService';
import { IViewManagerService } from '../common/services/viewManagerService';
Expand All @@ -12,6 +12,7 @@ import { IVSCodeLanguages } from '../common/vscode/languages';
import { IVSCodeWorkspace } from '../common/vscode/workspace';
import { IOssSuggestionWebviewProvider } from './interfaces';
import { OssCodeActionsProvider } from './providers/ossCodeActionsProvider';
import { IDiagnosticsIssueProvider } from '../common/services/diagnosticsService';

export class OssService extends ProductService<OssIssueData> {
public readonly productType = ScanProduct.OpenSource;
Expand All @@ -27,6 +28,7 @@ export class OssService extends ProductService<OssIssueData> {
workspaceTrust: IWorkspaceTrust,
languageServer: ILanguageServer,
languages: IVSCodeLanguages,
readonly diagnosticsIssueProvider: IDiagnosticsIssueProvider<OssIssueData>,
logger: ILog,
) {
super(
Expand All @@ -38,6 +40,7 @@ export class OssService extends ProductService<OssIssueData> {
workspaceTrust,
languageServer,
languages,
diagnosticsIssueProvider,
logger,
);

Expand Down
2 changes: 1 addition & 1 deletion src/test/unit/common/languageServer/languageServer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ suite('Language Server', () => {
enableTrustedFoldersFeature: 'true',
trustedFolders: ['/trusted/test/folder'],
insecure: 'true',
requiredProtocolVersion: '13',
requiredProtocolVersion: '14',
scanningMode: 'auto',
folderConfigs: [],
authenticationMethod: 'oauth',
Expand Down
4 changes: 4 additions & 0 deletions src/test/unit/common/services/productService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { IVSCodeLanguages } from '../../../../snyk/common/vscode/languages';
import { IVSCodeWorkspace } from '../../../../snyk/common/vscode/workspace';
import { LanguageServerMock } from '../../mocks/languageServer.mock';
import { LoggerMock } from '../../mocks/logger.mock';
import { IDiagnosticsIssueProvider } from '../../../../snyk/common/services/diagnosticsService';

type ProductData = {
productName: string;
Expand Down Expand Up @@ -55,6 +56,9 @@ suite('Product Service', () => {
new WorkspaceTrust(),
ls,
{} as IVSCodeLanguages,
{
getIssuesFromDiagnostics: () => [],
} as IDiagnosticsIssueProvider<ProductData>,
new LoggerMock(),
);
});
Expand Down
2 changes: 2 additions & 0 deletions src/test/unit/snykCode/codeService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { ICodeSuggestionWebviewProvider } from '../../../snyk/snykCode/views/int
import { LanguageServerMock } from '../mocks/languageServer.mock';
import { languagesMock } from '../mocks/languages.mock';
import { LoggerMock } from '../mocks/logger.mock';
import { IDiagnosticsIssueProvider } from '../../../snyk/common/services/diagnosticsService';

suite('Code Service', () => {
let ls: ILanguageServer;
Expand Down Expand Up @@ -43,6 +44,7 @@ suite('Code Service', () => {
new WorkspaceTrust(),
ls,
languagesMock,
{} as IDiagnosticsIssueProvider<CodeIssueData>,
new LoggerMock(),
);
});
Expand Down
2 changes: 2 additions & 0 deletions src/test/unit/snykIac/iacService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { IacService } from '../../../snyk/snykIac/iacService';
import { IacSuggestionWebviewProvider } from '../../../snyk/snykIac/views/suggestion/iacSuggestionWebviewProvider';
import { LanguageServerMock } from '../mocks/languageServer.mock';
import { LoggerMock } from '../mocks/logger.mock';
import { IDiagnosticsIssueProvider } from '../../../snyk/common/services/diagnosticsService';

suite('IaC Service', () => {
let ls: ILanguageServer;
Expand Down Expand Up @@ -45,6 +46,7 @@ suite('IaC Service', () => {
{
registerCodeActionsProvider: sinon.fake(),
} as unknown as IVSCodeLanguages,
{} as IDiagnosticsIssueProvider<IacIssueData>,
new LoggerMock(),
);
});
Expand Down
2 changes: 2 additions & 0 deletions src/test/unit/snykOss/ossService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { IOssSuggestionWebviewProvider } from '../../../snyk/snykOss/interfaces'
import { OssService } from '../../../snyk/snykOss/ossService';
import { LanguageServerMock } from '../mocks/languageServer.mock';
import { LoggerMock } from '../mocks/logger.mock';
import { IDiagnosticsIssueProvider } from '../../../snyk/common/services/diagnosticsService';

suite('OSS Service', () => {
let ls: ILanguageServer;
Expand Down Expand Up @@ -43,6 +44,7 @@ suite('OSS Service', () => {
{
registerCodeActionsProvider: sinon.fake(),
} as unknown as IVSCodeLanguages,
{} as unknown as IDiagnosticsIssueProvider<OssIssueData>,
new LoggerMock(),
);
});
Expand Down

0 comments on commit 167062f

Please sign in to comment.