Skip to content

Commit 089e935

Browse files
authored
CM-44175 - Add tree view filtering by severity (#125)
1 parent 2d227be commit 089e935

23 files changed

+537
-62
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## [Unreleased]
44

5+
- Add proper support for disabled modules
6+
- Add tree view filtering by severity
7+
- Fix auth required state of status bar
8+
59
## [v1.14.0]
610

711
- Add the "Ignore this violation" button for violation card of SCA

package.json

Lines changed: 207 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -63,41 +63,149 @@
6363
}
6464
],
6565
"view/item/context": [
66+
{
67+
"command": "cycode.enableFilterByCriticalSeverity",
68+
"when": "viewItem == FilterNode && !cycode:filter.severity.isCriticalEnabled",
69+
"group": "inline@1"
70+
},
71+
{
72+
"command": "cycode.disableFilterByCriticalSeverity",
73+
"when": "viewItem == FilterNode && cycode:filter.severity.isCriticalEnabled",
74+
"group": "inline@1"
75+
},
76+
{
77+
"command": "cycode.enableFilterByHighSeverity",
78+
"when": "viewItem == FilterNode && !cycode:filter.severity.isHighEnabled",
79+
"group": "inline@2"
80+
},
81+
{
82+
"command": "cycode.disableFilterByHighSeverity",
83+
"when": "viewItem == FilterNode && cycode:filter.severity.isHighEnabled",
84+
"group": "inline@2"
85+
},
86+
{
87+
"command": "cycode.enableFilterByMediumSeverity",
88+
"when": "viewItem == FilterNode && !cycode:filter.severity.isMediumEnabled",
89+
"group": "inline@3"
90+
},
91+
{
92+
"command": "cycode.disableFilterByMediumSeverity",
93+
"when": "viewItem == FilterNode && cycode:filter.severity.isMediumEnabled",
94+
"group": "inline@3"
95+
},
96+
{
97+
"command": "cycode.enableFilterByLowSeverity",
98+
"when": "viewItem == FilterNode && !cycode:filter.severity.isLowEnabled",
99+
"group": "inline@4"
100+
},
101+
{
102+
"command": "cycode.disableFilterByLowSeverity",
103+
"when": "viewItem == FilterNode && cycode:filter.severity.isLowEnabled",
104+
"group": "inline@4"
105+
},
106+
{
107+
"command": "cycode.enableFilterByInfoSeverity",
108+
"when": "viewItem == FilterNode && !cycode:filter.severity.isInfoEnabled",
109+
"group": "inline@5"
110+
},
111+
{
112+
"command": "cycode.disableFilterByInfoSeverity",
113+
"when": "viewItem == FilterNode && cycode:filter.severity.isInfoEnabled",
114+
"group": "inline@5"
115+
},
66116
{
67117
"command": "cycode.secretScanForProject",
68-
"when": "viewItem == secretScanTypeNode",
118+
"when": "viewItem == secretScanTypeNode && cycode:modules.isSecretScanningEnabled",
69119
"group": "inline"
70120
},
71121
{
72122
"command": "cycode.scaScan",
73-
"when": "viewItem == scaScanTypeNode",
123+
"when": "viewItem == scaScanTypeNode && cycode:modules.isScaScanningEnabled",
74124
"group": "inline"
75125
},
76126
{
77127
"command": "cycode.iacScanForProject",
78-
"when": "viewItem == iacScanTypeNode",
128+
"when": "viewItem == iacScanTypeNode && cycode:modules.isIacScanningEnabled",
79129
"group": "inline"
80130
},
81131
{
82132
"command": "cycode.sastScanForProject",
83-
"when": "viewItem == sastScanTypeNode",
133+
"when": "viewItem == sastScanTypeNode && cycode:modules.isSastScanningEnabled",
84134
"group": "inline"
85135
},
86136
{
87137
"command": "cycode.secretScanForProject",
88-
"when": "view == cycode.view.tree && viewItem == secretScanTypeNode"
138+
"when": "view == cycode.view.tree && viewItem == secretScanTypeNode && cycode:modules.isSecretScanningEnabled"
89139
},
90140
{
91141
"command": "cycode.scaScan",
92-
"when": "view == cycode.view.tree && viewItem == scaScanTypeNode"
142+
"when": "view == cycode.view.tree && viewItem == scaScanTypeNode && cycode:modules.isScaScanningEnabled"
93143
},
94144
{
95145
"command": "cycode.iacScanForProject",
96-
"when": "view == cycode.view.tree && viewItem == iacScanTypeNode"
146+
"when": "view == cycode.view.tree && viewItem == iacScanTypeNode && cycode:modules.isIacScanningEnabled"
97147
},
98148
{
99149
"command": "cycode.sastScanForProject",
100-
"when": "view == cycode.view.tree && viewItem == sastScanTypeNode"
150+
"when": "view == cycode.view.tree && viewItem == sastScanTypeNode && cycode:modules.isSastScanningEnabled"
151+
}
152+
],
153+
"commandPalette": [
154+
{
155+
"command": "cycode.secretScanForProject",
156+
"when": "cycode:modules.isSecretScanningEnabled"
157+
},
158+
{
159+
"command": "cycode.iacScanForProject",
160+
"when": "cycode:modules.isIacScanningEnabled"
161+
},
162+
{
163+
"command": "cycode.sastScanForProject",
164+
"when": "cycode:modules.isSastScanningEnabled"
165+
},
166+
{
167+
"command": "cycode.scaScan",
168+
"when": "cycode:modules.isScaScanningEnabled"
169+
},
170+
{
171+
"command": "cycode.enableFilterByCriticalSeverity",
172+
"when": "false"
173+
},
174+
{
175+
"command": "cycode.enableFilterByHighSeverity",
176+
"when": "false"
177+
},
178+
{
179+
"command": "cycode.enableFilterByMediumSeverity",
180+
"when": "false"
181+
},
182+
{
183+
"command": "cycode.enableFilterByLowSeverity",
184+
"when": "false"
185+
},
186+
{
187+
"command": "cycode.enableFilterByInfoSeverity",
188+
"when": "false"
189+
},
190+
{
191+
"command": "cycode.disableFilterByCriticalSeverity",
192+
"when": "false"
193+
},
194+
{
195+
"command": "cycode.disableFilterByHighSeverity",
196+
"when": "false"
197+
},
198+
{
199+
"command": "cycode.disableFilterByMediumSeverity",
200+
"when": "false"
201+
},
202+
{
203+
"command": "cycode.disableFilterByLowSeverity",
204+
"when": "false"
205+
},
206+
{
207+
"command": "cycode.disableFilterByInfoSeverity",
208+
"when": "false"
101209
}
102210
]
103211
},
@@ -198,6 +306,96 @@
198306
{
199307
"command": "cycode.auth",
200308
"title": "Authenticate with service"
309+
},
310+
{
311+
"command": "cycode.enableFilterByCriticalSeverity",
312+
"category": "Cycode",
313+
"title": "Enable filter by Critical severity",
314+
"icon": {
315+
"light": "resources/severity/Critical.png",
316+
"dark": "resources/severity/Critical.png"
317+
}
318+
},
319+
{
320+
"command": "cycode.enableFilterByHighSeverity",
321+
"category": "Cycode",
322+
"title": "Enable filter by High severity",
323+
"icon": {
324+
"light": "resources/severity/High.png",
325+
"dark": "resources/severity/High.png"
326+
}
327+
},
328+
{
329+
"command": "cycode.enableFilterByMediumSeverity",
330+
"category": "Cycode",
331+
"title": "Enable filter by Medium severity",
332+
"icon": {
333+
"light": "resources/severity/Medium.png",
334+
"dark": "resources/severity/Medium.png"
335+
}
336+
},
337+
{
338+
"command": "cycode.enableFilterByLowSeverity",
339+
"category": "Cycode",
340+
"title": "Enable filter by Low severity",
341+
"icon": {
342+
"light": "resources/severity/Low.png",
343+
"dark": "resources/severity/Low.png"
344+
}
345+
},
346+
{
347+
"command": "cycode.enableFilterByInfoSeverity",
348+
"category": "Cycode",
349+
"title": "Enable filter by Info severity",
350+
"icon": {
351+
"light": "resources/severity/Info.png",
352+
"dark": "resources/severity/Info.png"
353+
}
354+
},
355+
{
356+
"command": "cycode.disableFilterByCriticalSeverity",
357+
"category": "Cycode",
358+
"title": "Disable filter by Critical severity",
359+
"icon": {
360+
"light": "resources/severity/outline/Critical.png",
361+
"dark": "resources/severity/outline/Critical.png"
362+
}
363+
},
364+
{
365+
"command": "cycode.disableFilterByHighSeverity",
366+
"category": "Cycode",
367+
"title": "Disable filter by High severity",
368+
"icon": {
369+
"light": "resources/severity/outline/High.png",
370+
"dark": "resources/severity/outline/High.png"
371+
}
372+
},
373+
{
374+
"command": "cycode.disableFilterByMediumSeverity",
375+
"category": "Cycode",
376+
"title": "Disable filter by Medium severity",
377+
"icon": {
378+
"light": "resources/severity/outline/Medium.png",
379+
"dark": "resources/severity/outline/Medium.png"
380+
}
381+
},
382+
{
383+
"command": "cycode.disableFilterByLowSeverity",
384+
"category": "Cycode",
385+
"title": "Disable filter by Low severity",
386+
"icon": {
387+
"light": "resources/severity/outline/Low.png",
388+
"dark": "resources/severity/outline/Low.png"
389+
}
390+
},
391+
{
392+
"command": "cycode.disableFilterByInfoSeverity",
393+
"category": "Cycode",
394+
"title": "Disable filter by Info severity",
395+
"icon": {
396+
"light": "resources/severity/outline/Info.png",
397+
"dark": "resources/severity/outline/Info.png"
398+
}
201399
}
202400
],
203401
"viewsContainers": {
@@ -246,7 +444,7 @@
246444
},
247445
"icons": {
248446
"cycode-logo": {
249-
"description": "Cycode icon",
447+
"description": "Cycode Logo",
250448
"default": {
251449
"fontPath": "./resources/cycode.woff",
252450
"fontCharacter": "\\E800"
1.8 KB
Loading

resources/severity/outline/High.png

1.88 KB
Loading

resources/severity/outline/Info.png

1.87 KB
Loading

resources/severity/outline/Low.png

1.72 KB
Loading

resources/severity/outline/Medium.png

1.72 KB
Loading

src/commands/common.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export const getCommonCommand = (command: (...args: never[]) => void | Promise<v
1111
}
1212

1313
const stateService = container.resolve<IStateService>(StateServiceSymbol);
14-
if (requiredAuth && !stateService.globalState.CliAuthed) {
14+
if (requiredAuth && !stateService.tempState.CliAuthed) {
1515
vscode.window.showErrorMessage('Please authenticate with Cycode first');
1616
return;
1717
}

src/commands/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import treeViewExpandAllCommand from './tree-view-expand-all-command';
1616
import treeViewCollapseAllCommand from './tree-view-collapse-all-command';
1717
import runAllScansCommand from './run-all-scans-command';
1818
import clearAllScanResultsCommand from './clear-all-scan-results-command';
19+
import registerTreeViewSeverityFilterCommands from './tree-view-filter-by-severity-command';
1920

2021
export enum VscodeCommands {
2122
SecretScanCommandId = 'cycode.secretScan',
@@ -74,4 +75,6 @@ export const registerCommands = (context: vscode.ExtensionContext): void => {
7475
for (const [commandId, commandCallback] of Object.entries(_VS_CODE_COMMANDS_ID_TO_CALLBACK)) {
7576
context.subscriptions.push(vscode.commands.registerCommand(commandId, commandCallback));
7677
}
78+
79+
registerTreeViewSeverityFilterCommands(context);
7780
};

src/commands/run-all-scans-command.ts

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,27 @@ import { container } from 'tsyringe';
22
import { CycodeService, ICycodeService } from '../services/cycode-service';
33
import { CliScanType } from '../cli/models/cli-scan-type';
44
import { getCommonCommand } from './common';
5+
import { IStateService } from '../services/state-service';
6+
import { StateServiceSymbol } from '../symbols';
57

68
export default getCommonCommand(async () => {
79
const cycodeService = container.resolve<ICycodeService>(CycodeService);
10+
const stateService = container.resolve<IStateService>(StateServiceSymbol);
811

912
const scanPromises = [];
10-
scanPromises.push(cycodeService.startScanForCurrentProject(CliScanType.Secret));
11-
scanPromises.push(cycodeService.startScanForCurrentProject(CliScanType.Sca));
12-
scanPromises.push(cycodeService.startScanForCurrentProject(CliScanType.Iac));
13-
scanPromises.push(cycodeService.startScanForCurrentProject(CliScanType.Sast));
13+
14+
if (stateService.tempState.IsSecretScanningEnabled) {
15+
scanPromises.push(cycodeService.startScanForCurrentProject(CliScanType.Secret));
16+
}
17+
if (stateService.tempState.IsScaScanningEnabled) {
18+
scanPromises.push(cycodeService.startScanForCurrentProject(CliScanType.Sca));
19+
}
20+
if (stateService.tempState.IsIacScanningEnabled) {
21+
scanPromises.push(cycodeService.startScanForCurrentProject(CliScanType.Iac));
22+
}
23+
if (stateService.tempState.IsSastScanningEnabled) {
24+
scanPromises.push(cycodeService.startScanForCurrentProject(CliScanType.Sast));
25+
}
26+
1427
await Promise.all(scanPromises);
1528
});
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { container } from 'tsyringe';
2+
import { ExtensionServiceSymbol, StateServiceSymbol } from '../symbols';
3+
import vscode from 'vscode';
4+
import { IStateService } from '../services/state-service';
5+
import { IExtensionService } from '../services/extension-service';
6+
7+
const _SEVERITY_NAMES: readonly string[] = ['Critical', 'High', 'Medium', 'Low', 'Info'];
8+
9+
const treeViewFilterBySeverityCallback = (severityName: string, enabled: boolean) => {
10+
const extension = container.resolve<IExtensionService>(ExtensionServiceSymbol);
11+
const stateService = container.resolve<IStateService>(StateServiceSymbol);
12+
const tempState = stateService.tempState;
13+
14+
switch (severityName) {
15+
case 'Critical':
16+
tempState.IsTreeViewFilterByCriticalSeverityEnabled = enabled;
17+
break;
18+
case 'High':
19+
tempState.IsTreeViewFilterByHighSeverityEnabled = enabled;
20+
break;
21+
case 'Medium':
22+
tempState.IsTreeViewFilterByMediumSeverityEnabled = enabled;
23+
break;
24+
case 'Low':
25+
tempState.IsTreeViewFilterByLowSeverityEnabled = enabled;
26+
break;
27+
case 'Info':
28+
tempState.IsTreeViewFilterByInfoSeverityEnabled = enabled;
29+
break;
30+
}
31+
32+
stateService.save();
33+
extension.treeDataProvider.refresh();
34+
};
35+
36+
export default (context: vscode.ExtensionContext): void => {
37+
for (const severity of _SEVERITY_NAMES) {
38+
const enableFilterCommandId = `cycode.enableFilterBy${severity}Severity`;
39+
context.subscriptions.push(
40+
vscode.commands.registerCommand(
41+
enableFilterCommandId, () => { treeViewFilterBySeverityCallback(severity, true); },
42+
),
43+
);
44+
45+
const disableFilterCommandId = `cycode.disableFilterBy${severity}Severity`;
46+
context.subscriptions.push(
47+
vscode.commands.registerCommand(
48+
disableFilterCommandId, () => { treeViewFilterBySeverityCallback(severity, false); },
49+
),
50+
);
51+
}
52+
};

0 commit comments

Comments
 (0)