3 * Copyright (C) 2009-2022 SonarSource SA
4 * mailto:info AT sonarsource DOT com
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 3 of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 package org.sonar.server.project.ws;
22 import java.util.Arrays;
23 import java.util.Random;
25 import java.util.stream.IntStream;
26 import java.util.stream.Stream;
27 import org.junit.Rule;
28 import org.junit.Test;
29 import org.sonar.api.config.Configuration;
30 import org.sonar.api.resources.Qualifiers;
31 import org.sonar.api.resources.ResourceTypes;
32 import org.sonar.api.server.ws.WebService;
33 import org.sonar.api.utils.System2;
34 import org.sonar.api.web.UserRole;
35 import org.sonar.core.util.SequenceUuidFactory;
36 import org.sonar.core.util.Uuids;
37 import org.sonar.core.util.stream.MoreCollectors;
38 import org.sonar.db.DbClient;
39 import org.sonar.db.DbSession;
40 import org.sonar.db.DbTester;
41 import org.sonar.db.ce.CeQueueDto;
42 import org.sonar.db.component.BranchDto;
43 import org.sonar.db.component.ComponentDto;
44 import org.sonar.db.component.ComponentTesting;
45 import org.sonar.db.component.ResourceTypesRule;
46 import org.sonar.db.permission.GlobalPermission;
47 import org.sonar.db.permission.GroupPermissionDto;
48 import org.sonar.db.permission.UserPermissionDto;
49 import org.sonar.db.user.GroupDto;
50 import org.sonar.db.user.UserDto;
51 import org.sonar.server.component.TestComponentFinder;
52 import org.sonar.server.es.EsTester;
53 import org.sonar.server.es.ProjectIndexer;
54 import org.sonar.server.es.TestProjectIndexers;
55 import org.sonar.server.exceptions.BadRequestException;
56 import org.sonar.server.exceptions.ForbiddenException;
57 import org.sonar.server.exceptions.NotFoundException;
58 import org.sonar.server.exceptions.UnauthorizedException;
59 import org.sonar.server.permission.PermissionService;
60 import org.sonar.server.permission.PermissionServiceImpl;
61 import org.sonar.server.permission.index.FooIndexDefinition;
62 import org.sonar.server.tester.UserSessionRule;
63 import org.sonar.server.ws.TestRequest;
64 import org.sonar.server.ws.WsActionTester;
66 import static java.lang.String.format;
67 import static java.util.Arrays.stream;
68 import static java.util.Optional.of;
69 import static org.assertj.core.api.Assertions.assertThat;
70 import static org.assertj.core.api.Assertions.assertThatThrownBy;
71 import static org.assertj.core.api.Assertions.fail;
72 import static org.mockito.Mockito.mock;
73 import static org.mockito.Mockito.when;
74 import static org.sonar.api.CoreProperties.CORE_ALLOW_PERMISSION_MANAGEMENT_FOR_PROJECT_ADMINS_PROPERTY;
75 import static org.sonar.db.component.ComponentTesting.newProjectCopy;
77 public class UpdateVisibilityActionTest {
78 private static final String PARAM_VISIBILITY = "visibility";
79 private static final String PARAM_PROJECT = "project";
80 private static final String PUBLIC = "public";
81 private static final String PRIVATE = "private";
83 private static final Set<String> GLOBAL_PERMISSIONS_NAME_SET = stream(GlobalPermission.values()).map(GlobalPermission::getKey)
84 .collect(MoreCollectors.toSet(GlobalPermission.values().length));
87 public final DbTester dbTester = DbTester.create(System2.INSTANCE);
89 public final EsTester es = EsTester.createCustom(new FooIndexDefinition());
91 public final UserSessionRule userSessionRule = UserSessionRule.standalone().logIn();
93 private final ResourceTypes resourceTypes = new ResourceTypesRule().setRootQualifiers(Qualifiers.PROJECT);
94 private final PermissionService permissionService = new PermissionServiceImpl(resourceTypes);
95 private final Set<String> PROJECT_PERMISSIONS_BUT_USER_AND_CODEVIEWER = permissionService.getAllProjectPermissions().stream()
96 .filter(perm -> !perm.equals(UserRole.USER) && !perm.equals(UserRole.CODEVIEWER))
97 .collect(MoreCollectors.toSet(permissionService.getAllProjectPermissions().size() - 2));
99 private final DbClient dbClient = dbTester.getDbClient();
100 private final DbSession dbSession = dbTester.getSession();
101 private final TestProjectIndexers projectIndexers = new TestProjectIndexers();
102 private final Configuration configuration = mock(Configuration.class);
104 private final UpdateVisibilityAction underTest = new UpdateVisibilityAction(dbClient, TestComponentFinder.from(dbTester),
105 userSessionRule, projectIndexers, new SequenceUuidFactory(), configuration);
106 private final WsActionTester ws = new WsActionTester(underTest);
108 private final Random random = new Random();
109 private final String randomVisibility = random.nextBoolean() ? PUBLIC : PRIVATE;
110 private final TestRequest request = ws.newRequest();
113 public void definition() {
114 WebService.Action definition = ws.getDef();
116 assertThat(definition.key()).isEqualTo("update_visibility");
117 assertThat(definition.isPost()).isTrue();
118 assertThat(definition.since()).isEqualTo("6.4");
119 assertThat(definition.params()).extracting(WebService.Param::key).containsExactlyInAnyOrder("project", "visibility");
123 public void execute_fails_if_user_is_not_logged_in() {
124 userSessionRule.anonymous();
126 assertThatThrownBy(request::execute)
127 .isInstanceOf(UnauthorizedException.class)
128 .hasMessage("Authentication is required");
132 public void execute_fails_with_IAE_when_project_parameter_is_not_provided() {
133 assertThatThrownBy(request::execute)
134 .isInstanceOf(IllegalArgumentException.class)
135 .hasMessage("The 'project' parameter is missing");
139 public void execute_fails_with_IAE_when_project_parameter_is_not_empty() {
140 assertThatThrownBy(request::execute)
141 .isInstanceOf(IllegalArgumentException.class)
142 .hasMessage("The 'project' parameter is missing");
146 public void execute_fails_with_IAE_when_parameter_visibility_is_not_provided() {
147 request.setParam(PARAM_PROJECT, "foo");
149 assertThatThrownBy(request::execute)
150 .isInstanceOf(IllegalArgumentException.class)
151 .hasMessage("The 'visibility' parameter is missing");
155 public void execute_fails_with_IAE_when_parameter_visibility_is_empty() {
156 request.setParam(PARAM_PROJECT, "foo")
157 .setParam(PARAM_VISIBILITY, "");
159 assertThatThrownBy(request::execute)
160 .isInstanceOf(IllegalArgumentException.class)
161 .hasMessage("Value of parameter '" + PARAM_VISIBILITY + "' () must be one of: [private, public]");
165 public void execute_fails_with_IAE_when_value_of_parameter_visibility_is_not_lowercase() {
166 request.setParam(PARAM_PROJECT, "foo");
168 Stream.of("PUBLIC", "pUBliC", "PRIVATE", "PrIVAtE")
169 .forEach(visibility -> {
171 request.setParam(PARAM_VISIBILITY, visibility).execute();
172 fail("An exception should have been raised");
173 } catch (IllegalArgumentException e) {
174 assertThat(e.getMessage()).isEqualTo(format("Value of parameter '%s' (%s) must be one of: [private, public]", PARAM_VISIBILITY, visibility));
180 public void execute_fails_with_NotFoundException_when_specified_component_does_not_exist() {
181 request.setParam(PARAM_PROJECT, "foo")
182 .setParam(PARAM_VISIBILITY, randomVisibility);
184 assertThatThrownBy(request::execute)
185 .isInstanceOf(NotFoundException.class)
186 .hasMessage("Component key 'foo' not found");
190 public void execute_fails_with_BadRequestException_if_specified_component_is_neither_a_project_a_portfolio_nor_an_application() {
191 ComponentDto project = randomPublicOrPrivateProject();
192 ComponentDto module = ComponentTesting.newModuleDto(project);
193 ComponentDto dir = ComponentTesting.newDirectory(project, "path");
194 ComponentDto file = ComponentTesting.newFileDto(project);
195 dbTester.components().insertComponents(module, dir, file);
196 ComponentDto application = dbTester.components().insertPublicApplication();
197 ComponentDto portfolio = dbTester.components().insertPrivatePortfolio();
198 ComponentDto subView = ComponentTesting.newSubPortfolio(portfolio);
199 ComponentDto projectCopy = newProjectCopy("foo", project, subView);
200 dbTester.components().insertComponents(subView, projectCopy);
201 userSessionRule.addProjectPermission(UserRole.ADMIN, project, portfolio, application);
203 Stream.of(project, portfolio, application).forEach(c -> request
204 .setParam(PARAM_PROJECT, c.getKey())
205 .setParam(PARAM_VISIBILITY, randomVisibility)
208 Stream.of(module, dir, file, subView, projectCopy)
209 .forEach(nonRootComponent -> {
210 request.setParam(PARAM_PROJECT, nonRootComponent.getKey())
211 .setParam(PARAM_VISIBILITY, randomVisibility);
215 fail("a BadRequestException should have been raised");
216 } catch (BadRequestException e) {
217 assertThat(e.getMessage()).isEqualTo("Component must be a project, a portfolio or an application");
223 public void execute_throws_ForbiddenException_if_user_has_no_permission_on_specified_component() {
224 ComponentDto project = dbTester.components().insertPrivateProject();
225 request.setParam(PARAM_PROJECT, project.getKey())
226 .setParam(PARAM_VISIBILITY, randomVisibility);
228 assertThatThrownBy(request::execute)
229 .isInstanceOf(ForbiddenException.class)
230 .hasMessage("Insufficient privileges");
234 public void execute_throws_ForbiddenException_if_user_has_all_permissions_but_ADMIN_on_specified_component() {
235 ComponentDto project = dbTester.components().insertPublicProject();
236 request.setParam(PARAM_PROJECT, project.getKey())
237 .setParam(PARAM_VISIBILITY, randomVisibility);
238 userSessionRule.addProjectPermission(UserRole.ISSUE_ADMIN, project);
239 Arrays.stream(GlobalPermission.values())
240 .forEach(userSessionRule::addPermission);
242 assertThatThrownBy(request::execute)
243 .isInstanceOf(ForbiddenException.class)
244 .hasMessage("Insufficient privileges");
249 public void execute_throws_ForbiddenException_if_user_has_ADMIN_permission_but_sonar_allowPermissionManagementForProjectAdmins_is_set_to_false() {
250 when(configuration.getBoolean(CORE_ALLOW_PERMISSION_MANAGEMENT_FOR_PROJECT_ADMINS_PROPERTY)).thenReturn(of(false));
251 ComponentDto project = dbTester.components().insertPublicProject();
252 request.setParam(PARAM_PROJECT, project.getKey())
253 .setParam(PARAM_VISIBILITY, randomVisibility);
254 userSessionRule.addProjectPermission(UserRole.ADMIN, project);
256 assertThatThrownBy(request::execute)
257 .isInstanceOf(ForbiddenException.class)
258 .hasMessage("Insufficient privileges");
262 public void execute_throws_ForbiddenException_if_user_has_global_ADMIN_permission_even_if_sonar_allowPermissionManagementForProjectAdmins_is_set_to_false() {
263 when(configuration.getBoolean(CORE_ALLOW_PERMISSION_MANAGEMENT_FOR_PROJECT_ADMINS_PROPERTY)).thenReturn(of(false));
264 ComponentDto project = dbTester.components().insertPublicProject();
265 userSessionRule.setSystemAdministrator().addProjectPermission(UserRole.ADMIN, project);
266 request.setParam(PARAM_PROJECT, project.getKey())
267 .setParam(PARAM_VISIBILITY, "private");
271 assertThat(isPrivateInDb(project)).isTrue();
275 public void execute_throws_BadRequestException_if_specified_component_has_pending_tasks() {
276 ComponentDto project = randomPublicOrPrivateProject();
277 IntStream.range(0, 1 + Math.abs(random.nextInt(5)))
278 .forEach(i -> insertPendingTask(project));
279 request.setParam(PARAM_PROJECT, project.getKey())
280 .setParam(PARAM_VISIBILITY, randomVisibility);
281 userSessionRule.addProjectPermission(UserRole.ADMIN, project);
283 assertThatThrownBy(request::execute)
284 .isInstanceOf(BadRequestException.class)
285 .hasMessage("Component visibility can't be changed as long as it has background task(s) pending or in progress");
289 public void execute_throws_BadRequestException_if_main_component_of_specified_component_has_in_progress_tasks() {
290 ComponentDto project = randomPublicOrPrivateProject();
291 IntStream.range(0, 1 + Math.abs(random.nextInt(5)))
292 .forEach(i -> insertInProgressTask(project));
293 request.setParam(PARAM_PROJECT, project.getKey())
294 .setParam(PARAM_VISIBILITY, randomVisibility);
295 userSessionRule.addProjectPermission(UserRole.ADMIN, project);
297 assertThatThrownBy(request::execute)
298 .isInstanceOf(BadRequestException.class)
299 .hasMessage("Component visibility can't be changed as long as it has background task(s) pending or in progress");
303 public void execute_changes_private_flag_of_specified_project_and_all_children_to_specified_new_visibility() {
304 ComponentDto project = randomPublicOrPrivateProject();
305 boolean initiallyPrivate = project.isPrivate();
307 BranchDto branchDto = ComponentTesting.newBranchDto(project);
308 dbClient.branchDao().insert(dbSession, branchDto);
310 ComponentDto branch = ComponentTesting.newBranchComponent(project, branchDto);
311 ComponentDto module = ComponentTesting.newModuleDto(project);
312 ComponentDto dir = ComponentTesting.newDirectory(project, "path");
313 ComponentDto file = ComponentTesting.newFileDto(project);
315 dbTester.components().insertComponents(branch, module, dir, file);
316 userSessionRule.addProjectPermission(UserRole.ADMIN, project);
318 request.setParam(PARAM_PROJECT, project.getKey())
319 .setParam(PARAM_VISIBILITY, initiallyPrivate ? PUBLIC : PRIVATE)
322 assertThat(isPrivateInDb(project)).isEqualTo(!initiallyPrivate);
323 assertThat(isPrivateInDb(branch)).isEqualTo(!initiallyPrivate);
324 assertThat(isPrivateInDb(module)).isEqualTo(!initiallyPrivate);
325 assertThat(isPrivateInDb(dir)).isEqualTo(!initiallyPrivate);
326 assertThat(isPrivateInDb(file)).isEqualTo(!initiallyPrivate);
330 public void execute_has_no_effect_if_specified_project_already_has_specified_visibility() {
331 ComponentDto project = randomPublicOrPrivateProject();
332 boolean initiallyPrivate = project.isPrivate();
334 BranchDto branchDto = ComponentTesting.newBranchDto(project);
335 dbClient.branchDao().insert(dbSession, branchDto);
337 ComponentDto branch = ComponentTesting.newBranchComponent(project, branchDto)
338 .setPrivate(initiallyPrivate);
339 ComponentDto module = ComponentTesting.newModuleDto(project)
340 .setPrivate(initiallyPrivate);
341 ComponentDto dir = ComponentTesting.newDirectory(project, "path")
342 // child is inconsistent with root (should not occur) and won't be fixed
343 .setPrivate(!initiallyPrivate);
344 ComponentDto file = ComponentTesting.newFileDto(project)
345 .setPrivate(initiallyPrivate);
346 dbTester.components().insertComponents(branch, module, dir, file);
347 userSessionRule.addProjectPermission(UserRole.ADMIN, project);
349 request.setParam(PARAM_PROJECT, project.getKey())
350 .setParam(PARAM_VISIBILITY, initiallyPrivate ? PRIVATE : PUBLIC)
353 assertThat(isPrivateInDb(project)).isEqualTo(initiallyPrivate);
354 assertThat(isPrivateInDb(branch)).isEqualTo(initiallyPrivate);
355 assertThat(isPrivateInDb(module)).isEqualTo(initiallyPrivate);
356 assertThat(isPrivateInDb(dir)).isEqualTo(!initiallyPrivate);
357 assertThat(isPrivateInDb(file)).isEqualTo(initiallyPrivate);
361 public void execute_deletes_all_permissions_to_Anyone_on_specified_project_when_new_visibility_is_private() {
362 ComponentDto project = dbTester.components().insertPublicProject();
363 UserDto user = dbTester.users().insertUser();
364 GroupDto group = dbTester.users().insertGroup();
365 unsafeGiveAllPermissionsToRootComponent(project, user, group);
366 userSessionRule.addProjectPermission(UserRole.ADMIN, project);
368 request.setParam(PARAM_PROJECT, project.getKey())
369 .setParam(PARAM_VISIBILITY, PRIVATE)
372 verifyHasAllPermissionsButProjectPermissionsToGroupAnyOne(project, user, group);
376 public void execute_does_not_delete_all_permissions_to_AnyOne_on_specified_project_if_already_private() {
377 ComponentDto project = dbTester.components().insertPrivateProject();
378 UserDto user = dbTester.users().insertUser();
379 GroupDto group = dbTester.users().insertGroup();
380 unsafeGiveAllPermissionsToRootComponent(project, user, group);
381 userSessionRule.addProjectPermission(UserRole.ADMIN, project);
383 request.setParam(PARAM_PROJECT, project.getKey())
384 .setParam(PARAM_VISIBILITY, PRIVATE)
387 verifyStillHasAllPermissions(project, user, group);
391 public void execute_deletes_all_permissions_USER_and_BROWSE_of_specified_project_when_new_visibility_is_public() {
392 ComponentDto project = dbTester.components().insertPrivateProject();
393 UserDto user = dbTester.users().insertUser();
394 GroupDto group = dbTester.users().insertGroup();
395 unsafeGiveAllPermissionsToRootComponent(project, user, group);
396 userSessionRule.addProjectPermission(UserRole.ADMIN, project);
398 request.setParam(PARAM_PROJECT, project.getKey())
399 .setParam(PARAM_VISIBILITY, PUBLIC)
402 verifyHasAllPermissionsButProjectPermissionsUserAndBrowse(project, user, group);
406 public void execute_does_not_delete_permissions_USER_and_BROWSE_of_specified_project_when_new_component_is_already_public() {
407 ComponentDto project = dbTester.components().insertPublicProject();
408 UserDto user = dbTester.users().insertUser();
409 GroupDto group = dbTester.users().insertGroup();
410 unsafeGiveAllPermissionsToRootComponent(project, user, group);
411 userSessionRule.addProjectPermission(UserRole.ADMIN, project);
413 request.setParam(PARAM_PROJECT, project.getKey())
414 .setParam(PARAM_VISIBILITY, PUBLIC)
417 verifyStillHasAllPermissions(project, user, group);
421 public void execute_updates_permission_of_specified_project_in_indexes_when_changing_visibility() {
422 ComponentDto project = randomPublicOrPrivateProject();
423 boolean initiallyPrivate = project.isPrivate();
424 userSessionRule.addProjectPermission(UserRole.ADMIN, project);
426 request.setParam(PARAM_PROJECT, project.getKey())
427 .setParam(PARAM_VISIBILITY, initiallyPrivate ? PUBLIC : PRIVATE)
430 assertThat(projectIndexers.hasBeenCalled(project.uuid(), ProjectIndexer.Cause.PERMISSION_CHANGE)).isTrue();
434 public void execute_does_not_update_permission_of_specified_project_in_indexes_if_already_has_specified_visibility() {
435 ComponentDto project = randomPublicOrPrivateProject();
436 boolean initiallyPrivate = project.isPrivate();
437 userSessionRule.addProjectPermission(UserRole.ADMIN, project);
439 request.setParam(PARAM_PROJECT, project.getKey())
440 .setParam(PARAM_VISIBILITY, initiallyPrivate ? PRIVATE : PUBLIC)
443 assertThat(projectIndexers.hasBeenCalled(project.uuid())).isFalse();
447 public void execute_grants_USER_and_CODEVIEWER_permissions_to_any_user_with_at_least_one_permission_when_making_project_private() {
448 ComponentDto project = dbTester.components().insertPublicProject();
449 UserDto user1 = dbTester.users().insertUser();
450 UserDto user2 = dbTester.users().insertUser();
451 UserDto user3 = dbTester.users().insertUser();
452 dbTester.users().insertProjectPermissionOnUser(user1, "p1", project);
453 dbTester.users().insertProjectPermissionOnUser(user1, "p2", project);
454 dbTester.users().insertProjectPermissionOnUser(user2, "p2", project);
455 userSessionRule.addProjectPermission(UserRole.ADMIN, project);
457 request.setParam(PARAM_PROJECT, project.getKey())
458 .setParam(PARAM_VISIBILITY, PRIVATE)
461 assertThat(dbClient.userPermissionDao().selectProjectPermissionsOfUser(dbSession, user1.getUuid(), project.uuid()))
462 .containsOnly(UserRole.USER, UserRole.CODEVIEWER, "p1", "p2");
463 assertThat(dbClient.userPermissionDao().selectProjectPermissionsOfUser(dbSession, user2.getUuid(), project.uuid()))
464 .containsOnly(UserRole.USER, UserRole.CODEVIEWER, "p2");
465 assertThat(dbClient.userPermissionDao().selectProjectPermissionsOfUser(dbSession, user3.getUuid(), project.uuid()))
470 public void execute_grants_USER_and_CODEVIEWER_permissions_to_any_group_with_at_least_one_permission_when_making_project_private() {
471 ComponentDto project = dbTester.components().insertPublicProject();
472 GroupDto group1 = dbTester.users().insertGroup();
473 GroupDto group2 = dbTester.users().insertGroup();
474 GroupDto group3 = dbTester.users().insertGroup();
475 dbTester.users().insertProjectPermissionOnGroup(group1, "p1", project);
476 dbTester.users().insertProjectPermissionOnGroup(group1, "p2", project);
477 dbTester.users().insertProjectPermissionOnGroup(group2, "p2", project);
478 userSessionRule.addProjectPermission(UserRole.ADMIN, project);
480 request.setParam(PARAM_PROJECT, project.getKey())
481 .setParam(PARAM_VISIBILITY, PRIVATE)
484 assertThat(dbClient.groupPermissionDao().selectProjectPermissionsOfGroup(dbSession, group1.getUuid(), project.uuid()))
485 .containsOnly(UserRole.USER, UserRole.CODEVIEWER, "p1", "p2");
486 assertThat(dbClient.groupPermissionDao().selectProjectPermissionsOfGroup(dbSession, group2.getUuid(), project.uuid()))
487 .containsOnly(UserRole.USER, UserRole.CODEVIEWER, "p2");
488 assertThat(dbClient.groupPermissionDao().selectProjectPermissionsOfGroup(dbSession, group3.getUuid(), project.uuid()))
493 public void update_a_portfolio_to_private() {
494 ComponentDto portfolio = dbTester.components().insertPublicPortfolio();
495 GroupDto group = dbTester.users().insertGroup();
496 dbTester.users().insertProjectPermissionOnGroup(group, UserRole.ISSUE_ADMIN, portfolio);
497 UserDto user = dbTester.users().insertUser();
498 dbTester.users().insertProjectPermissionOnUser(user, UserRole.ADMIN, portfolio);
499 userSessionRule.addProjectPermission(UserRole.ADMIN, portfolio);
501 request.setParam(PARAM_PROJECT, portfolio.getKey())
502 .setParam(PARAM_VISIBILITY, PRIVATE)
505 assertThat(dbClient.componentDao().selectByUuid(dbSession, portfolio.uuid()).get().isPrivate()).isTrue();
506 assertThat(dbClient.groupPermissionDao().selectProjectPermissionsOfGroup(dbSession, group.getUuid(), portfolio.uuid()))
507 .containsOnly(UserRole.USER, UserRole.CODEVIEWER, UserRole.ISSUE_ADMIN);
508 assertThat(dbClient.userPermissionDao().selectProjectPermissionsOfUser(dbSession, user.getUuid(), portfolio.uuid()))
509 .containsOnly(UserRole.USER, UserRole.CODEVIEWER, UserRole.ADMIN);
513 public void update_a_portfolio_to_public() {
514 ComponentDto portfolio = dbTester.components().insertPrivatePortfolio();
515 userSessionRule.addProjectPermission(UserRole.ADMIN, portfolio);
516 GroupDto group = dbTester.users().insertGroup();
517 dbTester.users().insertProjectPermissionOnGroup(group, UserRole.ISSUE_ADMIN, portfolio);
518 dbTester.users().insertProjectPermissionOnGroup(group, UserRole.USER, portfolio);
519 dbTester.users().insertProjectPermissionOnGroup(group, UserRole.CODEVIEWER, portfolio);
520 UserDto user = dbTester.users().insertUser();
521 dbTester.users().insertProjectPermissionOnUser(user, UserRole.ADMIN, portfolio);
522 dbTester.users().insertProjectPermissionOnUser(user, UserRole.USER, portfolio);
523 dbTester.users().insertProjectPermissionOnUser(user, UserRole.CODEVIEWER, portfolio);
525 request.setParam(PARAM_PROJECT, portfolio.getKey())
526 .setParam(PARAM_VISIBILITY, PUBLIC)
529 assertThat(dbClient.componentDao().selectByUuid(dbSession, portfolio.uuid()).get().isPrivate()).isFalse();
530 assertThat(dbClient.groupPermissionDao().selectProjectPermissionsOfGroup(dbSession, group.getUuid(), portfolio.uuid()))
531 .containsOnly(UserRole.ISSUE_ADMIN);
532 assertThat(dbClient.userPermissionDao().selectProjectPermissionsOfUser(dbSession, user.getUuid(), portfolio.uuid()))
533 .containsOnly(UserRole.ADMIN);
537 public void update_an_application_to_private() {
538 ComponentDto application = dbTester.components().insertPublicApplication();
539 GroupDto group = dbTester.users().insertGroup();
540 dbTester.users().insertProjectPermissionOnGroup(group, UserRole.ISSUE_ADMIN, application);
541 UserDto user = dbTester.users().insertUser();
542 dbTester.users().insertProjectPermissionOnUser(user, UserRole.ADMIN, application);
543 userSessionRule.addProjectPermission(UserRole.ADMIN, application);
545 request.setParam(PARAM_PROJECT, application.getKey())
546 .setParam(PARAM_VISIBILITY, PRIVATE)
549 assertThat(dbClient.componentDao().selectByUuid(dbSession, application.uuid()).get().isPrivate()).isTrue();
550 assertThat(dbClient.groupPermissionDao().selectProjectPermissionsOfGroup(dbSession, group.getUuid(), application.uuid()))
551 .containsOnly(UserRole.USER, UserRole.CODEVIEWER, UserRole.ISSUE_ADMIN);
552 assertThat(dbClient.userPermissionDao().selectProjectPermissionsOfUser(dbSession, user.getUuid(), application.uuid()))
553 .containsOnly(UserRole.USER, UserRole.CODEVIEWER, UserRole.ADMIN);
557 public void update_an_application_to_public() {
558 ComponentDto portfolio = dbTester.components().insertPrivateApplication();
559 userSessionRule.addProjectPermission(UserRole.ADMIN, portfolio);
560 GroupDto group = dbTester.users().insertGroup();
561 dbTester.users().insertProjectPermissionOnGroup(group, UserRole.ISSUE_ADMIN, portfolio);
562 dbTester.users().insertProjectPermissionOnGroup(group, UserRole.USER, portfolio);
563 dbTester.users().insertProjectPermissionOnGroup(group, UserRole.CODEVIEWER, portfolio);
564 UserDto user = dbTester.users().insertUser();
565 dbTester.users().insertProjectPermissionOnUser(user, UserRole.ADMIN, portfolio);
566 dbTester.users().insertProjectPermissionOnUser(user, UserRole.USER, portfolio);
567 dbTester.users().insertProjectPermissionOnUser(user, UserRole.CODEVIEWER, portfolio);
569 request.setParam(PARAM_PROJECT, portfolio.getKey())
570 .setParam(PARAM_VISIBILITY, PUBLIC)
573 assertThat(dbClient.componentDao().selectByUuid(dbSession, portfolio.uuid()).get().isPrivate()).isFalse();
574 assertThat(dbClient.groupPermissionDao().selectProjectPermissionsOfGroup(dbSession, group.getUuid(), portfolio.uuid()))
575 .containsOnly(UserRole.ISSUE_ADMIN);
576 assertThat(dbClient.userPermissionDao().selectProjectPermissionsOfUser(dbSession, user.getUuid(), portfolio.uuid()))
577 .containsOnly(UserRole.ADMIN);
581 public void fail_when_using_branch_db_key() {
582 ComponentDto project = dbTester.components().insertPrivateProject();
583 userSessionRule.logIn().addProjectPermission(UserRole.USER, project);
584 ComponentDto branch = dbTester.components().insertProjectBranch(project);
586 TestRequest request = this.request.setParam(PARAM_PROJECT, branch.getKey())
587 .setParam(PARAM_VISIBILITY, PUBLIC);
588 assertThatThrownBy(request::execute)
589 .isInstanceOf(NotFoundException.class)
590 .hasMessage(String.format("Component key '%s' not found", branch.getKey()));
593 private void unsafeGiveAllPermissionsToRootComponent(ComponentDto component, UserDto user, GroupDto group) {
594 Arrays.stream(GlobalPermission.values())
595 .forEach(globalPermission -> {
596 dbTester.users().insertPermissionOnAnyone(globalPermission);
597 dbTester.users().insertPermissionOnGroup(group, globalPermission);
598 dbTester.users().insertPermissionOnUser(user, globalPermission);
600 permissionService.getAllProjectPermissions()
601 .forEach(permission -> {
602 unsafeInsertProjectPermissionOnAnyone(component, permission);
603 unsafeInsertProjectPermissionOnGroup(component, group, permission);
604 unsafeInsertProjectPermissionOnUser(component, user, permission);
608 private void unsafeInsertProjectPermissionOnAnyone(ComponentDto component, String permission) {
609 GroupPermissionDto dto = new GroupPermissionDto()
610 .setUuid(Uuids.createFast())
613 .setComponentUuid(component.uuid())
614 .setComponentName(component.name());
615 dbTester.getDbClient().groupPermissionDao().insert(dbTester.getSession(), dto, component, null);
619 private void unsafeInsertProjectPermissionOnGroup(ComponentDto component, GroupDto group, String permission) {
620 GroupPermissionDto dto = new GroupPermissionDto()
621 .setUuid(Uuids.createFast())
622 .setGroupUuid(group.getUuid())
623 .setGroupName(group.getName())
625 .setComponentUuid(component.uuid())
626 .setComponentName(component.name());
627 dbTester.getDbClient().groupPermissionDao().insert(dbTester.getSession(), dto, component, null);
631 private void unsafeInsertProjectPermissionOnUser(ComponentDto component, UserDto user, String permission) {
632 UserPermissionDto dto = new UserPermissionDto(Uuids.create(), permission, user.getUuid(), component.uuid());
633 dbTester.getDbClient().userPermissionDao().insert(dbTester.getSession(), dto, component, user, null);
637 private void verifyHasAllPermissionsButProjectPermissionsToGroupAnyOne(ComponentDto component, UserDto user, GroupDto group) {
638 assertThat(dbClient.groupPermissionDao().selectGlobalPermissionsOfGroup(dbSession, null))
639 .containsAll(GLOBAL_PERMISSIONS_NAME_SET);
640 assertThat(dbClient.groupPermissionDao().selectGlobalPermissionsOfGroup(dbSession, group.getUuid()))
641 .containsAll(GLOBAL_PERMISSIONS_NAME_SET);
642 assertThat(dbClient.userPermissionDao().selectGlobalPermissionsOfUser(dbSession, user.getUuid()))
643 .containsAll(GLOBAL_PERMISSIONS_NAME_SET);
644 assertThat(dbClient.groupPermissionDao().selectProjectPermissionsOfGroup(dbSession, null, component.uuid()))
646 assertThat(dbClient.groupPermissionDao().selectProjectPermissionsOfGroup(dbSession, group.getUuid(), component.uuid()))
647 .containsAll(permissionService.getAllProjectPermissions());
648 assertThat(dbClient.userPermissionDao().selectProjectPermissionsOfUser(dbSession, user.getUuid(), component.uuid()))
649 .containsAll(permissionService.getAllProjectPermissions());
652 private void verifyHasAllPermissionsButProjectPermissionsUserAndBrowse(ComponentDto component, UserDto user, GroupDto group) {
653 assertThat(dbClient.groupPermissionDao().selectGlobalPermissionsOfGroup(dbSession, null))
654 .containsAll(GLOBAL_PERMISSIONS_NAME_SET);
655 assertThat(dbClient.groupPermissionDao().selectGlobalPermissionsOfGroup(dbSession, group.getUuid()))
656 .containsAll(GLOBAL_PERMISSIONS_NAME_SET);
657 assertThat(dbClient.userPermissionDao().selectGlobalPermissionsOfUser(dbSession, user.getUuid()))
658 .containsAll(GLOBAL_PERMISSIONS_NAME_SET);
659 assertThat(dbClient.groupPermissionDao().selectProjectPermissionsOfGroup(dbSession, null, component.uuid()))
660 .doesNotContain(UserRole.USER)
661 .doesNotContain(UserRole.CODEVIEWER)
662 .containsAll(PROJECT_PERMISSIONS_BUT_USER_AND_CODEVIEWER);
663 assertThat(dbClient.groupPermissionDao().selectProjectPermissionsOfGroup(dbSession, group.getUuid(), component.uuid()))
664 .doesNotContain(UserRole.USER)
665 .doesNotContain(UserRole.CODEVIEWER)
666 .containsAll(PROJECT_PERMISSIONS_BUT_USER_AND_CODEVIEWER);
667 assertThat(dbClient.userPermissionDao().selectProjectPermissionsOfUser(dbSession, user.getUuid(), component.uuid()))
668 .doesNotContain(UserRole.USER)
669 .doesNotContain(UserRole.CODEVIEWER)
670 .containsAll(PROJECT_PERMISSIONS_BUT_USER_AND_CODEVIEWER);
673 private void verifyStillHasAllPermissions(ComponentDto component, UserDto user, GroupDto group) {
674 assertThat(dbClient.groupPermissionDao().selectGlobalPermissionsOfGroup(dbSession, null))
675 .containsAll(GLOBAL_PERMISSIONS_NAME_SET);
676 assertThat(dbClient.groupPermissionDao().selectGlobalPermissionsOfGroup(dbSession, group.getUuid()))
677 .containsAll(GLOBAL_PERMISSIONS_NAME_SET);
678 assertThat(dbClient.userPermissionDao().selectGlobalPermissionsOfUser(dbSession, user.getUuid()))
679 .containsAll(GLOBAL_PERMISSIONS_NAME_SET);
680 assertThat(dbClient.groupPermissionDao().selectProjectPermissionsOfGroup(dbSession, null, component.uuid()))
681 .containsAll(permissionService.getAllProjectPermissions());
682 assertThat(dbClient.groupPermissionDao().selectProjectPermissionsOfGroup(dbSession, group.getUuid(), component.uuid()))
683 .containsAll(permissionService.getAllProjectPermissions());
684 assertThat(dbClient.userPermissionDao().selectProjectPermissionsOfUser(dbSession, user.getUuid(), component.uuid()))
685 .containsAll(permissionService.getAllProjectPermissions());
688 private void insertPendingTask(ComponentDto project) {
689 insertCeQueueDto(project, CeQueueDto.Status.PENDING);
692 private void insertInProgressTask(ComponentDto project) {
693 insertCeQueueDto(project, CeQueueDto.Status.IN_PROGRESS);
696 private int counter = 0;
698 private void insertCeQueueDto(ComponentDto project, CeQueueDto.Status status) {
699 dbClient.ceQueueDao().insert(dbTester.getSession(), new CeQueueDto()
700 .setUuid("pending" + counter++)
701 .setComponent(project)
707 private boolean isPrivateInDb(ComponentDto project) {
708 return dbClient.componentDao().selectByUuid(dbTester.getSession(), project.uuid()).get().isPrivate();
711 private ComponentDto randomPublicOrPrivateProject() {
712 return random.nextBoolean() ? dbTester.components().insertPublicProject() : dbTester.components().insertPrivateProject();