@@ -167,6 +167,16 @@ public class RuleDoc extends BaseDoc { | |||
return this; | |||
} | |||
@CheckForNull | |||
public Collection<String> getOwaspTop10For2021() { | |||
return getNullableField(RuleIndexDefinition.FIELD_RULE_OWASP_TOP_10_2021); | |||
} | |||
public RuleDoc setOwaspTop10For2021(@Nullable Collection<String> o) { | |||
setField(RuleIndexDefinition.FIELD_RULE_OWASP_TOP_10_2021, o); | |||
return this; | |||
} | |||
@CheckForNull | |||
public Collection<String> getSansTop25() { | |||
return getNullableField(RuleIndexDefinition.FIELD_RULE_SANS_TOP_25); | |||
@@ -290,6 +300,7 @@ public class RuleDoc extends BaseDoc { | |||
.setLanguage(dto.getLanguage()) | |||
.setCwe(securityStandards.getCwe()) | |||
.setOwaspTop10(securityStandards.getOwaspTop10()) | |||
.setOwaspTop10For2021(securityStandards.getOwaspTop10For2021()) | |||
.setSansTop25(securityStandards.getSansTop25()) | |||
.setSonarSourceSecurityCategory(securityStandards.getSqCategory()) | |||
.setName(dto.getName()) |
@@ -98,6 +98,7 @@ 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_OWASP_TOP_10_2021; | |||
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; | |||
@@ -128,6 +129,7 @@ public class RuleIndex { | |||
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_OWASP_TOP_10_2021 = "owaspTop10-2021"; | |||
public static final String FACET_SONARSOURCE_SECURITY = "sonarsourceSecurity"; | |||
private static final int MAX_FACET_SIZE = 100; | |||
@@ -215,13 +217,13 @@ public class RuleIndex { | |||
BoolQueryBuilder textQuery = boolQuery(); | |||
JavaTokenizer.split(queryText) | |||
.stream().map(token -> boolQuery().should( | |||
matchQuery( | |||
SEARCH_GRAMS_ANALYZER.subField(FIELD_RULE_NAME), | |||
StringUtils.left(token, DefaultIndexSettings.MAXIMUM_NGRAM_LENGTH)).boost(20F)) | |||
.should( | |||
matchPhraseQuery( | |||
ENGLISH_HTML_ANALYZER.subField(FIELD_RULE_HTML_DESCRIPTION), | |||
token).boost(3F))) | |||
matchQuery( | |||
SEARCH_GRAMS_ANALYZER.subField(FIELD_RULE_NAME), | |||
StringUtils.left(token, DefaultIndexSettings.MAXIMUM_NGRAM_LENGTH)).boost(20F)) | |||
.should( | |||
matchPhraseQuery( | |||
ENGLISH_HTML_ANALYZER.subField(FIELD_RULE_HTML_DESCRIPTION), | |||
token).boost(3F))) | |||
.forEach(textQuery::must); | |||
qb.should(textQuery.boost(20F)); | |||
@@ -235,7 +237,7 @@ public class RuleIndex { | |||
private static QueryBuilder termQuery(String field, String query, float boost) { | |||
return QueryBuilders.multiMatchQuery(query, | |||
field, SEARCH_WORDS_ANALYZER.subField(field)) | |||
field, SEARCH_WORDS_ANALYZER.subField(field)) | |||
.operator(Operator.AND) | |||
.boost(boost); | |||
} | |||
@@ -255,63 +257,27 @@ public class RuleIndex { | |||
QueryBuilders.termQuery(FIELD_RULE_STATUS, | |||
RuleStatus.REMOVED.toString()))); | |||
if (StringUtils.isNotEmpty(query.getInternalKey())) { | |||
filters.put(FIELD_RULE_INTERNAL_KEY, | |||
QueryBuilders.termQuery(FIELD_RULE_INTERNAL_KEY, query.getInternalKey())); | |||
} | |||
addFilter(filters, FIELD_RULE_INTERNAL_KEY, query.getInternalKey()); | |||
if (StringUtils.isNotEmpty(query.getRuleKey())) { | |||
filters.put(FIELD_RULE_RULE_KEY, | |||
QueryBuilders.termQuery(FIELD_RULE_RULE_KEY, query.getRuleKey())); | |||
} | |||
addFilter(filters, FIELD_RULE_RULE_KEY, query.getRuleKey()); | |||
if (isNotEmpty(query.getLanguages())) { | |||
filters.put(FIELD_RULE_LANGUAGE, | |||
QueryBuilders.termsQuery(FIELD_RULE_LANGUAGE, query.getLanguages())); | |||
} | |||
addFilter(filters, query.getLanguages(), FIELD_RULE_LANGUAGE); | |||
if (isNotEmpty(query.getRepositories())) { | |||
filters.put(FIELD_RULE_REPOSITORY, | |||
QueryBuilders.termsQuery(FIELD_RULE_REPOSITORY, query.getRepositories())); | |||
} | |||
addFilter(filters, query.getRepositories(), FIELD_RULE_REPOSITORY); | |||
if (isNotEmpty(query.getSeverities())) { | |||
filters.put(FIELD_RULE_SEVERITY, | |||
QueryBuilders.termsQuery(FIELD_RULE_SEVERITY, query.getSeverities())); | |||
} | |||
addFilter(filters, query.getSeverities(), FIELD_RULE_SEVERITY); | |||
if (isNotEmpty(query.getCwe())) { | |||
filters.put(FIELD_RULE_CWE, | |||
boolQuery() | |||
.must(QueryBuilders.termsQuery(FIELD_RULE_CWE, query.getCwe())) | |||
.must(QueryBuilders.termsQuery(FIELD_RULE_TYPE, VULNERABILITY.name(), SECURITY_HOTSPOT.name()))); | |||
} | |||
addSecurityStandardFilter(filters, FIELD_RULE_CWE, query.getCwe()); | |||
if (isNotEmpty(query.getOwaspTop10())) { | |||
filters.put(FIELD_RULE_OWASP_TOP_10, | |||
boolQuery() | |||
.must(QueryBuilders.termsQuery(FIELD_RULE_OWASP_TOP_10, query.getOwaspTop10())) | |||
.must(QueryBuilders.termsQuery(FIELD_RULE_TYPE, VULNERABILITY.name(), SECURITY_HOTSPOT.name()))); | |||
} | |||
addSecurityStandardFilter(filters, FIELD_RULE_OWASP_TOP_10, query.getOwaspTop10()); | |||
if (isNotEmpty(query.getSansTop25())) { | |||
filters.put(FIELD_RULE_SANS_TOP_25, | |||
boolQuery() | |||
.must(QueryBuilders.termsQuery(FIELD_RULE_SANS_TOP_25, query.getSansTop25())) | |||
.must(QueryBuilders.termsQuery(FIELD_RULE_TYPE, VULNERABILITY.name(), SECURITY_HOTSPOT.name()))); | |||
} | |||
addSecurityStandardFilter(filters, FIELD_RULE_OWASP_TOP_10_2021, query.getOwaspTop10For2021()); | |||
if (isNotEmpty(query.getSonarsourceSecurity())) { | |||
filters.put(FIELD_RULE_SONARSOURCE_SECURITY, | |||
boolQuery() | |||
.must(QueryBuilders.termsQuery(FIELD_RULE_SONARSOURCE_SECURITY, query.getSonarsourceSecurity())) | |||
.must(QueryBuilders.termsQuery(FIELD_RULE_TYPE, VULNERABILITY.name(), SECURITY_HOTSPOT.name()))); | |||
} | |||
addSecurityStandardFilter(filters, FIELD_RULE_SANS_TOP_25, query.getSansTop25()); | |||
if (StringUtils.isNotEmpty(query.getKey())) { | |||
filters.put(FIELD_RULE_KEY, | |||
QueryBuilders.termQuery(FIELD_RULE_KEY, query.getKey())); | |||
} | |||
addSecurityStandardFilter(filters, FIELD_RULE_SONARSOURCE_SECURITY, query.getSonarsourceSecurity()); | |||
addFilter(filters, FIELD_RULE_KEY, query.getKey()); | |||
if (isNotEmpty(query.getTags())) { | |||
filters.put(FIELD_RULE_TAGS, buildTagsFilter(query.getTags())); | |||
@@ -384,6 +350,29 @@ public class RuleIndex { | |||
return filters; | |||
} | |||
private static void addSecurityStandardFilter(Map<String, QueryBuilder> filters, String key, Collection<String> values) { | |||
if (isNotEmpty(values)) { | |||
filters.put(key, | |||
boolQuery() | |||
.must(QueryBuilders.termsQuery(key, values)) | |||
.must(QueryBuilders.termsQuery(FIELD_RULE_TYPE, VULNERABILITY.name(), SECURITY_HOTSPOT.name()))); | |||
} | |||
} | |||
private static void addFilter(Map<String, QueryBuilder> filters, Collection<String> key, String value) { | |||
if (isNotEmpty(key)) { | |||
filters.put(value, | |||
QueryBuilders.termsQuery(value, key)); | |||
} | |||
} | |||
private static void addFilter(Map<String, QueryBuilder> filters, String key, String value) { | |||
if (StringUtils.isNotEmpty(value)) { | |||
filters.put(key, | |||
QueryBuilders.termQuery(key, value)); | |||
} | |||
} | |||
private static BoolQueryBuilder buildTagsFilter(Collection<String> tags) { | |||
BoolQueryBuilder q = boolQuery(); | |||
for (String tag : tags) { | |||
@@ -476,10 +465,10 @@ public class RuleIndex { | |||
private static Function<TermsAggregationBuilder, AggregationBuilder> filterSecurityCategories() { | |||
return termsAggregation -> AggregationBuilders.filter( | |||
"filter_by_rule_types_" + termsAggregation.getName(), | |||
termsQuery(FIELD_RULE_TYPE, | |||
VULNERABILITY.name(), | |||
SECURITY_HOTSPOT.name())) | |||
"filter_by_rule_types_" + termsAggregation.getName(), | |||
termsQuery(FIELD_RULE_TYPE, | |||
VULNERABILITY.name(), | |||
SECURITY_HOTSPOT.name())) | |||
.subAggregation(termsAggregation); | |||
} | |||
@@ -499,6 +488,13 @@ public class RuleIndex { | |||
FACET_DEFAULT_SIZE, filterSecurityCategories(), | |||
(categories == null) ? (new String[0]) : categories.toArray())); | |||
} | |||
if (options.getFacets().contains(FACET_OWASP_TOP_10_2021)) { | |||
Collection<String> categories = query.getOwaspTop10For2021(); | |||
aggregations.put(FACET_OWASP_TOP_10_2021, | |||
stickyFacetBuilder.buildStickyFacet(FIELD_RULE_OWASP_TOP_10_2021, FACET_OWASP_TOP_10_2021, | |||
FACET_DEFAULT_SIZE, filterSecurityCategories(), | |||
(categories == null) ? (new String[0]) : categories.toArray())); | |||
} | |||
if (options.getFacets().contains(FACET_SANS_TOP_25)) { | |||
Collection<String> categories = query.getSansTop25(); | |||
aggregations.put(FACET_SANS_TOP_25, |
@@ -21,6 +21,7 @@ package org.sonar.server.rule.index; | |||
import com.google.common.collect.ImmutableSet; | |||
import java.util.Set; | |||
import javax.inject.Inject; | |||
import org.sonar.api.config.Configuration; | |||
import org.sonar.api.config.internal.MapSettings; | |||
import org.sonar.server.es.Index; | |||
@@ -37,8 +38,6 @@ import static org.sonar.server.es.newindex.DefaultIndexSettingsElement.SORTABLE_ | |||
import static org.sonar.server.es.newindex.SettingsConfiguration.MANUAL_REFRESH_INTERVAL; | |||
import static org.sonar.server.es.newindex.SettingsConfiguration.newBuilder; | |||
import javax.inject.Inject; | |||
/** | |||
* Definition of ES index "rules", including settings and fields. | |||
*/ | |||
@@ -64,6 +63,7 @@ public class RuleIndexDefinition implements IndexDefinition { | |||
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_OWASP_TOP_10_2021 = "owaspTop10-2021"; | |||
public static final String FIELD_RULE_SANS_TOP_25 = "sansTop25"; | |||
public static final String FIELD_RULE_SONARSOURCE_SECURITY = "sonarsourceSecurity"; | |||
public static final String FIELD_RULE_TAGS = "tags"; | |||
@@ -146,6 +146,7 @@ public class RuleIndexDefinition implements IndexDefinition { | |||
ruleMapping.keywordFieldBuilder(FIELD_RULE_CWE).disableNorms().build(); | |||
ruleMapping.keywordFieldBuilder(FIELD_RULE_OWASP_TOP_10).disableNorms().build(); | |||
ruleMapping.keywordFieldBuilder(FIELD_RULE_OWASP_TOP_10_2021).disableNorms().build(); | |||
ruleMapping.keywordFieldBuilder(FIELD_RULE_SANS_TOP_25).disableNorms().build(); | |||
ruleMapping.keywordFieldBuilder(FIELD_RULE_SONARSOURCE_SECURITY).disableNorms().build(); | |||
@@ -54,6 +54,7 @@ public class RuleQuery { | |||
private String ruleKey; | |||
private boolean includeExternal; | |||
private Collection<String> owaspTop10; | |||
private Collection<String> owaspTop10For2021; | |||
private Collection<String> sansTop25; | |||
private Collection<String> cwe; | |||
private Collection<String> sonarsourceSecurity; | |||
@@ -307,6 +308,16 @@ public class RuleQuery { | |||
return this; | |||
} | |||
@CheckForNull | |||
public Collection<String> getOwaspTop10For2021() { | |||
return owaspTop10For2021; | |||
} | |||
public RuleQuery setOwaspTop10For2021(@Nullable Collection<String> owaspTop10For2021) { | |||
this.owaspTop10For2021 = owaspTop10For2021; | |||
return this; | |||
} | |||
@CheckForNull | |||
public Collection<String> getSansTop25() { | |||
return sansTop25; |
@@ -458,7 +458,7 @@ public class RuleIndexTest { | |||
} | |||
@Test | |||
public void search_by_security_owaspTop10_return_vulnerabilities_and_hotspots_only() { | |||
public void search_by_security_owaspTop10_2017_return_vulnerabilities_and_hotspots_only() { | |||
RuleDefinitionDto rule1 = createRule(setSecurityStandards(of("owaspTop10:a1", "owaspTop10:a10", "cwe:543")), r -> r.setType(VULNERABILITY)); | |||
RuleDefinitionDto rule2 = createRule(setSecurityStandards(of("owaspTop10:a10", "cwe:543")), r -> r.setType(SECURITY_HOTSPOT)); | |||
createRule(setSecurityStandards(of("cwe:543")), r -> r.setType(CODE_SMELL)); | |||
@@ -469,6 +469,18 @@ public class RuleIndexTest { | |||
assertThat(results.getUuids()).containsOnly(rule1.getUuid(), rule2.getUuid()); | |||
} | |||
@Test | |||
public void search_by_security_owaspTop10_2021_return_vulnerabilities_and_hotspots_only() { | |||
RuleDefinitionDto rule1 = createRule(setSecurityStandards(of("owaspTop10-2021:a1", "owaspTop10-2021:a10", "cwe:543")), r -> r.setType(VULNERABILITY)); | |||
RuleDefinitionDto rule2 = createRule(setSecurityStandards(of("owaspTop10-2021:a10", "cwe:543")), r -> r.setType(SECURITY_HOTSPOT)); | |||
createRule(setSecurityStandards(of("cwe:543")), r -> r.setType(CODE_SMELL)); | |||
index(); | |||
RuleQuery query = new RuleQuery().setOwaspTop10For2021(of("a5", "a10")); | |||
SearchIdResult<String> results = underTest.search(query, new SearchOptions().addFacets("owaspTop10-2021")); | |||
assertThat(results.getUuids()).containsOnly(rule1.getUuid(), rule2.getUuid()); | |||
} | |||
@Test | |||
public void search_by_security_sansTop25_return_vulnerabilities_and_hotspots_only() { | |||
RuleDefinitionDto rule1 = createRule(setSecurityStandards(of("owaspTop10:a1", "owaspTop10:a10", "cwe:89")), r -> r.setType(VULNERABILITY)); | |||
@@ -483,7 +495,7 @@ public class RuleIndexTest { | |||
@Test | |||
public void search_by_security_sonarsource_return_vulnerabilities_and_hotspots_only() { | |||
RuleDefinitionDto rule1 = createRule(setSecurityStandards(of("owaspTop10:a1", "owaspTop10:a10", "cwe:89")), r -> r.setType(VULNERABILITY)); | |||
RuleDefinitionDto rule1 = createRule(setSecurityStandards(of("owaspTop10:a1", "owaspTop10-2021:a10", "cwe:89")), r -> r.setType(VULNERABILITY)); | |||
createRule(setSecurityStandards(of("owaspTop10:a10", "cwe:829")), r -> r.setType(CODE_SMELL)); | |||
RuleDefinitionDto rule3 = createRule(setSecurityStandards(of("cwe:601")), r -> r.setType(SECURITY_HOTSPOT)); | |||
index(); |
@@ -43,6 +43,7 @@ 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_OWASP_TOP_10; | |||
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_OWASP_TOP_10_2021; | |||
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; | |||
@@ -100,6 +101,7 @@ public class RuleQueryFactory { | |||
query.setKey(request.param(PARAM_RULE_KEY)); | |||
query.setCwe(request.paramAsStrings(PARAM_CWE)); | |||
query.setOwaspTop10(request.paramAsStrings(PARAM_OWASP_TOP_10)); | |||
query.setOwaspTop10For2021(request.paramAsStrings(PARAM_OWASP_TOP_10_2021)); | |||
query.setSansTop25(request.paramAsStrings(PARAM_SANS_TOP_25)); | |||
query.setSonarsourceSecurity(request.paramAsStrings(PARAM_SONARSOURCE_SECURITY)); | |||
@@ -58,6 +58,7 @@ 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_OWASP_TOP_10; | |||
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_OWASP_TOP_10_2021; | |||
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; | |||
@@ -120,10 +121,15 @@ public class RuleWsSupport { | |||
.setExampleValue("12,125," + SecurityStandards.UNKNOWN_STANDARD); | |||
action.createParam(PARAM_OWASP_TOP_10) | |||
.setDescription("Comma-separated list of OWASP Top 10 lowercase categories.") | |||
.setDescription("Comma-separated list of OWASP Top 10 2017 lowercase categories.") | |||
.setSince("7.3") | |||
.setPossibleValues("a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "a10"); | |||
action.createParam(PARAM_OWASP_TOP_10_2021) | |||
.setDescription("Comma-separated list of OWASP Top 10 2021 lowercase categories.") | |||
.setSince("9.4") | |||
.setPossibleValues("a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "a10"); | |||
action.createParam(PARAM_SANS_TOP_25) | |||
.setDescription("Comma-separated list of SANS Top 25 categories.") | |||
.setSince("7.3") |
@@ -35,6 +35,7 @@ public class RulesWsParameters { | |||
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_OWASP_TOP_10_2021 = "owaspTop10-2021"; | |||
public static final String PARAM_SANS_TOP_25 = "sansTop25"; | |||
public static final String PARAM_SONARSOURCE_SECURITY = "sonarsourceSecurity"; | |||
public static final String PARAM_INHERITANCE = "inheritance"; |
@@ -73,6 +73,7 @@ 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_OWASP_TOP_10_2021; | |||
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; | |||
@@ -86,6 +87,7 @@ 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_OWASP_TOP_10_2021; | |||
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; | |||
@@ -99,7 +101,7 @@ public class SearchAction implements RulesWsAction { | |||
public static final String ACTION = "search"; | |||
private static final Collection<String> DEFAULT_FACETS = ImmutableSet.of(PARAM_LANGUAGES, PARAM_REPOSITORIES, "tags"); | |||
private static final String[] POSSIBLE_FACETS = new String[] { | |||
private static final String[] POSSIBLE_FACETS = new String[]{ | |||
FACET_LANGUAGES, | |||
FACET_REPOSITORIES, | |||
FACET_TAGS, | |||
@@ -110,6 +112,7 @@ public class SearchAction implements RulesWsAction { | |||
FACET_OLD_DEFAULT, | |||
FACET_CWE, | |||
FACET_OWASP_TOP_10, | |||
FACET_OWASP_TOP_10_2021, | |||
FACET_SANS_TOP_25, | |||
FACET_SONARSOURCE_SECURITY}; | |||
@@ -160,15 +163,15 @@ public class SearchAction implements RulesWsAction { | |||
Iterator<String> it = OPTIONAL_FIELDS.iterator(); | |||
paramFields.setExampleValue(format("%s,%s", it.next(), it.next())); | |||
action.setDescription("Search for a collection of relevant rules matching a specified query.<br/>" + | |||
"Since 5.5, following fields in the response have been deprecated :" + | |||
"<ul>" + | |||
"<li>\"effortToFixDescription\" becomes \"gapDescription\"</li>" + | |||
"<li>\"debtRemFnCoeff\" becomes \"remFnGapMultiplier\"</li>" + | |||
"<li>\"defaultDebtRemFnCoeff\" becomes \"defaultRemFnGapMultiplier\"</li>" + | |||
"<li>\"debtRemFnOffset\" becomes \"remFnBaseEffort\"</li>" + | |||
"<li>\"defaultDebtRemFnOffset\" becomes \"defaultRemFnBaseEffort\"</li>" + | |||
"<li>\"debtOverloaded\" becomes \"remFnOverloaded\"</li>" + | |||
"</ul>") | |||
"Since 5.5, following fields in the response have been deprecated :" + | |||
"<ul>" + | |||
"<li>\"effortToFixDescription\" becomes \"gapDescription\"</li>" + | |||
"<li>\"debtRemFnCoeff\" becomes \"remFnGapMultiplier\"</li>" + | |||
"<li>\"defaultDebtRemFnCoeff\" becomes \"defaultRemFnGapMultiplier\"</li>" + | |||
"<li>\"debtRemFnOffset\" becomes \"remFnBaseEffort\"</li>" + | |||
"<li>\"defaultDebtRemFnOffset\" becomes \"defaultRemFnBaseEffort\"</li>" + | |||
"<li>\"debtOverloaded\" becomes \"remFnOverloaded\"</li>" + | |||
"</ul>") | |||
.setResponseExample(getClass().getResource("search-example.json")) | |||
.setSince("4.4") | |||
.setHandler(this); | |||
@@ -301,6 +304,7 @@ public class SearchAction implements RulesWsAction { | |||
addMandatoryFacetValues(results, FACET_TYPES, RuleType.names()); | |||
addMandatoryFacetValues(results, FACET_CWE, request.getCwe()); | |||
addMandatoryFacetValues(results, FACET_OWASP_TOP_10, request.getOwaspTop10()); | |||
addMandatoryFacetValues(results, FACET_OWASP_TOP_10_2021, request.getOwaspTop10For2021()); | |||
addMandatoryFacetValues(results, FACET_SANS_TOP_25, request.getSansTop25()); | |||
addMandatoryFacetValues(results, FACET_SONARSOURCE_SECURITY, request.getSonarsourceSecurity()); | |||
@@ -316,6 +320,7 @@ public class SearchAction implements RulesWsAction { | |||
facetValuesByFacetKey.put(FACET_TYPES, request.getTypes()); | |||
facetValuesByFacetKey.put(FACET_CWE, request.getCwe()); | |||
facetValuesByFacetKey.put(FACET_OWASP_TOP_10, request.getOwaspTop10()); | |||
facetValuesByFacetKey.put(FACET_OWASP_TOP_10_2021, request.getOwaspTop10For2021()); | |||
facetValuesByFacetKey.put(FACET_SANS_TOP_25, request.getSansTop25()); | |||
facetValuesByFacetKey.put(FACET_SONARSOURCE_SECURITY, request.getSonarsourceSecurity()); | |||
@@ -378,6 +383,7 @@ public class SearchAction implements RulesWsAction { | |||
.setTypes(request.paramAsStrings(PARAM_TYPES)) | |||
.setCwe(request.paramAsStrings(PARAM_CWE)) | |||
.setOwaspTop10(request.paramAsStrings(PARAM_OWASP_TOP_10)) | |||
.setOwaspTop10For2021(request.paramAsStrings(PARAM_OWASP_TOP_10_2021)) | |||
.setSansTop25(request.paramAsStrings(PARAM_SANS_TOP_25)) | |||
.setSonarsourceSecurity(request.paramAsStrings(PARAM_SONARSOURCE_SECURITY)); | |||
} | |||
@@ -464,6 +470,7 @@ public class SearchAction implements RulesWsAction { | |||
private List<String> types; | |||
private List<String> cwe; | |||
private List<String> owaspTop10; | |||
private List<String> owaspTop10For2021; | |||
private List<String> sansTop25; | |||
private List<String> sonarsourceSecurity; | |||
@@ -584,6 +591,15 @@ public class SearchAction implements RulesWsAction { | |||
return this; | |||
} | |||
public List<String> getOwaspTop10For2021() { | |||
return owaspTop10For2021; | |||
} | |||
public SearchRequest setOwaspTop10For2021(@Nullable List<String> owaspTop10For2021) { | |||
this.owaspTop10For2021 = owaspTop10For2021; | |||
return this; | |||
} | |||
public List<String> getSansTop25() { | |||
return sansTop25; | |||
} |
@@ -89,6 +89,7 @@ public class ActivateRulesActionTest { | |||
"severities", | |||
"cwe", | |||
"owaspTop10", | |||
"owaspTop10-2021", | |||
"sansTop25", | |||
"sonarsourceSecurity"); | |||
} |
@@ -89,6 +89,7 @@ public class DeactivateRulesActionTest { | |||
"severities", | |||
"cwe", | |||
"owaspTop10", | |||
"owaspTop10-2021", | |||
"sansTop25", | |||
"sonarsourceSecurity"); | |||
} |
@@ -129,7 +129,7 @@ public class SearchActionTest { | |||
assertThat(def.since()).isEqualTo("4.4"); | |||
assertThat(def.isInternal()).isFalse(); | |||
assertThat(def.responseExampleAsString()).isNotEmpty(); | |||
assertThat(def.params()).hasSize(27); | |||
assertThat(def.params()).hasSize(28); | |||
WebService.Param compareToProfile = def.param("compareToProfile"); | |||
assertThat(compareToProfile.since()).isEqualTo("6.5"); |