Skip to content

Commit

Permalink
feat: intellij script for html (#538)
Browse files Browse the repository at this point in the history
  • Loading branch information
teodora-sandu authored Jun 4, 2024
1 parent 6e5ec6d commit 6ff3084
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 69 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Snyk Security Changelog


## [2.9.0]

### Added
- Inserts the IDE specific scripting.

## [2.8.1]
### Added
- Injects custom styling for the HTML panel used by Snyk Code for consistent ignores.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ import javax.swing.JPanel

class SuggestionDescriptionPanelFromLS(
snykFile: SnykFile,
private val issue: ScanIssue
private val issue: ScanIssue,
) : IssueDescriptionPanelBase(
title = issue.title(),
severity = issue.getSeverityAsEnum()
) {
title = issue.title(),
severity = issue.getSeverityAsEnum(),
) {
val project = snykFile.project
private val unexpectedErrorMessage =
"Snyk encountered an issue while rendering the vulnerability description. Please try again, or contact support if the problem persists. We apologize for any inconvenience caused."
Expand All @@ -39,26 +39,28 @@ class SuggestionDescriptionPanelFromLS(
) {
val openFileLoadHandlerGenerator = OpenFileLoadHandlerGenerator(snykFile)
val html = this.getStyledHTML()
val jbCefBrowserComponent = JCEFUtils.getJBCefBrowserComponentIfSupported(html) {
openFileLoadHandlerGenerator.generate(it)
}
val jbCefBrowserComponent =
JCEFUtils.getJBCefBrowserComponentIfSupported(html) {
openFileLoadHandlerGenerator.generate(it)
}
if (jbCefBrowserComponent == null) {
val statePanel = StatePanel(SnykToolWindowPanel.SELECT_ISSUE_TEXT)
this.add(wrapWithScrollPane(statePanel), BorderLayout.CENTER)
SnykBalloonNotificationHelper.showError(unexpectedErrorMessage, null)
} else {
val lastRowToAddSpacer = 5
val panel = JPanel(
GridLayoutManager(lastRowToAddSpacer + 1, 1, JBUI.insets(0, 10, 20, 10), -1, 20)
).apply {
this.add(
jbCefBrowserComponent,
panelGridConstraints(1)
)
}
val panel =
JPanel(
GridLayoutManager(lastRowToAddSpacer + 1, 1, JBUI.insets(0, 10, 20, 10), -1, 20),
).apply {
this.add(
jbCefBrowserComponent,
panelGridConstraints(1),
)
}
this.add(
wrapWithScrollPane(panel),
BorderLayout.CENTER
BorderLayout.CENTER,
)
this.add(panel)
}
Expand All @@ -67,61 +69,65 @@ class SuggestionDescriptionPanelFromLS(
}
}

override fun secondRowTitlePanel(): DescriptionHeaderPanel = descriptionHeaderPanel(
issueNaming = issue.issueNaming(),
cwes = issue.cwes(),
cvssScore = issue.cvssScore(),
cvssV3 = issue.cvssV3(),
cves = issue.cves(),
id = issue.id(),
)
override fun secondRowTitlePanel(): DescriptionHeaderPanel =
descriptionHeaderPanel(
issueNaming = issue.issueNaming(),
cwes = issue.cwes(),
cvssScore = issue.cvssScore(),
cvssV3 = issue.cvssV3(),
cves = issue.cves(),
id = issue.id(),
)

override fun createMainBodyPanel(): Pair<JPanel, Int> {
val lastRowToAddSpacer = 5
val panel = JPanel(
GridLayoutManager(lastRowToAddSpacer + 1, 1, JBUI.insets(0, 10, 20, 10), -1, 20)
).apply {
if (issue.additionalData.getProductType() == ProductType.CODE_SECURITY || issue.additionalData.getProductType() == ProductType.CODE_QUALITY) {
this.add(
SnykCodeOverviewPanel(issue.additionalData),
panelGridConstraints(2)
)
this.add(
SnykCodeDataflowPanel(project, issue.additionalData),
panelGridConstraints(3)
)
this.add(
SnykCodeExampleFixesPanel(issue.additionalData),
panelGridConstraints(4)
)
} else if (issue.additionalData.getProductType() == ProductType.OSS) {
this.add(
SnykOSSIntroducedThroughPanel(issue.additionalData),
baseGridConstraintsAnchorWest(1, indent = 0)
)
this.add(
SnykOSSDetailedPathsPanel(issue.additionalData),
panelGridConstraints(2)
)
this.add(
SnykOSSOverviewPanel(issue.additionalData),
panelGridConstraints(3)
)
} else {
TODO()
val panel =
JPanel(
GridLayoutManager(lastRowToAddSpacer + 1, 1, JBUI.insets(0, 10, 20, 10), -1, 20),
).apply {
if (issue.additionalData.getProductType() == ProductType.CODE_SECURITY || issue.additionalData.getProductType() == ProductType.CODE_QUALITY) {
this.add(
SnykCodeOverviewPanel(issue.additionalData),
panelGridConstraints(2),
)
this.add(
SnykCodeDataflowPanel(project, issue.additionalData),
panelGridConstraints(3),
)
this.add(
SnykCodeExampleFixesPanel(issue.additionalData),
panelGridConstraints(4),
)
} else if (issue.additionalData.getProductType() == ProductType.OSS) {
this.add(
SnykOSSIntroducedThroughPanel(issue.additionalData),
baseGridConstraintsAnchorWest(1, indent = 0),
)
this.add(
SnykOSSDetailedPathsPanel(issue.additionalData),
panelGridConstraints(2),
)
this.add(
SnykOSSOverviewPanel(issue.additionalData),
panelGridConstraints(3),
)
} else {
TODO()
}
}
}
return Pair(panel, lastRowToAddSpacer)
}

fun getStyledHTML(): String {
var html = issue.details()
var ideStyle = ""
if (issue.additionalData.getProductType() == ProductType.CODE_SECURITY || issue.additionalData.getProductType() == ProductType.CODE_QUALITY) {
if (issue.additionalData.getProductType() == ProductType.CODE_SECURITY ||
issue.additionalData.getProductType() == ProductType.CODE_QUALITY
) {
ideStyle = SnykStylesheets.SnykCodeSuggestion

}
html = html.replace("\${ideStyle}", "<style nonce=\${nonce}>$ideStyle</style>")
html = html.replace("\${ideScript}", "")

val nonce = getNonce()
html = html.replace("\${nonce}", nonce)
Expand All @@ -135,10 +141,12 @@ class SuggestionDescriptionPanelFromLS(
.map { allowedChars.random() }
.joinToString("")
}

}

fun defaultFontLabel(labelText: String, bold: Boolean = false): JLabel {
fun defaultFontLabel(
labelText: String,
bold: Boolean = false,
): JLabel {
return JLabel().apply {
val titleLabelFont: Font? = io.snyk.plugin.ui.getFont(if (bold) Font.BOLD else -1, 14, font)
titleLabelFont?.let { font = it }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
@file:Suppress("FunctionName")

package io.snyk.plugin.ui.toolwindow

import com.intellij.openapi.application.WriteAction
Expand All @@ -10,14 +11,13 @@ import io.mockk.mockk
import io.mockk.mockkObject
import io.mockk.unmockkAll
import io.snyk.plugin.Severity
import io.snyk.plugin.SnykFile
import io.snyk.plugin.pluginSettings
import io.snyk.plugin.resetSettings
import io.snyk.plugin.SnykFile
import io.snyk.plugin.ui.jcef.JCEFUtils
import io.snyk.plugin.ui.toolwindow.panels.SuggestionDescriptionPanelFromLS
import org.eclipse.lsp4j.Position
import org.eclipse.lsp4j.Range
import org.junit.Before
import org.junit.Test
import snyk.UIComponentFinder.getJBCEFBrowser
import snyk.UIComponentFinder.getJLabelByText
Expand Down Expand Up @@ -67,10 +67,18 @@ class SuggestionDescriptionPanelFromLSCodeTest : BasePlatformTestCase() {
every { issue.additionalData.getProductType() } returns ProductType.CODE_SECURITY
every { issue.additionalData.message } returns "Test message"
every { issue.additionalData.repoDatasetSize } returns 1
every { issue.additionalData.exampleCommitFixes } returns listOf(ExampleCommitFix("https://commit-url", listOf(
CommitChangeLine("1", 1, "lineChange")
)))
every { issue.additionalData.dataFlow } returns listOf(DataFlow(0, getTestDataPath(), Range(Position(1, 1), Position(1, 1)), ""))
every { issue.additionalData.exampleCommitFixes } returns
listOf(
ExampleCommitFix(
"https://commit-url",
listOf(
CommitChangeLine("1", 1, "lineChange"),
),
),
)
every {
issue.additionalData.dataFlow
} returns listOf(DataFlow(0, getTestDataPath(), Range(Position(1, 1), Position(1, 1)), ""))
}

@Test
Expand Down Expand Up @@ -149,7 +157,9 @@ class SuggestionDescriptionPanelFromLSCodeTest : BasePlatformTestCase() {

val mockJBCefBrowserComponent = JLabel("<html>HTML message</html>")
mockkObject(JCEFUtils)
every { JCEFUtils.getJBCefBrowserComponentIfSupported(eq("<html>HTML message</html>"), any()) } returns mockJBCefBrowserComponent
every {
JCEFUtils.getJBCefBrowserComponentIfSupported(eq("<html>HTML message</html>"), any())
} returns mockJBCefBrowserComponent

every { issue.details() } returns "<html>HTML message</html>"
every { issue.canLoadSuggestionPanelFromHTML() } returns true
Expand All @@ -172,6 +182,7 @@ class SuggestionDescriptionPanelFromLSCodeTest : BasePlatformTestCase() {

val actual = cut.getStyledHTML()
assertFalse(actual.contains("\${ideStyle}"))
assertFalse(actual.contains("\${ideScript}"))
assertFalse(actual.contains("\${nonce}"))
assertTrue(actual.contains(".ignore-warning"))
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
@file:Suppress("FunctionName")

package io.snyk.plugin.ui.toolwindow

import com.intellij.openapi.application.WriteAction
Expand All @@ -9,11 +10,10 @@ import io.mockk.every
import io.mockk.mockk
import io.mockk.unmockkAll
import io.snyk.plugin.Severity
import io.snyk.plugin.SnykFile
import io.snyk.plugin.pluginSettings
import io.snyk.plugin.resetSettings
import io.snyk.plugin.SnykFile
import io.snyk.plugin.ui.toolwindow.panels.SuggestionDescriptionPanelFromLS
import org.junit.Before
import org.junit.Test
import snyk.UIComponentFinder.getActionLinkByText
import snyk.UIComponentFinder.getJLabelByText
Expand Down Expand Up @@ -118,6 +118,7 @@ class SuggestionDescriptionPanelFromLSOSSTest : BasePlatformTestCase() {

// we don't apply any custom style for oss
assertFalse(actual.contains("\${ideStyle}"))
assertFalse(actual.contains("\${ideScript}"))
assertFalse(actual.contains(".ignore-warning"))
}
}

0 comments on commit 6ff3084

Please sign in to comment.