public class StickyFacetBuilder {
private static final int FACET_DEFAULT_MIN_DOC_COUNT = 1;
- private static final int FACET_DEFAULT_SIZE = 10;
+ public static final int FACET_DEFAULT_SIZE = 10;
private static final BucketOrder FACET_DEFAULT_ORDER = BucketOrder.count(false);
/** In some cases the user selects >15 items for one facet. In that case, we want to calculate the doc count for all of them (not just the first 15 items, which would be the
* default for the TermsAggregation). */
}
public AggregationBuilder buildStickyFacet(String fieldName, String facetName, Object... selected) {
- return buildStickyFacet(fieldName, facetName, FACET_DEFAULT_SIZE, t -> t, selected);
+ return buildStickyFacet(fieldName, facetName, FACET_DEFAULT_SIZE, t -> t, selected);
}
public AggregationBuilder buildStickyFacet(String fieldName, String facetName, int size, Object... selected) {
import static org.elasticsearch.index.query.QueryBuilders.matchPhraseQuery;
import static org.elasticsearch.index.query.QueryBuilders.matchQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;
+import static org.sonar.api.rules.RuleType.SECURITY_HOTSPOT;
+import static org.sonar.api.rules.RuleType.VULNERABILITY;
import static org.sonar.server.es.EsUtils.SCROLL_TIME_IN_MINUTES;
import static org.sonar.server.es.EsUtils.optimizeScrollRequest;
import static org.sonar.server.es.EsUtils.scrollIds;
import static org.sonar.server.es.IndexType.FIELD_INDEX_TYPE;
+import static org.sonar.server.es.StickyFacetBuilder.FACET_DEFAULT_SIZE;
import static org.sonar.server.es.newindex.DefaultIndexSettingsElement.ENGLISH_HTML_ANALYZER;
import static org.sonar.server.es.newindex.DefaultIndexSettingsElement.SEARCH_GRAMS_ANALYZER;
import static org.sonar.server.es.newindex.DefaultIndexSettingsElement.SEARCH_WORDS_ANALYZER;
if (isNotEmpty(query.getCwe())) {
filters.put(FIELD_RULE_CWE,
- QueryBuilders.termsQuery(FIELD_RULE_CWE, query.getCwe()));
+ boolQuery()
+ .must(QueryBuilders.termsQuery(FIELD_RULE_CWE, query.getCwe()))
+ .must(QueryBuilders.termsQuery(FIELD_RULE_TYPE, VULNERABILITY.name(), SECURITY_HOTSPOT.name())));
}
if (isNotEmpty(query.getOwaspTop10())) {
filters.put(FIELD_RULE_OWASP_TOP_10,
- QueryBuilders.termsQuery(FIELD_RULE_OWASP_TOP_10, query.getOwaspTop10()));
+ boolQuery()
+ .must(QueryBuilders.termsQuery(FIELD_RULE_OWASP_TOP_10, query.getOwaspTop10()))
+ .must(QueryBuilders.termsQuery(FIELD_RULE_TYPE, VULNERABILITY.name(), SECURITY_HOTSPOT.name())));
}
if (isNotEmpty(query.getSansTop25())) {
filters.put(FIELD_RULE_SANS_TOP_25,
- QueryBuilders.termsQuery(FIELD_RULE_SANS_TOP_25, query.getSansTop25()));
+ boolQuery()
+ .must(QueryBuilders.termsQuery(FIELD_RULE_SANS_TOP_25, query.getSansTop25()))
+ .must(QueryBuilders.termsQuery(FIELD_RULE_TYPE, VULNERABILITY.name(), SECURITY_HOTSPOT.name())));
}
if (isNotEmpty(query.getSonarsourceSecurity())) {
filters.put(FIELD_RULE_SONARSOURCE_SECURITY,
- QueryBuilders.termsQuery(FIELD_RULE_SONARSOURCE_SECURITY, query.getSonarsourceSecurity()));
+ boolQuery()
+ .must(QueryBuilders.termsQuery(FIELD_RULE_SONARSOURCE_SECURITY, query.getSonarsourceSecurity()))
+ .must(QueryBuilders.termsQuery(FIELD_RULE_TYPE, VULNERABILITY.name(), SECURITY_HOTSPOT.name())));
}
if (StringUtils.isNotEmpty(query.getKey())) {
addDefaultSecurityFacets(query, options, aggregations, stickyFacetBuilder);
}
+ 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()))
+ .subAggregation(termsAggregation);
+ }
+
private static void addDefaultSecurityFacets(RuleQuery query, SearchOptions options, Map<String, AggregationBuilder> aggregations,
StickyFacetBuilder stickyFacetBuilder) {
if (options.getFacets().contains(FACET_CWE)) {
Collection<String> categories = query.getCwe();
aggregations.put(FACET_CWE,
stickyFacetBuilder.buildStickyFacet(FIELD_RULE_CWE, FACET_CWE,
+ FACET_DEFAULT_SIZE, filterSecurityCategories(),
(categories == null) ? (new String[0]) : categories.toArray()));
}
if (options.getFacets().contains(FACET_OWASP_TOP_10)) {
Collection<String> categories = query.getOwaspTop10();
aggregations.put(FACET_OWASP_TOP_10,
stickyFacetBuilder.buildStickyFacet(FIELD_RULE_OWASP_TOP_10, FACET_OWASP_TOP_10,
+ 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,
stickyFacetBuilder.buildStickyFacet(FIELD_RULE_SANS_TOP_25, FACET_SANS_TOP_25,
+ FACET_DEFAULT_SIZE, filterSecurityCategories(),
(categories == null) ? (new String[0]) : categories.toArray()));
}
if (options.getFacets().contains(FACET_SONARSOURCE_SECURITY)) {
Collection<String> categories = query.getSonarsourceSecurity();
aggregations.put(FACET_SONARSOURCE_SECURITY,
stickyFacetBuilder.buildStickyFacet(FIELD_RULE_SONARSOURCE_SECURITY, FACET_SONARSOURCE_SECURITY,
+ FACET_DEFAULT_SIZE, filterSecurityCategories(),
(categories == null) ? (new String[0]) : categories.toArray()));
}
}
import org.sonar.api.impl.utils.AlwaysIncreasingSystem2;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.RuleStatus;
+import org.sonar.api.rules.RuleType;
import org.sonar.api.utils.System2;
import org.sonar.db.DbTester;
import org.sonar.db.organization.OrganizationDto;
import static org.sonar.api.rule.Severity.MINOR;
import static org.sonar.api.rules.RuleType.BUG;
import static org.sonar.api.rules.RuleType.CODE_SMELL;
+import static org.sonar.api.rules.RuleType.SECURITY_HOTSPOT;
import static org.sonar.api.rules.RuleType.VULNERABILITY;
import static org.sonar.db.rule.RuleTesting.setCreatedAt;
import static org.sonar.db.rule.RuleTesting.setIsExternal;
}
@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")));
+ public void search_by_security_cwe_return_vulnerabilities_and_hotspots_only() {
+ RuleDefinitionDto rule1 = createRule(setSecurityStandards(of("cwe:543", "cwe:123", "owaspTop10:a1")), r -> r.setType(VULNERABILITY));
+ RuleDefinitionDto rule2 = createRule(setSecurityStandards(of("cwe:543", "owaspTop10:a1")), r -> r.setType(SECURITY_HOTSPOT));
+ createRule(setSecurityStandards(of("owaspTop10:a1")), r -> r.setType(CODE_SMELL));
index();
RuleQuery query = new RuleQuery().setCwe(of("543"));
}
@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")));
+ public void search_by_security_owaspTop10_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));
index();
RuleQuery query = new RuleQuery().setOwaspTop10(of("a5", "a10"));
}
@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")));
+ 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));
+ RuleDefinitionDto rule2 = createRule(setSecurityStandards(of("owaspTop10:a10", "cwe:829")), r -> r.setType(SECURITY_HOTSPOT));
+ createRule(setSecurityStandards(of("cwe:306")), r -> r.setType(CODE_SMELL));
index();
RuleQuery query = new RuleQuery().setSansTop25(of(SANS_TOP_25_INSECURE_INTERACTION, SANS_TOP_25_RISKY_RESOURCE));
}
@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")));
+ 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));
+ 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();
RuleQuery query = new RuleQuery().setSonarsourceSecurity(of("sql-injection", "open-redirect"));
filters.addFilter(
FIELD_ISSUE_ORGANIZATION_UUID, new SimpleFieldFilterScope(FIELD_ISSUE_ORGANIZATION_UUID),
createTermFilter(FIELD_ISSUE_ORGANIZATION_UUID, query.organizationUuid()));
- filters.addFilter(
- FIELD_ISSUE_OWASP_TOP_10, OWASP_TOP_10.getFilterScope(),
- createTermsFilter(FIELD_ISSUE_OWASP_TOP_10, query.owaspTop10()));
- filters.addFilter(
- FIELD_ISSUE_SANS_TOP_25, SANS_TOP_25.getFilterScope(),
- createTermsFilter(FIELD_ISSUE_SANS_TOP_25, query.sansTop25()));
- filters.addFilter(FIELD_ISSUE_CWE, CWE.getFilterScope(), createTermsFilter(FIELD_ISSUE_CWE, query.cwe()));
+
+ // security category
+ addSecurityCategoryFilter(FIELD_ISSUE_OWASP_TOP_10, OWASP_TOP_10, query.owaspTop10(), 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);
+
addSeverityFilter(query, filters);
- filters.addFilter(
- FIELD_ISSUE_SQ_SECURITY_CATEGORY, SONARSOURCE_SECURITY.getFilterScope(),
- createTermsFilter(FIELD_ISSUE_SQ_SECURITY_CATEGORY, query.sonarsourceSecurity()));
addComponentRelatedFilters(query, filters);
addDatesFilter(filters, query);
return filters;
}
+ private static void addSecurityCategoryFilter(String fieldName, Facet facet, Collection<String> values, AllFilters allFilters) {
+ QueryBuilder securityCategoryFilter = createTermsFilter(fieldName, values);
+ if (securityCategoryFilter != null) {
+ allFilters.addFilter(
+ fieldName,
+ facet.getFilterScope(),
+ boolQuery()
+ .must(securityCategoryFilter)
+ .must(termQuery(FIELD_ISSUE_TYPE, VULNERABILITY.name())));
+ }
+ }
+
private static void addSeverityFilter(IssueQuery query, AllFilters allFilters) {
QueryBuilder severityFieldFilter = createTermsFilter(FIELD_ISSUE_SEVERITY, query.severities());
if (severityFieldFilter != null) {
addFacetIfNeeded(options, aggregationHelper, esRequest, AUTHOR, query.authors().toArray());
addFacetIfNeeded(options, aggregationHelper, esRequest, TAGS, query.tags().toArray());
addFacetIfNeeded(options, aggregationHelper, esRequest, TYPES, query.types().toArray());
- addFacetIfNeeded(options, aggregationHelper, esRequest, OWASP_TOP_10, query.owaspTop10().toArray());
- addFacetIfNeeded(options, aggregationHelper, esRequest, SANS_TOP_25, query.sansTop25().toArray());
- addFacetIfNeeded(options, aggregationHelper, esRequest, CWE, query.cwe().toArray());
- addFacetIfNeeded(options, aggregationHelper, esRequest, SONARSOURCE_SECURITY, query.sonarsourceSecurity().toArray());
+
+ addSecurityCategoryFacetIfNeeded(PARAM_OWASP_TOP_10, OWASP_TOP_10, options, aggregationHelper, esRequest, query.owaspTop10().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());
+
addSeverityFacetIfNeeded(options, aggregationHelper, esRequest);
addResolutionFacetIfNeeded(options, query, aggregationHelper, esRequest);
addAssigneesFacetIfNeeded(options, query, aggregationHelper, esRequest);
esRequest.addAggregation(topAggregation);
}
+ private static void addSecurityCategoryFacetIfNeeded(String param, Facet facet, SearchOptions options, TopAggregationHelper aggregationHelper, SearchRequestBuilder esRequest,
+ Object[] selectedValues) {
+ if (!options.getFacets().contains(param)) {
+ return;
+ }
+
+ AggregationBuilder aggregation = aggregationHelper.buildTermTopAggregation(
+ facet.getName(), facet.getTopAggregationDef(), facet.getNumberOfTerms(),
+ filter -> filter.must(termQuery(FIELD_ISSUE_TYPE, VULNERABILITY.name())),
+ t -> aggregationHelper.getSubAggregationHelper().buildSelectedItemsAggregation(facet.getName(), facet.getTopAggregationDef(), selectedValues)
+ .ifPresent(t::subAggregation));
+ esRequest.addAggregation(aggregation);
+ }
+
private static void addSeverityFacetIfNeeded(SearchOptions options, TopAggregationHelper aggregationHelper, SearchRequestBuilder esRequest) {
if (!options.getFacets().contains(PARAM_SEVERITIES)) {
return;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
-import org.sonar.api.utils.System2;
import org.sonar.api.impl.utils.TestSystem2;
+import org.sonar.api.rules.RuleType;
+import org.sonar.api.utils.System2;
import org.sonar.db.DbTester;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.server.permission.index.IndexPermissions;
import org.sonar.server.permission.index.PermissionIndexerTester;
import org.sonar.server.permission.index.WebAuthorizationTypeSupport;
+import org.sonar.server.security.SecurityStandards.SQCategory;
import org.sonar.server.tester.UserSessionRule;
import static java.util.Arrays.asList;
assertThatFacetHasSize(IssueQuery.builder().directories(asList(issue1.directoryPath(), issue2.directoryPath())).build(), "directories", 102);
}
+ @Test
+ public void facets_on_cwe() {
+ ComponentDto project = newPrivateProjectDto(newOrganizationDto());
+ ComponentDto file = newFileDto(project, null);
+
+ indexIssues(
+ newDoc("I1", file).setType(RuleType.VULNERABILITY).setCwe(asList("20", "564", "89", "943")),
+ newDoc("I2", file).setType(RuleType.VULNERABILITY).setCwe(asList("943")),
+ newDoc("I3", file));
+
+ assertThatFacetHasOnly(IssueQuery.builder(), "cwe",
+ entry("943", 2L),
+ entry("20", 1L),
+ entry("564", 1L),
+ entry("89", 1L));
+ }
+
+ @Test
+ public void facets_on_owaspTop10() {
+ ComponentDto project = newPrivateProjectDto(newOrganizationDto());
+ ComponentDto file = newFileDto(project, null);
+
+ indexIssues(
+ newDoc("I1", file).setType(RuleType.VULNERABILITY).setOwaspTop10(asList("a1", "a2")),
+ newDoc("I2", file).setType(RuleType.VULNERABILITY).setOwaspTop10(singletonList("a3")),
+ newDoc("I3", file));
+
+ assertThatFacetHasOnly(IssueQuery.builder(), "owaspTop10",
+ entry("a1", 1L),
+ entry("a2", 1L),
+ entry("a3", 1L));
+ }
+
+ @Test
+ public void facets_on_sansTop25() {
+ ComponentDto project = newPrivateProjectDto(newOrganizationDto());
+ ComponentDto file = newFileDto(project, null);
+
+ indexIssues(
+ newDoc("I1", file).setType(RuleType.VULNERABILITY).setSansTop25(asList("porous-defenses", "risky-resource", "insecure-interaction")),
+ newDoc("I2", file).setType(RuleType.VULNERABILITY).setSansTop25(singletonList("porous-defenses")),
+ newDoc("I3", file));
+
+ assertThatFacetHasOnly(IssueQuery.builder(), "sansTop25",
+ entry("insecure-interaction", 1L),
+ entry("porous-defenses", 2L),
+ entry("risky-resource", 1L));
+ }
+
+ @Test
+ public void facets_on_sonarSourceSecurity() {
+ ComponentDto project = newPrivateProjectDto(newOrganizationDto());
+ ComponentDto file = newFileDto(project, null);
+
+ indexIssues(
+ newDoc("I1", file).setType(RuleType.VULNERABILITY).setSonarSourceSecurityCategory(SQCategory.BUFFER_OVERFLOW),
+ newDoc("I2", file).setType(RuleType.VULNERABILITY).setSonarSourceSecurityCategory(SQCategory.DOS),
+ newDoc("I3", file));
+
+ assertThatFacetHasOnly(IssueQuery.builder(), "sonarsourceSecurity",
+ entry("buffer-overflow", 1L),
+ entry("dos", 1L));
+ }
+
@Test
public void facets_on_severities() {
ComponentDto project = newPrivateProjectDto(newOrganizationDto());
import org.sonar.api.impl.utils.TestSystem2;
import org.sonar.api.issue.Issue;
import org.sonar.api.rule.Severity;
+import org.sonar.api.rules.RuleType;
import org.sonar.api.utils.System2;
import org.sonar.db.DbTester;
import org.sonar.db.component.ComponentDto;
import org.sonar.server.permission.index.IndexPermissions;
import org.sonar.server.permission.index.PermissionIndexerTester;
import org.sonar.server.permission.index.WebAuthorizationTypeSupport;
+import org.sonar.server.security.SecurityStandards.SQCategory;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.view.index.ViewDoc;
import org.sonar.server.view.index.ViewIndexer;
assertThatSearchReturnsEmpty(query);
}
+ @Test
+ public void filter_by_cwe() {
+ ComponentDto project = newPrivateProjectDto(newOrganizationDto());
+ ComponentDto file = newFileDto(project, null);
+
+ indexIssues(
+ newDoc("I1", file).setType(RuleType.VULNERABILITY).setCwe(asList("20", "564", "89", "943")),
+ newDoc("I2", file).setType(RuleType.VULNERABILITY).setCwe(asList("943")),
+ newDoc("I3", file));
+
+ assertThatSearchReturnsOnly(IssueQuery.builder().cwe(asList("20")), "I1");
+ }
+
+ @Test
+ public void filter_by_owaspTop10() {
+ ComponentDto project = newPrivateProjectDto(newOrganizationDto());
+ ComponentDto file = newFileDto(project, null);
+
+ indexIssues(
+ newDoc("I1", file).setType(RuleType.VULNERABILITY).setOwaspTop10(asList("a1", "a2")),
+ newDoc("I2", file).setType(RuleType.VULNERABILITY).setCwe(singletonList("a3")),
+ newDoc("I3", file));
+
+ assertThatSearchReturnsOnly(IssueQuery.builder().owaspTop10(asList("a1")), "I1");
+ }
+
+ @Test
+ public void filter_by_sansTop25() {
+ ComponentDto project = newPrivateProjectDto(newOrganizationDto());
+ ComponentDto file = newFileDto(project, null);
+
+ indexIssues(
+ newDoc("I1", file).setType(RuleType.VULNERABILITY).setSansTop25(asList("porous-defenses", "risky-resource", "insecure-interaction")),
+ newDoc("I2", file).setType(RuleType.VULNERABILITY).setSansTop25(singletonList("porous-defenses")),
+ newDoc("I3", file));
+
+ assertThatSearchReturnsOnly(IssueQuery.builder().sansTop25(asList("risky-resource")), "I1");
+ }
+
+ @Test
+ public void filter_by_sonarSecurity() {
+ ComponentDto project = newPrivateProjectDto(newOrganizationDto());
+ ComponentDto file = newFileDto(project, null);
+
+ indexIssues(
+ newDoc("I1", file).setType(RuleType.VULNERABILITY).setSonarSourceSecurityCategory(SQCategory.BUFFER_OVERFLOW),
+ newDoc("I2", file).setType(RuleType.VULNERABILITY).setSonarSourceSecurityCategory(SQCategory.DOS),
+ newDoc("I3", file));
+
+ assertThatSearchReturnsOnly(IssueQuery.builder().sonarsourceSecurity(singletonList("buffer-overflow")), "I1");
+ }
+
private void verifyOrganizationFilter(String organizationUuid, String... expectedIssueKeys) {
IssueQuery.Builder query = IssueQuery.builder().organizationUuid(organizationUuid);
assertThatSearchReturnsOnly(query, expectedIssueKeys);
.containsExactly("82fd47d4-b650-4037-80bc-7b112bd4eac3", "82fd47d4-b650-4037-80bc-7b112bd4eac1", "82fd47d4-b650-4037-80bc-7b112bd4eac2");
}
+ @Test
+ public void only_vulnerabilities_are_returned_by_cwe() {
+ ComponentDto project = db.components().insertPublicProject();
+ ComponentDto file = db.components().insertComponent(newFileDto(project));
+ Consumer<RuleDefinitionDto> ruleConsumer = ruleDefinitionDto -> ruleDefinitionDto
+ .setSecurityStandards(Sets.newHashSet("cwe:20", "cwe:564", "cwe:89", "cwe:943", "owaspTop10:a1"))
+ .setSystemTags(Sets.newHashSet("bad-practice", "cwe", "owasp-a1", "sans-top25-insecure", "sql"));
+ Consumer<IssueDto> issueConsumer = issueDto -> issueDto.setTags(Sets.newHashSet("bad-practice", "cwe", "owasp-a1", "sans-top25-insecure", "sql"));
+ RuleDefinitionDto hotspotRule = db.rules().insertHotspotRule(ruleConsumer);
+ db.issues().insertHotspot(hotspotRule, project, file, issueConsumer);
+ RuleDefinitionDto 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));
+ IssueDto issueDto3 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(CODE_SMELL));
+ indexPermissions();
+ indexIssues();
+
+ SearchWsResponse result = ws.newRequest()
+ .setParam("cwe", "20")
+ .executeProtobuf(SearchWsResponse.class);
+
+ assertThat(result.getIssuesList())
+ .extracting(Issue::getKey)
+ .containsExactlyInAnyOrder(issueDto1.getKey(), issueDto2.getKey());
+ }
+
+ @Test
+ public void only_vulnerabilities_are_returned_by_owasp() {
+ ComponentDto project = db.components().insertPublicProject();
+ ComponentDto file = db.components().insertComponent(newFileDto(project));
+ Consumer<RuleDefinitionDto> ruleConsumer = ruleDefinitionDto -> ruleDefinitionDto
+ .setSecurityStandards(Sets.newHashSet("cwe:20", "cwe:564", "cwe:89", "cwe:943", "owaspTop10:a1"))
+ .setSystemTags(Sets.newHashSet("bad-practice", "cwe", "owasp-a1", "sans-top25-insecure", "sql"));
+ Consumer<IssueDto> issueConsumer = issueDto -> issueDto.setTags(Sets.newHashSet("bad-practice", "cwe", "owasp-a1", "sans-top25-insecure", "sql"));
+ RuleDefinitionDto hotspotRule = db.rules().insertHotspotRule(ruleConsumer);
+ db.issues().insertHotspot(hotspotRule, project, file, issueConsumer);
+ RuleDefinitionDto 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));
+ IssueDto issueDto3 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(CODE_SMELL));
+ indexPermissions();
+ indexIssues();
+
+ SearchWsResponse result = ws.newRequest()
+ .setParam("owaspTop10", "a1")
+ .executeProtobuf(SearchWsResponse.class);
+
+ assertThat(result.getIssuesList())
+ .extracting(Issue::getKey)
+ .containsExactlyInAnyOrder(issueDto1.getKey(), issueDto2.getKey());
+ }
+
+ @Test
+ public void only_vulnerabilities_are_returned_by_sansTop25() {
+ ComponentDto project = db.components().insertPublicProject();
+ ComponentDto file = db.components().insertComponent(newFileDto(project));
+ Consumer<RuleDefinitionDto> ruleConsumer = ruleDefinitionDto -> ruleDefinitionDto
+ .setSecurityStandards(Sets.newHashSet("cwe:266", "cwe:732", "owaspTop10:a5"))
+ .setSystemTags(Sets.newHashSet("cert", "cwe", "owasp-a5", "sans-top25-porous"));
+ Consumer<IssueDto> issueConsumer = issueDto -> issueDto.setTags(Sets.newHashSet("cert", "cwe", "owasp-a5", "sans-top25-porous"));
+ RuleDefinitionDto hotspotRule = db.rules().insertHotspotRule(ruleConsumer);
+ db.issues().insertHotspot(hotspotRule, project, file, issueConsumer);
+ RuleDefinitionDto 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));
+ IssueDto issueDto3 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(CODE_SMELL));
+ indexPermissions();
+ indexIssues();
+
+ SearchWsResponse result = ws.newRequest()
+ .setParam("sansTop25", "porous-defenses")
+ .executeProtobuf(SearchWsResponse.class);
+
+ assertThat(result.getIssuesList())
+ .extracting(Issue::getKey)
+ .containsExactlyInAnyOrder(issueDto1.getKey(), issueDto2.getKey());
+ }
+
+ @Test
+ public void only_vulnerabilities_are_returned_by_sonarsource_security() {
+ ComponentDto project = db.components().insertPublicProject();
+ ComponentDto file = db.components().insertComponent(newFileDto(project));
+ Consumer<RuleDefinitionDto> ruleConsumer = ruleDefinitionDto -> ruleDefinitionDto
+ .setSecurityStandards(Sets.newHashSet("cwe:20", "cwe:564", "cwe:89", "cwe:943", "owaspTop10:a1"))
+ .setSystemTags(Sets.newHashSet("cwe", "owasp-a1", "sans-top25-insecure", "sql"));
+ Consumer<IssueDto> issueConsumer = issueDto -> issueDto.setTags(Sets.newHashSet("cwe", "owasp-a1", "sans-top25-insecure", "sql"));
+ RuleDefinitionDto hotspotRule = db.rules().insertHotspotRule(ruleConsumer);
+ db.issues().insertHotspot(hotspotRule, project, file, issueConsumer);
+ RuleDefinitionDto 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));
+ IssueDto issueDto3 = db.issues().insertIssue(issueRule, project, file, issueConsumer, issueDto -> issueDto.setType(CODE_SMELL));
+ indexPermissions();
+ indexIssues();
+
+ SearchWsResponse result = ws.newRequest()
+ .setParam("sonarsourceSecurity", "sql-injection")
+ .executeProtobuf(SearchWsResponse.class);
+
+ assertThat(result.getIssuesList())
+ .extracting(Issue::getKey)
+ .containsExactlyInAnyOrder(issueDto1.getKey(), issueDto2.getKey());
+ }
+
@Test
public void security_hotspots_are_not_returned_by_default() {
ComponentDto project = db.components().insertPublicProject();
RuleDefinitionDto hotspotRule = db.rules().insertHotspotRule(ruleConsumer);
db.issues().insertHotspot(hotspotRule, project, file, issueConsumer);
RuleDefinitionDto issueRule = db.rules().insertIssueRule(ruleConsumer);
- IssueDto issueDto1 = db.issues().insertIssue(issueRule, project, file, issueConsumer);
- IssueDto issueDto2 = db.issues().insertIssue(issueRule, project, file, issueConsumer);
+ 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));
indexPermissions();
indexIssues();