]> source.dussan.org Git - sonarqube.git/blob
6118c8b0c709b3ba4f720214094e0aa3f6a941b9
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2016 SonarSource SA
4  * mailto:contact 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;
21
22 import java.io.IOException;
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.System2;
30 import org.sonar.api.web.UserRole;
31 import org.sonar.core.permission.GlobalPermissions;
32 import org.sonar.db.DbClient;
33 import org.sonar.db.DbSession;
34 import org.sonar.db.DbTester;
35 import org.sonar.db.component.ComponentDto;
36 import org.sonar.db.component.ResourceTypesRule;
37 import org.sonar.db.user.GroupDto;
38 import org.sonar.db.user.GroupRoleDto;
39 import org.sonar.db.user.UserDto;
40 import org.sonar.db.user.UserRoleDto;
41 import org.sonar.server.component.ComponentFinder;
42 import org.sonar.server.exceptions.ForbiddenException;
43 import org.sonar.server.exceptions.UnauthorizedException;
44 import org.sonar.server.i18n.I18nRule;
45 import org.sonar.server.tester.UserSessionRule;
46 import org.sonar.server.usergroups.ws.UserGroupFinder;
47 import org.sonar.server.ws.TestResponse;
48 import org.sonar.server.ws.WsActionTester;
49 import org.sonarqube.ws.MediaTypes;
50 import org.sonarqube.ws.WsPermissions.SearchProjectPermissionsWsResponse;
51
52 import static org.assertj.core.api.Assertions.assertThat;
53 import static org.sonar.api.server.ws.WebService.Param.PAGE;
54 import static org.sonar.api.server.ws.WebService.Param.PAGE_SIZE;
55 import static org.sonar.api.server.ws.WebService.Param.TEXT_QUERY;
56 import static org.sonar.db.component.ComponentTesting.newDeveloper;
57 import static org.sonar.db.component.ComponentTesting.newProjectCopy;
58 import static org.sonar.db.component.ComponentTesting.newProjectDto;
59 import static org.sonar.db.component.ComponentTesting.newView;
60 import static org.sonar.db.user.GroupTesting.newGroupDto;
61 import static org.sonar.db.user.UserTesting.newUserDto;
62 import static org.sonar.test.JsonAssert.assertJson;
63 import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_ID;
64 import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_QUALIFIER;
65
66
67 public class SearchProjectPermissionsActionTest {
68   @Rule
69   public ExpectedException expectedException = ExpectedException.none();
70   @Rule
71   public UserSessionRule userSession = UserSessionRule.standalone();
72   @Rule
73   public DbTester db = DbTester.create(System2.INSTANCE);
74
75   WsActionTester ws;
76   I18nRule i18n = new I18nRule();
77   DbClient dbClient = db.getDbClient();
78   final DbSession dbSession = db.getSession();
79   ResourceTypesRule resourceTypes = new ResourceTypesRule();
80   SearchProjectPermissionsDataLoader dataLoader;
81
82   SearchProjectPermissionsAction underTest;
83
84   @Before
85   public void setUp() {
86     resourceTypes.setRootQualifiers(Qualifiers.PROJECT, Qualifiers.VIEW, "DEV");
87     ComponentFinder componentFinder = new ComponentFinder(dbClient);
88     PermissionDependenciesFinder finder = new PermissionDependenciesFinder(dbClient, componentFinder, new UserGroupFinder(dbClient), resourceTypes);
89     i18n.setProjectPermissions();
90
91     dataLoader = new SearchProjectPermissionsDataLoader(dbClient, finder, resourceTypes);
92     underTest = new SearchProjectPermissionsAction(dbClient, userSession, i18n, resourceTypes, dataLoader);
93
94     ws = new WsActionTester(underTest);
95
96     userSession.login().setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN);
97   }
98
99   @Test
100   public void search_project_permissions() {
101     UserDto user1 = insertUser(newUserDto());
102     UserDto user2 = insertUser(newUserDto());
103     UserDto user3 = insertUser(newUserDto());
104
105     ComponentDto jdk7 = insertJdk7();
106     ComponentDto project2 = insertClang();
107     ComponentDto dev = insertDeveloper();
108     ComponentDto view = insertView();
109     insertProjectInView(jdk7, view);
110
111     insertUserRole(UserRole.ISSUE_ADMIN, user1.getId(), jdk7.getId());
112     insertUserRole(UserRole.ADMIN, user1.getId(), jdk7.getId());
113     insertUserRole(UserRole.ADMIN, user2.getId(), jdk7.getId());
114     insertUserRole(UserRole.ADMIN, user3.getId(), jdk7.getId());
115     insertUserRole(UserRole.ISSUE_ADMIN, user1.getId(), project2.getId());
116     insertUserRole(UserRole.ISSUE_ADMIN, user1.getId(), dev.getId());
117     insertUserRole(UserRole.ISSUE_ADMIN, user1.getId(), view.getId());
118     // global permission
119     insertUserRole(GlobalPermissions.SYSTEM_ADMIN, user1.getId(), null);
120
121     GroupDto group1 = insertGroup(newGroupDto());
122     GroupDto group2 = insertGroup(newGroupDto());
123     GroupDto group3 = insertGroup(newGroupDto());
124
125     insertGroupRole(UserRole.ADMIN, jdk7.getId(), null);
126     insertGroupRole(UserRole.ADMIN, jdk7.getId(), group1.getId());
127     insertGroupRole(UserRole.ADMIN, jdk7.getId(), group2.getId());
128     insertGroupRole(UserRole.ADMIN, jdk7.getId(), group3.getId());
129     insertGroupRole(UserRole.ADMIN, dev.getId(), group2.getId());
130     insertGroupRole(UserRole.ADMIN, view.getId(), group2.getId());
131
132     commit();
133
134     String result = ws.newRequest().execute().getInput();
135
136     assertJson(result)
137       .ignoreFields("permissions")
138       .isSimilarTo(getClass().getResource("search_project_permissions-example.json"));
139   }
140
141   @Test
142   public void empty_result() {
143     String result = ws.newRequest().execute().getInput();
144
145     assertJson(result)
146       .ignoreFields("permissions")
147       .isSimilarTo(getClass().getResource("SearchProjectPermissionsActionTest/empty.json"));
148   }
149
150   @Test
151   public void search_project_permissions_with_project_permission() {
152     userSession.login().addProjectUuidPermissions(UserRole.ADMIN, "project-uuid");
153     insertComponent(newProjectDto("project-uuid"));
154     commit();
155
156     String result = ws.newRequest()
157       .setParam(PARAM_PROJECT_ID, "project-uuid")
158       .execute().getInput();
159
160     assertThat(result).contains("project-uuid");
161   }
162
163   @Test
164   public void has_projects_ordered_by_name() {
165     for (int i = 9; i >= 1; i--) {
166       insertComponent(newProjectDto()
167         .setName("project-name-" + i));
168     }
169     commit();
170
171     String result = ws.newRequest()
172       .setParam(PAGE, "1")
173       .setParam(PAGE_SIZE, "3")
174       .execute().getInput();
175
176     assertThat(result)
177       .contains("project-name-1", "project-name-2", "project-name-3")
178       .doesNotContain("project-name-4");
179   }
180
181   @Test
182   public void search_by_query_on_name() {
183     insertComponent(newProjectDto().setName("project-name"));
184     insertComponent(newProjectDto().setName("another-name"));
185     commit();
186
187     String result = ws.newRequest()
188       .setParam(TEXT_QUERY, "project")
189       .execute().getInput();
190
191     assertThat(result).contains("project-name")
192       .doesNotContain("another-name");
193   }
194
195   @Test
196   public void search_by_query_on_key() {
197     insertComponent(newProjectDto().setKey("project-key"));
198     insertComponent(newProjectDto().setKey("another-key"));
199     commit();
200
201     String result = ws.newRequest()
202       .setParam(TEXT_QUERY, "project")
203       .execute().getInput();
204
205     assertThat(result).contains("project-key")
206       .doesNotContain("another-key");
207   }
208
209   @Test
210   public void handle_more_than_1000_projects() {
211     for (int i = 1; i <= 1001; i++) {
212       insertComponent(newProjectDto("project-uuid-" + i));
213     }
214     commit();
215
216     String result = ws.newRequest()
217       .setParam(TEXT_QUERY, "project")
218       .setParam(PAGE_SIZE, "1001")
219       .execute().getInput();
220
221     assertThat(result).contains("project-uuid-1", "project-uuid-999", "project-uuid-1001");
222   }
223
224   @Test
225   public void result_depends_of_root_types() {
226     resourceTypes.setRootQualifiers(Qualifiers.PROJECT);
227     insertComponent(newView("view-uuid"));
228     insertComponent(newDeveloper("developer-name"));
229     insertComponent(newProjectDto("project-uuid"));
230     commit();
231     dataLoader = new SearchProjectPermissionsDataLoader(dbClient,
232       new PermissionDependenciesFinder(dbClient, new ComponentFinder(dbClient), new UserGroupFinder(dbClient), resourceTypes),
233       resourceTypes);
234     underTest = new SearchProjectPermissionsAction(dbClient, userSession, i18n, resourceTypes, dataLoader);
235     ws = new WsActionTester(underTest);
236
237     String result = ws.newRequest().execute().getInput();
238
239     assertThat(result).contains("project-uuid")
240       .doesNotContain("view-uuid")
241       .doesNotContain("developer-name");
242   }
243
244   @Test
245   public void filter_by_qualifier() throws IOException {
246     insertComponent(newView("view-uuid"));
247     insertComponent(newDeveloper("developer-name"));
248     insertComponent(newProjectDto("project-uuid"));
249     commit();
250
251     TestResponse wsResponse = ws.newRequest()
252       .setMediaType(MediaTypes.PROTOBUF)
253       .setParam(PARAM_QUALIFIER, Qualifiers.PROJECT)
254       .execute();
255     SearchProjectPermissionsWsResponse result = SearchProjectPermissionsWsResponse.parseFrom(wsResponse.getInputStream());
256
257     assertThat(result.getProjectsList())
258       .extracting("id")
259       .contains("project-uuid")
260       .doesNotContain("view-uuid")
261       .doesNotContain("developer-name");
262   }
263
264   @Test
265   public void fail_if_not_logged_in() {
266     expectedException.expect(UnauthorizedException.class);
267     userSession.anonymous();
268
269     ws.newRequest().execute();
270   }
271
272   @Test
273   public void fail_if_not_admin() {
274     expectedException.expect(ForbiddenException.class);
275     userSession.login();
276
277     ws.newRequest().execute();
278   }
279
280   @Test
281   public void display_all_project_permissions() {
282     String result = ws.newRequest().execute().getInput();
283
284     assertJson(result)
285       .ignoreFields("permissions")
286       .isSimilarTo(getClass().getResource("SearchProjectPermissionsActionTest/display_all_project_permissions.json"));
287   }
288
289   private ComponentDto insertView() {
290     return insertComponent(newView()
291       .setUuid("752d8bfd-420c-4a83-a4e5-8ab19b13c8fc")
292       .setName("Java")
293       .setKey("Java"));
294   }
295
296   private ComponentDto insertProjectInView(ComponentDto project, ComponentDto view) {
297     return insertComponent(newProjectCopy("project-in-view-uuid", project, view));
298   }
299
300   private ComponentDto insertDeveloper() {
301     return insertComponent(newDeveloper("Simon Brandhof")
302       .setUuid("4e607bf9-7ed0-484a-946d-d58ba7dab2fb")
303       .setKey("simon-brandhof"));
304   }
305
306   private ComponentDto insertClang() {
307     return insertComponent(newProjectDto("project-uuid-2")
308       .setName("Clang")
309       .setKey("clang")
310       .setUuid("ce4c03d6-430f-40a9-b777-ad877c00aa4d"));
311   }
312
313   private ComponentDto insertJdk7() {
314     return insertComponent(newProjectDto("project-uuid-1")
315       .setName("JDK 7")
316       .setKey("net.java.openjdk:jdk7")
317       .setUuid("0bd7b1e7-91d6-439e-a607-4a3a9aad3c6a"));
318   }
319
320   private UserDto insertUser(UserDto user) {
321     return dbClient.userDao().insert(dbSession, user.setActive(true));
322   }
323
324   private void insertUserRole(String permission, long userId, @Nullable Long resourceId) {
325     dbClient.roleDao().insertUserRole(dbSession, new UserRoleDto()
326       .setRole(permission)
327       .setUserId(userId)
328       .setResourceId(resourceId));
329   }
330
331   private GroupDto insertGroup(GroupDto group) {
332     return dbClient.groupDao().insert(dbSession, group);
333   }
334
335   private void insertGroupRole(String permission, @Nullable Long resourceId, @Nullable Long groupId) {
336     dbClient.roleDao().insertGroupRole(dbSession, new GroupRoleDto().setRole(permission).setResourceId(resourceId).setGroupId(groupId));
337   }
338
339   private ComponentDto insertComponent(ComponentDto component) {
340     dbClient.componentDao().insert(dbSession, component.setEnabled(true));
341     return dbClient.componentDao().selectOrFailByUuid(dbSession, component.uuid());
342   }
343
344   private void commit() {
345     dbSession.commit();
346   }
347 }