Browse Source

SONAR-10980 Index security standards in ES and update issues/search WS

tags/7.5
Julien HENRY 5 years ago
parent
commit
d1c074ce4e

+ 36
- 0
server/sonar-server-common/src/main/java/org/sonar/server/issue/IssueQuery.java View File

@@ -74,6 +74,9 @@ public class IssueQuery {
private final Collection<String> languages;
private final Collection<String> tags;
private final Collection<String> types;
private final Collection<String> owaspTop10;
private final Collection<String> sansTop25;
private final Collection<String> cwe;
private final Map<String, PeriodStart> createdAfterByProjectUuids;
private final Boolean onComponentOnly;
private final Boolean assigned;
@@ -107,6 +110,9 @@ public class IssueQuery {
this.languages = defaultCollection(builder.languages);
this.tags = defaultCollection(builder.tags);
this.types = defaultCollection(builder.types);
this.owaspTop10 = defaultCollection(builder.owaspTop10);
this.sansTop25 = defaultCollection(builder.sansTop25);
this.cwe = defaultCollection(builder.cwe);
this.createdAfterByProjectUuids = defaultMap(builder.createdAfterByProjectUuids);
this.onComponentOnly = builder.onComponentOnly;
this.assigned = builder.assigned;
@@ -191,6 +197,18 @@ public class IssueQuery {
return types;
}

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

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

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

public Map<String, PeriodStart> createdAfterByProjectUuids() {
return createdAfterByProjectUuids;
}
@@ -284,6 +302,9 @@ public class IssueQuery {
private Collection<String> languages;
private Collection<String> tags;
private Collection<String> types;
private Collection<String> owaspTop10;
private Collection<String> sansTop25;
private Collection<String> cwe;
private Map<String, PeriodStart> createdAfterByProjectUuids;
private Boolean onComponentOnly = false;
private Boolean assigned = null;
@@ -388,6 +409,21 @@ public class IssueQuery {
return this;
}

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

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

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

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

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

@@ -64,6 +64,9 @@ public class SearchRequest {
private List<String> statuses;
private List<String> tags;
private List<String> types;
private List<String> owaspTop10;
private List<String> sansTop25;
private List<String> cwe;

@CheckForNull
public List<String> getActionPlans() {
@@ -405,6 +408,36 @@ public class SearchRequest {
return this;
}

@CheckForNull
public List<String> getOwaspTop10() {
return owaspTop10;
}

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

@CheckForNull
public List<String> getSansTop25() {
return sansTop25;
}

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

@CheckForNull
public List<String> getCwe() {
return cwe;
}

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

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

+ 30
- 0
server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueDoc.java View File

@@ -290,4 +290,34 @@ public class IssueDoc extends BaseDoc {
return this;
}

@CheckForNull
public Collection<String> getOwaspTop10() {
return getNullableField(IssueIndexDefinition.FIELD_ISSUE_OWASP_TOP_10);
}

public IssueDoc setOwaspTop10(@Nullable Collection<String> o) {
setField(IssueIndexDefinition.FIELD_ISSUE_OWASP_TOP_10, o);
return this;
}

@CheckForNull
public Collection<String> getSansTop25() {
return getNullableField(IssueIndexDefinition.FIELD_ISSUE_SANS_TOP_25);
}

public IssueDoc setSansTop25(@Nullable Collection<String> s) {
setField(IssueIndexDefinition.FIELD_ISSUE_SANS_TOP_25, s);
return this;
}

@CheckForNull
public Collection<String> getCwe() {
return getNullableField(IssueIndexDefinition.FIELD_ISSUE_CWE);
}

public IssueDoc setCwe(@Nullable Collection<String> c) {
setField(IssueIndexDefinition.FIELD_ISSUE_CWE, c);
return this;
}

}

+ 15
- 0
server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueIndex.java View File

@@ -104,14 +104,17 @@ import static org.sonarqube.ws.client.issue.IssuesWsParameters.FACET_MODE_EFFORT
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_ASSIGNEES;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_AUTHORS;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_CREATED_AT;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_CWE;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_DIRECTORIES;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_FILE_UUIDS;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_LANGUAGES;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_MODULE_UUIDS;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_OWASP_TOP_10;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_PROJECT_UUIDS;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_REPORTERS;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_RESOLUTIONS;
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_SEVERITIES;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_STATUSES;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_TAGS;
@@ -140,6 +143,9 @@ public class IssueIndex {
PARAM_LANGUAGES,
PARAM_TAGS,
PARAM_TYPES,
PARAM_OWASP_TOP_10,
PARAM_SANS_TOP_25,
PARAM_CWE,
PARAM_CREATED_AT);
public static final String AGGREGATION_NAME_FOR_TAGS = "tags__issues";
private static final String SUBSTRING_MATCH_REGEXP = ".*%s.*";
@@ -522,6 +528,15 @@ public class IssueIndex {
if (options.getFacets().contains(PARAM_TYPES)) {
esSearch.addAggregation(stickyFacetBuilder.buildStickyFacet(IssueIndexDefinition.FIELD_ISSUE_TYPE, PARAM_TYPES, query.types().toArray()));
}
if (options.getFacets().contains(PARAM_OWASP_TOP_10)) {
esSearch.addAggregation(stickyFacetBuilder.buildStickyFacet(IssueIndexDefinition.FIELD_ISSUE_OWASP_TOP_10, PARAM_OWASP_TOP_10, query.owaspTop10().toArray()));
}
if (options.getFacets().contains(PARAM_SANS_TOP_25)) {
esSearch.addAggregation(stickyFacetBuilder.buildStickyFacet(IssueIndexDefinition.FIELD_ISSUE_SANS_TOP_25, PARAM_SANS_TOP_25, query.sansTop25().toArray()));
}
if (options.getFacets().contains(PARAM_CWE)) {
esSearch.addAggregation(stickyFacetBuilder.buildStickyFacet(IssueIndexDefinition.FIELD_ISSUE_CWE, PARAM_CWE, query.cwe().toArray()));
}
if (options.getFacets().contains(PARAM_RESOLUTIONS)) {
esSearch.addAggregation(createResolutionFacet(query, filters, esQuery));
}

+ 6
- 0
server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueIndexDefinition.java View File

@@ -92,6 +92,9 @@ public class IssueIndexDefinition implements IndexDefinition {
public static final String FIELD_ISSUE_STATUS = "status";
public static final String FIELD_ISSUE_TAGS = "tags";
public static final String FIELD_ISSUE_TYPE = "type";
public static final String FIELD_ISSUE_OWASP_TOP_10 = "owaspTop10";
public static final String FIELD_ISSUE_SANS_TOP_25 = "sansTop25";
public static final String FIELD_ISSUE_CWE = "cwe";

private final Configuration config;
private final boolean enableSource;
@@ -151,5 +154,8 @@ public class IssueIndexDefinition implements IndexDefinition {
type.keywordFieldBuilder(FIELD_ISSUE_STATUS).disableNorms().addSubFields(SORTABLE_ANALYZER).build();
type.keywordFieldBuilder(FIELD_ISSUE_TAGS).disableNorms().build();
type.keywordFieldBuilder(FIELD_ISSUE_TYPE).disableNorms().build();
type.keywordFieldBuilder(FIELD_ISSUE_OWASP_TOP_10).disableNorms().build();
type.keywordFieldBuilder(FIELD_ISSUE_SANS_TOP_25).disableNorms().build();
type.keywordFieldBuilder(FIELD_ISSUE_CWE).disableNorms().build();
}
}

+ 44
- 4
server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueIteratorForSingleChunk.java View File

@@ -21,13 +21,18 @@ package org.sonar.server.issue.index;

import com.google.common.base.CharMatcher;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterators;
import com.google.common.collect.Maps;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import javax.annotation.CheckForNull;
@@ -41,8 +46,14 @@ import org.sonar.db.DbSession;
import org.sonar.db.ResultSetIterator;

import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Arrays.asList;
import static java.util.stream.Collectors.toList;
import static org.sonar.api.utils.DateUtils.longToDate;
import static org.sonar.db.DatabaseUtils.getLong;
import static org.sonar.server.issue.ws.SearchAction.SANS_TOP_25_INSECURE_INTERACTION;
import static org.sonar.server.issue.ws.SearchAction.SANS_TOP_25_POROUS_DEFENSES;
import static org.sonar.server.issue.ws.SearchAction.SANS_TOP_25_RISKY_RESOURCE;
import static org.sonar.server.issue.ws.SearchAction.UNKNOWN_STANDARD;

/**
* Scrolls over table ISSUES and reads documents to populate
@@ -73,11 +84,12 @@ class IssueIteratorForSingleChunk implements IssueIterator {
"c.scope",
"c.organization_uuid",
"c.project_uuid",
"c.main_branch_project_uuid",

// column 21
"c.main_branch_project_uuid",
"i.tags",
"i.issue_type"
"i.issue_type",
"r.security_standards"
};

private static final String SQL_ALL = "select " + StringUtils.join(FIELDS, ",") + " from issues i " +
@@ -89,7 +101,19 @@ class IssueIteratorForSingleChunk implements IssueIterator {
private static final String ISSUE_KEY_FILTER_SUFFIX = ")";

static final Splitter TAGS_SPLITTER = Splitter.on(',').trimResults().omitEmptyStrings();
static final Splitter SECURITY_STANDARDS_SPLITTER = TAGS_SPLITTER;
static final Splitter MODULE_PATH_SPLITTER = Splitter.on('.').trimResults().omitEmptyStrings();
private static final String OWASP_TOP10_PREFIX = "owaspTop10:";
private static final String CWE_PREFIX = "cwe:";

// See https://www.sans.org/top25-software-errors
private static final Set<String> INSECURE_CWE = new HashSet<>(asList("89", "78", "79", "434", "352", "601"));
private static final Set<String> RISKY_CWE = new HashSet<>(asList("120", "22", "494", "829", "676", "131", "134", "190"));
private static final Set<String> POROUS_CWE = new HashSet<>(asList("306", "862", "798", "311", "807", "250", "863", "732", "327", "307", "759"));
private static final Map<String, Set<String>> SANS_TOP_25_CWE_MAPPING = ImmutableMap.of(
SANS_TOP_25_INSECURE_INTERACTION, INSECURE_CWE,
SANS_TOP_25_RISKY_RESOURCE, RISKY_CWE,
SANS_TOP_25_POROUS_DEFENSES, POROUS_CWE);

private final DbSession session;

@@ -223,11 +247,27 @@ class IssueIteratorForSingleChunk implements IssueIterator {
doc.setIsMainBranch(false);
}
String tags = rs.getString(21);
doc.setTags(ImmutableList.copyOf(IssueIteratorForSingleChunk.TAGS_SPLITTER.split(tags == null ? "" : tags)));
doc.setTags(IssueIteratorForSingleChunk.TAGS_SPLITTER.splitToList(tags == null ? "" : tags));
doc.setType(RuleType.valueOf(rs.getInt(22)));
String securityStandards = rs.getString(23);

List<String> standards = IssueIteratorForSingleChunk.SECURITY_STANDARDS_SPLITTER.splitToList(securityStandards == null ? "" : securityStandards);
List<String> owaspTop10 = standards.stream().filter(s -> s.startsWith(OWASP_TOP10_PREFIX)).map(s -> s.substring(OWASP_TOP10_PREFIX.length())).collect(toList());
doc.setOwaspTop10(owaspTop10.isEmpty() ? Collections.singletonList(UNKNOWN_STANDARD) : owaspTop10);
List<String> cwe = standards.stream().filter(s -> s.startsWith(CWE_PREFIX)).map(s -> s.substring(CWE_PREFIX.length())).collect(toList());
doc.setCwe(cwe.isEmpty() ? Collections.singletonList(UNKNOWN_STANDARD) : cwe);
doc.setSansTop25(getSansTop25(cwe));
return doc;
}

private static List<String> getSansTop25(List<String> cwe) {
return SANS_TOP_25_CWE_MAPPING
.keySet()
.stream()
.filter(k -> cwe.stream().anyMatch(SANS_TOP_25_CWE_MAPPING.get(k)::contains))
.collect(toList());
}

@CheckForNull
private static String extractDirPath(@Nullable String filePath, String scope) {
if (filePath != null) {

+ 12
- 0
server/sonar-server-common/src/test/java/org/sonar/server/issue/IssueQueryTest.java View File

@@ -52,6 +52,9 @@ public class IssueQueryTest {
.languages(newArrayList("xoo"))
.tags(newArrayList("tag1", "tag2"))
.types(newArrayList("RELIABILITY", "SECURITY"))
.owaspTop10(newArrayList("a1", "a2"))
.sansTop25(newArrayList("insecure-interaction", "porous-defenses"))
.cwe(newArrayList("12", "125"))
.organizationUuid("orga")
.branchUuid("my_branch")
.createdAfterByProjectUuids(ImmutableMap.of("PROJECT", filterDate))
@@ -74,6 +77,9 @@ public class IssueQueryTest {
assertThat(query.languages()).containsOnly("xoo");
assertThat(query.tags()).containsOnly("tag1", "tag2");
assertThat(query.types()).containsOnly("RELIABILITY", "SECURITY");
assertThat(query.owaspTop10()).containsOnly("a1", "a2");
assertThat(query.sansTop25()).containsOnly("insecure-interaction", "porous-defenses");
assertThat(query.cwe()).containsOnly("12", "125");
assertThat(query.organizationUuid()).isEqualTo("orga");
assertThat(query.branchUuid()).isEqualTo("my_branch");
assertThat(query.createdAfterByProjectUuids()).containsOnly(entry("PROJECT", filterDate));
@@ -128,6 +134,9 @@ public class IssueQueryTest {
.languages(null)
.tags(null)
.types(null)
.owaspTop10(null)
.sansTop25(null)
.cwe(null)
.createdAfterByProjectUuids(null)
.build();
assertThat(query.issueKeys()).isEmpty();
@@ -142,6 +151,9 @@ public class IssueQueryTest {
assertThat(query.languages()).isEmpty();
assertThat(query.tags()).isEmpty();
assertThat(query.types()).isEmpty();
assertThat(query.owaspTop10()).isEmpty();
assertThat(query.sansTop25()).isEmpty();
assertThat(query.cwe()).isEmpty();
assertThat(query.createdAfterByProjectUuids()).isEmpty();
}


+ 22
- 0
server/sonar-server-common/src/test/java/org/sonar/server/issue/index/IssueIndexerTest.java View File

@@ -22,6 +22,7 @@ package org.sonar.server.issue.index;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@@ -56,6 +57,8 @@ import static org.junit.rules.ExpectedException.none;
import static org.sonar.db.component.ComponentTesting.newFileDto;
import static org.sonar.server.issue.IssueDocTesting.newDoc;
import static org.sonar.server.issue.index.IssueIndexDefinition.INDEX_TYPE_ISSUE;
import static org.sonar.server.issue.ws.SearchAction.SANS_TOP_25_POROUS_DEFENSES;
import static org.sonar.server.issue.ws.SearchAction.UNKNOWN_STANDARD;
import static org.sonar.server.permission.index.AuthorizationTypeSupport.TYPE_AUTHORIZATION;

public class IssueIndexerTest {
@@ -134,6 +137,25 @@ public class IssueIndexerTest {
assertThat(doc.line()).isEqualTo(issue.getLine());
// functional date
assertThat(doc.updateDate()).isEqualToIgnoringMillis(new Date(issue.getIssueUpdateTime()));
assertThat(doc.getCwe()).containsExactlyInAnyOrder(UNKNOWN_STANDARD);
assertThat(doc.getOwaspTop10()).containsExactlyInAnyOrder(UNKNOWN_STANDARD);
assertThat(doc.getSansTop25()).isEmpty();
}

@Test
public void verify_security_standards_indexation() {
RuleDefinitionDto rule = db.rules().insert(r -> r.setSecurityStandards(new HashSet<>(Arrays.asList("cwe:123,owaspTop10:a3,cwe:863"))));
ComponentDto project = db.components().insertPrivateProject(organization);
ComponentDto dir = db.components().insertComponent(ComponentTesting.newDirectory(project, "src/main/java/foo"));
ComponentDto file = db.components().insertComponent(newFileDto(project, dir, "F1"));
IssueDto issue = db.issues().insertIssue(IssueTesting.newIssue(rule, project, file));

underTest.indexOnStartup(emptySet());

IssueDoc doc = es.getDocuments(INDEX_TYPE_ISSUE, IssueDoc.class).get(0);
assertThat(doc.getCwe()).containsExactlyInAnyOrder("123", "863");
assertThat(doc.getOwaspTop10()).containsExactlyInAnyOrder("a3");
assertThat(doc.getSansTop25()).containsExactlyInAnyOrder(SANS_TOP_25_POROUS_DEFENSES);
}

@Test

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

@@ -103,6 +103,7 @@ import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_CREATED_AFT
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_CREATED_AT;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_CREATED_BEFORE;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_CREATED_IN_LAST;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_CWE;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_DIRECTORIES;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_FILE_UUIDS;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_ISSUES;
@@ -110,6 +111,7 @@ import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_LANGUAGES;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_MODULE_UUIDS;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_ON_COMPONENT_ONLY;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_ORGANIZATION;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_OWASP_TOP_10;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_PLANNED;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_PROJECTS;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_PROJECT_KEYS;
@@ -119,6 +121,7 @@ import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_REPORTERS;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_RESOLUTIONS;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_RESOLVED;
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_SEVERITIES;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_SINCE_LEAK_PERIOD;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_STATUSES;
@@ -128,6 +131,10 @@ import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_TYPES;
public class SearchAction implements IssuesWsAction {

public static final String LOGIN_MYSELF = "__me__";
public static final String UNKNOWN_STANDARD = "unknown";
public static final String SANS_TOP_25_INSECURE_INTERACTION = "insecure-interaction";
public static final String SANS_TOP_25_RISKY_RESOURCE = "risky-resource";
public static final String SANS_TOP_25_POROUS_DEFENSES = "porous-defenses";

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> IGNORED_FACETS = newHashSet(PARAM_PLANNED, DEPRECATED_PARAM_ACTION_PLANS, PARAM_REPORTERS);
@@ -174,7 +181,8 @@ public class SearchAction implements IssuesWsAction {
new Change("5.5", "response field 'debt' is renamed 'effort'"),
new Change("7.2", "response field 'externalRuleEngine' added to issues that have been imported from an external rule engine"),
new Change("7.2", format("value '%s' in parameter '%s' is deprecated, it won't have any effect", SORT_BY_ASSIGNEE, Param.SORT)),
new Change("7.3", "response field 'fromHotspot' added to issues that are security hotspots"))
new Change("7.3", "response field 'fromHotspot' added to issues that are security hotspots"),
new Change("7.3", "added facets 'sansTop25', 'owaspTop10' and 'cwe'"))
.setResponseExample(getClass().getResource("search-example.json"));

action.addPagingParams(100, MAX_LIMIT);
@@ -223,6 +231,17 @@ public class SearchAction implements IssuesWsAction {
.setSince("5.5")
.setPossibleValues((Object[]) RuleType.values())
.setExampleValue(format("%s,%s", RuleType.CODE_SMELL, RuleType.BUG));
action.createParam(PARAM_OWASP_TOP_10)
.setDescription("Comma-separated list of OWASP Top 10 lowercase categories. Use '" + UNKNOWN_STANDARD + "' to select issues not associated to any OWASP Top 10 category.")
.setSince("7.3")
.setPossibleValues("a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "a10", UNKNOWN_STANDARD);
action.createParam(PARAM_SANS_TOP_25)
.setDescription("Comma-separated list of SANS Top 25 categories.")
.setSince("7.3")
.setPossibleValues(SANS_TOP_25_INSECURE_INTERACTION, SANS_TOP_25_RISKY_RESOURCE, SANS_TOP_25_POROUS_DEFENSES);
action.createParam(PARAM_CWE)
.setDescription("Comma-separated list of CWE identifiers. Use '" + UNKNOWN_STANDARD + "' to select issues not associated to any CWE.")
.setExampleValue("12,125," + UNKNOWN_STANDARD);
action.createParam(PARAM_AUTHORS)
.setDescription("Comma-separated list of SCM accounts")
.setExampleValue("torvalds@linux-foundation.org");
@@ -556,6 +575,9 @@ public class SearchAction implements IssuesWsAction {
addMandatoryValuesToFacet(facets, PARAM_LANGUAGES, request.getLanguages());
addMandatoryValuesToFacet(facets, PARAM_TAGS, request.getTags());
addMandatoryValuesToFacet(facets, PARAM_TYPES, RuleType.names());
addMandatoryValuesToFacet(facets, PARAM_OWASP_TOP_10, request.getOwaspTop10());
addMandatoryValuesToFacet(facets, PARAM_SANS_TOP_25, request.getSansTop25());
addMandatoryValuesToFacet(facets, PARAM_CWE, request.getCwe());
addMandatoryValuesToFacet(facets, PARAM_COMPONENT_UUIDS, request.getComponentUuids());

List<String> requestedFacets = request.getFacets();
@@ -655,6 +677,9 @@ public class SearchAction implements IssuesWsAction {
.setSeverities(request.paramAsStrings(PARAM_SEVERITIES))
.setStatuses(request.paramAsStrings(PARAM_STATUSES))
.setTags(request.paramAsStrings(PARAM_TAGS))
.setTypes(request.paramAsStrings(PARAM_TYPES));
.setTypes(request.paramAsStrings(PARAM_TYPES))
.setOwaspTop10(request.paramAsStrings(PARAM_OWASP_TOP_10))
.setSansTop25(request.paramAsStrings(PARAM_SANS_TOP_25))
.setCwe(request.paramAsStrings(PARAM_CWE));
}
}

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

@@ -148,7 +148,7 @@ public class SearchActionTest {
"pullRequest", "organization",
"createdAfter", "createdAt", "createdBefore", "createdInLast", "directories", "facetMode", "facets", "fileUuids", "issues", "languages", "moduleUuids", "onComponentOnly",
"p", "projectUuids", "projects", "ps", "resolutions", "resolved", "rules", "s", "severities", "sinceLeakPeriod",
"statuses", "tags", "types");
"statuses", "tags", "types", "owaspTop10", "sansTop25", "cwe");

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

+ 4
- 1
sonar-ws/src/main/java/org/sonarqube/ws/client/issue/IssuesWsParameters.java View File

@@ -99,6 +99,9 @@ public class IssuesWsParameters {
public static final String PARAM_LANGUAGES = "languages";
public static final String PARAM_TAGS = "tags";
public static final String PARAM_TYPES = "types";
public static final String PARAM_OWASP_TOP_10 = "owaspTop10";
public static final String PARAM_SANS_TOP_25 = "sansTop25";
public static final String PARAM_CWE = "cwe";
public static final String PARAM_ASSIGNED = "assigned";

/**
@@ -132,7 +135,7 @@ public class IssuesWsParameters {
public static final String FACET_ASSIGNED_TO_ME = "assigned_to_me";

public static final List<String> ALL = ImmutableList.of(PARAM_ISSUES, PARAM_SEVERITIES, PARAM_STATUSES, PARAM_RESOLUTIONS, PARAM_RESOLVED,
PARAM_COMPONENTS, PARAM_COMPONENT_ROOTS, PARAM_RULES, DEPRECATED_PARAM_ACTION_PLANS, PARAM_REPORTERS, PARAM_TAGS, PARAM_TYPES,
PARAM_COMPONENTS, PARAM_COMPONENT_ROOTS, PARAM_RULES, DEPRECATED_PARAM_ACTION_PLANS, PARAM_REPORTERS, PARAM_TAGS, PARAM_TYPES, PARAM_OWASP_TOP_10, PARAM_SANS_TOP_25, PARAM_CWE,
PARAM_ASSIGNEES, PARAM_LANGUAGES, PARAM_ASSIGNED, PARAM_PLANNED, PARAM_HIDE_RULES, PARAM_CREATED_AT, PARAM_CREATED_AFTER, PARAM_CREATED_BEFORE, PARAM_CREATED_IN_LAST,
PARAM_COMPONENT_UUIDS, PARAM_COMPONENT_ROOT_UUIDS, FACET_MODE,
PARAM_PROJECTS, PARAM_PROJECT_UUIDS, PARAM_PROJECT_KEYS, PARAM_COMPONENT_KEYS, PARAM_MODULE_UUIDS, PARAM_DIRECTORIES, PARAM_FILE_UUIDS, PARAM_AUTHORS,

Loading…
Cancel
Save