Skip to content

Commit 2c96012

Browse files
authored
CM-43068 - Add the "Ignore this violation" button for the violation card of SCA (#82)
1 parent f5f8c6f commit 2c96012

File tree

17 files changed

+81
-15
lines changed

17 files changed

+81
-15
lines changed

CHANGELOG.md

+8-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44

55
## [Unreleased]
66

7+
## [2.3.0] - 2024-12-20
8+
9+
- Add the "Ignore this violation" button for violation card of SCA
10+
- Add support of `.gitignore` files for a file excluding from scans
11+
712
## [2.2.0] - 2024-12-11
813

914
- Add AI remediations for IaC and SAST
@@ -130,6 +135,8 @@
130135

131136
The first public release of the plugin.
132137

138+
[2.3.0]: https://github.com/cycodehq/intellij-platform-plugin/releases/tag/v2.3.0
139+
133140
[2.2.0]: https://github.com/cycodehq/intellij-platform-plugin/releases/tag/v2.2.0
134141

135142
[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.
182189

183190
[1.0.0]: https://github.com/cycodehq/intellij-platform-plugin/releases/tag/v1.0.0
184191

185-
[Unreleased]: https://github.com/cycodehq/intellij-platform-plugin/compare/v2.2.0...HEAD
192+
[Unreleased]: https://github.com/cycodehq/intellij-platform-plugin/compare/v2.3.0...HEAD

gradle.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ pluginGroup = com.cycode.plugin
44
pluginName = Cycode
55
pluginRepositoryUrl = https://github.com/cycodehq/intellij-platform-plugin
66
# SemVer format -> https://semver.org
7-
pluginVersion = 2.2.0
7+
pluginVersion = 2.3.0
88

99
# Supported build number ranges and IntelliJ Platform versions -> https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html
1010
pluginSinceBuild = 231

src/main/kotlin/com/cycode/plugin/Consts.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class Consts {
2727
companion object {
2828
val PLUGIN_PATH = PathManager.getPluginsPath() + "/cycode-intellij-platform-plugin"
2929
val DEFAULT_CLI_PATH = getDefaultCliPath()
30-
const val REQUIRED_CLI_VERSION = "2.1.0"
30+
const val REQUIRED_CLI_VERSION = "2.2.0"
3131

3232
const val CYCODE_DOMAIN = "cycode.com"
3333

src/main/kotlin/com/cycode/plugin/cli/CliIgnoreType.kt

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@ package com.cycode.plugin.cli
33
enum class CliIgnoreType {
44
VALUE,
55
RULE,
6-
PATH
6+
PATH,
7+
CVE,
78
}

src/main/kotlin/com/cycode/plugin/cli/models/scanResult/sca/ScaDetectionDetailsAlert.kt

+1
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ data class ScaDetectionDetailsAlert(
66
val description: String,
77
val vulnerableRequirements: String?,
88
val firstPatchedVersion: String?,
9+
val cveIdentifier: String?,
910
)

src/main/kotlin/com/cycode/plugin/components/toolWindow/components/treeView/TreeView.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ class TreeView(
122122
fun displayViolationCard(detection: DetectionBase) {
123123
val card = when (detection) {
124124
is SecretDetection -> SecretViolationCardContentTab(project).getContent(detection)
125-
is ScaDetection -> ScaViolationCardContentTab().getContent(detection)
125+
is ScaDetection -> ScaViolationCardContentTab(project).getContent(detection)
126126
is IacDetection -> IacViolationCardContentTab(project).getContent(detection)
127127
is SastDetection -> SastViolationCardContentTab(project).getContent(detection)
128128
else -> return

src/main/kotlin/com/cycode/plugin/components/toolWindow/components/violationCardContentTab/scaViolationCardContentTab/ScaViolationCardContentTab.kt

+5-1
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,25 @@ package com.cycode.plugin.components.toolWindow.components.violationCardContentT
22

33
import com.cycode.plugin.cli.models.scanResult.sca.ScaDetection
44
import com.cycode.plugin.components.toolWindow.components.violationCardContentTab.common.CommonViolationCardContentTab
5+
import com.cycode.plugin.components.toolWindow.components.violationCardContentTab.scaViolationCardContentTab.components.actions.ScaActions
56
import com.cycode.plugin.components.toolWindow.components.violationCardContentTab.scaViolationCardContentTab.components.companyGuidelines.ScaCompanyGuidelines
67
import com.cycode.plugin.components.toolWindow.components.violationCardContentTab.scaViolationCardContentTab.components.cycodeGuidelines.ScaCycodeGuidelines
78
import com.cycode.plugin.components.toolWindow.components.violationCardContentTab.scaViolationCardContentTab.components.header.ScaHeader
89
import com.cycode.plugin.components.toolWindow.components.violationCardContentTab.scaViolationCardContentTab.components.shortSummary.ScaShortSummary
910
import com.cycode.plugin.components.toolWindow.components.violationCardContentTab.scaViolationCardContentTab.components.summary.ScaSummary
1011
import com.cycode.plugin.components.toolWindow.components.violationCardContentTab.scaViolationCardContentTab.components.title.ScaTitle
12+
import com.intellij.openapi.project.Project
1113
import javax.swing.JComponent
1214

13-
class ScaViolationCardContentTab : CommonViolationCardContentTab() {
15+
class ScaViolationCardContentTab(val project: Project) : CommonViolationCardContentTab() {
1416
fun getContent(detection: ScaDetection): JComponent {
1517
val titlePanel = ScaTitle().getContent(detection)
1618
val shortSummaryPanel = ScaShortSummary().getContent(detection)
1719
val headerContentPanel = ScaHeader().addContent(detection)
1820
val companyGuidelines = ScaCompanyGuidelines().getContent(detection)
1921
val cycodeGuidelines = ScaCycodeGuidelines().getContent(detection)
2022
val summaryPanel = ScaSummary().getContent(detection)
23+
val actionsPanel = ScaActions(project).addContent(detection)
2124

2225
return getContent(
2326
listOf(
@@ -27,6 +30,7 @@ class ScaViolationCardContentTab : CommonViolationCardContentTab() {
2730
summaryPanel,
2831
companyGuidelines,
2932
cycodeGuidelines,
33+
actionsPanel,
3034
)
3135
)
3236
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.cycode.plugin.components.toolWindow.components.violationCardContentTab.scaViolationCardContentTab.components.actions
2+
3+
import com.cycode.plugin.CycodeBundle
4+
import com.cycode.plugin.cli.CliIgnoreType
5+
import com.cycode.plugin.cli.CliScanType
6+
import com.cycode.plugin.cli.models.scanResult.sca.ScaDetection
7+
import com.cycode.plugin.components.toolWindow.components.violationCardContentTab.common.actions.CardActions
8+
import com.cycode.plugin.services.cycode
9+
import com.intellij.openapi.project.Project
10+
import javax.swing.JComponent
11+
12+
class ScaActions(val project: Project) : CardActions() {
13+
fun addContent(detection: ScaDetection): JComponent {
14+
if (detection.detectionDetails.alert?.cveIdentifier != null) {
15+
addActionButton(CycodeBundle.message("violationCardIgnoreViolationBtn"), onClick = {
16+
cycode(project).applyIgnoreFromFileAnnotation(
17+
CliScanType.Sca,
18+
CliIgnoreType.CVE,
19+
detection.detectionDetails.alert.cveIdentifier
20+
)
21+
})
22+
}
23+
24+
return getContent()
25+
}
26+
}

src/main/kotlin/com/cycode/plugin/components/toolWindow/components/violationCardContentTab/secretViolationCardContentTab/components/actions/SecretActions.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import javax.swing.JComponent
1111

1212
class SecretActions(val project: Project) : CardActions() {
1313
fun addContent(detection: SecretDetection): JComponent {
14-
addActionButton(CycodeBundle.message("secretViolationCardIgnoreViolationBtn"), onClick = {
14+
addActionButton(CycodeBundle.message("violationCardIgnoreViolationBtn"), onClick = {
1515
if (detection.detectionDetails.detectedValue != null) {
1616
cycode(project).applyIgnoreFromFileAnnotation(
1717
CliScanType.Secret,

src/main/kotlin/com/cycode/plugin/services/CycodeService.kt

+2
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ class CycodeService(val project: Project) : Disposable {
120120
CliIgnoreType.VALUE -> "--by-value"
121121
CliIgnoreType.RULE -> "--by-rule"
122122
CliIgnoreType.PATH -> "--by-path"
123+
CliIgnoreType.CVE -> "--by-cve"
123124
}
124125
}
125126

@@ -131,6 +132,7 @@ class CycodeService(val project: Project) : Disposable {
131132
CliIgnoreType.VALUE -> scanResults.excludeResults(byValue = value)
132133
CliIgnoreType.RULE -> scanResults.excludeResults(byRuleId = value)
133134
CliIgnoreType.PATH -> scanResults.excludeResults(byPath = value)
135+
CliIgnoreType.CVE -> scanResults.excludeResults(byCve = value)
134136
}
135137

136138
DaemonCodeAnalyzer.getInstance(project).restart()

src/main/kotlin/com/cycode/plugin/services/ScanResultsService.kt

+7-5
Original file line numberDiff line numberDiff line change
@@ -92,25 +92,27 @@ class ScanResultsService {
9292
detectedSegments.filter { it.key.first == scanType }.forEach { detectedSegments.remove(it.key) }
9393
}
9494

95-
fun excludeResults(byValue: String? = null, byPath: String? = null, byRuleId: String? = null) {
95+
fun excludeResults(
96+
byValue: String? = null, byPath: String? = null, byRuleId: String? = null, byCve: String? = null
97+
) {
9698
if (secretResults is CliResult.Success) {
9799
val filter = SecretScanResultsFilter((secretResults as CliResult.Success<SecretScanResult>).result)
98-
filter.exclude(byValue, byPath, byRuleId)
100+
filter.exclude(byValue, byPath, byRuleId, byCve)
99101
secretResults = CliResult.Success(filter.getFilteredScanResults())
100102
}
101103
if (scaResults is CliResult.Success) {
102104
val filter = ScaScanResultsFilter((scaResults as CliResult.Success<ScaScanResult>).result)
103-
filter.exclude(byValue, byPath, byRuleId)
105+
filter.exclude(byValue, byPath, byRuleId, byCve)
104106
scaResults = CliResult.Success(filter.getFilteredScanResults())
105107
}
106108
if (iacResults is CliResult.Success) {
107109
val filter = IacScanResultsFilter((iacResults as CliResult.Success<IacScanResult>).result)
108-
filter.exclude(byValue, byPath, byRuleId)
110+
filter.exclude(byValue, byPath, byRuleId, byCve)
109111
iacResults = CliResult.Success(filter.getFilteredScanResults())
110112
}
111113
if (sastResults is CliResult.Success) {
112114
val filter = SastScanResultsFilter((sastResults as CliResult.Success<SastScanResult>).result)
113-
filter.exclude(byValue, byPath, byRuleId)
115+
filter.exclude(byValue, byPath, byRuleId, byCve)
114116
sastResults = CliResult.Success(filter.getFilteredScanResults())
115117
}
116118
}

src/main/kotlin/com/cycode/plugin/services/scanResultsFilters/IacScanResultsFilter.kt

+4
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ class IacScanResultsFilter(scanResults: IacScanResult) : ScanResultsFilterBase<I
2929
}
3030
}
3131

32+
override fun excludeByCve(cve: String) {
33+
// do nothing because we don't have a value field in IaC
34+
}
35+
3236
override fun getFilteredScanResults(): IacScanResult {
3337
return filteredScanResults
3438
}

src/main/kotlin/com/cycode/plugin/services/scanResultsFilters/SastScanResultsFilter.kt

+5-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class SastScanResultsFilter(scanResults: SastScanResult) : ScanResultsFilterBase
1414
}
1515

1616
override fun excludeByValue(value: String) {
17-
// do nothing because we don't have a value field in IaC
17+
// do nothing because we don't have a value field in SAST
1818
}
1919

2020
override fun excludeByPath(path: String) {
@@ -29,6 +29,10 @@ class SastScanResultsFilter(scanResults: SastScanResult) : ScanResultsFilterBase
2929
}
3030
}
3131

32+
override fun excludeByCve(cve: String) {
33+
// do nothing because we don't have a value field in SAST
34+
}
35+
3236
override fun getFilteredScanResults(): SastScanResult {
3337
return filteredScanResults
3438
}

src/main/kotlin/com/cycode/plugin/services/scanResultsFilters/ScaScanResultsFilter.kt

+6
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ class ScaScanResultsFilter(scanResults: ScaScanResult) : ScanResultsFilterBase<S
2929
}
3030
}
3131

32+
override fun excludeByCve(cve: String) {
33+
filter { detection ->
34+
detection.detectionDetails.alert?.cveIdentifier != cve
35+
}
36+
}
37+
3238
override fun getFilteredScanResults(): ScaScanResult {
3339
return filteredScanResults
3440
}

src/main/kotlin/com/cycode/plugin/services/scanResultsFilters/ScanResultsFilterBase.kt

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package com.cycode.plugin.services.scanResultsFilters
22

33
abstract class ScanResultsFilterBase<T>(val scanResults: T) {
4-
fun exclude(byValue: String? = null, byPath: String? = null, byRuleId: String? = null) {
4+
fun exclude(byValue: String? = null, byPath: String? = null, byRuleId: String? = null, byCve: String? = null) {
55
if (byValue != null) {
66
excludeByValue(byValue)
77
}
@@ -11,6 +11,9 @@ abstract class ScanResultsFilterBase<T>(val scanResults: T) {
1111
if (byRuleId != null) {
1212
excludeByRuleId(byRuleId)
1313
}
14+
if (byCve != null) {
15+
excludeByCve(byCve)
16+
}
1417
}
1518

1619
abstract fun excludeByValue(value: String)
@@ -19,5 +22,7 @@ abstract class ScanResultsFilterBase<T>(val scanResults: T) {
1922

2023
abstract fun excludeByRuleId(ruleId: String)
2124

25+
abstract fun excludeByCve(cve: String)
26+
2227
abstract fun getFilteredScanResults(): T
2328
}

src/main/kotlin/com/cycode/plugin/services/scanResultsFilters/SecretScanResultsFilter.kt

+4
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ class SecretScanResultsFilter(scanResults: SecretScanResult) : ScanResultsFilter
3131
}
3232
}
3333

34+
override fun excludeByCve(cve: String) {
35+
// do nothing because we don't have a value field in Secrets
36+
}
37+
3438
override fun getFilteredScanResults(): SecretScanResult {
3539
return filteredScanResults
3640
}

src/main/resources/messages/CycodeBundle.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ violationCardCompanyGuidelinesTitle=Company Guidelines
105105
violationCardCycodeGuidelinesTitle=Cycode Guidelines
106106
violationCardAiRemediationTitle=AI Remediation
107107
generateAiRemediationBtn=Generate AI Remediation
108+
violationCardIgnoreViolationBtn=Ignore this violation
108109
# sca violation card
109110
scaViolationCardShortSummary=<html>{0} | {1}</html>
110111
scaViolationCardHeaderPackageField=Package:
@@ -119,7 +120,6 @@ secretViolationCardTitle=Hardcoded {0} is used
119120
secretViolationCardHeaderRuleIdField=Rule ID:
120121
secretViolationCardHeaderFileField=In file:
121122
secretViolationCardHeaderShaField=Secret SHA:
122-
secretViolationCardIgnoreViolationBtn=Ignore this violation
123123
# iac violation card
124124
iacViolationCardHeaderRuleIdField=Rule ID:
125125
iacViolationCardHeaderFileField=In file:

0 commit comments

Comments
 (0)