Browse Source

SONAR-11973 add SonarSource security facet to issues search

tags/7.8
Michal Duda 5 years ago
parent
commit
443fb56144

+ 11
- 0
server/sonar-server-common/src/main/java/org/sonar/server/issue/SearchRequest.java View File

private List<String> types; private List<String> types;
private List<String> owaspTop10; private List<String> owaspTop10;
private List<String> sansTop25; private List<String> sansTop25;
private List<String> sonarsourceSecurity;
private List<String> cwe; private List<String> cwe;


@CheckForNull @CheckForNull
return this; return this;
} }


@CheckForNull
public List<String> getSonarsourceSecurity() {
return sonarsourceSecurity;
}

public SearchRequest setSonarsourceSecurity(@Nullable List<String> sonarsourceSecurity) {
this.sonarsourceSecurity = sonarsourceSecurity;
return this;
}

@CheckForNull @CheckForNull
public List<String> getComponentRootUuids() { public List<String> getComponentRootUuids() {
return componentRootUuids; return componentRootUuids;

+ 6
- 1
server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndex.java View File

import static org.sonar.server.issue.index.IssueIndex.Facet.RULES; import static org.sonar.server.issue.index.IssueIndex.Facet.RULES;
import static org.sonar.server.issue.index.IssueIndex.Facet.SANS_TOP_25; import static org.sonar.server.issue.index.IssueIndex.Facet.SANS_TOP_25;
import static org.sonar.server.issue.index.IssueIndex.Facet.SEVERITIES; import static org.sonar.server.issue.index.IssueIndex.Facet.SEVERITIES;
import static org.sonar.server.issue.index.IssueIndex.Facet.SONARSOURCE_SECURITY;
import static org.sonar.server.issue.index.IssueIndex.Facet.STATUSES; import static org.sonar.server.issue.index.IssueIndex.Facet.STATUSES;
import static org.sonar.server.issue.index.IssueIndex.Facet.TAGS; import static org.sonar.server.issue.index.IssueIndex.Facet.TAGS;
import static org.sonar.server.issue.index.IssueIndex.Facet.TYPES; import static org.sonar.server.issue.index.IssueIndex.Facet.TYPES;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_RULES; import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_RULES;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_SANS_TOP_25; import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_SANS_TOP_25;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_SEVERITIES; import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_SEVERITIES;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_SONARSOURCE_SECURITY;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_STATUSES; import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_STATUSES;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_TAGS; import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_TAGS;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_TYPES; import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_TYPES;
OWASP_TOP_10(PARAM_OWASP_TOP_10, FIELD_ISSUE_OWASP_TOP_10, DEFAULT_FACET_SIZE), OWASP_TOP_10(PARAM_OWASP_TOP_10, FIELD_ISSUE_OWASP_TOP_10, DEFAULT_FACET_SIZE),
SANS_TOP_25(PARAM_SANS_TOP_25, FIELD_ISSUE_SANS_TOP_25, DEFAULT_FACET_SIZE), SANS_TOP_25(PARAM_SANS_TOP_25, FIELD_ISSUE_SANS_TOP_25, DEFAULT_FACET_SIZE),
CWE(PARAM_CWE, FIELD_ISSUE_CWE, DEFAULT_FACET_SIZE), CWE(PARAM_CWE, FIELD_ISSUE_CWE, DEFAULT_FACET_SIZE),
CREATED_AT(PARAM_CREATED_AT, FIELD_ISSUE_FUNC_CREATED_AT, DEFAULT_FACET_SIZE);
CREATED_AT(PARAM_CREATED_AT, FIELD_ISSUE_FUNC_CREATED_AT, DEFAULT_FACET_SIZE),
SONARSOURCE_SECURITY(PARAM_SONARSOURCE_SECURITY, FIELD_ISSUE_SONARSOURCE_SECURITY, DEFAULT_FACET_SIZE);


private final String name; private final String name;
private final String fieldName; private final String fieldName;
filters.put(FIELD_ISSUE_SANS_TOP_25, createTermsFilter(FIELD_ISSUE_SANS_TOP_25, query.sansTop25())); filters.put(FIELD_ISSUE_SANS_TOP_25, createTermsFilter(FIELD_ISSUE_SANS_TOP_25, query.sansTop25()));
filters.put(FIELD_ISSUE_CWE, createTermsFilter(FIELD_ISSUE_CWE, query.cwe())); filters.put(FIELD_ISSUE_CWE, createTermsFilter(FIELD_ISSUE_CWE, query.cwe()));
addSeverityFilter(query, filters); addSeverityFilter(query, filters);
filters.put(FIELD_ISSUE_SONARSOURCE_SECURITY, createTermsFilter(FIELD_ISSUE_SONARSOURCE_SECURITY, query.sonarsourceSecurity()));


addComponentRelatedFilters(query, filters); addComponentRelatedFilters(query, filters);
addDatesFilter(filters, query); addDatesFilter(filters, query);
if (options.getFacets().contains(PARAM_SEVERITIES)) { if (options.getFacets().contains(PARAM_SEVERITIES)) {
esSearch.addAggregation(createSeverityFacet(query, filters, esQuery)); esSearch.addAggregation(createSeverityFacet(query, filters, esQuery));
} }
addSimpleStickyFacetIfNeeded(options, stickyFacetBuilder, esSearch, SONARSOURCE_SECURITY, query.sonarsourceSecurity().toArray());
if (options.getFacets().contains(PARAM_RESOLUTIONS)) { if (options.getFacets().contains(PARAM_RESOLUTIONS)) {
esSearch.addAggregation(createResolutionFacet(query, filters, esQuery)); esSearch.addAggregation(createResolutionFacet(query, filters, esQuery));
} }

+ 12
- 0
server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueQuery.java View File

private final Collection<String> owaspTop10; private final Collection<String> owaspTop10;
private final Collection<String> sansTop25; private final Collection<String> sansTop25;
private final Collection<String> cwe; private final Collection<String> cwe;
private final Collection<String> sonarsourceSecurity;
private final Map<String, PeriodStart> createdAfterByProjectUuids; private final Map<String, PeriodStart> createdAfterByProjectUuids;
private final Boolean onComponentOnly; private final Boolean onComponentOnly;
private final Boolean assigned; private final Boolean assigned;
this.owaspTop10 = defaultCollection(builder.owaspTop10); this.owaspTop10 = defaultCollection(builder.owaspTop10);
this.sansTop25 = defaultCollection(builder.sansTop25); this.sansTop25 = defaultCollection(builder.sansTop25);
this.cwe = defaultCollection(builder.cwe); this.cwe = defaultCollection(builder.cwe);
this.sonarsourceSecurity = defaultCollection(builder.sonarsourceSecurity);
this.createdAfterByProjectUuids = defaultMap(builder.createdAfterByProjectUuids); this.createdAfterByProjectUuids = defaultMap(builder.createdAfterByProjectUuids);
this.onComponentOnly = builder.onComponentOnly; this.onComponentOnly = builder.onComponentOnly;
this.assigned = builder.assigned; this.assigned = builder.assigned;
return cwe; return cwe;
} }


public Collection<String> sonarsourceSecurity() {
return sonarsourceSecurity;
}

public Map<String, PeriodStart> createdAfterByProjectUuids() { public Map<String, PeriodStart> createdAfterByProjectUuids() {
return createdAfterByProjectUuids; return createdAfterByProjectUuids;
} }
private Collection<String> owaspTop10; private Collection<String> owaspTop10;
private Collection<String> sansTop25; private Collection<String> sansTop25;
private Collection<String> cwe; private Collection<String> cwe;
private Collection<String> sonarsourceSecurity;
private Map<String, PeriodStart> createdAfterByProjectUuids; private Map<String, PeriodStart> createdAfterByProjectUuids;
private Boolean onComponentOnly = false; private Boolean onComponentOnly = false;
private Boolean assigned = null; private Boolean assigned = null;
return this; return this;
} }


public Builder sonarsourceSecurity(@Nullable Collection<String> sonarsourceSecurity) {
this.sonarsourceSecurity = sonarsourceSecurity;
return this;
}

public Builder createdAfterByProjectUuids(@Nullable Map<String, PeriodStart> createdAfterByProjectUuids) { public Builder createdAfterByProjectUuids(@Nullable Map<String, PeriodStart> createdAfterByProjectUuids) {
this.createdAfterByProjectUuids = createdAfterByProjectUuids; this.createdAfterByProjectUuids = createdAfterByProjectUuids;
return this; return this;

+ 1
- 0
server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueQueryFactory.java View File

.owaspTop10(request.getOwaspTop10()) .owaspTop10(request.getOwaspTop10())
.sansTop25(request.getSansTop25()) .sansTop25(request.getSansTop25())
.cwe(request.getCwe()) .cwe(request.getCwe())
.sonarsourceSecurity(request.getSonarsourceSecurity())
.assigned(request.getAssigned()) .assigned(request.getAssigned())
.createdAt(parseDateOrDateTime(request.getCreatedAt())) .createdAt(parseDateOrDateTime(request.getCreatedAt()))
.createdBefore(parseEndingDateOrDateTime(request.getCreatedBefore())) .createdBefore(parseEndingDateOrDateTime(request.getCreatedBefore()))

+ 11
- 2
server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAction.java View File

import static org.sonar.server.issue.index.SecurityStandardHelper.SANS_TOP_25_INSECURE_INTERACTION; 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_POROUS_DEFENSES;
import static org.sonar.server.issue.index.SecurityStandardHelper.SANS_TOP_25_RISKY_RESOURCE; 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.issue.index.SecurityStandardHelper.UNKNOWN_STANDARD;
import static org.sonar.server.ws.KeyExamples.KEY_BRANCH_EXAMPLE_001; 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_PROJECT_EXAMPLE_001;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_SANS_TOP_25; import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_SANS_TOP_25;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_SEVERITIES; import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_SEVERITIES;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_SINCE_LEAK_PERIOD; import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_SINCE_LEAK_PERIOD;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_SONARSOURCE_SECURITY;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_STATUSES; import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_STATUSES;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_TAGS; import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_TAGS;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_TYPES; import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_TYPES;
PARAM_OWASP_TOP_10, PARAM_OWASP_TOP_10,
PARAM_SANS_TOP_25, PARAM_SANS_TOP_25,
PARAM_CWE, PARAM_CWE,
PARAM_CREATED_AT);
PARAM_CREATED_AT,
PARAM_SONARSOURCE_SECURITY);


private static final String INTERNAL_PARAMETER_DISCLAIMER = "This parameter is mostly used by the Issues page, please prefer usage of the componentKeys parameter. "; private static final String INTERNAL_PARAMETER_DISCLAIMER = "This parameter is mostly used by the Issues page, please prefer usage of the componentKeys parameter. ";
private static final Set<String> FACETS_REQUIRING_PROJECT_OR_ORGANIZATION = newHashSet(PARAM_MODULE_UUIDS, PARAM_FILE_UUIDS, PARAM_DIRECTORIES); private static final Set<String> FACETS_REQUIRING_PROJECT_OR_ORGANIZATION = newHashSet(PARAM_MODULE_UUIDS, PARAM_FILE_UUIDS, PARAM_DIRECTORIES);
action.createParam(PARAM_CWE) action.createParam(PARAM_CWE)
.setDescription("Comma-separated list of CWE identifiers. Use '" + UNKNOWN_STANDARD + "' to select issues not associated to any CWE.") .setDescription("Comma-separated list of CWE identifiers. Use '" + UNKNOWN_STANDARD + "' to select issues not associated to any CWE.")
.setExampleValue("12,125," + UNKNOWN_STANDARD); .setExampleValue("12,125," + UNKNOWN_STANDARD);
action.createParam(PARAM_SONARSOURCE_SECURITY)
.setDescription("Comma-separated list of SonarSource security categories.")
.setSince("7.8")
.setPossibleValues(SONARSOURCE_CWE_MAPPING.keySet());
action.createParam(DEPRECATED_PARAM_AUTHORS) action.createParam(DEPRECATED_PARAM_AUTHORS)
.setDeprecatedSince("7.7") .setDeprecatedSince("7.7")
.setDescription("This parameter is deprecated, please use '%s' instead", PARAM_AUTHOR) .setDescription("This parameter is deprecated, please use '%s' instead", PARAM_AUTHOR)
addMandatoryValuesToFacet(facets, PARAM_OWASP_TOP_10, request.getOwaspTop10()); addMandatoryValuesToFacet(facets, PARAM_OWASP_TOP_10, request.getOwaspTop10());
addMandatoryValuesToFacet(facets, PARAM_SANS_TOP_25, request.getSansTop25()); addMandatoryValuesToFacet(facets, PARAM_SANS_TOP_25, request.getSansTop25());
addMandatoryValuesToFacet(facets, PARAM_CWE, request.getCwe()); addMandatoryValuesToFacet(facets, PARAM_CWE, request.getCwe());
addMandatoryValuesToFacet(facets, PARAM_SONARSOURCE_SECURITY, request.getSonarsourceSecurity());
} }


private static void addMandatoryValuesToFacet(Facets facets, String facetName, @Nullable Iterable<String> mandatoryValues) { private static void addMandatoryValuesToFacet(Facets facets, String facetName, @Nullable Iterable<String> mandatoryValues) {
.setTypes(request.paramAsStrings(PARAM_TYPES)) .setTypes(request.paramAsStrings(PARAM_TYPES))
.setOwaspTop10(request.paramAsStrings(PARAM_OWASP_TOP_10)) .setOwaspTop10(request.paramAsStrings(PARAM_OWASP_TOP_10))
.setSansTop25(request.paramAsStrings(PARAM_SANS_TOP_25)) .setSansTop25(request.paramAsStrings(PARAM_SANS_TOP_25))
.setCwe(request.paramAsStrings(PARAM_CWE));
.setCwe(request.paramAsStrings(PARAM_CWE))
.setSonarsourceSecurity(request.paramAsStrings(PARAM_SONARSOURCE_SECURITY));
} }


private List<String> getLogins(DbSession dbSession, @Nullable List<String> assigneeLogins) { private List<String> getLogins(DbSession dbSession, @Nullable List<String> assigneeLogins) {

+ 1
- 1
server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionTest.java View File

"pullRequest", "organization", "pullRequest", "organization",
"createdAfter", "createdAt", "createdBefore", "createdInLast", "directories", "facetMode", "facets", "fileUuids", "issues", "languages", "moduleUuids", "onComponentOnly", "createdAfter", "createdAt", "createdBefore", "createdInLast", "directories", "facetMode", "facets", "fileUuids", "issues", "languages", "moduleUuids", "onComponentOnly",
"p", "projects", "ps", "resolutions", "resolved", "rules", "s", "severities", "sinceLeakPeriod", "p", "projects", "ps", "resolutions", "resolved", "rules", "s", "severities", "sinceLeakPeriod",
"statuses", "tags", "types", "owaspTop10", "sansTop25", "cwe");
"statuses", "tags", "types", "owaspTop10", "sansTop25", "cwe", "sonarsourceSecurity");


assertThat(def.param("organization")) assertThat(def.param("organization"))
.matches(WebService.Param::isInternal) .matches(WebService.Param::isInternal)

Loading…
Cancel
Save