From 8d5df5c6b16493d1ecc8f9faae5925460b18b325 Mon Sep 17 00:00:00 2001 From: Belen Pruvost Date: Wed, 1 Dec 2021 10:36:41 +0100 Subject: [PATCH] SONAR-15702 - Return 403 or filter issues when user can't access child projects in app - api/issues/search - api/hotspots/search - api/governance_reports/download - api/governance_reports/subscribe - api/applications/create_branch - api/applications/update_branch --- .../tester/AbstractMockUserSession.java | 12 +++ .../sonar/server/tester/UserSessionRule.java | 5 ++ .../server/issue/index/IssueQueryFactory.java | 6 +- .../issue/index/IssueQueryFactoryTest.java | 22 ++++- .../sonar/server/hotspot/ws/SearchAction.java | 11 ++- .../sonar/server/issue/ws/SearchAction.java | 3 +- .../measure/ws/ComponentTreeAction.java | 1 + .../measure/ws/SearchHistoryAction.java | 3 +- .../projectanalysis/ws/SearchAction.java | 5 +- .../sonar/server/ui/ws/ComponentAction.java | 3 +- .../server/hotspot/ws/SearchActionTest.java | 84 +++++++++---------- .../issue/ws/SearchActionComponentsTest.java | 15 ++-- 12 files changed, 108 insertions(+), 62 deletions(-) diff --git a/server/sonar-webserver-auth/src/testFixtures/java/org/sonar/server/tester/AbstractMockUserSession.java b/server/sonar-webserver-auth/src/testFixtures/java/org/sonar/server/tester/AbstractMockUserSession.java index 9e040fb3a7c..b563be3bd23 100644 --- a/server/sonar-webserver-auth/src/testFixtures/java/org/sonar/server/tester/AbstractMockUserSession.java +++ b/server/sonar-webserver-auth/src/testFixtures/java/org/sonar/server/tester/AbstractMockUserSession.java @@ -95,6 +95,18 @@ public abstract class AbstractMockUserSession return clazz.cast(this); } + public T registerApplication(ComponentDto application, ComponentDto... appProjects) { + registerComponents(application); + registerComponents(appProjects); + + var appProjectsUuid = Arrays.stream(appProjects) + .map(ComponentDto::uuid) + .collect(Collectors.toSet()); + this.applicationProjects.put(application.uuid(), appProjectsUuid); + + return clazz.cast(this); + } + public T registerApplication(ProjectDto application, ProjectDto... appProjects) { registerProjects(application); registerProjects(appProjects); diff --git a/server/sonar-webserver-auth/src/testFixtures/java/org/sonar/server/tester/UserSessionRule.java b/server/sonar-webserver-auth/src/testFixtures/java/org/sonar/server/tester/UserSessionRule.java index c343ae92d19..6077a66fa93 100644 --- a/server/sonar-webserver-auth/src/testFixtures/java/org/sonar/server/tester/UserSessionRule.java +++ b/server/sonar-webserver-auth/src/testFixtures/java/org/sonar/server/tester/UserSessionRule.java @@ -198,6 +198,11 @@ public class UserSessionRule implements TestRule, UserSession { return this; } + public UserSessionRule registerApplication(ComponentDto application, ComponentDto... appProjects) { + ensureAbstractMockUserSession().registerApplication(application, appProjects); + return this; + } + public UserSessionRule addProjectPermission(String projectPermission, ComponentDto... components) { ensureAbstractMockUserSession().addProjectPermission(projectPermission, components); return this; diff --git a/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQueryFactory.java b/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQueryFactory.java index c41b8a9f8cd..5647bab8e1f 100644 --- a/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQueryFactory.java +++ b/server/sonar-webserver-es/src/main/java/org/sonar/server/issue/index/IssueQueryFactory.java @@ -46,7 +46,6 @@ import org.sonar.api.resources.Qualifiers; import org.sonar.api.rule.RuleKey; import org.sonar.api.rules.RuleType; import org.sonar.api.server.ServerSide; -import org.sonar.api.web.UserRole; import org.sonar.core.util.stream.MoreCollectors; import org.sonar.db.DbClient; import org.sonar.db.DbSession; @@ -68,6 +67,7 @@ import static org.sonar.api.issue.Issue.STATUS_TO_REVIEW; import static org.sonar.api.utils.DateUtils.longToDate; import static org.sonar.api.utils.DateUtils.parseEndingDateOrDateTime; import static org.sonar.api.utils.DateUtils.parseStartingDateOrDateTime; +import static org.sonar.api.web.UserRole.USER; import static org.sonar.core.util.stream.MoreCollectors.toHashSet; import static org.sonar.core.util.stream.MoreCollectors.toList; import static org.sonar.core.util.stream.MoreCollectors.toSet; @@ -304,7 +304,7 @@ public class IssueQueryFactory { private void addViewsOrSubViews(IssueQuery.Builder builder, Collection viewOrSubViewUuids) { List filteredViewUuids = viewOrSubViewUuids.stream() - .filter(uuid -> userSession.hasComponentPermission(UserRole.USER, uuid)) + .filter(uuid -> userSession.hasComponentPermission(USER, uuid)) .map(ComponentDto::uuid) .collect(Collectors.toList()); if (filteredViewUuids.isEmpty()) { @@ -315,7 +315,7 @@ public class IssueQueryFactory { private void addApplications(IssueQuery.Builder builder, DbSession dbSession, List applications, SearchRequest request) { Set authorizedApplicationUuids = applications.stream() - .filter(app -> userSession.hasComponentPermission(UserRole.USER, app)) + .filter(app -> userSession.hasComponentPermission(USER, app) && userSession.hasChildProjectsPermission(USER, app)) .map(ComponentDto::uuid) .collect(toSet()); diff --git a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueQueryFactoryTest.java b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueQueryFactoryTest.java index eba149036e2..a04621b98dd 100644 --- a/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueQueryFactoryTest.java +++ b/server/sonar-webserver-es/src/test/java/org/sonar/server/issue/index/IssueQueryFactoryTest.java @@ -290,13 +290,26 @@ public class IssueQueryFactoryTest { ComponentDto application = db.components().insertPublicApplication(); db.components().insertComponents(newProjectCopy("PC1", project1, application)); db.components().insertComponents(newProjectCopy("PC2", project2, application)); - userSession.registerComponents(application, project1, project2); + userSession.registerApplication(application, project1, project2); IssueQuery result = underTest.create(new SearchRequest().setComponentUuids(singletonList(application.uuid()))); assertThat(result.viewUuids()).containsExactlyInAnyOrder(application.uuid()); } + @Test + public void application_search_project_issues_returns_empty_if_user_cannot_access_child_projects() { + ComponentDto project1 = db.components().insertPrivateProject(); + ComponentDto project2 = db.components().insertPrivateProject(); + ComponentDto application = db.components().insertPublicApplication(); + db.components().insertComponents(newProjectCopy("PC1", project1, application)); + db.components().insertComponents(newProjectCopy("PC2", project2, application)); + + IssueQuery result = underTest.create(new SearchRequest().setComponentUuids(singletonList(application.uuid()))); + + assertThat(result.viewUuids()).containsOnly(""); + } + @Test public void application_search_project_issues_on_leak() { Date now = new Date(); @@ -310,7 +323,7 @@ public class IssueQueryFactoryTest { db.components().insertComponents(newProjectCopy("PC1", project1, application)); db.components().insertComponents(newProjectCopy("PC2", project2, application)); db.components().insertComponents(newProjectCopy("PC3", project3, application)); - userSession.registerComponents(application, project1, project2, project3); + userSession.registerApplication(application, project1, project2, project3); IssueQuery result = underTest.create(new SearchRequest() .setComponentUuids(singletonList(application.uuid())) @@ -492,7 +505,10 @@ public class IssueQueryFactoryTest { ComponentDto project2 = db.components().insertPrivateProject(); db.components().insertComponents(newProjectCopy(project1, application)); db.components().insertComponents(newProjectCopy(project2, application)); - userSession.addProjectPermission(USER, application); + userSession.registerApplication(application, project1, project2) + .addProjectPermission(USER, application) + .addProjectPermission(USER, project1) + .addProjectPermission(USER, project2); assertThat(underTest.create(new SearchRequest() .setComponents(singletonList(application.getKey()))) diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/SearchAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/SearchAction.java index 63fcd54367c..b38fd680b8f 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/SearchAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/SearchAction.java @@ -45,7 +45,6 @@ import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.Paging; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.component.BranchDto; @@ -80,6 +79,7 @@ import static org.sonar.api.server.ws.WebService.Param.PAGE_SIZE; import static org.sonar.api.utils.DateUtils.formatDateTime; import static org.sonar.api.utils.DateUtils.longToDate; import static org.sonar.api.utils.Paging.forPageIndex; +import static org.sonar.api.web.UserRole.USER; import static org.sonar.core.util.stream.MoreCollectors.toList; import static org.sonar.core.util.stream.MoreCollectors.uniqueIndex; import static org.sonar.server.security.SecurityStandards.SANS_TOP_25_INSECURE_INTERACTION; @@ -176,8 +176,10 @@ public class SearchAction implements HotspotsWsAction { WebService.NewAction action = controller .createAction("search") .setHandler(this) - .setDescription("Search for Security Hotpots." - + "
When issue indexation is in progress returns 503 service unavailable HTTP code.") + .setDescription("Search for Security Hotpots.
" + + "Requires the 'Browse' permission on the specified project(s).
" + + "For applications, it also requires 'Browse' permission on its child projects.
" + + "When issue indexation is in progress returns 503 service unavailable HTTP code.") .setSince("8.1") .setInternal(true); @@ -286,7 +288,8 @@ public class SearchAction implements HotspotsWsAction { .filter(t -> Scopes.PROJECT.equals(t.scope()) && SUPPORTED_QUALIFIERS.contains(t.qualifier())) .filter(ComponentDto::isEnabled) .orElseThrow(() -> new NotFoundException(format("Project '%s' not found", projectKey))); - userSession.checkComponentPermission(UserRole.USER, project); + userSession.checkComponentPermission(USER, project); + userSession.checkChildProjectsPermission(USER, project); return project; }); } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SearchAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SearchAction.java index 127348186d8..970b8aa9d0c 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SearchAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/SearchAction.java @@ -182,7 +182,8 @@ public class SearchAction implements IssuesWsAction { WebService.NewAction action = controller .createAction(ACTION_SEARCH) .setHandler(this) - .setDescription("Search for issues.
Requires the 'Browse' permission on the specified project(s)." + .setDescription("Search for issues.
Requires the 'Browse' permission on the specified project(s).
" + + "For applications, it also requires 'Browse' permission on its child projects." + "
When issue indexation is in progress returns 503 service unavailable HTTP code.") .setSince("3.6") .setChangelog( diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentTreeAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentTreeAction.java index 66fbe2ce9d7..f0d68708697 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentTreeAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentTreeAction.java @@ -172,6 +172,7 @@ public class ComponentTreeAction implements MeasuresWsAction { WebService.NewAction action = context.createAction(ACTION_COMPONENT_TREE) .setDescription(format("Navigate through components based on the chosen strategy with specified measures.
" + "Requires the following permission: 'Browse' on the specified project.
" + + "For applications, it also requires 'Browse' permission on its child projects.
" + "When limiting search with the %s parameter, directories are not returned.", Param.TEXT_QUERY)) .setResponseExample(getClass().getResource("component_tree-example.json")) .setSince("5.4") diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchHistoryAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchHistoryAction.java index 9cca3a1a218..192907c04f0 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchHistoryAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchHistoryAction.java @@ -88,7 +88,8 @@ public class SearchHistoryAction implements MeasuresWsAction { .setDescription("Search measures history of a component.
" + "Measures are ordered chronologically.
" + "Pagination applies to the number of measures for each metric.
" + - "Requires the following permission: 'Browse' on the specified component") + "Requires the following permission: 'Browse' on the specified component.
" + + "For applications, it also requires 'Browse' permission on its child projects.") .setResponseExample(getClass().getResource("search_history-example.json")) .setSince("6.3") .setChangelog(new Change("7.6", format("The use of module keys in parameter '%s' is deprecated", PARAM_COMPONENT))) diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectanalysis/ws/SearchAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectanalysis/ws/SearchAction.java index 745a50aa694..1cca2c75ce8 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectanalysis/ws/SearchAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectanalysis/ws/SearchAction.java @@ -76,7 +76,8 @@ public class SearchAction implements ProjectAnalysesWsAction { public void define(WebService.NewController context) { WebService.NewAction action = context.createAction("search") .setDescription("Search a project analyses and attached events.
" + - "Requires the following permission: 'Browse' on the specified project") + "Requires the following permission: 'Browse' on the specified project.
" + + "For applications, it also requires 'Browse' permission on its child projects.") .setSince("6.3") .setResponseExample(getClass().getResource("search-example.json")) .setChangelog( @@ -150,7 +151,7 @@ public class SearchAction implements ProjectAnalysesWsAction { private void addManualBaseline(SearchData.Builder data) { dbClient.branchDao().selectByUuid(data.getDbSession(), data.getProject().uuid()) .ifPresent(branchDto -> dbClient.newCodePeriodDao().selectByBranch( - data.getDbSession(), branchDto.getProjectUuid(), branchDto.getUuid()) + data.getDbSession(), branchDto.getProjectUuid(), branchDto.getUuid()) .ifPresent(newCodePeriodDto -> data.setManualBaseline(newCodePeriodDto.getValue()))); } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ui/ws/ComponentAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ui/ws/ComponentAction.java index abbcc844f42..c44a1579c42 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ui/ws/ComponentAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ui/ws/ComponentAction.java @@ -114,7 +114,8 @@ public class ComponentAction implements NavigationWsAction { public void define(NewController context) { NewAction action = context.createAction("component") .setDescription("Get information concerning component navigation for the current user. " + - "Requires the 'Browse' permission on the component's project.") + "Requires the 'Browse' permission on the component's project.
" + + "For applications, it also requires 'Browse' permission on its child projects.") .setHandler(this) .setInternal(true) .setResponseExample(getClass().getResource("component-example.json")) diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/hotspot/ws/SearchActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/hotspot/ws/SearchActionTest.java index af34743e568..bd676ba254c 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/hotspot/ws/SearchActionTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/hotspot/ws/SearchActionTest.java @@ -44,7 +44,6 @@ import org.sonar.api.issue.Issue; import org.sonar.api.rules.RuleType; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; import org.sonar.db.DbClient; import org.sonar.db.DbTester; import org.sonar.db.component.BranchDto; @@ -96,6 +95,7 @@ import static org.sonar.api.issue.Issue.STATUS_REVIEWED; import static org.sonar.api.issue.Issue.STATUS_TO_REVIEW; import static org.sonar.api.rules.RuleType.SECURITY_HOTSPOT; import static org.sonar.api.utils.DateUtils.formatDateTime; +import static org.sonar.api.web.UserRole.USER; import static org.sonar.core.util.stream.MoreCollectors.uniqueIndex; import static org.sonar.db.component.ComponentTesting.newDirectory; import static org.sonar.db.component.ComponentTesting.newFileDto; @@ -206,11 +206,11 @@ public class SearchActionTest { @DataProvider public static Object[][] badStatuses() { return Stream.concat( - Issue.STATUSES.stream(), - Stream.of(randomAlphabetic(3))) + Issue.STATUSES.stream(), + Stream.of(randomAlphabetic(3))) .filter(t -> !STATUS_REVIEWED.equals(t)) .filter(t -> !STATUS_TO_REVIEW.equals(t)) - .map(t -> new Object[] {t}) + .map(t -> new Object[]{t}) .toArray(Object[][]::new); } @@ -242,13 +242,13 @@ public class SearchActionTest { @DataProvider public static Object[][] badResolutions() { return Stream.of( - Issue.RESOLUTIONS.stream(), - Issue.SECURITY_HOTSPOT_RESOLUTIONS.stream(), - Stream.of(randomAlphabetic(4))) + Issue.RESOLUTIONS.stream(), + Issue.SECURITY_HOTSPOT_RESOLUTIONS.stream(), + Stream.of(randomAlphabetic(4))) .flatMap(t -> t) .filter(t -> !RESOLUTION_FIXED.equals(t)) .filter(t -> !RESOLUTION_SAFE.equals(t)) - .map(t -> new Object[] {t}) + .map(t -> new Object[]{t}) .toArray(Object[][]::new); } @@ -279,7 +279,7 @@ public class SearchActionTest { @DataProvider public static Object[][] fixedOrSafeResolution() { - return new Object[][] { + return new Object[][]{ {RESOLUTION_SAFE}, {RESOLUTION_FIXED} }; @@ -350,7 +350,7 @@ public class SearchActionTest { @Test public void succeeds_on_public_application() { ComponentDto application = dbTester.components().insertPublicApplication(); - userSessionRule.registerComponents(application); + userSessionRule.registerApplication(application); SearchWsResponse response = newRequest(application) .executeProtobuf(SearchWsResponse.class); @@ -363,7 +363,7 @@ public class SearchActionTest { public void succeeds_on_private_project_with_permission() { ComponentDto project = dbTester.components().insertPrivateProject(); userSessionRule.registerComponents(project); - userSessionRule.logIn().addProjectPermission(UserRole.USER, project); + userSessionRule.logIn().addProjectPermission(USER, project); SearchWsResponse response = newRequest(project) .executeProtobuf(SearchWsResponse.class); @@ -375,8 +375,7 @@ public class SearchActionTest { @Test public void succeeds_on_private_application_with_permission() { ComponentDto application = dbTester.components().insertPrivateApplication(); - userSessionRule.registerComponents(application); - userSessionRule.logIn().addProjectPermission(UserRole.USER, application); + userSessionRule.logIn().registerApplication(application).addProjectPermission(USER, application); SearchWsResponse response = newRequest(application) .executeProtobuf(SearchWsResponse.class); @@ -561,7 +560,8 @@ public class SearchActionTest { dbTester.components().insertComponent(ComponentTesting.newProjectCopy(project1, application1)); dbTester.components().insertComponent(ComponentTesting.newProjectCopy(project2, application2)); indexViews(); - userSessionRule.registerComponents(application1, application2, project1, project2); + userSessionRule.registerApplication(application1, project1) + .registerApplication(application2, project2); indexPermissions(); ComponentDto file1 = dbTester.components().insertComponent(newFileDto(project1)); ComponentDto file2 = dbTester.components().insertComponent(newFileDto(project2)); @@ -604,7 +604,7 @@ public class SearchActionTest { dbTester.components().insertComponent(ComponentTesting.newProjectCopy(project1, application)); dbTester.components().insertComponent(ComponentTesting.newProjectCopy(project2, applicationBranch)); indexViews(); - userSessionRule.registerComponents(application, applicationBranch, project1, project2); + userSessionRule.registerApplication(application, applicationBranch, project1, project2); indexPermissions(); ComponentDto file1 = dbTester.components().insertComponent(newFileDto(project1)); ComponentDto file2 = dbTester.components().insertComponent(newFileDto(project2)); @@ -731,7 +731,7 @@ public class SearchActionTest { @DataProvider public static Object[][] onlyMineParamValues() { - return new Object[][] { + return new Object[][]{ {"yes", true}, {"true", true}, {"no", false}, @@ -744,7 +744,7 @@ public class SearchActionTest { ComponentDto project = dbTester.components().insertPrivateProject(); userSessionRule.registerComponents(project); - userSessionRule.logIn().addProjectPermission(UserRole.USER, project); + userSessionRule.logIn().addProjectPermission(USER, project); TestRequest request = actionTester.newRequest() .setParam("hotspots", IntStream.range(2, 10).mapToObj(String::valueOf).collect(joining(","))) @@ -926,7 +926,7 @@ public class SearchActionTest { @DataProvider public static Object[][] validStatusesAndResolutions() { - return new Object[][] { + return new Object[][]{ {STATUS_TO_REVIEW, null}, {STATUS_REVIEWED, RESOLUTION_FIXED}, {STATUS_REVIEWED, RESOLUTION_SAFE}, @@ -957,13 +957,13 @@ public class SearchActionTest { public static Object[][] allSQCategories() { Stream allCategoriesButOTHERS = SecurityStandards.CWES_BY_SQ_CATEGORY.entrySet() .stream() - .map(t -> new Object[] { + .map(t -> new Object[]{ t.getValue().stream().map(c -> "cwe:" + c).collect(toSet()), t.getKey() }); Stream sqCategoryOTHERS = Stream.of( - new Object[] {Collections.emptySet(), SQCategory.OTHERS}, - new Object[] {of("foo", "donut", "acme"), SQCategory.OTHERS}); + new Object[]{Collections.emptySet(), SQCategory.OTHERS}, + new Object[]{of("foo", "donut", "acme"), SQCategory.OTHERS}); return Stream.concat(allCategoriesButOTHERS, sqCategoryOTHERS).toArray(Object[][]::new); } @@ -1161,14 +1161,14 @@ public class SearchActionTest { ComponentDto file3 = dbTester.components().insertComponent(newFileDto(project).setPath("a/a/d")); RuleDefinitionDto rule = newRule(SECURITY_HOTSPOT); List hotspots = Stream.of( - newHotspot(rule, project, file3).setLine(8), - newHotspot(rule, project, file3).setLine(10), - newHotspot(rule, project, file1).setLine(null), - newHotspot(rule, project, file1).setLine(9), - newHotspot(rule, project, file1).setLine(11).setKee("a"), - newHotspot(rule, project, file1).setLine(11).setKee("b"), - newHotspot(rule, project, file2).setLine(null), - newHotspot(rule, project, file2).setLine(2)) + newHotspot(rule, project, file3).setLine(8), + newHotspot(rule, project, file3).setLine(10), + newHotspot(rule, project, file1).setLine(null), + newHotspot(rule, project, file1).setLine(9), + newHotspot(rule, project, file1).setLine(11).setKee("a"), + newHotspot(rule, project, file1).setLine(11).setKee("b"), + newHotspot(rule, project, file2).setLine(null), + newHotspot(rule, project, file2).setLine(2)) .collect(toList()); String[] expectedHotspotKeys = hotspots.stream().map(IssueDto::getKey).toArray(String[]::new); // insert hotspots in random order @@ -1465,21 +1465,21 @@ public class SearchActionTest { assertThat(responseAll.getHotspotsList()) .extracting(SearchWsResponse.Hotspot::getKey) .containsExactlyInAnyOrder(Stream.of( - hotspotsInLeakPeriod.stream(), - atLeakPeriod.stream(), - hotspotsBefore.stream()) + hotspotsInLeakPeriod.stream(), + atLeakPeriod.stream(), + hotspotsBefore.stream()) .flatMap(t -> t) .map(IssueDto::getKey) .toArray(String[]::new)); SearchWsResponse responseOnLeak = newRequest(project, t -> t.setParam("sinceLeakPeriod", "true")) - .executeProtobuf(SearchWsResponse.class); + .executeProtobuf(SearchWsResponse.class); assertThat(responseOnLeak.getHotspotsList()) .extracting(SearchWsResponse.Hotspot::getKey) .containsExactlyInAnyOrder(Stream.concat( - hotspotsInLeakPeriod.stream(), - atLeakPeriod.stream()) + hotspotsInLeakPeriod.stream(), + atLeakPeriod.stream()) .map(IssueDto::getKey) .toArray(String[]::new)); } @@ -1511,7 +1511,7 @@ public class SearchActionTest { SearchWsResponse responseOnLeak = newRequest(project, t -> t.setParam("sinceLeakPeriod", "true")) - .executeProtobuf(SearchWsResponse.class); + .executeProtobuf(SearchWsResponse.class); assertThat(responseOnLeak.getHotspotsList()).isEmpty(); } @@ -1543,7 +1543,7 @@ public class SearchActionTest { SearchWsResponse responseOnLeak = newRequest(project, t -> t.setParam("sinceLeakPeriod", "true").setParam("pullRequest", "pr")) - .executeProtobuf(SearchWsResponse.class); + .executeProtobuf(SearchWsResponse.class); assertThat(responseOnLeak.getHotspotsList()).hasSize(3); } @@ -1564,7 +1564,7 @@ public class SearchActionTest { indexViews(); - userSessionRule.registerComponents(application, project, project2); + userSessionRule.registerApplication(application, project, project2); indexPermissions(); ComponentDto file = dbTester.components().insertComponent(newFileDto(project)); dbTester.components().insertSnapshot(project, t -> t.setPeriodDate(referenceDate).setLast(true)); @@ -1586,7 +1586,7 @@ public class SearchActionTest { 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()); @@ -1619,7 +1619,7 @@ public class SearchActionTest { indexViews(); - userSessionRule.registerProjects(application, project, project2); + userSessionRule.registerApplication(application, project, project2); indexPermissions(); ComponentDto file = dbTester.components().insertComponent(newFileDto(projectBranchComponentDto)); @@ -1638,14 +1638,14 @@ public class SearchActionTest { ComponentDto applicationComponentDto = dbClient.componentDao().selectByUuid(dbTester.getSession(), application.getUuid()).get(); SearchWsResponse responseAll = newRequest(applicationComponentDto, t -> t.setParam("branch", applicationBranch.getKey())) - .executeProtobuf(SearchWsResponse.class); + .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); + .executeProtobuf(SearchWsResponse.class); assertThat(responseOnLeak.getHotspotsList()) .extracting(SearchWsResponse.Hotspot::getKey) .containsExactlyInAnyOrder(afterRef.getKey()); diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ws/SearchActionComponentsTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ws/SearchActionComponentsTest.java index c0a0c6df7b1..97a1f0b7a4c 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ws/SearchActionComponentsTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ws/SearchActionComponentsTest.java @@ -407,7 +407,7 @@ public class SearchActionComponentsTest { RuleDefinitionDto rule = db.rules().insertIssueRule(); IssueDto issue1 = db.issues().insertIssue(rule, project1, project1); IssueDto issue2 = db.issues().insertIssue(rule, project2, project2); - allowAnyoneOnProjects(project1, project2, application); + allowAnyoneOnApplication(application, project1, project2); userSession.addProjectPermission(USER, application); indexIssuesAndViews(); @@ -520,7 +520,7 @@ public class SearchActionComponentsTest { IssueDto project2Issue1 = db.issues().insertIssue(rule, project2, project2, i -> i.setIssueCreationDate(addDays(now, -15))); IssueDto project2Issue2 = db.issues().insertIssue(rule, project2, project2, i -> i.setIssueCreationDate(addDays(now, -30))); // Permissions and index - allowAnyoneOnProjects(project1, project2, application); + allowAnyoneOnApplication(application, project1, project2); indexIssuesAndViews(); SearchWsResponse result = ws.newRequest() @@ -543,7 +543,7 @@ public class SearchActionComponentsTest { RuleDefinitionDto rule = db.rules().insertIssueRule(); IssueDto issue1 = db.issues().insertIssue(rule, project1, project1); IssueDto issue2 = db.issues().insertIssue(rule, project2, project2); - allowAnyoneOnProjects(project1, project2, application); + allowAnyoneOnApplication(application, project1, project2); indexIssuesAndViews(); SearchWsResponse result = ws.newRequest() @@ -574,7 +574,7 @@ public class SearchActionComponentsTest { IssueDto project2Issue1 = db.issues().insertIssue(rule, project2, project2, i -> i.setIssueCreationDate(addDays(now, -15))); IssueDto project2Issue2 = db.issues().insertIssue(rule, project2, project2, i -> i.setIssueCreationDate(addDays(now, -30))); // Permissions and index - allowAnyoneOnProjects(project1, project2, application); + allowAnyoneOnApplication(application, project1, project2); indexIssuesAndViews(); SearchWsResponse result = ws.newRequest() @@ -606,7 +606,7 @@ public class SearchActionComponentsTest { IssueDto project2Issue1 = db.issues().insertIssue(rule, project2, project2, i -> i.setIssueCreationDate(addDays(now, -15))); IssueDto project2Issue2 = db.issues().insertIssue(rule, project2, project2, i -> i.setIssueCreationDate(addDays(now, -30))); // Permissions and index - allowAnyoneOnProjects(project1, project2, application); + allowAnyoneOnApplication(application, project1, project2); indexIssuesAndViews(); SearchWsResponse result = ws.newRequest() @@ -774,6 +774,11 @@ public class SearchActionComponentsTest { Arrays.stream(projects).forEach(p -> permissionIndexer.allowOnlyAnyone(p)); } + private void allowAnyoneOnApplication(ComponentDto application, ComponentDto... projects) { + userSession.registerApplication(application); + Arrays.stream(projects).forEach(p -> permissionIndexer.allowOnlyAnyone(p)); + } + private void indexIssues() { issueIndexer.indexAllIssues(); } -- 2.39.5