]> source.dussan.org Git - sonarqube.git/blob
81a8ff02d38e25b73242216056aa598824edb684
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2022 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.platform.db.migration.version.v00;
21
22 import java.sql.SQLException;
23 import java.util.Date;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Random;
27 import java.util.stream.Stream;
28 import org.junit.Before;
29 import org.junit.Rule;
30 import org.junit.Test;
31 import org.sonar.api.SonarRuntime;
32 import org.sonar.api.utils.System2;
33 import org.sonar.api.utils.Version;
34 import org.sonar.core.util.UuidFactory;
35 import org.sonar.core.util.UuidFactoryFast;
36 import org.sonar.core.util.stream.MoreCollectors;
37 import org.sonar.db.CoreDbTester;
38
39 import static org.assertj.core.api.Assertions.assertThat;
40 import static org.mockito.Mockito.mock;
41 import static org.mockito.Mockito.when;
42
43 public class PopulateInitialSchemaTest {
44
45   private static final long NOW = 1_500L;
46
47   private final Random random = new Random();
48   private final Version version = Version.create(1 + random.nextInt(10), 1 + random.nextInt(10), random.nextInt(10));
49   private final UuidFactory uuidFactory = UuidFactoryFast.getInstance();
50   private final System2 system2 = mock(System2.class);
51   private final SonarRuntime sonarRuntime = mock(SonarRuntime.class);
52
53   @Rule
54   public final CoreDbTester db = CoreDbTester.createForSchema(PopulateInitialSchemaTest.class, "v89.sql");
55
56   private final PopulateInitialSchema underTest = new PopulateInitialSchema(db.database(), system2, uuidFactory, sonarRuntime);
57
58   @Before
59   public void setUp() {
60     when(sonarRuntime.getApiVersion()).thenReturn(version);
61   }
62
63   @Test
64   public void migration_inserts_users_and_groups() throws SQLException {
65     when(system2.now()).thenReturn(NOW);
66
67     underTest.execute();
68
69     verifyAdminUser();
70     verifyGroup("sonar-users", "Any new users created will automatically join this group");
71     verifyGroup("sonar-administrators", "System administrators");
72     String qualityGateUuid = verifyQualityGate();
73     verifyInternalProperties();
74     verifyProperties(qualityGateUuid);
75     verifyRolesOfAdminsGroup();
76     verifyRolesOfUsersGroup();
77     verifyRolesOfAnyone();
78     verifyMembershipOfAdminUser();
79   }
80
81   private void verifyAdminUser() {
82     Map<String, Object> cols = db.selectFirst("select " +
83       "login as \"LOGIN\", " +
84       "name as \"NAME\", " +
85       "email as \"EMAIL\", " +
86       "external_id as \"EXTERNAL_ID\", " +
87       "external_login as \"EXTERNAL_LOGIN\", " +
88       "external_identity_provider as \"EXT_IDENT_PROVIDER\", " +
89       "user_local as \"USER_LOCAL\", " +
90       "crypted_password as \"CRYPTED_PASSWORD\", " +
91       "salt as \"SALT\", " +
92       "hash_method as \"HASH_METHOD\", " +
93       "is_root as \"IS_ROOT\", " +
94       "onboarded as \"ONBOARDED\", " +
95       "created_at as \"CREATED_AT\", " +
96       "updated_at as \"UPDATED_AT\", " +
97       "reset_password as \"RESET_PASSWORD\" " +
98       "from users where login='admin'");
99
100     assertThat(cols)
101       .containsEntry("LOGIN", "admin")
102       .containsEntry("NAME", "Administrator")
103       .containsEntry("EXTERNAL_ID", "admin")
104       .containsEntry("EXTERNAL_LOGIN", "admin")
105       .containsEntry("EXT_IDENT_PROVIDER", "sonarqube")
106       .containsEntry("USER_LOCAL", true)
107       .containsEntry("CRYPTED_PASSWORD", "$2a$12$uCkkXmhW5ThVK8mpBvnXOOJRLd64LJeHTeCkSuB3lfaR2N0AYBaSi")
108       .containsEntry("HASH_METHOD", "BCRYPT")
109       .containsEntry("IS_ROOT", false)
110       .containsEntry("ONBOARDED", true)
111       .containsEntry("CREATED_AT", NOW)
112       .containsEntry("RESET_PASSWORD", true)
113       .containsEntry("UPDATED_AT", NOW);
114
115     assertThat(cols.get("EMAIL")).isNull();
116     assertThat(cols.get("SALT")).isNull();
117   }
118
119   private void verifyGroup(String expectedName, String expectedDescription) {
120     List<Map<String, Object>> rows = db.select("select " +
121       "uuid as \"UUID\"," +
122       "name as \"name\", " +
123       "description as \"description\", " +
124       "created_at as \"CREATED_AT\", " +
125       "updated_at as \"UPDATED_AT\" " +
126       "from groups where name='" + expectedName + "'");
127     assertThat(rows).hasSize(1);
128
129     Map<String, Object> row = rows.get(0);
130     assertThat(row).containsEntry("name", expectedName);
131     assertThat(row).containsEntry("description", expectedDescription);
132     assertThat(((Date) row.get("CREATED_AT")).getTime()).isEqualTo(NOW);
133     assertThat(((Date) row.get("UPDATED_AT")).getTime()).isEqualTo(NOW);
134
135   }
136
137   private String verifyQualityGate() {
138     List<Map<String, Object>> rows = db.select("select " +
139       "uuid as \"UUID\", " +
140       "name as \"NAME\", " +
141       "is_built_in as \"BUILTIN\"," +
142       "created_at as \"CREATED_AT\", " +
143       "updated_at as \"UPDATED_AT\"" +
144       " from quality_gates");
145     assertThat(rows).hasSize(1);
146
147     Map<String, Object> row = rows.get(0);
148     assertThat(row).containsEntry("NAME", "Sonar way");
149     assertThat(row).containsEntry("BUILTIN", true);
150     assertThat(((Date) row.get("CREATED_AT")).getTime()).isEqualTo(NOW);
151     assertThat(((Date) row.get("UPDATED_AT")).getTime()).isEqualTo(NOW);
152     return (String) row.get("UUID");
153   }
154
155   private void verifyInternalProperties() {
156     List<Map<String, Object>> rows = db.select("select " +
157       "kee as \"KEE\", " +
158       "is_empty as \"EMPTY\", " +
159       "text_value as \"VAL\"," +
160       "created_at as \"CREATED_AT\" " +
161       " from internal_properties");
162     assertThat(rows).hasSize(2);
163
164     Map<String, Map<String, Object>> rowsByKey = rows.stream().collect(MoreCollectors.uniqueIndex(t -> (String) t.get("KEE")));
165     verifyInternalProperty(rowsByKey, "installation.date", String.valueOf(system2.now()));
166     verifyInternalProperty(rowsByKey, "installation.version", version.toString());
167   }
168
169   private static void verifyInternalProperty(Map<String, Map<String, Object>> rowsByKey, String key, String val) {
170     Map<String, Object> row = rowsByKey.get(key);
171     assertThat(row)
172       .containsEntry("KEE", key)
173       .containsEntry("EMPTY", false)
174       .containsEntry("VAL", val)
175       .containsEntry("CREATED_AT", NOW);
176   }
177
178   private void verifyProperties(String qualityGateUuid) {
179     List<Map<String, Object>> rows = db.select("select " +
180       "prop_key as \"PROP_KEY\", " +
181       "is_empty as \"EMPTY\", " +
182       "text_value as \"VAL\"," +
183       "created_at as \"CREATED_AT\" " +
184       " from properties");
185     assertThat(rows).hasSize(3);
186
187     Map<String, Map<String, Object>> rowsByKey = rows.stream().collect(MoreCollectors.uniqueIndex(t -> (String) t.get("PROP_KEY")));
188     verifyProperty(rowsByKey, "sonar.forceAuthentication", "true");
189     verifyProperty(rowsByKey, "projects.default.visibility", "public");
190     verifyProperty(rowsByKey, "qualitygate.default", qualityGateUuid);
191   }
192
193   private static void verifyProperty(Map<String, Map<String, Object>> rowsByKey, String key, String val) {
194     Map<String, Object> row = rowsByKey.get(key);
195     assertThat(row)
196       .containsEntry("PROP_KEY", key)
197       .containsEntry("EMPTY", false)
198       .containsEntry("VAL", val)
199       .containsEntry("CREATED_AT", NOW);
200   }
201
202   private void verifyRolesOfAdminsGroup() {
203     assertThat(selectRoles("sonar-administrators")).containsOnly("admin", "profileadmin", "gateadmin", "provisioning", "applicationcreator", "portfoliocreator");
204   }
205
206   private void verifyRolesOfUsersGroup() {
207     assertThat(selectRoles("sonar-users")).isEmpty();
208   }
209
210   private void verifyRolesOfAnyone() {
211     List<Map<String, Object>> rows = db.select("select gr.role as \"role\" " +
212       "from group_roles gr where gr.group_uuid is null");
213     Stream<String> roles = rows.stream()
214       .map(row -> (String) row.get("role"));
215     assertThat(roles).containsOnly("provisioning", "scan");
216   }
217
218   private Stream<String> selectRoles(String groupName) {
219     List<Map<String, Object>> rows = db.select("select gr.role as \"role\" " +
220       "from group_roles gr " +
221       "inner join groups g on gr.group_uuid = g.uuid " +
222       "where g.name='" + groupName + "'");
223     return rows.stream()
224       .map(row -> (String) row.get("role"));
225   }
226
227   private void verifyMembershipOfAdminUser() {
228     List<Map<String, Object>> rows = db.select("select g.name as \"groupName\" from groups g " +
229       "inner join groups_users gu on gu.group_uuid = g.uuid " +
230       "inner join users u on gu.user_uuid = u.uuid " +
231       "where u.login='admin'");
232     List<String> groupNames = rows.stream()
233       .map(row -> (String) row.get("groupName"))
234       .collect(MoreCollectors.toArrayList());
235     assertThat(groupNames).containsOnly("sonar-administrators", "sonar-users");
236   }
237
238 }