aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/issue/index/SecurityStandardCategoryStatistics.java16
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/issue/workflow/IssueWorkflow.java25
-rw-r--r--server/sonar-server-common/src/test/java/org/sonar/server/issue/workflow/IssueWorkflowForSecurityHotspotsTest.java245
-rw-r--r--server/sonar-server-common/src/test/java/org/sonar/server/issue/workflow/IssueWorkflowTest.java117
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndex.java21
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/issue/ws/DoTransitionAction.java9
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualitygate/changeevent/QGChangeEventListener.java3
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualitygate/changeevent/QGChangeEventListenersImpl.java2
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexSecurityReportsTest.java104
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/qualitygate/changeevent/QGChangeEventListenersImplTest.java2
-rw-r--r--server/sonar-server/src/test/resources/com/sonar/governance/securityreport/ws/ShowActionTest/empty.json22
-rw-r--r--server/sonar-server/src/test/resources/com/sonar/governance/securityreport/ws/ShowActionTest/owaspNoCwe.json22
-rw-r--r--server/sonar-server/src/test/resources/com/sonar/governance/securityreport/ws/ShowActionTest/sansWithCwe.json8
-rw-r--r--server/sonar-server/src/test/resources/com/sonar/governance/securityreport/ws/ShowActionTest/sonarsourceSecurityNoCwe.json40
-rw-r--r--server/sonar-server/src/test/resources/com/sonar/governance/securityreport/ws/ShowActionTest/sonarsourceSecurityOnApplication.json42
-rw-r--r--server/sonar-server/src/test/resources/com/sonar/governance/securityreport/ws/ShowActionTest/sonarsourceSecurityWithCwe.json42
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/issue/DefaultTransitions.java10
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/issue/Issue.java5
-rw-r--r--sonar-ws/src/main/protobuf/ws-security.proto8
19 files changed, 448 insertions, 295 deletions
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/SecurityStandardCategoryStatistics.java b/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/SecurityStandardCategoryStatistics.java
index 11a45cb4946..4148b57c121 100644
--- a/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/SecurityStandardCategoryStatistics.java
+++ b/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/SecurityStandardCategoryStatistics.java
@@ -28,20 +28,20 @@ public class SecurityStandardCategoryStatistics {
private final String category;
private final long vulnerabilities;
private final OptionalInt vulnerabiliyRating;
+ private final long inReviewSecurityHotspots;
private final long toReviewSecurityHotspots;
- private final long openSecurityHotspots;
private final long wontFixSecurityHotspots;
private final List<SecurityStandardCategoryStatistics> children;
private long activeRules;
private long totalRules;
- public SecurityStandardCategoryStatistics(String category, long vulnerabilities, OptionalInt vulnerabiliyRating, long toReviewSecurityHotspots, long openSecurityHotspots,
- long wontFixSecurityHotspots, @Nullable List<SecurityStandardCategoryStatistics> children) {
+ public SecurityStandardCategoryStatistics(String category, long vulnerabilities, OptionalInt vulnerabiliyRating, long inReviewSecurityHotspots, long toReviewSecurityHotspots,
+ long wontFixSecurityHotspots, @Nullable List<SecurityStandardCategoryStatistics> children) {
this.category = category;
this.vulnerabilities = vulnerabilities;
this.vulnerabiliyRating = vulnerabiliyRating;
+ this.inReviewSecurityHotspots = inReviewSecurityHotspots;
this.toReviewSecurityHotspots = toReviewSecurityHotspots;
- this.openSecurityHotspots = openSecurityHotspots;
this.wontFixSecurityHotspots = wontFixSecurityHotspots;
this.children = children;
}
@@ -58,12 +58,12 @@ public class SecurityStandardCategoryStatistics {
return vulnerabiliyRating;
}
- public long getToReviewSecurityHotspots() {
- return toReviewSecurityHotspots;
+ public long getInReviewSecurityHotspots() {
+ return inReviewSecurityHotspots;
}
- public long getOpenSecurityHotspots() {
- return openSecurityHotspots;
+ public long getToReviewSecurityHotspots() {
+ return toReviewSecurityHotspots;
}
public long getWontFixSecurityHotspots() {
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/workflow/IssueWorkflow.java b/server/sonar-server-common/src/main/java/org/sonar/server/issue/workflow/IssueWorkflow.java
index 1a7cfe32e1b..eea7b1e28e7 100644
--- a/server/sonar-server-common/src/main/java/org/sonar/server/issue/workflow/IssueWorkflow.java
+++ b/server/sonar-server-common/src/main/java/org/sonar/server/issue/workflow/IssueWorkflow.java
@@ -39,6 +39,7 @@ import static org.sonar.api.issue.Issue.RESOLUTION_REMOVED;
import static org.sonar.api.issue.Issue.RESOLUTION_WONT_FIX;
import static org.sonar.api.issue.Issue.STATUS_CLOSED;
import static org.sonar.api.issue.Issue.STATUS_CONFIRMED;
+import static org.sonar.api.issue.Issue.STATUS_IN_REVIEW;
import static org.sonar.api.issue.Issue.STATUS_OPEN;
import static org.sonar.api.issue.Issue.STATUS_REOPENED;
import static org.sonar.api.issue.Issue.STATUS_RESOLVED;
@@ -61,7 +62,7 @@ public class IssueWorkflow implements Startable {
@Override
public void start() {
StateMachine.Builder builder = StateMachine.builder()
- .states(STATUS_OPEN, STATUS_CONFIRMED, STATUS_REOPENED, STATUS_RESOLVED, STATUS_CLOSED, STATUS_TO_REVIEW);
+ .states(STATUS_OPEN, STATUS_CONFIRMED, STATUS_REOPENED, STATUS_RESOLVED, STATUS_CLOSED, STATUS_TO_REVIEW, STATUS_IN_REVIEW);
buildManualTransitions(builder);
buildAutomaticTransitions(builder);
buildSecurityHotspotTransitions(builder);
@@ -149,6 +150,12 @@ public class IssueWorkflow implements Startable {
private static void buildSecurityHotspotTransitions(StateMachine.Builder builder) {
builder
+ .transition(Transition.builder(DefaultTransitions.SET_AS_IN_REVIEW)
+ .from(STATUS_TO_REVIEW).to(STATUS_IN_REVIEW)
+ .conditions(new HasType(RuleType.SECURITY_HOTSPOT))
+ .requiredProjectPermission(UserRole.SECURITYHOTSPOT_ADMIN)
+ .build())
+
.transition(Transition.builder(DefaultTransitions.DETECT)
.from(STATUS_TO_REVIEW).to(STATUS_OPEN)
.conditions(new HasType(RuleType.SECURITY_HOTSPOT))
@@ -167,16 +174,6 @@ public class IssueWorkflow implements Startable {
.functions(new SetType(RuleType.SECURITY_HOTSPOT))
.requiredProjectPermission(UserRole.SECURITYHOTSPOT_ADMIN)
.build())
- .transition(Transition.builder(DefaultTransitions.REQUEST_REVIEW)
- .from(STATUS_OPEN).to(STATUS_RESOLVED)
- .conditions(IsManualVulnerability.INSTANCE)
- .functions(new SetType(RuleType.SECURITY_HOTSPOT), new SetResolution(RESOLUTION_FIXED))
- .build())
- .transition(Transition.builder(DefaultTransitions.REQUEST_REVIEW)
- .from(STATUS_REOPENED).to(STATUS_RESOLVED)
- .conditions(IsManualVulnerability.INSTANCE)
- .functions(new SetType(RuleType.SECURITY_HOTSPOT), new SetResolution(RESOLUTION_FIXED))
- .build())
.transition(Transition.builder(DefaultTransitions.REJECT)
.from(STATUS_RESOLVED).to(STATUS_REOPENED)
.conditions(new HasType(RuleType.SECURITY_HOTSPOT), new HasResolution(RESOLUTION_FIXED))
@@ -236,6 +233,12 @@ public class IssueWorkflow implements Startable {
.functions(SetClosed.INSTANCE, SetCloseDate.INSTANCE)
.automatic()
.build())
+ .transition(Transition.builder(AUTOMATIC_CLOSE_TRANSITION)
+ .from(STATUS_IN_REVIEW).to(STATUS_CLOSED)
+ .conditions(IsBeingClosed.INSTANCE, new HasType(RuleType.SECURITY_HOTSPOT))
+ .functions(SetClosed.INSTANCE, SetCloseDate.INSTANCE)
+ .automatic()
+ .build())
// Reopen issues that are marked as resolved but that are still alive.
.transition(Transition.builder("automaticreopen")
diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/issue/workflow/IssueWorkflowForSecurityHotspotsTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/issue/workflow/IssueWorkflowForSecurityHotspotsTest.java
new file mode 100644
index 00000000000..03bb3584109
--- /dev/null
+++ b/server/sonar-server-common/src/test/java/org/sonar/server/issue/workflow/IssueWorkflowForSecurityHotspotsTest.java
@@ -0,0 +1,245 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.issue.workflow;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Collections2;
+import com.tngtech.java.junit.dataprovider.DataProvider;
+import com.tngtech.java.junit.dataprovider.DataProviderRunner;
+import com.tngtech.java.junit.dataprovider.UseDataProvider;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import javax.annotation.Nullable;
+import org.apache.commons.lang.time.DateUtils;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.sonar.api.issue.DefaultTransitions;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.rules.RuleType;
+import org.sonar.core.issue.DefaultIssue;
+import org.sonar.core.issue.FieldDiffs;
+import org.sonar.core.issue.IssueChangeContext;
+import org.sonar.server.issue.IssueFieldsSetter;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.api.issue.Issue.RESOLUTION_FIXED;
+import static org.sonar.api.issue.Issue.RESOLUTION_REMOVED;
+import static org.sonar.api.issue.Issue.RESOLUTION_WONT_FIX;
+import static org.sonar.api.issue.Issue.STATUS_CLOSED;
+import static org.sonar.api.issue.Issue.STATUS_IN_REVIEW;
+import static org.sonar.api.issue.Issue.STATUS_RESOLVED;
+import static org.sonar.api.issue.Issue.STATUS_TO_REVIEW;
+import static org.sonar.db.rule.RuleTesting.XOO_X1;
+
+@RunWith(DataProviderRunner.class)
+public class IssueWorkflowForSecurityHotspotsTest {
+
+ private static final String[] ALL_STATUSES_LEADING_TO_CLOSED = new String[] {STATUS_TO_REVIEW, STATUS_IN_REVIEW, STATUS_RESOLVED};
+
+ private static final String[] SUPPORTED_RESOLUTIONS_FOR_UNCLOSING = new String[] {RESOLUTION_FIXED, RESOLUTION_REMOVED};
+
+ private IssueFieldsSetter updater = new IssueFieldsSetter();
+
+ private IssueWorkflow underTest = new IssueWorkflow(new FunctionExecutor(updater), updater);
+
+ @Test
+ public void list_out_transitions_in_status_to_review() {
+ underTest.start();
+ DefaultIssue issue = new DefaultIssue().setType(RuleType.SECURITY_HOTSPOT).setStatus(STATUS_TO_REVIEW);
+
+ List<Transition> transitions = underTest.outTransitions(issue);
+
+ assertThat(keys(transitions)).containsOnly("setinreview", "detect", "clear");
+ }
+
+ @Test
+ public void list_out_transitions_in_status_in_review() {
+ underTest.start();
+ DefaultIssue issue = new DefaultIssue().setType(RuleType.SECURITY_HOTSPOT).setStatus(STATUS_IN_REVIEW);
+
+ List<Transition> transitions = underTest.outTransitions(issue);
+
+ assertThat(keys(transitions)).isEmpty();
+ }
+
+ @Test
+ public void set_as_in_review() {
+ underTest.start();
+ DefaultIssue issue = new DefaultIssue()
+ .setType(RuleType.SECURITY_HOTSPOT)
+ .setIsFromHotspot(true)
+ .setStatus(STATUS_TO_REVIEW);
+
+ boolean result = underTest.doManualTransition(issue, DefaultTransitions.SET_AS_IN_REVIEW, IssueChangeContext.createUser(new Date(), "USER1"));
+
+ assertThat(result).isTrue();
+ assertThat(issue.getStatus()).isEqualTo(STATUS_IN_REVIEW);
+ assertThat(issue.resolution()).isNull();
+ }
+
+ @Test
+ public void automatically_close_resolved_security_hotspots_in_status_to_review() {
+ underTest.start();
+ DefaultIssue issue = new DefaultIssue()
+ .setType(RuleType.SECURITY_HOTSPOT)
+ .setResolution(null)
+ .setStatus(STATUS_TO_REVIEW)
+ .setNew(false)
+ .setBeingClosed(true);
+ Date now = new Date();
+
+ underTest.doAutomaticTransition(issue, IssueChangeContext.createScan(now));
+
+ assertThat(issue.resolution()).isEqualTo(RESOLUTION_FIXED);
+ assertThat(issue.status()).isEqualTo(STATUS_CLOSED);
+ assertThat(issue.closeDate()).isNotNull();
+ assertThat(issue.updateDate()).isEqualTo(DateUtils.truncate(now, Calendar.SECOND));
+ }
+
+ @Test
+ public void automatically_close_resolved_security_hotspots_in_status_in_review() {
+ underTest.start();
+ DefaultIssue issue = new DefaultIssue()
+ .setType(RuleType.SECURITY_HOTSPOT)
+ .setResolution(null)
+ .setStatus(STATUS_IN_REVIEW)
+ .setNew(false)
+ .setBeingClosed(true);
+ Date now = new Date();
+
+ underTest.doAutomaticTransition(issue, IssueChangeContext.createScan(now));
+
+ assertThat(issue.resolution()).isEqualTo(RESOLUTION_FIXED);
+ assertThat(issue.status()).isEqualTo(STATUS_CLOSED);
+ assertThat(issue.closeDate()).isNotNull();
+ assertThat(issue.updateDate()).isEqualTo(DateUtils.truncate(now, Calendar.SECOND));
+ }
+
+ @Test
+ @UseDataProvider("allStatusesLeadingToClosed")
+ public void do_not_automatically_reopen_closed_issues_of_security_hotspots(String previousStatus) {
+ DefaultIssue[] issues = Arrays.stream(SUPPORTED_RESOLUTIONS_FOR_UNCLOSING)
+ .map(resolution -> {
+ DefaultIssue issue = newClosedIssue(resolution);
+ setStatusPreviousToClosed(issue, previousStatus);
+ issue.setType(RuleType.SECURITY_HOTSPOT);
+ return issue;
+ })
+ .toArray(DefaultIssue[]::new);
+ Date now = new Date();
+ underTest.start();
+
+ Arrays.stream(issues).forEach(issue -> {
+ underTest.doAutomaticTransition(issue, IssueChangeContext.createScan(now));
+
+ assertThat(issue.status()).isEqualTo(STATUS_CLOSED);
+ assertThat(issue.updateDate()).isNull();
+ });
+ }
+
+ @Test
+ public void doAutomaticTransition_does_nothing_on_security_hotspots_in_to_review_status() {
+ DefaultIssue issue = new DefaultIssue()
+ .setKey("ABCDE")
+ .setRuleKey(XOO_X1)
+ .setResolution(null)
+ .setStatus(STATUS_TO_REVIEW);
+
+ underTest.start();
+ underTest.doAutomaticTransition(issue, IssueChangeContext.createScan(new Date()));
+
+ assertThat(issue.status()).isEqualTo(STATUS_TO_REVIEW);
+ assertThat(issue.resolution()).isNull();
+ }
+
+ @Test
+ @UseDataProvider("allStatusesLeadingToClosed")
+ public void do_not_automatically_reopen_closed_issues_of_manual_vulnerability(String previousStatus) {
+ DefaultIssue[] issues = Arrays.stream(SUPPORTED_RESOLUTIONS_FOR_UNCLOSING)
+ .map(resolution -> {
+ DefaultIssue issue = newClosedIssue(resolution);
+ setStatusPreviousToClosed(issue, previousStatus);
+ issue.setIsFromHotspot(true);
+ return issue;
+ })
+ .toArray(DefaultIssue[]::new);
+ Date now = new Date();
+ underTest.start();
+
+ Arrays.stream(issues).forEach(issue -> {
+ underTest.doAutomaticTransition(issue, IssueChangeContext.createScan(now));
+
+ assertThat(issue.status()).isEqualTo(STATUS_CLOSED);
+ assertThat(issue.updateDate()).isNull();
+ });
+ }
+
+ @DataProvider
+ public static Object[][] allStatusesLeadingToClosed() {
+ return Arrays.stream(ALL_STATUSES_LEADING_TO_CLOSED)
+ .map(t -> new Object[] {t})
+ .toArray(Object[][]::new);
+ }
+
+ @Test
+ public void do_not_allow_to_doManualTransition_when_condition_fails() {
+ underTest.start();
+ DefaultIssue issue = new DefaultIssue()
+ .setKey("ABCDE")
+ // Detect is only available on hotspot
+ .setType(RuleType.VULNERABILITY)
+ .setIsFromHotspot(true)
+ .setStatus(STATUS_RESOLVED)
+ .setResolution(RESOLUTION_WONT_FIX)
+ .setRuleKey(XOO_X1);
+
+ assertThat(underTest.doManualTransition(issue, DefaultTransitions.DETECT, IssueChangeContext.createScan(new Date()))).isFalse();
+ }
+
+ private static DefaultIssue newClosedIssue(String resolution) {
+ return new DefaultIssue()
+ .setKey("ABCDE")
+ .setRuleKey(RuleKey.of("js", "S001"))
+ .setResolution(resolution)
+ .setStatus(STATUS_CLOSED)
+ .setNew(false)
+ .setCloseDate(new Date(5_999_999L));
+ }
+
+ private static void setStatusPreviousToClosed(DefaultIssue issue, String previousStatus) {
+ addStatusChange(issue, new Date(), previousStatus, STATUS_CLOSED);
+ }
+
+ private static void addStatusChange(DefaultIssue issue, Date date, String previousStatus, String newStatus) {
+ issue.addChange(new FieldDiffs().setCreationDate(date).setDiff("status", previousStatus, newStatus));
+ }
+
+ private Collection<String> keys(List<Transition> transitions) {
+ return Collections2.transform(transitions, new Function<Transition, String>() {
+ @Override
+ public String apply(@Nullable Transition transition) {
+ return transition.key();
+ }
+ });
+ }
+}
diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/issue/workflow/IssueWorkflowTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/issue/workflow/IssueWorkflowTest.java
index 4151f7280b6..a8b7c9998d4 100644
--- a/server/sonar-server-common/src/test/java/org/sonar/server/issue/workflow/IssueWorkflowTest.java
+++ b/server/sonar-server-common/src/test/java/org/sonar/server/issue/workflow/IssueWorkflowTest.java
@@ -24,6 +24,7 @@ import com.google.common.collect.Collections2;
import com.tngtech.java.junit.dataprovider.DataProvider;
import com.tngtech.java.junit.dataprovider.DataProviderRunner;
import com.tngtech.java.junit.dataprovider.UseDataProvider;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
@@ -36,7 +37,6 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.sonar.api.issue.DefaultTransitions;
import org.sonar.api.rule.RuleKey;
-import org.sonar.api.rules.RuleType;
import org.sonar.core.issue.DefaultIssue;
import org.sonar.core.issue.FieldDiffs;
import org.sonar.core.issue.IssueChangeContext;
@@ -52,11 +52,11 @@ import static org.sonar.api.issue.Issue.RESOLUTION_REMOVED;
import static org.sonar.api.issue.Issue.RESOLUTION_WONT_FIX;
import static org.sonar.api.issue.Issue.STATUS_CLOSED;
import static org.sonar.api.issue.Issue.STATUS_CONFIRMED;
+import static org.sonar.api.issue.Issue.STATUS_IN_REVIEW;
import static org.sonar.api.issue.Issue.STATUS_OPEN;
import static org.sonar.api.issue.Issue.STATUS_REOPENED;
import static org.sonar.api.issue.Issue.STATUS_RESOLVED;
import static org.sonar.api.issue.Issue.STATUS_TO_REVIEW;
-import static org.sonar.db.rule.RuleTesting.XOO_X1;
@RunWith(DataProviderRunner.class)
public class IssueWorkflowTest {
@@ -68,7 +68,14 @@ public class IssueWorkflowTest {
@Test
public void list_statuses() {
underTest.start();
- assertThat(underTest.statusKeys()).containsExactly(STATUS_OPEN, STATUS_CONFIRMED, STATUS_REOPENED, STATUS_RESOLVED, STATUS_CLOSED, STATUS_TO_REVIEW);
+
+ List<String> expectedStatus = new ArrayList<>();
+ // issues statuses
+ expectedStatus.addAll(Arrays.asList(STATUS_OPEN, STATUS_CONFIRMED, STATUS_REOPENED, STATUS_RESOLVED, STATUS_CLOSED));
+ // hostpots statuses
+ expectedStatus.addAll(Arrays.asList(STATUS_TO_REVIEW, STATUS_IN_REVIEW));
+
+ assertThat(underTest.statusKeys()).containsExactlyInAnyOrder(expectedStatus.toArray(new String[]{}));
}
@Test
@@ -117,16 +124,6 @@ public class IssueWorkflowTest {
}
@Test
- public void list_out_transitions_from_security_hotspot_in_status_to_review() {
- underTest.start();
- DefaultIssue issue = new DefaultIssue().setType(RuleType.SECURITY_HOTSPOT).setStatus(STATUS_TO_REVIEW);
-
- List<Transition> transitions = underTest.outTransitions(issue);
-
- assertThat(keys(transitions)).containsOnly("detect", "clear");
- }
-
- @Test
public void fail_if_unknown_status_when_listing_transitions() {
underTest.start();
@@ -159,27 +156,6 @@ public class IssueWorkflowTest {
}
@Test
- public void automatically_close_resolved_security_hotspots_in_to_review() {
- underTest.start();
- DefaultIssue issue = new DefaultIssue()
- .setKey("ABCDE")
- .setType(RuleType.SECURITY_HOTSPOT)
- .setRuleKey(XOO_X1)
- .setResolution(null)
- .setStatus(STATUS_TO_REVIEW)
- .setNew(false)
- .setBeingClosed(true);
- Date now = new Date();
-
- underTest.doAutomaticTransition(issue, IssueChangeContext.createScan(now));
-
- assertThat(issue.resolution()).isEqualTo(RESOLUTION_FIXED);
- assertThat(issue.status()).isEqualTo(STATUS_CLOSED);
- assertThat(issue.closeDate()).isNotNull();
- assertThat(issue.updateDate()).isEqualTo(DateUtils.truncate(now, Calendar.SECOND));
- }
-
- @Test
@UseDataProvider("allStatusesLeadingToClosed")
public void automatically_reopen_closed_issue_to_its_previous_status_from_changelog(String previousStatus) {
DefaultIssue[] issues = Arrays.stream(SUPPORTED_RESOLUTIONS_FOR_UNCLOSING)
@@ -328,64 +304,6 @@ public class IssueWorkflowTest {
});
}
- @Test
- @UseDataProvider("allStatusesLeadingToClosed")
- public void do_not_automatically_reopen_closed_issues_of_security_hotspots(String previousStatus) {
- DefaultIssue[] issues = Arrays.stream(SUPPORTED_RESOLUTIONS_FOR_UNCLOSING)
- .map(resolution -> {
- DefaultIssue issue = newClosedIssue(resolution);
- setStatusPreviousToClosed(issue, previousStatus);
- issue.setType(RuleType.SECURITY_HOTSPOT);
- return issue;
- })
- .toArray(DefaultIssue[]::new);
- Date now = new Date();
- underTest.start();
-
- Arrays.stream(issues).forEach(issue -> {
- underTest.doAutomaticTransition(issue, IssueChangeContext.createScan(now));
-
- assertThat(issue.status()).isEqualTo(STATUS_CLOSED);
- assertThat(issue.updateDate()).isNull();
- });
- }
-
- @Test
- public void doAutomaticTransition_does_nothing_on_security_hotspots_in_to_review_status() {
- DefaultIssue issue = new DefaultIssue()
- .setKey("ABCDE")
- .setRuleKey(XOO_X1)
- .setResolution(null)
- .setStatus(STATUS_TO_REVIEW);
-
- underTest.start();
- underTest.doAutomaticTransition(issue, IssueChangeContext.createScan(new Date()));
-
- assertThat(issue.status()).isEqualTo(STATUS_TO_REVIEW);
- assertThat(issue.resolution()).isNull();
- }
-
- @Test
- @UseDataProvider("allStatusesLeadingToClosed")
- public void do_not_automatically_reopen_closed_issues_of_manual_vulnerability(String previousStatus) {
- DefaultIssue[] issues = Arrays.stream(SUPPORTED_RESOLUTIONS_FOR_UNCLOSING)
- .map(resolution -> {
- DefaultIssue issue = newClosedIssue(resolution);
- setStatusPreviousToClosed(issue, previousStatus);
- issue.setIsFromHotspot(true);
- return issue;
- })
- .toArray(DefaultIssue[]::new);
- Date now = new Date();
- underTest.start();
-
- Arrays.stream(issues).forEach(issue -> {
- underTest.doAutomaticTransition(issue, IssueChangeContext.createScan(now));
-
- assertThat(issue.status()).isEqualTo(STATUS_CLOSED);
- assertThat(issue.updateDate()).isNull();
- });
- }
private static final String[] ALL_STATUSES_LEADING_TO_CLOSED = new String[] {STATUS_OPEN, STATUS_REOPENED, STATUS_CONFIRMED, STATUS_RESOLVED};
private static final String[] ALL_RESOLUTIONS_BEFORE_CLOSING = new String[] {
null,
@@ -511,21 +429,6 @@ public class IssueWorkflowTest {
assertThat(issue.assignee()).isNull();
}
- @Test
- public void do_not_allow_to_doManualTransition_when_condition_fails() {
- underTest.start();
- DefaultIssue issue = new DefaultIssue()
- .setKey("ABCDE")
- // Detect is only available on hotspot
- .setType(RuleType.VULNERABILITY)
- .setIsFromHotspot(true)
- .setStatus(STATUS_RESOLVED)
- .setResolution(RESOLUTION_WONT_FIX)
- .setRuleKey(XOO_X1);
-
- assertThat(underTest.doManualTransition(issue, DefaultTransitions.DETECT, IssueChangeContext.createScan(new Date()))).isFalse();
- }
-
private static DefaultIssue newClosedIssue(String resolution) {
return new DefaultIssue()
.setKey("ABCDE")
diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndex.java b/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndex.java
index 580edfee6aa..b2949e27210 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndex.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndex.java
@@ -192,20 +192,21 @@ public class IssueIndex {
private static final int MAX_FACET_SIZE = 100;
private static final String AGG_VULNERABILITIES = "vulnerabilities";
private static final String AGG_SEVERITIES = "severities";
- private static final String AGG_OPEN_SECURITY_HOTSPOTS = "openSecurityHotspots";
private static final String AGG_TO_REVIEW_SECURITY_HOTSPOTS = "toReviewSecurityHotspots";
+ private static final String AGG_IN_REVIEW_SECURITY_HOTSPOTS = "inReviewSecurityHotspots";
private static final String AGG_WONT_FIX_SECURITY_HOTSPOTS = "wontFixSecurityHotspots";
private static final String AGG_CWES = "cwes";
private static final BoolQueryBuilder NON_RESOLVED_VULNERABILITIES_FILTER = boolQuery()
.filter(termQuery(FIELD_ISSUE_TYPE, VULNERABILITY.name()))
.mustNot(existsQuery(FIELD_ISSUE_RESOLUTION));
- private static final BoolQueryBuilder NON_RESOLVED_HOTSTPOS_FILTER = boolQuery()
+ private static final BoolQueryBuilder IN_REVIEW_HOTSPOTS_FILTER = boolQuery()
.filter(termQuery(FIELD_ISSUE_TYPE, SECURITY_HOTSPOT.name()))
+ .filter(termQuery(FIELD_ISSUE_STATUS, Issue.STATUS_IN_REVIEW))
.mustNot(existsQuery(FIELD_ISSUE_RESOLUTION));
private static final BoolQueryBuilder TO_REVIEW_HOTSPOTS_FILTER = boolQuery()
.filter(termQuery(FIELD_ISSUE_TYPE, SECURITY_HOTSPOT.name()))
- .filter(termQuery(FIELD_ISSUE_STATUS, Issue.STATUS_RESOLVED))
- .filter(termQuery(FIELD_ISSUE_RESOLUTION, Issue.RESOLUTION_FIXED));
+ .filter(termQuery(FIELD_ISSUE_STATUS, Issue.STATUS_TO_REVIEW))
+ .mustNot(existsQuery(FIELD_ISSUE_RESOLUTION));
private static final BoolQueryBuilder WONT_FIX_HOTSPOTS_FILTER = boolQuery()
.filter(termQuery(FIELD_ISSUE_TYPE, SECURITY_HOTSPOT.name()))
.filter(termQuery(FIELD_ISSUE_STATUS, Issue.STATUS_RESOLVED))
@@ -927,14 +928,14 @@ public class IssueIndex {
.mapToInt(b -> Severity.ALL.indexOf(b.getKeyAsString()) + 1)
.max();
- long openSecurityHotspots = ((InternalValueCount) ((InternalFilter) categoryBucket.getAggregations().get(AGG_OPEN_SECURITY_HOTSPOTS)).getAggregations().get(AGG_COUNT))
- .getValue();
long toReviewSecurityHotspots = ((InternalValueCount) ((InternalFilter) categoryBucket.getAggregations().get(AGG_TO_REVIEW_SECURITY_HOTSPOTS)).getAggregations().get(AGG_COUNT))
.getValue();
+ long inReviewSecurityHotspots = ((InternalValueCount) ((InternalFilter) categoryBucket.getAggregations().get(AGG_IN_REVIEW_SECURITY_HOTSPOTS)).getAggregations().get(AGG_COUNT))
+ .getValue();
long wontFixSecurityHotspots = ((InternalValueCount) ((InternalFilter) categoryBucket.getAggregations().get(AGG_WONT_FIX_SECURITY_HOTSPOTS)).getAggregations().get(AGG_COUNT))
.getValue();
- return new SecurityStandardCategoryStatistics(categoryName, vulnerabilities, severityRating, toReviewSecurityHotspots, openSecurityHotspots,
+ return new SecurityStandardCategoryStatistics(categoryName, vulnerabilities, severityRating, inReviewSecurityHotspots, toReviewSecurityHotspots,
wontFixSecurityHotspots, children);
}
@@ -962,10 +963,10 @@ public class IssueIndex {
AggregationBuilders.terms(AGG_SEVERITIES).field(FIELD_ISSUE_SEVERITY)
.subAggregation(
AggregationBuilders.count(AGG_COUNT).field(FIELD_ISSUE_KEY))))
- .subAggregation(AggregationBuilders.filter(AGG_OPEN_SECURITY_HOTSPOTS, NON_RESOLVED_HOTSTPOS_FILTER)
+ .subAggregation(AggregationBuilders.filter(AGG_TO_REVIEW_SECURITY_HOTSPOTS, TO_REVIEW_HOTSPOTS_FILTER)
.subAggregation(
AggregationBuilders.count(AGG_COUNT).field(FIELD_ISSUE_KEY)))
- .subAggregation(AggregationBuilders.filter(AGG_TO_REVIEW_SECURITY_HOTSPOTS, TO_REVIEW_HOTSPOTS_FILTER)
+ .subAggregation(AggregationBuilders.filter(AGG_IN_REVIEW_SECURITY_HOTSPOTS, IN_REVIEW_HOTSPOTS_FILTER)
.subAggregation(
AggregationBuilders.count(AGG_COUNT).field(FIELD_ISSUE_KEY)))
.subAggregation(AggregationBuilders.filter(AGG_WONT_FIX_SECURITY_HOTSPOTS, WONT_FIX_HOTSPOTS_FILTER)
@@ -990,8 +991,8 @@ public class IssueIndex {
.setQuery(
componentFilter
.should(NON_RESOLVED_VULNERABILITIES_FILTER)
- .should(NON_RESOLVED_HOTSTPOS_FILTER)
.should(TO_REVIEW_HOTSPOTS_FILTER)
+ .should(IN_REVIEW_HOTSPOTS_FILTER)
.should(WONT_FIX_HOTSPOTS_FILTER)
.minimumShouldMatch(1))
.setSize(0);
diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/ws/DoTransitionAction.java b/server/sonar-server/src/main/java/org/sonar/server/issue/ws/DoTransitionAction.java
index dd3cfb81bd9..972e8f7c38b 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/issue/ws/DoTransitionAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/issue/ws/DoTransitionAction.java
@@ -38,6 +38,8 @@ import org.sonar.server.issue.IssueUpdater;
import org.sonar.server.issue.TransitionService;
import org.sonar.server.user.UserSession;
+import static java.lang.String.format;
+import static org.sonar.api.issue.DefaultTransitions.SET_AS_IN_REVIEW;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.ACTION_DO_TRANSITION;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_ISSUE;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_TRANSITION;
@@ -68,12 +70,13 @@ public class DoTransitionAction implements IssuesWsAction {
WebService.NewAction action = controller.createAction(ACTION_DO_TRANSITION)
.setDescription("Do workflow transition on an issue. Requires authentication and Browse permission on project.<br/>" +
"The transitions '" + DefaultTransitions.WONT_FIX + "' and '" + DefaultTransitions.FALSE_POSITIVE + "' require the permission 'Administer Issues'.<br/>" +
- "The transitions involving security hotspots (except '" + DefaultTransitions.REQUEST_REVIEW + "') require the permission 'Administer Security Hotspot'.")
+ "The transitions involving security hotspots require the permission 'Administer Security Hotspot'.")
.setSince("3.6")
.setChangelog(
+ new Change("7.8", format("added transition '%s' for security hotspots ", SET_AS_IN_REVIEW)),
+ new Change("7.3", "added transitions for security hotspots"),
new Change("6.5", "the database ids of the components are removed from the response"),
- new Change("6.5", "the response field components.uuid is deprecated. Use components.key instead."),
- new Change("7.3", "added transitions for security hotspots"))
+ new Change("6.5", "the response field components.uuid is deprecated. Use components.key instead."))
.setHandler(this)
.setResponseExample(Resources.getResource(this.getClass(), "do_transition-example.json"))
.setPost(true);
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/changeevent/QGChangeEventListener.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/changeevent/QGChangeEventListener.java
index 0f7b94220e6..1e93e6ff96c 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/changeevent/QGChangeEventListener.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/changeevent/QGChangeEventListener.java
@@ -56,7 +56,8 @@ public interface QGChangeEventListener {
RESOLVED_FP,
RESOLVED_WF,
RESOLVED_FIXED,
- TO_REVIEW;
+ TO_REVIEW,
+ IN_REVIEW;
protected static final Set<Status> CLOSED_STATUSES = EnumSet.of(CONFIRMED, RESOLVED_FIXED, RESOLVED_FP, RESOLVED_WF);
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/changeevent/QGChangeEventListenersImpl.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/changeevent/QGChangeEventListenersImpl.java
index e1100812ca9..ba51aef85fd 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/changeevent/QGChangeEventListenersImpl.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/changeevent/QGChangeEventListenersImpl.java
@@ -120,6 +120,8 @@ public class QGChangeEventListenersImpl implements QGChangeEventListeners {
return QGChangeEventListener.Status.REOPENED;
case Issue.STATUS_TO_REVIEW:
return QGChangeEventListener.Status.TO_REVIEW;
+ case Issue.STATUS_IN_REVIEW:
+ return QGChangeEventListener.Status.IN_REVIEW;
case Issue.STATUS_RESOLVED:
return statusOfResolved(issue);
default:
diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexSecurityReportsTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexSecurityReportsTest.java
index bc00cddd508..ce04036104c 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexSecurityReportsTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexSecurityReportsTest.java
@@ -134,12 +134,12 @@ public class IssueIndexSecurityReportsTest {
ComponentDto project = newPrivateProjectDto(org);
ComponentDto another = newPrivateProjectDto(org);
indexIssues(
- newDoc("openhotspot1", project).setOwaspTop10(asList("a1")).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_OPEN),
- newDoc("anotherProject", another).setOwaspTop10(asList("a1")).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_OPEN));
+ newDoc("openhotspot1", project).setOwaspTop10(asList("a1")).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW),
+ newDoc("anotherProject", another).setOwaspTop10(asList("a1")).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW));
List<SecurityStandardCategoryStatistics> owaspTop10Report = underTest.getOwaspTop10Report(project.uuid(), false, false);
assertThat(owaspTop10Report)
- .extracting(SecurityStandardCategoryStatistics::getCategory, SecurityStandardCategoryStatistics::getOpenSecurityHotspots)
+ .extracting(SecurityStandardCategoryStatistics::getCategory, SecurityStandardCategoryStatistics::getToReviewSecurityHotspots)
.contains(
tuple("a1", 1L /* openhotspot1 */));
}
@@ -149,13 +149,13 @@ public class IssueIndexSecurityReportsTest {
OrganizationDto org = newOrganizationDto();
ComponentDto project = newPrivateProjectDto(org);
indexIssues(
- newDoc("openhotspot1", project).setOwaspTop10(asList("a1")).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_OPEN),
+ newDoc("openhotspot1", project).setOwaspTop10(asList("a1")).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW),
newDoc("closedHotspot", project).setOwaspTop10(asList("a1")).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_CLOSED)
.setResolution(Issue.RESOLUTION_FIXED));
List<SecurityStandardCategoryStatistics> owaspTop10Report = underTest.getOwaspTop10Report(project.uuid(), false, false);
assertThat(owaspTop10Report)
- .extracting(SecurityStandardCategoryStatistics::getCategory, SecurityStandardCategoryStatistics::getOpenSecurityHotspots)
+ .extracting(SecurityStandardCategoryStatistics::getCategory, SecurityStandardCategoryStatistics::getToReviewSecurityHotspots)
.contains(
tuple("a1", 1L /* openhotspot1 */));
}
@@ -175,15 +175,15 @@ public class IssueIndexSecurityReportsTest {
.collect(Collectors.toMap(SecurityStandardCategoryStatistics::getCategory, SecurityStandardCategoryStatistics::getChildren));
assertThat(cweByOwasp.get("a1")).extracting(SecurityStandardCategoryStatistics::getCategory, SecurityStandardCategoryStatistics::getVulnerabilities,
- SecurityStandardCategoryStatistics::getVulnerabiliyRating, SecurityStandardCategoryStatistics::getOpenSecurityHotspots,
- SecurityStandardCategoryStatistics::getToReviewSecurityHotspots, SecurityStandardCategoryStatistics::getWontFixSecurityHotspots)
+ SecurityStandardCategoryStatistics::getVulnerabiliyRating, SecurityStandardCategoryStatistics::getToReviewSecurityHotspots,
+ SecurityStandardCategoryStatistics::getInReviewSecurityHotspots, SecurityStandardCategoryStatistics::getWontFixSecurityHotspots)
.containsExactlyInAnyOrder(
tuple("123", 1L /* openvul1 */, OptionalInt.of(3)/* MAJOR = C */, 0L, 0L, 0L),
tuple("456", 1L /* openvul1 */, OptionalInt.of(3)/* MAJOR = C */, 0L, 0L, 0L),
tuple("unknown", 0L, OptionalInt.empty(), 1L /* openhotspot1 */, 0L, 0L));
assertThat(cweByOwasp.get("a3")).extracting(SecurityStandardCategoryStatistics::getCategory, SecurityStandardCategoryStatistics::getVulnerabilities,
- SecurityStandardCategoryStatistics::getVulnerabiliyRating, SecurityStandardCategoryStatistics::getOpenSecurityHotspots,
- SecurityStandardCategoryStatistics::getToReviewSecurityHotspots, SecurityStandardCategoryStatistics::getWontFixSecurityHotspots)
+ SecurityStandardCategoryStatistics::getVulnerabiliyRating, SecurityStandardCategoryStatistics::getToReviewSecurityHotspots,
+ SecurityStandardCategoryStatistics::getInReviewSecurityHotspots, SecurityStandardCategoryStatistics::getWontFixSecurityHotspots)
.containsExactlyInAnyOrder(
tuple("123", 2L /* openvul1, openvul2 */, OptionalInt.of(3)/* MAJOR = C */, 0L, 0L, 0L),
tuple("456", 1L /* openvul1 */, OptionalInt.of(3)/* MAJOR = C */, 0L, 1L /* toReviewHotspot */, 0L),
@@ -193,35 +193,28 @@ public class IssueIndexSecurityReportsTest {
private List<SecurityStandardCategoryStatistics> indexIssuesAndAssertOwaspReport(boolean includeCwe) {
OrganizationDto org = newOrganizationDto();
ComponentDto project = newPrivateProjectDto(org);
- ComponentDto another = newPrivateProjectDto(org);
indexIssues(
- newDoc("openvul1", project).setOwaspTop10(asList("a1", "a3")).setCwe(asList("123", "456")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN)
- .setSeverity(Severity.MAJOR),
- newDoc("openvul2", project).setOwaspTop10(asList("a3", "a6")).setCwe(asList("123")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_REOPENED)
- .setSeverity(Severity.MINOR),
- newDoc("notowaspvul", project).setOwaspTop10(singletonList(UNKNOWN_STANDARD)).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN)
- .setSeverity(Severity.CRITICAL),
- newDoc("openhotspot1", project).setOwaspTop10(asList("a1", "a3")).setCwe(singletonList(UNKNOWN_STANDARD)).setType(RuleType.SECURITY_HOTSPOT)
- .setStatus(Issue.STATUS_OPEN),
- newDoc("openhotspot2", project).setOwaspTop10(asList("a3", "a6")).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_REOPENED),
- newDoc("toReviewHotspot", project).setOwaspTop10(asList("a5", "a3")).setCwe(asList("456")).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_RESOLVED)
- .setResolution(Issue.RESOLUTION_FIXED),
- newDoc("WFHotspot", project).setOwaspTop10(asList("a3", "a8")).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_RESOLVED)
- .setResolution(Issue.RESOLUTION_WONT_FIX),
- newDoc("notowasphotspot", project).setOwaspTop10(singletonList(UNKNOWN_STANDARD)).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_OPEN));
+ newDoc("openvul1", project).setOwaspTop10(asList("a1", "a3")).setCwe(asList("123", "456")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN).setSeverity(Severity.MAJOR),
+ newDoc("openvul2", project).setOwaspTop10(asList("a3", "a6")).setCwe(asList("123")).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_REOPENED).setSeverity(Severity.MINOR),
+ newDoc("notowaspvul", project).setOwaspTop10(singletonList(UNKNOWN_STANDARD)).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN).setSeverity(Severity.CRITICAL),
+ newDoc("toreviewhotspot1", project).setOwaspTop10(asList("a1", "a3")).setCwe(singletonList(UNKNOWN_STANDARD)).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW),
+ newDoc("toreviewhotspot2", project).setOwaspTop10(asList("a3", "a6")).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW),
+ newDoc("inreviewhotspot", project).setOwaspTop10(asList("a5", "a3")).setCwe(asList("456")).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_IN_REVIEW),
+ newDoc("WFHotspot", project).setOwaspTop10(asList("a3", "a8")).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_RESOLVED).setResolution(Issue.RESOLUTION_WONT_FIX),
+ newDoc("notowasphotspot", project).setOwaspTop10(singletonList(UNKNOWN_STANDARD)).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW));
List<SecurityStandardCategoryStatistics> owaspTop10Report = underTest.getOwaspTop10Report(project.uuid(), false, includeCwe);
assertThat(owaspTop10Report)
.extracting(SecurityStandardCategoryStatistics::getCategory, SecurityStandardCategoryStatistics::getVulnerabilities,
- SecurityStandardCategoryStatistics::getVulnerabiliyRating, SecurityStandardCategoryStatistics::getOpenSecurityHotspots,
- SecurityStandardCategoryStatistics::getToReviewSecurityHotspots, SecurityStandardCategoryStatistics::getWontFixSecurityHotspots)
+ SecurityStandardCategoryStatistics::getVulnerabiliyRating, SecurityStandardCategoryStatistics::getToReviewSecurityHotspots,
+ SecurityStandardCategoryStatistics::getInReviewSecurityHotspots, SecurityStandardCategoryStatistics::getWontFixSecurityHotspots)
.containsExactlyInAnyOrder(
- tuple("a1", 1L /* openvul1 */, OptionalInt.of(3)/* MAJOR = C */, 1L /* openhotspot1 */, 0L, 0L),
+ tuple("a1", 1L /* openvul1 */, OptionalInt.of(3)/* MAJOR = C */, 1L /* toreviewhotspot1 */, 0L, 0L),
tuple("a2", 0L, OptionalInt.empty(), 0L, 0L, 0L),
- tuple("a3", 2L /* openvul1,openvul2 */, OptionalInt.of(3)/* MAJOR = C */, 2L/* openhotspot1,openhotspot2 */, 1L /* toReviewHotspot */, 1L /* WFHotspot */),
+ tuple("a3", 2L /* openvul1,openvul2 */, OptionalInt.of(3)/* MAJOR = C */, 2L/* toreviewhotspot1,toreviewhotspot2 */, 1L /* inReviewHotspot */, 1L /* WFHotspot */),
tuple("a4", 0L, OptionalInt.empty(), 0L, 0L, 0L),
- tuple("a5", 0L, OptionalInt.empty(), 0L, 1L/* toReviewHotspot */, 0L),
- tuple("a6", 1L /* openvul2 */, OptionalInt.of(2) /* MINOR = B */, 1L /* openhotspot2 */, 0L, 0L),
+ tuple("a5", 0L, OptionalInt.empty(), 0L, 1L/* inReviewHotspot */, 0L),
+ tuple("a6", 1L /* openvul2 */, OptionalInt.of(2) /* MINOR = B */, 1L /* toreviewhotspot2 */, 0L, 0L),
tuple("a7", 0L, OptionalInt.empty(), 0L, 0L, 0L),
tuple("a8", 0L, OptionalInt.empty(), 0L, 0L, 1L /* WFHotspot */),
tuple("a9", 0L, OptionalInt.empty(), 0L, 0L, 0L),
@@ -242,27 +235,21 @@ public class IssueIndexSecurityReportsTest {
newDoc("notopenvul", project).setSansTop25(asList(SANS_TOP_25_RISKY_RESOURCE, SANS_TOP_25_POROUS_DEFENSES)).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_CLOSED)
.setResolution(Issue.RESOLUTION_FIXED)
.setSeverity(Severity.BLOCKER),
- newDoc("notsansvul", project).setSansTop25(singletonList(UNKNOWN_STANDARD)).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN)
- .setSeverity(Severity.CRITICAL),
- newDoc("openhotspot1", project).setSansTop25(asList(SANS_TOP_25_INSECURE_INTERACTION, SANS_TOP_25_RISKY_RESOURCE)).setType(RuleType.SECURITY_HOTSPOT)
- .setStatus(Issue.STATUS_OPEN),
- newDoc("openhotspot2", project).setSansTop25(asList(SANS_TOP_25_RISKY_RESOURCE, SANS_TOP_25_POROUS_DEFENSES)).setType(RuleType.SECURITY_HOTSPOT)
- .setStatus(Issue.STATUS_REOPENED),
- newDoc("toReviewHotspot", project).setSansTop25(asList(SANS_TOP_25_RISKY_RESOURCE)).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_RESOLVED)
- .setResolution(Issue.RESOLUTION_FIXED),
- newDoc("WFHotspot", project).setSansTop25(asList(SANS_TOP_25_RISKY_RESOURCE)).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_RESOLVED)
- .setResolution(Issue.RESOLUTION_WONT_FIX),
- newDoc("notowasphotspot", project).setSansTop25(singletonList(UNKNOWN_STANDARD)).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_OPEN));
+ newDoc("notsansvul", project).setSansTop25(singletonList(UNKNOWN_STANDARD)).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN).setSeverity(Severity.CRITICAL),
+ newDoc("toreviewhotspot1", project).setSansTop25(asList(SANS_TOP_25_INSECURE_INTERACTION, SANS_TOP_25_RISKY_RESOURCE)).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW),
+ newDoc("toreviewhotspot2", project).setSansTop25(asList(SANS_TOP_25_RISKY_RESOURCE, SANS_TOP_25_POROUS_DEFENSES)).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW),
+ newDoc("inReviewHotspot", project).setSansTop25(asList(SANS_TOP_25_RISKY_RESOURCE)).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_IN_REVIEW),
+ newDoc("WFHotspot", project).setSansTop25(asList(SANS_TOP_25_RISKY_RESOURCE)).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_RESOLVED).setResolution(Issue.RESOLUTION_WONT_FIX),
+ newDoc("notowasphotspot", project).setSansTop25(singletonList(UNKNOWN_STANDARD)).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW));
List<SecurityStandardCategoryStatistics> sansTop25Report = underTest.getSansTop25Report(project.uuid(), false, false);
assertThat(sansTop25Report)
.extracting(SecurityStandardCategoryStatistics::getCategory, SecurityStandardCategoryStatistics::getVulnerabilities,
- SecurityStandardCategoryStatistics::getVulnerabiliyRating, SecurityStandardCategoryStatistics::getOpenSecurityHotspots,
- SecurityStandardCategoryStatistics::getToReviewSecurityHotspots, SecurityStandardCategoryStatistics::getWontFixSecurityHotspots)
+ SecurityStandardCategoryStatistics::getVulnerabiliyRating, SecurityStandardCategoryStatistics::getToReviewSecurityHotspots,
+ SecurityStandardCategoryStatistics::getInReviewSecurityHotspots, SecurityStandardCategoryStatistics::getWontFixSecurityHotspots)
.containsExactlyInAnyOrder(
- tuple(SANS_TOP_25_INSECURE_INTERACTION, 1L /* openvul1 */, OptionalInt.of(3)/* MAJOR = C */, 1L /* openhotspot1 */, 0L, 0L),
- tuple(SANS_TOP_25_RISKY_RESOURCE, 2L /* openvul1,openvul2 */, OptionalInt.of(3)/* MAJOR = C */, 2L/* openhotspot1,openhotspot2 */, 1L /* toReviewHotspot */,
- 1L /* WFHotspot */),
+ tuple(SANS_TOP_25_INSECURE_INTERACTION, 1L /* openvul1 */, OptionalInt.of(3)/* MAJOR = C */, 1L /* toreviewhotspot1 */, 0L, 0L),
+ tuple(SANS_TOP_25_RISKY_RESOURCE, 2L /* openvul1,openvul2 */, OptionalInt.of(3)/* MAJOR = C */, 2L/* toreviewhotspot1,toreviewhotspot2 */, 1L /* inReviewHotspot */,1L /* WFHotspot */),
tuple(SANS_TOP_25_POROUS_DEFENSES, 1L /* openvul2 */, OptionalInt.of(2)/* MINOR = B */, 1L/* openhotspot2 */, 0L, 0L));
assertThat(sansTop25Report).allMatch(category -> category.getChildren().isEmpty());
@@ -283,17 +270,12 @@ public class IssueIndexSecurityReportsTest {
newDoc("notopenvul", project1).setSansTop25(asList(SANS_TOP_25_RISKY_RESOURCE, SANS_TOP_25_POROUS_DEFENSES)).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_CLOSED)
.setResolution(Issue.RESOLUTION_FIXED)
.setSeverity(Severity.BLOCKER),
- newDoc("notsansvul", project2).setSansTop25(singletonList(UNKNOWN_STANDARD)).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN)
- .setSeverity(Severity.CRITICAL),
- newDoc("openhotspot1", project1).setSansTop25(asList(SANS_TOP_25_INSECURE_INTERACTION, SANS_TOP_25_RISKY_RESOURCE)).setType(RuleType.SECURITY_HOTSPOT)
- .setStatus(Issue.STATUS_OPEN),
- newDoc("openhotspot2", project2).setSansTop25(asList(SANS_TOP_25_RISKY_RESOURCE, SANS_TOP_25_POROUS_DEFENSES)).setType(RuleType.SECURITY_HOTSPOT)
- .setStatus(Issue.STATUS_REOPENED),
- newDoc("toReviewHotspot", project1).setSansTop25(asList(SANS_TOP_25_RISKY_RESOURCE)).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_RESOLVED)
- .setResolution(Issue.RESOLUTION_FIXED),
- newDoc("WFHotspot", project2).setSansTop25(asList(SANS_TOP_25_RISKY_RESOURCE)).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_RESOLVED)
- .setResolution(Issue.RESOLUTION_WONT_FIX),
- newDoc("notowasphotspot", project1).setSansTop25(singletonList(UNKNOWN_STANDARD)).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_OPEN));
+ newDoc("notsansvul", project2).setSansTop25(singletonList(UNKNOWN_STANDARD)).setType(RuleType.VULNERABILITY).setStatus(Issue.STATUS_OPEN).setSeverity(Severity.CRITICAL),
+ newDoc("toreviewhotspot1", project1).setSansTop25(asList(SANS_TOP_25_INSECURE_INTERACTION, SANS_TOP_25_RISKY_RESOURCE)).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW),
+ newDoc("toreviewhotspot2", project2).setSansTop25(asList(SANS_TOP_25_RISKY_RESOURCE, SANS_TOP_25_POROUS_DEFENSES)).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW),
+ newDoc("inReviewHotspot", project1).setSansTop25(asList(SANS_TOP_25_RISKY_RESOURCE)).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_IN_REVIEW),
+ newDoc("WFHotspot", project2).setSansTop25(asList(SANS_TOP_25_RISKY_RESOURCE)).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_RESOLVED).setResolution(Issue.RESOLUTION_WONT_FIX),
+ newDoc("notowasphotspot", project1).setSansTop25(singletonList(UNKNOWN_STANDARD)).setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW));
indexView(portfolio1.uuid(), singletonList(project1.uuid()));
indexView(portfolio2.uuid(), singletonList(project2.uuid()));
@@ -301,11 +283,11 @@ public class IssueIndexSecurityReportsTest {
List<SecurityStandardCategoryStatistics> sansTop25Report = underTest.getSansTop25Report(portfolio1.uuid(), true, false);
assertThat(sansTop25Report)
.extracting(SecurityStandardCategoryStatistics::getCategory, SecurityStandardCategoryStatistics::getVulnerabilities,
- SecurityStandardCategoryStatistics::getVulnerabiliyRating, SecurityStandardCategoryStatistics::getOpenSecurityHotspots,
- SecurityStandardCategoryStatistics::getToReviewSecurityHotspots, SecurityStandardCategoryStatistics::getWontFixSecurityHotspots)
+ SecurityStandardCategoryStatistics::getVulnerabiliyRating, SecurityStandardCategoryStatistics::getToReviewSecurityHotspots,
+ SecurityStandardCategoryStatistics::getInReviewSecurityHotspots, SecurityStandardCategoryStatistics::getWontFixSecurityHotspots)
.containsExactlyInAnyOrder(
- tuple(SANS_TOP_25_INSECURE_INTERACTION, 1L /* openvul1 */, OptionalInt.of(3)/* MAJOR = C */, 1L /* openhotspot1 */, 0L, 0L),
- tuple(SANS_TOP_25_RISKY_RESOURCE, 1L /* openvul1 */, OptionalInt.of(3)/* MAJOR = C */, 1L/* openhotspot1 */, 1L /* toReviewHotspot */, 0L),
+ tuple(SANS_TOP_25_INSECURE_INTERACTION, 1L /* openvul1 */, OptionalInt.of(3)/* MAJOR = C */, 1L /* toreviewhotspot1 */, 0L, 0L),
+ tuple(SANS_TOP_25_RISKY_RESOURCE, 1L /* openvul1 */, OptionalInt.of(3)/* MAJOR = C */, 1L/* toreviewhotspot1 */, 1L /* inReviewHotspot */, 0L),
tuple(SANS_TOP_25_POROUS_DEFENSES, 0L, OptionalInt.empty(), 0L, 0L, 0L));
assertThat(sansTop25Report).allMatch(category -> category.getChildren().isEmpty());
diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/changeevent/QGChangeEventListenersImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/changeevent/QGChangeEventListenersImplTest.java
index 021a872cefb..21961822894 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/changeevent/QGChangeEventListenersImplTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/changeevent/QGChangeEventListenersImplTest.java
@@ -288,6 +288,8 @@ public class QGChangeEventListenersImplTest {
public void test_status_mapping_on_security_hotspots() {
assertThat(ChangedIssueImpl.statusOf(new DefaultIssue().setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_TO_REVIEW)))
.isEqualTo(QGChangeEventListener.Status.TO_REVIEW);
+ assertThat(ChangedIssueImpl.statusOf(new DefaultIssue().setType(RuleType.SECURITY_HOTSPOT).setStatus(Issue.STATUS_IN_REVIEW)))
+ .isEqualTo(QGChangeEventListener.Status.IN_REVIEW);
}
private void verifyListenerCalled(QGChangeEventListener listener, QGChangeEvent changeEvent, DefaultIssue... issues) {
diff --git a/server/sonar-server/src/test/resources/com/sonar/governance/securityreport/ws/ShowActionTest/empty.json b/server/sonar-server/src/test/resources/com/sonar/governance/securityreport/ws/ShowActionTest/empty.json
index 4c8399afeb0..c7c300c51a5 100644
--- a/server/sonar-server/src/test/resources/com/sonar/governance/securityreport/ws/ShowActionTest/empty.json
+++ b/server/sonar-server/src/test/resources/com/sonar/governance/securityreport/ws/ShowActionTest/empty.json
@@ -3,8 +3,8 @@
{
"category": "a1",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 1,
@@ -13,8 +13,8 @@
{
"category": "a2",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 1,
@@ -23,8 +23,8 @@
{
"category": "a3",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -33,8 +33,8 @@
{
"category": "a4",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -43,8 +43,8 @@
{
"category": "a5",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -53,8 +53,8 @@
{
"category": "a6",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -63,8 +63,8 @@
{
"category": "a7",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -73,8 +73,8 @@
{
"category": "a8",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -83,8 +83,8 @@
{
"category": "a9",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -93,8 +93,8 @@
{
"category": "a10",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -103,8 +103,8 @@
{
"category": "unknown",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 1,
diff --git a/server/sonar-server/src/test/resources/com/sonar/governance/securityreport/ws/ShowActionTest/owaspNoCwe.json b/server/sonar-server/src/test/resources/com/sonar/governance/securityreport/ws/ShowActionTest/owaspNoCwe.json
index 99e1e68464f..3e4614196f9 100644
--- a/server/sonar-server/src/test/resources/com/sonar/governance/securityreport/ws/ShowActionTest/owaspNoCwe.json
+++ b/server/sonar-server/src/test/resources/com/sonar/governance/securityreport/ws/ShowActionTest/owaspNoCwe.json
@@ -3,8 +3,8 @@
{
"category": "a1",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 1,
@@ -14,8 +14,8 @@
"category": "a2",
"vulnerabilities": 1,
"vulnerabilityRating": 3,
+ "inReviewSecurityHotspots": 1,
"toReviewSecurityHotspots": 1,
- "openSecurityHotspots": 1,
"wontFixSecurityHotspots": 1,
"distribution": [],
"activeRules": 1,
@@ -24,8 +24,8 @@
{
"category": "a3",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -34,8 +34,8 @@
{
"category": "a4",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -44,8 +44,8 @@
{
"category": "a5",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -54,8 +54,8 @@
{
"category": "a6",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -64,8 +64,8 @@
{
"category": "a7",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -74,8 +74,8 @@
{
"category": "a8",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -84,8 +84,8 @@
{
"category": "a9",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -94,8 +94,8 @@
{
"category": "a10",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -104,8 +104,8 @@
{
"category": "unknown",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 1,
diff --git a/server/sonar-server/src/test/resources/com/sonar/governance/securityreport/ws/ShowActionTest/sansWithCwe.json b/server/sonar-server/src/test/resources/com/sonar/governance/securityreport/ws/ShowActionTest/sansWithCwe.json
index 30733dbca61..7d7cb59ac97 100644
--- a/server/sonar-server/src/test/resources/com/sonar/governance/securityreport/ws/ShowActionTest/sansWithCwe.json
+++ b/server/sonar-server/src/test/resources/com/sonar/governance/securityreport/ws/ShowActionTest/sansWithCwe.json
@@ -3,8 +3,8 @@
{
"category": "porous-defenses",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -13,8 +13,8 @@
{
"category": "risky-resource",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 1,
@@ -24,16 +24,16 @@
"category": "insecure-interaction",
"vulnerabilities": 1,
"vulnerabilityRating": 3,
+ "inReviewSecurityHotspots": 1,
"toReviewSecurityHotspots": 1,
- "openSecurityHotspots": 1,
"wontFixSecurityHotspots": 0,
"distribution": [
{
"cwe": "89",
"vulnerabilities": 1,
"vulnerabilityRating": 3,
+ "inReviewSecurityHotspots": 1,
"toReviewSecurityHotspots": 1,
- "openSecurityHotspots": 1,
"wontFixSecurityHotspots": 0,
"activeRules": 1,
"totalRules": 1
diff --git a/server/sonar-server/src/test/resources/com/sonar/governance/securityreport/ws/ShowActionTest/sonarsourceSecurityNoCwe.json b/server/sonar-server/src/test/resources/com/sonar/governance/securityreport/ws/ShowActionTest/sonarsourceSecurityNoCwe.json
index fb15c48a6e9..f5e6c4eb702 100644
--- a/server/sonar-server/src/test/resources/com/sonar/governance/securityreport/ws/ShowActionTest/sonarsourceSecurityNoCwe.json
+++ b/server/sonar-server/src/test/resources/com/sonar/governance/securityreport/ws/ShowActionTest/sonarsourceSecurityNoCwe.json
@@ -3,8 +3,8 @@
{
"category": "ldap-injection",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -13,8 +13,8 @@
{
"category": "object-injection",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -23,8 +23,8 @@
{
"category": "ssrf",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -33,8 +33,8 @@
{
"category": "insecure-conf",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -43,8 +43,8 @@
{
"category": "xxe",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -53,8 +53,8 @@
{
"category": "auth",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -63,8 +63,8 @@
{
"category": "xpath-injection",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -73,8 +73,8 @@
{
"category": "weak-cryptography",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -83,8 +83,8 @@
{
"category": "dos",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -93,8 +93,8 @@
{
"category": "open-redirect",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -103,8 +103,8 @@
{
"category": "log-injection",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -113,8 +113,8 @@
{
"category": "csrf",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -124,8 +124,8 @@
"category": "sql-injection",
"vulnerabilities": 1,
"vulnerabilityRating": 3,
+ "inReviewSecurityHotspots": 1,
"toReviewSecurityHotspots": 1,
- "openSecurityHotspots": 1,
"wontFixSecurityHotspots": 1,
"distribution": [],
"activeRules": 1,
@@ -134,8 +134,8 @@
{
"category": "file-manipulation",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -144,8 +144,8 @@
{
"category": "expression-lang-injection",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -154,8 +154,8 @@
{
"category": "rce",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -164,8 +164,8 @@
{
"category": "xss",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -174,8 +174,8 @@
{
"category": "path-traversal-injection",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 1,
@@ -184,8 +184,8 @@
{
"category": "command-injection",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 1,
@@ -194,8 +194,8 @@
{
"category": "http-response-splitting",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
diff --git a/server/sonar-server/src/test/resources/com/sonar/governance/securityreport/ws/ShowActionTest/sonarsourceSecurityOnApplication.json b/server/sonar-server/src/test/resources/com/sonar/governance/securityreport/ws/ShowActionTest/sonarsourceSecurityOnApplication.json
index b565b5d309d..a01609a9d19 100644
--- a/server/sonar-server/src/test/resources/com/sonar/governance/securityreport/ws/ShowActionTest/sonarsourceSecurityOnApplication.json
+++ b/server/sonar-server/src/test/resources/com/sonar/governance/securityreport/ws/ShowActionTest/sonarsourceSecurityOnApplication.json
@@ -3,96 +3,96 @@
{
"category": "ldap-injection",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": []
},
{
"category": "object-injection",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": []
},
{
"category": "ssrf",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": []
},
{
"category": "insecure-conf",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": []
},
{
"category": "xxe",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": []
},
{
"category": "auth",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": []
},
{
"category": "xpath-injection",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": []
},
{
"category": "weak-cryptography",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": []
},
{
"category": "dos",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": []
},
{
"category": "open-redirect",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": []
},
{
"category": "log-injection",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": []
},
{
"category": "csrf",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": []
},
@@ -100,16 +100,16 @@
"category": "sql-injection",
"vulnerabilities": 1,
"vulnerabilityRating": 3,
+ "inReviewSecurityHotspots": 1,
"toReviewSecurityHotspots": 1,
- "openSecurityHotspots": 1,
"wontFixSecurityHotspots": 1,
"distribution": [
{
"cwe": "89",
"vulnerabilities": 1,
"vulnerabilityRating": 3,
+ "inReviewSecurityHotspots": 1,
"toReviewSecurityHotspots": 1,
- "openSecurityHotspots": 1,
"wontFixSecurityHotspots": 1
}
]
@@ -117,56 +117,56 @@
{
"category": "file-manipulation",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": []
},
{
"category": "expression-lang-injection",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": []
},
{
"category": "rce",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": []
},
{
"category": "xss",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": []
},
{
"category": "path-traversal-injection",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": []
},
{
"category": "command-injection",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": []
},
{
"category": "http-response-splitting",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": []
}
diff --git a/server/sonar-server/src/test/resources/com/sonar/governance/securityreport/ws/ShowActionTest/sonarsourceSecurityWithCwe.json b/server/sonar-server/src/test/resources/com/sonar/governance/securityreport/ws/ShowActionTest/sonarsourceSecurityWithCwe.json
index 2936bdadd8b..61f4ca5cacd 100644
--- a/server/sonar-server/src/test/resources/com/sonar/governance/securityreport/ws/ShowActionTest/sonarsourceSecurityWithCwe.json
+++ b/server/sonar-server/src/test/resources/com/sonar/governance/securityreport/ws/ShowActionTest/sonarsourceSecurityWithCwe.json
@@ -3,8 +3,8 @@
{
"category": "ldap-injection",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -13,8 +13,8 @@
{
"category": "object-injection",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -23,8 +23,8 @@
{
"category": "ssrf",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -33,8 +33,8 @@
{
"category": "insecure-conf",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -43,8 +43,8 @@
{
"category": "xxe",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -53,8 +53,8 @@
{
"category": "auth",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -63,8 +63,8 @@
{
"category": "xpath-injection",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -73,8 +73,8 @@
{
"category": "weak-cryptography",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -83,8 +83,8 @@
{
"category": "dos",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -93,8 +93,8 @@
{
"category": "open-redirect",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -103,8 +103,8 @@
{
"category": "log-injection",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -113,8 +113,8 @@
{
"category": "csrf",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -124,16 +124,16 @@
"category": "sql-injection",
"vulnerabilities": 1,
"vulnerabilityRating": 3,
+ "inReviewSecurityHotspots": 1,
"toReviewSecurityHotspots": 1,
- "openSecurityHotspots": 1,
"wontFixSecurityHotspots": 1,
"distribution": [
{
"cwe": "89",
"vulnerabilities": 1,
"vulnerabilityRating": 3,
+ "inReviewSecurityHotspots": 1,
"toReviewSecurityHotspots": 1,
- "openSecurityHotspots": 1,
"wontFixSecurityHotspots": 1,
"activeRules": 1,
"totalRules": 1
@@ -145,8 +145,8 @@
{
"category": "file-manipulation",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -155,8 +155,8 @@
{
"category": "expression-lang-injection",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -165,8 +165,8 @@
{
"category": "rce",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -175,8 +175,8 @@
{
"category": "xss",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
@@ -185,8 +185,8 @@
{
"category": "path-traversal-injection",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 1,
@@ -195,8 +195,8 @@
{
"category": "command-injection",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 1,
@@ -205,8 +205,8 @@
{
"category": "http-response-splitting",
"vulnerabilities": 0,
+ "inReviewSecurityHotspots": 0,
"toReviewSecurityHotspots": 0,
- "openSecurityHotspots": 0,
"wontFixSecurityHotspots": 0,
"distribution": [],
"activeRules": 0,
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/issue/DefaultTransitions.java b/sonar-plugin-api/src/main/java/org/sonar/api/issue/DefaultTransitions.java
index 6bca276eec3..106dfb0cbd7 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/issue/DefaultTransitions.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/issue/DefaultTransitions.java
@@ -22,6 +22,7 @@ package org.sonar.api.issue;
import java.util.List;
import static java.util.Arrays.asList;
+import static java.util.Collections.unmodifiableList;
/**
* @since 3.6
@@ -46,13 +47,18 @@ public interface DefaultTransitions {
String DETECT = "detect";
String DISMISS = "dismiss";
String REJECT = "reject";
- String REQUEST_REVIEW = "requestreview";
String ACCEPT = "accept";
String CLEAR = "clear";
String REOPEN_HOTSPOT = "reopenhotspot";
/**
+ * @since 7.8
+ */
+ String SET_AS_IN_REVIEW = "setinreview";
+
+ /**
* @since 4.4
*/
- List<String> ALL = asList(CONFIRM, UNCONFIRM, REOPEN, RESOLVE, FALSE_POSITIVE, WONT_FIX, CLOSE, DETECT, DISMISS, REJECT, REQUEST_REVIEW, ACCEPT, CLEAR, REOPEN_HOTSPOT);
+ List<String> ALL = unmodifiableList(asList(CONFIRM, UNCONFIRM, REOPEN, RESOLVE, FALSE_POSITIVE, WONT_FIX, CLOSE,
+ DETECT, DISMISS, REJECT, SET_AS_IN_REVIEW, ACCEPT, CLEAR, REOPEN_HOTSPOT));
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/issue/Issue.java b/sonar-plugin-api/src/main/java/org/sonar/api/issue/Issue.java
index c5add0eab45..49db5e45f31 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/issue/Issue.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/issue/Issue.java
@@ -81,6 +81,11 @@ public interface Issue extends Serializable {
String STATUS_TO_REVIEW = "TOREVIEW";
/**
+ * @since 7.8
+ */
+ String STATUS_IN_REVIEW = "INREVIEW";
+
+ /**
* Return all available statuses
*
* @since 4.4
diff --git a/sonar-ws/src/main/protobuf/ws-security.proto b/sonar-ws/src/main/protobuf/ws-security.proto
index b9d9b3686ae..059bd1666da 100644
--- a/sonar-ws/src/main/protobuf/ws-security.proto
+++ b/sonar-ws/src/main/protobuf/ws-security.proto
@@ -35,8 +35,8 @@ message SecurityStandardCategoryStatistics {
optional string category = 1;
optional int64 vulnerabilities = 2;
optional int64 vulnerabilityRating = 3;
- optional int64 toReviewSecurityHotspots = 4;
- optional int64 openSecurityHotspots = 5;
+ optional int64 inReviewSecurityHotspots = 4;
+ optional int64 toReviewSecurityHotspots = 5;
optional int64 wontFixSecurityHotspots = 6;
repeated CweStatistics distribution = 7;
optional int64 activeRules = 8;
@@ -47,8 +47,8 @@ message CweStatistics {
optional string cwe = 1;
optional int64 vulnerabilities = 2;
optional int64 vulnerabilityRating = 3;
- optional int64 toReviewSecurityHotspots = 4;
- optional int64 openSecurityHotspots = 5;
+ optional int64 inReviewSecurityHotspots = 4;
+ optional int64 toReviewSecurityHotspots = 5;
optional int64 wontFixSecurityHotspots = 6;
optional int64 activeRules = 7;
optional int64 totalRules = 8;