Skip to content

Commit

Permalink
feat: render html from snyk-ls
Browse files Browse the repository at this point in the history
  • Loading branch information
teodora-sandu committed Mar 26, 2024
1 parent 5ef2a28 commit 8f2d2fe
Show file tree
Hide file tree
Showing 11 changed files with 83 additions and 15 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Snyk Security Changelog

## [2.7.13]
### Added
- Render Snyk Code vulnerabilities using HTML served by the Language Server behind a feature flag.

## [2.7.12]
### Added
- Mark ignored findings as ignored behind a feature flag.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,4 +110,12 @@ object SnykBalloonNotificationHelper {
)
showBalloonForComponent(balloon, component, showAbove)
}
fun showErrorBalloonForComponent(message: String, component: Component, showAbove: Boolean = false) {
val balloon = createBalloon(
message,
AllIcons.General.BalloonError,
MessageType.ERROR.popupBackground
)
showBalloonForComponent(balloon, component, showAbove)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ object SnykBalloonNotifications {

const val sastForOrgEnablementMessage = "Snyk Code is disabled by your organisation's configuration."
const val networkErrorAlertMessage = "Not able to connect to Snyk server."
const val unexpectedErrorAlertMessage = "Something went wrong."

private val notificationGroup = NotificationGroupManager.getInstance().getNotificationGroup("Snyk")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,30 @@ package io.snyk.plugin.ui.toolwindow.panels

import com.intellij.ui.IdeBorderFactory
import com.intellij.ui.SideBorder
import com.intellij.ui.jcef.JBCefApp
import com.intellij.ui.jcef.JBCefBrowserBuilder
import com.intellij.ui.jcef.JBCefJSQuery
import com.intellij.uiDesigner.core.GridLayoutManager
import com.intellij.util.ui.JBUI
import com.intellij.util.ui.JBUI.Borders
import com.intellij.util.ui.UIUtil
import icons.SnykIcons
import io.snyk.plugin.Severity
import io.snyk.plugin.pluginSettings
import io.snyk.plugin.ui.DescriptionHeaderPanel
import io.snyk.plugin.ui.SnykBalloonNotificationHelper
import io.snyk.plugin.ui.SnykBalloonNotifications
import io.snyk.plugin.ui.addSpacer
import io.snyk.plugin.ui.baseGridConstraints
import io.snyk.plugin.ui.baseGridConstraintsAnchorWest
import io.snyk.plugin.ui.panelGridConstraints
import io.snyk.plugin.ui.wrapWithScrollPane
import org.cef.browser.CefBrowser
import org.cef.browser.CefFrame
import org.cef.handler.CefLoadHandlerAdapter
import snyk.common.lsp.LanguageServerWrapper
import java.awt.BorderLayout
import java.awt.Dimension
import java.awt.Font
import java.awt.Insets
import javax.swing.JButton
Expand All @@ -23,18 +36,43 @@ private val EMPTY_PANEL = JBUI.Panels.simplePanel()

abstract class IssueDescriptionPanelBase(
private val title: String,
private val severity: Severity
private val severity: Severity,
private val details: String?
) : JPanel(BorderLayout()), IssueDescriptionPanel {

/**
* **MUST** be invoked in derived class to actually create the UI elements.
* Can't be part of constructor due to `state` usage in underling abstract/open methods/props:
*/
protected fun createUI() {
this.add(
wrapWithScrollPane(descriptionBodyPanel()),
BorderLayout.CENTER
)
if (pluginSettings().isGlobalIgnoresFeatureEnabled) {
if (!JBCefApp.isSupported()) {
SnykBalloonNotificationHelper.showError("Something went wrong.", null)
return
}

val cefClient = JBCefApp.getInstance().createClient()
val jbCefBrowser = JBCefBrowserBuilder().setClient(cefClient).setEnableOpenDevToolsMenuItem(true).build()

val panel = JPanel()
panel.add(jbCefBrowser.component, BorderLayout())
this.add(
wrapWithScrollPane(panel),
BorderLayout.CENTER
)

if (this.details == null) {
SnykBalloonNotificationHelper.showError("Something went wrong.", null)
return
}

jbCefBrowser.loadHTML(this.details, jbCefBrowser.cefBrowser.url)

} else {
this.add(
wrapWithScrollPane(descriptionBodyPanel()),
BorderLayout.CENTER
)
}
if (isBottomPanelNeeded) {
this.add(
bottomPanel(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,11 @@ class SuggestionDescriptionPanel(
private val snykCodeFile: SnykCodeFile,
private val suggestion: SuggestionForFile,
private val suggestionIndex: Int
) : IssueDescriptionPanelBase(title = suggestion.title, severity = suggestion.getSeverityAsEnum()) {
) : IssueDescriptionPanelBase(
title = suggestion.title,
severity = suggestion.getSeverityAsEnum(),
details = null
) {
val project = snykCodeFile.project

private val suggestionRange: MyTextRange? = suggestion.ranges?.getOrNull(suggestionIndex)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@ import kotlin.math.max
class SuggestionDescriptionPanelFromLS(
snykCodeFile: SnykCodeFile,
private val issue: ScanIssue
) : IssueDescriptionPanelBase(title = getIssueTitle(issue), severity = issue.getSeverityAsEnum()) {
) : IssueDescriptionPanelBase(
title = getIssueTitle(issue),
severity = issue.getSeverityAsEnum(),
details = issue.additionalData.details
) {
val project = snykCodeFile.project

init {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ import javax.swing.JPanel

class VulnerabilityDescriptionPanel(
private val groupedVulns: Collection<Vulnerability>
) : IssueDescriptionPanelBase(title = groupedVulns.first().title, severity = groupedVulns.first().getSeverity()) {
) : IssueDescriptionPanelBase(
title = groupedVulns.first().title,
severity = groupedVulns.first().getSeverity(),
details = null) {

private val labelProvider: LabelProvider = LabelProvider()
private val vulnerability = groupedVulns.first()
Expand Down
5 changes: 3 additions & 2 deletions src/main/kotlin/snyk/common/lsp/Types.kt
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,7 @@ data class IssueData(
@SerializedName("priorityScore") val priorityScore: Int,
@SerializedName("hasAIFix") val hasAIFix: Boolean,
@SerializedName("dataFlow") val dataFlow: List<DataFlow>,
@SerializedName("isIgnored") val isIgnored: Boolean?,
@SerializedName("ignoreDetails") val ignoreDetails: IgnoreDetails?,
@SerializedName("details") val details: String,
) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
Expand Down Expand Up @@ -231,6 +230,7 @@ data class IssueData(
if (priorityScore != other.priorityScore) return false
if (hasAIFix != other.hasAIFix) return false
if (dataFlow != other.dataFlow) return false
if (details != other.details) return false

return true
}
Expand All @@ -251,6 +251,7 @@ data class IssueData(
result = 31 * result + priorityScore
result = 31 * result + hasAIFix.hashCode()
result = 31 * result + dataFlow.hashCode()
result = 31 * result + details.hashCode()
return result
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,11 @@ import javax.swing.JTextArea

class BaseImageRemediationDetailPanel(
private val project: Project,
private val imageIssues: ContainerIssuesForImage
private val imageIssues: ContainerIssuesForImage,
) : IssueDescriptionPanelBase(
title = imageIssues.imageName,
severity = imageIssues.getSeverities().maxOrNull() ?: Severity.UNKNOWN
severity = imageIssues.getSeverities().maxOrNull() ?: Severity.UNKNOWN,
details = null
) {

private val targetImages: List<KubernetesWorkloadImage> = getKubernetesImageCache(project)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ import javax.swing.JPanel

class ContainerIssueDetailPanel(
private val groupedVulns: Collection<ContainerIssue>
) : IssueDescriptionPanelBase(title = groupedVulns.first().title, severity = groupedVulns.first().getSeverity()) {
) : IssueDescriptionPanelBase(
title = groupedVulns.first().title,
severity = groupedVulns.first().getSeverity(),
details = null
) {

private val issue = groupedVulns.first()

Expand Down
2 changes: 1 addition & 1 deletion src/main/kotlin/snyk/iac/IacSuggestionDescriptionPanel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class IacSuggestionDescriptionPanel(
val issue: IacIssue,
val psiFile: PsiFile?,
val project: Project
) : IssueDescriptionPanelBase(title = issue.title, severity = issue.getSeverity()) {
) : IssueDescriptionPanelBase(title = issue.title, severity = issue.getSeverity(), details = null) {

private val labelProvider = LabelProvider()

Expand Down

0 comments on commit 8f2d2fe

Please sign in to comment.