From 3b7745121f384577dec62d760c214b96de1a8b5c Mon Sep 17 00:00:00 2001 From: Michal Duda Date: Tue, 23 Apr 2019 15:07:11 +0200 Subject: [PATCH] SONAR-11180 add security facet to api/rules/search --- .../java/org/sonar/db/rule/RuleTesting.java | 7 +- .../index/IssueIteratorForSingleChunk.java | 10 +-- .../org/sonar/server/rule/index/RuleDoc.java | 47 +++++++++++++ .../sonar/server/rule/index/RuleIndex.java | 58 +++++++++++++++ .../rule/index/RuleIndexDefinition.java | 9 +++ .../sonar/server/rule/index/RuleQuery.java | 44 ++++++++++++ .../SecurityStandardHelper.java | 5 +- .../server/issue/index/IssueIndexerTest.java | 4 +- .../server/rule/index/RuleIndexTest.java | 57 ++++++++++++++- .../sonar/server/issue/index/IssueIndex.java | 9 +-- .../sonar/server/issue/ws/SearchAction.java | 10 +-- .../server/rule/ws/RuleQueryFactory.java | 8 +++ .../sonar/server/rule/ws/RuleWsSupport.java | 30 +++++++- .../server/rule/ws/RulesWsParameters.java | 4 ++ .../sonar/server/rule/ws/SearchAction.java | 70 ++++++++++++++++++- .../server/securityreport/ws/ShowAction.java | 12 ++-- .../index/IssueIndexSecurityReportsTest.java | 8 +-- .../ws/ActivateRulesActionTest.java | 6 +- .../ws/DeactivateRulesActionTest.java | 6 +- .../server/rule/ws/SearchActionTest.java | 2 +- 20 files changed, 366 insertions(+), 40 deletions(-) rename server/sonar-server-common/src/main/java/org/sonar/server/{issue/index => security}/SecurityStandardHelper.java (98%) diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleTesting.java b/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleTesting.java index 6e579e1ef95..9df18d86726 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleTesting.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleTesting.java @@ -21,6 +21,7 @@ package org.sonar.db.rule; import com.google.common.collect.ImmutableSet; import java.util.Date; +import java.util.Set; import java.util.function.Consumer; import javax.annotation.Nullable; import org.sonar.api.rule.RuleKey; @@ -319,11 +320,15 @@ public class RuleTesting { public static Consumer setType(RuleType type) { return rule -> rule.setType(type); } - + public static Consumer setIsExternal(boolean isExternal) { return rule -> rule.setIsExternal(isExternal); } + public static Consumer setSecurityStandards(Set securityStandards) { + return rule -> rule.setSecurityStandards(securityStandards); + } + public static Consumer setIsTemplate(boolean isTemplate) { return rule -> rule.setIsTemplate(isTemplate); } 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 022a91f5281..ee54f4a6d9f 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 @@ -43,11 +43,11 @@ import org.sonar.db.ResultSetIterator; import static com.google.common.base.Preconditions.checkArgument; import static org.sonar.api.utils.DateUtils.longToDate; import static org.sonar.db.DatabaseUtils.getLong; -import static org.sonar.server.issue.index.SecurityStandardHelper.getCwe; -import static org.sonar.server.issue.index.SecurityStandardHelper.getOwaspTop10; -import static org.sonar.server.issue.index.SecurityStandardHelper.getSansTop25; -import static org.sonar.server.issue.index.SecurityStandardHelper.getSecurityStandards; -import static org.sonar.server.issue.index.SecurityStandardHelper.getSonarSourceSecurityCategories; +import static org.sonar.server.security.SecurityStandardHelper.getCwe; +import static org.sonar.server.security.SecurityStandardHelper.getOwaspTop10; +import static org.sonar.server.security.SecurityStandardHelper.getSansTop25; +import static org.sonar.server.security.SecurityStandardHelper.getSecurityStandards; +import static org.sonar.server.security.SecurityStandardHelper.getSonarSourceSecurityCategories; /** * Scrolls over table ISSUES and reads documents to populate diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleDoc.java b/server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleDoc.java index 0ab4ce88747..8d7b38be50d 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleDoc.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleDoc.java @@ -21,6 +21,7 @@ package org.sonar.server.rule.index; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.Maps; +import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Optional; @@ -34,6 +35,7 @@ import org.sonar.db.rule.RuleDto; import org.sonar.db.rule.RuleForIndexingDto; import org.sonar.markdown.Markdown; import org.sonar.server.es.BaseDoc; +import org.sonar.server.security.SecurityStandardHelper; import static org.sonar.server.rule.index.RuleIndexDefinition.TYPE_RULE; @@ -153,6 +155,46 @@ public class RuleDoc extends BaseDoc { return this; } + @CheckForNull + public Collection getOwaspTop10() { + return getNullableField(RuleIndexDefinition.FIELD_RULE_OWASP_TOP_10); + } + + public RuleDoc setOwaspTop10(@Nullable Collection o) { + setField(RuleIndexDefinition.FIELD_RULE_OWASP_TOP_10, o); + return this; + } + + @CheckForNull + public Collection getSansTop25() { + return getNullableField(RuleIndexDefinition.FIELD_RULE_SANS_TOP_25); + } + + public RuleDoc setSansTop25(@Nullable Collection s) { + setField(RuleIndexDefinition.FIELD_RULE_SANS_TOP_25, s); + return this; + } + + @CheckForNull + public Collection getCwe() { + return getNullableField(RuleIndexDefinition.FIELD_RULE_CWE); + } + + public RuleDoc setCwe(@Nullable Collection c) { + setField(RuleIndexDefinition.FIELD_RULE_CWE, c); + return this; + } + + @CheckForNull + public Collection getSonarSourceSecurityCategories() { + return getNullableField(RuleIndexDefinition.FIELD_RULE_SONARSOURCE_SECURITY); + } + + public RuleDoc setSonarSourceSecurityCategories(@Nullable Collection c) { + setField(RuleIndexDefinition.FIELD_RULE_SONARSOURCE_SECURITY, c); + return this; + } + @CheckForNull public RuleStatus status() { return RuleStatus.valueOf(getField(RuleIndexDefinition.FIELD_RULE_STATUS)); @@ -226,6 +268,7 @@ public class RuleDoc extends BaseDoc { } public static RuleDoc of(RuleForIndexingDto dto) { + Collection cwe = SecurityStandardHelper.getCwe(dto.getSecurityStandardsAsSet()); RuleDoc ruleDoc = new RuleDoc() .setId(dto.getId()) .setKey(dto.getRuleKey().toString()) @@ -234,6 +277,10 @@ public class RuleDoc extends BaseDoc { .setIsTemplate(dto.isTemplate()) .setIsExternal(dto.isExternal()) .setLanguage(dto.getLanguage()) + .setCwe(cwe) + .setOwaspTop10(SecurityStandardHelper.getOwaspTop10(dto.getSecurityStandardsAsSet())) + .setSansTop25(SecurityStandardHelper.getSansTop25(cwe)) + .setSonarSourceSecurityCategories(SecurityStandardHelper.getSonarSourceSecurityCategories(cwe)) .setName(dto.getName()) .setRuleKey(dto.getPluginRuleKey()) .setSeverity(dto.getSeverityAsString()) diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleIndex.java b/server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleIndex.java index d0e3c43107f..b26cf2e2dbd 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleIndex.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleIndex.java @@ -89,6 +89,7 @@ import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_ACTIVE_RULE_ import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_ACTIVE_RULE_PROFILE_UUID; import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_ACTIVE_RULE_SEVERITY; import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_CREATED_AT; +import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_CWE; import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_EXTENSION_SCOPE; import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_EXTENSION_TAGS; import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_HTML_DESCRIPTION; @@ -98,9 +99,12 @@ import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_IS_TEMP import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_KEY; import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_LANGUAGE; import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_NAME; +import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_OWASP_TOP_10; import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_REPOSITORY; import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_RULE_KEY; +import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_SANS_TOP_25; import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_SEVERITY; +import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_SONARSOURCE_SECURITY; import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_STATUS; import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_TEMPLATE_KEY; import static org.sonar.server.rule.index.RuleIndexDefinition.FIELD_RULE_TYPE; @@ -123,6 +127,10 @@ public class RuleIndex { public static final String FACET_STATUSES = "statuses"; public static final String FACET_TYPES = "types"; public static final String FACET_OLD_DEFAULT = "true"; + public static final String FACET_CWE = "cwe"; + public static final String FACET_SANS_TOP_25 = "sansTop25"; + public static final String FACET_OWASP_TOP_10 = "owaspTop10"; + public static final String FACET_SONARSOURCE_SECURITY = "sonarsourceSecurity"; private static final int MAX_FACET_SIZE = 100; @@ -271,6 +279,26 @@ public class RuleIndex { QueryBuilders.termsQuery(FIELD_RULE_SEVERITY, query.getSeverities())); } + if (isNotEmpty(query.getCwe())) { + filters.put(FIELD_RULE_CWE, + QueryBuilders.termsQuery(FIELD_RULE_CWE, query.getCwe())); + } + + if (isNotEmpty(query.getOwaspTop10())) { + filters.put(FIELD_RULE_OWASP_TOP_10, + QueryBuilders.termsQuery(FIELD_RULE_OWASP_TOP_10, query.getOwaspTop10())); + } + + if (isNotEmpty(query.getSansTop25())) { + filters.put(FIELD_RULE_SANS_TOP_25, + QueryBuilders.termsQuery(FIELD_RULE_SANS_TOP_25, query.getSansTop25())); + } + + if (isNotEmpty(query.getSonarsourceSecurity())) { + filters.put(FIELD_RULE_SONARSOURCE_SECURITY, + QueryBuilders.termsQuery(FIELD_RULE_SONARSOURCE_SECURITY, query.getSonarsourceSecurity())); + } + if (StringUtils.isNotEmpty(query.getKey())) { filters.put(FIELD_RULE_KEY, QueryBuilders.termQuery(FIELD_RULE_KEY, query.getKey())); @@ -452,6 +480,36 @@ public class RuleIndex { stickyFacetBuilder.buildStickyFacet(FIELD_RULE_REPOSITORY, FACET_REPOSITORIES, (repositories == null) ? (new String[0]) : repositories.toArray())); } + + addDefaultSecurityFacets(query, options, aggregations, stickyFacetBuilder); + } + + private static void addDefaultSecurityFacets(RuleQuery query, SearchOptions options, Map aggregations, + StickyFacetBuilder stickyFacetBuilder) { + if (options.getFacets().contains(FACET_CWE)) { + Collection categories = query.getCwe(); + aggregations.put(FACET_CWE, + stickyFacetBuilder.buildStickyFacet(FIELD_RULE_CWE, FACET_CWE, + (categories == null) ? (new String[0]) : categories.toArray())); + } + if (options.getFacets().contains(FACET_OWASP_TOP_10)) { + Collection categories = query.getOwaspTop10(); + aggregations.put(FACET_OWASP_TOP_10, + stickyFacetBuilder.buildStickyFacet(FIELD_RULE_OWASP_TOP_10, FACET_OWASP_TOP_10, + (categories == null) ? (new String[0]) : categories.toArray())); + } + if (options.getFacets().contains(FACET_SANS_TOP_25)) { + Collection categories = query.getSansTop25(); + aggregations.put(FACET_SANS_TOP_25, + stickyFacetBuilder.buildStickyFacet(FIELD_RULE_SANS_TOP_25, FACET_SANS_TOP_25, + (categories == null) ? (new String[0]) : categories.toArray())); + } + if (options.getFacets().contains(FACET_SONARSOURCE_SECURITY)) { + Collection categories = query.getSonarsourceSecurity(); + aggregations.put(FACET_SONARSOURCE_SECURITY, + stickyFacetBuilder.buildStickyFacet(FIELD_RULE_SONARSOURCE_SECURITY, FACET_SONARSOURCE_SECURITY, + (categories == null) ? (new String[0]) : categories.toArray())); + } } private static void addStatusFacetIfNeeded(SearchOptions options, Map aggregations, StickyFacetBuilder stickyFacetBuilder) { diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleIndexDefinition.java b/server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleIndexDefinition.java index 4d0226a0229..f1cf0f9ab59 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleIndexDefinition.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleIndexDefinition.java @@ -60,6 +60,10 @@ public class RuleIndexDefinition implements IndexDefinition { public static final String FIELD_RULE_TYPE = "type"; public static final String FIELD_RULE_CREATED_AT = "createdAt"; public static final String FIELD_RULE_UPDATED_AT = "updatedAt"; + public static final String FIELD_RULE_CWE = "cwe"; + public static final String FIELD_RULE_OWASP_TOP_10 = "owaspTop10"; + public static final String FIELD_RULE_SANS_TOP_25 = "sansTop25"; + public static final String FIELD_RULE_SONARSOURCE_SECURITY = "sonarsourceSecurity"; public static final Set SORT_FIELDS = ImmutableSet.of( FIELD_RULE_NAME, @@ -143,6 +147,11 @@ public class RuleIndexDefinition implements IndexDefinition { ruleMapping.createLongField(FIELD_RULE_CREATED_AT); ruleMapping.createLongField(FIELD_RULE_UPDATED_AT); + ruleMapping.keywordFieldBuilder(FIELD_RULE_CWE).disableNorms().build(); + ruleMapping.keywordFieldBuilder(FIELD_RULE_OWASP_TOP_10).disableNorms().build(); + ruleMapping.keywordFieldBuilder(FIELD_RULE_SANS_TOP_25).disableNorms().build(); + ruleMapping.keywordFieldBuilder(FIELD_RULE_SONARSOURCE_SECURITY).disableNorms().build(); + // Active rule index.createTypeMapping(TYPE_ACTIVE_RULE) .keywordFieldBuilder(FIELD_ACTIVE_RULE_ID).disableNorms().build() diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleQuery.java b/server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleQuery.java index 332fcb67f3d..ae29a147fdb 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleQuery.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleQuery.java @@ -55,6 +55,10 @@ public class RuleQuery { private String ruleKey; private OrganizationDto organization; private boolean includeExternal; + private Collection owaspTop10; + private Collection sansTop25; + private Collection cwe; + private Collection sonarsourceSecurity; @CheckForNull public QProfileDto getQProfile() { @@ -293,4 +297,44 @@ public class RuleQuery { this.compareToQProfile = compareToQProfile; return this; } + + @CheckForNull + public Collection getCwe() { + return cwe; + } + + public RuleQuery setCwe(@Nullable Collection cwe) { + this.cwe = cwe; + return this; + } + + @CheckForNull + public Collection getOwaspTop10() { + return owaspTop10; + } + + public RuleQuery setOwaspTop10(@Nullable Collection owaspTop10) { + this.owaspTop10 = owaspTop10; + return this; + } + + @CheckForNull + public Collection getSansTop25() { + return sansTop25; + } + + public RuleQuery setSansTop25(@Nullable Collection sansTop25) { + this.sansTop25 = sansTop25; + return this; + } + + @CheckForNull + public Collection getSonarsourceSecurity() { + return sonarsourceSecurity; + } + + public RuleQuery setSonarsourceSecurity(@Nullable Collection sonarsourceSecurity) { + this.sonarsourceSecurity = sonarsourceSecurity; + return this; + } } diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/SecurityStandardHelper.java b/server/sonar-server-common/src/main/java/org/sonar/server/security/SecurityStandardHelper.java similarity index 98% rename from server/sonar-server-common/src/main/java/org/sonar/server/issue/index/SecurityStandardHelper.java rename to server/sonar-server-common/src/main/java/org/sonar/server/security/SecurityStandardHelper.java index 8c445fb9a8e..d8ac726e0e7 100644 --- a/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/SecurityStandardHelper.java +++ b/server/sonar-server-common/src/main/java/org/sonar/server/security/SecurityStandardHelper.java @@ -17,7 +17,7 @@ * 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.index; +package org.sonar.server.security; import com.google.common.base.Splitter; import com.google.common.collect.ImmutableMap; @@ -47,7 +47,6 @@ public class SecurityStandardHelper { private static final Set RISKY_CWE = new HashSet<>(asList("120", "22", "494", "829", "676", "131", "134", "190")); private static final Set POROUS_CWE = new HashSet<>(asList("306", "862", "798", "311", "807", "250", "863", "732", "327", "307", "759")); - public static final Map> SONARSOURCE_CWE_MAPPING = ImmutableMap.>builder() .put("sql-injection", asList("89", "564")) .put("command-injection", asList("78", "77")) @@ -66,7 +65,7 @@ public class SecurityStandardHelper { .put("xxe", asList("611", "827")) .put("object-injection", singletonList("470")) .put("weak-cryptography", asList("326", "295", "326", "327", "297", "780", "328", "327")) - .put("auth", asList("798", "640", "620", "549", "522", "521", "263", "262", "261", "259", "522", "284")) + .put("auth", asList("798", "640", "620", "549", "522", "521", "263", "262", "261", "259", "284")) .put("insecure-conf", asList("102", "489")) .put("file-manipulation", asList("97", "73")) .build(); diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/issue/index/IssueIndexerTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/issue/index/IssueIndexerTest.java index 67264571c84..199237e9e40 100644 --- a/server/sonar-server-common/src/test/java/org/sonar/server/issue/index/IssueIndexerTest.java +++ b/server/sonar-server-common/src/test/java/org/sonar/server/issue/index/IssueIndexerTest.java @@ -57,8 +57,8 @@ import static org.junit.rules.ExpectedException.none; import static org.sonar.db.component.ComponentTesting.newFileDto; import static org.sonar.server.issue.IssueDocTesting.newDoc; import static org.sonar.server.issue.index.IssueIndexDefinition.TYPE_ISSUE; -import static org.sonar.server.issue.index.SecurityStandardHelper.SANS_TOP_25_POROUS_DEFENSES; -import static org.sonar.server.issue.index.SecurityStandardHelper.UNKNOWN_STANDARD; +import static org.sonar.server.security.SecurityStandardHelper.SANS_TOP_25_POROUS_DEFENSES; +import static org.sonar.server.security.SecurityStandardHelper.UNKNOWN_STANDARD; import static org.sonar.server.permission.index.IndexAuthorizationConstants.TYPE_AUTHORIZATION; public class IssueIndexerTest { diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/rule/index/RuleIndexTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/rule/index/RuleIndexTest.java index e365428c917..d11ab122cad 100644 --- a/server/sonar-server-common/src/test/java/org/sonar/server/rule/index/RuleIndexTest.java +++ b/server/sonar-server-common/src/test/java/org/sonar/server/rule/index/RuleIndexTest.java @@ -69,6 +69,7 @@ import static org.sonar.db.rule.RuleTesting.setName; import static org.sonar.db.rule.RuleTesting.setOrganization; import static org.sonar.db.rule.RuleTesting.setRepositoryKey; import static org.sonar.db.rule.RuleTesting.setRuleKey; +import static org.sonar.db.rule.RuleTesting.setSecurityStandards; import static org.sonar.db.rule.RuleTesting.setSeverity; import static org.sonar.db.rule.RuleTesting.setStatus; import static org.sonar.db.rule.RuleTesting.setSystemTags; @@ -85,6 +86,8 @@ import static org.sonar.server.rule.index.RuleIndex.FACET_TYPES; import static org.sonar.server.rule.index.RuleIndexDefinition.TYPE_ACTIVE_RULE; import static org.sonar.server.rule.index.RuleIndexDefinition.TYPE_RULE; import static org.sonar.server.rule.index.RuleIndexDefinition.TYPE_RULE_EXTENSION; +import static org.sonar.server.security.SecurityStandardHelper.SANS_TOP_25_INSECURE_INTERACTION; +import static org.sonar.server.security.SecurityStandardHelper.SANS_TOP_25_RISKY_RESOURCE; public class RuleIndexTest { @@ -122,7 +125,7 @@ public class RuleIndexTest { RuleDefinitionDto cobol1 = createRule( setRepositoryKey("cobol"), setRuleKey("X001")); - RuleDefinitionDto php2 = createRule( + createRule( setRepositoryKey("php"), setRuleKey("S002")); index(); @@ -451,6 +454,54 @@ public class RuleIndexTest { assertThat(underTest.search(query, new SearchOptions()).getIds()).hasSize(2); } + @Test + public void search_by_security_cwe() { + RuleDefinitionDto rule1 = createRule(setSecurityStandards(of("cwe:543", "cwe:123", "owaspTop10:a1"))); + RuleDefinitionDto rule2 = createRule(setSecurityStandards(of("cwe:543", "owaspTop10:a1"))); + createRule(setSecurityStandards(of("owaspTop10:a1"))); + index(); + + RuleQuery query = new RuleQuery().setCwe(of("543")); + SearchIdResult results = underTest.search(query, new SearchOptions().addFacets("cwe")); + assertThat(results.getIds()).containsOnly(rule1.getId(), rule2.getId()); + } + + @Test + public void search_by_security_owaspTop10() { + RuleDefinitionDto rule1 = createRule(setSecurityStandards(of("owaspTop10:a1", "owaspTop10:a10", "cwe:543"))); + RuleDefinitionDto rule2 = createRule(setSecurityStandards(of("owaspTop10:a10", "cwe:543"))); + createRule(setSecurityStandards(of("cwe:543"))); + index(); + + RuleQuery query = new RuleQuery().setOwaspTop10(of("a5", "a10")); + SearchIdResult results = underTest.search(query, new SearchOptions().addFacets("owaspTop10")); + assertThat(results.getIds()).containsOnly(rule1.getId(), rule2.getId()); + } + + @Test + public void search_by_security_sansTop25() { + RuleDefinitionDto rule1 = createRule(setSecurityStandards(of("owaspTop10:a1", "owaspTop10:a10", "cwe:89"))); + RuleDefinitionDto rule2 = createRule(setSecurityStandards(of("owaspTop10:a10", "cwe:829"))); + createRule(setSecurityStandards(of("cwe:306"))); + index(); + + RuleQuery query = new RuleQuery().setSansTop25(of(SANS_TOP_25_INSECURE_INTERACTION, SANS_TOP_25_RISKY_RESOURCE)); + SearchIdResult results = underTest.search(query, new SearchOptions().addFacets("sansTop25")); + assertThat(results.getIds()).containsOnly(rule1.getId(), rule2.getId()); + } + + @Test + public void search_by_security_sonarsource() { + RuleDefinitionDto rule1 = createRule(setSecurityStandards(of("owaspTop10:a1", "owaspTop10:a10", "cwe:89"))); + createRule(setSecurityStandards(of("owaspTop10:a10", "cwe:829"))); + RuleDefinitionDto rule3 = createRule(setSecurityStandards(of("cwe:601"))); + index(); + + RuleQuery query = new RuleQuery().setSonarsourceSecurity(of("sql-injection", "open-redirect")); + SearchIdResult results = underTest.search(query, new SearchOptions().addFacets("sonarsourceSecurity")); + assertThat(results.getIds()).containsOnly(rule1.getId(), rule3.getId()); + } + @Test public void compare_to_another_profile() { String xoo = "xoo"; @@ -842,7 +893,7 @@ public class RuleIndexTest { @Test public void languages_facet_should_return_top_100_items() { - rangeClosed(1, 101).forEach(i -> db.rules().insert(r -> r.setLanguage("lang" + i))); + rangeClosed(1, 101).forEach(i -> db.rules().insert(r -> r.setLanguage("lang" + i))); index(); SearchIdResult result = underTest.search(new RuleQuery(), new SearchOptions().addFacets(singletonList(FACET_LANGUAGES))); @@ -852,7 +903,7 @@ public class RuleIndexTest { @Test public void repositories_facet_should_return_top_10_items() { - rangeClosed(1, 11).forEach(i -> db.rules().insert(r -> r.setRepositoryKey("repo" + i))); + rangeClosed(1, 11).forEach(i -> db.rules().insert(r -> r.setRepositoryKey("repo" + i))); index(); SearchIdResult result = underTest.search(new RuleQuery(), new SearchOptions().addFacets(singletonList(FACET_REPOSITORIES))); 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 3e4d017d0d3..4babfa38c5a 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 @@ -82,6 +82,7 @@ import org.sonar.server.es.StickyFacetBuilder; import org.sonar.server.issue.index.IssueQuery.PeriodStart; import org.sonar.server.permission.index.AuthorizationDoc; import org.sonar.server.permission.index.WebAuthorizationTypeSupport; +import org.sonar.server.security.SecurityStandardHelper; import org.sonar.server.user.UserSession; import org.sonar.server.view.index.ViewIndexDefinition; @@ -151,10 +152,10 @@ import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_ISSUE_STAT import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_ISSUE_TAGS; import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_ISSUE_TYPE; import static org.sonar.server.issue.index.IssueIndexDefinition.TYPE_ISSUE; -import static org.sonar.server.issue.index.SecurityStandardHelper.SANS_TOP_25_INSECURE_INTERACTION; -import static org.sonar.server.issue.index.SecurityStandardHelper.SANS_TOP_25_POROUS_DEFENSES; -import static org.sonar.server.issue.index.SecurityStandardHelper.SANS_TOP_25_RISKY_RESOURCE; -import static org.sonar.server.issue.index.SecurityStandardHelper.UNKNOWN_STANDARD; +import static org.sonar.server.security.SecurityStandardHelper.SANS_TOP_25_INSECURE_INTERACTION; +import static org.sonar.server.security.SecurityStandardHelper.SANS_TOP_25_POROUS_DEFENSES; +import static org.sonar.server.security.SecurityStandardHelper.SANS_TOP_25_RISKY_RESOURCE; +import static org.sonar.server.security.SecurityStandardHelper.UNKNOWN_STANDARD; import static org.sonar.server.view.index.ViewIndexDefinition.TYPE_VIEW; import static org.sonarqube.ws.client.issue.IssuesWsParameters.DEPRECATED_PARAM_AUTHORS; import static org.sonarqube.ws.client.issue.IssuesWsParameters.FACET_MODE_EFFORT; diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAction.java b/server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAction.java index 326651d5944..1c15a9e1ea5 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAction.java @@ -76,11 +76,11 @@ import static org.sonar.server.issue.index.IssueIndex.FACET_ASSIGNED_TO_ME; import static org.sonar.server.issue.index.IssueIndex.FACET_PROJECTS; import static org.sonar.server.issue.index.IssueQuery.SORT_BY_ASSIGNEE; import static org.sonar.server.issue.index.IssueQueryFactory.UNKNOWN; -import static org.sonar.server.issue.index.SecurityStandardHelper.SANS_TOP_25_INSECURE_INTERACTION; -import static org.sonar.server.issue.index.SecurityStandardHelper.SANS_TOP_25_POROUS_DEFENSES; -import static org.sonar.server.issue.index.SecurityStandardHelper.SANS_TOP_25_RISKY_RESOURCE; -import static org.sonar.server.issue.index.SecurityStandardHelper.SONARSOURCE_CWE_MAPPING; -import static org.sonar.server.issue.index.SecurityStandardHelper.UNKNOWN_STANDARD; +import static org.sonar.server.security.SecurityStandardHelper.SANS_TOP_25_INSECURE_INTERACTION; +import static org.sonar.server.security.SecurityStandardHelper.SANS_TOP_25_POROUS_DEFENSES; +import static org.sonar.server.security.SecurityStandardHelper.SANS_TOP_25_RISKY_RESOURCE; +import static org.sonar.server.security.SecurityStandardHelper.SONARSOURCE_CWE_MAPPING; +import static org.sonar.server.security.SecurityStandardHelper.UNKNOWN_STANDARD; import static org.sonar.server.ws.KeyExamples.KEY_BRANCH_EXAMPLE_001; import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001; import static org.sonar.server.ws.KeyExamples.KEY_PULL_REQUEST_EXAMPLE_001; diff --git a/server/sonar-server/src/main/java/org/sonar/server/rule/ws/RuleQueryFactory.java b/server/sonar-server/src/main/java/org/sonar/server/rule/ws/RuleQueryFactory.java index f0a36f68990..35482f639be 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/rule/ws/RuleQueryFactory.java +++ b/server/sonar-server/src/main/java/org/sonar/server/rule/ws/RuleQueryFactory.java @@ -38,15 +38,19 @@ import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_ACTIVATION; import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_ACTIVE_SEVERITIES; import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_AVAILABLE_SINCE; import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_COMPARE_TO_PROFILE; +import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_CWE; import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_INCLUDE_EXTERNAL; import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_INHERITANCE; import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_IS_TEMPLATE; import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_LANGUAGES; import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_ORGANIZATION; +import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_OWASP_TOP_10; import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_QPROFILE; import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_REPOSITORIES; import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_RULE_KEY; +import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_SANS_TOP_25; import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_SEVERITIES; +import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_SONARSOURCE_SECURITY; import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_STATUSES; import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_TAGS; import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_TEMPLATE_KEY; @@ -105,6 +109,10 @@ public class RuleQueryFactory { query.setTemplateKey(request.param(PARAM_TEMPLATE_KEY)); query.setTypes(toEnums(request.paramAsStrings(PARAM_TYPES), RuleType.class)); query.setKey(request.param(PARAM_RULE_KEY)); + query.setCwe(request.paramAsStrings(PARAM_CWE)); + query.setOwaspTop10(request.paramAsStrings(PARAM_OWASP_TOP_10)); + query.setSansTop25(request.paramAsStrings(PARAM_SANS_TOP_25)); + query.setSonarsourceSecurity(request.paramAsStrings(PARAM_SONARSOURCE_SECURITY)); String sortParam = request.param(WebService.Param.SORT); if (sortParam != null) { diff --git a/server/sonar-server/src/main/java/org/sonar/server/rule/ws/RuleWsSupport.java b/server/sonar-server/src/main/java/org/sonar/server/rule/ws/RuleWsSupport.java index 3b2559b7d68..eb19feff8a5 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/rule/ws/RuleWsSupport.java +++ b/server/sonar-server/src/main/java/org/sonar/server/rule/ws/RuleWsSupport.java @@ -35,6 +35,7 @@ import org.sonar.db.DbSession; import org.sonar.db.organization.OrganizationDto; import org.sonar.db.rule.RuleDto; import org.sonar.db.user.UserDto; +import org.sonar.server.security.SecurityStandardHelper; import org.sonar.server.organization.DefaultOrganizationProvider; import org.sonar.server.qualityprofile.ActiveRuleInheritance; import org.sonar.server.rule.index.RuleIndexDefinition; @@ -49,19 +50,25 @@ import static org.sonar.core.util.stream.MoreCollectors.toSet; import static org.sonar.core.util.stream.MoreCollectors.uniqueIndex; import static org.sonar.db.organization.OrganizationDto.Subscription.PAID; import static org.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_PROFILES; +import static org.sonar.server.security.SecurityStandardHelper.SANS_TOP_25_CWE_MAPPING; +import static org.sonar.server.security.SecurityStandardHelper.UNKNOWN_STANDARD; import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_ACTIVATION; import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_ACTIVE_SEVERITIES; import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_AVAILABLE_SINCE; import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_COMPARE_TO_PROFILE; +import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_CWE; import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_INCLUDE_EXTERNAL; import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_INHERITANCE; import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_IS_TEMPLATE; import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_LANGUAGES; import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_ORGANIZATION; +import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_OWASP_TOP_10; import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_QPROFILE; import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_REPOSITORIES; import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_RULE_KEY; +import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_SANS_TOP_25; import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_SEVERITIES; +import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_SONARSOURCE_SECURITY; import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_STATUSES; import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_TAGS; import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_TEMPLATE_KEY; @@ -130,6 +137,28 @@ public class RuleWsSupport { .setPossibleValues(Severity.ALL) .setExampleValue("CRITICAL,BLOCKER"); + action + .createParam(PARAM_CWE) + .setDescription("Comma-separated list of CWE identifiers. Use '" + UNKNOWN_STANDARD + "' to select rules not associated to any CWE.") + .setExampleValue("12,125," + UNKNOWN_STANDARD); + + action.createParam(PARAM_OWASP_TOP_10) + .setDescription("Comma-separated list of OWASP Top 10 lowercase categories. Use '" + UNKNOWN_STANDARD + "' to select rules not associated to any OWASP " + + "Top 10 category.") + .setSince("7.3") + .setPossibleValues("a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "a10", UNKNOWN_STANDARD); + + action.createParam(PARAM_SANS_TOP_25) + .setDescription("Comma-separated list of SANS Top 25 categories.") + .setSince("7.3") + .setPossibleValues(SANS_TOP_25_CWE_MAPPING.keySet()); + + action + .createParam(PARAM_SONARSOURCE_SECURITY) + .setDescription("Comma-separated list of SonarSource report categories.") + .setPossibleValues(SecurityStandardHelper.SONARSOURCE_CWE_MAPPING.keySet()) + .setExampleValue("sql-injection,command-injection"); + action .createParam(PARAM_LANGUAGES) .setDescription("Comma-separated list of languages") @@ -231,5 +260,4 @@ public class RuleWsSupport { .setSince("7.2"); } - } diff --git a/server/sonar-server/src/main/java/org/sonar/server/rule/ws/RulesWsParameters.java b/server/sonar-server/src/main/java/org/sonar/server/rule/ws/RulesWsParameters.java index ec27029e35f..bf420fe8347 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/rule/ws/RulesWsParameters.java +++ b/server/sonar-server/src/main/java/org/sonar/server/rule/ws/RulesWsParameters.java @@ -33,6 +33,10 @@ public class RulesWsParameters { public static final String PARAM_LANGUAGES = "languages"; public static final String PARAM_TAGS = "tags"; public static final String PARAM_TYPES = "types"; + public static final String PARAM_CWE = "cwe"; + public static final String PARAM_OWASP_TOP_10 = "owaspTop10"; + public static final String PARAM_SANS_TOP_25 = "sansTop25"; + public static final String PARAM_SONARSOURCE_SECURITY = "sonarsourceSecurity"; public static final String PARAM_INHERITANCE = "inheritance"; public static final String PARAM_ACTIVE_SEVERITIES = "active_severities"; public static final String PARAM_IS_TEMPLATE = "is_template"; diff --git a/server/sonar-server/src/main/java/org/sonar/server/rule/ws/SearchAction.java b/server/sonar-server/src/main/java/org/sonar/server/rule/ws/SearchAction.java index 416b45795ed..6b13e86e350 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/rule/ws/SearchAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/rule/ws/SearchAction.java @@ -66,18 +66,26 @@ import static org.sonar.api.server.ws.WebService.Param.PAGE_SIZE; import static org.sonar.server.es.SearchOptions.MAX_LIMIT; import static org.sonar.server.rule.index.RuleIndex.ALL_STATUSES_EXCEPT_REMOVED; import static org.sonar.server.rule.index.RuleIndex.FACET_ACTIVE_SEVERITIES; +import static org.sonar.server.rule.index.RuleIndex.FACET_CWE; import static org.sonar.server.rule.index.RuleIndex.FACET_LANGUAGES; import static org.sonar.server.rule.index.RuleIndex.FACET_OLD_DEFAULT; +import static org.sonar.server.rule.index.RuleIndex.FACET_OWASP_TOP_10; import static org.sonar.server.rule.index.RuleIndex.FACET_REPOSITORIES; +import static org.sonar.server.rule.index.RuleIndex.FACET_SANS_TOP_25; import static org.sonar.server.rule.index.RuleIndex.FACET_SEVERITIES; +import static org.sonar.server.rule.index.RuleIndex.FACET_SONARSOURCE_SECURITY; import static org.sonar.server.rule.index.RuleIndex.FACET_STATUSES; import static org.sonar.server.rule.index.RuleIndex.FACET_TAGS; import static org.sonar.server.rule.index.RuleIndex.FACET_TYPES; import static org.sonar.server.rule.ws.RulesWsParameters.OPTIONAL_FIELDS; import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_ACTIVE_SEVERITIES; +import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_CWE; import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_LANGUAGES; +import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_OWASP_TOP_10; import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_REPOSITORIES; +import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_SANS_TOP_25; import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_SEVERITIES; +import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_SONARSOURCE_SECURITY; import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_STATUSES; import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_TAGS; import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_TYPES; @@ -95,7 +103,11 @@ public class SearchAction implements RulesWsAction { FACET_ACTIVE_SEVERITIES, FACET_STATUSES, FACET_TYPES, - FACET_OLD_DEFAULT}; + FACET_OLD_DEFAULT, + FACET_CWE, + FACET_OWASP_TOP_10, + FACET_SANS_TOP_25, + FACET_SONARSOURCE_SECURITY}; private final RuleQueryFactory ruleQueryFactory; private final DbClient dbClient; @@ -265,6 +277,10 @@ public class SearchAction implements RulesWsAction { addMandatoryFacetValues(results, FACET_ACTIVE_SEVERITIES, Severity.ALL); addMandatoryFacetValues(results, FACET_TAGS, request.getTags()); addMandatoryFacetValues(results, FACET_TYPES, RuleType.names()); + addMandatoryFacetValues(results, FACET_CWE, request.getCwe()); + addMandatoryFacetValues(results, FACET_OWASP_TOP_10, request.getOwaspTop10()); + addMandatoryFacetValues(results, FACET_SANS_TOP_25, request.getSansTop25()); + addMandatoryFacetValues(results, FACET_SONARSOURCE_SECURITY, request.getSonarsourceSecurity()); Common.Facet.Builder facet = Common.Facet.newBuilder(); Common.FacetValue.Builder value = Common.FacetValue.newBuilder(); @@ -276,6 +292,10 @@ public class SearchAction implements RulesWsAction { facetValuesByFacetKey.put(FACET_ACTIVE_SEVERITIES, request.getActiveSeverities()); facetValuesByFacetKey.put(FACET_TAGS, request.getTags()); facetValuesByFacetKey.put(FACET_TYPES, request.getTypes()); + facetValuesByFacetKey.put(FACET_CWE, request.getCwe()); + facetValuesByFacetKey.put(FACET_OWASP_TOP_10, request.getOwaspTop10()); + facetValuesByFacetKey.put(FACET_SANS_TOP_25, request.getSansTop25()); + facetValuesByFacetKey.put(FACET_SONARSOURCE_SECURITY, request.getSonarsourceSecurity()); for (String facetName : context.getFacets()) { facet.clear().setProperty(facetName); @@ -333,7 +353,11 @@ public class SearchAction implements RulesWsAction { .setSeverities(request.paramAsStrings(PARAM_SEVERITIES)) .setStatuses(request.paramAsStrings(PARAM_STATUSES)) .setTags(request.paramAsStrings(PARAM_TAGS)) - .setTypes(request.paramAsStrings(PARAM_TYPES)); + .setTypes(request.paramAsStrings(PARAM_TYPES)) + .setCwe(request.paramAsStrings(PARAM_CWE)) + .setOwaspTop10(request.paramAsStrings(PARAM_OWASP_TOP_10)) + .setSansTop25(request.paramAsStrings(PARAM_SANS_TOP_25)) + .setSonarsourceSecurity(request.paramAsStrings(PARAM_SONARSOURCE_SECURITY)); } static class SearchResult { @@ -416,6 +440,10 @@ public class SearchAction implements RulesWsAction { private List statuses; private List tags; private List types; + private List cwe; + private List owaspTop10; + private List sansTop25; + private List sonarsourceSecurity; private SearchRequest setActiveSeverities(List activeSeverities) { this.activeSeverities = activeSeverities; @@ -507,7 +535,7 @@ public class SearchAction implements RulesWsAction { return tags; } - private SearchRequest setTypes(List types) { + private SearchRequest setTypes(@Nullable List types) { this.types = types; return this; } @@ -515,5 +543,41 @@ public class SearchAction implements RulesWsAction { private List getTypes() { return types; } + + public List getCwe() { + return cwe; + } + + public SearchRequest setCwe(@Nullable List cwe) { + this.cwe = cwe; + return this; + } + + public List getOwaspTop10() { + return owaspTop10; + } + + public SearchRequest setOwaspTop10(@Nullable List owaspTop10) { + this.owaspTop10 = owaspTop10; + return this; + } + + public List getSansTop25() { + return sansTop25; + } + + public SearchRequest setSansTop25(@Nullable List sansTop25) { + this.sansTop25 = sansTop25; + return this; + } + + public List getSonarsourceSecurity() { + return sonarsourceSecurity; + } + + public SearchRequest setSonarsourceSecurity(@Nullable List sonarsourceSecurity) { + this.sonarsourceSecurity = sonarsourceSecurity; + return this; + } } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/securityreport/ws/ShowAction.java b/server/sonar-server/src/main/java/org/sonar/server/securityreport/ws/ShowAction.java index 143da15a107..344a8d4d170 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/securityreport/ws/ShowAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/securityreport/ws/ShowAction.java @@ -38,7 +38,7 @@ import org.sonar.db.rule.RuleDto; import org.sonar.server.component.ComponentFinder; import org.sonar.server.issue.index.IssueIndex; import org.sonar.server.issue.index.SecurityStandardCategoryStatistics; -import org.sonar.server.issue.index.SecurityStandardHelper; +import org.sonar.server.security.SecurityStandardHelper; import org.sonar.server.qualityprofile.QPMeasureData; import org.sonar.server.qualityprofile.QualityProfile; import org.sonar.server.user.UserSession; @@ -51,11 +51,11 @@ import static java.util.Comparator.comparing; import static java.util.stream.Collectors.toList; import static org.sonar.api.measures.CoreMetrics.QUALITY_PROFILES_KEY; import static org.sonar.api.web.UserRole.USER; -import static org.sonar.server.issue.index.SecurityStandardHelper.UNKNOWN_STANDARD; -import static org.sonar.server.issue.index.SecurityStandardHelper.getCwe; -import static org.sonar.server.issue.index.SecurityStandardHelper.getOwaspTop10; -import static org.sonar.server.issue.index.SecurityStandardHelper.getSansTop25; -import static org.sonar.server.issue.index.SecurityStandardHelper.getSonarSourceSecurityCategories; +import static org.sonar.server.security.SecurityStandardHelper.UNKNOWN_STANDARD; +import static org.sonar.server.security.SecurityStandardHelper.getCwe; +import static org.sonar.server.security.SecurityStandardHelper.getOwaspTop10; +import static org.sonar.server.security.SecurityStandardHelper.getSansTop25; +import static org.sonar.server.security.SecurityStandardHelper.getSonarSourceSecurityCategories; import static org.sonar.server.ws.WsUtils.writeProtobuf; import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_OWASP_TOP_10; import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_SANS_TOP_25; 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 c1d70e74edf..bc00cddd508 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 @@ -54,10 +54,10 @@ import static org.sonar.api.resources.Qualifiers.PROJECT; import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto; import static org.sonar.db.organization.OrganizationTesting.newOrganizationDto; import static org.sonar.server.issue.IssueDocTesting.newDoc; -import static org.sonar.server.issue.index.SecurityStandardHelper.SANS_TOP_25_INSECURE_INTERACTION; -import static org.sonar.server.issue.index.SecurityStandardHelper.SANS_TOP_25_POROUS_DEFENSES; -import static org.sonar.server.issue.index.SecurityStandardHelper.SANS_TOP_25_RISKY_RESOURCE; -import static org.sonar.server.issue.index.SecurityStandardHelper.UNKNOWN_STANDARD; +import static org.sonar.server.security.SecurityStandardHelper.SANS_TOP_25_INSECURE_INTERACTION; +import static org.sonar.server.security.SecurityStandardHelper.SANS_TOP_25_POROUS_DEFENSES; +import static org.sonar.server.security.SecurityStandardHelper.SANS_TOP_25_RISKY_RESOURCE; +import static org.sonar.server.security.SecurityStandardHelper.UNKNOWN_STANDARD; public class IssueIndexSecurityReportsTest { diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ActivateRulesActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ActivateRulesActionTest.java index 3619411c221..38e1f83d456 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ActivateRulesActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ActivateRulesActionTest.java @@ -102,7 +102,11 @@ public class ActivateRulesActionTest { "available_since", "activation", "severities", - "organization"); + "organization", + "cwe", + "owaspTop10", + "sansTop25", + "sonarsourceSecurity"); WebService.Param targetProfile = definition.param("targetKey"); assertThat(targetProfile.deprecatedKey()).isEqualTo("profile_key"); WebService.Param targetSeverity = definition.param("targetSeverity"); diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/DeactivateRulesActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/DeactivateRulesActionTest.java index ae9c55e0ad6..4f0311aff96 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/DeactivateRulesActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/DeactivateRulesActionTest.java @@ -100,7 +100,11 @@ public class DeactivateRulesActionTest { "available_since", "activation", "severities", - "organization"); + "organization", + "cwe", + "owaspTop10", + "sansTop25", + "sonarsourceSecurity"); WebService.Param targetProfile = definition.param("targetKey"); assertThat(targetProfile.deprecatedKey()).isEqualTo("profile_key"); } diff --git a/server/sonar-server/src/test/java/org/sonar/server/rule/ws/SearchActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/rule/ws/SearchActionTest.java index 8e1e23dc435..e1272f7aa5e 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/rule/ws/SearchActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/rule/ws/SearchActionTest.java @@ -136,7 +136,7 @@ public class SearchActionTest { assertThat(def.since()).isEqualTo("4.4"); assertThat(def.isInternal()).isFalse(); assertThat(def.responseExampleAsString()).isNotEmpty(); - assertThat(def.params()).hasSize(24); + assertThat(def.params()).hasSize(28); WebService.Param compareToProfile = def.param("compareToProfile"); assertThat(compareToProfile.since()).isEqualTo("6.5"); -- 2.39.5