]> source.dussan.org Git - sonarqube.git/blob
e7aba7949a562cefe33ce047b188ca95d02c9237
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2021 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.index;
21
22 import java.util.ArrayList;
23 import java.util.Collection;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.function.Function;
27 import org.assertj.core.api.Assertions;
28 import org.junit.Before;
29 import org.junit.Rule;
30 import org.junit.Test;
31 import org.sonar.api.utils.System2;
32 import org.sonar.core.util.Uuids;
33 import org.sonar.core.util.stream.MoreCollectors;
34 import org.sonar.db.DbClient;
35 import org.sonar.db.DbSession;
36 import org.sonar.db.DbTester;
37 import org.sonar.db.component.ComponentDbTester;
38 import org.sonar.db.component.ComponentDto;
39 import org.sonar.db.permission.GroupPermissionDto;
40 import org.sonar.db.user.GroupDto;
41 import org.sonar.db.user.UserDbTester;
42 import org.sonar.db.user.UserDto;
43
44 import static java.util.Arrays.asList;
45 import static java.util.Collections.singletonList;
46 import static org.assertj.core.api.Assertions.assertThat;
47 import static org.sonar.api.resources.Qualifiers.APP;
48 import static org.sonar.api.resources.Qualifiers.PROJECT;
49 import static org.sonar.api.resources.Qualifiers.VIEW;
50 import static org.sonar.api.web.UserRole.ADMIN;
51 import static org.sonar.api.web.UserRole.USER;
52
53 public class PermissionIndexerDaoTest {
54
55   @Rule
56   public DbTester dbTester = DbTester.create(System2.INSTANCE);
57
58   private final DbClient dbClient = dbTester.getDbClient();
59   private final DbSession dbSession = dbTester.getSession();
60   private final ComponentDbTester componentDbTester = new ComponentDbTester(dbTester);
61   private final UserDbTester userDbTester = new UserDbTester(dbTester);
62
63   private ComponentDto publicProject;
64   private ComponentDto privateProject1;
65   private ComponentDto privateProject2;
66   private ComponentDto view1;
67   private ComponentDto view2;
68   private ComponentDto application;
69   private UserDto user1;
70   private UserDto user2;
71   private GroupDto group;
72
73   private final PermissionIndexerDao underTest = new PermissionIndexerDao();
74
75   @Before
76   public void setUp() {
77     publicProject = componentDbTester.insertPublicProject();
78     privateProject1 = componentDbTester.insertPrivateProject();
79     privateProject2 = componentDbTester.insertPrivateProject();
80     view1 = componentDbTester.insertPublicPortfolio();
81     view2 = componentDbTester.insertPublicPortfolio();
82     application = componentDbTester.insertPublicApplication();
83     user1 = userDbTester.insertUser();
84     user2 = userDbTester.insertUser();
85     group = userDbTester.insertGroup();
86   }
87
88   @Test
89   public void select_all() {
90     insertTestDataForProjectsAndViews();
91
92     Collection<IndexPermissions> dtos = underTest.selectAll(dbClient, dbSession);
93     Assertions.assertThat(dtos).hasSize(6);
94
95     IndexPermissions publicProjectAuthorization = getByProjectUuid(publicProject.uuid(), dtos);
96     isPublic(publicProjectAuthorization, PROJECT);
97
98     IndexPermissions view1Authorization = getByProjectUuid(view1.uuid(), dtos);
99     isPublic(view1Authorization, VIEW);
100
101     IndexPermissions applicationAuthorization = getByProjectUuid(application.uuid(), dtos);
102     isPublic(applicationAuthorization, APP);
103
104     IndexPermissions privateProject1Authorization = getByProjectUuid(privateProject1.uuid(), dtos);
105     assertThat(privateProject1Authorization.getGroupUuids()).containsOnly(group.getUuid());
106     assertThat(privateProject1Authorization.isAllowAnyone()).isFalse();
107     assertThat(privateProject1Authorization.getUserUuids()).containsOnly(user1.getUuid(), user2.getUuid());
108     assertThat(privateProject1Authorization.getQualifier()).isEqualTo(PROJECT);
109
110     IndexPermissions privateProject2Authorization = getByProjectUuid(privateProject2.uuid(), dtos);
111     assertThat(privateProject2Authorization.getGroupUuids()).isEmpty();
112     assertThat(privateProject2Authorization.isAllowAnyone()).isFalse();
113     assertThat(privateProject2Authorization.getUserUuids()).containsOnly(user1.getUuid());
114     assertThat(privateProject2Authorization.getQualifier()).isEqualTo(PROJECT);
115
116     IndexPermissions view2Authorization = getByProjectUuid(view2.uuid(), dtos);
117     isPublic(view2Authorization, VIEW);
118   }
119
120   @Test
121   public void selectByUuids() {
122     insertTestDataForProjectsAndViews();
123
124     Map<String, IndexPermissions> dtos = underTest
125       .selectByUuids(dbClient, dbSession, asList(publicProject.uuid(), privateProject1.uuid(), privateProject2.uuid(), view1.uuid(), view2.uuid(), application.uuid()))
126       .stream()
127       .collect(MoreCollectors.uniqueIndex(IndexPermissions::getProjectUuid, Function.identity()));
128     Assertions.assertThat(dtos).hasSize(6);
129
130     IndexPermissions publicProjectAuthorization = dtos.get(publicProject.uuid());
131     isPublic(publicProjectAuthorization, PROJECT);
132
133     IndexPermissions view1Authorization = dtos.get(view1.uuid());
134     isPublic(view1Authorization, VIEW);
135
136     IndexPermissions applicationAuthorization = dtos.get(application.uuid());
137     isPublic(applicationAuthorization, APP);
138
139     IndexPermissions privateProject1Authorization = dtos.get(privateProject1.uuid());
140     assertThat(privateProject1Authorization.getGroupUuids()).containsOnly(group.getUuid());
141     assertThat(privateProject1Authorization.isAllowAnyone()).isFalse();
142     assertThat(privateProject1Authorization.getUserUuids()).containsOnly(user1.getUuid(), user2.getUuid());
143     assertThat(privateProject1Authorization.getQualifier()).isEqualTo(PROJECT);
144
145     IndexPermissions privateProject2Authorization = dtos.get(privateProject2.uuid());
146     assertThat(privateProject2Authorization.getGroupUuids()).isEmpty();
147     assertThat(privateProject2Authorization.isAllowAnyone()).isFalse();
148     assertThat(privateProject2Authorization.getUserUuids()).containsOnly(user1.getUuid());
149     assertThat(privateProject2Authorization.getQualifier()).isEqualTo(PROJECT);
150
151     IndexPermissions view2Authorization = dtos.get(view2.uuid());
152     isPublic(view2Authorization, VIEW);
153   }
154
155   @Test
156   public void selectByUuids_returns_empty_list_when_project_does_not_exist() {
157     insertTestDataForProjectsAndViews();
158
159     List<IndexPermissions> dtos = underTest.selectByUuids(dbClient, dbSession, singletonList("missing"));
160     Assertions.assertThat(dtos).isEmpty();
161   }
162
163   @Test
164   public void select_by_projects_with_high_number_of_projects() {
165     List<String> projectUuids = new ArrayList<>();
166     for (int i = 0; i < 3500; i++) {
167       ComponentDto project = dbTester.components().insertPrivateProject(Integer.toString(i));
168       projectUuids.add(project.uuid());
169       GroupPermissionDto dto = new GroupPermissionDto()
170         .setUuid(Uuids.createFast())
171         .setGroupUuid(group.getUuid())
172         .setGroupName(group.getName())
173         .setRole(USER)
174         .setComponentUuid(project.uuid())
175         .setComponentName(project.name());
176       dbClient.groupPermissionDao().insert(dbSession, dto, project);
177     }
178     dbSession.commit();
179
180     assertThat(underTest.selectByUuids(dbClient, dbSession, projectUuids))
181       .hasSize(3500)
182       .extracting(IndexPermissions::getProjectUuid)
183       .containsAll(projectUuids);
184   }
185
186   @Test
187   public void return_private_project_without_any_permission_when_no_permission_in_DB() {
188     List<IndexPermissions> dtos = underTest.selectByUuids(dbClient, dbSession, singletonList(privateProject1.uuid()));
189
190     // no permissions
191     Assertions.assertThat(dtos).hasSize(1);
192     IndexPermissions dto = dtos.get(0);
193     assertThat(dto.getGroupUuids()).isEmpty();
194     assertThat(dto.getUserUuids()).isEmpty();
195     assertThat(dto.isAllowAnyone()).isFalse();
196     assertThat(dto.getProjectUuid()).isEqualTo(privateProject1.uuid());
197     assertThat(dto.getQualifier()).isEqualTo(privateProject1.qualifier());
198   }
199
200   @Test
201   public void return_public_project_with_only_AllowAnyone_true_when_no_permission_in_DB() {
202     List<IndexPermissions> dtos = underTest.selectByUuids(dbClient, dbSession, singletonList(publicProject.uuid()));
203
204     Assertions.assertThat(dtos).hasSize(1);
205     IndexPermissions dto = dtos.get(0);
206     assertThat(dto.getGroupUuids()).isEmpty();
207     assertThat(dto.getUserUuids()).isEmpty();
208     assertThat(dto.isAllowAnyone()).isTrue();
209     assertThat(dto.getProjectUuid()).isEqualTo(publicProject.uuid());
210     assertThat(dto.getQualifier()).isEqualTo(publicProject.qualifier());
211   }
212
213   @Test
214   public void return_private_project_with_AllowAnyone_false_and_user_id_when_user_is_granted_USER_permission_directly() {
215     dbTester.users().insertProjectPermissionOnUser(user1, USER, privateProject1);
216     List<IndexPermissions> dtos = underTest.selectByUuids(dbClient, dbSession, singletonList(privateProject1.uuid()));
217
218     Assertions.assertThat(dtos).hasSize(1);
219     IndexPermissions dto = dtos.get(0);
220     assertThat(dto.getGroupUuids()).isEmpty();
221     assertThat(dto.getUserUuids()).containsOnly(user1.getUuid());
222     assertThat(dto.isAllowAnyone()).isFalse();
223     assertThat(dto.getProjectUuid()).isEqualTo(privateProject1.uuid());
224     assertThat(dto.getQualifier()).isEqualTo(privateProject1.qualifier());
225   }
226
227   @Test
228   public void return_private_project_with_AllowAnyone_false_and_group_id_but_not_user_id_when_user_is_granted_USER_permission_through_group() {
229     dbTester.users().insertMember(group, user1);
230     dbTester.users().insertProjectPermissionOnGroup(group, USER, privateProject1);
231     List<IndexPermissions> dtos = underTest.selectByUuids(dbClient, dbSession, singletonList(privateProject1.uuid()));
232
233     Assertions.assertThat(dtos).hasSize(1);
234     IndexPermissions dto = dtos.get(0);
235     assertThat(dto.getGroupUuids()).containsOnly(group.getUuid());
236     assertThat(dto.getUserUuids()).isEmpty();
237     assertThat(dto.isAllowAnyone()).isFalse();
238     assertThat(dto.getProjectUuid()).isEqualTo(privateProject1.uuid());
239     assertThat(dto.getQualifier()).isEqualTo(privateProject1.qualifier());
240   }
241
242   private void isPublic(IndexPermissions view1Authorization, String qualifier) {
243     assertThat(view1Authorization.getGroupUuids()).isEmpty();
244     assertThat(view1Authorization.isAllowAnyone()).isTrue();
245     assertThat(view1Authorization.getUserUuids()).isEmpty();
246     assertThat(view1Authorization.getQualifier()).isEqualTo(qualifier);
247   }
248
249   private static IndexPermissions getByProjectUuid(String projectUuid, Collection<IndexPermissions> dtos) {
250     return dtos.stream().filter(dto -> dto.getProjectUuid().equals(projectUuid)).findFirst().orElseThrow(IllegalArgumentException::new);
251   }
252
253   private void insertTestDataForProjectsAndViews() {
254     // user1 has USER access on both private projects
255     userDbTester.insertProjectPermissionOnUser(user1, ADMIN, publicProject);
256     userDbTester.insertProjectPermissionOnUser(user1, USER, privateProject1);
257     userDbTester.insertProjectPermissionOnUser(user1, USER, privateProject2);
258     userDbTester.insertProjectPermissionOnUser(user1, ADMIN, view1);
259     userDbTester.insertProjectPermissionOnUser(user1, ADMIN, application);
260
261     // user2 has USER access on privateProject1 only
262     userDbTester.insertProjectPermissionOnUser(user2, USER, privateProject1);
263     userDbTester.insertProjectPermissionOnUser(user2, ADMIN, privateProject2);
264
265     // group1 has USER access on privateProject1 only
266     userDbTester.insertProjectPermissionOnGroup(group, USER, privateProject1);
267     userDbTester.insertProjectPermissionOnGroup(group, ADMIN, privateProject1);
268     userDbTester.insertProjectPermissionOnGroup(group, ADMIN, view1);
269     userDbTester.insertProjectPermissionOnGroup(group, ADMIN, application);
270   }
271 }