From 2c96012f2dd850c0ad782b7d918e356b6d751025 Mon Sep 17 00:00:00 2001 From: Ilya Siamionau Date: Fri, 20 Dec 2024 10:45:28 +0100 Subject: [PATCH] CM-43068 - Add the "Ignore this violation" button for the violation card of SCA (#82) --- CHANGELOG.md | 9 ++++++- gradle.properties | 2 +- src/main/kotlin/com/cycode/plugin/Consts.kt | 2 +- .../com/cycode/plugin/cli/CliIgnoreType.kt | 3 ++- .../sca/ScaDetectionDetailsAlert.kt | 1 + .../components/treeView/TreeView.kt | 2 +- .../ScaViolationCardContentTab.kt | 6 ++++- .../components/actions/ScaActions.kt | 26 +++++++++++++++++++ .../components/actions/SecretActions.kt | 2 +- .../cycode/plugin/services/CycodeService.kt | 2 ++ .../plugin/services/ScanResultsService.kt | 12 +++++---- .../IacScanResultsFilter.kt | 4 +++ .../SastScanResultsFilter.kt | 6 ++++- .../ScaScanResultsFilter.kt | 6 +++++ .../ScanResultsFilterBase.kt | 7 ++++- .../SecretScanResultsFilter.kt | 4 +++ .../messages/CycodeBundle.properties | 2 +- 17 files changed, 81 insertions(+), 15 deletions(-) create mode 100644 src/main/kotlin/com/cycode/plugin/components/toolWindow/components/violationCardContentTab/scaViolationCardContentTab/components/actions/ScaActions.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index 92ca8df..8a98071 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ ## [Unreleased] +## [2.3.0] - 2024-12-20 + +- Add the "Ignore this violation" button for violation card of SCA +- Add support of `.gitignore` files for a file excluding from scans + ## [2.2.0] - 2024-12-11 - Add AI remediations for IaC and SAST @@ -130,6 +135,8 @@ The first public release of the plugin. +[2.3.0]: https://github.com/cycodehq/intellij-platform-plugin/releases/tag/v2.3.0 + [2.2.0]: https://github.com/cycodehq/intellij-platform-plugin/releases/tag/v2.2.0 [2.1.0]: https://github.com/cycodehq/intellij-platform-plugin/releases/tag/v2.1.0 @@ -182,4 +189,4 @@ The first public release of the plugin. [1.0.0]: https://github.com/cycodehq/intellij-platform-plugin/releases/tag/v1.0.0 -[Unreleased]: https://github.com/cycodehq/intellij-platform-plugin/compare/v2.2.0...HEAD +[Unreleased]: https://github.com/cycodehq/intellij-platform-plugin/compare/v2.3.0...HEAD diff --git a/gradle.properties b/gradle.properties index 60c3a5d..d523ae0 100755 --- a/gradle.properties +++ b/gradle.properties @@ -4,7 +4,7 @@ pluginGroup = com.cycode.plugin pluginName = Cycode pluginRepositoryUrl = https://github.com/cycodehq/intellij-platform-plugin # SemVer format -> https://semver.org -pluginVersion = 2.2.0 +pluginVersion = 2.3.0 # Supported build number ranges and IntelliJ Platform versions -> https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html pluginSinceBuild = 231 diff --git a/src/main/kotlin/com/cycode/plugin/Consts.kt b/src/main/kotlin/com/cycode/plugin/Consts.kt index 7cb2d4c..7de1969 100644 --- a/src/main/kotlin/com/cycode/plugin/Consts.kt +++ b/src/main/kotlin/com/cycode/plugin/Consts.kt @@ -27,7 +27,7 @@ class Consts { companion object { val PLUGIN_PATH = PathManager.getPluginsPath() + "/cycode-intellij-platform-plugin" val DEFAULT_CLI_PATH = getDefaultCliPath() - const val REQUIRED_CLI_VERSION = "2.1.0" + const val REQUIRED_CLI_VERSION = "2.2.0" const val CYCODE_DOMAIN = "cycode.com" diff --git a/src/main/kotlin/com/cycode/plugin/cli/CliIgnoreType.kt b/src/main/kotlin/com/cycode/plugin/cli/CliIgnoreType.kt index d2c5533..6e0542a 100644 --- a/src/main/kotlin/com/cycode/plugin/cli/CliIgnoreType.kt +++ b/src/main/kotlin/com/cycode/plugin/cli/CliIgnoreType.kt @@ -3,5 +3,6 @@ package com.cycode.plugin.cli enum class CliIgnoreType { VALUE, RULE, - PATH + PATH, + CVE, } diff --git a/src/main/kotlin/com/cycode/plugin/cli/models/scanResult/sca/ScaDetectionDetailsAlert.kt b/src/main/kotlin/com/cycode/plugin/cli/models/scanResult/sca/ScaDetectionDetailsAlert.kt index 1929780..af607b7 100644 --- a/src/main/kotlin/com/cycode/plugin/cli/models/scanResult/sca/ScaDetectionDetailsAlert.kt +++ b/src/main/kotlin/com/cycode/plugin/cli/models/scanResult/sca/ScaDetectionDetailsAlert.kt @@ -6,4 +6,5 @@ data class ScaDetectionDetailsAlert( val description: String, val vulnerableRequirements: String?, val firstPatchedVersion: String?, + val cveIdentifier: String?, ) diff --git a/src/main/kotlin/com/cycode/plugin/components/toolWindow/components/treeView/TreeView.kt b/src/main/kotlin/com/cycode/plugin/components/toolWindow/components/treeView/TreeView.kt index 5cce7bb..617c78f 100644 --- a/src/main/kotlin/com/cycode/plugin/components/toolWindow/components/treeView/TreeView.kt +++ b/src/main/kotlin/com/cycode/plugin/components/toolWindow/components/treeView/TreeView.kt @@ -122,7 +122,7 @@ class TreeView( fun displayViolationCard(detection: DetectionBase) { val card = when (detection) { is SecretDetection -> SecretViolationCardContentTab(project).getContent(detection) - is ScaDetection -> ScaViolationCardContentTab().getContent(detection) + is ScaDetection -> ScaViolationCardContentTab(project).getContent(detection) is IacDetection -> IacViolationCardContentTab(project).getContent(detection) is SastDetection -> SastViolationCardContentTab(project).getContent(detection) else -> return diff --git a/src/main/kotlin/com/cycode/plugin/components/toolWindow/components/violationCardContentTab/scaViolationCardContentTab/ScaViolationCardContentTab.kt b/src/main/kotlin/com/cycode/plugin/components/toolWindow/components/violationCardContentTab/scaViolationCardContentTab/ScaViolationCardContentTab.kt index 624817e..9d6e4ef 100644 --- a/src/main/kotlin/com/cycode/plugin/components/toolWindow/components/violationCardContentTab/scaViolationCardContentTab/ScaViolationCardContentTab.kt +++ b/src/main/kotlin/com/cycode/plugin/components/toolWindow/components/violationCardContentTab/scaViolationCardContentTab/ScaViolationCardContentTab.kt @@ -2,15 +2,17 @@ package com.cycode.plugin.components.toolWindow.components.violationCardContentT import com.cycode.plugin.cli.models.scanResult.sca.ScaDetection import com.cycode.plugin.components.toolWindow.components.violationCardContentTab.common.CommonViolationCardContentTab +import com.cycode.plugin.components.toolWindow.components.violationCardContentTab.scaViolationCardContentTab.components.actions.ScaActions import com.cycode.plugin.components.toolWindow.components.violationCardContentTab.scaViolationCardContentTab.components.companyGuidelines.ScaCompanyGuidelines import com.cycode.plugin.components.toolWindow.components.violationCardContentTab.scaViolationCardContentTab.components.cycodeGuidelines.ScaCycodeGuidelines import com.cycode.plugin.components.toolWindow.components.violationCardContentTab.scaViolationCardContentTab.components.header.ScaHeader import com.cycode.plugin.components.toolWindow.components.violationCardContentTab.scaViolationCardContentTab.components.shortSummary.ScaShortSummary import com.cycode.plugin.components.toolWindow.components.violationCardContentTab.scaViolationCardContentTab.components.summary.ScaSummary import com.cycode.plugin.components.toolWindow.components.violationCardContentTab.scaViolationCardContentTab.components.title.ScaTitle +import com.intellij.openapi.project.Project import javax.swing.JComponent -class ScaViolationCardContentTab : CommonViolationCardContentTab() { +class ScaViolationCardContentTab(val project: Project) : CommonViolationCardContentTab() { fun getContent(detection: ScaDetection): JComponent { val titlePanel = ScaTitle().getContent(detection) val shortSummaryPanel = ScaShortSummary().getContent(detection) @@ -18,6 +20,7 @@ class ScaViolationCardContentTab : CommonViolationCardContentTab() { val companyGuidelines = ScaCompanyGuidelines().getContent(detection) val cycodeGuidelines = ScaCycodeGuidelines().getContent(detection) val summaryPanel = ScaSummary().getContent(detection) + val actionsPanel = ScaActions(project).addContent(detection) return getContent( listOf( @@ -27,6 +30,7 @@ class ScaViolationCardContentTab : CommonViolationCardContentTab() { summaryPanel, companyGuidelines, cycodeGuidelines, + actionsPanel, ) ) } diff --git a/src/main/kotlin/com/cycode/plugin/components/toolWindow/components/violationCardContentTab/scaViolationCardContentTab/components/actions/ScaActions.kt b/src/main/kotlin/com/cycode/plugin/components/toolWindow/components/violationCardContentTab/scaViolationCardContentTab/components/actions/ScaActions.kt new file mode 100644 index 0000000..9b365af --- /dev/null +++ b/src/main/kotlin/com/cycode/plugin/components/toolWindow/components/violationCardContentTab/scaViolationCardContentTab/components/actions/ScaActions.kt @@ -0,0 +1,26 @@ +package com.cycode.plugin.components.toolWindow.components.violationCardContentTab.scaViolationCardContentTab.components.actions + +import com.cycode.plugin.CycodeBundle +import com.cycode.plugin.cli.CliIgnoreType +import com.cycode.plugin.cli.CliScanType +import com.cycode.plugin.cli.models.scanResult.sca.ScaDetection +import com.cycode.plugin.components.toolWindow.components.violationCardContentTab.common.actions.CardActions +import com.cycode.plugin.services.cycode +import com.intellij.openapi.project.Project +import javax.swing.JComponent + +class ScaActions(val project: Project) : CardActions() { + fun addContent(detection: ScaDetection): JComponent { + if (detection.detectionDetails.alert?.cveIdentifier != null) { + addActionButton(CycodeBundle.message("violationCardIgnoreViolationBtn"), onClick = { + cycode(project).applyIgnoreFromFileAnnotation( + CliScanType.Sca, + CliIgnoreType.CVE, + detection.detectionDetails.alert.cveIdentifier + ) + }) + } + + return getContent() + } +} diff --git a/src/main/kotlin/com/cycode/plugin/components/toolWindow/components/violationCardContentTab/secretViolationCardContentTab/components/actions/SecretActions.kt b/src/main/kotlin/com/cycode/plugin/components/toolWindow/components/violationCardContentTab/secretViolationCardContentTab/components/actions/SecretActions.kt index a943b3a..ff20278 100644 --- a/src/main/kotlin/com/cycode/plugin/components/toolWindow/components/violationCardContentTab/secretViolationCardContentTab/components/actions/SecretActions.kt +++ b/src/main/kotlin/com/cycode/plugin/components/toolWindow/components/violationCardContentTab/secretViolationCardContentTab/components/actions/SecretActions.kt @@ -11,7 +11,7 @@ import javax.swing.JComponent class SecretActions(val project: Project) : CardActions() { fun addContent(detection: SecretDetection): JComponent { - addActionButton(CycodeBundle.message("secretViolationCardIgnoreViolationBtn"), onClick = { + addActionButton(CycodeBundle.message("violationCardIgnoreViolationBtn"), onClick = { if (detection.detectionDetails.detectedValue != null) { cycode(project).applyIgnoreFromFileAnnotation( CliScanType.Secret, diff --git a/src/main/kotlin/com/cycode/plugin/services/CycodeService.kt b/src/main/kotlin/com/cycode/plugin/services/CycodeService.kt index 09fe0f2..e8b0046 100755 --- a/src/main/kotlin/com/cycode/plugin/services/CycodeService.kt +++ b/src/main/kotlin/com/cycode/plugin/services/CycodeService.kt @@ -120,6 +120,7 @@ class CycodeService(val project: Project) : Disposable { CliIgnoreType.VALUE -> "--by-value" CliIgnoreType.RULE -> "--by-rule" CliIgnoreType.PATH -> "--by-path" + CliIgnoreType.CVE -> "--by-cve" } } @@ -131,6 +132,7 @@ class CycodeService(val project: Project) : Disposable { CliIgnoreType.VALUE -> scanResults.excludeResults(byValue = value) CliIgnoreType.RULE -> scanResults.excludeResults(byRuleId = value) CliIgnoreType.PATH -> scanResults.excludeResults(byPath = value) + CliIgnoreType.CVE -> scanResults.excludeResults(byCve = value) } DaemonCodeAnalyzer.getInstance(project).restart() diff --git a/src/main/kotlin/com/cycode/plugin/services/ScanResultsService.kt b/src/main/kotlin/com/cycode/plugin/services/ScanResultsService.kt index 1d21b9c..0efd6ee 100755 --- a/src/main/kotlin/com/cycode/plugin/services/ScanResultsService.kt +++ b/src/main/kotlin/com/cycode/plugin/services/ScanResultsService.kt @@ -92,25 +92,27 @@ class ScanResultsService { detectedSegments.filter { it.key.first == scanType }.forEach { detectedSegments.remove(it.key) } } - fun excludeResults(byValue: String? = null, byPath: String? = null, byRuleId: String? = null) { + fun excludeResults( + byValue: String? = null, byPath: String? = null, byRuleId: String? = null, byCve: String? = null + ) { if (secretResults is CliResult.Success) { val filter = SecretScanResultsFilter((secretResults as CliResult.Success).result) - filter.exclude(byValue, byPath, byRuleId) + filter.exclude(byValue, byPath, byRuleId, byCve) secretResults = CliResult.Success(filter.getFilteredScanResults()) } if (scaResults is CliResult.Success) { val filter = ScaScanResultsFilter((scaResults as CliResult.Success).result) - filter.exclude(byValue, byPath, byRuleId) + filter.exclude(byValue, byPath, byRuleId, byCve) scaResults = CliResult.Success(filter.getFilteredScanResults()) } if (iacResults is CliResult.Success) { val filter = IacScanResultsFilter((iacResults as CliResult.Success).result) - filter.exclude(byValue, byPath, byRuleId) + filter.exclude(byValue, byPath, byRuleId, byCve) iacResults = CliResult.Success(filter.getFilteredScanResults()) } if (sastResults is CliResult.Success) { val filter = SastScanResultsFilter((sastResults as CliResult.Success).result) - filter.exclude(byValue, byPath, byRuleId) + filter.exclude(byValue, byPath, byRuleId, byCve) sastResults = CliResult.Success(filter.getFilteredScanResults()) } } diff --git a/src/main/kotlin/com/cycode/plugin/services/scanResultsFilters/IacScanResultsFilter.kt b/src/main/kotlin/com/cycode/plugin/services/scanResultsFilters/IacScanResultsFilter.kt index 1080fac..62b39e7 100644 --- a/src/main/kotlin/com/cycode/plugin/services/scanResultsFilters/IacScanResultsFilter.kt +++ b/src/main/kotlin/com/cycode/plugin/services/scanResultsFilters/IacScanResultsFilter.kt @@ -29,6 +29,10 @@ class IacScanResultsFilter(scanResults: IacScanResult) : ScanResultsFilterBase + detection.detectionDetails.alert?.cveIdentifier != cve + } + } + override fun getFilteredScanResults(): ScaScanResult { return filteredScanResults } diff --git a/src/main/kotlin/com/cycode/plugin/services/scanResultsFilters/ScanResultsFilterBase.kt b/src/main/kotlin/com/cycode/plugin/services/scanResultsFilters/ScanResultsFilterBase.kt index 2eb7303..953b03c 100644 --- a/src/main/kotlin/com/cycode/plugin/services/scanResultsFilters/ScanResultsFilterBase.kt +++ b/src/main/kotlin/com/cycode/plugin/services/scanResultsFilters/ScanResultsFilterBase.kt @@ -1,7 +1,7 @@ package com.cycode.plugin.services.scanResultsFilters abstract class ScanResultsFilterBase(val scanResults: T) { - fun exclude(byValue: String? = null, byPath: String? = null, byRuleId: String? = null) { + fun exclude(byValue: String? = null, byPath: String? = null, byRuleId: String? = null, byCve: String? = null) { if (byValue != null) { excludeByValue(byValue) } @@ -11,6 +11,9 @@ abstract class ScanResultsFilterBase(val scanResults: T) { if (byRuleId != null) { excludeByRuleId(byRuleId) } + if (byCve != null) { + excludeByCve(byCve) + } } abstract fun excludeByValue(value: String) @@ -19,5 +22,7 @@ abstract class ScanResultsFilterBase(val scanResults: T) { abstract fun excludeByRuleId(ruleId: String) + abstract fun excludeByCve(cve: String) + abstract fun getFilteredScanResults(): T } \ No newline at end of file diff --git a/src/main/kotlin/com/cycode/plugin/services/scanResultsFilters/SecretScanResultsFilter.kt b/src/main/kotlin/com/cycode/plugin/services/scanResultsFilters/SecretScanResultsFilter.kt index abb5da8..60a02ba 100644 --- a/src/main/kotlin/com/cycode/plugin/services/scanResultsFilters/SecretScanResultsFilter.kt +++ b/src/main/kotlin/com/cycode/plugin/services/scanResultsFilters/SecretScanResultsFilter.kt @@ -31,6 +31,10 @@ class SecretScanResultsFilter(scanResults: SecretScanResult) : ScanResultsFilter } } + override fun excludeByCve(cve: String) { + // do nothing because we don't have a value field in Secrets + } + override fun getFilteredScanResults(): SecretScanResult { return filteredScanResults } diff --git a/src/main/resources/messages/CycodeBundle.properties b/src/main/resources/messages/CycodeBundle.properties index d01436f..7263220 100755 --- a/src/main/resources/messages/CycodeBundle.properties +++ b/src/main/resources/messages/CycodeBundle.properties @@ -105,6 +105,7 @@ violationCardCompanyGuidelinesTitle=Company Guidelines violationCardCycodeGuidelinesTitle=Cycode Guidelines violationCardAiRemediationTitle=AI Remediation generateAiRemediationBtn=Generate AI Remediation +violationCardIgnoreViolationBtn=Ignore this violation # sca violation card scaViolationCardShortSummary={0} | {1} scaViolationCardHeaderPackageField=Package: @@ -119,7 +120,6 @@ secretViolationCardTitle=Hardcoded {0} is used secretViolationCardHeaderRuleIdField=Rule ID: secretViolationCardHeaderFileField=In file: secretViolationCardHeaderShaField=Secret SHA: -secretViolationCardIgnoreViolationBtn=Ignore this violation # iac violation card iacViolationCardHeaderRuleIdField=Rule ID: iacViolationCardHeaderFileField=In file: