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;
22 import org.junit.Before;
23 import org.junit.Test;
24 import org.sonar.api.resources.Qualifiers;
25 import org.sonar.api.web.UserRole;
26 import org.sonar.core.permission.GlobalPermissions;
27 import org.sonar.db.component.ComponentDbTester;
28 import org.sonar.db.component.ComponentDto;
29 import org.sonar.db.component.ResourceTypesRule;
30 import org.sonar.db.user.GroupDto;
31 import org.sonar.db.user.UserDto;
32 import org.sonar.server.exceptions.ForbiddenException;
33 import org.sonar.server.exceptions.UnauthorizedException;
34 import org.sonar.server.i18n.I18nRule;
35 import org.sonar.server.ws.WsTester;
36 import org.sonarqube.ws.MediaTypes;
37 import org.sonarqube.ws.WsPermissions;
39 import static org.assertj.core.api.Assertions.assertThat;
40 import static org.sonar.api.server.ws.WebService.Param.PAGE;
41 import static org.sonar.api.server.ws.WebService.Param.PAGE_SIZE;
42 import static org.sonar.api.server.ws.WebService.Param.TEXT_QUERY;
43 import static org.sonar.db.component.ComponentTesting.newDeveloper;
44 import static org.sonar.db.component.ComponentTesting.newProjectCopy;
45 import static org.sonar.db.component.ComponentTesting.newProjectDto;
46 import static org.sonar.db.component.ComponentTesting.newView;
47 import static org.sonar.db.user.GroupTesting.newGroupDto;
48 import static org.sonar.test.JsonAssert.assertJson;
49 import static org.sonarqube.ws.client.permission.PermissionsWsParameters.CONTROLLER;
50 import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_ID;
51 import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_QUALIFIER;
53 public class SearchProjectPermissionsActionTest extends BasePermissionWsTest<SearchProjectPermissionsAction> {
55 private ComponentDbTester componentDb = new ComponentDbTester(db);
56 private I18nRule i18n = new I18nRule();
60 i18n.setProjectPermissions();
61 userSession.login().setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN);
65 protected SearchProjectPermissionsAction buildWsAction() {
66 i18n.setProjectPermissions();
67 ResourceTypesRule rootResourceTypes = newRootResourceTypes();
68 PermissionWsSupport wsSupport = newPermissionWsSupport();
69 SearchProjectPermissionsDataLoader dataLoader = new SearchProjectPermissionsDataLoader(db.getDbClient(), wsSupport, rootResourceTypes);
70 return new SearchProjectPermissionsAction(db.getDbClient(), userSession, i18n, rootResourceTypes, dataLoader, wsSupport);
74 public void search_project_permissions() throws Exception {
75 UserDto user1 = db.users().insertUser();
76 UserDto user2 = db.users().insertUser();
77 UserDto user3 = db.users().insertUser();
79 ComponentDto jdk7 = insertJdk7();
80 ComponentDto project2 = insertClang();
81 ComponentDto dev = insertDeveloper();
82 ComponentDto view = insertView();
83 insertProjectInView(jdk7, view);
85 db.users().insertProjectPermissionOnUser(user1, UserRole.ISSUE_ADMIN, jdk7);
86 db.users().insertProjectPermissionOnUser(user1, UserRole.ADMIN, jdk7);
87 db.users().insertProjectPermissionOnUser(user2, UserRole.ADMIN, jdk7);
88 db.users().insertProjectPermissionOnUser(user3, UserRole.ADMIN, jdk7);
89 db.users().insertProjectPermissionOnUser(user1, UserRole.ISSUE_ADMIN, project2);
90 db.users().insertProjectPermissionOnUser(user1, UserRole.ISSUE_ADMIN, dev);
91 db.users().insertProjectPermissionOnUser(user1, UserRole.ISSUE_ADMIN, view);
93 db.users().insertPermissionOnUser(user1, GlobalPermissions.SYSTEM_ADMIN);
95 GroupDto group1 = db.users().insertGroup(newGroupDto());
96 GroupDto group2 = db.users().insertGroup(newGroupDto());
97 GroupDto group3 = db.users().insertGroup(newGroupDto());
99 db.users().insertProjectPermissionOnAnyone(db.getDefaultOrganization(), UserRole.ADMIN, jdk7);
100 db.users().insertProjectPermissionOnGroup(group1, UserRole.ADMIN, jdk7);
101 db.users().insertProjectPermissionOnGroup(group2, UserRole.ADMIN, jdk7);
102 db.users().insertProjectPermissionOnGroup(group3, UserRole.ADMIN, jdk7);
103 db.users().insertProjectPermissionOnGroup(group2, UserRole.ADMIN, dev);
104 db.users().insertProjectPermissionOnGroup(group2, UserRole.ADMIN, view);
108 String result = newRequest().execute().outputAsString();
111 .ignoreFields("permissions")
112 .isSimilarTo(getClass().getResource("search_project_permissions-example.json"));
116 public void empty_result() throws Exception {
117 String result = newRequest().execute().outputAsString();
120 .ignoreFields("permissions")
121 .isSimilarTo(getClass().getResource("SearchProjectPermissionsActionTest/empty.json"));
125 public void search_project_permissions_with_project_permission() throws Exception {
126 userSession.login().addProjectUuidPermissions(UserRole.ADMIN, "project-uuid");
127 db.components().insertComponent(newProjectDto("project-uuid"));
129 String result = newRequest()
130 .setParam(PARAM_PROJECT_ID, "project-uuid")
131 .execute().outputAsString();
133 assertThat(result).contains("project-uuid");
137 public void has_projects_ordered_by_name() throws Exception {
138 for (int i = 9; i >= 1; i--) {
139 db.components().insertComponent(newProjectDto()
140 .setName("project-name-" + i));
143 String result = newRequest()
145 .setParam(PAGE_SIZE, "3")
146 .execute().outputAsString();
149 .contains("project-name-1", "project-name-2", "project-name-3")
150 .doesNotContain("project-name-4");
154 public void search_by_query_on_name() throws Exception {
155 componentDb.insertProjectAndSnapshot(newProjectDto().setName("project-name"));
156 componentDb.insertProjectAndSnapshot(newProjectDto().setName("another-name"));
157 componentDb.indexAllComponents();
159 String result = newRequest()
160 .setParam(TEXT_QUERY, "project")
161 .execute().outputAsString();
163 assertThat(result).contains("project-name")
164 .doesNotContain("another-name");
168 public void search_by_query_on_key_must_match_exactly() throws Exception {
169 componentDb.insertProjectAndSnapshot(newProjectDto().setKey("project-key"));
170 componentDb.insertProjectAndSnapshot(newProjectDto().setKey("another-key"));
171 componentDb.indexAllComponents();
173 String result = newRequest()
174 .setParam(TEXT_QUERY, "project-key")
178 assertThat(result).contains("project-key")
179 .doesNotContain("another-key");
183 public void handle_more_than_1000_projects() throws Exception {
184 for (int i = 1; i <= 1001; i++) {
185 componentDb.insertProjectAndSnapshot(newProjectDto("project-uuid-" + i));
187 componentDb.indexAllComponents();
189 String result = newRequest()
190 .setParam(TEXT_QUERY, "project")
191 .setParam(PAGE_SIZE, "1001")
195 assertThat(result).contains("project-uuid-1", "project-uuid-999", "project-uuid-1001");
199 public void filter_by_qualifier() throws Exception {
200 db.components().insertComponent(newView("view-uuid"));
201 db.components().insertComponent(newDeveloper("developer-name"));
202 db.components().insertComponent(newProjectDto("project-uuid"));
204 byte[] wsResponse = newRequest()
205 .setMediaType(MediaTypes.PROTOBUF)
206 .setParam(PARAM_QUALIFIER, Qualifiers.PROJECT)
209 WsPermissions.SearchProjectPermissionsWsResponse result = WsPermissions.SearchProjectPermissionsWsResponse.parseFrom(wsResponse);
211 assertThat(result.getProjectsList())
213 .contains("project-uuid")
214 .doesNotContain("view-uuid")
215 .doesNotContain("developer-name");
219 public void fail_if_not_logged_in() throws Exception {
220 userSession.anonymous();
222 expectedException.expect(UnauthorizedException.class);
224 newRequest().execute();
228 public void fail_if_not_admin() throws Exception {
231 expectedException.expect(ForbiddenException.class);
233 newRequest().execute();
237 public void display_all_project_permissions() throws Exception {
238 String result = newRequest().execute().outputAsString();
241 .ignoreFields("permissions")
242 .isSimilarTo(getClass().getResource("SearchProjectPermissionsActionTest/display_all_project_permissions.json"));
245 private ComponentDto insertView() {
246 return db.components().insertComponent(newView()
247 .setUuid("752d8bfd-420c-4a83-a4e5-8ab19b13c8fc")
252 private ComponentDto insertProjectInView(ComponentDto project, ComponentDto view) {
253 return db.components().insertComponent(newProjectCopy("project-in-view-uuid", project, view));
256 private ComponentDto insertDeveloper() {
257 return db.components().insertComponent(newDeveloper("Simon Brandhof")
258 .setUuid("4e607bf9-7ed0-484a-946d-d58ba7dab2fb")
259 .setKey("simon-brandhof"));
262 private ComponentDto insertClang() {
263 return db.components().insertComponent(newProjectDto("project-uuid-2")
266 .setUuid("ce4c03d6-430f-40a9-b777-ad877c00aa4d"));
269 private ComponentDto insertJdk7() {
270 return db.components().insertComponent(newProjectDto("project-uuid-1")
272 .setKey("net.java.openjdk:jdk7")
273 .setUuid("0bd7b1e7-91d6-439e-a607-4a3a9aad3c6a"));
276 private WsTester.TestRequest newRequest() {
277 return wsTester.newPostRequest(CONTROLLER, "search_project_permissions");