aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulien HENRY <julien.henry@sonarsource.com>2019-04-30 14:51:54 +0200
committersonartech <sonartech@sonarsource.com>2019-05-07 09:54:29 +0200
commit78ac82da528beca83055beba26e9d96aec79d80e (patch)
tree84a7b2661ed5f91d4f33f0a6fa86fa79e2cbcd84
parent86fa76012f7a9a566c581d9fbd712b9aead5a4a2 (diff)
downloadsonarqube-78ac82da528beca83055beba26e9d96aec79d80e.tar.gz
sonarqube-78ac82da528beca83055beba26e9d96aec79d80e.zip
SONAR-11825 Don't return activeRules and rules for applications and portfolios
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/securityreport/ws/ShowAction.java40
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/securityreport/ws/ShowActionTest.java67
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/securityreport/ws/ShowActionTest/sonarsourceSecurityOnApplication.json174
3 files changed, 251 insertions, 30 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/securityreport/ws/ShowAction.java b/server/sonar-server/src/main/java/org/sonar/server/securityreport/ws/ShowAction.java
index 344a8d4d170..03bc4d8b856 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/securityreport/ws/ShowAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/securityreport/ws/ShowAction.java
@@ -38,9 +38,9 @@ import org.sonar.db.rule.RuleDto;
import org.sonar.server.component.ComponentFinder;
import org.sonar.server.issue.index.IssueIndex;
import org.sonar.server.issue.index.SecurityStandardCategoryStatistics;
-import org.sonar.server.security.SecurityStandardHelper;
import org.sonar.server.qualityprofile.QPMeasureData;
import org.sonar.server.qualityprofile.QualityProfile;
+import org.sonar.server.security.SecurityStandardHelper;
import org.sonar.server.user.UserSession;
import org.sonarqube.ws.SecurityReports;
@@ -132,31 +132,31 @@ public class ShowAction implements SecurityReportsWsAction {
}
String standard = request.mandatoryParam(PARAM_STANDARD);
boolean includeCwe = request.mandatoryParamAsBoolean(PARAM_INCLUDE_DISTRIBUTION);
+ List<SecurityStandardCategoryStatistics> statistics;
switch (standard) {
case PARAM_OWASP_TOP_10:
- List<SecurityStandardCategoryStatistics> owaspCategories = issueIndex.getOwaspTop10Report(projectDto.uuid(), isViewOrApp, includeCwe)
+ statistics = issueIndex.getOwaspTop10Report(projectDto.uuid(), isViewOrApp, includeCwe)
.stream()
.sorted(comparing(ShowAction::index))
.collect(toList());
- completeStatistics(owaspCategories, projectDto, standard, includeCwe);
- writeResponse(request, response, owaspCategories);
break;
case PARAM_SANS_TOP_25:
- List<SecurityStandardCategoryStatistics> sansTop25Report = issueIndex.getSansTop25Report(projectDto.uuid(), isViewOrApp, includeCwe);
- completeStatistics(sansTop25Report, projectDto, standard, includeCwe);
- writeResponse(request, response, sansTop25Report);
+ statistics = issueIndex.getSansTop25Report(projectDto.uuid(), isViewOrApp, includeCwe);
break;
case PARAM_SONARSOURCE_SECURITY:
- List<SecurityStandardCategoryStatistics> sonarSourceReport = issueIndex.getSonarSourceReport(projectDto.uuid(), isViewOrApp, includeCwe);
- completeStatistics(sonarSourceReport, projectDto, standard, includeCwe);
- writeResponse(request, response, sonarSourceReport);
+ statistics = issueIndex.getSonarSourceReport(projectDto.uuid(), isViewOrApp, includeCwe);
break;
default:
throw new IllegalArgumentException(String.format(UNSUPPORTED_STANDARD_MSG, standard));
}
+ if (!isViewOrApp) {
+ // App and Portfolios don't have a quality profile
+ completeRulesStatistics(statistics, projectDto, standard, includeCwe);
+ }
+ writeResponse(request, response, statistics, isViewOrApp);
}
- private void completeStatistics(List<SecurityStandardCategoryStatistics> input, ComponentDto project, String standard, boolean includeCwe) {
+ private void completeRulesStatistics(List<SecurityStandardCategoryStatistics> input, ComponentDto project, String standard, boolean includeCwe) {
try (DbSession dbSession = dbClient.openSession(false)) {
Set<QualityProfile> qualityProfiles = dbClient.liveMeasureDao().selectMeasure(dbSession, project.projectUuid(), QUALITY_PROFILES_KEY)
.map(LiveMeasureDto::getDataAsString)
@@ -239,7 +239,7 @@ public class ShowAction implements SecurityReportsWsAction {
return 11;
}
- private static void writeResponse(Request request, Response response, List<SecurityStandardCategoryStatistics> categories) {
+ private static void writeResponse(Request request, Response response, List<SecurityStandardCategoryStatistics> categories, boolean isViewOrApp) {
SecurityReports.ShowWsResponse.Builder builder = SecurityReports.ShowWsResponse.newBuilder();
categories.forEach(cat -> {
SecurityReports.SecurityStandardCategoryStatistics.Builder catBuilder = SecurityReports.SecurityStandardCategoryStatistics.newBuilder();
@@ -250,9 +250,11 @@ public class ShowAction implements SecurityReportsWsAction {
catBuilder
.setOpenSecurityHotspots(cat.getOpenSecurityHotspots())
.setToReviewSecurityHotspots(cat.getToReviewSecurityHotspots())
- .setWontFixSecurityHotspots(cat.getWontFixSecurityHotspots())
- .setTotalRules(cat.getTotalRules())
- .setActiveRules(cat.getActiveRules());
+ .setWontFixSecurityHotspots(cat.getWontFixSecurityHotspots());
+ if (!isViewOrApp) {
+ catBuilder.setTotalRules(cat.getTotalRules())
+ .setActiveRules(cat.getActiveRules());
+ }
if (cat.getChildren() != null) {
cat.getChildren().stream()
.sorted(comparing(cweIndex()))
@@ -265,9 +267,11 @@ public class ShowAction implements SecurityReportsWsAction {
cweBuilder
.setOpenSecurityHotspots(cwe.getOpenSecurityHotspots())
.setToReviewSecurityHotspots(cwe.getToReviewSecurityHotspots())
- .setWontFixSecurityHotspots(cwe.getWontFixSecurityHotspots())
- .setActiveRules(cwe.getActiveRules())
- .setTotalRules(cwe.getTotalRules());
+ .setWontFixSecurityHotspots(cwe.getWontFixSecurityHotspots());
+ if (!isViewOrApp) {
+ cweBuilder.setActiveRules(cwe.getActiveRules())
+ .setTotalRules(cwe.getTotalRules());
+ }
catBuilder.addDistribution(cweBuilder);
});
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/securityreport/ws/ShowActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/securityreport/ws/ShowActionTest.java
index 11aa64b9274..247bc07e307 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/securityreport/ws/ShowActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/securityreport/ws/ShowActionTest.java
@@ -20,6 +20,7 @@
package org.sonar.server.securityreport.ws;
import java.util.Date;
+import java.util.List;
import java.util.Set;
import org.junit.Before;
import org.junit.Rule;
@@ -33,6 +34,7 @@ import org.sonar.api.web.UserRole;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
+import org.sonar.db.component.ComponentDbTester;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ComponentTesting;
import org.sonar.db.issue.IssueDto;
@@ -52,6 +54,8 @@ import org.sonar.server.permission.index.WebAuthorizationTypeSupport;
import org.sonar.server.qualityprofile.QPMeasureData;
import org.sonar.server.qualityprofile.QualityProfile;
import org.sonar.server.tester.UserSessionRule;
+import org.sonar.server.view.index.ViewDoc;
+import org.sonar.server.view.index.ViewIndexer;
import org.sonar.server.ws.WsActionTester;
import static com.google.common.collect.Sets.newHashSet;
@@ -77,9 +81,11 @@ public class ShowActionTest {
public ExpectedException expectedException = none();
private DbClient dbClient = db.getDbClient();
+ private ComponentDbTester componentDbTester = db.components();
private DbSession session = db.getSession();
private IssueIndex issueIndex = new IssueIndex(es.client(), System2.INSTANCE, userSessionRule, new WebAuthorizationTypeSupport(userSessionRule));
private IssueIndexer issueIndexer = new IssueIndexer(es.client(), dbClient, new IssueIteratorFactory(dbClient));
+ private ViewIndexer viewIndexer = new ViewIndexer(db.getDbClient(), es.client());
private WsActionTester ws = new WsActionTester(new ShowAction(userSessionRule, TestComponentFinder.from(db), issueIndex, dbClient));
private StartupIndexer permissionIndexer = new PermissionIndexer(dbClient, es.client(), issueIndexer);
@@ -97,7 +103,7 @@ public class ShowActionTest {
public void setUp() {
user = db.users().insertUser("john");
userSessionRule.logIn(user);
- project = insertComponent(ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization(), "PROJECT_ID").setDbKey("PROJECT_KEY"));
+ project = componentDbTester.insertComponent(ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization(), "PROJECT_ID").setDbKey("PROJECT_KEY"));
qualityProfile = db.qualityProfiles().insert(db.getDefaultOrganization(), qp -> qp.setLanguage("java"));
// owasp : a2 and TopSans25 insecure
rule1 = newRule(newHashSet("owaspTop10:a2", "cwe:123", "cwe:89"), RuleType.SECURITY_HOTSPOT);
@@ -132,7 +138,7 @@ public class ShowActionTest {
public void owasp_empty() {
userSessionRule.addProjectPermission(UserRole.USER, project);
indexPermissions();
- ComponentDto file = insertComponent(newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY"));
+ ComponentDto file = componentDbTester.insertComponent(newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY"));
IssueDto issue1 = newIssue(rule1, project, file)
.setStatus("OPEN")
.setSeverity("MAJOR")
@@ -161,7 +167,7 @@ public class ShowActionTest {
public void owasp_without_cwe() {
userSessionRule.addProjectPermission(UserRole.USER, project);
indexPermissions();
- ComponentDto file = insertComponent(newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY"));
+ ComponentDto file = componentDbTester.insertComponent(newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY"));
IssueDto issue1 = newIssue(rule1, project, file)
.setStatus("OPEN")
.setSeverity("MAJOR")
@@ -196,7 +202,7 @@ public class ShowActionTest {
public void owasp_with_cwe__matching_json_example() {
userSessionRule.addProjectPermission(UserRole.USER, project);
indexPermissions();
- ComponentDto file = insertComponent(newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY"));
+ ComponentDto file = componentDbTester.insertComponent(newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY"));
IssueDto issue1 = newIssue(rule1, project, file)
.setStatus("OPEN")
.setSeverity("MAJOR")
@@ -232,7 +238,7 @@ public class ShowActionTest {
public void sans_with_cwe() {
userSessionRule.addProjectPermission(UserRole.USER, project);
indexPermissions();
- ComponentDto file = insertComponent(newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY"));
+ ComponentDto file = componentDbTester.insertComponent(newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY"));
IssueDto issue1 = newIssue(rule1, project, file)
.setStatus("OPEN")
.setSeverity("MAJOR")
@@ -314,7 +320,7 @@ public class ShowActionTest {
public void sonarsource_security_without_cwe() {
userSessionRule.addProjectPermission(UserRole.USER, project);
indexPermissions();
- ComponentDto file = insertComponent(newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY"));
+ ComponentDto file = componentDbTester.insertComponent(newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY"));
IssueDto issue1 = newIssue(rule1, project, file)
.setStatus("OPEN")
.setSeverity("MAJOR")
@@ -350,7 +356,7 @@ public class ShowActionTest {
public void sonarsource_security_with_cwe() {
userSessionRule.addProjectPermission(UserRole.USER, project);
indexPermissions();
- ComponentDto file = insertComponent(newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY"));
+ ComponentDto file = componentDbTester.insertComponent(newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY"));
IssueDto issue1 = newIssue(rule1, project, file)
.setStatus("OPEN")
.setSeverity("MAJOR")
@@ -382,6 +388,44 @@ public class ShowActionTest {
.isSimilarTo(this.getClass().getResource("ShowActionTest/sonarsourceSecurityWithCwe.json"));
}
+ @Test
+ public void dont_return_rules_on_application() {
+ ComponentDto application = db.components().insertPrivateApplication(db.getDefaultOrganization());
+ indexView(application.uuid(), singletonList(project.uuid()));
+ userSessionRule.addProjectPermission(UserRole.USER, application);
+ indexPermissions();
+ ComponentDto file = componentDbTester.insertComponent(newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY"));
+ IssueDto issue1 = newIssue(rule1, project, file)
+ .setStatus("OPEN")
+ .setSeverity("MAJOR")
+ .setType(RuleType.VULNERABILITY);
+ IssueDto issue2 = newIssue(rule1, project, file)
+ .setStatus("OPEN")
+ .setSeverity("MAJOR")
+ .setType(RuleType.SECURITY_HOTSPOT);
+ IssueDto issue3 = newIssue(rule1, project, file)
+ .setStatus(Issue.STATUS_RESOLVED)
+ .setResolution(Issue.RESOLUTION_FIXED)
+ .setSeverity("MAJOR")
+ .setType(RuleType.SECURITY_HOTSPOT);
+ IssueDto issue4 = newIssue(rule1, project, file)
+ .setStatus(Issue.STATUS_RESOLVED)
+ .setResolution(Issue.RESOLUTION_WONT_FIX)
+ .setSeverity("MAJOR")
+ .setType(RuleType.SECURITY_HOTSPOT);
+ dbClient.issueDao().insert(session, issue1, issue2, issue3, issue4);
+ session.commit();
+ indexIssues();
+
+ assertJson(ws.newRequest()
+ .setParam("standard", "sonarsourceSecurity")
+ .setParam("project", application.getKey())
+ .setParam("includeDistribution", "true")
+ .execute().getInput())
+ .withStrictArrayOrder()
+ .isSimilarTo(this.getClass().getResource("ShowActionTest/sonarsourceSecurityOnApplication.json"));
+ }
+
private RuleDefinitionDto newRule(Set<String> standards, RuleType type) {
RuleDefinitionDto rule = RuleTesting.newRule()
.setType(type)
@@ -399,14 +443,13 @@ public class ShowActionTest {
issueIndexer.indexOnStartup(issueIndexer.getIndexTypes());
}
+ private void indexView(String viewUuid, List<String> projects) {
+ viewIndexer.index(new ViewDoc().setUuid(viewUuid).setProjects(projects));
+ }
+
private void insertQPLiveMeasure(ComponentDto project) {
QualityProfile qp = new QualityProfile(qualityProfile.getKee(), qualityProfile.getName(), qualityProfile.getLanguage(), new Date());
db.measures().insertLiveMeasure(project, qpMetric, lm -> lm.setData(QPMeasureData.toJson(new QPMeasureData(singletonList(qp)))));
}
- private ComponentDto insertComponent(ComponentDto component) {
- dbClient.componentDao().insert(session, component);
- session.commit();
- return component;
- }
}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/securityreport/ws/ShowActionTest/sonarsourceSecurityOnApplication.json b/server/sonar-server/src/test/resources/org/sonar/server/securityreport/ws/ShowActionTest/sonarsourceSecurityOnApplication.json
new file mode 100644
index 00000000000..b565b5d309d
--- /dev/null
+++ b/server/sonar-server/src/test/resources/org/sonar/server/securityreport/ws/ShowActionTest/sonarsourceSecurityOnApplication.json
@@ -0,0 +1,174 @@
+{
+ "categories": [
+ {
+ "category": "ldap-injection",
+ "vulnerabilities": 0,
+ "toReviewSecurityHotspots": 0,
+ "openSecurityHotspots": 0,
+ "wontFixSecurityHotspots": 0,
+ "distribution": []
+ },
+ {
+ "category": "object-injection",
+ "vulnerabilities": 0,
+ "toReviewSecurityHotspots": 0,
+ "openSecurityHotspots": 0,
+ "wontFixSecurityHotspots": 0,
+ "distribution": []
+ },
+ {
+ "category": "ssrf",
+ "vulnerabilities": 0,
+ "toReviewSecurityHotspots": 0,
+ "openSecurityHotspots": 0,
+ "wontFixSecurityHotspots": 0,
+ "distribution": []
+ },
+ {
+ "category": "insecure-conf",
+ "vulnerabilities": 0,
+ "toReviewSecurityHotspots": 0,
+ "openSecurityHotspots": 0,
+ "wontFixSecurityHotspots": 0,
+ "distribution": []
+ },
+ {
+ "category": "xxe",
+ "vulnerabilities": 0,
+ "toReviewSecurityHotspots": 0,
+ "openSecurityHotspots": 0,
+ "wontFixSecurityHotspots": 0,
+ "distribution": []
+ },
+ {
+ "category": "auth",
+ "vulnerabilities": 0,
+ "toReviewSecurityHotspots": 0,
+ "openSecurityHotspots": 0,
+ "wontFixSecurityHotspots": 0,
+ "distribution": []
+ },
+ {
+ "category": "xpath-injection",
+ "vulnerabilities": 0,
+ "toReviewSecurityHotspots": 0,
+ "openSecurityHotspots": 0,
+ "wontFixSecurityHotspots": 0,
+ "distribution": []
+ },
+ {
+ "category": "weak-cryptography",
+ "vulnerabilities": 0,
+ "toReviewSecurityHotspots": 0,
+ "openSecurityHotspots": 0,
+ "wontFixSecurityHotspots": 0,
+ "distribution": []
+ },
+ {
+ "category": "dos",
+ "vulnerabilities": 0,
+ "toReviewSecurityHotspots": 0,
+ "openSecurityHotspots": 0,
+ "wontFixSecurityHotspots": 0,
+ "distribution": []
+ },
+ {
+ "category": "open-redirect",
+ "vulnerabilities": 0,
+ "toReviewSecurityHotspots": 0,
+ "openSecurityHotspots": 0,
+ "wontFixSecurityHotspots": 0,
+ "distribution": []
+ },
+ {
+ "category": "log-injection",
+ "vulnerabilities": 0,
+ "toReviewSecurityHotspots": 0,
+ "openSecurityHotspots": 0,
+ "wontFixSecurityHotspots": 0,
+ "distribution": []
+ },
+ {
+ "category": "csrf",
+ "vulnerabilities": 0,
+ "toReviewSecurityHotspots": 0,
+ "openSecurityHotspots": 0,
+ "wontFixSecurityHotspots": 0,
+ "distribution": []
+ },
+ {
+ "category": "sql-injection",
+ "vulnerabilities": 1,
+ "vulnerabilityRating": 3,
+ "toReviewSecurityHotspots": 1,
+ "openSecurityHotspots": 1,
+ "wontFixSecurityHotspots": 1,
+ "distribution": [
+ {
+ "cwe": "89",
+ "vulnerabilities": 1,
+ "vulnerabilityRating": 3,
+ "toReviewSecurityHotspots": 1,
+ "openSecurityHotspots": 1,
+ "wontFixSecurityHotspots": 1
+ }
+ ]
+ },
+ {
+ "category": "file-manipulation",
+ "vulnerabilities": 0,
+ "toReviewSecurityHotspots": 0,
+ "openSecurityHotspots": 0,
+ "wontFixSecurityHotspots": 0,
+ "distribution": []
+ },
+ {
+ "category": "expression-lang-injection",
+ "vulnerabilities": 0,
+ "toReviewSecurityHotspots": 0,
+ "openSecurityHotspots": 0,
+ "wontFixSecurityHotspots": 0,
+ "distribution": []
+ },
+ {
+ "category": "rce",
+ "vulnerabilities": 0,
+ "toReviewSecurityHotspots": 0,
+ "openSecurityHotspots": 0,
+ "wontFixSecurityHotspots": 0,
+ "distribution": []
+ },
+ {
+ "category": "xss",
+ "vulnerabilities": 0,
+ "toReviewSecurityHotspots": 0,
+ "openSecurityHotspots": 0,
+ "wontFixSecurityHotspots": 0,
+ "distribution": []
+ },
+ {
+ "category": "path-traversal-injection",
+ "vulnerabilities": 0,
+ "toReviewSecurityHotspots": 0,
+ "openSecurityHotspots": 0,
+ "wontFixSecurityHotspots": 0,
+ "distribution": []
+ },
+ {
+ "category": "command-injection",
+ "vulnerabilities": 0,
+ "toReviewSecurityHotspots": 0,
+ "openSecurityHotspots": 0,
+ "wontFixSecurityHotspots": 0,
+ "distribution": []
+ },
+ {
+ "category": "http-response-splitting",
+ "vulnerabilities": 0,
+ "toReviewSecurityHotspots": 0,
+ "openSecurityHotspots": 0,
+ "wontFixSecurityHotspots": 0,
+ "distribution": []
+ }
+ ]
+}