3 * Copyright (C) 2009-2016 SonarSource SA
4 * mailto:contact 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.permission.ws.template;
22 import java.util.Arrays;
23 import javax.annotation.Nullable;
24 import org.junit.Before;
25 import org.junit.Rule;
26 import org.junit.Test;
27 import org.junit.rules.ExpectedException;
28 import org.sonar.api.resources.Qualifiers;
29 import org.sonar.api.utils.internal.AlwaysIncreasingSystem2;
30 import org.sonar.api.web.UserRole;
31 import org.sonar.db.DbClient;
32 import org.sonar.db.DbTester;
33 import org.sonar.db.component.ResourceTypesRule;
34 import org.sonar.db.organization.OrganizationDto;
35 import org.sonar.db.permission.template.PermissionTemplateDto;
36 import org.sonar.db.permission.template.PermissionTemplateTesting;
37 import org.sonar.db.user.GroupDto;
38 import org.sonar.db.user.GroupTesting;
39 import org.sonar.db.user.UserDto;
40 import org.sonar.db.user.UserTesting;
41 import org.sonar.server.component.ComponentFinder;
42 import org.sonar.server.exceptions.BadRequestException;
43 import org.sonar.server.exceptions.ForbiddenException;
44 import org.sonar.server.exceptions.NotFoundException;
45 import org.sonar.server.exceptions.UnauthorizedException;
46 import org.sonar.server.organization.TestDefaultOrganizationProvider;
47 import org.sonar.server.permission.ws.PermissionWsSupport;
48 import org.sonar.server.tester.UserSessionRule;
49 import org.sonar.server.usergroups.ws.GroupWsSupport;
50 import org.sonar.server.ws.TestRequest;
51 import org.sonar.server.ws.TestResponse;
52 import org.sonar.server.ws.WsActionTester;
54 import static org.assertj.core.api.Assertions.assertThat;
55 import static org.assertj.core.api.Assertions.fail;
56 import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
57 import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_ORGANIZATION_KEY;
58 import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_TEMPLATE_ID;
59 import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_TEMPLATE_NAME;
61 public class DeleteTemplateActionTest {
64 public DbTester db = DbTester.create(new AlwaysIncreasingSystem2());
66 public ExpectedException expectedException = ExpectedException.none();
68 private UserSessionRule userSession = UserSessionRule.standalone();
69 private DbClient dbClient = db.getDbClient();
70 private final ResourceTypesRule resourceTypes = new ResourceTypesRule().setRootQualifiers(Qualifiers.PROJECT);
71 private final ResourceTypesRule resourceTypesWithViews = new ResourceTypesRule().setRootQualifiers(Qualifiers.PROJECT, Qualifiers.VIEW);
72 private DefaultTemplatesResolver defaultTemplatesResolver = new DefaultTemplatesResolverImpl(resourceTypes);
73 private DefaultTemplatesResolver defaultTemplatesResolverWithViews = new DefaultTemplatesResolverImpl(resourceTypesWithViews);
75 private WsActionTester underTestWithoutViews;
76 private WsActionTester underTestWithViews;
79 public void setUp() throws Exception {
80 GroupWsSupport groupWsSupport = new GroupWsSupport(dbClient, TestDefaultOrganizationProvider.from(db));
81 this.underTestWithoutViews = new WsActionTester(new DeleteTemplateAction(dbClient, userSession,
82 new PermissionWsSupport(dbClient, new ComponentFinder(dbClient), groupWsSupport, resourceTypes),
83 defaultTemplatesResolver));
84 this.underTestWithViews = new WsActionTester(new DeleteTemplateAction(dbClient, userSession,
85 new PermissionWsSupport(dbClient, new ComponentFinder(dbClient), groupWsSupport, resourceTypesWithViews),
86 defaultTemplatesResolverWithViews));
90 public void delete_template_in_db() throws Exception {
91 runOnAllUnderTests((underTest) -> {
92 OrganizationDto organization = db.organizations().insert();
93 PermissionTemplateDto template = insertTemplateAndAssociatedPermissions(organization);
94 db.organizations().setDefaultTemplates(
95 db.permissionTemplates().insertTemplate(organization),
96 db.permissionTemplates().insertTemplate(organization));
97 loginAsAdmin(organization);
99 TestResponse result = newRequestByUuid(underTest, template.getUuid());
101 assertThat(result.getInput()).isEmpty();
102 assertTemplateDoesNotExist(template);
107 public void delete_template_by_name_case_insensitive() throws Exception {
108 runOnAllUnderTests((underTest) -> {
109 OrganizationDto organization = db.organizations().insert();
110 db.organizations().setDefaultTemplates(
111 db.permissionTemplates().insertTemplate(organization),
112 db.permissionTemplates().insertTemplate(organization));
113 PermissionTemplateDto template = insertTemplateAndAssociatedPermissions(organization);
114 loginAsAdmin(organization);
115 newRequestByName(underTest, organization, template);
117 assertTemplateDoesNotExist(template);
122 public void delete_template_by_name_returns_empty_when_no_organization_is_provided_and_templates_does_not_belong_to_default_organization() throws Exception {
123 OrganizationDto organization = db.organizations().insert();
124 db.organizations().setDefaultTemplates(
125 db.permissionTemplates().insertTemplate(organization),
126 db.permissionTemplates().insertTemplate(organization));
127 PermissionTemplateDto template = insertTemplateAndAssociatedPermissions(organization);
128 loginAsAdmin(organization);
130 runOnAllUnderTests((underTest) -> {
132 newRequestByName(underTest, null, template);
133 fail("NotFoundException should have been raised");
134 } catch (NotFoundException e) {
135 assertThat(e).hasMessage("Permission template with name '" + template.getName() + "' is not found (case insensitive)");
141 public void delete_template_by_name_returns_empty_when_wrong_organization_is_provided() throws Exception {
142 OrganizationDto organization = db.organizations().insert();
143 db.organizations().setDefaultTemplates(
144 db.permissionTemplates().insertTemplate(organization),
145 db.permissionTemplates().insertTemplate(organization));
146 PermissionTemplateDto template = insertTemplateAndAssociatedPermissions(organization);
147 OrganizationDto otherOrganization = db.organizations().insert();
148 loginAsAdmin(organization);
150 runOnAllUnderTests((underTest) -> {
152 newRequestByName(underTest, otherOrganization, template);
153 fail("NotFoundException should have been raised");
154 } catch (NotFoundException e) {
155 assertThat(e).hasMessage("Permission template with name '" + template.getName() + "' is not found (case insensitive)");
161 public void fail_if_uuid_is_not_known_without_views() throws Exception {
164 expectedException.expect(NotFoundException.class);
166 newRequestByUuid(underTestWithoutViews, "unknown-template-uuid");
170 public void fail_if_uuid_is_not_known_with_views() throws Exception {
173 expectedException.expect(NotFoundException.class);
175 newRequestByUuid(underTestWithViews, "unknown-template-uuid");
179 public void fail_to_delete_by_uuid_if_template_is_default_template_for_project_without_views() throws Exception {
180 fail_to_delete_by_uuid_if_template_is_default_template_for_project(this.underTestWithoutViews);
184 public void fail_to_delete_by_uuid_if_template_is_default_template_for_project_with_views() throws Exception {
185 fail_to_delete_by_uuid_if_template_is_default_template_for_project(this.underTestWithViews);
188 private void fail_to_delete_by_uuid_if_template_is_default_template_for_project(WsActionTester underTest) throws Exception {
189 OrganizationDto organization = db.organizations().insert();
190 PermissionTemplateDto projectTemplate = insertTemplateAndAssociatedPermissions(organization);
191 db.organizations().setDefaultTemplates(projectTemplate,
192 db.permissionTemplates().insertTemplate(organization));
193 loginAsAdmin(organization);
195 expectedException.expect(BadRequestException.class);
196 expectedException.expectMessage("It is not possible to delete the default permission template for projects");
198 newRequestByUuid(underTest, projectTemplate.getUuid());
202 public void fail_to_delete_by_name_if_template_is_default_template_for_project_without_views() throws Exception {
203 fail_to_delete_by_name_if_template_is_default_template_for_project(this.underTestWithoutViews);
207 public void fail_to_delete_by_name_if_template_is_default_template_for_project_with_views() throws Exception {
208 fail_to_delete_by_name_if_template_is_default_template_for_project(this.underTestWithViews);
211 private void fail_to_delete_by_name_if_template_is_default_template_for_project(WsActionTester underTest) throws Exception {
212 OrganizationDto organization = db.organizations().insert();
213 PermissionTemplateDto projectTemplate = insertTemplateAndAssociatedPermissions(organization);
214 db.organizations().setDefaultTemplates(projectTemplate, db.permissionTemplates().insertTemplate(organization));
215 loginAsAdmin(organization);
217 expectedException.expect(BadRequestException.class);
218 expectedException.expectMessage("It is not possible to delete the default permission template for projects");
220 newRequestByName(underTest, organization.getKey(), projectTemplate.getName());
224 public void fail_to_delete_by_uuid_if_template_is_default_template_for_view_with_views() throws Exception {
225 OrganizationDto organization = db.organizations().insert();
226 PermissionTemplateDto template = insertTemplateAndAssociatedPermissions(organization);
227 db.organizations().setDefaultTemplates(db.permissionTemplates().insertTemplate(organization), template);
228 loginAsAdmin(organization);
230 expectedException.expect(BadRequestException.class);
231 expectedException.expectMessage("It is not possible to delete the default permission template for views");
233 newRequestByUuid(this.underTestWithViews, template.getUuid());
237 public void default_template_for_views_can_be_deleted_by_uuid_if_views_is_not_installed_and_default_template_for_views_is_reset() throws Exception {
238 OrganizationDto organization = db.organizations().insert();
239 PermissionTemplateDto projectTemplate = db.permissionTemplates().insertTemplate(organization);
240 PermissionTemplateDto viewTemplate = insertTemplateAndAssociatedPermissions(organization);
241 db.organizations().setDefaultTemplates(projectTemplate, viewTemplate);
242 loginAsAdmin(organization);
244 newRequestByUuid(this.underTestWithoutViews, viewTemplate.getUuid());
246 assertTemplateDoesNotExist(viewTemplate);
248 assertThat(db.getDbClient().organizationDao().getDefaultTemplates(db.getSession(), organization.getUuid())
249 .get().getViewUuid())
254 public void fail_to_delete_by_uuid_if_not_logged_in_without_views() throws Exception {
255 expectedException.expect(UnauthorizedException.class);
257 newRequestByUuid(underTestWithoutViews, "uuid");
261 public void fail_to_delete_by_uuid_if_not_logged_in_with_views() throws Exception {
262 expectedException.expect(UnauthorizedException.class);
264 newRequestByUuid(underTestWithViews, "uuid");
268 public void fail_to_delete_by_name_if_not_logged_in_without_views() throws Exception {
269 expectedException.expect(UnauthorizedException.class);
271 newRequestByName(underTestWithoutViews, "whatever", "name");
275 public void fail_to_delete_by_name_if_not_logged_in_with_views() throws Exception {
276 expectedException.expect(UnauthorizedException.class);
278 newRequestByName(underTestWithViews, "whatever", "name");
282 public void fail_to_delete_by_uuid_if_not_admin_without_views() throws Exception {
283 OrganizationDto organization = db.organizations().insert();
284 PermissionTemplateDto template = insertTemplateAndAssociatedPermissions(organization);
287 expectedException.expect(ForbiddenException.class);
289 newRequestByUuid(underTestWithoutViews, template.getUuid());
293 public void fail_to_delete_by_uuid_if_not_admin_with_views() throws Exception {
294 OrganizationDto organization = db.organizations().insert();
295 PermissionTemplateDto template = insertTemplateAndAssociatedPermissions(organization);
298 expectedException.expect(ForbiddenException.class);
300 newRequestByUuid(underTestWithViews, template.getUuid());
304 public void fail_to_delete_by_name_if_not_admin_without_views() throws Exception {
305 OrganizationDto organization = db.organizations().insert();
306 PermissionTemplateDto template = db.permissionTemplates().insertTemplate(organization);
309 expectedException.expect(ForbiddenException.class);
311 newRequestByName(underTestWithoutViews, organization.getKey(), template.getName());
315 public void fail_to_delete_by_name_if_not_admin_with_views() throws Exception {
316 OrganizationDto organization = db.organizations().insert();
317 PermissionTemplateDto template = db.permissionTemplates().insertTemplate(PermissionTemplateTesting.newPermissionTemplateDto()
318 .setOrganizationUuid(organization.getUuid())
319 .setName("the name"));
322 expectedException.expect(ForbiddenException.class);
324 newRequestByName(underTestWithViews, organization, template);
328 public void fail_if_neither_uuid_nor_name_is_provided_without_views() throws Exception {
331 expectedException.expect(BadRequestException.class);
333 newRequestByUuid(underTestWithoutViews, null);
337 public void fail_if_neither_uuid_nor_name_is_provided_with_views() throws Exception {
340 expectedException.expect(BadRequestException.class);
342 newRequestByUuid(underTestWithViews, null);
346 public void fail_if_both_uuid_and_name_are_provided_without_views() throws Exception {
349 expectedException.expect(BadRequestException.class);
351 underTestWithoutViews.newRequest().setMethod("POST")
352 .setParam(PARAM_TEMPLATE_ID, "uuid")
353 .setParam(PARAM_TEMPLATE_NAME, "name")
358 public void fail_if_both_uuid_and_name_are_provided_with_views() throws Exception {
361 expectedException.expect(BadRequestException.class);
363 underTestWithViews.newRequest().setMethod("POST")
364 .setParam(PARAM_TEMPLATE_ID, "uuid")
365 .setParam(PARAM_TEMPLATE_NAME, "name")
370 // public void delete_perm_tpl_characteristic_when_delete_template() throws Exception {
371 // db.getDbClient().permissionTemplateCharacteristicDao().insert(db.getSession(), new PermissionTemplateCharacteristicDto()
372 // .setPermission(UserRole.USER)
373 // .setTemplateId(template.getId())
374 // .setWithProjectCreator(true)
375 // .setCreatedAt(new Date().getTime())
376 // .setUpdatedAt(new Date().getTime()));
379 // newRequest(template.getUuid());
381 // assertThat(db.getDbClient().permissionTemplateCharacteristicDao().selectByTemplateIds(db.getSession(),
382 // asList(template.getId()))).isEmpty();
385 private UserSessionRule loginAsAdmin(OrganizationDto organization) {
386 return userSession.logIn().addOrganizationPermission(organization.getUuid(), SYSTEM_ADMIN);
389 private void runOnAllUnderTests(ConsumerWithException<WsActionTester> consumer) throws Exception {
390 for (WsActionTester underTest : Arrays.asList(underTestWithoutViews, underTestWithViews)) {
391 consumer.accept(underTest);
395 private interface ConsumerWithException<T> {
396 void accept(T e) throws Exception;
399 private PermissionTemplateDto insertTemplateAndAssociatedPermissions(OrganizationDto organization) {
400 PermissionTemplateDto dto = db.permissionTemplates().insertTemplate(organization);
401 UserDto user = db.getDbClient().userDao().insert(db.getSession(), UserTesting.newUserDto().setActive(true));
402 GroupDto group = db.getDbClient().groupDao().insert(db.getSession(), GroupTesting.newGroupDto());
403 db.getDbClient().permissionTemplateDao().insertUserPermission(db.getSession(), dto.getId(), user.getId(), UserRole.ADMIN);
404 db.getDbClient().permissionTemplateDao().insertGroupPermission(db.getSession(), dto.getId(), group.getId(), UserRole.CODEVIEWER);
409 private TestResponse newRequestByUuid(WsActionTester actionTester, @Nullable String id) throws Exception {
410 TestRequest request = actionTester.newRequest().setMethod("POST");
412 request.setParam(PARAM_TEMPLATE_ID, id);
414 return request.execute();
417 private TestResponse newRequestByName(WsActionTester actionTester, @Nullable OrganizationDto organizationDto, @Nullable PermissionTemplateDto permissionTemplateDto)
419 return newRequestByName(
421 organizationDto == null ? null : organizationDto.getKey(),
422 permissionTemplateDto == null ? null : permissionTemplateDto.getName());
425 private TestResponse newRequestByName(WsActionTester actionTester, @Nullable String organizationKey, @Nullable String name) throws Exception {
426 TestRequest request = actionTester.newRequest().setMethod("POST");
427 if (organizationKey != null) {
428 request.setParam(PARAM_ORGANIZATION_KEY, organizationKey);
431 request.setParam(PARAM_TEMPLATE_NAME, name);
434 return request.execute();
437 private void assertTemplateDoesNotExist(PermissionTemplateDto template) {
438 assertThat(db.getDbClient().permissionTemplateDao().selectByUuid(db.getSession(), template.getUuid())).isNull();