3 * Copyright (C) 2009-2017 SonarSource SA
4 * mailto:info 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.
21 package org.sonar.server.platform.db.migration.version.v64;
23 import com.google.common.collect.ImmutableMap;
24 import java.sql.SQLException;
25 import java.util.List;
27 import java.util.Optional;
28 import javax.annotation.Nullable;
29 import org.apache.commons.lang.RandomStringUtils;
30 import org.junit.Rule;
31 import org.junit.Test;
32 import org.junit.rules.ExpectedException;
33 import org.sonar.core.util.stream.MoreCollectors;
34 import org.sonar.db.CoreDbTester;
35 import org.sonar.server.platform.db.migration.version.v63.DefaultOrganizationUuidProviderImpl;
37 import static java.lang.String.format;
38 import static org.apache.commons.lang.math.RandomUtils.nextLong;
39 import static org.assertj.core.api.Assertions.assertThat;
41 public class PopulateOrganizationMembersTableTest {
43 private static final String TABLE = "organization_members";
45 private static final String DEFAULT_ORGANIZATION_UUID = "def org uuid";
47 private static final String PERMISSION_PROVISIONING = "provisioning";
48 private static final String PERMISSION_ADMIN = "admin";
49 private static final String PERMISSION_BROWSE = "user";
50 private static final String PERMISSION_CODEVIEWER = "codeviewer";
52 private static final String ORG1_UUID = "ORG1_UUID";
53 private static final String ORG2_UUID = "ORG2_UUID";
55 private static final String USER1_LOGIN = "USER1";
56 private static final String USER2_LOGIN = "USER2";
57 private static final String USER3_LOGIN = "USER3";
60 public ExpectedException expectedException = ExpectedException.none();
63 public CoreDbTester db = CoreDbTester.createForSchema(PopulateOrganizationMembersTableTest.class, "initial.sql");
65 private PopulateOrganizationMembersTable underTest = new PopulateOrganizationMembersTable(db.database(), new DefaultOrganizationUuidProviderImpl());
68 public void fails_with_ISE_when_no_default_organization_is_set() throws SQLException {
69 expectedException.expect(IllegalStateException.class);
70 expectedException.expectMessage("Default organization uuid is missing");
76 public void fails_with_ISE_when_default_organization_does_not_exist_in_table_ORGANIZATIONS() throws SQLException {
77 setDefaultOrganizationProperty("blabla");
79 expectedException.expect(IllegalStateException.class);
80 expectedException.expectMessage("Default organization with uuid 'blabla' does not exist in table ORGANIZATIONS");
86 public void execute_has_no_effect_when_table_is_empty() throws SQLException {
87 setupDefaultOrganization();
93 public void execute_is_reentrant_when_table_is_empty() throws SQLException {
94 setupDefaultOrganization();
101 public void migrate_user_having_direct_global_permissions() throws Exception {
102 setupDefaultOrganization();
103 insertOrganization(ORG1_UUID);
104 insertOrganization(ORG2_UUID);
105 int userId = insertUser(USER1_LOGIN);
106 insertUserRole(userId, PERMISSION_PROVISIONING, ORG1_UUID, null);
107 insertUserRole(userId, PERMISSION_ADMIN, ORG1_UUID, null);
108 insertUserRole(userId, PERMISSION_ADMIN, ORG2_UUID, null);
112 verifyUserMembership(userId, ORG1_UUID, ORG2_UUID, DEFAULT_ORGANIZATION_UUID);
116 public void migrate_user_having_direct_project_permissions() throws Exception {
117 setupDefaultOrganization();
118 insertOrganization(ORG1_UUID);
119 insertOrganization(ORG2_UUID);
120 int userId = insertUser(USER1_LOGIN);
121 insertUserRole(userId, PERMISSION_BROWSE, ORG1_UUID, 1);
122 insertUserRole(userId, PERMISSION_CODEVIEWER, ORG1_UUID, 1);
123 insertUserRole(userId, PERMISSION_ADMIN, ORG2_UUID, 2);
127 verifyUserMembership(userId, ORG1_UUID, ORG2_UUID, DEFAULT_ORGANIZATION_UUID);
131 public void migrate_user_having_global_permissions_from_group() throws Exception {
132 setupDefaultOrganization();
133 insertOrganization(ORG1_UUID);
134 insertOrganization(ORG2_UUID);
135 int userId = insertUser(USER1_LOGIN);
136 int group1Id = insertNewGroup(ORG1_UUID);
137 int group2Id = insertNewGroup(ORG2_UUID);
138 insertUserGroup(userId, group1Id);
139 insertUserGroup(userId, group2Id);
143 verifyUserMembership(userId, ORG1_UUID, ORG2_UUID, DEFAULT_ORGANIZATION_UUID);
147 public void user_without_any_permission_should_be_member_of_default_organization() throws Exception {
148 setupDefaultOrganization();
149 int userId = insertUser(USER1_LOGIN);
153 verifyUserMembership(userId, DEFAULT_ORGANIZATION_UUID, DEFAULT_ORGANIZATION_UUID);
157 public void migrate_users_having_any_kind_of_permission() throws Exception {
158 setupDefaultOrganization();
159 insertOrganization(ORG1_UUID);
160 insertOrganization(ORG2_UUID);
161 int user1 = insertUser(USER1_LOGIN);
162 int user2 = insertUser(USER2_LOGIN);
163 int user3 = insertUser(USER3_LOGIN);
164 int groupId = insertNewGroup(ORG1_UUID);
165 insertUserGroup(user2, groupId);
166 insertUserRole(user1, PERMISSION_PROVISIONING, ORG1_UUID, null);
167 insertUserRole(user1, PERMISSION_BROWSE, ORG2_UUID, 1);
171 verifyUserMembership(user1, ORG1_UUID, ORG2_UUID, DEFAULT_ORGANIZATION_UUID);
172 verifyUserMembership(user2, ORG1_UUID, DEFAULT_ORGANIZATION_UUID);
173 verifyUserMembership(user3, DEFAULT_ORGANIZATION_UUID);
177 public void migrate_missing_membership_on_direct_permission() throws Exception {
178 setupDefaultOrganization();
179 insertOrganization(ORG1_UUID);
180 insertOrganization(ORG2_UUID);
181 int userId = insertUser(USER1_LOGIN);
182 insertUserRole(userId, PERMISSION_ADMIN, ORG1_UUID, null);
183 insertUserRole(userId, PERMISSION_PROVISIONING, ORG2_UUID, null);
184 // Membership on organization 1 already exists, migration will add membership on organization 2 and default organization
185 insertOrganizationMember(userId, ORG1_UUID);
189 verifyUserMembership(userId, ORG1_UUID, ORG2_UUID, DEFAULT_ORGANIZATION_UUID);
193 public void migrate_missing_membership_on_group_permission() throws Exception {
194 setupDefaultOrganization();
195 insertOrganization(ORG1_UUID);
196 insertOrganization(ORG2_UUID);
197 int userId = insertUser(USER1_LOGIN);
198 int group1Id = insertNewGroup(ORG1_UUID);
199 int group2Id = insertNewGroup(ORG2_UUID);
200 insertUserGroup(userId, group1Id);
201 insertUserGroup(userId, group2Id);
202 // Membership on organization 1 already exists, migration will add membership on organization 2 and default organization
203 insertOrganizationMember(userId, ORG1_UUID);
207 verifyUserMembership(userId, ORG1_UUID, ORG2_UUID, DEFAULT_ORGANIZATION_UUID);
211 public void migrate_active_users_to_default_organization() throws Exception {
212 setupDefaultOrganization();
213 int user1Id = insertUser(USER1_LOGIN, false);
214 int user2Id = insertUser(USER2_LOGIN, false);
215 int user3Id = insertUser(USER3_LOGIN, false);
216 int group1Id = insertNewGroup(ORG1_UUID);
217 insertUserRole(user1Id, PERMISSION_ADMIN, ORG1_UUID, null);
218 insertUserGroup(user2Id, group1Id);
222 verifyUserMembership(user1Id);
223 verifyUserMembership(user2Id);
224 verifyUserMembership(user3Id);
228 public void ignore_already_associated_users() throws Exception {
229 setupDefaultOrganization();
230 insertOrganization(ORG1_UUID);
231 int userId = insertUser(USER1_LOGIN);
232 insertUserRole(userId, PERMISSION_PROVISIONING, ORG1_UUID, null);
233 // User is already associated to organization 1 and to default organization, it should not fail
234 insertOrganizationMember(userId, ORG1_UUID);
235 insertOrganizationMember(userId, DEFAULT_ORGANIZATION_UUID);
239 verifyUserMembership(userId, ORG1_UUID, DEFAULT_ORGANIZATION_UUID);
243 public void migration_is_reentrant() throws Exception {
244 setupDefaultOrganization();
245 insertOrganization(ORG1_UUID);
246 int userId = insertUser(USER1_LOGIN);
247 insertUserRole(userId, PERMISSION_PROVISIONING, ORG1_UUID, null);
248 verifyUserMembership(userId);
251 verifyUserMembership(userId, ORG1_UUID, DEFAULT_ORGANIZATION_UUID);
254 verifyUserMembership(userId, ORG1_UUID, DEFAULT_ORGANIZATION_UUID);
257 private void insertOrganizationMember(int userId, String organizationUuid) {
258 db.executeInsert(TABLE, "USER_ID", userId, "ORGANIZATION_UUID", organizationUuid);
261 private void insertOrganization(String uuid) {
262 db.executeInsert("ORGANIZATIONS", "UUID", uuid, "KEE", uuid, "NAME", uuid, "GUARDED", false, "CREATED_AT", nextLong(), "UPDATED_AT", nextLong());
265 private int insertUser(String login) {
266 return insertUser(login, true);
269 private int insertUser(String login, boolean enabled) {
270 db.executeInsert("USERS", "LOGIN", login, "NAME", login, "ACTIVE", enabled, "IS_ROOT", false);
271 return ((Long) db.selectFirst(format("select ID from users where login='%s'", login)).get("ID")).intValue();
274 private void insertUserRole(int userId, String permission, String organizationUuid, @Nullable Integer componentId) {
275 ImmutableMap.Builder<String, Object> builder = ImmutableMap.<String, Object>builder()
276 .putAll(ImmutableMap.of("USER_ID", userId, "ROLE", permission, "ORGANIZATION_UUID", organizationUuid));
277 Optional.ofNullable(componentId).ifPresent(id -> builder.put("RESOURCE_ID", id));
278 db.executeInsert("USER_ROLES", builder.build());
281 private int insertNewGroup(String organizationUuid) {
282 String groupName = RandomStringUtils.random(10);
283 db.executeInsert("GROUPS", "NAME", groupName, "ORGANIZATION_UUID", organizationUuid);
284 return ((Long) db.selectFirst(format("select ID from groups where name='%s' and organization_uuid='%s'", groupName, organizationUuid)).get("ID")).intValue();
287 private void insertUserGroup(int userId, int groupId) {
288 db.executeInsert("GROUPS_USERS", "USER_ID", userId, "GROUP_ID", groupId);
291 private void setupDefaultOrganization() {
292 setDefaultOrganizationProperty(DEFAULT_ORGANIZATION_UUID);
293 insertOrganization(DEFAULT_ORGANIZATION_UUID);
296 private void setDefaultOrganizationProperty(String defaultOrganizationUuid) {
298 "INTERNAL_PROPERTIES",
299 "KEE", "organization.default",
301 "TEXT_VALUE", defaultOrganizationUuid);
304 private void verifyUserMembership(int userId, String... organizationUuids) {
305 List<Map<String, Object>> rows = db.select(format("SELECT ORGANIZATION_UUID FROM " + TABLE + " WHERE USER_ID = %s", userId));
306 List<String> userOrganizationUuids = rows.stream()
307 .map(values -> (String) values.get("ORGANIZATION_UUID"))
308 .collect(MoreCollectors.toList());
309 assertThat(userOrganizationUuids).containsOnly(organizationUuids);