From 6943335f31a66164ebd6d4c8934136692f6b83a9 Mon Sep 17 00:00:00 2001 From: Antoine Vinot Date: Wed, 14 Dec 2022 11:46:51 +0100 Subject: [PATCH] SONAR-17671 Add description context key for taint vulnerabilities --- .../pushevent/PushEventFactory.java | 18 ++++++------ .../pushevent/TaintVulnerabilityRaised.java | 12 ++++++-- .../pushevent/PushEventFactoryTest.java | 29 +++++++++++++++++-- .../org/sonar/db/issue/IssueMapper.xml | 3 +- .../sonar/server/issue/ws/BasePullAction.java | 2 +- ...ullTaintActionProtobufObjectGenerator.java | 1 + .../server/issue/ws/pull-taint-example.proto | 2 ++ .../server/issue/ws/PullTaintActionTest.java | 10 +++++-- sonar-ws/src/main/protobuf/ws-issues.proto | 1 + 9 files changed, 60 insertions(+), 18 deletions(-) diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/pushevent/PushEventFactory.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/pushevent/PushEventFactory.java index 30b12214562..85e5218b402 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/pushevent/PushEventFactory.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/pushevent/PushEventFactory.java @@ -99,22 +99,22 @@ public class PushEventFactory { event.setSeverity(issue.severity()); event.setRuleKey(issue.getRuleKey().toString()); event.setType(issue.type().name()); - event.setBranch(analysisMetadataHolder.getBranch().getName()); + event.setMainLocation(prepareMainLocation(component, issue)); + event.setFlows(flowGenerator.convertFlows(component.getName(), requireNonNull(issue.getLocations()))); + issue.getRuleDescriptionContextKey().ifPresent(event::setRuleDescriptionContextKey); + return event; + } + private static Location prepareMainLocation(Component component, DefaultIssue issue) { DbIssues.Locations issueLocations = requireNonNull(issue.getLocations()); + TextRange mainLocationTextRange = getTextRange(issueLocations.getTextRange(), issueLocations.getChecksum()); Location mainLocation = new Location(); - mainLocation.setMessage(issue.getMessage()); - + Optional.ofNullable(issue.getMessage()).ifPresent(mainLocation::setMessage); mainLocation.setFilePath(component.getName()); - - TextRange mainLocationTextRange = getTextRange(issueLocations.getTextRange(), issueLocations.getChecksum()); mainLocation.setTextRange(mainLocationTextRange); - event.setMainLocation(mainLocation); - - event.setFlows(flowGenerator.convertFlows(component.getName(), issueLocations)); - return event; + return mainLocation; } private static PushEventDto raiseTaintVulnerabilityClosedEvent(String projectUuid, DefaultIssue issue) { diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/pushevent/TaintVulnerabilityRaised.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/pushevent/TaintVulnerabilityRaised.java index a3ddd139ef6..d490bcf7fb7 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/pushevent/TaintVulnerabilityRaised.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/pushevent/TaintVulnerabilityRaised.java @@ -20,6 +20,7 @@ package org.sonar.ce.task.projectanalysis.pushevent; import java.util.List; +import java.util.Optional; import org.sonar.ce.task.projectanalysis.locations.flow.Flow; import org.sonar.ce.task.projectanalysis.locations.flow.Location; @@ -32,10 +33,9 @@ public class TaintVulnerabilityRaised { private String ruleKey; private String severity; private String type; - private Location mainLocation; - private List flows; + private String ruleDescriptionContextKey; public TaintVulnerabilityRaised() { // nothing to do @@ -112,4 +112,12 @@ public class TaintVulnerabilityRaised { public void setFlows(List flows) { this.flows = flows; } + + public Optional getRuleDescriptionContextKey() { + return Optional.ofNullable(ruleDescriptionContextKey); + } + + public void setRuleDescriptionContextKey(String ruleDescriptionContextKey) { + this.ruleDescriptionContextKey = ruleDescriptionContextKey; + } } diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/pushevent/PushEventFactoryTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/pushevent/PushEventFactoryTest.java index 1b4a04e3d5d..55959eb9a8f 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/pushevent/PushEventFactoryTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/pushevent/PushEventFactoryTest.java @@ -19,6 +19,8 @@ */ package org.sonar.ce.task.projectanalysis.pushevent; +import com.google.gson.Gson; +import java.nio.charset.StandardCharsets; import java.util.Date; import java.util.List; import org.junit.Before; @@ -39,19 +41,24 @@ import org.sonar.db.protobuf.DbCommons; import org.sonar.db.protobuf.DbIssues; import org.sonar.server.issue.TaintChecker; +import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; public class PushEventFactoryTest { + private static final Gson gson = new Gson(); + private static final String BRANCH_NAME = "develop"; + private final TaintChecker taintChecker = mock(TaintChecker.class); @Rule public MutableTreeRootHolderRule treeRootHolder = new MutableTreeRootHolderRule(); @Rule public AnalysisMetadataHolderRule analysisMetadataHolder = new AnalysisMetadataHolderRule() - .setBranch(new TestBranch("develop")); + .setBranch(new TestBranch(BRANCH_NAME)); private final FlowGenerator flowGenerator = new FlowGenerator(treeRootHolder); private final PushEventFactory underTest = new PushEventFactory(treeRootHolder, analysisMetadataHolder, taintChecker, flowGenerator); @@ -67,19 +74,35 @@ public class PushEventFactoryTest { @Test public void raise_event_to_repository_if_taint_vulnerability_is_new() { DefaultIssue defaultIssue = createDefaultIssue() - .setNew(true); + .setNew(true) + .setRuleDescriptionContextKey(randomAlphabetic(6)); assertThat(underTest.raiseEventOnIssue("some-project-uuid", defaultIssue)) .isNotEmpty() .hasValueSatisfying(pushEventDto -> { assertThat(pushEventDto.getName()).isEqualTo("TaintVulnerabilityRaised"); - assertThat(pushEventDto.getPayload()).isNotNull(); + verifyPayload(pushEventDto.getPayload(), defaultIssue); assertThat(pushEventDto.getLanguage()).isEqualTo("java"); assertThat(pushEventDto.getProjectUuid()).isEqualTo("some-project-uuid"); }); } + private static void verifyPayload(byte[] payload, DefaultIssue defaultIssue) { + assertThat(payload).isNotNull(); + + TaintVulnerabilityRaised taintVulnerabilityRaised = gson.fromJson(new String(payload, StandardCharsets.UTF_8), TaintVulnerabilityRaised.class); + assertThat(taintVulnerabilityRaised.getProjectKey()).isEqualTo(defaultIssue.projectKey()); + assertThat(taintVulnerabilityRaised.getCreationDate()).isEqualTo(defaultIssue.creationDate().getTime()); + assertThat(taintVulnerabilityRaised.getKey()).isEqualTo(defaultIssue.key()); + assertThat(taintVulnerabilityRaised.getSeverity()).isEqualTo(defaultIssue.severity()); + assertThat(taintVulnerabilityRaised.getRuleKey()).isEqualTo(defaultIssue.ruleKey().toString()); + assertThat(taintVulnerabilityRaised.getType()).isEqualTo(defaultIssue.type().name()); + assertThat(taintVulnerabilityRaised.getBranch()).isEqualTo(BRANCH_NAME); + String ruleDescriptionContextKey = taintVulnerabilityRaised.getRuleDescriptionContextKey().orElseGet(() -> fail("No rule description context key")); + assertThat(ruleDescriptionContextKey).isEqualTo(defaultIssue.getRuleDescriptionContextKey().orElse(null)); + } + @Test public void raise_event_to_repository_if_taint_vulnerability_is_reopened() { DefaultIssue defaultIssue = createDefaultIssue() diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/issue/IssueMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/issue/IssueMapper.xml index 655c142af2e..b8126c88f96 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/issue/IssueMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/issue/IssueMapper.xml @@ -702,7 +702,8 @@ i.issue_type as type, i.locations as locations, i.component_uuid as component_uuid, - i.assignee as assigneeUuid + i.assignee as assigneeUuid, + i.rule_description_context_key as ruleDescriptionContextKey