3 * Copyright (C) 2009-2017 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.permission.ws.template;
22 import java.util.List;
23 import org.junit.Before;
24 import org.junit.Test;
25 import org.sonar.api.resources.Qualifiers;
26 import org.sonar.api.server.ws.WebService.Param;
27 import org.sonar.api.web.UserRole;
28 import org.sonar.db.component.ComponentDto;
29 import org.sonar.db.component.ComponentTesting;
30 import org.sonar.db.organization.OrganizationDto;
31 import org.sonar.db.permission.PermissionQuery;
32 import org.sonar.db.permission.template.PermissionTemplateDto;
33 import org.sonar.db.user.GroupDto;
34 import org.sonar.db.user.UserDto;
35 import org.sonar.server.es.ProjectIndexers;
36 import org.sonar.server.es.TestProjectIndexers;
37 import org.sonar.server.exceptions.BadRequestException;
38 import org.sonar.server.exceptions.NotFoundException;
39 import org.sonar.server.i18n.I18nRule;
40 import org.sonar.server.permission.PermissionTemplateService;
41 import org.sonar.server.permission.ws.BasePermissionWsTest;
43 import static org.assertj.core.api.Assertions.assertThat;
44 import static org.sonar.db.component.ComponentTesting.newApplication;
45 import static org.sonar.db.component.ComponentTesting.newView;
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_QUALIFIERS;
51 public class BulkApplyTemplateActionTest extends BasePermissionWsTest<BulkApplyTemplateAction> {
54 public DefaultTemplatesResolverRule defaultTemplatesResolver = DefaultTemplatesResolverRule.withoutGovernance();
56 private UserDto user1;
57 private UserDto user2;
58 private GroupDto group1;
59 private GroupDto group2;
60 private OrganizationDto organization;
61 private PermissionTemplateDto template1;
62 private PermissionTemplateDto template2;
63 private ProjectIndexers projectIndexers = new TestProjectIndexers();
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());
74 organization = db.organizations().insert();
76 user1 = db.users().insertUser();
77 user2 = db.users().insertUser();
78 group1 = db.users().insertGroup(organization);
79 group2 = db.users().insertGroup(organization);
81 db.organizations().addMember(organization, user1);
82 db.organizations().addMember(organization, user2);
84 // template 1 for org 1
85 template1 = db.permissionTemplates().insertTemplate(organization);
86 addUserToTemplate(user1, template1, UserRole.CODEVIEWER);
87 addUserToTemplate(user2, template1, UserRole.ISSUE_ADMIN);
88 addGroupToTemplate(group1, template1, UserRole.ADMIN);
89 addGroupToTemplate(group2, template1, UserRole.USER);
91 template2 = db.permissionTemplates().insertTemplate(organization);
92 addUserToTemplate(user1, template2, UserRole.USER);
93 addUserToTemplate(user2, template2, UserRole.USER);
94 addGroupToTemplate(group1, template2, UserRole.USER);
95 addGroupToTemplate(group2, template2, UserRole.USER);
99 public void bulk_apply_template_by_template_uuid() throws Exception {
100 // this project should not be applied the template
101 OrganizationDto otherOrganization = db.organizations().insert();
102 db.components().insertPrivateProject(otherOrganization);
104 ComponentDto privateProject = db.components().insertPrivateProject(organization);
105 ComponentDto publicProject = db.components().insertPublicProject(organization);
106 ComponentDto view = db.components().insertView(organization);
107 loginAsAdmin(organization);
110 .setParam(PARAM_TEMPLATE_ID, template1.getUuid())
111 .setParam(PARAM_QUALIFIERS, String.join(",", Qualifiers.PROJECT, Qualifiers.VIEW))
114 assertTemplate1AppliedToPrivateProject(privateProject);
115 assertTemplate1AppliedToPublicProject(publicProject);
116 assertTemplate1AppliedToPublicProject(view);
120 public void request_throws_NotFoundException_if_template_with_specified_name_does_not_exist_in_specified_organization() throws Exception {
121 OrganizationDto otherOrganization = db.organizations().insert();
122 loginAsAdmin(otherOrganization);
124 expectedException.expect(NotFoundException.class);
125 expectedException.expectMessage("Permission template with name '" + template1.getName()
126 + "' is not found (case insensitive) in organization with key '" + otherOrganization.getKey() + "'");
129 .setParam(PARAM_ORGANIZATION, otherOrganization.getKey())
130 .setParam(PARAM_TEMPLATE_NAME, template1.getName())
135 public void bulk_apply_template_by_template_name() throws Exception {
136 ComponentDto privateProject = db.components().insertPrivateProject(organization);
137 ComponentDto publicProject = db.components().insertPublicProject(organization);
138 loginAsAdmin(organization);
141 .setParam(PARAM_ORGANIZATION, organization.getKey())
142 .setParam(PARAM_TEMPLATE_NAME, template1.getName())
145 assertTemplate1AppliedToPrivateProject(privateProject);
146 assertTemplate1AppliedToPublicProject(publicProject);
150 public void apply_template_by_qualifiers() throws Exception {
151 ComponentDto publicProject = db.components().insertPublicProject(organization);
152 ComponentDto privateProject = db.components().insertPrivateProject(organization);
153 ComponentDto view = db.components().insertComponent(newView(organization));
154 ComponentDto application = db.components().insertComponent(newApplication(organization));
155 loginAsAdmin(organization);
158 .setParam(PARAM_TEMPLATE_ID, template1.getUuid())
159 .setParam(PARAM_QUALIFIERS, String.join(",", Qualifiers.PROJECT, Qualifiers.APP))
162 assertTemplate1AppliedToPrivateProject(privateProject);
163 assertTemplate1AppliedToPublicProject(publicProject);
164 assertTemplate1AppliedToPublicProject(application);
165 assertNoPermissionOnProject(view);
169 public void apply_template_by_query_on_name_and_key_public_project() throws Exception {
170 ComponentDto publicProjectFoundByKey = ComponentTesting.newPublicProjectDto(organization).setDbKey("sonar");
171 db.components().insertProjectAndSnapshot(publicProjectFoundByKey);
172 ComponentDto publicProjectFoundByName = ComponentTesting.newPublicProjectDto(organization).setName("name-sonar-name");
173 db.components().insertProjectAndSnapshot(publicProjectFoundByName);
174 // match must be exact on key
175 ComponentDto projectUntouched = ComponentTesting.newPublicProjectDto(organization).setDbKey("new-sonar").setName("project-name");
176 db.components().insertProjectAndSnapshot(projectUntouched);
177 loginAsAdmin(organization);
180 .setParam(PARAM_TEMPLATE_ID, template1.getUuid())
181 .setParam(Param.TEXT_QUERY, "sonar")
184 assertTemplate1AppliedToPublicProject(publicProjectFoundByKey);
185 assertTemplate1AppliedToPublicProject(publicProjectFoundByName);
186 assertNoPermissionOnProject(projectUntouched);
190 public void apply_template_by_query_on_name_and_key() throws Exception {
191 ComponentDto privateProjectFoundByKey = ComponentTesting.newPrivateProjectDto(organization).setDbKey("sonar");
192 db.components().insertProjectAndSnapshot(privateProjectFoundByKey);
193 ComponentDto privateProjectFoundByName = ComponentTesting.newPrivateProjectDto(organization).setName("name-sonar-name");
194 db.components().insertProjectAndSnapshot(privateProjectFoundByName);
195 // match must be exact on key
196 ComponentDto projectUntouched = ComponentTesting.newPublicProjectDto(organization).setDbKey("new-sonar").setName("project-name");
197 db.components().insertProjectAndSnapshot(projectUntouched);
198 loginAsAdmin(organization);
201 .setParam(PARAM_TEMPLATE_ID, template1.getUuid())
202 .setParam(Param.TEXT_QUERY, "sonar")
205 assertTemplate1AppliedToPrivateProject(privateProjectFoundByKey);
206 assertTemplate1AppliedToPrivateProject(privateProjectFoundByName);
207 assertNoPermissionOnProject(projectUntouched);
211 public void fail_if_no_template_parameter() throws Exception {
212 loginAsAdmin(db.getDefaultOrganization());
214 expectedException.expect(BadRequestException.class);
215 expectedException.expectMessage("Template name or template id must be provided, not both.");
217 newRequest().execute();
221 public void fail_if_template_name_is_incorrect() throws Exception {
222 loginAsAdmin(db.getDefaultOrganization());
224 expectedException.expect(NotFoundException.class);
225 expectedException.expectMessage("Permission template with id 'unknown-template-uuid' is not found");
227 newRequest().setParam(PARAM_TEMPLATE_ID, "unknown-template-uuid").execute();
230 private void assertTemplate1AppliedToPublicProject(ComponentDto project) throws Exception {
231 assertThat(selectProjectPermissionGroups(project, UserRole.ADMIN)).containsExactly(group1.getName());
232 assertThat(selectProjectPermissionGroups(project, UserRole.USER)).isEmpty();
233 assertThat(selectProjectPermissionUsers(project, UserRole.ADMIN)).isEmpty();
234 assertThat(selectProjectPermissionUsers(project, UserRole.CODEVIEWER)).isEmpty();
235 assertThat(selectProjectPermissionUsers(project, UserRole.ISSUE_ADMIN)).containsExactly(user2.getId());
238 private void assertTemplate1AppliedToPrivateProject(ComponentDto project) throws Exception {
239 assertThat(selectProjectPermissionGroups(project, UserRole.ADMIN)).containsExactly(group1.getName());
240 assertThat(selectProjectPermissionGroups(project, UserRole.USER)).containsExactly(group2.getName());
241 assertThat(selectProjectPermissionUsers(project, UserRole.ADMIN)).isEmpty();
242 assertThat(selectProjectPermissionUsers(project, UserRole.CODEVIEWER)).containsExactly(user1.getId());
243 assertThat(selectProjectPermissionUsers(project, UserRole.ISSUE_ADMIN)).containsExactly(user2.getId());
246 private void assertNoPermissionOnProject(ComponentDto project) throws Exception {
247 assertThat(selectProjectPermissionGroups(project, UserRole.ADMIN)).isEmpty();
248 assertThat(selectProjectPermissionGroups(project, UserRole.CODEVIEWER)).isEmpty();
249 assertThat(selectProjectPermissionGroups(project, UserRole.ISSUE_ADMIN)).isEmpty();
250 assertThat(selectProjectPermissionGroups(project, UserRole.USER)).isEmpty();
251 assertThat(selectProjectPermissionUsers(project, UserRole.ADMIN)).isEmpty();
252 assertThat(selectProjectPermissionUsers(project, UserRole.CODEVIEWER)).isEmpty();
253 assertThat(selectProjectPermissionUsers(project, UserRole.ISSUE_ADMIN)).isEmpty();
254 assertThat(selectProjectPermissionUsers(project, UserRole.USER)).isEmpty();
257 private void addUserToTemplate(UserDto user, PermissionTemplateDto permissionTemplate, String permission) {
258 db.getDbClient().permissionTemplateDao().insertUserPermission(db.getSession(), permissionTemplate.getId(), user.getId(), permission);
262 private void addGroupToTemplate(GroupDto group, PermissionTemplateDto permissionTemplate, String permission) {
263 db.getDbClient().permissionTemplateDao().insertGroupPermission(db.getSession(), permissionTemplate.getId(), group.getId(), permission);
267 private List<String> selectProjectPermissionGroups(ComponentDto project, String permission) {
268 PermissionQuery query = PermissionQuery.builder().setOrganizationUuid(project.getOrganizationUuid()).setPermission(permission).setComponentUuid(project.uuid()).build();
269 return db.getDbClient().groupPermissionDao().selectGroupNamesByQuery(db.getSession(), query);
272 private List<Integer> selectProjectPermissionUsers(ComponentDto project, String permission) {
273 PermissionQuery query = PermissionQuery.builder().setOrganizationUuid(project.getOrganizationUuid()).setPermission(permission).setComponentUuid(project.uuid()).build();
274 return db.getDbClient().userPermissionDao().selectUserIdsByQuery(db.getSession(), query);