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; |
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)); | ||||
} | } |
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; |
.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())) |
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) { |
"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) |