]> source.dussan.org Git - sonarqube.git/blob
9a8a0b3ba897d3d5c1e6820962e2ff1e62eb22e6
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2023 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
22 import java.util.stream.IntStream;
23 import javax.annotation.Nullable;
24 import org.junit.Test;
25 import org.sonar.api.resources.Qualifiers;
26 import org.sonar.api.resources.ResourceTypes;
27 import org.sonar.api.server.ws.WebService;
28 import org.sonar.api.web.UserRole;
29 import org.sonar.core.permission.GlobalPermissions;
30 import org.sonar.db.component.ResourceTypesRule;
31 import org.sonar.db.permission.template.PermissionTemplateDto;
32 import org.sonar.db.permission.template.PermissionTemplateGroupDto;
33 import org.sonar.db.user.GroupDto;
34 import org.sonar.server.exceptions.BadRequestException;
35 import org.sonar.server.exceptions.ForbiddenException;
36 import org.sonar.server.exceptions.NotFoundException;
37 import org.sonar.server.exceptions.UnauthorizedException;
38 import org.sonar.server.permission.PermissionService;
39 import org.sonar.server.permission.PermissionServiceImpl;
40 import org.sonar.server.permission.RequestValidator;
41 import org.sonar.server.permission.ws.BasePermissionWsTest;
42 import org.sonar.server.permission.ws.WsParameters;
43 import org.sonarqube.ws.Permissions.WsGroupsResponse;
44
45 import static org.assertj.core.api.Assertions.assertThat;
46 import static org.assertj.core.api.Assertions.assertThatThrownBy;
47 import static org.sonar.api.server.ws.WebService.Param.PAGE;
48 import static org.sonar.api.server.ws.WebService.Param.PAGE_SIZE;
49 import static org.sonar.api.server.ws.WebService.Param.TEXT_QUERY;
50 import static org.sonar.api.web.UserRole.ADMIN;
51 import static org.sonar.api.web.UserRole.CODEVIEWER;
52 import static org.sonar.api.web.UserRole.ISSUE_ADMIN;
53 import static org.sonar.api.web.UserRole.USER;
54 import static org.sonar.db.permission.PermissionQuery.DEFAULT_PAGE_SIZE;
55 import static org.sonar.db.permission.template.PermissionTemplateTesting.newPermissionTemplateGroupDto;
56 import static org.sonar.db.user.GroupTesting.newGroupDto;
57 import static org.sonar.test.JsonAssert.assertJson;
58 import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PERMISSION;
59 import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_TEMPLATE_ID;
60 import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_TEMPLATE_NAME;
61
62 public class TemplateGroupsActionTest extends BasePermissionWsTest<TemplateGroupsAction> {
63
64   private final ResourceTypes resourceTypes = new ResourceTypesRule().setRootQualifiers(Qualifiers.PROJECT);
65   private final PermissionService permissionService = new PermissionServiceImpl(resourceTypes);
66   private final WsParameters wsParameters = new WsParameters(permissionService);
67   private final RequestValidator requestValidator = new RequestValidator(permissionService);
68
69   @Override
70   protected TemplateGroupsAction buildWsAction() {
71     return new TemplateGroupsAction(db.getDbClient(), userSession, newPermissionWsSupport(), wsParameters, requestValidator);
72   }
73
74   @Test
75   public void define_template_groups() {
76     WebService.Action action = wsTester.getDef();
77
78     assertThat(action).isNotNull();
79     assertThat(action.key()).isEqualTo("template_groups");
80     assertThat(action.isPost()).isFalse();
81     assertThat(action.isInternal()).isTrue();
82     assertThat(action.since()).isEqualTo("5.2");
83   }
84
85   @Test
86   public void template_groups_of_json_example() {
87     GroupDto adminGroup = insertGroup("sonar-administrators", "System administrators");
88     GroupDto userGroup = insertGroup("sonar-users", "Every authenticated user automatically belongs to this group");
89
90     PermissionTemplateDto template = addTemplate();
91     addGroupToTemplate(newPermissionTemplateGroup(ISSUE_ADMIN, template.getUuid(), adminGroup.getUuid()), template.getName());
92     addGroupToTemplate(newPermissionTemplateGroup(ISSUE_ADMIN, template.getUuid(), userGroup.getUuid()), template.getName());
93     // Anyone group
94     addGroupToTemplate(newPermissionTemplateGroup(USER, template.getUuid(), null), template.getName());
95     addGroupToTemplate(newPermissionTemplateGroup(ISSUE_ADMIN, template.getUuid(), null), template.getName());
96     loginAsAdmin();
97
98     String response = newRequest()
99       .setParam(PARAM_PERMISSION, ISSUE_ADMIN)
100       .setParam(PARAM_TEMPLATE_ID, template.getUuid())
101       .execute()
102       .getInput();
103
104     assertJson(response)
105       .ignoreFields("id")
106       .withStrictArrayOrder()
107       .isSimilarTo(getClass().getResource("template_groups-example.json"));
108   }
109
110   @Test
111   public void return_all_permissions_of_matching_groups() {
112     PermissionTemplateDto template = addTemplate();
113
114     GroupDto group1 = db.users().insertGroup("group-1-name");
115     addGroupToTemplate(newPermissionTemplateGroup(CODEVIEWER, template.getUuid(), group1.getUuid()), template.getName());
116     addGroupToTemplate(newPermissionTemplateGroup(ADMIN, template.getUuid(), group1.getUuid()), template.getName());
117
118     GroupDto group2 = db.users().insertGroup("group-2-name");
119     addGroupToTemplate(newPermissionTemplateGroup(USER, template.getUuid(), group2.getUuid()), template.getName());
120     addGroupToTemplate(newPermissionTemplateGroup(ADMIN, template.getUuid(), group2.getUuid()), template.getName());
121
122     GroupDto group3 = db.users().insertGroup("group-3-name");
123
124     // Anyone
125     addGroupToTemplate(newPermissionTemplateGroup(USER, template.getUuid(), null), template.getName());
126     addGroupToTemplate(newPermissionTemplateGroup(ISSUE_ADMIN, template.getUuid(), null), template.getName());
127
128     PermissionTemplateDto anotherTemplate = addTemplate();
129     GroupDto group4 = db.users().insertGroup("group-4-name");
130     addGroupToTemplate(newPermissionTemplateGroup(ADMIN, anotherTemplate.getUuid(), group3.getUuid()), anotherTemplate.getName());
131     addGroupToTemplate(newPermissionTemplateGroup(ADMIN, anotherTemplate.getUuid(), group4.getUuid()), anotherTemplate.getName());
132     loginAsAdmin();
133
134     WsGroupsResponse response = newRequest()
135       .setParam(PARAM_TEMPLATE_ID, template.getUuid())
136       .executeProtobuf(WsGroupsResponse.class);
137
138     assertThat(response.getGroupsList()).extracting("name").containsExactly("Anyone", "group-1-name", "group-2-name", "group-3-name", "group-4-name");
139     assertThat(response.getGroups(0).getPermissionsList()).containsOnly("user", "issueadmin");
140     assertThat(response.getGroups(1).getPermissionsList()).containsOnly("codeviewer", "admin");
141     assertThat(response.getGroups(2).getPermissionsList()).containsOnly("user", "admin");
142     assertThat(response.getGroups(3).getPermissionsList()).isEmpty();
143   }
144
145   @Test
146   public void search_by_permission() {
147     PermissionTemplateDto template = addTemplate();
148
149     GroupDto group1 = db.users().insertGroup("group-1-name");
150     addGroupToTemplate(newPermissionTemplateGroup(USER, template.getUuid(), group1.getUuid()), template.getName());
151     addGroupToTemplate(newPermissionTemplateGroup(CODEVIEWER, template.getUuid(), group1.getUuid()), template.getName());
152
153     GroupDto group2 = db.users().insertGroup("group-2-name");
154     addGroupToTemplate(newPermissionTemplateGroup(ADMIN, template.getUuid(), group2.getUuid()), template.getName());
155
156     GroupDto group3 = db.users().insertGroup("group-3-name");
157
158     // Anyone
159     addGroupToTemplate(newPermissionTemplateGroup(USER, template.getUuid(), null), template.getName());
160
161     PermissionTemplateDto anotherTemplate = addTemplate();
162     addGroupToTemplate(newPermissionTemplateGroup(ADMIN, anotherTemplate.getUuid(), group3.getUuid()), anotherTemplate.getName());
163     loginAsAdmin();
164
165     WsGroupsResponse response = newRequest()
166       .setParam(PARAM_PERMISSION, USER)
167       .setParam(PARAM_TEMPLATE_ID, template.getUuid())
168       .executeProtobuf(WsGroupsResponse.class);
169
170     assertThat(response.getGroupsList()).extracting("name").containsExactly("Anyone", "group-1-name");
171     assertThat(response.getGroups(0).getPermissionsList()).containsOnly("user");
172     assertThat(response.getGroups(1).getPermissionsList()).containsOnly("user", "codeviewer");
173   }
174
175   @Test
176   public void search_by_template_name() {
177     GroupDto group1 = db.users().insertGroup("group-1-name");
178     GroupDto group2 = db.users().insertGroup("group-2-name");
179     GroupDto group3 = db.users().insertGroup("group-3-name");
180
181     PermissionTemplateDto template = addTemplate();
182     addGroupToTemplate(newPermissionTemplateGroup(USER, template.getUuid(), group1.getUuid()), template.getName());
183     addGroupToTemplate(newPermissionTemplateGroup(ADMIN, template.getUuid(), group2.getUuid()), template.getName());
184     addGroupToTemplate(newPermissionTemplateGroup(USER, template.getUuid(), null), template.getName());
185
186     PermissionTemplateDto anotherTemplate = addTemplate();
187     addGroupToTemplate(newPermissionTemplateGroup(USER, anotherTemplate.getUuid(), group1.getUuid()), anotherTemplate.getName());
188     loginAsAdmin();
189
190     WsGroupsResponse response = newRequest()
191       .setParam(PARAM_TEMPLATE_NAME, template.getName())
192       .executeProtobuf(WsGroupsResponse.class);
193
194     assertThat(response.getGroupsList()).extracting("name").containsExactly("Anyone", "group-1-name", "group-2-name", "group-3-name");
195   }
196
197   @Test
198   public void search_with_pagination() {
199     PermissionTemplateDto template = addTemplate();
200     GroupDto group1 = db.users().insertGroup("group-1-name");
201     addGroupToTemplate(newPermissionTemplateGroup(USER, template.getUuid(), group1.getUuid()), template.getName());
202     GroupDto group2 = db.users().insertGroup("group-2-name");
203     addGroupToTemplate(newPermissionTemplateGroup(USER, template.getUuid(), group2.getUuid()), template.getName());
204     loginAsAdmin();
205
206     WsGroupsResponse response = newRequest()
207       .setParam(PARAM_PERMISSION, USER)
208       .setParam(PARAM_TEMPLATE_NAME, template.getName())
209       .setParam(PAGE, "2")
210       .setParam(PAGE_SIZE, "1")
211       .executeProtobuf(WsGroupsResponse.class);
212
213     assertThat(response.getGroupsList()).extracting("name").containsExactly("group-2-name");
214   }
215
216   @Test
217   public void search_with_text_query() {
218     PermissionTemplateDto template = addTemplate();
219     GroupDto group1 = db.users().insertGroup("group-1-name");
220     addGroupToTemplate(newPermissionTemplateGroup(USER, template.getUuid(), group1.getUuid()), template.getName());
221     GroupDto group2 = db.users().insertGroup("group-2-name");
222     GroupDto group3 = db.users().insertGroup("group-3");
223     loginAsAdmin();
224
225     WsGroupsResponse response = newRequest()
226       .setParam(PARAM_TEMPLATE_NAME, template.getName())
227       .setParam(TEXT_QUERY, "-nam")
228       .executeProtobuf(WsGroupsResponse.class);
229
230     assertThat(response.getGroupsList()).extracting("name").containsExactly("group-1-name", "group-2-name");
231   }
232
233   @Test
234   public void search_with_text_query_return_all_groups_even_when_no_permission_set() {
235     PermissionTemplateDto template = addTemplate();
236     db.users().insertGroup("group-1-name");
237     db.users().insertGroup("group-2-name");
238     db.users().insertGroup("group-3-name");
239     loginAsAdmin();
240
241     WsGroupsResponse response = newRequest()
242       .setParam(PARAM_TEMPLATE_ID, template.getUuid())
243       .setParam(TEXT_QUERY, "-name")
244       .executeProtobuf(WsGroupsResponse.class);
245
246     assertThat(response.getGroupsList()).extracting("name").containsExactly("group-1-name", "group-2-name", "group-3-name");
247     assertThat(response.getGroups(0).getPermissionsList()).isEmpty();
248     assertThat(response.getGroups(1).getPermissionsList()).isEmpty();
249     assertThat(response.getGroups(2).getPermissionsList()).isEmpty();
250   }
251
252   @Test
253   public void search_with_text_query_return_anyone_group_even_when_no_permission_set() {
254     PermissionTemplateDto template = addTemplate();
255     GroupDto group = db.users().insertGroup("group");
256     addGroupToTemplate(newPermissionTemplateGroup(USER, template.getUuid(), group.getUuid()), template.getName());
257     loginAsAdmin();
258
259     WsGroupsResponse response = newRequest()
260       .setParam(PARAM_TEMPLATE_ID, template.getUuid())
261       .setParam(TEXT_QUERY, "nyo")
262       .executeProtobuf(WsGroupsResponse.class);
263
264     assertThat(response.getGroupsList()).extracting("name").containsExactly("Anyone");
265     assertThat(response.getGroups(0).getPermissionsList()).isEmpty();
266   }
267
268   @Test
269   public void search_ignores_other_template_and_is_ordered_by_groups_with_permission_then_by_name_when_many_groups() {
270     PermissionTemplateDto template = addTemplate();
271     PermissionTemplateDto otherTemplate = db.permissionTemplates().insertTemplate();
272     IntStream.rangeClosed(1, DEFAULT_PAGE_SIZE + 1).forEach(i -> {
273       GroupDto group = db.users().insertGroup("Group-" + i);
274       db.permissionTemplates().addGroupToTemplate(otherTemplate, group, UserRole.USER);
275     });
276     String lastGroupName = "Group-" + (DEFAULT_PAGE_SIZE + 1);
277     db.permissionTemplates().addGroupToTemplate(template, db.users().selectGroup(lastGroupName).get(), UserRole.USER);
278     loginAsAdmin();
279
280     WsGroupsResponse response = newRequest()
281       .setParam(PARAM_TEMPLATE_ID, template.getUuid())
282       .executeProtobuf(WsGroupsResponse.class);
283
284     assertThat(response.getGroupsList())
285       .extracting("name")
286       .hasSize(DEFAULT_PAGE_SIZE)
287       .startsWith("Anyone", lastGroupName, "Group-1");
288   }
289
290   @Test
291   public void fail_if_not_logged_in() {
292     PermissionTemplateDto template1 = addTemplate();
293     userSession.anonymous();
294
295     assertThatThrownBy(() ->  {
296       newRequest()
297         .setParam(PARAM_PERMISSION, USER)
298         .setParam(PARAM_TEMPLATE_ID, template1.getUuid())
299         .execute();
300     })
301       .isInstanceOf(UnauthorizedException.class);
302   }
303
304   @Test
305   public void fail_if_insufficient_privileges() {
306     PermissionTemplateDto template1 = addTemplate();
307     userSession.logIn();
308
309     assertThatThrownBy(() ->  {
310       newRequest()
311         .setParam(PARAM_PERMISSION, USER)
312         .setParam(PARAM_TEMPLATE_ID, template1.getUuid())
313         .execute();
314     })
315       .isInstanceOf(ForbiddenException.class);
316   }
317
318   @Test
319   public void fail_if_template_uuid_and_name_provided() {
320     PermissionTemplateDto template1 = addTemplate();
321     loginAsAdmin();
322
323     assertThatThrownBy(() ->  {
324       newRequest()
325         .setParam(PARAM_PERMISSION, USER)
326         .setParam(PARAM_TEMPLATE_ID, template1.getUuid())
327         .setParam(PARAM_TEMPLATE_NAME, template1.getName())
328         .execute();
329     })
330       .isInstanceOf(BadRequestException.class);
331   }
332
333   @Test
334   public void fail_if_template_uuid_nor_name_provided() {
335     loginAsAdmin();
336
337     assertThatThrownBy(() ->  {
338       newRequest()
339         .setParam(PARAM_PERMISSION, USER)
340         .execute();
341     })
342       .isInstanceOf(BadRequestException.class);
343   }
344
345   @Test
346   public void fail_if_template_is_not_found() {
347     loginAsAdmin();
348
349     assertThatThrownBy(() ->  {
350       newRequest()
351         .setParam(PARAM_PERMISSION, USER)
352         .setParam(PARAM_TEMPLATE_ID, "unknown-uuid")
353         .execute();
354     })
355       .isInstanceOf(NotFoundException.class);
356   }
357
358   @Test
359   public void fail_if_not_a_project_permission() {
360     loginAsAdmin();
361     PermissionTemplateDto template1 = addTemplate();
362
363     assertThatThrownBy(() ->  {
364       newRequest()
365         .setParam(PARAM_PERMISSION, GlobalPermissions.QUALITY_GATE_ADMIN)
366         .setParam(PARAM_TEMPLATE_ID, template1.getUuid())
367         .execute();
368     })
369       .isInstanceOf(IllegalArgumentException.class);
370   }
371
372   private GroupDto insertGroup(String name, String description) {
373     return db.users().insertGroup(newGroupDto().setName(name).setDescription(description));
374   }
375
376   private void addGroupToTemplate(PermissionTemplateGroupDto permissionTemplateGroup, String templateName) {
377     db.getDbClient().permissionTemplateDao().insertGroupPermission(db.getSession(), permissionTemplateGroup, templateName);
378     db.commit();
379   }
380
381   private static PermissionTemplateGroupDto newPermissionTemplateGroup(String permission, String templateUuid, @Nullable String groupUuid) {
382     return newPermissionTemplateGroupDto()
383       .setPermission(permission)
384       .setTemplateUuid(templateUuid)
385       .setGroupUuid(groupUuid);
386   }
387
388 }