From: Léo Geoffroy Date: Wed, 24 Jul 2024 09:39:07 +0000 (+0200) Subject: SONAR-22543 Index new CASA security standard X-Git-Tag: 10.7.0.96327~306 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=ebb080570d77aa6a8dbc0bd360a730e7015342ba;p=sonarqube.git SONAR-22543 Index new CASA security standard --- 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 owaspAsvs40; private List owaspTop10For2021; private List stigAsdV5R3; + private List casa; private List sansTop25; private List sonarsourceSecurity; private List cwe; @@ -447,6 +448,16 @@ public class SearchRequest { return this; } + @CheckForNull + public List getCasa() { + return casa; + } + + public SearchRequest setCasa(@Nullable List casa) { + this.casa = casa; + return this; + } + @CheckForNull public List 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 @@ -374,6 +374,16 @@ public class IssueDoc extends BaseDoc { return this; } + @CheckForNull + public Collection getCasa() { + return getNullableField(IssueIndexDefinition.FIELD_ISSUE_CASA); + } + + public IssueDoc setCasa(@Nullable Collection o) { + setField(IssueIndexDefinition.FIELD_ISSUE_CASA, o); + return this; + } + @CheckForNull public Collection 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 CWE_TOP25_2023 = List.of("787", "79", "89", "416", "78", "20", "125", "22", "352", "434", "862", "476", "287", "190", "502", + public static final List 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 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 OWASP_ASVS_40_LEVEL_3 = Stream @@ -326,14 +328,96 @@ public final class SecurityStandards { private static final Ordering SQ_CATEGORY_ORDERING = Ordering.explicit(stream(SQCategory.values()).toList()); public static final Ordering SQ_CATEGORY_KEYS_ORDERING = Ordering.explicit(stream(SQCategory.values()).map(SQCategory::getKey).toList()); + public static final Map CWES_BY_CASA_CATEGORY; + + static { + Map 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 standards; private final Set cwe; + private final Set casaCategories; private final SQCategory sqCategory; private final Set ignoredSQCategories; - private SecurityStandards(Set standards, Set cwe, SQCategory sqCategory, Set ignoredSQCategories) { + private SecurityStandards(Set standards, Set cwe, Set casaCategories, + SQCategory sqCategory, Set 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 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 sq = toSortedSQCategories(cwe); SQCategory sqCategory = sq.iterator().next(); Set ignoredSQCategories = sq.stream().skip(1).collect(Collectors.toSet()); - return new SecurityStandards(standards, cwe, sqCategory, ignoredSQCategories); + Set casaCategories = toCasaCategories(cwe); + return new SecurityStandards(standards, cwe, casaCategories, sqCategory, ignoredSQCategories); } public static Set getRequirementsForCategoryAndLevel(String category, int level) { @@ -456,4 +545,12 @@ public final class SecurityStandards { return result.isEmpty() ? singletonList(SQCategory.OTHERS) : result; } + private static Set toCasaCategories(Set 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 @@ -112,6 +112,12 @@ class SecurityStandardsTest { assertThat(securityStandards.getStig(RulesDefinition.StigVersion.ASD_V5R3)).containsExactly("V-222400"); } + @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 sqCategories = EnumSet.allOf(SQCategory.class); 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 { } /** - *

Builds the Elasticsearch boolean query to filter the PCI DSS categories.

+ *

Builds the Elasticsearch boolean query to filter the PCI DSS and CASA.

* *

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

@@ -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 owaspTop10For2021; private final Collection stigAsdV5R3; + private final Collection casa; private final Collection sansTop25; private final Collection cwe; private final Collection 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 casa() { + return casa; + } + public Collection sansTop25() { return sansTop25; } @@ -399,6 +405,7 @@ public class IssueQuery { private Collection owaspTop10; private Collection owaspTop10For2021; private Collection stigAsdV5R3; + private Collection casa; private Collection sansTop25; private Collection cwe; private Collection sonarsourceSecurity; @@ -564,6 +571,11 @@ public class IssueQuery { return this; } + public Builder casa(@Nullable Collection o) { + this.casa = o; + return this; + } + public Builder sansTop25(@Nullable Collection 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(); @@ -1570,6 +1574,37 @@ public class SearchActionIT { .containsExactly(hotspot3.getKey()); } + @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(); 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 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 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 owasp2017Top10 = setFromList(request.paramAsStrings(PARAM_OWASP_TOP_10_2017)); Set owasp2021Top10 = setFromList(request.paramAsStrings(PARAM_OWASP_TOP_10_2021)); Set stigAsdV5R3 = setFromList(request.paramAsStrings(PARAM_STIG_ASD_V5R3)); + Set casa = setFromList(request.paramAsStrings(PARAM_CASA)); Set sansTop25 = setFromList(request.paramAsStrings(PARAM_SANS_TOP_25)); Set sonarsourceSecurity = setFromList(request.paramAsStrings(PARAM_SONARSOURCE_SECURITY)); Set 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 owaspTop10For2017; private final Set owaspTop10For2021; private final Set stigAsdV5R3; + private final Set casa; private final Set sansTop25; private final Set sonarsourceSecurity; private final Set cwe; @@ -633,7 +642,7 @@ public class SearchAction implements HotspotsWsAction { @Nullable String projectKey, @Nullable String branch, @Nullable String pullRequest, Set hotspotKeys, @Nullable String status, @Nullable String resolution, @Nullable Boolean inNewCodePeriod, @Nullable Boolean onlyMine, @Nullable Integer owaspAsvsLevel, Set pciDss32, Set pciDss40, Set owaspAsvs40, - Set owaspTop10For2017, Set owaspTop10For2021, Set stigAsdV5R3, Set sansTop25, Set sonarsourceSecurity, + Set owaspTop10For2017, Set owaspTop10For2021, Set stigAsdV5R3, Set casa, Set sansTop25, Set sonarsourceSecurity, Set cwe, @Nullable Set 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 getCasa() { + return casa; + } + public Set 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 { + "
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)) diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/issue/IssuesWsParameters.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/issue/IssuesWsParameters.java index aa9d6305f92..4f8856d5c23 100644 --- a/sonar-ws/src/main/java/org/sonarqube/ws/client/issue/IssuesWsParameters.java +++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/issue/IssuesWsParameters.java @@ -96,6 +96,7 @@ public class IssuesWsParameters { public static final String PARAM_OWASP_TOP_10_2021 = "owaspTop10-2021"; public static final String PARAM_STIG_ASD_V5R3 = "stig-ASD_V5R3"; public static final String PARAM_STIG = "stig"; + public static final String PARAM_CASA = "casa"; @Deprecated public static final String PARAM_SANS_TOP_25 = "sansTop25"; public static final String PARAM_CWE_TOP_25 = "cweTop25";