浏览代码

SONAR-12717 refactor SecurityStandardHelper into SecurityStandards

and cleanup responsibility for parsing serialized tags and security standards into table RULES
tags/8.2.0.32929
Sébastien Lesaint 4 年前
父节点
当前提交
8c4a7402f8

+ 28
- 7
server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDefinitionDto.java 查看文件

@@ -19,11 +19,10 @@
*/
package org.sonar.db.rule;

import java.util.Arrays;
import java.util.HashSet;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableSet;
import java.util.Objects;
import java.util.Set;
import java.util.TreeSet;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.apache.commons.lang.StringUtils;
@@ -37,6 +36,8 @@ import static com.google.common.base.Preconditions.checkArgument;

public class RuleDefinitionDto {

private static final Splitter SPLITTER = Splitter.on(',').trimResults().omitEmptyStrings();

private Integer id;
private String repositoryKey;
private String ruleKey;
@@ -91,6 +92,26 @@ public class RuleDefinitionDto {
private long createdAt;
private long updatedAt;

public static Set<String> deserializeTagsString(@Nullable String tags) {
return deserializeStringSet(tags);
}

public static Set<String> deserializeSecurityStandardsString(@Nullable String securityStandards) {
return deserializeStringSet(securityStandards);
}

private static Set<String> deserializeStringSet(@Nullable String securityStandards) {
if (securityStandards == null || securityStandards.isEmpty()) {
return ImmutableSet.of();
}

return ImmutableSet.copyOf(SPLITTER.split(securityStandards));
}

private static String serializeStringSet(@Nullable Set<String> strings) {
return strings == null || strings.isEmpty() ? null : StringUtils.join(strings, ',');
}

public RuleKey getKey() {
if (key == null) {
key = RuleKey.of(getRepositoryKey(), getRuleKey());
@@ -300,7 +321,7 @@ public class RuleDefinitionDto {
}

public Set<String> getSystemTags() {
return systemTags == null ? new HashSet<>() : new TreeSet<>(Arrays.asList(StringUtils.split(systemTags, ',')));
return deserializeTagsString(systemTags);
}

private String getSystemTagsField() {
@@ -312,12 +333,12 @@ public class RuleDefinitionDto {
}

public RuleDefinitionDto setSystemTags(Set<String> tags) {
this.systemTags = tags.isEmpty() ? null : StringUtils.join(tags, ',');
this.systemTags = serializeStringSet(tags);
return this;
}

public Set<String> getSecurityStandards() {
return securityStandards == null ? new HashSet<>() : new TreeSet<>(Arrays.asList(StringUtils.split(securityStandards, ',')));
return deserializeSecurityStandardsString(securityStandards);
}

private String getSecurityStandardsField() {
@@ -329,7 +350,7 @@ public class RuleDefinitionDto {
}

public RuleDefinitionDto setSecurityStandards(Set<String> standards) {
this.securityStandards = standards.isEmpty() ? null : StringUtils.join(standards, ',');
this.securityStandards = serializeStringSet(standards);
return this;
}


+ 4
- 17
server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleForIndexingDto.java 查看文件

@@ -19,8 +19,6 @@
*/
package org.sonar.db.rule;

import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableSet;
import java.util.Set;
import javax.annotation.CheckForNull;
import org.sonar.api.rule.RuleKey;
@@ -49,9 +47,6 @@ public class RuleForIndexingDto {
private long createdAt;
private long updatedAt;

private static final Splitter TAGS_SPLITTER = Splitter.on(',').trimResults().omitEmptyStrings();
private static final Splitter SECURITY_STANDARDS_SPLITTER = TAGS_SPLITTER;

public Integer getId() {
return id;
}
@@ -88,12 +83,12 @@ public class RuleForIndexingDto {
return isTemplate;
}

public String getSystemTags() {
return systemTags;
public Set<String> getSystemTags() {
return RuleDefinitionDto.deserializeTagsString(systemTags);
}

public String getSecurityStandards() {
return securityStandards;
public Set<String> getSecurityStandards() {
return RuleDefinitionDto.deserializeSecurityStandardsString(securityStandards);
}

public String getTemplateRuleKey() {
@@ -140,12 +135,4 @@ public class RuleForIndexingDto {
public RuleKey getRuleKey() {
return RuleKey.of(repository, pluginRuleKey);
}

public Set<String> getSystemTagsAsSet() {
return ImmutableSet.copyOf(TAGS_SPLITTER.split(systemTags == null ? "" : systemTags));
}

public Set<String> getSecurityStandardsAsSet() {
return ImmutableSet.copyOf(SECURITY_STANDARDS_SPLITTER.split(securityStandards == null ? "" : securityStandards));
}
}

+ 4
- 4
server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDaoTest.java 查看文件

@@ -957,8 +957,8 @@ public class RuleDaoTest {
assertThat(firstRule.getStatus()).isEqualTo(r1.getStatus());
assertThat(firstRule.isExternal()).isFalse();
assertThat(firstRule.isTemplate()).isEqualTo(r1.isTemplate());
assertThat(firstRule.getSystemTagsAsSet()).isEqualTo(r1.getSystemTags());
assertThat(firstRule.getSecurityStandardsAsSet()).isEqualTo(r1.getSecurityStandards());
assertThat(firstRule.getSystemTags()).isEqualTo(r1.getSystemTags());
assertThat(firstRule.getSecurityStandards()).isEqualTo(r1.getSecurityStandards());
assertThat(firstRule.getTemplateRuleKey()).isNull();
assertThat(firstRule.getTemplateRepository()).isNull();
assertThat(firstRule.getInternalKey()).isEqualTo(r1.getConfigKey());
@@ -1036,8 +1036,8 @@ public class RuleDaoTest {
assertThat(firstRule.getSeverityAsString()).isEqualTo(SeverityUtil.getSeverityFromOrdinal(r1.getSeverity()));
assertThat(firstRule.getStatus()).isEqualTo(r1.getStatus());
assertThat(firstRule.isTemplate()).isEqualTo(r1.isTemplate());
assertThat(firstRule.getSystemTagsAsSet()).isEqualTo(r1.getSystemTags());
assertThat(firstRule.getSecurityStandardsAsSet()).isEqualTo(r1.getSecurityStandards());
assertThat(firstRule.getSystemTags()).isEqualTo(r1.getSystemTags());
assertThat(firstRule.getSecurityStandards()).isEqualTo(r1.getSecurityStandards());
assertThat(firstRule.getInternalKey()).isEqualTo(r1.getConfigKey());
assertThat(firstRule.getLanguage()).isEqualTo(r1.getLanguage());
assertThat(firstRule.getType()).isEqualTo(r1.getType());

+ 8
- 13
server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueIteratorForSingleChunk.java 查看文件

@@ -27,7 +27,6 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import javax.annotation.CheckForNull;
@@ -39,15 +38,13 @@ import org.sonar.db.DatabaseUtils;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.ResultSetIterator;
import org.sonar.server.security.SecurityStandards;

import static com.google.common.base.Preconditions.checkArgument;
import static org.sonar.api.utils.DateUtils.longToDate;
import static org.sonar.db.DatabaseUtils.getLong;
import static org.sonar.server.security.SecurityStandardHelper.getCwe;
import static org.sonar.server.security.SecurityStandardHelper.getOwaspTop10;
import static org.sonar.server.security.SecurityStandardHelper.getSansTop25;
import static org.sonar.server.security.SecurityStandardHelper.getSecurityStandards;
import static org.sonar.server.security.SecurityStandardHelper.getSonarSourceSecurityCategories;
import static org.sonar.db.rule.RuleDefinitionDto.deserializeSecurityStandardsString;
import static org.sonar.server.security.SecurityStandards.fromSecurityStandards;

/**
* Scrolls over table ISSUES and reads documents to populate
@@ -231,14 +228,12 @@ class IssueIteratorForSingleChunk implements IssueIterator {
String tags = rs.getString(21);
doc.setTags(IssueIteratorForSingleChunk.TAGS_SPLITTER.splitToList(tags == null ? "" : tags));
doc.setType(RuleType.valueOf(rs.getInt(22)));
String securityStandards = rs.getString(23);

List<String> standards = getSecurityStandards(securityStandards);
doc.setOwaspTop10(getOwaspTop10(standards));
List<String> cwe = getCwe(standards);
doc.setCwe(cwe);
doc.setSansTop25(getSansTop25(cwe));
doc.setSonarSourceSecurityCategories(getSonarSourceSecurityCategories(cwe));
SecurityStandards securityStandards = fromSecurityStandards(deserializeSecurityStandardsString(rs.getString(23)));
doc.setOwaspTop10(securityStandards.getOwaspTop10());
doc.setCwe(securityStandards.getCwe());
doc.setSansTop25(securityStandards.getSansTop25());
doc.setSonarSourceSecurityCategories(securityStandards.getSq());
return doc;
}


+ 6
- 6
server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleDoc.java 查看文件

@@ -35,7 +35,7 @@ import org.sonar.db.rule.RuleDto;
import org.sonar.db.rule.RuleForIndexingDto;
import org.sonar.markdown.Markdown;
import org.sonar.server.es.BaseDoc;
import org.sonar.server.security.SecurityStandardHelper;
import org.sonar.server.security.SecurityStandards;

import static org.sonar.server.rule.index.RuleIndexDefinition.TYPE_RULE;

@@ -268,7 +268,7 @@ public class RuleDoc extends BaseDoc {
}

public static RuleDoc of(RuleForIndexingDto dto) {
Collection<String> cwe = SecurityStandardHelper.getCwe(dto.getSecurityStandardsAsSet());
SecurityStandards securityStandards = SecurityStandards.fromSecurityStandards(dto.getSecurityStandards());
RuleDoc ruleDoc = new RuleDoc()
.setId(dto.getId())
.setKey(dto.getRuleKey().toString())
@@ -277,10 +277,10 @@ public class RuleDoc extends BaseDoc {
.setIsTemplate(dto.isTemplate())
.setIsExternal(dto.isExternal())
.setLanguage(dto.getLanguage())
.setCwe(cwe)
.setOwaspTop10(SecurityStandardHelper.getOwaspTop10(dto.getSecurityStandardsAsSet()))
.setSansTop25(SecurityStandardHelper.getSansTop25(cwe))
.setSonarSourceSecurityCategories(SecurityStandardHelper.getSonarSourceSecurityCategories(cwe))
.setCwe(securityStandards.getCwe())
.setOwaspTop10(securityStandards.getOwaspTop10())
.setSansTop25(securityStandards.getSansTop25())
.setSonarSourceSecurityCategories(securityStandards.getSq())
.setName(dto.getName())
.setRuleKey(dto.getPluginRuleKey())
.setSeverity(dto.getSeverityAsString())

+ 1
- 1
server/sonar-server-common/src/main/java/org/sonar/server/rule/index/RuleExtensionDoc.java 查看文件

@@ -81,7 +81,7 @@ public class RuleExtensionDoc extends BaseDoc {
return new RuleExtensionDoc()
.setRuleId(rule.getId())
.setScope(RuleExtensionScope.system())
.setTags(rule.getSystemTagsAsSet());
.setTags(rule.getSystemTags());
}

public static RuleExtensionDoc of(RuleExtensionForIndexingDto rule) {

server/sonar-server-common/src/main/java/org/sonar/server/security/SecurityStandardHelper.java → server/sonar-server-common/src/main/java/org/sonar/server/security/SecurityStandards.java 查看文件

@@ -19,24 +19,23 @@
*/
package org.sonar.server.security;

import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Ordering;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
import org.sonar.core.util.stream.MoreCollectors;

import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
import static java.util.stream.Collectors.toList;
import static java.util.Collections.singleton;

public class SecurityStandardHelper {
@Immutable
public final class SecurityStandards {

public static final String UNKNOWN_STANDARD = "unknown";
public static final String SANS_TOP_25_INSECURE_INTERACTION = "insecure-interaction";
@@ -49,12 +48,12 @@ public class SecurityStandardHelper {
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"));
public static final Map<String, Set<String>> SANS_TOP_25_CWE_MAPPING = ImmutableMap.of(
public static final Map<String, Set<String>> CWES_BY_SANS_TOP_25 = ImmutableMap.of(
SANS_TOP_25_INSECURE_INTERACTION, INSECURE_CWE,
SANS_TOP_25_RISKY_RESOURCE, RISKY_CWE,
SANS_TOP_25_POROUS_DEFENSES, POROUS_CWE);

public static final Map<String, Set<String>> SONARSOURCE_CWE_MAPPING = ImmutableMap.<String, Set<String>>builder()
public static final Map<String, Set<String>> CWES_BY_SQ_CATEGORY = ImmutableMap.<String, Set<String>>builder()
.put("sql-injection", ImmutableSet.of("89", "564"))
.put("command-injection", ImmutableSet.of("77", "78", "88", "214"))
.put("path-traversal-injection", ImmutableSet.of("22"))
@@ -75,65 +74,85 @@ public class SecurityStandardHelper {
.put("insecure-conf", ImmutableSet.of("102", "215", "311", "315", "346", "614", "489", "942"))
.put("file-manipulation", ImmutableSet.of("97", "73"))
.build();
public static final String SONARSOURCE_OTHER_CWES_CATEGORY = "others";
public static final Ordering<String> SONARSOURCE_CATEGORY_ORDERING = Ordering.explicit(
ImmutableList.<String>builder().addAll(SONARSOURCE_CWE_MAPPING.keySet()).add(SONARSOURCE_OTHER_CWES_CATEGORY).build());
public static final String SQ_OTHER_CATEGORY = "others";
public static final Set<String> SQ_CATEGORIES = ImmutableSet.<String>builder().addAll(CWES_BY_SQ_CATEGORY.keySet()).add(SQ_OTHER_CATEGORY).build();
public static final Ordering<String> SQ_CATEGORIES_ORDERING = Ordering.explicit(
ImmutableList.<String>builder().addAll(CWES_BY_SQ_CATEGORY.keySet()).add(SQ_OTHER_CATEGORY).build());

private final Set<String> standards;
private final Set<String> cwe;
private final Set<String> owaspTop10;
private final Set<String> sansTop25;
private final Set<String> sq;

private SecurityStandards(Set<String> standards, Set<String> cwe, Set<String> owaspTop10, Set<String> sansTop25, Set<String> sq) {
this.standards = standards;
this.cwe = cwe;
this.owaspTop10 = owaspTop10;
this.sansTop25 = sansTop25;
this.sq = sq;
}

private static final Splitter SECURITY_STANDARDS_SPLITTER = Splitter.on(',').trimResults().omitEmptyStrings();
public Set<String> getStandards() {
return standards;
}

private SecurityStandardHelper() {
// Utility class
public Set<String> getCwe() {
return cwe;
}

public static List<String> getSecurityStandards(@Nullable String securityStandards) {
return securityStandards == null ? emptyList() : SECURITY_STANDARDS_SPLITTER.splitToList(securityStandards);
public Set<String> getOwaspTop10() {
return owaspTop10;
}

public static List<String> getSansTop25(Collection<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());
public Set<String> getSansTop25() {
return sansTop25;
}

public static List<String> getSonarSourceSecurityCategories(Collection<String> cwe) {
List<String> result = SONARSOURCE_CWE_MAPPING
.keySet()
.stream()
.filter(k -> cwe.stream().anyMatch(SONARSOURCE_CWE_MAPPING.get(k)::contains))
.collect(toList());
return result.isEmpty() ? singletonList(SONARSOURCE_OTHER_CWES_CATEGORY) : result;
public Set<String> getSq() {
return sq;
}

public static SecurityStandards fromSecurityStandards(Set<String> securityStandards) {
Set<String> standards = securityStandards.stream()
.filter(Objects::nonNull)
.collect(MoreCollectors.toSet());
Set<String> owaspTop10 = toOwaspTop10(standards);
Set<String> cwe = toCwe(standards);
Set<String> sansTop25 = toSansTop25(cwe);
Set<String> sq = toSonarSourceSecurityCategories(cwe);
return new SecurityStandards(standards, cwe, owaspTop10, sansTop25, sq);
}

public static List<String> getOwaspTop10(Collection<String> securityStandards) {
private static Set<String> toOwaspTop10(Set<String> securityStandards) {
return securityStandards.stream()
.filter(s -> s.startsWith(OWASP_TOP10_PREFIX))
.map(s -> s.substring(OWASP_TOP10_PREFIX.length()))
.collect(toList());
.collect(MoreCollectors.toSet());
}

public static List<String> getCwe(Collection<String> securityStandards) {
List<String> result = securityStandards.stream()
private static Set<String> toCwe(Collection<String> securityStandards) {
Set<String> result = securityStandards.stream()
.filter(s -> s.startsWith(CWE_PREFIX))
.map(s -> s.substring(CWE_PREFIX.length()))
.collect(toList());
return result.isEmpty() ? singletonList(UNKNOWN_STANDARD) : result;
.collect(MoreCollectors.toSet());
return result.isEmpty() ? singleton(UNKNOWN_STANDARD) : result;
}

public static List<String> getSansTop25(String securityStandards) {
return getSansTop25(getCwe(getSecurityStandards(securityStandards)));
}

public static List<String> getSonarSourceSecurityCategories(String securityStandards) {
return getSonarSourceSecurityCategories(getCwe(getSecurityStandards(securityStandards)));
}

public static List<String> getOwaspTop10(String securityStandards) {
return getOwaspTop10(getSecurityStandards(securityStandards));
private static Set<String> toSansTop25(Collection<String> cwe) {
return CWES_BY_SANS_TOP_25
.keySet()
.stream()
.filter(k -> cwe.stream().anyMatch(CWES_BY_SANS_TOP_25.get(k)::contains))
.collect(MoreCollectors.toSet());
}

public static List<String> getCwe(String securityStandards) {
return getCwe(getSecurityStandards(securityStandards));
private static Set<String> toSonarSourceSecurityCategories(Collection<String> cwe) {
Set<String> result = CWES_BY_SQ_CATEGORY
.keySet()
.stream()
.filter(k -> cwe.stream().anyMatch(CWES_BY_SQ_CATEGORY.get(k)::contains))
.collect(MoreCollectors.toSet());
return result.isEmpty() ? singleton(SQ_OTHER_CATEGORY) : result;
}
}

+ 4
- 5
server/sonar-server-common/src/test/java/org/sonar/server/issue/index/IssueIndexerTest.java 查看文件

@@ -48,6 +48,7 @@ import org.sonar.server.es.IndexingResult;
import org.sonar.server.es.ProjectIndexer;
import org.sonar.server.permission.index.AuthorizationScope;
import org.sonar.server.permission.index.IndexPermissions;
import org.sonar.server.security.SecurityStandards;

import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
@@ -57,10 +58,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.TYPE_ISSUE;
import static org.sonar.server.security.SecurityStandardHelper.SANS_TOP_25_POROUS_DEFENSES;
import static org.sonar.server.security.SecurityStandardHelper.SONARSOURCE_OTHER_CWES_CATEGORY;
import static org.sonar.server.security.SecurityStandardHelper.UNKNOWN_STANDARD;
import static org.sonar.server.permission.index.IndexAuthorizationConstants.TYPE_AUTHORIZATION;
import static org.sonar.server.security.SecurityStandards.SANS_TOP_25_POROUS_DEFENSES;

public class IssueIndexerTest {

@@ -136,10 +135,10 @@ 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.getCwe()).containsExactlyInAnyOrder(SecurityStandards.UNKNOWN_STANDARD);
assertThat(doc.getOwaspTop10()).isEmpty();
assertThat(doc.getSansTop25()).isEmpty();
assertThat(doc.getSonarSourceSecurityCategories()).containsExactlyInAnyOrder(SONARSOURCE_OTHER_CWES_CATEGORY);
assertThat(doc.getSonarSourceSecurityCategories()).containsOnly(SecurityStandards.SQ_OTHER_CATEGORY);
}

@Test

+ 2
- 2
server/sonar-server-common/src/test/java/org/sonar/server/rule/index/RuleIndexTest.java 查看文件

@@ -86,8 +86,8 @@ import static org.sonar.server.rule.index.RuleIndex.FACET_TYPES;
import static org.sonar.server.rule.index.RuleIndexDefinition.TYPE_ACTIVE_RULE;
import static org.sonar.server.rule.index.RuleIndexDefinition.TYPE_RULE;
import static org.sonar.server.rule.index.RuleIndexDefinition.TYPE_RULE_EXTENSION;
import static org.sonar.server.security.SecurityStandardHelper.SANS_TOP_25_INSECURE_INTERACTION;
import static org.sonar.server.security.SecurityStandardHelper.SANS_TOP_25_RISKY_RESOURCE;
import static org.sonar.server.security.SecurityStandards.SANS_TOP_25_INSECURE_INTERACTION;
import static org.sonar.server.security.SecurityStandards.SANS_TOP_25_RISKY_RESOURCE;

public class RuleIndexTest {


+ 8
- 10
server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueIndex.java 查看文件

@@ -82,6 +82,7 @@ import org.sonar.server.es.StickyFacetBuilder;
import org.sonar.server.issue.index.IssueQuery.PeriodStart;
import org.sonar.server.permission.index.AuthorizationDoc;
import org.sonar.server.permission.index.WebAuthorizationTypeSupport;
import org.sonar.server.security.SecurityStandards;
import org.sonar.server.user.UserSession;
import org.sonar.server.view.index.ViewIndexDefinition;

@@ -152,12 +153,10 @@ import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_ISSUE_STAT
import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_ISSUE_TAGS;
import static org.sonar.server.issue.index.IssueIndexDefinition.FIELD_ISSUE_TYPE;
import static org.sonar.server.issue.index.IssueIndexDefinition.TYPE_ISSUE;
import static org.sonar.server.security.SecurityStandardHelper.SANS_TOP_25_CWE_MAPPING;
import static org.sonar.server.security.SecurityStandardHelper.SANS_TOP_25_INSECURE_INTERACTION;
import static org.sonar.server.security.SecurityStandardHelper.SANS_TOP_25_POROUS_DEFENSES;
import static org.sonar.server.security.SecurityStandardHelper.SANS_TOP_25_RISKY_RESOURCE;
import static org.sonar.server.security.SecurityStandardHelper.SONARSOURCE_CWE_MAPPING;
import static org.sonar.server.security.SecurityStandardHelper.SONARSOURCE_OTHER_CWES_CATEGORY;
import static org.sonar.server.security.SecurityStandards.SANS_TOP_25_INSECURE_INTERACTION;
import static org.sonar.server.security.SecurityStandards.SANS_TOP_25_POROUS_DEFENSES;
import static org.sonar.server.security.SecurityStandards.SANS_TOP_25_RISKY_RESOURCE;
import static org.sonar.server.security.SecurityStandards.SQ_CATEGORIES;
import static org.sonar.server.view.index.ViewIndexDefinition.TYPE_VIEW;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.DEPRECATED_PARAM_AUTHORS;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.FACET_MODE_EFFORT;
@@ -874,15 +873,14 @@ public class IssueIndex {
public List<SecurityStandardCategoryStatistics> getSansTop25Report(String projectUuid, boolean isViewOrApp, boolean includeCwe) {
SearchRequestBuilder request = prepareNonClosedVulnerabilitiesAndHotspotSearch(projectUuid, isViewOrApp);
Stream.of(SANS_TOP_25_INSECURE_INTERACTION, SANS_TOP_25_RISKY_RESOURCE, SANS_TOP_25_POROUS_DEFENSES)
.forEach(sansCategory -> request.addAggregation(createAggregation(FIELD_ISSUE_SANS_TOP_25, sansCategory, includeCwe, Optional.of(SANS_TOP_25_CWE_MAPPING))));
.forEach(sansCategory -> request.addAggregation(createAggregation(FIELD_ISSUE_SANS_TOP_25, sansCategory, includeCwe, Optional.of(SecurityStandards.CWES_BY_SANS_TOP_25))));
return processSecurityReportSearchResults(request, includeCwe);
}

public List<SecurityStandardCategoryStatistics> getSonarSourceReport(String projectUuid, boolean isViewOrApp, boolean includeCwe) {
SearchRequestBuilder request = prepareNonClosedVulnerabilitiesAndHotspotSearch(projectUuid, isViewOrApp);
Stream.concat(SONARSOURCE_CWE_MAPPING.keySet().stream(), Stream.of(SONARSOURCE_OTHER_CWES_CATEGORY))
.forEach(sonarsourceCategory -> request.addAggregation(
createAggregation(FIELD_ISSUE_SONARSOURCE_SECURITY, sonarsourceCategory, includeCwe, Optional.of(SONARSOURCE_CWE_MAPPING))));
SQ_CATEGORIES.forEach(sonarsourceCategory -> request.addAggregation(
createAggregation(FIELD_ISSUE_SONARSOURCE_SECURITY, sonarsourceCategory, includeCwe, Optional.of(SecurityStandards.CWES_BY_SQ_CATEGORY))));
return processSecurityReportSearchResults(request, includeCwe);
}


+ 4
- 4
server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueIndexSecurityReportsTest.java 查看文件

@@ -54,10 +54,10 @@ import static org.sonar.api.resources.Qualifiers.PROJECT;
import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto;
import static org.sonar.db.organization.OrganizationTesting.newOrganizationDto;
import static org.sonar.server.issue.IssueDocTesting.newDoc;
import static org.sonar.server.security.SecurityStandardHelper.SANS_TOP_25_INSECURE_INTERACTION;
import static org.sonar.server.security.SecurityStandardHelper.SANS_TOP_25_POROUS_DEFENSES;
import static org.sonar.server.security.SecurityStandardHelper.SANS_TOP_25_RISKY_RESOURCE;
import static org.sonar.server.security.SecurityStandardHelper.UNKNOWN_STANDARD;
import static org.sonar.server.security.SecurityStandards.SANS_TOP_25_INSECURE_INTERACTION;
import static org.sonar.server.security.SecurityStandards.SANS_TOP_25_POROUS_DEFENSES;
import static org.sonar.server.security.SecurityStandards.SANS_TOP_25_RISKY_RESOURCE;
import static org.sonar.server.security.SecurityStandards.UNKNOWN_STANDARD;

public class IssueIndexSecurityReportsTest {


+ 8
- 8
server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SearchAction.java 查看文件

@@ -54,6 +54,7 @@ import org.sonar.server.issue.SearchRequest;
import org.sonar.server.issue.index.IssueIndex;
import org.sonar.server.issue.index.IssueQuery;
import org.sonar.server.issue.index.IssueQueryFactory;
import org.sonar.server.security.SecurityStandards;
import org.sonar.server.user.UserSession;
import org.sonarqube.ws.Issues.SearchWsResponse;

@@ -84,12 +85,11 @@ import static org.sonar.server.issue.index.IssueIndex.FACET_ASSIGNED_TO_ME;
import static org.sonar.server.issue.index.IssueIndex.FACET_PROJECTS;
import static org.sonar.server.issue.index.IssueQuery.SORT_BY_ASSIGNEE;
import static org.sonar.server.issue.index.IssueQueryFactory.UNKNOWN;
import static org.sonar.server.security.SecurityStandardHelper.SANS_TOP_25_INSECURE_INTERACTION;
import static org.sonar.server.security.SecurityStandardHelper.SANS_TOP_25_POROUS_DEFENSES;
import static org.sonar.server.security.SecurityStandardHelper.SANS_TOP_25_RISKY_RESOURCE;
import static org.sonar.server.security.SecurityStandardHelper.SONARSOURCE_CWE_MAPPING;
import static org.sonar.server.security.SecurityStandardHelper.SONARSOURCE_OTHER_CWES_CATEGORY;
import static org.sonar.server.security.SecurityStandardHelper.UNKNOWN_STANDARD;
import static org.sonar.server.security.SecurityStandards.SANS_TOP_25_INSECURE_INTERACTION;
import static org.sonar.server.security.SecurityStandards.SANS_TOP_25_POROUS_DEFENSES;
import static org.sonar.server.security.SecurityStandards.SANS_TOP_25_RISKY_RESOURCE;
import static org.sonar.server.security.SecurityStandards.SQ_OTHER_CATEGORY;
import static org.sonar.server.security.SecurityStandards.UNKNOWN_STANDARD;
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_PULL_REQUEST_EXAMPLE_001;
@@ -273,10 +273,10 @@ public class SearchAction implements IssuesWsAction, Startable {
.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_SONARSOURCE_SECURITY)
.setDescription("Comma-separated list of SonarSource security categories. Use '" + SONARSOURCE_OTHER_CWES_CATEGORY + "' to select issues not associated" +
.setDescription("Comma-separated list of SonarSource security categories. Use '" + SQ_OTHER_CATEGORY + "' to select issues not associated" +
" with any category")
.setSince("7.8")
.setPossibleValues(ImmutableList.builder().addAll(SONARSOURCE_CWE_MAPPING.keySet()).add(SONARSOURCE_OTHER_CWES_CATEGORY).build());
.setPossibleValues(SecurityStandards.SQ_CATEGORIES);
action.createParam(DEPRECATED_PARAM_AUTHORS)
.setDeprecatedSince("7.7")
.setDescription("This parameter is deprecated, please use '%s' instead", PARAM_AUTHOR)

+ 8
- 11
server/sonar-webserver-webapi/src/main/java/org/sonar/server/rule/ws/RuleWsSupport.java 查看文件

@@ -19,7 +19,6 @@
*/
package org.sonar.server.rule.ws;

import com.google.common.collect.ImmutableList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -39,6 +38,7 @@ import org.sonar.db.user.UserDto;
import org.sonar.server.organization.DefaultOrganizationProvider;
import org.sonar.server.qualityprofile.ActiveRuleInheritance;
import org.sonar.server.rule.index.RuleIndexDefinition;
import org.sonar.server.security.SecurityStandards;
import org.sonar.server.user.UserSession;

import static org.sonar.api.server.ws.WebService.Param.ASCENDING;
@@ -50,6 +50,7 @@ import static org.sonar.core.util.stream.MoreCollectors.toSet;
import static org.sonar.core.util.stream.MoreCollectors.uniqueIndex;
import static org.sonar.db.organization.OrganizationDto.Subscription.PAID;
import static org.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_PROFILES;
import static org.sonar.server.exceptions.NotFoundException.checkFoundWithOptional;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_ACTIVATION;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_ACTIVE_SEVERITIES;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_AVAILABLE_SINCE;
@@ -71,11 +72,7 @@ import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_STATUSES;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_TAGS;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_TEMPLATE_KEY;
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_TYPES;
import static org.sonar.server.security.SecurityStandardHelper.SANS_TOP_25_CWE_MAPPING;
import static org.sonar.server.security.SecurityStandardHelper.SONARSOURCE_CWE_MAPPING;
import static org.sonar.server.security.SecurityStandardHelper.SONARSOURCE_OTHER_CWES_CATEGORY;
import static org.sonar.server.security.SecurityStandardHelper.UNKNOWN_STANDARD;
import static org.sonar.server.exceptions.NotFoundException.checkFoundWithOptional;
import static org.sonar.server.security.SecurityStandards.SQ_OTHER_CATEGORY;

@ServerSide
public class RuleWsSupport {
@@ -141,8 +138,8 @@ public class RuleWsSupport {

action
.createParam(PARAM_CWE)
.setDescription("Comma-separated list of CWE identifiers. Use '" + UNKNOWN_STANDARD + "' to select rules not associated to any CWE.")
.setExampleValue("12,125," + UNKNOWN_STANDARD);
.setDescription("Comma-separated list of CWE identifiers. Use '" + SecurityStandards.UNKNOWN_STANDARD + "' to select rules not associated to any CWE.")
.setExampleValue("12,125," + SecurityStandards.UNKNOWN_STANDARD);

action.createParam(PARAM_OWASP_TOP_10)
.setDescription("Comma-separated list of OWASP Top 10 lowercase categories.")
@@ -152,14 +149,14 @@ public class RuleWsSupport {
action.createParam(PARAM_SANS_TOP_25)
.setDescription("Comma-separated list of SANS Top 25 categories.")
.setSince("7.3")
.setPossibleValues(SANS_TOP_25_CWE_MAPPING.keySet());
.setPossibleValues(SecurityStandards.CWES_BY_SANS_TOP_25.keySet());

action
.createParam(PARAM_SONARSOURCE_SECURITY)
.setDescription("Comma-separated list of SonarSource security categories. Use '" + SONARSOURCE_OTHER_CWES_CATEGORY + "' to select rules not associated" +
.setDescription("Comma-separated list of SonarSource security categories. Use '" + SQ_OTHER_CATEGORY + "' to select rules not associated" +
" with any category")
.setSince("7.8")
.setPossibleValues(ImmutableList.builder().addAll(SONARSOURCE_CWE_MAPPING.keySet()).add(SONARSOURCE_OTHER_CWES_CATEGORY).build())
.setPossibleValues(SecurityStandards.SQ_CATEGORIES)
.setExampleValue("sql-injection,command-injection,others");

action

正在加载...
取消
保存