]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-10913 Exclude security hotspots and manual vulnerabilities from /batch/issues
authorJanos Gyerik <janos.gyerik@sonarsource.com>
Mon, 18 Jun 2018 14:36:46 +0000 (16:36 +0200)
committersonartech <sonartech@sonarsource.com>
Wed, 4 Jul 2018 07:31:04 +0000 (09:31 +0200)
server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueDao.java
server/sonar-db-dao/src/main/resources/org/sonar/db/issue/IssueMapper.xml
server/sonar-db-dao/src/test/java/org/sonar/db/issue/IssueDaoTest.java
server/sonar-server/src/main/java/org/sonar/server/batch/IssuesAction.java
server/sonar-server/src/test/java/org/sonar/server/batch/IssuesActionTest.java

index abefc0aed3e6e4fed8aa855cadc6092cd0115fa6..33b2a60c1e892e32cb045e206bd11531e45b27f4 100644 (file)
@@ -61,11 +61,11 @@ public class IssueDao implements Dao {
     return mapper(session).selectComponentUuidsOfOpenIssuesForProjectUuid(projectUuid);
   }
 
-  public List<IssueDto> selectNonClosedByComponentUuidExcludingExternals(DbSession dbSession, String componentUuid) {
+  public List<IssueDto> selectNonClosedByComponentUuidExcludingExternalsAndSecurityHotspots(DbSession dbSession, String componentUuid) {
     return mapper(dbSession).selectNonClosedByComponentUuidExcludingExternals(componentUuid);
   }
 
-  public List<IssueDto> selectNonClosedByModuleOrProjectExcludingExternals(DbSession dbSession, ComponentDto module) {
+  public List<IssueDto> selectNonClosedByModuleOrProjectExcludingExternalsAndSecurityHotspots(DbSession dbSession, ComponentDto module) {
     String likeModuleUuidPath = buildLikeValue(module.moduleUuidPath(), WildcardPosition.AFTER);
     return mapper(dbSession).selectNonClosedByModuleOrProject(module.projectUuid(), likeModuleUuidPath);
   }
index 63468133dd1d81828206737872f22e3afac11279..3c30811cc82c4e9a11a02e2dd307773d609a1cc3 100644 (file)
     where
     (r.is_external is NULL or r.is_external = ${_false}) and
     i.component_uuid = #{componentUuid,jdbcType=VARCHAR} and
-    i.status &lt;&gt; 'CLOSED'
+    i.status &lt;&gt; 'CLOSED' and
+    i.issue_type &lt;&gt; 4 and (i.from_hotspot is NULL or i.from_hotspot = ${_false})
   </select>
 
   <select id="selectComponentUuidsOfOpenIssuesForProjectUuid" parameterType="string" resultType="string">
     (r.is_external is NULL or r.is_external = ${_false}) and
     i.project_uuid = #{projectUuid, jdbcType=VARCHAR} and
     p.module_uuid_path like  #{likeModuleUuidPath, jdbcType=VARCHAR} escape '/' and
-    i.status &lt;&gt; 'CLOSED'
+    i.status &lt;&gt; 'CLOSED' and
+    i.issue_type &lt;&gt; 4 and (i.from_hotspot is NULL or i.from_hotspot = ${_false})
   </select>
 
   <select id="selectIssueGroupsByBaseComponent" resultType="org.sonar.db.issue.IssueGroupDto" parameterType="map">
index 6fb7664d5eb570462e53a2d211b2ecb0303850ce..4e1c60fb9964ea9b7aa4dcee966aa94956c3d4ae 100644 (file)
@@ -24,6 +24,7 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 
+import java.util.stream.Stream;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
@@ -42,6 +43,7 @@ import org.sonar.db.rule.RuleDto;
 import org.sonar.db.rule.RuleTesting;
 
 import static java.util.Arrays.asList;
+import static org.apache.commons.lang.math.RandomUtils.nextInt;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.junit.rules.ExpectedException.none;
 import static org.sonar.db.component.ComponentTesting.newFileDto;
@@ -57,6 +59,10 @@ public class IssueDaoTest {
   private static final String ISSUE_KEY1 = "I1";
   private static final String ISSUE_KEY2 = "I2";
 
+  private static final RuleType[] RULE_TYPES_EXCEPT_HOTSPOT = Stream.of(RuleType.values())
+    .filter(r -> r != RuleType.SECURITY_HOTSPOT)
+    .toArray(RuleType[]::new);
+
   @Rule
   public ExpectedException expectedException = none();
   @Rule
@@ -127,23 +133,26 @@ public class IssueDaoTest {
     RuleDefinitionDto rule = db.rules().insert();
     ComponentDto project = db.components().insertPrivateProject();
     ComponentDto file = db.components().insertComponent(newFileDto(project));
-    IssueDto openIssue1OnFile = db.issues().insert(rule, project, file, i -> i.setStatus("OPEN").setResolution(null));
-    IssueDto openIssue2OnFile = db.issues().insert(rule, project, file, i -> i.setStatus("OPEN").setResolution(null));
-    IssueDto closedIssueOnFile = db.issues().insert(rule, project, file, i -> i.setStatus("CLOSED").setResolution("FIXED"));
-    IssueDto openIssueOnProject = db.issues().insert(rule, project, project, i -> i.setStatus("OPEN").setResolution(null));
+    IssueDto openIssue1OnFile = db.issues().insert(rule, project, file, i -> i.setStatus("OPEN").setResolution(null).setType(randomRuleTypeExceptHotspot()));
+    IssueDto openIssue2OnFile = db.issues().insert(rule, project, file, i -> i.setStatus("OPEN").setResolution(null).setType(randomRuleTypeExceptHotspot()));
+    IssueDto closedIssueOnFile = db.issues().insert(rule, project, file, i -> i.setStatus("CLOSED").setResolution("FIXED").setType(randomRuleTypeExceptHotspot()));
+    IssueDto openIssueOnProject = db.issues().insert(rule, project, project, i -> i.setStatus("OPEN").setResolution(null).setType(randomRuleTypeExceptHotspot()));
+
+    IssueDto securityHotspot = db.issues().insert(rule, project, file, i -> i.setType(RuleType.SECURITY_HOTSPOT));
+    IssueDto manualVulnerability = db.issues().insert(rule, project, file, i -> i.setType(RuleType.VULNERABILITY).setIsFromHotspot(true));
 
     RuleDefinitionDto external = db.rules().insert(ruleDefinitionDto -> ruleDefinitionDto.setIsExternal(true));
-    IssueDto issueFromExteralruleOnFile = db.issues().insert(external, project, file, i -> i.setKee("ON_FILE_FROM_EXTERNAL"));
+    IssueDto issueFromExteralruleOnFile = db.issues().insert(external, project, file, i -> i.setKee("ON_FILE_FROM_EXTERNAL").setType(randomRuleTypeExceptHotspot()));
 
-    assertThat(underTest.selectNonClosedByComponentUuidExcludingExternals(db.getSession(), file.uuid()))
+    assertThat(underTest.selectNonClosedByComponentUuidExcludingExternalsAndSecurityHotspots(db.getSession(), file.uuid()))
       .extracting(IssueDto::getKey)
       .containsExactlyInAnyOrder(Arrays.stream(new IssueDto[] {openIssue1OnFile, openIssue2OnFile}).map(IssueDto::getKey).toArray(String[]::new));
 
-    assertThat(underTest.selectNonClosedByComponentUuidExcludingExternals(db.getSession(), project.uuid()))
+    assertThat(underTest.selectNonClosedByComponentUuidExcludingExternalsAndSecurityHotspots(db.getSession(), project.uuid()))
       .extracting(IssueDto::getKey)
       .containsExactlyInAnyOrder(Arrays.stream(new IssueDto[] {openIssueOnProject}).map(IssueDto::getKey).toArray(String[]::new));
 
-    assertThat(underTest.selectNonClosedByComponentUuidExcludingExternals(db.getSession(), "does_not_exist")).isEmpty();
+    assertThat(underTest.selectNonClosedByComponentUuidExcludingExternalsAndSecurityHotspots(db.getSession(), "does_not_exist")).isEmpty();
   }
 
   @Test
@@ -153,26 +162,29 @@ public class IssueDaoTest {
     ComponentDto anotherProject = db.components().insertPrivateProject();
     ComponentDto module = db.components().insertComponent(newModuleDto(project));
     ComponentDto file = db.components().insertComponent(newFileDto(module));
-    IssueDto openIssue1OnFile = db.issues().insert(rule, project, file, i -> i.setStatus("OPEN").setResolution(null));
-    IssueDto openIssue2OnFile = db.issues().insert(rule, project, file, i -> i.setStatus("OPEN").setResolution(null));
-    IssueDto closedIssueOnFile = db.issues().insert(rule, project, file, i -> i.setStatus("CLOSED").setResolution("FIXED"));
-    IssueDto openIssueOnModule = db.issues().insert(rule, project, module, i -> i.setStatus("OPEN").setResolution(null));
-    IssueDto openIssueOnProject = db.issues().insert(rule, project, project, i -> i.setStatus("OPEN").setResolution(null));
-    IssueDto openIssueOnAnotherProject = db.issues().insert(rule, anotherProject, anotherProject, i -> i.setStatus("OPEN").setResolution(null));
+    IssueDto openIssue1OnFile = db.issues().insert(rule, project, file, i -> i.setStatus("OPEN").setResolution(null).setType(randomRuleTypeExceptHotspot()));
+    IssueDto openIssue2OnFile = db.issues().insert(rule, project, file, i -> i.setStatus("OPEN").setResolution(null).setType(randomRuleTypeExceptHotspot()));
+    IssueDto closedIssueOnFile = db.issues().insert(rule, project, file, i -> i.setStatus("CLOSED").setResolution("FIXED").setType(randomRuleTypeExceptHotspot()));
+    IssueDto openIssueOnModule = db.issues().insert(rule, project, module, i -> i.setStatus("OPEN").setResolution(null).setType(randomRuleTypeExceptHotspot()));
+    IssueDto openIssueOnProject = db.issues().insert(rule, project, project, i -> i.setStatus("OPEN").setResolution(null).setType(randomRuleTypeExceptHotspot()));
+    IssueDto openIssueOnAnotherProject = db.issues().insert(rule, anotherProject, anotherProject, i -> i.setStatus("OPEN").setResolution(null).setType(randomRuleTypeExceptHotspot()));
+
+    IssueDto securityHotspot = db.issues().insert(rule, project, file, i -> i.setType(RuleType.SECURITY_HOTSPOT));
+    IssueDto manualVulnerability = db.issues().insert(rule, project, file, i -> i.setType(RuleType.VULNERABILITY).setIsFromHotspot(true));
 
     RuleDefinitionDto external = db.rules().insert(ruleDefinitionDto -> ruleDefinitionDto.setIsExternal(true));
-    IssueDto issueFromExteralruleOnFile = db.issues().insert(external, project, file, i -> i.setKee("ON_FILE_FROM_EXTERNAL"));
+    IssueDto issueFromExteralruleOnFile = db.issues().insert(external, project, file, i -> i.setKee("ON_FILE_FROM_EXTERNAL").setType(randomRuleTypeExceptHotspot()));
 
-    assertThat(underTest.selectNonClosedByModuleOrProjectExcludingExternals(db.getSession(), project))
+    assertThat(underTest.selectNonClosedByModuleOrProjectExcludingExternalsAndSecurityHotspots(db.getSession(), project))
       .extracting(IssueDto::getKey)
       .containsExactlyInAnyOrder(Arrays.stream(new IssueDto[] {openIssue1OnFile, openIssue2OnFile, openIssueOnModule, openIssueOnProject}).map(IssueDto::getKey).toArray(String[]::new));
 
-    assertThat(underTest.selectNonClosedByModuleOrProjectExcludingExternals(db.getSession(), module))
+    assertThat(underTest.selectNonClosedByModuleOrProjectExcludingExternalsAndSecurityHotspots(db.getSession(), module))
       .extracting(IssueDto::getKey)
       .containsExactlyInAnyOrder(Arrays.stream(new IssueDto[] {openIssue1OnFile, openIssue2OnFile, openIssueOnModule}).map(IssueDto::getKey).toArray(String[]::new));
 
     ComponentDto notPersisted = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
-    assertThat(underTest.selectNonClosedByModuleOrProjectExcludingExternals(db.getSession(), notPersisted)).isEmpty();
+    assertThat(underTest.selectNonClosedByModuleOrProjectExcludingExternalsAndSecurityHotspots(db.getSession(), notPersisted)).isEmpty();
   }
 
   @Test
@@ -321,4 +333,8 @@ public class IssueDaoTest {
       .setProjectUuid(PROJECT_UUID));
     db.getSession().commit();
   }
+
+  private static RuleType randomRuleTypeExceptHotspot() {
+    return RULE_TYPES_EXCEPT_HOTSPOT[nextInt(RULE_TYPES_EXCEPT_HOTSPOT.length)];
+  }
 }
index 01055bb34f9caadfcf836ff8b45502b2a1bf88b5..753bc883fa27520448ef70d774ca1dda3c602371 100644 (file)
@@ -104,10 +104,10 @@ public class IssuesAction implements BatchWsAction {
       List<IssueDto> issueDtos = new ArrayList<>();
       switch (component.scope()) {
         case Scopes.PROJECT:
-          issueDtos.addAll(dbClient.issueDao().selectNonClosedByModuleOrProjectExcludingExternals(dbSession, component));
+          issueDtos.addAll(dbClient.issueDao().selectNonClosedByModuleOrProjectExcludingExternalsAndSecurityHotspots(dbSession, component));
           break;
         case Scopes.FILE:
-          issueDtos.addAll(dbClient.issueDao().selectNonClosedByComponentUuidExcludingExternals(dbSession, component.uuid()));
+          issueDtos.addAll(dbClient.issueDao().selectNonClosedByComponentUuidExcludingExternalsAndSecurityHotspots(dbSession, component.uuid()));
           break;
         default:
           // only projects, modules and files are supported. Other types of components are not allowed.
index 195086c3d3b9bd55a9da81f61f0e6e384b0f7b13..35961c13d98d28512cbcb6c60e8065833a9b4070 100644 (file)
 package org.sonar.server.batch;
 
 import java.io.IOException;
+import java.util.stream.Stream;
 import javax.annotation.Nullable;
 import org.assertj.core.groups.Tuple;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
+import org.sonar.api.rules.RuleType;
 import org.sonar.api.utils.System2;
 import org.sonar.api.web.UserRole;
 import org.sonar.core.util.CloseableIterator;
@@ -45,6 +47,7 @@ import org.sonar.server.ws.TestResponse;
 import org.sonar.server.ws.WsActionTester;
 
 import static java.lang.String.format;
+import static org.apache.commons.lang.math.RandomUtils.nextInt;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.tuple;
 import static org.sonar.api.rules.RuleType.BUG;
@@ -54,6 +57,10 @@ import static org.sonar.db.component.ComponentTesting.newModuleDto;
 
 public class IssuesActionTest {
 
+  private static final RuleType[] RULE_TYPES_EXCEPT_HOTSPOT = Stream.of(RuleType.values())
+    .filter(r -> r != RuleType.SECURITY_HOTSPOT)
+    .toArray(RuleType[]::new);
+
   private System2 system2 = System2.INSTANCE;
 
   @Rule
@@ -146,9 +153,9 @@ public class IssuesActionTest {
     ComponentDto project = db.components().insertPrivateProject();
     ComponentDto module = db.components().insertComponent(newModuleDto(project));
     ComponentDto file = db.components().insertComponent(newFileDto(module, null));
-    IssueDto issueOnFile = db.issues().insert(rule, project, file, i -> i.setKee("ON_FILE"));
-    IssueDto issueOnModule = db.issues().insert(rule, project, module, i -> i.setKee("ON_MODULE"));
-    IssueDto issueOnProject = db.issues().insert(rule, project, project, i -> i.setKee("ON_PROJECT"));
+    IssueDto issueOnFile = db.issues().insert(rule, project, file, i -> i.setKee("ON_FILE").setType(randomRuleTypeExceptHotspot()));
+    IssueDto issueOnModule = db.issues().insert(rule, project, module, i -> i.setKee("ON_MODULE").setType(randomRuleTypeExceptHotspot()));
+    IssueDto issueOnProject = db.issues().insert(rule, project, project, i -> i.setKee("ON_PROJECT").setType(randomRuleTypeExceptHotspot()));
 
     addPermissionTo(project);
     try (CloseableIterator<ServerIssue> result = callStream(project.getKey(), null)) {
@@ -167,16 +174,16 @@ public class IssuesActionTest {
     ComponentDto project = db.components().insertPrivateProject();
     ComponentDto module = db.components().insertComponent(newModuleDto(project));
     ComponentDto file = db.components().insertComponent(newFileDto(module, null));
-    IssueDto issueOnProject = db.issues().insert(rule, project, project, i -> i.setKee("ON_PROJECT"));
-    IssueDto issueOnModule = db.issues().insert(rule, project, module, i -> i.setKee("ON_MODULE"));
-    IssueDto issueOnFile = db.issues().insert(rule, project, file, i -> i.setKee("ON_FILE"));
+    IssueDto issueOnProject = db.issues().insert(rule, project, project, i -> i.setKee("ON_PROJECT").setType(randomRuleTypeExceptHotspot()));
+    IssueDto issueOnModule = db.issues().insert(rule, project, module, i -> i.setKee("ON_MODULE").setType(randomRuleTypeExceptHotspot()));
+    IssueDto issueOnFile = db.issues().insert(rule, project, file, i -> i.setKee("ON_FILE").setType(randomRuleTypeExceptHotspot()));
 
     RuleDefinitionDto external = db.rules().insert(ruleDefinitionDto -> ruleDefinitionDto.setIsExternal(true));
-    IssueDto issueFromExteralruleOnFile = db.issues().insert(external, project, file, i -> i.setKee("ON_FILE_FROM_EXTERNAL"));
+    IssueDto issueFromExteralruleOnFile = db.issues().insert(external, project, file, i -> i.setKee("ON_FILE_FROM_EXTERNAL").setType(randomRuleTypeExceptHotspot()));
     
     RuleDefinitionDto migrated = db.rules().insert();
     db.executeUpdateSql("update rules set is_external = NULL where rules.id = ?", migrated.getId());
-    IssueDto issueFromMigratedRule = db.issues().insert(migrated, project, file, i -> i.setKee("MIGRATED"));
+    IssueDto issueFromMigratedRule = db.issues().insert(migrated, project, file, i -> i.setKee("MIGRATED").setType(randomRuleTypeExceptHotspot()));
 
     addPermissionTo(project);
     try (CloseableIterator<ServerIssue> result = callStream(project.getKey(), null)) {
@@ -196,9 +203,9 @@ public class IssuesActionTest {
     ComponentDto project = db.components().insertPrivateProject();
     ComponentDto module = db.components().insertComponent(newModuleDto(project));
     ComponentDto file = db.components().insertComponent(newFileDto(module, null));
-    IssueDto issueOnFile = db.issues().insert(rule, project, file, i -> i.setKee("ON_FILE"));
-    IssueDto issueOnModule = db.issues().insert(rule, project, module, i -> i.setKee("ON_MODULE"));
-    IssueDto issueOnProject = db.issues().insert(rule, project, project, i -> i.setKee("ON_PROJECT"));
+    IssueDto issueOnFile = db.issues().insert(rule, project, file, i -> i.setKee("ON_FILE").setType(randomRuleTypeExceptHotspot()));
+    IssueDto issueOnModule = db.issues().insert(rule, project, module, i -> i.setKee("ON_MODULE").setType(randomRuleTypeExceptHotspot()));
+    IssueDto issueOnProject = db.issues().insert(rule, project, project, i -> i.setKee("ON_PROJECT").setType(randomRuleTypeExceptHotspot()));
 
     addPermissionTo(project);
     try (CloseableIterator<ServerIssue> result = callStream(module.getKey(), null)) {
@@ -216,9 +223,9 @@ public class IssuesActionTest {
     ComponentDto project = db.components().insertPrivateProject();
     ComponentDto module = db.components().insertComponent(newModuleDto(project));
     ComponentDto file = db.components().insertComponent(newFileDto(module, null));
-    IssueDto issueOnFile = db.issues().insert(rule, project, file);
-    IssueDto issueOnModule = db.issues().insert(rule, project, module);
-    IssueDto issueOnProject = db.issues().insert(rule, project, project);
+    IssueDto issueOnFile = db.issues().insert(rule, project, file, i -> i.setType(randomRuleTypeExceptHotspot()));
+    IssueDto issueOnModule = db.issues().insert(rule, project, module, i -> i.setType(randomRuleTypeExceptHotspot()));
+    IssueDto issueOnProject = db.issues().insert(rule, project, project, i -> i.setType(randomRuleTypeExceptHotspot()));
 
     addPermissionTo(project);
     try (CloseableIterator<ServerIssue> result = callStream(file.getKey(), null)) {
@@ -236,8 +243,8 @@ public class IssuesActionTest {
     addPermissionTo(project);
     ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setKey("my_branch"));
     ComponentDto file = db.components().insertComponent(newFileDto(branch));
-    IssueDto issueOnFile = db.issues().insert(rule, branch, file);
-    IssueDto issueOnBranch = db.issues().insert(rule, branch, branch);
+    IssueDto issueOnFile = db.issues().insert(rule, branch, file, i -> i.setType(randomRuleTypeExceptHotspot()));
+    IssueDto issueOnBranch = db.issues().insert(rule, branch, branch, i -> i.setType(randomRuleTypeExceptHotspot()));
 
     assertResult(project.getKey(), "my_branch",
       tuple(issueOnFile.getKey(), branch.getKey()),
@@ -253,9 +260,9 @@ public class IssuesActionTest {
     ComponentDto module = db.components().insertComponent(newModuleDto(branch));
     ComponentDto subModule = db.components().insertComponent(newModuleDto(module));
     ComponentDto file = db.components().insertComponent(newFileDto(subModule));
-    IssueDto issueOnFile = db.issues().insert(rule, branch, file);
-    IssueDto issueOnSubModule = db.issues().insert(rule, branch, subModule);
-    IssueDto issueOnModule = db.issues().insert(rule, branch, module);
+    IssueDto issueOnFile = db.issues().insert(rule, branch, file, i -> i.setType(randomRuleTypeExceptHotspot()));
+    IssueDto issueOnSubModule = db.issues().insert(rule, branch, subModule, i -> i.setType(randomRuleTypeExceptHotspot()));
+    IssueDto issueOnModule = db.issues().insert(rule, branch, module, i -> i.setType(randomRuleTypeExceptHotspot()));
 
     assertResult(module.getKey(), "my_branch",
       tuple(issueOnFile.getKey(), subModule.getKey()),
@@ -282,7 +289,7 @@ public class IssuesActionTest {
     ComponentDto project = db.components().insertPrivateProject();
     ComponentDto module = db.components().insertComponent(newModuleDto(project).setEnabled(false));
     ComponentDto file = db.components().insertComponent(newFileDto(module, null).setEnabled(false));
-    IssueDto issue = db.issues().insert(rule, project, file);
+    IssueDto issue = db.issues().insert(rule, project, file, i -> i.setType(randomRuleTypeExceptHotspot()));
 
     addPermissionTo(project);
     try (CloseableIterator<ServerIssue> result = callStream(project.getKey(), null)) {
@@ -351,4 +358,8 @@ public class IssuesActionTest {
         .containsExactlyInAnyOrder(tuples);
     }
   }
+
+  private RuleType randomRuleTypeExceptHotspot() {
+    return RULE_TYPES_EXCEPT_HOTSPOT[nextInt(RULE_TYPES_EXCEPT_HOTSPOT.length)];
+  }
 }