]> source.dussan.org Git - sonarqube.git/blob
58a204505066a80a84268db85c025e3e91daa6f1
[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.common.github.permissions;
21
22 import java.util.List;
23 import java.util.Map;
24 import java.util.Set;
25 import org.junit.Rule;
26 import org.junit.Test;
27 import org.sonar.core.util.SequenceUuidFactory;
28 import org.sonar.core.util.UuidFactory;
29 import org.sonar.db.DbSession;
30 import org.sonar.db.DbTester;
31 import org.sonar.db.audit.AuditPersister;
32 import org.sonar.db.provisioning.GithubPermissionsMappingDao;
33 import org.sonar.db.provisioning.GithubPermissionsMappingDto;
34 import org.sonar.server.common.permission.Operation;
35 import org.sonar.server.exceptions.NotFoundException;
36
37 import static org.assertj.core.api.Assertions.assertThat;
38 import static org.assertj.core.api.Assertions.assertThatThrownBy;
39 import static org.mockito.Mockito.mock;
40 import static org.sonar.server.common.github.permissions.GithubPermissionsMappingService.ADMIN_GITHUB_ROLE;
41 import static org.sonar.server.common.github.permissions.GithubPermissionsMappingService.MAINTAIN_GITHUB_ROLE;
42 import static org.sonar.server.common.github.permissions.GithubPermissionsMappingService.READ_GITHUB_ROLE;
43 import static org.sonar.server.common.github.permissions.GithubPermissionsMappingService.TRIAGE_GITHUB_ROLE;
44 import static org.sonar.server.common.github.permissions.GithubPermissionsMappingService.WRITE_GITHUB_ROLE;
45
46 public class GithubPermissionsMappingServiceIT {
47
48   private static final String CUSTOM_ROLE_NAME = "customRole1";
49
50   private static final SonarqubePermissions NO_SQ_PERMISSIONS = new SonarqubePermissions(false, false, false, false, false, false);
51
52   @Rule
53   public DbTester db = DbTester.create();
54   private final DbSession dbSession = db.getSession();
55
56   private final AuditPersister auditPersister = mock();
57   private final GithubPermissionsMappingDao githubPermissionsMappingDao = new GithubPermissionsMappingDao(auditPersister);
58
59   private final UuidFactory uuidFactory = new SequenceUuidFactory();
60
61   private final GithubPermissionsMappingService underTest = new GithubPermissionsMappingService(db.getDbClient(), githubPermissionsMappingDao, uuidFactory);
62
63   @Test
64   public void getPermissionsMapping_whenMappingNotDefined_returnMappingEntirelyFalse() {
65     List<GithubPermissionsMapping> actualPermissionsMapping = underTest.getPermissionsMapping();
66
67     List<GithubPermissionsMapping> expectedPermissionsMapping = List.of(
68       new GithubPermissionsMapping(READ_GITHUB_ROLE, true, NO_SQ_PERMISSIONS),
69       new GithubPermissionsMapping(TRIAGE_GITHUB_ROLE, true, NO_SQ_PERMISSIONS),
70       new GithubPermissionsMapping(WRITE_GITHUB_ROLE, true, NO_SQ_PERMISSIONS),
71       new GithubPermissionsMapping(MAINTAIN_GITHUB_ROLE, true, NO_SQ_PERMISSIONS),
72       new GithubPermissionsMapping(ADMIN_GITHUB_ROLE, true, NO_SQ_PERMISSIONS));
73
74     assertThat(actualPermissionsMapping).containsAll(expectedPermissionsMapping);
75   }
76
77   @Test
78   public void getPermissionsMapping_whenMappingDefined_returnMapping() {
79     Map<String, Set<String>> githubRolesToSqPermissions = Map.of(
80       CUSTOM_ROLE_NAME, Set.of("user"),
81       READ_GITHUB_ROLE, Set.of("user", "codeviewer"),
82       WRITE_GITHUB_ROLE, Set.of("user", "codeviewer", "issueadmin", "securityhotspotadmin", "admin", "scan"));
83     persistGithubPermissionsMapping(githubRolesToSqPermissions);
84
85     List<GithubPermissionsMapping> actualPermissionsMapping = underTest.getPermissionsMapping();
86
87     List<GithubPermissionsMapping> expectedPermissionsMapping = List.of(
88       new GithubPermissionsMapping(CUSTOM_ROLE_NAME, false, new SonarqubePermissions(true, false, false, false, false, false)),
89       new GithubPermissionsMapping(READ_GITHUB_ROLE, true, new SonarqubePermissions(true, true, false, false, false, false)),
90       new GithubPermissionsMapping(TRIAGE_GITHUB_ROLE, true, NO_SQ_PERMISSIONS),
91       new GithubPermissionsMapping(WRITE_GITHUB_ROLE, true, new SonarqubePermissions(true, true, true, true, true, true)),
92       new GithubPermissionsMapping(MAINTAIN_GITHUB_ROLE, true, NO_SQ_PERMISSIONS),
93       new GithubPermissionsMapping(ADMIN_GITHUB_ROLE, true, NO_SQ_PERMISSIONS));
94
95     assertThat(actualPermissionsMapping).containsAll(expectedPermissionsMapping);
96   }
97
98   private void persistGithubPermissionsMapping(Map<String, Set<String>> githubRolesToSonarqubePermissions) {
99     for (Map.Entry<String, Set<String>> githubRoleToSonarqubePermissions : githubRolesToSonarqubePermissions.entrySet()) {
100       String githubRole = githubRoleToSonarqubePermissions.getKey();
101       githubRoleToSonarqubePermissions.getValue()
102         .forEach(permission -> githubPermissionsMappingDao.insert(
103           dbSession,
104           new GithubPermissionsMappingDto("uuid_" + githubRole + "_" + permission, githubRole, permission)));
105     }
106     dbSession.commit();
107   }
108
109   @Test
110   public void updatePermissionsMappings_onBaseRole_shouldAddAndRemovePermissions() {
111     Map<String, Set<String>> githubRolesToSqPermissions = Map.of(READ_GITHUB_ROLE, Set.of("user", "codeviewer"));
112     persistGithubPermissionsMapping(githubRolesToSqPermissions);
113
114     PermissionMappingChange permToAdd1 = new PermissionMappingChange(READ_GITHUB_ROLE, "issueadmin", Operation.ADD);
115     PermissionMappingChange permToAdd2 = new PermissionMappingChange(READ_GITHUB_ROLE, "scan", Operation.ADD);
116     PermissionMappingChange permToRemove1 = new PermissionMappingChange(READ_GITHUB_ROLE, "user", Operation.REMOVE);
117     PermissionMappingChange permToRemove2 = new PermissionMappingChange(READ_GITHUB_ROLE, "codeviewer", Operation.REMOVE);
118
119     underTest.updatePermissionsMappings(Set.of(permToAdd1, permToAdd2, permToRemove1, permToRemove2));
120
121     GithubPermissionsMapping updatedPermissionsMapping = underTest.getPermissionsMappingForGithubRole(READ_GITHUB_ROLE);
122
123     SonarqubePermissions expectedSqPermissions = new SonarqubePermissions(false, false, true, false, false, true);
124     GithubPermissionsMapping expectedPermissionsMapping = new GithubPermissionsMapping(READ_GITHUB_ROLE, true, expectedSqPermissions);
125     assertThat(updatedPermissionsMapping).isEqualTo(expectedPermissionsMapping);
126   }
127
128   @Test
129   public void updatePermissionsMappings_onCustomRole_shouldAddAndRemovePermissions() {
130     Map<String, Set<String>> githubRolesToSqPermissions = Map.of(CUSTOM_ROLE_NAME, Set.of("user", "codeviewer"));
131     persistGithubPermissionsMapping(githubRolesToSqPermissions);
132
133     PermissionMappingChange permToAdd1 = new PermissionMappingChange(CUSTOM_ROLE_NAME, "issueadmin", Operation.ADD);
134     PermissionMappingChange permToRemove1 = new PermissionMappingChange(CUSTOM_ROLE_NAME, "user", Operation.REMOVE);
135
136     underTest.updatePermissionsMappings(Set.of(permToAdd1, permToRemove1));
137
138     GithubPermissionsMapping updatedPermissionsMapping = underTest.getPermissionsMappingForGithubRole(CUSTOM_ROLE_NAME);
139
140     SonarqubePermissions expectedSqPermissions = new SonarqubePermissions(false, true, true, false, false, false);
141     GithubPermissionsMapping expectedPermissionsMapping = new GithubPermissionsMapping(CUSTOM_ROLE_NAME, false, expectedSqPermissions);
142     assertThat(updatedPermissionsMapping).isEqualTo(expectedPermissionsMapping);
143   }
144
145   @Test
146   public void updatePermissionsMappings_whenRemovingNonExistingPermission_isNoOp() {
147     PermissionMappingChange permToRemove1 = new PermissionMappingChange(READ_GITHUB_ROLE, "user", Operation.REMOVE);
148
149     underTest.updatePermissionsMappings(Set.of(permToRemove1));
150
151     GithubPermissionsMapping updatedPermissionsMapping = underTest.getPermissionsMappingForGithubRole(READ_GITHUB_ROLE);
152
153     GithubPermissionsMapping expectedPermissionsMapping = new GithubPermissionsMapping(READ_GITHUB_ROLE, true, NO_SQ_PERMISSIONS);
154     assertThat(updatedPermissionsMapping).isEqualTo(expectedPermissionsMapping);
155   }
156
157   @Test
158   public void updatePermissionsMappings_whenAddingAlreadyExistingPermission_isNoOp() {
159     Map<String, Set<String>> githubRolesToSqPermissions = Map.of(READ_GITHUB_ROLE, Set.of("user", "codeviewer"));
160     persistGithubPermissionsMapping(githubRolesToSqPermissions);
161     PermissionMappingChange permToAdd1 = new PermissionMappingChange(READ_GITHUB_ROLE, "user", Operation.ADD);
162
163     underTest.updatePermissionsMappings(Set.of(permToAdd1));
164
165     GithubPermissionsMapping updatedPermissionsMapping = underTest.getPermissionsMappingForGithubRole(READ_GITHUB_ROLE);
166
167     SonarqubePermissions expectedSqPermissions = new SonarqubePermissions(true, true, false, false, false, false);
168     GithubPermissionsMapping expectedPermissionsMapping = new GithubPermissionsMapping(READ_GITHUB_ROLE, true, expectedSqPermissions);
169     assertThat(updatedPermissionsMapping).isEqualTo(expectedPermissionsMapping);
170   }
171
172   @Test
173   public void updatePermissionsMappings_handlesUpdatesForDifferentRoles() {
174     PermissionMappingChange permToAdd1 = new PermissionMappingChange(READ_GITHUB_ROLE, "user", Operation.ADD);
175     PermissionMappingChange permToAdd2 = new PermissionMappingChange(WRITE_GITHUB_ROLE, "user", Operation.ADD);
176
177     underTest.updatePermissionsMappings(Set.of(permToAdd1, permToAdd2));
178
179     SonarqubePermissions userOnlySqPermission = new SonarqubePermissions(true, false, false, false, false, false);
180
181     GithubPermissionsMapping updatedPermissionsMapping = underTest.getPermissionsMappingForGithubRole(READ_GITHUB_ROLE);
182     assertThat(updatedPermissionsMapping).isEqualTo(new GithubPermissionsMapping(READ_GITHUB_ROLE, true, userOnlySqPermission));
183
184     updatedPermissionsMapping = underTest.getPermissionsMappingForGithubRole(WRITE_GITHUB_ROLE);
185     assertThat(updatedPermissionsMapping).isEqualTo(new GithubPermissionsMapping(WRITE_GITHUB_ROLE, true, userOnlySqPermission));
186   }
187
188   @Test
189   public void getPermissionsMappingForGithubRole_onBaseRole_shouldReturnMappingOnlyForRole() {
190     Map<String, Set<String>> githubRolesToSqPermissions = Map.of(
191       READ_GITHUB_ROLE, Set.of("user", "codeviewer"),
192       WRITE_GITHUB_ROLE, Set.of("user", "codeviewer", "issueadmin", "securityhotspotadmin", "admin", "scan"));
193     persistGithubPermissionsMapping(githubRolesToSqPermissions);
194
195     GithubPermissionsMapping actualPermissionsMapping = underTest.getPermissionsMappingForGithubRole(READ_GITHUB_ROLE);
196
197     SonarqubePermissions expectedSqPermissions = new SonarqubePermissions(true, true, false, false, false, false);
198     GithubPermissionsMapping expectedPermissionsMapping = new GithubPermissionsMapping(READ_GITHUB_ROLE, true, expectedSqPermissions);
199
200     assertThat(actualPermissionsMapping).isEqualTo(expectedPermissionsMapping);
201   }
202
203   @Test
204   public void getPermissionsMappingForGithubRole_onCustomRole_shouldReturnMappingOnlyForRole() {
205     Map<String, Set<String>> githubRolesToSqPermissions = Map.of(
206       CUSTOM_ROLE_NAME, Set.of("admin"),
207       WRITE_GITHUB_ROLE, Set.of("user", "codeviewer", "issueadmin", "securityhotspotadmin", "admin", "scan"));
208     persistGithubPermissionsMapping(githubRolesToSqPermissions);
209
210     GithubPermissionsMapping actualPermissionsMapping = underTest.getPermissionsMappingForGithubRole(CUSTOM_ROLE_NAME);
211
212     SonarqubePermissions expectedSqPermissions = new SonarqubePermissions(false, false, false, false, true, false);
213     GithubPermissionsMapping expectedPermissionsMapping = new GithubPermissionsMapping(CUSTOM_ROLE_NAME, false, expectedSqPermissions);
214
215     assertThat(actualPermissionsMapping).isEqualTo(expectedPermissionsMapping);
216   }
217
218   @Test
219   public void deletePermissionMappings_whenTryingToDeleteForBaseRole_shouldThrow() {
220     assertThatThrownBy(() -> underTest.deletePermissionMappings(READ_GITHUB_ROLE))
221       .isInstanceOf(IllegalArgumentException.class)
222       .hasMessage("Deleting permission mapping for GitHub base role '" + READ_GITHUB_ROLE + "' is not allowed.");
223   }
224
225   @Test
226   public void deletePermissionMappings_whenNoMappingsExistForGithubRole_shouldThrow() {
227     assertThatThrownBy(() -> underTest.deletePermissionMappings(CUSTOM_ROLE_NAME))
228       .isInstanceOf(NotFoundException.class)
229       .hasMessage("Role '" + CUSTOM_ROLE_NAME + "' not found.");
230   }
231
232   @Test
233   public void deletePermissionMappings_whenTryingToDeleteForCustomRole_shouldDeleteMapping() {
234     Map<String, Set<String>> githubRolesToSqPermissions = Map.of(
235       READ_GITHUB_ROLE, Set.of("user", "codeviewer"),
236       WRITE_GITHUB_ROLE, Set.of("user", "codeviewer", "issueadmin", "securityhotspotadmin", "admin", "scan"),
237       CUSTOM_ROLE_NAME, Set.of("user", "codeviewer", "scan"),
238       "customRole2", Set.of("user", "codeviewer"));
239
240     persistGithubPermissionsMapping(githubRolesToSqPermissions);
241     underTest.deletePermissionMappings("customRole2");
242
243     List<GithubPermissionsMapping> allPermissionMappings = underTest.getPermissionsMapping();
244
245     assertThat(allPermissionMappings)
246       .containsExactlyInAnyOrder(
247         new GithubPermissionsMapping(READ_GITHUB_ROLE, true, new SonarqubePermissions(true, true, false, false, false, false)),
248         new GithubPermissionsMapping(WRITE_GITHUB_ROLE, true, new SonarqubePermissions(true, true, true, true, true, true)),
249         new GithubPermissionsMapping(TRIAGE_GITHUB_ROLE, true, NO_SQ_PERMISSIONS),
250         new GithubPermissionsMapping(MAINTAIN_GITHUB_ROLE, true, NO_SQ_PERMISSIONS),
251         new GithubPermissionsMapping(ADMIN_GITHUB_ROLE, true, NO_SQ_PERMISSIONS),
252         new GithubPermissionsMapping(CUSTOM_ROLE_NAME, false, new SonarqubePermissions(true, true, false, false, false, true)));
253   }
254
255 }