aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-webserver-es/src
diff options
context:
space:
mode:
authorJacek <jacek.poreda@sonarsource.com>2020-08-10 14:45:45 +0200
committersonartech <sonartech@sonarsource.com>2020-08-26 20:06:44 +0000
commit56826fb52dbddbe6166f7a1e80065bddc7fd254a (patch)
tree1e92566183197c407eda09f6a3b9b9af273add2e /server/sonar-webserver-es/src
parent8cba7b5098395a6c39e616570a687b167e618153 (diff)
downloadsonarqube-56826fb52dbddbe6166f7a1e80065bddc7fd254a.tar.gz
sonarqube-56826fb52dbddbe6166f7a1e80065bddc7fd254a.zip
SONAR-12459 Security Category filters vulnerability issues only
Diffstat (limited to 'server/sonar-webserver-es/src')
-rw-r--r--server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndex.java53
-rw-r--r--server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexFacetsTest.java68
-rw-r--r--server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexFiltersTest.java54
3 files changed, 160 insertions, 15 deletions
diff --git a/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndex.java b/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndex.java
index fc652c7b454..db39fc3028e 100644
--- a/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndex.java
+++ b/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndex.java
@@ -433,17 +433,14 @@ public class IssueIndex {
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);
@@ -451,6 +448,18 @@ public class IssueIndex {
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) {
@@ -659,10 +668,12 @@ public class IssueIndex {
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);
@@ -685,6 +696,20 @@ public class IssueIndex {
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;
diff --git a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexFacetsTest.java b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexFacetsTest.java
index b735f379a4f..2fe031c9355 100644
--- a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexFacetsTest.java
+++ b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexFacetsTest.java
@@ -24,8 +24,9 @@ import org.elasticsearch.action.search.SearchResponse;
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;
@@ -36,6 +37,7 @@ import org.sonar.server.es.SearchOptions;
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;
@@ -170,6 +172,70 @@ public class IssueIndexFacetsTest {
}
@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());
ComponentDto file = newFileDto(project, null);
diff --git a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexFiltersTest.java b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexFiltersTest.java
index 3359730b847..6b61d3d86c4 100644
--- a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexFiltersTest.java
+++ b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexFiltersTest.java
@@ -32,6 +32,7 @@ import org.junit.rules.ExpectedException;
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;
@@ -42,6 +43,7 @@ import org.sonar.server.es.SearchOptions;
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;
@@ -740,6 +742,58 @@ public class IssueIndexFiltersTest {
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);