.setInternal(true) | .setInternal(true) | ||||
.setChangelog( | .setChangelog( | ||||
new Change("9.6", "Added parameters 'pciDss-3.2' and 'pciDss-4.0"), | new Change("9.6", "Added parameters 'pciDss-3.2' and 'pciDss-4.0"), | ||||
new Change("9.7", "Hotspot flows in the response may contain a description and a type")); | |||||
new Change("9.7", "Hotspot flows in the response may contain a description and a type"), | |||||
new Change("9.7", "Hotspot in the response contain the corresponding ruleKey")); | |||||
action.addPagingParams(100); | action.addPagingParams(100); | ||||
action.createParam(PARAM_PROJECT_KEY) | action.createParam(PARAM_PROJECT_KEY) | ||||
.setComponent(hotspot.getComponentKey()) | .setComponent(hotspot.getComponentKey()) | ||||
.setProject(hotspot.getProjectKey()) | .setProject(hotspot.getProjectKey()) | ||||
.setSecurityCategory(sqCategory.getKey()) | .setSecurityCategory(sqCategory.getKey()) | ||||
.setVulnerabilityProbability(sqCategory.getVulnerability().name()); | |||||
.setVulnerabilityProbability(sqCategory.getVulnerability().name()) | |||||
.setRuleKey(hotspot.getRuleKey().toString()); | |||||
ofNullable(hotspot.getStatus()).ifPresent(builder::setStatus); | ofNullable(hotspot.getStatus()).ifPresent(builder::setStatus); | ||||
ofNullable(hotspot.getResolution()).ifPresent(builder::setResolution); | ofNullable(hotspot.getResolution()).ifPresent(builder::setResolution); | ||||
ofNullable(hotspot.getLine()).ifPresent(builder::setLine); | ofNullable(hotspot.getLine()).ifPresent(builder::setLine); |
"assignee": "assignee-uuid", | "assignee": "assignee-uuid", | ||||
"author": "joe", | "author": "joe", | ||||
"creationDate": "2020-01-02T15:43:10+0100", | "creationDate": "2020-01-02T15:43:10+0100", | ||||
"updateDate": "2020-01-02T15:43:10+0100" | |||||
"updateDate": "2020-01-02T15:43:10+0100", | |||||
"flows": [], | |||||
"ruleKey": "repository-0:rule-0" | |||||
}, | }, | ||||
{ | { | ||||
"key": "hotspot-1", | "key": "hotspot-1", | ||||
"assignee": "assignee-uuid", | "assignee": "assignee-uuid", | ||||
"author": "joe", | "author": "joe", | ||||
"creationDate": "2020-01-02T15:43:10+0100", | "creationDate": "2020-01-02T15:43:10+0100", | ||||
"updateDate": "2020-01-02T15:43:10+0100" | |||||
"updateDate": "2020-01-02T15:43:10+0100", | |||||
"flows": [], | |||||
"ruleKey": "repository-1:rule-1" | |||||
}, | }, | ||||
{ | { | ||||
"key": "hotspot-2", | "key": "hotspot-2", | ||||
"assignee": "assignee-uuid", | "assignee": "assignee-uuid", | ||||
"author": "joe", | "author": "joe", | ||||
"creationDate": "2020-01-02T15:43:10+0100", | "creationDate": "2020-01-02T15:43:10+0100", | ||||
"updateDate": "2020-01-02T15:43:10+0100" | |||||
"updateDate": "2020-01-02T15:43:10+0100", | |||||
"flows": [], | |||||
"ruleKey": "repository-2:rule-2" | |||||
} | } | ||||
], | ], | ||||
"components": [ | "components": [ | ||||
"longName": "test-project" | "longName": "test-project" | ||||
} | } | ||||
] | ] | ||||
} | |||||
} |
import org.junit.runner.RunWith; | import org.junit.runner.RunWith; | ||||
import org.sonar.api.impl.utils.TestSystem2; | import org.sonar.api.impl.utils.TestSystem2; | ||||
import org.sonar.api.issue.Issue; | import org.sonar.api.issue.Issue; | ||||
import org.sonar.api.rule.RuleKey; | |||||
import org.sonar.api.rules.RuleType; | import org.sonar.api.rules.RuleType; | ||||
import org.sonar.api.server.ws.WebService; | import org.sonar.api.server.ws.WebService; | ||||
import org.sonar.api.utils.System2; | import org.sonar.api.utils.System2; | ||||
IssueDto[] hotspots = IntStream.range(0, 3) | IssueDto[] hotspots = IntStream.range(0, 3) | ||||
.mapToObj(i -> { | .mapToObj(i -> { | ||||
RuleDto rule = newRule(SECURITY_HOTSPOT) | |||||
RuleKey ruleKey = RuleKey.of("repository-"+i,"rule-"+i); | |||||
RuleDto rule = newRule(SECURITY_HOTSPOT,ruleKey) | |||||
.setSecurityStandards(Sets.newHashSet(SQCategory.WEAK_CRYPTOGRAPHY.getKey())); | .setSecurityStandards(Sets.newHashSet(SQCategory.WEAK_CRYPTOGRAPHY.getKey())); | ||||
return insertHotspot(rule, project, fileWithHotspot, issueDto -> issueDto.setKee("hotspot-" + i) | return insertHotspot(rule, project, fileWithHotspot, issueDto -> issueDto.setKee("hotspot-" + i) | ||||
.setAssigneeUuid("assignee-uuid") | .setAssigneeUuid("assignee-uuid") | ||||
.assertJson(actionTester.getDef().responseExampleAsString()); | .assertJson(actionTester.getDef().responseExampleAsString()); | ||||
} | } | ||||
@Test | |||||
public void returns_hotspots_with_ruleKey() { | |||||
ComponentDto project = dbTester.components().insertPublicProject(); | |||||
userSessionRule.registerComponents(project); | |||||
indexPermissions(); | |||||
ComponentDto file = dbTester.components().insertComponent(newFileDto(project)); | |||||
RuleDto rule1 = newRule(SECURITY_HOTSPOT); | |||||
insertHotspot(project, file, rule1); | |||||
indexIssues(); | |||||
SearchWsResponse response = newRequest(project) | |||||
.executeProtobuf(SearchWsResponse.class); | |||||
assertThat(response.getHotspotsList()) | |||||
.extracting(SearchWsResponse.Hotspot::getRuleKey) | |||||
.containsExactly(rule1.getKey().toString()); | |||||
} | |||||
private IssueDto insertHotspot(ComponentDto project, ComponentDto file, RuleDto rule) { | private IssueDto insertHotspot(ComponentDto project, ComponentDto file, RuleDto rule) { | ||||
return insertHotspot(rule, project, file, t -> { | return insertHotspot(rule, project, file, t -> { | ||||
}); | }); | ||||
}); | }); | ||||
} | } | ||||
private RuleDto newRule(RuleType ruleType, RuleKey ruleKey){ | |||||
RuleDto ruleDto = RuleTesting.newRule(ruleKey) | |||||
.setType(ruleType); | |||||
dbTester.rules().insert(ruleDto); | |||||
return ruleDto; | |||||
} | |||||
private RuleDto newRule(RuleType ruleType, Consumer<RuleDto> populate) { | private RuleDto newRule(RuleType ruleType, Consumer<RuleDto> populate) { | ||||
RuleDto ruleDto = RuleTesting.newRule() | RuleDto ruleDto = RuleTesting.newRule() | ||||
.setType(ruleType); | .setType(ruleType); |
optional string updateDate = 13; | optional string updateDate = 13; | ||||
optional sonarqube.ws.commons.TextRange textRange = 14; | optional sonarqube.ws.commons.TextRange textRange = 14; | ||||
repeated sonarqube.ws.commons.Flow flows = 15; | repeated sonarqube.ws.commons.Flow flows = 15; | ||||
optional string ruleKey = 16; | |||||
} | } | ||||
} | } | ||||