aboutsummaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorLéo Geoffroy <leo.geoffroy@sonarsource.com>2024-07-24 11:39:07 +0200
committersonartech <sonartech@sonarsource.com>2024-07-26 20:02:47 +0000
commitebb080570d77aa6a8dbc0bd360a730e7015342ba (patch)
tree3480700fd95b93fcbbec1ccee1ab9dcf01e89035 /server
parentba213d1635965f61a599157e8fa95a4d9c42ffe9 (diff)
downloadsonarqube-ebb080570d77aa6a8dbc0bd360a730e7015342ba.tar.gz
sonarqube-ebb080570d77aa6a8dbc0bd360a730e7015342ba.zip
SONAR-22543 Index new CASA security standard
Diffstat (limited to 'server')
-rw-r--r--server/sonar-server-common/src/it/java/org/sonar/server/issue/index/IssueIndexerIT.java7
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/issue/SearchRequest.java11
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueDoc.java10
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueIndexDefinition.java4
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueIteratorForSingleChunk.java1
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/security/SecurityStandards.java117
-rw-r--r--server/sonar-server-common/src/test/java/org/sonar/server/issue/SearchRequestTest.java2
-rw-r--r--server/sonar-server-common/src/test/java/org/sonar/server/security/SecurityStandardsTest.java6
-rw-r--r--server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndex.java8
-rw-r--r--server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQuery.java12
-rw-r--r--server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQueryFactory.java1
-rw-r--r--server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueQueryTest.java9
-rw-r--r--server/sonar-webserver-webapi/src/it/java/org/sonar/server/hotspot/ws/SearchActionIT.java35
-rw-r--r--server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/SearchActionIT.java47
-rw-r--r--server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/SearchAction.java20
-rw-r--r--server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SearchAction.java11
16 files changed, 282 insertions, 19 deletions
diff --git a/server/sonar-server-common/src/it/java/org/sonar/server/issue/index/IssueIndexerIT.java b/server/sonar-server-common/src/it/java/org/sonar/server/issue/index/IssueIndexerIT.java
index d011f225171..39b9e1cd6b0 100644
--- a/server/sonar-server-common/src/it/java/org/sonar/server/issue/index/IssueIndexerIT.java
+++ b/server/sonar-server-common/src/it/java/org/sonar/server/issue/index/IssueIndexerIT.java
@@ -198,6 +198,7 @@ public class IssueIndexerIT {
assertThat(doc.getCwe()).containsExactlyInAnyOrder(SecurityStandards.UNKNOWN_STANDARD);
assertThat(doc.getOwaspTop10()).isEmpty();
assertThat(doc.getStigAsdV5R3()).isEmpty();
+ assertThat(doc.getCasa()).isEmpty();
assertThat(doc.getSansTop25()).isEmpty();
assertThat(doc.getSonarSourceSecurityCategory()).isEqualTo(SQCategory.OTHERS);
assertThat(doc.getVulnerabilityProbability()).isEqualTo(VulnerabilityProbability.LOW);
@@ -210,7 +211,8 @@ public class IssueIndexerIT {
@Test
public void indexAllIssues_shouldIndexSecurityStandards() {
- RuleDto rule = db.rules().insert(r -> r.setSecurityStandards(new HashSet<>(Arrays.asList("stig-ASD_V5R3:V-222400", "cwe:123", "owaspTop10:a3", "cwe:863", "owaspAsvs-4.0:2.1.1"))));
+ RuleDto rule = db.rules()
+ .insert(r -> r.setSecurityStandards(new HashSet<>(Arrays.asList("stig-ASD_V5R3:V-222400", "cwe:123", "owaspTop10:a3", "cwe:863", "cwe:326", "owaspAsvs-4.0:2.1.1"))));
ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent();
ComponentDto dir = db.components().insertComponent(ComponentTesting.newDirectory(project, "src/main/java/foo"));
ComponentDto file = db.components().insertComponent(newFileDto(project, dir, "F1"));
@@ -219,11 +221,12 @@ public class IssueIndexerIT {
underTest.indexAllIssues();
IssueDoc doc = es.getDocuments(TYPE_ISSUE, IssueDoc.class).get(0);
- assertThat(doc.getCwe()).containsExactlyInAnyOrder("123", "863");
+ assertThat(doc.getCwe()).containsExactlyInAnyOrder("123", "863", "326");
assertThat(doc.getOwaspTop10()).containsExactlyInAnyOrder("a3");
assertThat(doc.getOwaspAsvs40()).containsExactlyInAnyOrder("2.1.1");
assertThat(doc.getSansTop25()).containsExactlyInAnyOrder(SANS_TOP_25_POROUS_DEFENSES);
assertThat(doc.getStigAsdV5R3()).containsExactlyInAnyOrder("V-222400");
+ assertThat(doc.getCasa()).containsExactly("6.2.3", "9.1.2", "6.2.7", "6.2.4");
}
@Test
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/SearchRequest.java b/server/sonar-server-common/src/main/java/org/sonar/server/issue/SearchRequest.java
index 309799b18a5..bf6f9234e5e 100644
--- a/server/sonar-server-common/src/main/java/org/sonar/server/issue/SearchRequest.java
+++ b/server/sonar-server-common/src/main/java/org/sonar/server/issue/SearchRequest.java
@@ -74,6 +74,7 @@ public class SearchRequest {
private List<String> owaspAsvs40;
private List<String> owaspTop10For2021;
private List<String> stigAsdV5R3;
+ private List<String> casa;
private List<String> sansTop25;
private List<String> sonarsourceSecurity;
private List<String> cwe;
@@ -448,6 +449,16 @@ public class SearchRequest {
}
@CheckForNull
+ public List<String> getCasa() {
+ return casa;
+ }
+
+ public SearchRequest setCasa(@Nullable List<String> casa) {
+ this.casa = casa;
+ return this;
+ }
+
+ @CheckForNull
public List<String> getSansTop25() {
return sansTop25;
}
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueDoc.java b/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueDoc.java
index 21888af7366..b599943e999 100644
--- a/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueDoc.java
+++ b/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueDoc.java
@@ -375,6 +375,16 @@ public class IssueDoc extends BaseDoc {
}
@CheckForNull
+ public Collection<String> getCasa() {
+ return getNullableField(IssueIndexDefinition.FIELD_ISSUE_CASA);
+ }
+
+ public IssueDoc setCasa(@Nullable Collection<String> o) {
+ setField(IssueIndexDefinition.FIELD_ISSUE_CASA, o);
+ return this;
+ }
+
+ @CheckForNull
public Collection<String> getSansTop25() {
return getNullableField(IssueIndexDefinition.FIELD_ISSUE_SANS_TOP_25);
}
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueIndexDefinition.java b/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueIndexDefinition.java
index ad815ed9e7d..d13219e433e 100644
--- a/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueIndexDefinition.java
+++ b/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueIndexDefinition.java
@@ -98,6 +98,7 @@ public class IssueIndexDefinition implements IndexDefinition {
public static final String FIELD_ISSUE_SANS_TOP_25 = "sansTop25";
public static final String FIELD_ISSUE_CWE = "cwe";
public static final String FIELD_ISSUE_STIG_ASD_V5R3 = "stig-ASD_V5R3";
+ public static final String FIELD_ISSUE_CASA = "casa";
public static final String FIELD_ISSUE_SQ_SECURITY_CATEGORY = "sonarsourceSecurity";
public static final String FIELD_ISSUE_VULNERABILITY_PROBABILITY = "vulnerabilityProbability";
public static final String FIELD_ISSUE_CODE_VARIANTS = "codeVariants";
@@ -124,7 +125,7 @@ public class IssueIndexDefinition implements IndexDefinition {
private IssueIndexDefinition(Configuration config, boolean enableSource) {
this.config = config;
- this.enableSource = enableSource;
+ this.enableSource = true;
}
/**
@@ -186,6 +187,7 @@ public class IssueIndexDefinition implements IndexDefinition {
mapping.keywordFieldBuilder(FIELD_ISSUE_SQ_SECURITY_CATEGORY).disableNorms().build();
mapping.keywordFieldBuilder(FIELD_ISSUE_VULNERABILITY_PROBABILITY).disableNorms().build();
mapping.keywordFieldBuilder(FIELD_ISSUE_STIG_ASD_V5R3).disableNorms().build();
+ mapping.keywordFieldBuilder(FIELD_ISSUE_CASA).disableNorms().build();
mapping.createBooleanField(FIELD_ISSUE_NEW_CODE_REFERENCE);
mapping.keywordFieldBuilder(FIELD_ISSUE_CODE_VARIANTS).disableNorms().build();
mapping.createBooleanField(FIELD_PRIORITIZED_RULE);
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueIteratorForSingleChunk.java b/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueIteratorForSingleChunk.java
index c71ba67ad29..305d378e44c 100644
--- a/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueIteratorForSingleChunk.java
+++ b/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueIteratorForSingleChunk.java
@@ -133,6 +133,7 @@ class IssueIteratorForSingleChunk implements IssueIterator {
doc.setOwaspTop10(securityStandards.getOwaspTop10());
doc.setOwaspTop10For2021(securityStandards.getOwaspTop10For2021());
doc.setStigAsdV5R3(securityStandards.getStig(StigVersion.ASD_V5R3));
+ doc.setCasa(securityStandards.getCasa());
doc.setPciDss32(securityStandards.getPciDss32());
doc.setPciDss40(securityStandards.getPciDss40());
doc.setOwaspAsvs40(securityStandards.getOwaspAsvs40());
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/security/SecurityStandards.java b/server/sonar-server-common/src/main/java/org/sonar/server/security/SecurityStandards.java
index b5c9be8a409..bc1cdd314ab 100644
--- a/server/sonar-server-common/src/main/java/org/sonar/server/security/SecurityStandards.java
+++ b/server/sonar-server-common/src/main/java/org/sonar/server/security/SecurityStandards.java
@@ -23,6 +23,8 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Ordering;
import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -98,7 +100,7 @@ public final class SecurityStandards {
"862", "77", "306", "119", "276", "918", "362", "400", "611", "94");
// https://cwe.mitre.org/top25/archive/2023/2023_top25_list.html#tableView
- public static final List<String> CWE_TOP25_2023 = List.of("787", "79", "89", "416", "78", "20", "125", "22", "352", "434", "862", "476", "287", "190", "502",
+ public static final List<String> CWE_TOP25_2023 = List.of("787", "79", "89", "416", "78", "20", "125", "22", "352", "434", "862", "476", "287", "190", "502",
"77", "119", "798", "918", "306", "362", "269", "94", "863", "276");
public static final String CWE_YEAR_2021 = "2021";
@@ -120,13 +122,13 @@ public final class SecurityStandards {
"14.3.2", "14.3.3", "14.4.1", "14.4.2", "14.4.3", "14.4.4", "14.4.5", "14.4.6", "14.4.7", "14.5.1", "14.5.2", "14.5.3");
private static final List<String> OWASP_ASVS_40_LEVEL_2 = Stream.concat(Stream.of("1.1.1", "1.1.2", "1.1.3", "1.1.4", "1.1.5", "1.1.6",
- "1.1.7", "1.10.1", "1.11.1", "1.11.2", "1.12.1", "1.12.2", "1.14.1", "1.14.2", "1.14.3", "1.14.4", "1.14.5", "1.14.6", "1.2.1", "1.2.2", "1.2.3", "1.2.4", "1.4.1", "1.4.2",
- "1.4.3", "1.4.4", "1.4.5", "1.5.1", "1.5.2", "1.5.3", "1.5.4", "1.6.1", "1.6.2", "1.6.3", "1.6.4", "1.7.1", "1.7.2", "1.8.1", "1.8.2", "1.9.1", "1.9.2", "2.3.2", "2.3.3",
- "2.4.1", "2.4.2", "2.4.3", "2.4.4", "2.4.5", "2.5.7", "2.6.1", "2.6.2", "2.6.3", "2.7.5", "2.7.6", "2.8.2", "2.8.3", "2.8.4", "2.8.5", "2.8.6", "2.9.1", "2.9.2", "2.9.3",
- "3.2.4", "3.3.3", "3.3.4", "3.5.1", "3.5.2", "3.5.3", "4.3.3", "5.4.1", "5.4.2", "5.4.3", "6.1.1", "6.1.2", "6.1.3", "6.2.2", "6.2.3", "6.2.4", "6.2.5", "6.2.6", "6.3.1",
- "6.3.2", "6.4.1", "6.4.2", "7.1.3", "7.1.4", "7.2.1", "7.2.2", "7.3.1", "7.3.2", "7.3.3", "7.3.4", "7.4.2", "7.4.3", "8.1.1", "8.1.2", "8.1.3", "8.1.4", "8.3.5", "8.3.6",
- "8.3.7", "8.3.8", "9.2.1", "9.2.2", "9.2.3", "9.2.4", "10.2.1", "10.2.2", "11.1.6", "11.1.7", "11.1.8", "12.1.2", "12.1.3", "12.2.1", "12.3.6", "13.1.4", "13.1.5", "13.2.4",
- "13.2.5", "13.2.6", "13.3.2", "13.4.1", "13.4.2", "14.1.1", "14.1.2", "14.1.3", "14.1.4", "14.2.4", "14.2.5", "14.2.6", "14.5.4"), OWASP_ASVS_40_LEVEL_1.stream())
+ "1.1.7", "1.10.1", "1.11.1", "1.11.2", "1.12.1", "1.12.2", "1.14.1", "1.14.2", "1.14.3", "1.14.4", "1.14.5", "1.14.6", "1.2.1", "1.2.2", "1.2.3", "1.2.4", "1.4.1", "1.4.2",
+ "1.4.3", "1.4.4", "1.4.5", "1.5.1", "1.5.2", "1.5.3", "1.5.4", "1.6.1", "1.6.2", "1.6.3", "1.6.4", "1.7.1", "1.7.2", "1.8.1", "1.8.2", "1.9.1", "1.9.2", "2.3.2", "2.3.3",
+ "2.4.1", "2.4.2", "2.4.3", "2.4.4", "2.4.5", "2.5.7", "2.6.1", "2.6.2", "2.6.3", "2.7.5", "2.7.6", "2.8.2", "2.8.3", "2.8.4", "2.8.5", "2.8.6", "2.9.1", "2.9.2", "2.9.3",
+ "3.2.4", "3.3.3", "3.3.4", "3.5.1", "3.5.2", "3.5.3", "4.3.3", "5.4.1", "5.4.2", "5.4.3", "6.1.1", "6.1.2", "6.1.3", "6.2.2", "6.2.3", "6.2.4", "6.2.5", "6.2.6", "6.3.1",
+ "6.3.2", "6.4.1", "6.4.2", "7.1.3", "7.1.4", "7.2.1", "7.2.2", "7.3.1", "7.3.2", "7.3.3", "7.3.4", "7.4.2", "7.4.3", "8.1.1", "8.1.2", "8.1.3", "8.1.4", "8.3.5", "8.3.6",
+ "8.3.7", "8.3.8", "9.2.1", "9.2.2", "9.2.3", "9.2.4", "10.2.1", "10.2.2", "11.1.6", "11.1.7", "11.1.8", "12.1.2", "12.1.3", "12.2.1", "12.3.6", "13.1.4", "13.1.5", "13.2.4",
+ "13.2.5", "13.2.6", "13.3.2", "13.4.1", "13.4.2", "14.1.1", "14.1.2", "14.1.3", "14.1.4", "14.2.4", "14.2.5", "14.2.6", "14.5.4"), OWASP_ASVS_40_LEVEL_1.stream())
.toList();
private static final List<String> OWASP_ASVS_40_LEVEL_3 = Stream
@@ -326,14 +328,96 @@ public final class SecurityStandards {
private static final Ordering<SQCategory> SQ_CATEGORY_ORDERING = Ordering.explicit(stream(SQCategory.values()).toList());
public static final Ordering<String> SQ_CATEGORY_KEYS_ORDERING = Ordering.explicit(stream(SQCategory.values()).map(SQCategory::getKey).toList());
+ public static final Map<String, String> CWES_BY_CASA_CATEGORY;
+
+ static {
+ Map<String, String> map = new HashMap<>();
+ map.put("1.1.4", "1059");
+ map.put("1.14.6", "477");
+ map.put("1.4.1", "602");
+ map.put("1.8.1", null);
+ map.put("1.8.2", null);
+ map.put("2.1.1", "521");
+ map.put("2.3.1", "330");
+ map.put("2.4.1", "916");
+ map.put("2.5.4", "16");
+ map.put("2.6.1", "308");
+ map.put("2.7.2", "287");
+ map.put("2.7.6", "310");
+ map.put("3.3.1", "613");
+ map.put("3.3.3", "613");
+ map.put("3.4.1", "614");
+ map.put("3.4.2", "1004");
+ map.put("3.4.3", "1275");
+ map.put("3.5.2", "798");
+ map.put("3.5.3", "345");
+ map.put("3.7.1", "306");
+ map.put("4.1.1", "602");
+ map.put("4.1.2", "639");
+ map.put("4.1.3", "285");
+ map.put("4.1.5", "285");
+ map.put("4.2.1", "639");
+ map.put("4.2.2", "352");
+ map.put("4.3.1", "419");
+ map.put("4.3.2", "548");
+ map.put("5.1.1", "235");
+ map.put("5.1.5", "601");
+ map.put("5.2.3", "147");
+ map.put("5.2.4", "95");
+ map.put("5.2.5", "94");
+ map.put("5.2.6", "918");
+ map.put("5.2.7", "159");
+ map.put("5.3.1", "116");
+ map.put("5.3.10", "643");
+ map.put("5.3.3", "79");
+ map.put("5.3.4", "89");
+ map.put("5.3.6", "830");
+ map.put("5.3.7", "90");
+ map.put("5.3.8", "78");
+ map.put("5.3.9", "829");
+ map.put("5.5.2", "611");
+ map.put("6.1.1", "311");
+ map.put("6.2.1", "310");
+ map.put("6.2.3", "326");
+ map.put("6.2.4", "326");
+ map.put("6.2.7", "326");
+ map.put("6.2.8", "385");
+ map.put("6.3.2", "338");
+ map.put("6.4.2", "320");
+ map.put("7.1.1", "532");
+ map.put("8.1.1", "524");
+ map.put("8.2.2", "922");
+ map.put("8.3.1", "319");
+ map.put("8.3.5", "532");
+ map.put("9.1.2", "326");
+ map.put("9.2.1", "295");
+ map.put("9.2.4", "299");
+ map.put("10.3.2", "353");
+ map.put("10.3.3", "350");
+ map.put("11.1.4", "770");
+ map.put("12.4.1", "552");
+ map.put("12.4.2", "509");
+ map.put("13.1.3", "598");
+ map.put("13.1.4", "285");
+ map.put("13.2.1", "650");
+ map.put("14.1.1", null);
+ map.put("14.1.4", null);
+ map.put("14.1.5", null);
+ map.put("14.3.2", "497");
+ map.put("14.5.2", "346");
+ CWES_BY_CASA_CATEGORY = Collections.unmodifiableMap(map);
+ }
private final Set<String> standards;
private final Set<String> cwe;
+ private final Set<String> casaCategories;
private final SQCategory sqCategory;
private final Set<SQCategory> ignoredSQCategories;
- private SecurityStandards(Set<String> standards, Set<String> cwe, SQCategory sqCategory, Set<SQCategory> ignoredSQCategories) {
+ private SecurityStandards(Set<String> standards, Set<String> cwe, Set<String> casaCategories,
+ SQCategory sqCategory, Set<SQCategory> ignoredSQCategories) {
this.standards = standards;
this.cwe = cwe;
+ this.casaCategories = casaCategories;
this.sqCategory = sqCategory;
this.ignoredSQCategories = ignoredSQCategories;
}
@@ -370,6 +454,10 @@ public final class SecurityStandards {
return getMatchingStandards(standards, version.prefix() + ":");
}
+ public Set<String> getCasa() {
+ return casaCategories;
+ }
+
/**
* @deprecated SansTop25 report is outdated, it has been completely deprecated in version 10.0 and will be removed from version 11.0
*/
@@ -402,7 +490,8 @@ public final class SecurityStandards {
List<SQCategory> sq = toSortedSQCategories(cwe);
SQCategory sqCategory = sq.iterator().next();
Set<SQCategory> ignoredSQCategories = sq.stream().skip(1).collect(Collectors.toSet());
- return new SecurityStandards(standards, cwe, sqCategory, ignoredSQCategories);
+ Set<String> casaCategories = toCasaCategories(cwe);
+ return new SecurityStandards(standards, cwe, casaCategories, sqCategory, ignoredSQCategories);
}
public static Set<String> getRequirementsForCategoryAndLevel(String category, int level) {
@@ -456,4 +545,12 @@ public final class SecurityStandards {
return result.isEmpty() ? singletonList(SQCategory.OTHERS) : result;
}
+ private static Set<String> toCasaCategories(Set<String> cwe) {
+ return CWES_BY_CASA_CATEGORY
+ .keySet()
+ .stream()
+ .filter(k -> cwe.contains(CWES_BY_CASA_CATEGORY.get(k)))
+ .collect(Collectors.toSet());
+ }
+
}
diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/issue/SearchRequestTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/issue/SearchRequestTest.java
index 1779e509993..fa0c0e485f7 100644
--- a/server/sonar-server-common/src/test/java/org/sonar/server/issue/SearchRequestTest.java
+++ b/server/sonar-server-common/src/test/java/org/sonar/server/issue/SearchRequestTest.java
@@ -55,6 +55,7 @@ public class SearchRequestTest {
.setOwaspAsvs40(asList("1.1.1", "4.2.2"))
.setOwaspAsvsLevel(2)
.setStigAsdV5R3(List.of("V-222400", "V-222401"))
+ .setCasa(List.of("1.4.1", "6.4.2"))
.setPciDss32(asList("1", "4"))
.setPciDss40(asList("3", "5"))
.setCodeVariants(asList("variant1", "variant2"))
@@ -83,6 +84,7 @@ public class SearchRequestTest {
assertThat(underTest.getInNewCodePeriod()).isTrue();
assertOwasp(underTest);
assertThat(underTest.getStigAsdV5R3()).containsExactly("V-222400", "V-222401");
+ assertThat(underTest.getStigAsdV5R3()).containsExactly("V-222400", "V-222401");
assertThat(underTest.getPciDss32()).containsExactly("1", "4");
assertThat(underTest.getPciDss40()).containsExactly("3", "5");
assertThat(underTest.getCodeVariants()).containsExactly("variant1", "variant2");
diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/security/SecurityStandardsTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/security/SecurityStandardsTest.java
index 09d2f53ceb2..37806b612f7 100644
--- a/server/sonar-server-common/src/test/java/org/sonar/server/security/SecurityStandardsTest.java
+++ b/server/sonar-server-common/src/test/java/org/sonar/server/security/SecurityStandardsTest.java
@@ -113,6 +113,12 @@ class SecurityStandardsTest {
}
@Test
+ void fromSecurityStandards_shouldReturnExpectedCasaBasedOnCweMapping() {
+ SecurityStandards securityStandards = fromSecurityStandards(Set.of("cwe:326", "cwe:477"));
+ assertThat(securityStandards.getCasa()).containsExactly("6.2.3", "1.14.6", "9.1.2", "6.2.7", "6.2.4");
+ }
+
+ @Test
void fromSecurityStandards_finds_SQCategory_first_in_order_when_CWEs_map_to_multiple_SQCategories() {
EnumSet<SQCategory> sqCategories = EnumSet.allOf(SQCategory.class);
sqCategories.remove(SQCategory.OTHERS);
diff --git a/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndex.java b/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndex.java
index 61f39ec36d0..8ce28b2d237 100644
--- a/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndex.java
+++ b/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndex.java
@@ -127,6 +127,7 @@ import static org.sonar.server.es.searchrequest.TopAggregationHelper.NO_OTHER_SU
import static org.sonar.server.issue.index.IssueIndex.Facet.ASSIGNED_TO_ME;
import static org.sonar.server.issue.index.IssueIndex.Facet.ASSIGNEES;
import static org.sonar.server.issue.index.IssueIndex.Facet.AUTHOR;
+import static org.sonar.server.issue.index.IssueIndex.Facet.CASA;
import static org.sonar.server.issue.index.IssueIndex.Facet.CLEAN_CODE_ATTRIBUTE_CATEGORY;
import static org.sonar.server.issue.index.IssueIndex.Facet.CODE_VARIANTS;
import static org.sonar.server.issue.index.IssueIndex.Facet.CREATED_AT;
@@ -157,6 +158,7 @@ import static org.sonar.server.issue.index.IssueIndex.Facet.TYPES;
import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_ISSUE_ASSIGNEE_UUID;
import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_ISSUE_AUTHOR_LOGIN;
import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_ISSUE_BRANCH_UUID;
+import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_ISSUE_CASA;
import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_ISSUE_CLEAN_CODE_ATTRIBUTE_CATEGORY;
import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_ISSUE_CODE_VARIANTS;
import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_ISSUE_COMPONENT_UUID;
@@ -204,6 +206,7 @@ import static org.sonar.server.view.index.ViewIndexDefinition.TYPE_VIEW;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.FACET_MODE_EFFORT;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_ASSIGNEES;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_AUTHOR;
+import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_CASA;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_CLEAN_CODE_ATTRIBUTE_CATEGORIES;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_CODE_VARIANTS;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_CREATED_AT;
@@ -293,6 +296,7 @@ public class IssueIndex {
OWASP_TOP_10(PARAM_OWASP_TOP_10, FIELD_ISSUE_OWASP_TOP_10, STICKY, DEFAULT_FACET_SIZE),
OWASP_TOP_10_2021(PARAM_OWASP_TOP_10_2021, FIELD_ISSUE_OWASP_TOP_10_2021, STICKY, DEFAULT_FACET_SIZE),
STIG_ASD_V5R3(PARAM_STIG_ASD_V5R3, FIELD_ISSUE_STIG_ASD_V5R3, STICKY, DEFAULT_FACET_SIZE),
+ CASA(PARAM_CASA, FIELD_ISSUE_CASA, STICKY, DEFAULT_FACET_SIZE),
SANS_TOP_25(PARAM_SANS_TOP_25, FIELD_ISSUE_SANS_TOP_25, STICKY, DEFAULT_FACET_SIZE),
CWE(PARAM_CWE, FIELD_ISSUE_CWE, STICKY, DEFAULT_FACET_SIZE),
CREATED_AT(PARAM_CREATED_AT, FIELD_ISSUE_FUNC_CREATED_AT, NON_STICKY),
@@ -507,6 +511,7 @@ public class IssueIndex {
addSecurityCategoryFilter(FIELD_ISSUE_OWASP_TOP_10, OWASP_TOP_10, query.owaspTop10(), filters);
addSecurityCategoryFilter(FIELD_ISSUE_OWASP_TOP_10_2021, OWASP_TOP_10_2021, query.owaspTop10For2021(), filters);
addSecurityCategoryFilter(FIELD_ISSUE_STIG_ASD_V5R3, STIG_ASD_V5R3, query.stigAsdV5R3(), filters);
+ addSecurityCategoryPrefixFilter(FIELD_ISSUE_CASA, CASA, query.casa(), filters);
addSecurityCategoryFilter(FIELD_ISSUE_SANS_TOP_25, SANS_TOP_25, query.sansTop25(), filters);
addSecurityCategoryFilter(FIELD_ISSUE_CWE, CWE, query.cwe(), filters);
addSecurityCategoryFilter(FIELD_ISSUE_SQ_SECURITY_CATEGORY, SONARSOURCE_SECURITY, query.sonarsourceSecurity(), filters);
@@ -561,7 +566,7 @@ public class IssueIndex {
}
/**
- * <p>Builds the Elasticsearch boolean query to filter the PCI DSS categories.</p>
+ * <p>Builds the Elasticsearch boolean query to filter the PCI DSS and CASA.</p>
*
* <p>The PCI DSS security report handles all the subcategories as one level. This means that subcategory 1.1 doesn't include the issues from 1.1.1.
* Taking this into account, the search filter follows the same logic and uses prefix matching for top-level categories and exact matching for subcategories</p>
@@ -895,6 +900,7 @@ public class IssueIndex {
addSecurityCategoryFacetIfNeeded(PARAM_OWASP_TOP_10, OWASP_TOP_10, options, aggregationHelper, esRequest, query.owaspTop10().toArray());
addSecurityCategoryFacetIfNeeded(PARAM_OWASP_TOP_10_2021, OWASP_TOP_10_2021, options, aggregationHelper, esRequest, query.owaspTop10For2021().toArray());
addSecurityCategoryFacetIfNeeded(PARAM_STIG_ASD_V5R3, STIG_ASD_V5R3, options, aggregationHelper, esRequest, query.stigAsdV5R3().toArray());
+ addSecurityCategoryFacetIfNeeded(PARAM_CASA, CASA, options, aggregationHelper, esRequest, query.casa().toArray());
addSecurityCategoryFacetIfNeeded(PARAM_SANS_TOP_25, SANS_TOP_25, options, aggregationHelper, esRequest, query.sansTop25().toArray());
addSecurityCategoryFacetIfNeeded(PARAM_CWE, CWE, options, aggregationHelper, esRequest, query.cwe().toArray());
addSecurityCategoryFacetIfNeeded(PARAM_SONARSOURCE_SECURITY, SONARSOURCE_SECURITY, options, aggregationHelper, esRequest, query.sonarsourceSecurity().toArray());
diff --git a/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQuery.java b/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQuery.java
index bcaa26373a9..536deb94d1b 100644
--- a/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQuery.java
+++ b/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQuery.java
@@ -81,6 +81,7 @@ public class IssueQuery {
private final Integer owaspAsvsLevel;
private final Collection<String> owaspTop10For2021;
private final Collection<String> stigAsdV5R3;
+ private final Collection<String> casa;
private final Collection<String> sansTop25;
private final Collection<String> cwe;
private final Collection<String> sonarsourceSecurity;
@@ -131,6 +132,7 @@ public class IssueQuery {
this.owaspTop10 = defaultCollection(builder.owaspTop10);
this.owaspTop10For2021 = defaultCollection(builder.owaspTop10For2021);
this.stigAsdV5R3 = defaultCollection(builder.stigAsdV5R3);
+ this.casa = defaultCollection(builder.casa);
this.sansTop25 = defaultCollection(builder.sansTop25);
this.cwe = defaultCollection(builder.cwe);
this.sonarsourceSecurity = defaultCollection(builder.sonarsourceSecurity);
@@ -266,6 +268,10 @@ public class IssueQuery {
return stigAsdV5R3;
}
+ public Collection<String> casa() {
+ return casa;
+ }
+
public Collection<String> sansTop25() {
return sansTop25;
}
@@ -399,6 +405,7 @@ public class IssueQuery {
private Collection<String> owaspTop10;
private Collection<String> owaspTop10For2021;
private Collection<String> stigAsdV5R3;
+ private Collection<String> casa;
private Collection<String> sansTop25;
private Collection<String> cwe;
private Collection<String> sonarsourceSecurity;
@@ -564,6 +571,11 @@ public class IssueQuery {
return this;
}
+ public Builder casa(@Nullable Collection<String> o) {
+ this.casa = o;
+ return this;
+ }
+
public Builder sansTop25(@Nullable Collection<String> s) {
this.sansTop25 = s;
return this;
diff --git a/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQueryFactory.java b/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQueryFactory.java
index 43fb8a0cb26..3037d74553a 100644
--- a/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQueryFactory.java
+++ b/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQueryFactory.java
@@ -153,6 +153,7 @@ public class IssueQueryFactory {
.owaspTop10(request.getOwaspTop10())
.owaspTop10For2021(request.getOwaspTop10For2021())
.stigAsdR5V3(request.getStigAsdV5R3())
+ .casa(request.getCasa())
.sansTop25(request.getSansTop25())
.cwe(request.getCwe())
.sonarsourceSecurity(request.getSonarsourceSecurity())
diff --git a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueQueryTest.java b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueQueryTest.java
index 003a1db746d..d3684444443 100644
--- a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueQueryTest.java
+++ b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueQueryTest.java
@@ -136,6 +136,15 @@ class IssueQueryTest {
assertThat(query.stigAsdV5R3()).containsOnly("V-222400", "V-222401");
}
+ @Test
+ void build_casa_query() {
+ IssueQuery query = IssueQuery.builder()
+ .casa(List.of("1.1.4", "6.1.1"))
+ .build();
+
+ assertThat(query.casa()).containsOnly("1.1.4", "6.1.1");
+ }
+
@Test
void build_query_without_dates() {
diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/hotspot/ws/SearchActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/hotspot/ws/SearchActionIT.java
index a6cbbd43ef2..893a8214476 100644
--- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/hotspot/ws/SearchActionIT.java
+++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/hotspot/ws/SearchActionIT.java
@@ -114,6 +114,7 @@ import static org.sonar.db.component.ComponentTesting.newFileDto;
import static org.sonar.db.issue.IssueTesting.newCodeReferenceIssue;
import static org.sonar.db.issue.IssueTesting.newIssue;
import static org.sonar.db.newcodeperiod.NewCodePeriodType.REFERENCE_BRANCH;
+import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_CASA;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_STIG_ASD_V5R3;
@SuppressWarnings("ALL")
@@ -171,6 +172,7 @@ public class SearchActionIT {
WebService.Param owasAsvs40Param = actionTester.getDef().param(PARAM_OWASP_ASVS_40);
WebService.Param owaspTop10Param = actionTester.getDef().param(PARAM_OWASP_TOP_10_2017);
WebService.Param stigAsdV5R3 = actionTester.getDef().param(PARAM_STIG_ASD_V5R3);
+ WebService.Param casa = actionTester.getDef().param(PARAM_CASA);
WebService.Param sansTop25Param = actionTester.getDef().param(PARAM_SANS_TOP_25);
WebService.Param sonarsourceSecurityParam = actionTester.getDef().param(PARAM_SONARSOURCE_SECURITY);
WebService.Param filesParam = actionTester.getDef().param(PARAM_FILES);
@@ -191,6 +193,8 @@ public class SearchActionIT {
assertThat(owaspTop10Param.isRequired()).isFalse();
assertThat(stigAsdV5R3).isNotNull();
assertThat(stigAsdV5R3.isRequired()).isFalse();
+ assertThat(casa).isNotNull();
+ assertThat(casa.isRequired()).isFalse();
assertThat(sansTop25Param).isNotNull();
assertThat(sansTop25Param.isRequired()).isFalse();
assertThat(sonarsourceSecurityParam).isNotNull();
@@ -1571,6 +1575,37 @@ public class SearchActionIT {
}
@Test
+ public void executeProtobuf_WhenHotspotHasCwe_shoultReturnExpectedHotspotOnCasaParam() {
+ ProjectData projectData = dbTester.components().insertPublicProject();
+ ComponentDto project = projectData.getMainBranchComponent();
+
+ userSessionRule.registerProjects(projectData.getProjectDto());
+ indexPermissions();
+ ComponentDto file = dbTester.components().insertComponent(newFileDto(project));
+ RuleDto rule1 = newRule(SECURITY_HOTSPOT);
+ RuleDto rule2 = newRule(SECURITY_HOTSPOT, r -> r.setSecurityStandards(Set.of("cwe:310")));
+ RuleDto rule3 = newRule(SECURITY_HOTSPOT, r -> r.setSecurityStandards(Set.of("cwe:639")));
+ insertHotspot(project, file, rule1);
+ insertHotspot(project, file, rule2);
+ IssueDto hotspot3 = insertHotspot(project, file, rule3);
+ indexIssues();
+
+ SearchWsResponse response = newRequest(project).setParam(PARAM_CASA, "4.1.2")
+ .executeProtobuf(SearchWsResponse.class);
+
+ assertThat(response.getHotspotsList())
+ .extracting(SearchWsResponse.Hotspot::getKey)
+ .containsExactly(hotspot3.getKey());
+
+ response = newRequest(project).setParam(PARAM_CASA, "4")
+ .executeProtobuf(SearchWsResponse.class);
+
+ assertThat(response.getHotspotsList())
+ .extracting(SearchWsResponse.Hotspot::getKey)
+ .containsExactly(hotspot3.getKey());
+ }
+
+ @Test
public void returns_hotspots_with_specified_pciDss_category() {
ProjectData projectData = dbTester.components().insertPublicProject();
ComponentDto project = projectData.getMainBranchComponent();
diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/SearchActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/SearchActionIT.java
index 9d9818ec646..516107ac4c8 100644
--- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/SearchActionIT.java
+++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/issue/ws/SearchActionIT.java
@@ -1767,11 +1767,56 @@ public class SearchActionIT {
SearchWsResponse result = ws.newRequest()
.setParam("stig-ASD_V5R3", "V-222402")
+ .setParam(FACETS, "stig-ASD_V5R3")
.executeProtobuf(SearchWsResponse.class);
assertThat(result.getIssuesList())
.extracting(Issue::getKey)
.containsExactlyInAnyOrder(issueDto1.getKey(), issueDto2.getKey());
+
+ assertThat(result.getFacets().getFacets(0).getValuesList())
+ .extracting(Common.FacetValue::getVal, Common.FacetValue::getCount)
+ .containsExactlyInAnyOrder(tuple("V-222402", 2L), tuple("V-222403", 2L), tuple("V-222404", 2L));
+ }
+
+ @Test
+ public void only_vulnerabilities_are_returned_by_casa() {
+ ComponentDto project = db.components().insertPublicProject().getMainBranchComponent();
+ ComponentDto file = db.components().insertComponent(newFileDto(project));
+ Consumer<RuleDto> ruleConsumer = ruleDefinitionDto -> ruleDefinitionDto
+ .setSecurityStandards(Sets.newHashSet("cwe:20", "cwe:564", "cwe:639", "cwe:326"))
+ .setSystemTags(Sets.newHashSet("bad-practice", "cwe", "sans-top25-insecure", "sql"));
+ Consumer<IssueDto> issueConsumer = issueDto -> issueDto.setTags(Sets.newHashSet("bad-practice", "cwe", "sans-top25-insecure", "sql"));
+ RuleDto hotspotRule = db.rules().insertHotspotRule(ruleConsumer);
+ db.issues().insertHotspot(hotspotRule, project, file, issueConsumer);
+ RuleDto issueRule = db.rules().insertIssueRule(ruleConsumer);
+ IssueDto issueDto1 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(RuleType.VULNERABILITY));
+ IssueDto issueDto2 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(RuleType.VULNERABILITY));
+ db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(CODE_SMELL));
+ indexPermissionsAndIssues();
+
+ SearchWsResponse result = ws.newRequest()
+ .setParam("casa", "4.1.2")
+ .setParam(FACETS, "casa")
+ .executeProtobuf(SearchWsResponse.class);
+
+ assertThat(result.getIssuesList())
+ .extracting(Issue::getKey)
+ .containsExactlyInAnyOrder(issueDto1.getKey(), issueDto2.getKey());
+
+ assertThat(result.getFacets().getFacets(0).getValuesList())
+ .extracting(Common.FacetValue::getVal, Common.FacetValue::getCount)
+ .containsExactlyInAnyOrder(tuple("4.1.2", 2L), tuple("4.2.1", 2L), tuple("6.2.3", 2L),
+ tuple("6.2.4", 2L), tuple("6.2.7", 2L), tuple("9.1.2", 2L));
+
+ result = ws.newRequest()
+ .setParam("casa", "4")
+ .executeProtobuf(SearchWsResponse.class);
+
+ assertThat(result.getIssuesList())
+ .as("We should be able to search with only the prefix '4'")
+ .extracting(Issue::getKey)
+ .containsExactlyInAnyOrder(issueDto1.getKey(), issueDto2.getKey());
}
@Test
@@ -2108,7 +2153,7 @@ public class SearchActionIT {
"additionalFields", "asc", "assigned", "assignees", "author", "components", "branch", "pullRequest", "createdAfter", "createdAt",
"createdBefore", "createdInLast", "directories", "facets", "files", "issues", "scopes", "languages", "onComponentOnly",
"p", "projects", "ps", "resolutions", "resolved", "rules", "s", "severities", "statuses", "tags", "types", "pciDss-3.2", "pciDss-4.0", "owaspAsvs-4.0",
- "owaspAsvsLevel", "owaspTop10", "owaspTop10-2021", "stig-ASD_V5R3", "sansTop25", "cwe", "sonarsourceSecurity", "timeZone", "inNewCodePeriod", "codeVariants",
+ "owaspAsvsLevel", "owaspTop10", "owaspTop10-2021", "stig-ASD_V5R3", "casa", "sansTop25", "cwe", "sonarsourceSecurity", "timeZone", "inNewCodePeriod", "codeVariants",
"cleanCodeAttributeCategories", "impactSeverities", "impactSoftwareQualities", "issueStatuses", "fixedInPullRequest",
"prioritizedRule");
diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/SearchAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/SearchAction.java
index 09b0cefe680..9ccf68d9498 100644
--- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/SearchAction.java
+++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/SearchAction.java
@@ -111,6 +111,7 @@ public class SearchAction implements HotspotsWsAction {
private static final String PARAM_OWASP_TOP_10_2017 = "owaspTop10";
private static final String PARAM_OWASP_TOP_10_2021 = "owaspTop10-2021";
private static final String PARAM_STIG_ASD_V5R3 = "stig-ASD_V5R3";
+ private static final String PARAM_CASA = "casa";
/**
* @deprecated SansTop25 report is outdated, it has been completely deprecated in version 10.0 and will be removed from version 11.0
*/
@@ -153,6 +154,7 @@ public class SearchAction implements HotspotsWsAction {
Set<String> owasp2017Top10 = setFromList(request.paramAsStrings(PARAM_OWASP_TOP_10_2017));
Set<String> owasp2021Top10 = setFromList(request.paramAsStrings(PARAM_OWASP_TOP_10_2021));
Set<String> stigAsdV5R3 = setFromList(request.paramAsStrings(PARAM_STIG_ASD_V5R3));
+ Set<String> casa = setFromList(request.paramAsStrings(PARAM_CASA));
Set<String> sansTop25 = setFromList(request.paramAsStrings(PARAM_SANS_TOP_25));
Set<String> sonarsourceSecurity = setFromList(request.paramAsStrings(PARAM_SONARSOURCE_SECURITY));
Set<String> cwes = setFromList(request.paramAsStrings(PARAM_CWE));
@@ -162,7 +164,7 @@ public class SearchAction implements HotspotsWsAction {
request.mandatoryParamAsInt(PAGE), request.mandatoryParamAsInt(PAGE_SIZE), request.param(PARAM_PROJECT), request.param(PARAM_BRANCH),
request.param(PARAM_PULL_REQUEST), hotspotKeys, request.param(PARAM_STATUS), request.param(PARAM_RESOLUTION),
request.paramAsBoolean(PARAM_IN_NEW_CODE_PERIOD), request.paramAsBoolean(PARAM_ONLY_MINE), request.paramAsInt(PARAM_OWASP_ASVS_LEVEL),
- pciDss32, pciDss40, owaspAsvs40, owasp2017Top10, owasp2021Top10, stigAsdV5R3, sansTop25, sonarsourceSecurity, cwes, files);
+ pciDss32, pciDss40, owaspAsvs40, owasp2017Top10, owasp2021Top10, stigAsdV5R3, casa, sansTop25, sonarsourceSecurity, cwes, files);
}
@Override
@@ -208,6 +210,9 @@ public class SearchAction implements HotspotsWsAction {
if (!wsRequest.getStigAsdV5R3().isEmpty()) {
builder.stigAsdR5V3(wsRequest.getStigAsdV5R3());
}
+ if (!wsRequest.getCasa().isEmpty()) {
+ builder.casa(wsRequest.getCasa());
+ }
if (!wsRequest.getSansTop25().isEmpty()) {
builder.sansTop25(wsRequest.getSansTop25());
}
@@ -230,7 +235,7 @@ public class SearchAction implements HotspotsWsAction {
+ "When issue indexing is in progress returns 503 service unavailable HTTP code.")
.setSince("8.1")
.setChangelog(
- new Change("10.7", format("Added parameter '%s'", PARAM_STIG_ASD_V5R3)),
+ new Change("10.7", format("Added parameter '%s' and '%s'", PARAM_STIG_ASD_V5R3, PARAM_CASA)),
new Change("10.2", format("Parameter '%s' renamed to '%s'", PARAM_PROJECT_KEY, PARAM_PROJECT)),
new Change("10.0", "Parameter 'sansTop25' is deprecated"),
new Change("9.6", "Added parameters 'pciDss-3.2' and 'pciDss-4.0"),
@@ -315,6 +320,9 @@ public class SearchAction implements HotspotsWsAction {
action.createParam(PARAM_STIG_ASD_V5R3)
.setDescription("Comma-separated list of STIG V5R3 lowercase categories.")
.setSince("10.7");
+ action.createParam(PARAM_CASA)
+ .setDescription("Comma-separated list of CASA categories.")
+ .setSince("10.7");
action.createParam(PARAM_SANS_TOP_25)
.setDescription("Comma-separated list of SANS Top 25 categories.")
.setDeprecatedSince("10.0")
@@ -624,6 +632,7 @@ public class SearchAction implements HotspotsWsAction {
private final Set<String> owaspTop10For2017;
private final Set<String> owaspTop10For2021;
private final Set<String> stigAsdV5R3;
+ private final Set<String> casa;
private final Set<String> sansTop25;
private final Set<String> sonarsourceSecurity;
private final Set<String> cwe;
@@ -633,7 +642,7 @@ public class SearchAction implements HotspotsWsAction {
@Nullable String projectKey, @Nullable String branch, @Nullable String pullRequest, Set<String> hotspotKeys,
@Nullable String status, @Nullable String resolution, @Nullable Boolean inNewCodePeriod, @Nullable Boolean onlyMine,
@Nullable Integer owaspAsvsLevel, Set<String> pciDss32, Set<String> pciDss40, Set<String> owaspAsvs40,
- Set<String> owaspTop10For2017, Set<String> owaspTop10For2021, Set<String> stigAsdV5R3, Set<String> sansTop25, Set<String> sonarsourceSecurity,
+ Set<String> owaspTop10For2017, Set<String> owaspTop10For2021, Set<String> stigAsdV5R3, Set<String> casa, Set<String> sansTop25, Set<String> sonarsourceSecurity,
Set<String> cwe, @Nullable Set<String> files) {
this.page = page;
this.index = index;
@@ -652,6 +661,7 @@ public class SearchAction implements HotspotsWsAction {
this.owaspTop10For2017 = owaspTop10For2017;
this.owaspTop10For2021 = owaspTop10For2021;
this.stigAsdV5R3 = stigAsdV5R3;
+ this.casa = casa;
this.sansTop25 = sansTop25;
this.sonarsourceSecurity = sonarsourceSecurity;
this.cwe = cwe;
@@ -726,6 +736,10 @@ public class SearchAction implements HotspotsWsAction {
return stigAsdV5R3;
}
+ public Set<String> getCasa() {
+ return casa;
+ }
+
public Set<String> getSansTop25() {
return sansTop25;
}
diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SearchAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SearchAction.java
index b0fa2213b27..9caf366a7e5 100644
--- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SearchAction.java
+++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SearchAction.java
@@ -99,6 +99,7 @@ import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_ASSIGNED;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_ASSIGNEES;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_AUTHOR;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_BRANCH;
+import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_CASA;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_CLEAN_CODE_ATTRIBUTE_CATEGORIES;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_CODE_VARIANTS;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_COMPONENTS;
@@ -166,6 +167,7 @@ public class SearchAction implements IssuesWsAction {
PARAM_OWASP_TOP_10,
PARAM_OWASP_TOP_10_2021,
PARAM_STIG_ASD_V5R3,
+ PARAM_CASA,
PARAM_SANS_TOP_25,
PARAM_CWE,
PARAM_CREATED_AT,
@@ -215,6 +217,8 @@ public class SearchAction implements IssuesWsAction {
+ "<br/>When issue indexing is in progress returns 503 service unavailable HTTP code.")
.setSince("3.6")
.setChangelog(
+ new Change("10.7", format(NEW_FACET_ADDED_MESSAGE, PARAM_CASA)),
+ new Change("10.7", format(NEW_PARAM_ADDED_MESSAGE, PARAM_CASA)),
new Change("10.7", format(NEW_FACET_ADDED_MESSAGE, PARAM_STIG_ASD_V5R3)),
new Change("10.7", format(NEW_PARAM_ADDED_MESSAGE, PARAM_STIG_ASD_V5R3)),
new Change("10.6", format(NEW_FACET_ADDED_MESSAGE, PARAM_PRIORITIZED_RULE)),
@@ -377,7 +381,10 @@ public class SearchAction implements IssuesWsAction {
.setPossibleValues("a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "a10");
action.createParam(PARAM_STIG_ASD_V5R3)
.setDescription("Comma-separated list of STIG V5R3 categories.")
- .setSince("9.4");
+ .setSince("10.7");
+ action.createParam(PARAM_CASA)
+ .setDescription("Comma-separated list of CASA categories.")
+ .setSince("10.7");
action.createParam(PARAM_SANS_TOP_25)
.setDescription("Comma-separated list of SANS Top 25 categories.")
.setDeprecatedSince("10.0")
@@ -602,6 +609,7 @@ public class SearchAction implements IssuesWsAction {
addMandatoryValuesToFacet(facets, PARAM_OWASP_TOP_10, request.getOwaspTop10());
addMandatoryValuesToFacet(facets, PARAM_OWASP_TOP_10_2021, request.getOwaspTop10For2021());
addMandatoryValuesToFacet(facets, PARAM_STIG_ASD_V5R3, request.getStigAsdV5R3());
+ addMandatoryValuesToFacet(facets, PARAM_CASA, request.getCasa());
addMandatoryValuesToFacet(facets, PARAM_SANS_TOP_25, request.getSansTop25());
addMandatoryValuesToFacet(facets, PARAM_CWE, request.getCwe());
addMandatoryValuesToFacet(facets, PARAM_SONARSOURCE_SECURITY, request.getSonarsourceSecurity());
@@ -690,6 +698,7 @@ public class SearchAction implements IssuesWsAction {
.setOwaspTop10(request.paramAsStrings(PARAM_OWASP_TOP_10))
.setOwaspTop10For2021(request.paramAsStrings(PARAM_OWASP_TOP_10_2021))
.setStigAsdV5R3(request.paramAsStrings(PARAM_STIG_ASD_V5R3))
+ .setCasa(request.paramAsStrings(PARAM_CASA))
.setSansTop25(request.paramAsStrings(PARAM_SANS_TOP_25))
.setCwe(request.paramAsStrings(PARAM_CWE))
.setSonarsourceSecurity(request.paramAsStrings(PARAM_SONARSOURCE_SECURITY))