@@ -303,7 +303,7 @@ | |||
rules r | |||
<include refid="outerJoinRulesMetadata"/> | |||
where | |||
r.status != 'REMOVED' | |||
r.status != 'REMOVED' and r.is_external is false and r.is_template is false | |||
and r.rule_type in <foreach collection="types" item="type" separator="," open="(" close=")">#{type, jdbcType=INTEGER}</foreach> | |||
and r.language in <foreach collection="languages" item="language" separator="," open="(" close=")">#{language, jdbcType=VARCHAR}</foreach> | |||
</select> |
@@ -19,6 +19,7 @@ | |||
*/ | |||
package org.sonar.db.rule; | |||
import com.hazelcast.map.impl.querycache.accumulator.Accumulator; | |||
import java.util.ArrayList; | |||
import java.util.Arrays; | |||
import java.util.Collections; | |||
@@ -525,6 +526,40 @@ public class RuleDaoTest { | |||
.isEmpty(); | |||
} | |||
@Test | |||
public void selectByTypeAndLanguages_ignores_external_rules() { | |||
OrganizationDto organization = db.organizations().insert(); | |||
RuleDefinitionDto rule1 = db.rules().insert( | |||
r -> r.setKey(RuleKey.of("java", "S001")) | |||
.setConfigKey("S1") | |||
.setType(RuleType.VULNERABILITY) | |||
.setIsExternal(true) | |||
.setLanguage("java")); | |||
db.rules().insertOrUpdateMetadata(rule1, organization); | |||
assertThat(underTest.selectByTypeAndLanguages(db.getSession(), organization.getUuid(), singletonList(RuleType.VULNERABILITY.getDbConstant()), singletonList("java"))) | |||
.extracting(RuleDto::getOrganizationUuid, RuleDto::getId, RuleDto::getLanguage, RuleDto::getType) | |||
.isEmpty(); | |||
} | |||
@Test | |||
public void selectByTypeAndLanguages_ignores_template_rules() { | |||
OrganizationDto organization = db.organizations().insert(); | |||
RuleDefinitionDto rule1 = db.rules().insert( | |||
r -> r.setKey(RuleKey.of("java", "S001")) | |||
.setConfigKey("S1") | |||
.setType(RuleType.VULNERABILITY) | |||
.setIsTemplate(true) | |||
.setLanguage("java")); | |||
db.rules().insertOrUpdateMetadata(rule1, organization); | |||
assertThat(underTest.selectByTypeAndLanguages(db.getSession(), organization.getUuid(), singletonList(RuleType.VULNERABILITY.getDbConstant()), singletonList("java"))) | |||
.extracting(RuleDto::getOrganizationUuid, RuleDto::getId, RuleDto::getLanguage, RuleDto::getType) | |||
.isEmpty(); | |||
} | |||
@Test | |||
public void select_by_query() { | |||
OrganizationDto organization = db.organizations().insert(); |
@@ -19,26 +19,41 @@ | |||
*/ | |||
package org.sonar.server.securityreport.ws; | |||
import com.google.common.collect.ArrayListMultimap; | |||
import com.google.common.collect.Multimap; | |||
import java.util.List; | |||
import java.util.Set; | |||
import java.util.function.Function; | |||
import org.sonar.api.resources.Qualifiers; | |||
import org.sonar.api.rules.RuleType; | |||
import org.sonar.api.server.ws.Request; | |||
import org.sonar.api.server.ws.Response; | |||
import org.sonar.api.server.ws.WebService; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.component.ComponentDto; | |||
import org.sonar.db.measure.LiveMeasureDto; | |||
import org.sonar.db.qualityprofile.OrgActiveRuleDto; | |||
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.qualityprofile.QPMeasureData; | |||
import org.sonar.server.qualityprofile.QualityProfile; | |||
import org.sonar.server.user.UserSession; | |||
import org.sonarqube.ws.SecurityReports; | |||
import static java.lang.Integer.parseInt; | |||
import static java.util.Arrays.asList; | |||
import static java.util.Collections.emptySortedSet; | |||
import static java.util.Comparator.comparing; | |||
import static java.util.stream.Collectors.toList; | |||
import static org.sonar.api.measures.CoreMetrics.QUALITY_PROFILES_KEY; | |||
import static org.sonar.api.web.UserRole.USER; | |||
import static org.sonar.server.issue.index.IssueIndexDefinition.UNKNOWN_STANDARD; | |||
import static org.sonar.server.issue.index.SecurityStandardHelper.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.ws.WsUtils.writeProtobuf; | |||
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_OWASP_TOP_10; | |||
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_SANS_TOP_25; | |||
@@ -118,16 +133,88 @@ public class ShowAction implements SecurityReportsWsAction { | |||
.stream() | |||
.sorted(comparing(ShowAction::index)) | |||
.collect(toList()); | |||
completeStatistics(owaspCategories, projectDto, standard, includeCwe); | |||
writeResponse(request, response, owaspCategories); | |||
break; | |||
case PARAM_SANS_TOP_25: | |||
writeResponse(request, response, issueIndex.getSansTop25Report(projectDto.uuid(), isViewOrApp, includeCwe)); | |||
List<SecurityStandardCategoryStatistics> sansTop25Report = issueIndex.getSansTop25Report(projectDto.uuid(), isViewOrApp, includeCwe); | |||
completeStatistics(sansTop25Report, projectDto, standard, includeCwe); | |||
writeResponse(request, response, sansTop25Report); | |||
break; | |||
default: | |||
throw new IllegalArgumentException("Unsupported standard: '" + standard + "'"); | |||
} | |||
} | |||
private void completeStatistics(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) | |||
.map(data -> QPMeasureData.fromJson(data).getProfiles()) | |||
.orElse(emptySortedSet()); | |||
List<OrgActiveRuleDto> activeRuleDtos = dbClient.activeRuleDao().selectByTypeAndProfileUuids(dbSession, | |||
asList(RuleType.SECURITY_HOTSPOT.getDbConstant(), RuleType.VULNERABILITY.getDbConstant()), | |||
qualityProfiles.stream() | |||
.map(QualityProfile::getQpKey) | |||
.collect(toList())); | |||
Multimap<String, OrgActiveRuleDto> activeRulesByCategory = ArrayListMultimap.create(); | |||
activeRuleDtos | |||
.forEach(r -> { | |||
List<String> cwe = getCwe(r.getSecurityStandards()); | |||
if (includeCwe) { | |||
cwe.forEach(s -> activeRulesByCategory.put(s, r)); | |||
} | |||
switch (standard) { | |||
case PARAM_OWASP_TOP_10: | |||
getOwaspTop10(r.getSecurityStandards()).forEach(s -> activeRulesByCategory.put(s, r)); | |||
break; | |||
case PARAM_SANS_TOP_25: | |||
getSansTop25(cwe).forEach(s -> activeRulesByCategory.put(s, r)); | |||
break; | |||
default: | |||
throw new IllegalArgumentException("Unsupported standard: '" + standard + "'"); | |||
} | |||
}); | |||
List<RuleDto> ruleDtos = dbClient.ruleDao().selectByTypeAndLanguages(dbSession, | |||
project.getOrganizationUuid(), | |||
asList(RuleType.SECURITY_HOTSPOT.getDbConstant(), RuleType.VULNERABILITY.getDbConstant()), | |||
qualityProfiles.stream() | |||
.map(QualityProfile::getLanguageKey) | |||
.collect(toList())); | |||
Multimap<String, RuleDto> rulesByCategory = ArrayListMultimap.create(); | |||
ruleDtos | |||
.forEach(r -> { | |||
List<String> cwe = getCwe(r.getSecurityStandards()); | |||
if (includeCwe) { | |||
cwe.forEach(s -> rulesByCategory.put(s, r)); | |||
} | |||
switch (standard) { | |||
case PARAM_OWASP_TOP_10: | |||
getOwaspTop10(r.getSecurityStandards()).forEach(s -> rulesByCategory.put(s, r)); | |||
break; | |||
case PARAM_SANS_TOP_25: | |||
getSansTop25(cwe).forEach(s -> rulesByCategory.put(s, r)); | |||
break; | |||
default: | |||
throw new IllegalArgumentException("Unsupported standard: '" + standard + "'"); | |||
} | |||
}); | |||
input.forEach(c -> { | |||
c.setTotalRules(rulesByCategory.get(c.getCategory()).size()); | |||
c.setActiveRules(activeRulesByCategory.get(c.getCategory()).size()); | |||
c.getChildren().forEach(child -> { | |||
child.setTotalRules(rulesByCategory.get(child.getCategory()).size()); | |||
child.setActiveRules(activeRulesByCategory.get(child.getCategory()).size()); | |||
}); | |||
}); | |||
} | |||
} | |||
private static Integer index(SecurityStandardCategoryStatistics owaspCat) { | |||
if (owaspCat.getCategory().startsWith(OWASP_CAT_PREFIX)) { | |||
return parseInt(owaspCat.getCategory().substring(OWASP_CAT_PREFIX.length())); | |||
@@ -147,7 +234,9 @@ public class ShowAction implements SecurityReportsWsAction { | |||
catBuilder | |||
.setOpenSecurityHotspots(cat.getOpenSecurityHotspots()) | |||
.setToReviewSecurityHotspots(cat.getToReviewSecurityHotspots()) | |||
.setWontFixSecurityHotspots(cat.getWontFixSecurityHotspots()); | |||
.setWontFixSecurityHotspots(cat.getWontFixSecurityHotspots()) | |||
.setTotalRules(cat.getTotalRules()) | |||
.setActiveRules(cat.getActiveRules()); | |||
if (cat.getChildren() != null) { | |||
cat.getChildren().stream() | |||
.sorted(comparing(cweIndex())) | |||
@@ -160,7 +249,9 @@ public class ShowAction implements SecurityReportsWsAction { | |||
cweBuilder | |||
.setOpenSecurityHotspots(cwe.getOpenSecurityHotspots()) | |||
.setToReviewSecurityHotspots(cwe.getToReviewSecurityHotspots()) | |||
.setWontFixSecurityHotspots(cwe.getWontFixSecurityHotspots()); | |||
.setWontFixSecurityHotspots(cwe.getWontFixSecurityHotspots()) | |||
.setActiveRules(cwe.getActiveRules()) | |||
.setTotalRules(cwe.getTotalRules()); | |||
catBuilder.addDistribution(cweBuilder); | |||
}); | |||
} |
@@ -19,8 +19,8 @@ | |||
*/ | |||
package org.sonar.server.securityreport.ws; | |||
import java.util.Arrays; | |||
import java.util.HashSet; | |||
import java.util.Date; | |||
import java.util.Set; | |||
import org.junit.Before; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
@@ -36,7 +36,9 @@ import org.sonar.db.DbTester; | |||
import org.sonar.db.component.ComponentDto; | |||
import org.sonar.db.component.ComponentTesting; | |||
import org.sonar.db.issue.IssueDto; | |||
import org.sonar.db.metric.MetricDto; | |||
import org.sonar.db.permission.GroupPermissionDto; | |||
import org.sonar.db.qualityprofile.QProfileDto; | |||
import org.sonar.db.rule.RuleDefinitionDto; | |||
import org.sonar.db.rule.RuleTesting; | |||
import org.sonar.db.user.UserDto; | |||
@@ -48,11 +50,17 @@ import org.sonar.server.issue.index.IssueIndexer; | |||
import org.sonar.server.issue.index.IssueIteratorFactory; | |||
import org.sonar.server.permission.index.PermissionIndexer; | |||
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.ws.WsActionTester; | |||
import static com.google.common.collect.Sets.newHashSet; | |||
import static java.util.Collections.singletonList; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.junit.rules.ExpectedException.none; | |||
import static org.sonar.api.measures.CoreMetrics.QUALITY_PROFILES_KEY; | |||
import static org.sonar.api.measures.Metric.ValueType.STRING; | |||
import static org.sonar.db.component.ComponentTesting.newFileDto; | |||
import static org.sonar.db.issue.IssueTesting.newIssue; | |||
import static org.sonar.server.tester.UserSessionRule.standalone; | |||
@@ -77,11 +85,33 @@ public class ShowActionTest { | |||
private StartupIndexer permissionIndexer = new PermissionIndexer(dbClient, es.client(), issueIndexer); | |||
private UserDto user; | |||
private ComponentDto project; | |||
private QProfileDto qualityProfile; | |||
private RuleDefinitionDto rule1; | |||
private RuleDefinitionDto rule2; | |||
private RuleDefinitionDto rule3; | |||
private RuleDefinitionDto rule4; | |||
private MetricDto qpMetric; | |||
@Before | |||
public void setUp() { | |||
user = db.users().insertUser("john"); | |||
userSessionRule.logIn(user); | |||
project = 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")); | |||
// owasp : a1 and TopSans25 risky | |||
rule2 = newRule(newHashSet("owaspTop10:a1", "cwe:22", "cwe:190")); | |||
// owasp : a4 and TopSans25 porous, not activated | |||
rule3 = newRule(newHashSet("owaspTop10:a3", "cwe:759", "cwe:000")); | |||
// cwe with unknown | |||
rule4 = newRule(newHashSet("cwe:999")); | |||
db.qualityProfiles().activateRule(qualityProfile, rule1); | |||
db.qualityProfiles().activateRule(qualityProfile, rule2); | |||
qpMetric = db.measures().insertMetric(m -> m.setValueType(STRING.name()).setKey(QUALITY_PROFILES_KEY)); | |||
insertQPLiveMeasure(project); | |||
} | |||
@Test | |||
@@ -95,24 +125,20 @@ public class ShowActionTest { | |||
assertThat(def.params()).extracting("key").containsExactlyInAnyOrder("standard", "project", "branch", "includeDistribution"); | |||
} | |||
@Test | |||
public void owasp_empty() { | |||
ComponentDto project = insertComponent(ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization(), "PROJECT_ID").setDbKey("PROJECT_KEY")); | |||
userSessionRule.addProjectPermission(UserRole.USER, project); | |||
indexPermissions(); | |||
ComponentDto file = insertComponent(newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY")); | |||
RuleDefinitionDto rule = newRule(); | |||
IssueDto issue1 = newIssue(rule, project, file) | |||
IssueDto issue1 = newIssue(rule1, project, file) | |||
.setStatus("OPEN") | |||
.setSeverity("MAJOR") | |||
.setType(RuleType.CODE_SMELL); | |||
IssueDto issue2 = newIssue(rule, project, file) | |||
IssueDto issue2 = newIssue(rule1, project, file) | |||
.setStatus("OPEN") | |||
.setSeverity("MAJOR") | |||
.setType(RuleType.BUG); | |||
IssueDto issue3 = newIssue(rule, project, file) | |||
IssueDto issue3 = newIssue(rule1, project, file) | |||
.setStatus("OPEN") | |||
.setSeverity("MAJOR") | |||
.setType(RuleType.CODE_SMELL); | |||
@@ -130,26 +156,23 @@ public class ShowActionTest { | |||
@Test | |||
public void owasp_without_cwe() { | |||
ComponentDto project = insertComponent(ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization(), "PROJECT_ID").setDbKey("PROJECT_KEY")); | |||
userSessionRule.addProjectPermission(UserRole.USER, project); | |||
indexPermissions(); | |||
ComponentDto file = insertComponent(newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY")); | |||
RuleDefinitionDto rule = newRule(); | |||
IssueDto issue1 = newIssue(rule, project, file) | |||
IssueDto issue1 = newIssue(rule1, project, file) | |||
.setStatus("OPEN") | |||
.setSeverity("MAJOR") | |||
.setType(RuleType.VULNERABILITY); | |||
IssueDto issue2 = newIssue(rule, project, file) | |||
IssueDto issue2 = newIssue(rule1, project, file) | |||
.setStatus("OPEN") | |||
.setSeverity("MAJOR") | |||
.setType(RuleType.SECURITY_HOTSPOT); | |||
IssueDto issue3 = newIssue(rule, project, file) | |||
IssueDto issue3 = newIssue(rule1, project, file) | |||
.setStatus(Issue.STATUS_RESOLVED) | |||
.setResolution(Issue.RESOLUTION_FIXED) | |||
.setSeverity("MAJOR") | |||
.setType(RuleType.SECURITY_HOTSPOT); | |||
IssueDto issue4 = newIssue(rule, project, file) | |||
IssueDto issue4 = newIssue(rule1, project, file) | |||
.setStatus(Issue.STATUS_RESOLVED) | |||
.setResolution(Issue.RESOLUTION_WONT_FIX) | |||
.setSeverity("MAJOR") | |||
@@ -168,26 +191,23 @@ public class ShowActionTest { | |||
@Test | |||
public void owasp_with_cwe() { | |||
ComponentDto project = insertComponent(ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization(), "PROJECT_ID").setDbKey("PROJECT_KEY")); | |||
userSessionRule.addProjectPermission(UserRole.USER, project); | |||
indexPermissions(); | |||
ComponentDto file = insertComponent(newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY")); | |||
RuleDefinitionDto rule = newRule(); | |||
IssueDto issue1 = newIssue(rule, project, file) | |||
IssueDto issue1 = newIssue(rule1, project, file) | |||
.setStatus("OPEN") | |||
.setSeverity("MAJOR") | |||
.setType(RuleType.VULNERABILITY); | |||
IssueDto issue2 = newIssue(rule, project, file) | |||
IssueDto issue2 = newIssue(rule1, project, file) | |||
.setStatus("OPEN") | |||
.setSeverity("MAJOR") | |||
.setType(RuleType.SECURITY_HOTSPOT); | |||
IssueDto issue3 = newIssue(rule, project, file) | |||
IssueDto issue3 = newIssue(rule1, project, file) | |||
.setStatus(Issue.STATUS_RESOLVED) | |||
.setResolution(Issue.RESOLUTION_FIXED) | |||
.setSeverity("MAJOR") | |||
.setType(RuleType.SECURITY_HOTSPOT); | |||
IssueDto issue4 = newIssue(rule, project, file) | |||
IssueDto issue4 = newIssue(rule1, project, file) | |||
.setStatus(Issue.STATUS_RESOLVED) | |||
.setResolution(Issue.RESOLUTION_WONT_FIX) | |||
.setSeverity("MAJOR") | |||
@@ -207,25 +227,23 @@ public class ShowActionTest { | |||
@Test | |||
public void sans_with_cwe() { | |||
ComponentDto project = insertComponent(ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization(), "PROJECT_ID").setDbKey("PROJECT_KEY")); | |||
userSessionRule.addProjectPermission(UserRole.USER, project); | |||
indexPermissions(); | |||
ComponentDto file = insertComponent(newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY")); | |||
RuleDefinitionDto rule = newRule(); | |||
IssueDto issue1 = newIssue(rule, project, file) | |||
IssueDto issue1 = newIssue(rule1, project, file) | |||
.setStatus("OPEN") | |||
.setSeverity("MAJOR") | |||
.setType(RuleType.VULNERABILITY); | |||
IssueDto issue2 = newIssue(rule, project, file) | |||
IssueDto issue2 = newIssue(rule1, project, file) | |||
.setStatus("OPEN") | |||
.setSeverity("MAJOR") | |||
.setType(RuleType.SECURITY_HOTSPOT); | |||
IssueDto issue3 = newIssue(rule, project, file) | |||
IssueDto issue3 = newIssue(rule1, project, file) | |||
.setStatus(Issue.STATUS_RESOLVED) | |||
.setResolution(Issue.RESOLUTION_FIXED) | |||
.setSeverity("MAJOR") | |||
.setType(RuleType.SECURITY_HOTSPOT); | |||
IssueDto issue4 = newIssue(rule, project, file) | |||
IssueDto issue4 = newIssue(rule1, project, file) | |||
.setStatus(Issue.STATUS_RESOLVED) | |||
.setResolution(Issue.RESOLUTION_WONT_FIX) | |||
.setSeverity("MAJOR") | |||
@@ -250,24 +268,27 @@ public class ShowActionTest { | |||
ComponentDto fileOnProject1Branch1 = db.components().insertComponent(newFileDto(project1Branch1)); | |||
ComponentDto project2 = db.components().insertPrivateProject(p -> p.setDbKey("prj2")); | |||
insertQPLiveMeasure(project1); | |||
insertQPLiveMeasure(project1Branch1); | |||
insertQPLiveMeasure(project2); | |||
userSessionRule.addProjectPermission(UserRole.USER, project1); | |||
userSessionRule.addProjectPermission(UserRole.USER, project2); | |||
indexPermissions(); | |||
RuleDefinitionDto rule = newRule(); | |||
IssueDto issue1 = newIssue(rule, project1Branch1, fileOnProject1Branch1) | |||
IssueDto issue1 = newIssue(rule1, project1Branch1, fileOnProject1Branch1) | |||
.setStatus("OPEN") | |||
.setSeverity("MAJOR") | |||
.setType(RuleType.VULNERABILITY); | |||
IssueDto issue2 = newIssue(rule, project1Branch1, fileOnProject1Branch1) | |||
IssueDto issue2 = newIssue(rule1, project1Branch1, fileOnProject1Branch1) | |||
.setStatus("OPEN") | |||
.setSeverity("MAJOR") | |||
.setType(RuleType.SECURITY_HOTSPOT); | |||
IssueDto issue3 = newIssue(rule, project1Branch1, fileOnProject1Branch1) | |||
IssueDto issue3 = newIssue(rule1, project1Branch1, fileOnProject1Branch1) | |||
.setStatus(Issue.STATUS_RESOLVED) | |||
.setResolution(Issue.RESOLUTION_FIXED) | |||
.setSeverity("MAJOR") | |||
.setType(RuleType.SECURITY_HOTSPOT); | |||
IssueDto issue4 = newIssue(rule, project1Branch1, fileOnProject1Branch1) | |||
IssueDto issue4 = newIssue(rule1, project1Branch1, fileOnProject1Branch1) | |||
.setStatus(Issue.STATUS_RESOLVED) | |||
.setResolution(Issue.RESOLUTION_WONT_FIX) | |||
.setSeverity("MAJOR") | |||
@@ -286,10 +307,11 @@ public class ShowActionTest { | |||
.isSimilarTo(this.getClass().getResource("ShowActionTest/sansWithCwe.json")); | |||
} | |||
private RuleDefinitionDto newRule() { | |||
private RuleDefinitionDto newRule(Set tags) { | |||
RuleDefinitionDto rule = RuleTesting.newRule() | |||
.setSecurityStandards(new HashSet<>(Arrays.asList("owaspTop10:a2", "cwe:123", "cwe:89"))); | |||
.setType(RuleType.SECURITY_HOTSPOT) | |||
.setLanguage("java") | |||
.setSecurityStandards(tags); | |||
db.rules().insert(rule); | |||
return rule; | |||
} | |||
@@ -302,6 +324,11 @@ public class ShowActionTest { | |||
issueIndexer.indexOnStartup(issueIndexer.getIndexTypes()); | |||
} | |||
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 void grantPermissionToAnyone(ComponentDto project, String permission) { | |||
dbClient.groupPermissionDao().insert(session, | |||
new GroupPermissionDto() |
@@ -6,7 +6,9 @@ | |||
"toReviewSecurityHotspots": 0, | |||
"openSecurityHotspots": 0, | |||
"wontFixSecurityHotspots": 0, | |||
"distribution": [] | |||
"distribution": [], | |||
"activeRules": 1, | |||
"totalRules": 1 | |||
}, | |||
{ | |||
"category": "a2", | |||
@@ -14,7 +16,9 @@ | |||
"toReviewSecurityHotspots": 0, | |||
"openSecurityHotspots": 0, | |||
"wontFixSecurityHotspots": 0, | |||
"distribution": [] | |||
"distribution": [], | |||
"activeRules": 1, | |||
"totalRules": 1 | |||
}, | |||
{ | |||
"category": "a3", | |||
@@ -22,7 +26,9 @@ | |||
"toReviewSecurityHotspots": 0, | |||
"openSecurityHotspots": 0, | |||
"wontFixSecurityHotspots": 0, | |||
"distribution": [] | |||
"distribution": [], | |||
"activeRules": 0, | |||
"totalRules": 1 | |||
}, | |||
{ | |||
"category": "a4", | |||
@@ -30,7 +36,9 @@ | |||
"toReviewSecurityHotspots": 0, | |||
"openSecurityHotspots": 0, | |||
"wontFixSecurityHotspots": 0, | |||
"distribution": [] | |||
"distribution": [], | |||
"activeRules": 0, | |||
"totalRules": 0 | |||
}, | |||
{ | |||
"category": "a5", | |||
@@ -38,7 +46,9 @@ | |||
"toReviewSecurityHotspots": 0, | |||
"openSecurityHotspots": 0, | |||
"wontFixSecurityHotspots": 0, | |||
"distribution": [] | |||
"distribution": [], | |||
"activeRules": 0, | |||
"totalRules": 0 | |||
}, | |||
{ | |||
"category": "a6", | |||
@@ -46,7 +56,9 @@ | |||
"toReviewSecurityHotspots": 0, | |||
"openSecurityHotspots": 0, | |||
"wontFixSecurityHotspots": 0, | |||
"distribution": [] | |||
"distribution": [], | |||
"activeRules": 0, | |||
"totalRules": 0 | |||
}, | |||
{ | |||
"category": "a7", | |||
@@ -54,7 +66,9 @@ | |||
"toReviewSecurityHotspots": 0, | |||
"openSecurityHotspots": 0, | |||
"wontFixSecurityHotspots": 0, | |||
"distribution": [] | |||
"distribution": [], | |||
"activeRules": 0, | |||
"totalRules": 0 | |||
}, | |||
{ | |||
"category": "a8", | |||
@@ -62,7 +76,9 @@ | |||
"toReviewSecurityHotspots": 0, | |||
"openSecurityHotspots": 0, | |||
"wontFixSecurityHotspots": 0, | |||
"distribution": [] | |||
"distribution": [], | |||
"activeRules": 0, | |||
"totalRules": 0 | |||
}, | |||
{ | |||
"category": "a9", | |||
@@ -70,7 +86,9 @@ | |||
"toReviewSecurityHotspots": 0, | |||
"openSecurityHotspots": 0, | |||
"wontFixSecurityHotspots": 0, | |||
"distribution": [] | |||
"distribution": [], | |||
"activeRules": 0, | |||
"totalRules": 0 | |||
}, | |||
{ | |||
"category": "a10", | |||
@@ -78,7 +96,9 @@ | |||
"toReviewSecurityHotspots": 0, | |||
"openSecurityHotspots": 0, | |||
"wontFixSecurityHotspots": 0, | |||
"distribution": [] | |||
"distribution": [], | |||
"activeRules": 0, | |||
"totalRules": 0 | |||
}, | |||
{ | |||
"category": "unknown", | |||
@@ -86,7 +106,9 @@ | |||
"toReviewSecurityHotspots": 0, | |||
"openSecurityHotspots": 0, | |||
"wontFixSecurityHotspots": 0, | |||
"distribution": [] | |||
"distribution": [], | |||
"activeRules": 0, | |||
"totalRules": 1 | |||
} | |||
] | |||
} | |||
} |
@@ -6,7 +6,9 @@ | |||
"toReviewSecurityHotspots": 0, | |||
"openSecurityHotspots": 0, | |||
"wontFixSecurityHotspots": 0, | |||
"distribution": [] | |||
"distribution": [], | |||
"activeRules": 1, | |||
"totalRules": 1 | |||
}, | |||
{ | |||
"category": "a2", | |||
@@ -15,7 +17,9 @@ | |||
"toReviewSecurityHotspots": 1, | |||
"openSecurityHotspots": 1, | |||
"wontFixSecurityHotspots": 1, | |||
"distribution": [] | |||
"distribution": [], | |||
"activeRules": 1, | |||
"totalRules": 1 | |||
}, | |||
{ | |||
"category": "a3", | |||
@@ -23,7 +27,9 @@ | |||
"toReviewSecurityHotspots": 0, | |||
"openSecurityHotspots": 0, | |||
"wontFixSecurityHotspots": 0, | |||
"distribution": [] | |||
"distribution": [], | |||
"activeRules": 0, | |||
"totalRules": 1 | |||
}, | |||
{ | |||
"category": "a4", | |||
@@ -31,7 +37,9 @@ | |||
"toReviewSecurityHotspots": 0, | |||
"openSecurityHotspots": 0, | |||
"wontFixSecurityHotspots": 0, | |||
"distribution": [] | |||
"distribution": [], | |||
"activeRules": 0, | |||
"totalRules": 0 | |||
}, | |||
{ | |||
"category": "a5", | |||
@@ -39,7 +47,9 @@ | |||
"toReviewSecurityHotspots": 0, | |||
"openSecurityHotspots": 0, | |||
"wontFixSecurityHotspots": 0, | |||
"distribution": [] | |||
"distribution": [], | |||
"activeRules": 0, | |||
"totalRules": 0 | |||
}, | |||
{ | |||
"category": "a6", | |||
@@ -47,7 +57,9 @@ | |||
"toReviewSecurityHotspots": 0, | |||
"openSecurityHotspots": 0, | |||
"wontFixSecurityHotspots": 0, | |||
"distribution": [] | |||
"distribution": [], | |||
"activeRules": 0, | |||
"totalRules": 0 | |||
}, | |||
{ | |||
"category": "a7", | |||
@@ -55,7 +67,9 @@ | |||
"toReviewSecurityHotspots": 0, | |||
"openSecurityHotspots": 0, | |||
"wontFixSecurityHotspots": 0, | |||
"distribution": [] | |||
"distribution": [], | |||
"activeRules": 0, | |||
"totalRules": 0 | |||
}, | |||
{ | |||
"category": "a8", | |||
@@ -63,7 +77,9 @@ | |||
"toReviewSecurityHotspots": 0, | |||
"openSecurityHotspots": 0, | |||
"wontFixSecurityHotspots": 0, | |||
"distribution": [] | |||
"distribution": [], | |||
"activeRules": 0, | |||
"totalRules": 0 | |||
}, | |||
{ | |||
"category": "a9", | |||
@@ -71,7 +87,9 @@ | |||
"toReviewSecurityHotspots": 0, | |||
"openSecurityHotspots": 0, | |||
"wontFixSecurityHotspots": 0, | |||
"distribution": [] | |||
"distribution": [], | |||
"activeRules": 0, | |||
"totalRules": 0 | |||
}, | |||
{ | |||
"category": "a10", | |||
@@ -79,7 +97,9 @@ | |||
"toReviewSecurityHotspots": 0, | |||
"openSecurityHotspots": 0, | |||
"wontFixSecurityHotspots": 0, | |||
"distribution": [] | |||
"distribution": [], | |||
"activeRules": 0, | |||
"totalRules": 0 | |||
}, | |||
{ | |||
"category": "unknown", | |||
@@ -87,7 +107,9 @@ | |||
"toReviewSecurityHotspots": 0, | |||
"openSecurityHotspots": 0, | |||
"wontFixSecurityHotspots": 0, | |||
"distribution": [] | |||
"distribution": [], | |||
"activeRules": 0, | |||
"totalRules": 1 | |||
} | |||
] | |||
} | |||
} |
@@ -6,7 +6,9 @@ | |||
"toReviewSecurityHotspots": 0, | |||
"openSecurityHotspots": 0, | |||
"wontFixSecurityHotspots": 0, | |||
"distribution": [] | |||
"distribution": [], | |||
"activeRules": 1, | |||
"totalRules": 1 | |||
}, | |||
{ | |||
"category": "a2", | |||
@@ -22,7 +24,9 @@ | |||
"vulnerabilityRating": 3, | |||
"toReviewSecurityHotspots": 1, | |||
"openSecurityHotspots": 1, | |||
"wontFixSecurityHotspots": 1 | |||
"wontFixSecurityHotspots": 1, | |||
"activeRules": 1, | |||
"totalRules": 1 | |||
}, | |||
{ | |||
"cwe": "123", | |||
@@ -30,9 +34,13 @@ | |||
"vulnerabilityRating": 3, | |||
"toReviewSecurityHotspots": 1, | |||
"openSecurityHotspots": 1, | |||
"wontFixSecurityHotspots": 1 | |||
"wontFixSecurityHotspots": 1, | |||
"activeRules": 1, | |||
"totalRules": 1 | |||
} | |||
] | |||
], | |||
"activeRules": 1, | |||
"totalRules": 1 | |||
}, | |||
{ | |||
"category": "a3", | |||
@@ -40,7 +48,9 @@ | |||
"toReviewSecurityHotspots": 0, | |||
"openSecurityHotspots": 0, | |||
"wontFixSecurityHotspots": 0, | |||
"distribution": [] | |||
"distribution": [], | |||
"activeRules": 0, | |||
"totalRules": 1 | |||
}, | |||
{ | |||
"category": "a4", | |||
@@ -48,7 +58,9 @@ | |||
"toReviewSecurityHotspots": 0, | |||
"openSecurityHotspots": 0, | |||
"wontFixSecurityHotspots": 0, | |||
"distribution": [] | |||
"distribution": [], | |||
"activeRules": 0, | |||
"totalRules": 0 | |||
}, | |||
{ | |||
"category": "a5", | |||
@@ -56,7 +68,9 @@ | |||
"toReviewSecurityHotspots": 0, | |||
"openSecurityHotspots": 0, | |||
"wontFixSecurityHotspots": 0, | |||
"distribution": [] | |||
"distribution": [], | |||
"activeRules": 0, | |||
"totalRules": 0 | |||
}, | |||
{ | |||
"category": "a6", | |||
@@ -64,7 +78,9 @@ | |||
"toReviewSecurityHotspots": 0, | |||
"openSecurityHotspots": 0, | |||
"wontFixSecurityHotspots": 0, | |||
"distribution": [] | |||
"distribution": [], | |||
"activeRules": 0, | |||
"totalRules": 0 | |||
}, | |||
{ | |||
"category": "a7", | |||
@@ -72,7 +88,9 @@ | |||
"toReviewSecurityHotspots": 0, | |||
"openSecurityHotspots": 0, | |||
"wontFixSecurityHotspots": 0, | |||
"distribution": [] | |||
"distribution": [], | |||
"activeRules": 0, | |||
"totalRules": 0 | |||
}, | |||
{ | |||
"category": "a8", | |||
@@ -80,7 +98,9 @@ | |||
"toReviewSecurityHotspots": 0, | |||
"openSecurityHotspots": 0, | |||
"wontFixSecurityHotspots": 0, | |||
"distribution": [] | |||
"distribution": [], | |||
"activeRules": 0, | |||
"totalRules": 0 | |||
}, | |||
{ | |||
"category": "a9", | |||
@@ -88,7 +108,9 @@ | |||
"toReviewSecurityHotspots": 0, | |||
"openSecurityHotspots": 0, | |||
"wontFixSecurityHotspots": 0, | |||
"distribution": [] | |||
"distribution": [], | |||
"activeRules": 0, | |||
"totalRules": 0 | |||
}, | |||
{ | |||
"category": "a10", | |||
@@ -96,7 +118,9 @@ | |||
"toReviewSecurityHotspots": 0, | |||
"openSecurityHotspots": 0, | |||
"wontFixSecurityHotspots": 0, | |||
"distribution": [] | |||
"distribution": [], | |||
"activeRules": 0, | |||
"totalRules": 0 | |||
}, | |||
{ | |||
"category": "unknown", | |||
@@ -104,7 +128,9 @@ | |||
"toReviewSecurityHotspots": 0, | |||
"openSecurityHotspots": 0, | |||
"wontFixSecurityHotspots": 0, | |||
"distribution": [] | |||
"distribution": [], | |||
"activeRules": 0, | |||
"totalRules": 1 | |||
} | |||
] | |||
} | |||
} |
@@ -6,7 +6,9 @@ | |||
"toReviewSecurityHotspots": 0, | |||
"openSecurityHotspots": 0, | |||
"wontFixSecurityHotspots": 0, | |||
"distribution": [] | |||
"distribution": [], | |||
"activeRules": 0, | |||
"totalRules": 1 | |||
}, | |||
{ | |||
"category": "risky-resource", | |||
@@ -14,7 +16,9 @@ | |||
"toReviewSecurityHotspots": 0, | |||
"openSecurityHotspots": 0, | |||
"wontFixSecurityHotspots": 0, | |||
"distribution": [] | |||
"distribution": [], | |||
"activeRules": 1, | |||
"totalRules": 1 | |||
}, | |||
{ | |||
"category": "insecure-interaction", | |||
@@ -30,7 +34,9 @@ | |||
"vulnerabilityRating": 3, | |||
"toReviewSecurityHotspots": 1, | |||
"openSecurityHotspots": 1, | |||
"wontFixSecurityHotspots": 1 | |||
"wontFixSecurityHotspots": 1, | |||
"activeRules": 1, | |||
"totalRules": 1 | |||
}, | |||
{ | |||
"cwe": "123", | |||
@@ -38,9 +44,13 @@ | |||
"vulnerabilityRating": 3, | |||
"toReviewSecurityHotspots": 1, | |||
"openSecurityHotspots": 1, | |||
"wontFixSecurityHotspots": 1 | |||
"wontFixSecurityHotspots": 1, | |||
"activeRules": 1, | |||
"totalRules": 1 | |||
} | |||
] | |||
], | |||
"activeRules": 1, | |||
"totalRules": 1 | |||
} | |||
] | |||
} | |||
} |
@@ -39,6 +39,8 @@ message SecurityStandardCategoryStatistics { | |||
optional int64 openSecurityHotspots = 5; | |||
optional int64 wontFixSecurityHotspots = 6; | |||
repeated CweStatistics distribution = 7; | |||
optional int64 activeRules = 8; | |||
optional int64 totalRules = 9; | |||
} | |||
message CweStatistics { | |||
@@ -48,6 +50,8 @@ message CweStatistics { | |||
optional int64 toReviewSecurityHotspots = 4; | |||
optional int64 openSecurityHotspots = 5; | |||
optional int64 wontFixSecurityHotspots = 6; | |||
optional int64 activeRules = 7; | |||
optional int64 totalRules = 8; | |||
} | |||