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;
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;
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;
}
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;
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;
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() {
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;
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;
+ }
+
}
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;
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.*";
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));
}
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;
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();
}
}
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;
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
"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 " +
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;
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) {
.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))
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));
.languages(null)
.tags(null)
.types(null)
+ .owaspTop10(null)
+ .sansTop25(null)
+ .cwe(null)
.createdAfterByProjectUuids(null)
.build();
assertThat(query.issueKeys()).isEmpty();
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();
}
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;
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 {
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
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;
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;
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;
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);
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);
.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");
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();
.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));
}
}
"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)
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";
/**
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,