import org.sonar.api.web.UserRole;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
+import org.sonar.db.component.BranchDto;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.SnapshotDto;
import org.sonar.db.issue.IssueDto;
import static org.sonar.api.utils.DateUtils.longToDate;
import static org.sonar.api.utils.Paging.forPageIndex;
import static org.sonar.core.util.stream.MoreCollectors.toList;
-import static org.sonar.core.util.stream.MoreCollectors.toSet;
import static org.sonar.core.util.stream.MoreCollectors.uniqueIndex;
import static org.sonar.server.security.SecurityStandards.SANS_TOP_25_INSECURE_INTERACTION;
import static org.sonar.server.security.SecurityStandards.SANS_TOP_25_POROUS_DEFENSES;
}
private SearchResponse doIndexSearch(WsRequest wsRequest, DbSession dbSession, @Nullable ComponentDto project) {
- IssueQuery.Builder builder = IssueQuery.builder()
+ var builder = IssueQuery.builder()
.types(singleton(RuleType.SECURITY_HOTSPOT.name()))
.sort(IssueQuery.SORT_HOTSPOTS)
.asc(true)
String projectUuid = firstNonNull(project.getMainBranchProjectUuid(), project.uuid());
if (Qualifiers.APP.equals(project.qualifier())) {
builder.viewUuids(singletonList(projectUuid));
- addCreatedAfterByProjects(builder, dbSession, wsRequest, project);
+ if (wsRequest.isSinceLeakPeriod() && wsRequest.getPullRequest().isEmpty()) {
+ addCreatedAfterByProjects(builder, dbSession, project);
+ }
} else {
builder.projectUuids(singletonList(projectUuid));
- if (wsRequest.isSinceLeakPeriod() && !wsRequest.getPullRequest().isPresent()) {
- Date sinceDate = dbClient.snapshotDao().selectLastAnalysisByComponentUuid(dbSession, project.uuid())
+ if (wsRequest.isSinceLeakPeriod() && wsRequest.getPullRequest().isEmpty()) {
+ var sinceDate = dbClient.snapshotDao().selectLastAnalysisByComponentUuid(dbSession, project.uuid())
.map(s -> longToDate(s.getPeriodDate()))
.orElseGet(() -> new Date(system2.now()));
builder.createdAfter(sinceDate, false);
return issueIndex.search(query, searchOptions);
}
- private void addCreatedAfterByProjects(IssueQuery.Builder builder, DbSession dbSession, WsRequest wsRequest, ComponentDto application) {
- if (!wsRequest.isSinceLeakPeriod() || wsRequest.getPullRequest().isPresent()) {
- return;
+ private void addCreatedAfterByProjects(IssueQuery.Builder builder, DbSession dbSession, ComponentDto application) {
+ Set<String> projectUuids;
+ if (application.getMainBranchProjectUuid() == null) {
+ projectUuids = dbClient.applicationProjectsDao().selectProjects(dbSession, application.uuid()).stream()
+ .map(ProjectDto::getUuid)
+ .collect(Collectors.toSet());
+ } else {
+ projectUuids = dbClient.applicationProjectsDao().selectProjectBranchesFromAppBranch(dbSession, application.uuid()).stream()
+ .map(BranchDto::getUuid)
+ .collect(Collectors.toSet());
}
- Set<String> projectUuids = dbClient.applicationProjectsDao().selectProjects(dbSession, application.uuid()).stream()
- .map(ProjectDto::getUuid)
- .collect(Collectors.toSet());
long now = system2.now();
Map<String, IssueQuery.PeriodStart> leakByProjects = dbClient.snapshotDao().selectLastAnalysesByRootComponentUuids(dbSession, projectUuids).stream()
- .collect(uniqueIndex(SnapshotDto::getComponentUuid, s ->
- new IssueQuery.PeriodStart(longToDate(s.getPeriodDate() == null ? now : s.getPeriodDate()), false)));
+ .collect(uniqueIndex(SnapshotDto::getComponentUuid, s -> new IssueQuery.PeriodStart(longToDate(s.getPeriodDate() == null ? now : s.getPeriodDate()), false)));
builder.createdAfterByProjectUuids(leakByProjects);
}
import org.sonar.api.web.UserRole;
import org.sonar.db.DbClient;
import org.sonar.db.DbTester;
+import org.sonar.db.component.BranchDto;
import org.sonar.db.component.BranchType;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ComponentTesting;
}
@Test
- public void returns_issues_when_sinceLeakPeriod_is_true_and_is_application() {
+ public void returns_issues_when_sinceLeakPeriod_is_true_and_is_application_for_main_branch() {
long referenceDate = 800_996_999_332L;
system2.setNow(referenceDate + 10_000);
SearchWsResponse responseOnLeak = newRequest(application,
t -> t.setParam("sinceLeakPeriod", "true"))
- .executeProtobuf(SearchWsResponse.class);
+ .executeProtobuf(SearchWsResponse.class);
assertThat(responseOnLeak.getHotspotsList())
.extracting(SearchWsResponse.Hotspot::getKey)
.containsExactlyInAnyOrder(afterRef.getKey());
+ }
+
+ @Test
+ public void returns_issues_when_sinceLeakPeriod_is_true_and_is_application_for_branch_other_than_main() {
+ long referenceDate = 800_996_999_332L;
+
+ system2.setNow(referenceDate + 10_000);
+ ProjectDto application = dbTester.components().insertPublicApplicationDto();
+ BranchDto applicationBranch = dbTester.components().insertProjectBranch(application, branchDto -> branchDto.setKey("application_branch_1"));
+ ProjectDto project = dbTester.components().insertPublicProjectDto();
+ BranchDto projectBranch = dbTester.components().insertProjectBranch(project, branchDto -> branchDto.setKey("project_1_branch_1"));
+
+ ProjectDto project2 = dbTester.components().insertPublicProjectDto();
+ BranchDto project2Branch = dbTester.components().insertProjectBranch(project2, branchDto -> branchDto.setKey("project_2_branch_1"));
+
+ dbTester.components().addApplicationProject(application, project);
+ dbTester.components().addApplicationProject(application, project2);
+
+ dbTester.components().addProjectBranchToApplicationBranch(applicationBranch, projectBranch, project2Branch);
+
+ ComponentDto applicationBranchComponentDto = dbClient.componentDao().selectByUuid(dbTester.getSession(), applicationBranch.getUuid()).get();
+ ComponentDto projectBranchComponentDto = dbClient.componentDao().selectByUuid(dbTester.getSession(), projectBranch.getUuid()).get();
+ ComponentDto project2BranchComponentDto = dbClient.componentDao().selectByUuid(dbTester.getSession(), project2Branch.getUuid()).get();
+
+ dbTester.components().insertComponent(ComponentTesting.newProjectCopy(projectBranchComponentDto, applicationBranchComponentDto));
+ dbTester.components().insertComponent(ComponentTesting.newProjectCopy(project2BranchComponentDto, applicationBranchComponentDto));
+
+ indexViews();
+ userSessionRule.registerProjects(application, project, project2);
+ indexPermissions();
+
+ ComponentDto file = dbTester.components().insertComponent(newFileDto(projectBranchComponentDto));
+ dbTester.components().insertSnapshot(projectBranch, t -> t.setPeriodDate(referenceDate).setLast(true));
+
+ RuleDefinitionDto rule = newRule(SECURITY_HOTSPOT);
+ IssueDto afterRef = dbTester.issues().insertHotspot(rule, projectBranchComponentDto, file, t -> t.setIssueCreationTime(referenceDate + 1000));
+ IssueDto atRef = dbTester.issues().insertHotspot(rule, projectBranchComponentDto, file, t -> t.setType(SECURITY_HOTSPOT).setIssueCreationTime(referenceDate));
+ IssueDto beforeRef = dbTester.issues().insertHotspot(rule, projectBranchComponentDto, file, t -> t.setIssueCreationTime(referenceDate - 1000));
+
+ ComponentDto file2 = dbTester.components().insertComponent(newFileDto(project2BranchComponentDto));
+ IssueDto project2Issue = dbTester.issues().insertHotspot(rule, project2BranchComponentDto, file2, t -> t.setIssueCreationTime(referenceDate - 1000));
+
+ indexIssues();
+
+ ComponentDto applicationComponentDto = dbClient.componentDao().selectByUuid(dbTester.getSession(), application.getUuid()).get();
+ SearchWsResponse responseAll = newRequest(applicationComponentDto,
+ t -> t.setParam("branch", applicationBranch.getKey()))
+ .executeProtobuf(SearchWsResponse.class);
+ assertThat(responseAll.getHotspotsList())
+ .extracting(SearchWsResponse.Hotspot::getKey)
+ .containsExactlyInAnyOrder(afterRef.getKey(), atRef.getKey(), beforeRef.getKey(), project2Issue.getKey());
+
+ SearchWsResponse responseOnLeak = newRequest(applicationComponentDto,
+ t -> t.setParam("sinceLeakPeriod", "true").setParam("branch", applicationBranch.getKey()))
+ .executeProtobuf(SearchWsResponse.class);
+ assertThat(responseOnLeak.getHotspotsList())
+ .extracting(SearchWsResponse.Hotspot::getKey)
+ .containsExactlyInAnyOrder(afterRef.getKey());
}
@Test