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.

BulkApplyTemplateActionTest.java 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  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.sonar.server.permission.ws.template;
  21. import java.util.List;
  22. import org.junit.Before;
  23. import org.junit.Test;
  24. import org.sonar.api.resources.Qualifiers;
  25. import org.sonar.api.server.ws.WebService.Param;
  26. import org.sonar.api.web.UserRole;
  27. import org.sonar.db.component.ComponentDto;
  28. import org.sonar.db.component.ComponentTesting;
  29. import org.sonar.db.organization.OrganizationDto;
  30. import org.sonar.db.permission.PermissionQuery;
  31. import org.sonar.db.permission.template.PermissionTemplateDto;
  32. import org.sonar.db.user.GroupDto;
  33. import org.sonar.db.user.UserDto;
  34. import org.sonar.server.es.ProjectIndexers;
  35. import org.sonar.server.es.TestProjectIndexers;
  36. import org.sonar.server.exceptions.BadRequestException;
  37. import org.sonar.server.exceptions.NotFoundException;
  38. import org.sonar.server.i18n.I18nRule;
  39. import org.sonar.server.permission.PermissionTemplateService;
  40. import org.sonar.server.permission.ws.BasePermissionWsTest;
  41. import static org.assertj.core.api.Assertions.assertThat;
  42. import static org.sonar.api.utils.DateUtils.parseDate;
  43. import static org.sonar.db.component.ComponentTesting.newApplication;
  44. import static org.sonar.db.component.ComponentTesting.newView;
  45. import static org.sonar.db.component.SnapshotTesting.newAnalysis;
  46. import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_ORGANIZATION;
  47. import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_TEMPLATE_ID;
  48. import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_TEMPLATE_NAME;
  49. import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_ANALYZED_BEFORE;
  50. import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_ON_PROVISIONED_ONLY;
  51. import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_PROJECTS;
  52. import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_QUALIFIERS;
  53. import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_VISIBILITY;
  54. public class BulkApplyTemplateActionTest extends BasePermissionWsTest<BulkApplyTemplateAction> {
  55. @org.junit.Rule
  56. public DefaultTemplatesResolverRule defaultTemplatesResolver = DefaultTemplatesResolverRule.withoutGovernance();
  57. private UserDto user1;
  58. private UserDto user2;
  59. private GroupDto group1;
  60. private GroupDto group2;
  61. private OrganizationDto organization;
  62. private PermissionTemplateDto template1;
  63. private PermissionTemplateDto template2;
  64. private ProjectIndexers projectIndexers = new TestProjectIndexers();
  65. @Override
  66. protected BulkApplyTemplateAction buildWsAction() {
  67. PermissionTemplateService permissionTemplateService = new PermissionTemplateService(db.getDbClient(),
  68. projectIndexers, userSession, defaultTemplatesResolver);
  69. return new BulkApplyTemplateAction(db.getDbClient(), userSession, permissionTemplateService, newPermissionWsSupport(), new I18nRule(), newRootResourceTypes());
  70. }
  71. @Before
  72. public void setUp() {
  73. organization = db.organizations().insert();
  74. user1 = db.users().insertUser();
  75. user2 = db.users().insertUser();
  76. group1 = db.users().insertGroup(organization);
  77. group2 = db.users().insertGroup(organization);
  78. db.organizations().addMember(organization, user1);
  79. db.organizations().addMember(organization, user2);
  80. // template 1 for org 1
  81. template1 = db.permissionTemplates().insertTemplate(organization);
  82. addUserToTemplate(user1, template1, UserRole.CODEVIEWER);
  83. addUserToTemplate(user2, template1, UserRole.ISSUE_ADMIN);
  84. addGroupToTemplate(group1, template1, UserRole.ADMIN);
  85. addGroupToTemplate(group2, template1, UserRole.USER);
  86. // template 2
  87. template2 = db.permissionTemplates().insertTemplate(organization);
  88. addUserToTemplate(user1, template2, UserRole.USER);
  89. addUserToTemplate(user2, template2, UserRole.USER);
  90. addGroupToTemplate(group1, template2, UserRole.USER);
  91. addGroupToTemplate(group2, template2, UserRole.USER);
  92. }
  93. @Test
  94. public void bulk_apply_template_by_template_uuid() throws Exception {
  95. // this project should not be applied the template
  96. OrganizationDto otherOrganization = db.organizations().insert();
  97. db.components().insertPrivateProject(otherOrganization);
  98. ComponentDto privateProject = db.components().insertPrivateProject(organization);
  99. ComponentDto publicProject = db.components().insertPublicProject(organization);
  100. loginAsAdmin(organization);
  101. newRequest()
  102. .setParam(PARAM_TEMPLATE_ID, template1.getUuid())
  103. .execute();
  104. assertTemplate1AppliedToPrivateProject(privateProject);
  105. assertTemplate1AppliedToPublicProject(publicProject);
  106. }
  107. @Test
  108. public void request_throws_NotFoundException_if_template_with_specified_name_does_not_exist_in_specified_organization() throws Exception {
  109. OrganizationDto otherOrganization = db.organizations().insert();
  110. loginAsAdmin(otherOrganization);
  111. expectedException.expect(NotFoundException.class);
  112. expectedException.expectMessage("Permission template with name '" + template1.getName()
  113. + "' is not found (case insensitive) in organization with key '" + otherOrganization.getKey() + "'");
  114. newRequest()
  115. .setParam(PARAM_ORGANIZATION, otherOrganization.getKey())
  116. .setParam(PARAM_TEMPLATE_NAME, template1.getName())
  117. .execute();
  118. }
  119. @Test
  120. public void bulk_apply_template_by_template_name() throws Exception {
  121. ComponentDto privateProject = db.components().insertPrivateProject(organization);
  122. ComponentDto publicProject = db.components().insertPublicProject(organization);
  123. loginAsAdmin(organization);
  124. newRequest()
  125. .setParam(PARAM_ORGANIZATION, organization.getKey())
  126. .setParam(PARAM_TEMPLATE_NAME, template1.getName())
  127. .execute();
  128. assertTemplate1AppliedToPrivateProject(privateProject);
  129. assertTemplate1AppliedToPublicProject(publicProject);
  130. }
  131. @Test
  132. public void apply_template_by_qualifiers() throws Exception {
  133. ComponentDto publicProject = db.components().insertPublicProject(organization);
  134. ComponentDto privateProject = db.components().insertPrivateProject(organization);
  135. ComponentDto view = db.components().insertComponent(newView(organization));
  136. ComponentDto application = db.components().insertComponent(newApplication(organization));
  137. loginAsAdmin(organization);
  138. newRequest()
  139. .setParam(PARAM_TEMPLATE_ID, template1.getUuid())
  140. .setParam(PARAM_QUALIFIERS, String.join(",", Qualifiers.PROJECT, Qualifiers.APP))
  141. .execute();
  142. assertTemplate1AppliedToPrivateProject(privateProject);
  143. assertTemplate1AppliedToPublicProject(publicProject);
  144. assertTemplate1AppliedToPublicProject(application);
  145. assertNoPermissionOnProject(view);
  146. }
  147. @Test
  148. public void apply_template_by_query_on_name_and_key_public_project() throws Exception {
  149. ComponentDto publicProjectFoundByKey = ComponentTesting.newPublicProjectDto(organization).setDbKey("sonar");
  150. db.components().insertProjectAndSnapshot(publicProjectFoundByKey);
  151. ComponentDto publicProjectFoundByName = ComponentTesting.newPublicProjectDto(organization).setName("name-sonar-name");
  152. db.components().insertProjectAndSnapshot(publicProjectFoundByName);
  153. ComponentDto projectUntouched = ComponentTesting.newPublicProjectDto(organization).setDbKey("new-sona").setName("project-name");
  154. db.components().insertProjectAndSnapshot(projectUntouched);
  155. loginAsAdmin(organization);
  156. newRequest()
  157. .setParam(PARAM_TEMPLATE_ID, template1.getUuid())
  158. .setParam(Param.TEXT_QUERY, "SONAR")
  159. .execute();
  160. assertTemplate1AppliedToPublicProject(publicProjectFoundByKey);
  161. assertTemplate1AppliedToPublicProject(publicProjectFoundByName);
  162. assertNoPermissionOnProject(projectUntouched);
  163. }
  164. @Test
  165. public void apply_template_by_query_on_name_and_key() throws Exception {
  166. // partial match on key
  167. ComponentDto privateProjectFoundByKey = ComponentTesting.newPrivateProjectDto(organization).setDbKey("sonarqube");
  168. db.components().insertProjectAndSnapshot(privateProjectFoundByKey);
  169. ComponentDto privateProjectFoundByName = ComponentTesting.newPrivateProjectDto(organization).setName("name-sonar-name");
  170. db.components().insertProjectAndSnapshot(privateProjectFoundByName);
  171. ComponentDto projectUntouched = ComponentTesting.newPublicProjectDto(organization).setDbKey("new-sona").setName("project-name");
  172. db.components().insertProjectAndSnapshot(projectUntouched);
  173. loginAsAdmin(organization);
  174. newRequest()
  175. .setParam(PARAM_TEMPLATE_ID, template1.getUuid())
  176. .setParam(Param.TEXT_QUERY, "SONAR")
  177. .execute();
  178. assertTemplate1AppliedToPrivateProject(privateProjectFoundByKey);
  179. assertTemplate1AppliedToPrivateProject(privateProjectFoundByName);
  180. assertNoPermissionOnProject(projectUntouched);
  181. }
  182. @Test
  183. public void apply_template_by_project_keys() throws Exception {
  184. ComponentDto project1 = db.components().insertPrivateProject(organization);
  185. ComponentDto project2 = db.components().insertPrivateProject(organization);
  186. ComponentDto untouchedProject = db.components().insertPrivateProject(organization);
  187. loginAsAdmin(organization);
  188. newRequest()
  189. .setParam(PARAM_TEMPLATE_ID, template1.getUuid())
  190. .setParam(PARAM_PROJECTS, String.join(",", project1.getKey(), project2.getKey()))
  191. .execute();
  192. assertTemplate1AppliedToPrivateProject(project1);
  193. assertTemplate1AppliedToPrivateProject(project2);
  194. assertNoPermissionOnProject(untouchedProject);
  195. }
  196. @Test
  197. public void apply_template_by_provisioned_only() throws Exception {
  198. ComponentDto provisionedProject1 = db.components().insertPrivateProject(organization);
  199. ComponentDto provisionedProject2 = db.components().insertPrivateProject(organization);
  200. ComponentDto analyzedProject = db.components().insertPrivateProject(organization);
  201. db.components().insertSnapshot(newAnalysis(analyzedProject));
  202. loginAsAdmin(organization);
  203. newRequest()
  204. .setParam(PARAM_TEMPLATE_ID, template1.getUuid())
  205. .setParam(PARAM_ON_PROVISIONED_ONLY, "true")
  206. .execute();
  207. assertTemplate1AppliedToPrivateProject(provisionedProject1);
  208. assertTemplate1AppliedToPrivateProject(provisionedProject2);
  209. assertNoPermissionOnProject(analyzedProject);
  210. }
  211. @Test
  212. public void apply_template_by_analyzed_before() throws Exception {
  213. ComponentDto oldProject1 = db.components().insertPrivateProject(organization);
  214. ComponentDto oldProject2 = db.components().insertPrivateProject(organization);
  215. ComponentDto recentProject = db.components().insertPrivateProject(organization);
  216. db.components().insertSnapshot(oldProject1, a -> a.setCreatedAt(parseDate("2015-02-03").getTime()));
  217. db.components().insertSnapshot(oldProject2, a -> a.setCreatedAt(parseDate("2016-12-11").getTime()));
  218. db.components().insertSnapshot(recentProject, a -> a.setCreatedAt(System.currentTimeMillis()));
  219. loginAsAdmin(organization);
  220. newRequest()
  221. .setParam(PARAM_TEMPLATE_ID, template1.getUuid())
  222. .setParam(PARAM_ANALYZED_BEFORE, "2017-09-07")
  223. .execute();
  224. assertTemplate1AppliedToPrivateProject(oldProject1);
  225. assertTemplate1AppliedToPrivateProject(oldProject2);
  226. assertNoPermissionOnProject(recentProject);
  227. }
  228. @Test
  229. public void apply_template_by_visibility() throws Exception {
  230. ComponentDto privateProject1 = db.components().insertPrivateProject(organization);
  231. ComponentDto privateProject2 = db.components().insertPrivateProject(organization);
  232. ComponentDto publicProject = db.components().insertPublicProject(organization);
  233. loginAsAdmin(organization);
  234. newRequest()
  235. .setParam(PARAM_TEMPLATE_ID, template1.getUuid())
  236. .setParam(PARAM_VISIBILITY, "private")
  237. .execute();
  238. assertTemplate1AppliedToPrivateProject(privateProject1);
  239. assertTemplate1AppliedToPrivateProject(privateProject2);
  240. assertNoPermissionOnProject(publicProject);
  241. }
  242. @Test
  243. public void fail_if_no_template_parameter() throws Exception {
  244. loginAsAdmin(db.getDefaultOrganization());
  245. expectedException.expect(BadRequestException.class);
  246. expectedException.expectMessage("Template name or template id must be provided, not both.");
  247. newRequest().execute();
  248. }
  249. @Test
  250. public void fail_if_template_name_is_incorrect() throws Exception {
  251. loginAsAdmin(db.getDefaultOrganization());
  252. expectedException.expect(NotFoundException.class);
  253. expectedException.expectMessage("Permission template with id 'unknown-template-uuid' is not found");
  254. newRequest().setParam(PARAM_TEMPLATE_ID, "unknown-template-uuid").execute();
  255. }
  256. private void assertTemplate1AppliedToPublicProject(ComponentDto project) throws Exception {
  257. assertThat(selectProjectPermissionGroups(project, UserRole.ADMIN)).containsExactly(group1.getName());
  258. assertThat(selectProjectPermissionGroups(project, UserRole.USER)).isEmpty();
  259. assertThat(selectProjectPermissionUsers(project, UserRole.ADMIN)).isEmpty();
  260. assertThat(selectProjectPermissionUsers(project, UserRole.CODEVIEWER)).isEmpty();
  261. assertThat(selectProjectPermissionUsers(project, UserRole.ISSUE_ADMIN)).containsExactly(user2.getId());
  262. }
  263. private void assertTemplate1AppliedToPrivateProject(ComponentDto project) throws Exception {
  264. assertThat(selectProjectPermissionGroups(project, UserRole.ADMIN)).containsExactly(group1.getName());
  265. assertThat(selectProjectPermissionGroups(project, UserRole.USER)).containsExactly(group2.getName());
  266. assertThat(selectProjectPermissionUsers(project, UserRole.ADMIN)).isEmpty();
  267. assertThat(selectProjectPermissionUsers(project, UserRole.CODEVIEWER)).containsExactly(user1.getId());
  268. assertThat(selectProjectPermissionUsers(project, UserRole.ISSUE_ADMIN)).containsExactly(user2.getId());
  269. }
  270. private void assertNoPermissionOnProject(ComponentDto project) throws Exception {
  271. assertThat(selectProjectPermissionGroups(project, UserRole.ADMIN)).isEmpty();
  272. assertThat(selectProjectPermissionGroups(project, UserRole.CODEVIEWER)).isEmpty();
  273. assertThat(selectProjectPermissionGroups(project, UserRole.ISSUE_ADMIN)).isEmpty();
  274. assertThat(selectProjectPermissionGroups(project, UserRole.USER)).isEmpty();
  275. assertThat(selectProjectPermissionUsers(project, UserRole.ADMIN)).isEmpty();
  276. assertThat(selectProjectPermissionUsers(project, UserRole.CODEVIEWER)).isEmpty();
  277. assertThat(selectProjectPermissionUsers(project, UserRole.ISSUE_ADMIN)).isEmpty();
  278. assertThat(selectProjectPermissionUsers(project, UserRole.USER)).isEmpty();
  279. }
  280. private void addUserToTemplate(UserDto user, PermissionTemplateDto permissionTemplate, String permission) {
  281. db.getDbClient().permissionTemplateDao().insertUserPermission(db.getSession(), permissionTemplate.getId(), user.getId(), permission);
  282. db.commit();
  283. }
  284. private void addGroupToTemplate(GroupDto group, PermissionTemplateDto permissionTemplate, String permission) {
  285. db.getDbClient().permissionTemplateDao().insertGroupPermission(db.getSession(), permissionTemplate.getId(), group.getId(), permission);
  286. db.commit();
  287. }
  288. private List<String> selectProjectPermissionGroups(ComponentDto project, String permission) {
  289. PermissionQuery query = PermissionQuery.builder().setOrganizationUuid(project.getOrganizationUuid()).setPermission(permission).setComponentUuid(project.uuid()).build();
  290. return db.getDbClient().groupPermissionDao().selectGroupNamesByQuery(db.getSession(), query);
  291. }
  292. private List<Integer> selectProjectPermissionUsers(ComponentDto project, String permission) {
  293. PermissionQuery query = PermissionQuery.builder().setOrganizationUuid(project.getOrganizationUuid()).setPermission(permission).setComponentUuid(project.uuid()).build();
  294. return db.getDbClient().userPermissionDao().selectUserIdsByQuery(db.getSession(), query);
  295. }
  296. }