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