You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

PermissionTemplateTest.java 9.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2017 SonarSource SA
  4. * mailto:info AT sonarsource DOT com
  5. *
  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.
  10. *
  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.
  15. *
  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.
  19. */
  20. package org.sonarqube.tests.authorisation;
  21. import com.sonar.orchestrator.Orchestrator;
  22. import java.util.Arrays;
  23. import java.util.Optional;
  24. import org.junit.After;
  25. import org.junit.ClassRule;
  26. import org.junit.Rule;
  27. import org.junit.Test;
  28. import org.junit.rules.DisableOnDebug;
  29. import org.junit.rules.TestRule;
  30. import org.junit.rules.Timeout;
  31. import org.sonarqube.tests.Category6Suite;
  32. import org.sonarqube.tests.Tester;
  33. import org.sonarqube.ws.Organizations.Organization;
  34. import org.sonarqube.ws.WsPermissions;
  35. import org.sonarqube.ws.WsPermissions.CreateTemplateWsResponse;
  36. import org.sonarqube.ws.WsProjects.CreateWsResponse.Project;
  37. import org.sonarqube.ws.WsUsers.CreateWsResponse;
  38. import org.sonarqube.ws.client.WsClient;
  39. import org.sonarqube.ws.client.component.SearchProjectsRequest;
  40. import org.sonarqube.ws.client.permission.AddUserToTemplateWsRequest;
  41. import org.sonarqube.ws.client.permission.ApplyTemplateWsRequest;
  42. import org.sonarqube.ws.client.permission.BulkApplyTemplateWsRequest;
  43. import org.sonarqube.ws.client.permission.CreateTemplateWsRequest;
  44. import org.sonarqube.ws.client.permission.PermissionsService;
  45. import org.sonarqube.ws.client.permission.UsersWsRequest;
  46. import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
  47. import static org.assertj.core.api.Assertions.assertThat;
  48. public class PermissionTemplateTest {
  49. @ClassRule
  50. public static final Orchestrator orchestrator = Category6Suite.ORCHESTRATOR;
  51. @Rule
  52. public TestRule safeguard = new DisableOnDebug(Timeout.seconds(300));
  53. @Rule
  54. public Tester tester = new Tester(orchestrator)
  55. .setElasticsearchHttpPort(Category6Suite.SEARCH_HTTP_PORT);
  56. @After
  57. public void tearDown() throws Exception {
  58. unlockWritesOnProjectIndices();
  59. }
  60. @Test
  61. public void apply_permission_template_on_project() {
  62. Organization organization = tester.organizations().generate();
  63. Project project = createPrivateProject(organization);
  64. CreateWsResponse.User user = tester.users().generateMember(organization);
  65. CreateWsResponse.User anotherUser = tester.users().generateMember(organization);
  66. assertThatUserDoesNotHavePermission(user, organization, project);
  67. assertThatUserDoesNotHavePermission(anotherUser, organization, project);
  68. assertThat(userHasAccessToIndexedProject(user, organization, project)).isTrue();
  69. assertThat(userHasAccessToIndexedProject(anotherUser, organization, project)).isTrue();
  70. // create permission template that gives read permission to "user"
  71. createAndApplyTemplate(organization, project, user);
  72. assertThatUserHasPermission(user, organization, project);
  73. assertThatUserDoesNotHavePermission(anotherUser, organization, project);
  74. assertThat(userHasAccessToIndexedProject(user, organization, project)).isTrue();
  75. assertThat(userHasAccessToIndexedProject(anotherUser, organization, project)).isFalse();
  76. }
  77. @Test
  78. public void bulk_apply_template_on_projects() {
  79. Organization organization = tester.organizations().generate();
  80. CreateWsResponse.User user = tester.users().generateMember(organization);
  81. CreateWsResponse.User anotherUser = tester.users().generateMember(organization);
  82. WsPermissions.PermissionTemplate template = createTemplate(organization).getPermissionTemplate();
  83. tester.wsClient().permissions().addUserToTemplate(new AddUserToTemplateWsRequest()
  84. .setOrganization(organization.getKey())
  85. .setTemplateId(template.getId())
  86. .setLogin(user.getLogin())
  87. .setPermission("user"));
  88. Project project1 = createPrivateProject(organization);
  89. Project project2 = createPrivateProject(organization);
  90. Project untouchedProject = createPrivateProject(organization);
  91. tester.wsClient().permissions().bulkApplyTemplate(new BulkApplyTemplateWsRequest()
  92. .setOrganization(organization.getKey())
  93. .setTemplateId(template.getId())
  94. .setProjects(Arrays.asList(project1.getKey(), project2.getKey())));
  95. assertThatUserDoesNotHavePermission(anotherUser, organization, untouchedProject);
  96. assertThatUserDoesNotHavePermission(anotherUser, organization, project1);
  97. assertThatUserDoesNotHavePermission(anotherUser, organization, project2);
  98. assertThatUserHasPermission(user, organization, project1);
  99. assertThatUserHasPermission(user, organization, project2);
  100. assertThatUserDoesNotHavePermission(user, organization, untouchedProject);
  101. }
  102. @Test
  103. public void indexing_errors_are_recovered_when_applying_permission_template_on_project() throws Exception {
  104. Organization organization = tester.organizations().generate();
  105. Project project = createPrivateProject(organization);
  106. CreateWsResponse.User user = tester.users().generateMember(organization);
  107. CreateWsResponse.User anotherUser = tester.users().generateMember(organization);
  108. lockWritesOnProjectIndices();
  109. createAndApplyTemplate(organization, project, user);
  110. assertThatUserHasPermission(user, organization, project);
  111. assertThatUserDoesNotHavePermission(anotherUser, organization, project);
  112. assertThat(userHasAccessToIndexedProject(user, organization, project)).isTrue();
  113. // inconsistent, should be false. Waiting for ES to be updated.
  114. assertThat(userHasAccessToIndexedProject(user, organization, project)).isTrue();
  115. unlockWritesOnProjectIndices();
  116. boolean recovered = false;
  117. while (!recovered) {
  118. Thread.sleep(1_000L);
  119. recovered = !userHasAccessToIndexedProject(anotherUser, organization, project);
  120. }
  121. }
  122. private void lockWritesOnProjectIndices() throws Exception {
  123. tester.elasticsearch().lockWrites("issues");
  124. tester.elasticsearch().lockWrites("projectmeasures");
  125. tester.elasticsearch().lockWrites("components");
  126. }
  127. private void unlockWritesOnProjectIndices() throws Exception {
  128. tester.elasticsearch().unlockWrites("issues");
  129. tester.elasticsearch().unlockWrites("projectmeasures");
  130. tester.elasticsearch().unlockWrites("components");
  131. }
  132. /**
  133. * Gives the read access only to the specified user. All other users and groups
  134. * loose their ability to see the project.
  135. */
  136. private void createAndApplyTemplate(Organization organization, Project project, CreateWsResponse.User user) {
  137. String templateName = "For user";
  138. PermissionsService service = tester.wsClient().permissions();
  139. service.createTemplate(new CreateTemplateWsRequest()
  140. .setOrganization(organization.getKey())
  141. .setName(templateName)
  142. .setDescription("Give admin permissions to single user"));
  143. service.addUserToTemplate(new AddUserToTemplateWsRequest()
  144. .setOrganization(organization.getKey())
  145. .setLogin(user.getLogin())
  146. .setPermission("user")
  147. .setTemplateName(templateName));
  148. service.applyTemplate(new ApplyTemplateWsRequest()
  149. .setOrganization(organization.getKey())
  150. .setProjectKey(project.getKey())
  151. .setTemplateName(templateName));
  152. }
  153. private CreateTemplateWsResponse createTemplate(Organization organization) {
  154. return tester.wsClient().permissions().createTemplate(new CreateTemplateWsRequest()
  155. .setOrganization(organization.getKey())
  156. .setName(randomAlphabetic(20)));
  157. }
  158. private Project createPrivateProject(Organization organization) {
  159. return tester.projects().generate(organization, p -> p.setVisibility("private"));
  160. }
  161. private void assertThatUserHasPermission(CreateWsResponse.User user, Organization organization, Project project) {
  162. assertThat(hasBrowsePermission(user, organization, project)).isTrue();
  163. }
  164. private void assertThatUserDoesNotHavePermission(CreateWsResponse.User user, Organization organization, Project project) {
  165. assertThat(hasBrowsePermission(user, organization, project)).isFalse();
  166. }
  167. private boolean userHasAccessToIndexedProject(CreateWsResponse.User user, Organization organization, Project project) {
  168. SearchProjectsRequest request = SearchProjectsRequest.builder().setOrganization(organization.getKey()).build();
  169. WsClient userSession = tester.as(user.getLogin()).wsClient();
  170. return userSession.components().searchProjects(request)
  171. .getComponentsList().stream()
  172. .anyMatch(c -> c.getKey().equals(project.getKey()));
  173. }
  174. private boolean hasBrowsePermission(CreateWsResponse.User user, Organization organization, Project project) {
  175. UsersWsRequest request = new UsersWsRequest()
  176. .setOrganization(organization.getKey())
  177. .setProjectKey(project.getKey())
  178. .setPermission("user");
  179. WsPermissions.UsersWsResponse response = tester.wsClient().permissions().users(request);
  180. Optional<WsPermissions.User> found = response.getUsersList().stream()
  181. .filter(u -> user.getLogin().equals(u.getLogin()))
  182. .findFirst();
  183. return found.isPresent();
  184. }
  185. }