]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-11370 Extract Owasp, SansTop25 constant to a dedicated helper
authorEric Hartmann <hartmann.eric@gmail.com>
Fri, 19 Oct 2018 08:49:04 +0000 (10:49 +0200)
committerSonarTech <sonartech@sonarsource.com>
Thu, 25 Oct 2018 18:21:01 +0000 (20:21 +0200)
server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueIndexDefinition.java
server/sonar-server-common/src/main/java/org/sonar/server/issue/index/IssueIteratorForSingleChunk.java
server/sonar-server-common/src/main/java/org/sonar/server/issue/index/SecurityStandardCategoryStatistics.java
server/sonar-server-common/src/main/java/org/sonar/server/issue/index/SecurityStandardHelper.java [new file with mode: 0644]
server/sonar-server-common/src/test/java/org/sonar/server/issue/index/IssueIndexerTest.java
server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndex.java
server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAction.java
server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexSecurityReportsTest.java

index d6e49f49a511f29539353afb6d8e706e132a790b..dd13a01395a0098946d5b708f14b15eb3c9edfe4 100644 (file)
  */
 package org.sonar.server.issue.index;
 
-import com.google.common.collect.ImmutableMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
 import org.sonar.api.config.Configuration;
 import org.sonar.api.config.internal.MapSettings;
 import org.sonar.server.es.IndexDefinition;
 import org.sonar.server.es.IndexType;
 import org.sonar.server.es.NewIndex;
 
-import static java.util.Arrays.asList;
 import static org.sonar.server.es.DefaultIndexSettingsElement.SORTABLE_ANALYZER;
 import static org.sonar.server.es.NewIndex.SettingsConfiguration.MANUAL_REFRESH_INTERVAL;
 import static org.sonar.server.es.NewIndex.SettingsConfiguration.newBuilder;
@@ -100,18 +95,6 @@ public class IssueIndexDefinition implements IndexDefinition {
   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";
-  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";
-  // 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"));
-  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 Configuration config;
   private final boolean enableSource;
index eafd2aed3b00a083e31168f06d7bf9657a825c98..d62bf23e60995b5259f4d615ab5458ba9a3e10c8 100644 (file)
@@ -27,7 +27,6 @@ import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.List;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
@@ -42,11 +41,12 @@ import org.sonar.db.DbSession;
 import org.sonar.db.ResultSetIterator;
 
 import static com.google.common.base.Preconditions.checkArgument;
-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.index.IssueIndexDefinition.SANS_TOP_25_CWE_MAPPING;
-import static org.sonar.server.issue.index.IssueIndexDefinition.UNKNOWN_STANDARD;
+import static org.sonar.server.issue.index.SecurityStandardHelper.getCwe;
+import static org.sonar.server.issue.index.SecurityStandardHelper.getOwaspTop10;
+import static org.sonar.server.issue.index.SecurityStandardHelper.getSansTop25;
+import static org.sonar.server.issue.index.SecurityStandardHelper.getSecurityStandards;
 
 /**
  * Scrolls over table ISSUES and reads documents to populate
@@ -94,10 +94,7 @@ 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:";
 
   private final DbSession session;
 
@@ -235,23 +232,14 @@ class IssueIteratorForSingleChunk implements IssueIterator {
       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);
+      List<String> standards = getSecurityStandards(securityStandards);
+      doc.setOwaspTop10(getOwaspTop10(standards));
+      List<String> cwe = getCwe(standards);
+      doc.setCwe(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) {
index 291c394bd7de48c814537a963cc2bce13dc530c3..de2bdd983be40a288d572a440325fd8c58c1535c 100644 (file)
@@ -32,6 +32,8 @@ public class SecurityStandardCategoryStatistics {
   private final long openSecurityHotspots;
   private final long wontFixSecurityHotspots;
   private final List<SecurityStandardCategoryStatistics> children;
+  private long activeRules;
+  private long totalRules;
 
   public SecurityStandardCategoryStatistics(String category, long vulnerabilities, OptionalInt vulnerabiliyRating, long toReviewSecurityHotspots, long openSecurityHotspots,
     long wontFixSecurityHotspots, @Nullable List<SecurityStandardCategoryStatistics> children) {
@@ -71,4 +73,22 @@ public class SecurityStandardCategoryStatistics {
   public List<SecurityStandardCategoryStatistics> getChildren() {
     return children;
   }
+
+  public long getActiveRules() {
+    return activeRules;
+  }
+
+  public long getTotalRules() {
+    return totalRules;
+  }
+
+  public SecurityStandardCategoryStatistics setActiveRules(long activeRules) {
+    this.activeRules = activeRules;
+    return this;
+  }
+
+  public SecurityStandardCategoryStatistics setTotalRules(long totalRules) {
+    this.totalRules = totalRules;
+    return this;
+  }
 }
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/SecurityStandardHelper.java b/server/sonar-server-common/src/main/java/org/sonar/server/issue/index/SecurityStandardHelper.java
new file mode 100644 (file)
index 0000000..cdae44c
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.server.issue.index;
+
+import com.google.common.base.Splitter;
+import com.google.common.collect.ImmutableMap;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.annotation.Nullable;
+
+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;
+
+public class SecurityStandardHelper {
+
+  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 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"));
+
+  public 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 static final Splitter SECURITY_STANDARDS_SPLITTER = Splitter.on(',').trimResults().omitEmptyStrings();
+
+  private SecurityStandardHelper() {
+    // Utility class
+  }
+
+  public static List<String> getSecurityStandards(@Nullable String securityStandards) {
+    return securityStandards == null ? emptyList() : SECURITY_STANDARDS_SPLITTER.splitToList(securityStandards);
+  }
+
+  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 static List<String> getOwaspTop10(Collection<String> securityStandards) {
+    List<String> result = securityStandards.stream()
+      .filter(s -> s.startsWith(OWASP_TOP10_PREFIX))
+      .map(s -> s.substring(OWASP_TOP10_PREFIX.length()))
+      .collect(toList());
+    return result.isEmpty() ? singletonList(UNKNOWN_STANDARD) : result;
+  }
+
+  public static List<String> getCwe(Collection<String> securityStandards) {
+    List<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;
+  }
+
+  public static List<String> getSansTop25(String securityStandards) {
+    return getSansTop25(getCwe(getSecurityStandards(securityStandards)));
+  }
+
+  public static List<String> getOwaspTop10(String securityStandards) {
+    return getOwaspTop10(getSecurityStandards(securityStandards));
+  }
+
+  public static List<String> getCwe(String securityStandards) {
+    return getCwe(getSecurityStandards(securityStandards));
+  }
+}
index 3c793a28e6ee9991d5e950c670c1349ef9a287d6..7f370f15c1627017c72f33f8f3c70284f0bd780b 100644 (file)
@@ -57,8 +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.index.IssueIndexDefinition.SANS_TOP_25_POROUS_DEFENSES;
-import static org.sonar.server.issue.index.IssueIndexDefinition.UNKNOWN_STANDARD;
+import static org.sonar.server.issue.index.SecurityStandardHelper.SANS_TOP_25_POROUS_DEFENSES;
+import static org.sonar.server.issue.index.SecurityStandardHelper.UNKNOWN_STANDARD;
 import static org.sonar.server.permission.index.IndexAuthorizationConstants.TYPE_AUTHORIZATION;
 
 public class IssueIndexerTest {
index 7370d306fba2b569153e0f000d0cebd702d34c1c..e2aee03ac5722f5d63ae7782bac806d0dcbd123c 100644 (file)
@@ -143,10 +143,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.INDEX_TYPE_ISSUE;
-import static org.sonar.server.issue.index.IssueIndexDefinition.SANS_TOP_25_INSECURE_INTERACTION;
-import static org.sonar.server.issue.index.IssueIndexDefinition.SANS_TOP_25_POROUS_DEFENSES;
-import static org.sonar.server.issue.index.IssueIndexDefinition.SANS_TOP_25_RISKY_RESOURCE;
-import static org.sonar.server.issue.index.IssueIndexDefinition.UNKNOWN_STANDARD;
+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_RISKY_RESOURCE;
+import static org.sonar.server.issue.index.SecurityStandardHelper.UNKNOWN_STANDARD;
 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;
index cdac6357f14e45f6bf7924625c7cf0150947044b..147b9aab680eb407f79553492459b713d5f5406d 100644 (file)
@@ -73,10 +73,10 @@ import static org.sonar.process.ProcessProperties.Property.SONARCLOUD_ENABLED;
 import static org.sonar.server.es.SearchOptions.MAX_LIMIT;
 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.IssueIndexDefinition.SANS_TOP_25_INSECURE_INTERACTION;
-import static org.sonar.server.issue.index.IssueIndexDefinition.SANS_TOP_25_POROUS_DEFENSES;
-import static org.sonar.server.issue.index.IssueIndexDefinition.SANS_TOP_25_RISKY_RESOURCE;
-import static org.sonar.server.issue.index.IssueIndexDefinition.UNKNOWN_STANDARD;
+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_RISKY_RESOURCE;
+import static org.sonar.server.issue.index.SecurityStandardHelper.UNKNOWN_STANDARD;
 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.ws.KeyExamples.KEY_BRANCH_EXAMPLE_001;
index 1aa86d13e5a94da2ecb7bc91df36602494921ea0..8dcd90ce6b8888637263e788b95393cc1dd57dd5 100644 (file)
@@ -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.issue.index.IssueIndexDefinition.SANS_TOP_25_INSECURE_INTERACTION;
-import static org.sonar.server.issue.index.IssueIndexDefinition.SANS_TOP_25_POROUS_DEFENSES;
-import static org.sonar.server.issue.index.IssueIndexDefinition.SANS_TOP_25_RISKY_RESOURCE;
-import static org.sonar.server.issue.index.IssueIndexDefinition.UNKNOWN_STANDARD;
+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_RISKY_RESOURCE;
+import static org.sonar.server.issue.index.SecurityStandardHelper.UNKNOWN_STANDARD;
 
 public class IssueIndexSecurityReportsTest {