From dc4ccd2355d08a8df87e8157fa83fbb9c851d4b5 Mon Sep 17 00:00:00 2001 From: galactica Date: Mon, 10 Feb 2025 23:29:17 +0200 Subject: [PATCH 1/4] Add get state func and add state id for triage update. add tests --- src/main/wrapper/CxConstants.ts | 2 + src/main/wrapper/CxWrapper.ts | 11 ++++- src/tests/PredicateTest.test.ts | 85 +++++++++++++++++++++++++-------- 3 files changed, 77 insertions(+), 21 deletions(-) diff --git a/src/main/wrapper/CxConstants.ts b/src/main/wrapper/CxConstants.ts index 479cb5e4..0c1b5055 100644 --- a/src/main/wrapper/CxConstants.ts +++ b/src/main/wrapper/CxConstants.ts @@ -36,6 +36,7 @@ export enum CxConstants { SUB_CMD_CREATE = "create", CMD_TRIAGE = "triage", SUB_CMD_UPDATE = "update", + SUB_CMD_GET_STATES = "get-states", CMD_RESULT = "results", SUB_CMD_BFL = "bfl", CMD_CODE_BASHING = "codebashing", @@ -72,6 +73,7 @@ export enum CxConstants { SIMILARITY_ID = "--similarity-id", QUERY_ID = "--query-id", STATE = "--state", + STATE_ID = "--state-id", COMMENT = "--comment", SEVERITY = "--severity", REPORT_FORMAT = "--report-format", diff --git a/src/main/wrapper/CxWrapper.ts b/src/main/wrapper/CxWrapper.ts index 869ce902..afda4a50 100644 --- a/src/main/wrapper/CxWrapper.ts +++ b/src/main/wrapper/CxWrapper.ts @@ -200,8 +200,15 @@ export class CxWrapper { return await exec.executeCommands(this.config.pathToExecutable, commands, CxConstants.PREDICATE_TYPE); } - async triageUpdate(projectId: string, similarityId: string, scanType: string, state: string, comment: string, severity: string): Promise { - const commands: string[] = [CxConstants.CMD_TRIAGE, CxConstants.SUB_CMD_UPDATE, CxConstants.PROJECT_ID, projectId, CxConstants.SIMILARITY_ID, similarityId, CxConstants.SCAN_TYPES_SUB_CMD, scanType, CxConstants.STATE, state, CxConstants.COMMENT, comment, CxConstants.SEVERITY, severity]; + async triageUpdate(projectId: string, similarityId: string, scanType: string, state: string, comment: string, severity: string, stateId=""): Promise { + const commands: string[] = [CxConstants.CMD_TRIAGE, CxConstants.SUB_CMD_UPDATE, CxConstants.PROJECT_ID, projectId, CxConstants.SIMILARITY_ID, similarityId, CxConstants.SCAN_TYPES_SUB_CMD, scanType, CxConstants.STATE, state, CxConstants.STATE_ID, stateId, CxConstants.COMMENT, comment, CxConstants.SEVERITY, severity]; + commands.push(...this.initializeCommands(false)); + const exec = new ExecutionService(); + return await exec.executeCommands(this.config.pathToExecutable, commands); + } + + async triageGetStates(): Promise { + const commands: string[] = [CxConstants.CMD_TRIAGE, CxConstants.SUB_CMD_GET_STATES]; commands.push(...this.initializeCommands(false)); const exec = new ExecutionService(); return await exec.executeCommands(this.config.pathToExecutable, commands); diff --git a/src/tests/PredicateTest.test.ts b/src/tests/PredicateTest.test.ts index 68cdf99a..b186ab6d 100644 --- a/src/tests/PredicateTest.test.ts +++ b/src/tests/PredicateTest.test.ts @@ -6,36 +6,83 @@ import {CxConstants} from '../main/wrapper/CxConstants'; describe("Triage cases", () => { const cxScanConfig = new BaseTest(); - - it('Triage Successful case', async () => { - const auth = new CxWrapper(cxScanConfig); - + const auth = new CxWrapper(cxScanConfig); + const getScanAndResult = async (): Promise<{ scan: any, result: CxResult }> => { const scanList: CxCommandOutput = await auth.scanList("statuses=Completed,limit=100"); - let result: CxResult; - let scan, output; - while (!output && scanList && scanList.payload && scanList.payload.length > 0) { - scan = scanList.payload.pop() - console.log("Triage Successful case - ScanId " + scan.id) - output = await auth.getResultsList(scan.id) - if (output.status == "Error in the json file.") { + let scan, output, result; + while (!output && scanList?.payload?.length > 0) { + scan = scanList.payload.pop(); + console.log("Triage case - ScanId " + scan.id); + output = await auth.getResultsList(scan.id); + if (output.status === "Error in the json file.") { output = undefined; } else { - result = output.payload.find(res => res.type == CxConstants.SAST) - if (!result || !result.similarityId) { + result = output.payload.find(res => res.type === CxConstants.SAST); + if (!result?.similarityId) { output = undefined; } } } + return { scan, result }; + }; + const handleTriageShow = async (scan: any, result: CxResult) => { const cxShow: CxCommandOutput = await auth.triageShow(scan.projectID, result.similarityId, result.type); - expect(cxShow.exitCode).toEqual(0); + } - const cxUpdate: CxCommandOutput = await - auth.triageUpdate(scan.projectID, result.similarityId, result.type, result.state, - "Edited via JavascriptWrapper", - result.severity.toLowerCase() == "high" ? CxConstants.SEVERITY_MEDIUM : CxConstants.SEVERITY_HIGH); - + const handleTriageUpdate = async (scan: any, result: CxResult, newState: string, newSeverity: string, newStateId="") => { + const cxUpdate: CxCommandOutput = await auth.triageUpdate( + scan.projectID, result.similarityId, result.type, newState, + "Edited via JavascriptWrapper", + newSeverity, newStateId + ); expect(cxUpdate.exitCode).toEqual(0); + }; + + it('Triage Successful case', async () => { + const { scan, result } = await getScanAndResult(); + await handleTriageShow(scan, result); + await handleTriageUpdate(scan, result, result.state, result.severity.toLowerCase() === "high" ? CxConstants.SEVERITY_MEDIUM : CxConstants.SEVERITY_HIGH); + }); + + it('Triage with custom state Successful case', async () => { + const { scan, result } = await getScanAndResult(); + + const cxCommandOutput: CxCommandOutput = await auth.triageGetStates(); + console.log("Json object from states successful case: " + JSON.stringify(cxCommandOutput)); + expect(cxCommandOutput.payload.length).toBeGreaterThan(1); + expect(cxCommandOutput.exitCode).toBe(0); + + let customState = cxCommandOutput.payload[0].name + + if (result.state == customState) { + if (cxCommandOutput.payload.length > 1) { + customState = cxCommandOutput.payload[1].name + } else { + await handleTriageUpdate(scan, result, CxConstants.STATE_CONFIRMED, CxConstants.SEVERITY_MEDIUM); + } + } + await handleTriageUpdate(scan, result, customState, CxConstants.SEVERITY_MEDIUM); + + }); it('Triage with custom state id Successful case', async () => { + const { scan, result } = await getScanAndResult(); + + const cxCommandOutput: CxCommandOutput = await auth.triageGetStates(); + console.log("Json object from states successful case: " + JSON.stringify(cxCommandOutput)); + expect(cxCommandOutput.payload.length).toBeGreaterThan(1); + expect(cxCommandOutput.exitCode).toBe(0); + const allStates = cxCommandOutput.payload; + let customStateId = allStates[0].id + const customStateName = allStates[0].name + + if (result.state == customStateName) { + if (allStates.length > 1) { + customStateId = allStates[1].id + } else { + await handleTriageUpdate(scan, result, CxConstants.STATE_CONFIRMED, CxConstants.SEVERITY_MEDIUM); + } + } + await handleTriageUpdate(scan, result, "", CxConstants.SEVERITY_MEDIUM, customStateId.toString()); }); }); \ No newline at end of file From f1007c04ca61742a23b6714b753b28143a3b2e8a Mon Sep 17 00:00:00 2001 From: galactica Date: Mon, 10 Feb 2025 23:30:20 +0200 Subject: [PATCH 2/4] Skip on custom state tests. --- src/tests/PredicateTest.test.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/tests/PredicateTest.test.ts b/src/tests/PredicateTest.test.ts index b186ab6d..198a4800 100644 --- a/src/tests/PredicateTest.test.ts +++ b/src/tests/PredicateTest.test.ts @@ -46,7 +46,7 @@ describe("Triage cases", () => { await handleTriageUpdate(scan, result, result.state, result.severity.toLowerCase() === "high" ? CxConstants.SEVERITY_MEDIUM : CxConstants.SEVERITY_HIGH); }); - it('Triage with custom state Successful case', async () => { + it.skip('Triage with custom state Successful case', async () => { const { scan, result } = await getScanAndResult(); const cxCommandOutput: CxCommandOutput = await auth.triageGetStates(); @@ -65,7 +65,9 @@ describe("Triage cases", () => { } await handleTriageUpdate(scan, result, customState, CxConstants.SEVERITY_MEDIUM); - }); it('Triage with custom state id Successful case', async () => { + }); + + it.skip('Triage with custom state id Successful case', async () => { const { scan, result } = await getScanAndResult(); const cxCommandOutput: CxCommandOutput = await auth.triageGetStates(); From 90e32de2a1f1bca9bcd1bbf75919435ea09e5a97 Mon Sep 17 00:00:00 2001 From: galactica Date: Tue, 11 Feb 2025 15:16:09 +0200 Subject: [PATCH 3/4] Add --all flag --- src/main/wrapper/CxConstants.ts | 1 + src/main/wrapper/CxWrapper.ts | 5 +++-- src/tests/PredicateTest.test.ts | 20 +++++++++++--------- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/main/wrapper/CxConstants.ts b/src/main/wrapper/CxConstants.ts index 0c1b5055..4f41ea0e 100644 --- a/src/main/wrapper/CxConstants.ts +++ b/src/main/wrapper/CxConstants.ts @@ -37,6 +37,7 @@ export enum CxConstants { CMD_TRIAGE = "triage", SUB_CMD_UPDATE = "update", SUB_CMD_GET_STATES = "get-states", + ALL_STATES_FLAG = "--all", CMD_RESULT = "results", SUB_CMD_BFL = "bfl", CMD_CODE_BASHING = "codebashing", diff --git a/src/main/wrapper/CxWrapper.ts b/src/main/wrapper/CxWrapper.ts index afda4a50..bf9151bf 100644 --- a/src/main/wrapper/CxWrapper.ts +++ b/src/main/wrapper/CxWrapper.ts @@ -200,15 +200,16 @@ export class CxWrapper { return await exec.executeCommands(this.config.pathToExecutable, commands, CxConstants.PREDICATE_TYPE); } - async triageUpdate(projectId: string, similarityId: string, scanType: string, state: string, comment: string, severity: string, stateId=""): Promise { + async triageUpdate(projectId: string, similarityId: string, scanType: string, state: string, comment: string, severity: string, stateId = ""): Promise { const commands: string[] = [CxConstants.CMD_TRIAGE, CxConstants.SUB_CMD_UPDATE, CxConstants.PROJECT_ID, projectId, CxConstants.SIMILARITY_ID, similarityId, CxConstants.SCAN_TYPES_SUB_CMD, scanType, CxConstants.STATE, state, CxConstants.STATE_ID, stateId, CxConstants.COMMENT, comment, CxConstants.SEVERITY, severity]; commands.push(...this.initializeCommands(false)); const exec = new ExecutionService(); return await exec.executeCommands(this.config.pathToExecutable, commands); } - async triageGetStates(): Promise { + async triageGetStates(all: boolean): Promise { const commands: string[] = [CxConstants.CMD_TRIAGE, CxConstants.SUB_CMD_GET_STATES]; + if (all) commands.push(CxConstants.ALL_STATES_FLAG) commands.push(...this.initializeCommands(false)); const exec = new ExecutionService(); return await exec.executeCommands(this.config.pathToExecutable, commands); diff --git a/src/tests/PredicateTest.test.ts b/src/tests/PredicateTest.test.ts index 198a4800..3f8bbad5 100644 --- a/src/tests/PredicateTest.test.ts +++ b/src/tests/PredicateTest.test.ts @@ -31,7 +31,7 @@ describe("Triage cases", () => { expect(cxShow.exitCode).toEqual(0); } - const handleTriageUpdate = async (scan: any, result: CxResult, newState: string, newSeverity: string, newStateId="") => { + const handleTriageUpdate = async (scan: any, result: CxResult, newState: string, newSeverity: string, newStateId = "") => { const cxUpdate: CxCommandOutput = await auth.triageUpdate( scan.projectID, result.similarityId, result.type, newState, "Edited via JavascriptWrapper", @@ -39,6 +39,13 @@ describe("Triage cases", () => { ); expect(cxUpdate.exitCode).toEqual(0); }; + const handlegetStates = async () => { + const cxCommandOutput: CxCommandOutput = await auth.triageGetStates(false); + console.log("Json object from states successful case: " + JSON.stringify(cxCommandOutput)); + expect(cxCommandOutput.payload.length).toBeGreaterThanOrEqual(1); + expect(cxCommandOutput.exitCode).toBe(0); + return cxCommandOutput + }; it('Triage Successful case', async () => { const { scan, result } = await getScanAndResult(); @@ -49,10 +56,7 @@ describe("Triage cases", () => { it.skip('Triage with custom state Successful case', async () => { const { scan, result } = await getScanAndResult(); - const cxCommandOutput: CxCommandOutput = await auth.triageGetStates(); - console.log("Json object from states successful case: " + JSON.stringify(cxCommandOutput)); - expect(cxCommandOutput.payload.length).toBeGreaterThan(1); - expect(cxCommandOutput.exitCode).toBe(0); + const cxCommandOutput = await handlegetStates(); let customState = cxCommandOutput.payload[0].name @@ -70,10 +74,8 @@ describe("Triage cases", () => { it.skip('Triage with custom state id Successful case', async () => { const { scan, result } = await getScanAndResult(); - const cxCommandOutput: CxCommandOutput = await auth.triageGetStates(); - console.log("Json object from states successful case: " + JSON.stringify(cxCommandOutput)); - expect(cxCommandOutput.payload.length).toBeGreaterThan(1); - expect(cxCommandOutput.exitCode).toBe(0); + const cxCommandOutput = await handlegetStates(); + const allStates = cxCommandOutput.payload; let customStateId = allStates[0].id const customStateName = allStates[0].name From ba412cdd90d28bfff8b3ddcfdddd4def632afac8 Mon Sep 17 00:00:00 2001 From: galactica Date: Tue, 11 Feb 2025 17:05:11 +0200 Subject: [PATCH 4/4] State id is optional --- src/main/wrapper/CxWrapper.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/wrapper/CxWrapper.ts b/src/main/wrapper/CxWrapper.ts index bf9151bf..ccd61842 100644 --- a/src/main/wrapper/CxWrapper.ts +++ b/src/main/wrapper/CxWrapper.ts @@ -201,7 +201,11 @@ export class CxWrapper { } async triageUpdate(projectId: string, similarityId: string, scanType: string, state: string, comment: string, severity: string, stateId = ""): Promise { - const commands: string[] = [CxConstants.CMD_TRIAGE, CxConstants.SUB_CMD_UPDATE, CxConstants.PROJECT_ID, projectId, CxConstants.SIMILARITY_ID, similarityId, CxConstants.SCAN_TYPES_SUB_CMD, scanType, CxConstants.STATE, state, CxConstants.STATE_ID, stateId, CxConstants.COMMENT, comment, CxConstants.SEVERITY, severity]; + const commands: string[] = [CxConstants.CMD_TRIAGE, CxConstants.SUB_CMD_UPDATE, CxConstants.PROJECT_ID, projectId, CxConstants.SIMILARITY_ID, similarityId, CxConstants.SCAN_TYPES_SUB_CMD, scanType, CxConstants.STATE, state, CxConstants.COMMENT, comment, CxConstants.SEVERITY, severity]; + if(stateId) { + commands.push(CxConstants.STATE_ID) + commands.push(stateId) + } commands.push(...this.initializeCommands(false)); const exec = new ExecutionService(); return await exec.executeCommands(this.config.pathToExecutable, commands);