]> source.dussan.org Git - sonarqube.git/blob
74cf229a2f780940bd99f8bc5b11c0dcff73015b
[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.Arrays;
24 import java.util.Date;
25 import java.util.List;
26 import org.sonar.api.SonarRuntime;
27 import org.sonar.api.utils.System2;
28 import org.sonar.core.util.UuidFactory;
29 import org.sonar.db.Database;
30 import org.sonar.server.platform.db.migration.step.DataChange;
31 import org.sonar.server.platform.db.migration.step.Upsert;
32
33 import static java.util.Arrays.stream;
34 import static java.util.Objects.requireNonNull;
35 import static java.util.stream.Collectors.joining;
36 import static java.util.stream.Stream.concat;
37 import static java.util.stream.Stream.of;
38
39 public class PopulateInitialSchema extends DataChange {
40
41   private static final String ADMINS_GROUP = "sonar-administrators";
42   private static final String USERS_GROUP = "sonar-users";
43   private static final String ADMIN_USER = "admin";
44   private static final String ADMIN_CRYPTED_PASSWORD = "$2a$12$uCkkXmhW5ThVK8mpBvnXOOJRLd64LJeHTeCkSuB3lfaR2N0AYBaSi";
45   private static final List<String> ADMIN_ROLES = Arrays.asList("admin", "profileadmin", "gateadmin", "provisioning", "applicationcreator", "portfoliocreator");
46
47   private final System2 system2;
48   private final UuidFactory uuidFactory;
49   private final SonarRuntime sonarRuntime;
50
51   public PopulateInitialSchema(Database db, System2 system2, UuidFactory uuidFactory, SonarRuntime sonarRuntime) {
52     super(db);
53     this.system2 = system2;
54     this.uuidFactory = uuidFactory;
55     this.sonarRuntime = sonarRuntime;
56   }
57
58   @Override
59   public void execute(Context context) throws SQLException {
60     String adminUserUuid = insertAdminUser(context);
61     Groups groups = insertGroups(context);
62     String defaultQGUuid = insertQualityGate(context);
63     insertInternalProperty(context);
64     insertProperties(context, defaultQGUuid);
65     insertGroupRoles(context, groups);
66     insertGroupUsers(context, adminUserUuid, groups);
67   }
68
69   private String insertAdminUser(Context context) throws SQLException {
70     truncateTable(context, "users");
71
72     long now = system2.now();
73     context.prepareUpsert("insert into users " +
74       "(uuid, login, name, email, external_id, external_login, external_identity_provider, user_local, crypted_password, salt, hash_method, is_root, onboarded, reset_password, " +
75       "created_at, updated_at)" +
76       " values " +
77       "(?, ?, 'Administrator', null, 'admin', 'admin', 'sonarqube', ?, ?, null, 'BCRYPT', ?, ?, ?, ?, ?)")
78       .setString(1, uuidFactory.create())
79       .setString(2, ADMIN_USER)
80       .setBoolean(3, true)
81       .setString(4, ADMIN_CRYPTED_PASSWORD)
82       .setBoolean(5, false)
83       .setBoolean(6, true)
84       .setBoolean(7, true)
85       .setLong(8, now)
86       .setLong(9, now)
87       .execute()
88       .commit();
89
90     String res = context.prepareSelect("select uuid from users where login=?")
91       .setString(1, ADMIN_USER)
92       .get(t -> t.getString(1));
93     return requireNonNull(res);
94   }
95
96   private void insertInternalProperty(Context context) throws SQLException {
97     String tableName = "internal_properties";
98     truncateTable(context, tableName);
99
100     long now = system2.now();
101     Upsert upsert = context.prepareUpsert(createInsertStatement(tableName, "kee", "is_empty", "text_value", "created_at"));
102     upsert
103       .setString(1, "installation.date")
104       .setBoolean(2, false)
105       .setString(3, String.valueOf(system2.now()))
106       .setLong(4, now)
107       .addBatch();
108     upsert
109       .setString(1, "installation.version")
110       .setBoolean(2, false)
111       .setString(3, sonarRuntime.getApiVersion().toString())
112       .setLong(4, now)
113       .addBatch();
114     upsert
115       .execute()
116       .commit();
117   }
118
119   private void insertProperties(Context context, String defaultQualityGate) throws SQLException {
120     var tableName = "properties";
121     truncateTable(context, tableName);
122
123     long now = system2.now();
124     var upsert = context
125       .prepareUpsert(createInsertStatement(tableName, "uuid", "prop_key", "is_empty", "text_value", "created_at"));
126
127     upsert.setString(1, uuidFactory.create())
128       .setString(2, "sonar.forceAuthentication")
129       .setBoolean(3, false)
130       .setString(4, "true")
131       .setLong(5, now)
132       .addBatch();
133
134     upsert
135       .setString(1, uuidFactory.create())
136       .setString(2, "projects.default.visibility")
137       .setBoolean(3, false)
138       .setString(4, "public")
139       .setLong(5, system2.now())
140       .addBatch();
141
142     upsert
143       .setString(1, uuidFactory.create())
144       .setString(2, "qualitygate.default")
145       .setBoolean(3, false)
146       .setString(4, defaultQualityGate)
147       .setLong(5, system2.now())
148       .addBatch();
149
150     upsert
151       .execute()
152       .commit();
153   }
154
155   private Groups insertGroups(Context context) throws SQLException {
156     truncateTable(context, "groups");
157
158     Date now = new Date(system2.now());
159     Upsert upsert = context.prepareUpsert(createInsertStatement(
160       "groups",
161       "uuid", "name", "description", "created_at", "updated_at"));
162     upsert
163       .setString(1, uuidFactory.create())
164       .setString(2, ADMINS_GROUP)
165       .setString(3, "System administrators")
166       .setDate(4, now)
167       .setDate(5, now)
168       .addBatch();
169     upsert
170       .setString(1, uuidFactory.create())
171       .setString(2, USERS_GROUP)
172       .setString(3, "Any new users created will automatically join this group")
173       .setDate(4, now)
174       .setDate(5, now)
175       .addBatch();
176     upsert
177       .execute()
178       .commit();
179
180     return new Groups(getGroupUuid(context, ADMINS_GROUP), getGroupUuid(context, USERS_GROUP));
181   }
182
183   private static String getGroupUuid(Context context, String groupName) throws SQLException {
184     String res = context.prepareSelect("select uuid from groups where name=?")
185       .setString(1, groupName)
186       .get(t -> t.getString(1));
187     return requireNonNull(res);
188   }
189
190   private String insertQualityGate(Context context) throws SQLException {
191     truncateTable(context, "quality_gates");
192
193     String uuid = uuidFactory.create();
194     Date now = new Date(system2.now());
195     context.prepareUpsert(createInsertStatement("quality_gates", "uuid", "name", "is_built_in", "created_at", "updated_at"))
196       .setString(1, uuid)
197       .setString(2, "Sonar way")
198       .setBoolean(3, true)
199       .setDate(4, now)
200       .setDate(5, now)
201       .execute()
202       .commit();
203     return uuid;
204   }
205
206   private static final class Groups {
207     private final String adminGroupUuid;
208     private final String userGroupUuid;
209
210     private Groups(String adminGroupUuid, String userGroupUuid) {
211       this.adminGroupUuid = adminGroupUuid;
212       this.userGroupUuid = userGroupUuid;
213     }
214
215     public String getAdminGroupUuid() {
216       return adminGroupUuid;
217     }
218
219     public String getUserGroupUuid() {
220       return userGroupUuid;
221     }
222   }
223
224   private void insertGroupRoles(Context context, Groups groups) throws SQLException {
225     truncateTable(context, "group_roles");
226
227     Upsert upsert = context.prepareUpsert(createInsertStatement("group_roles", "uuid","group_uuid", "role"));
228     for (String adminRole : ADMIN_ROLES) {
229       upsert
230         .setString(1, uuidFactory.create())
231         .setString(2, groups.getAdminGroupUuid())
232         .setString(3, adminRole)
233         .addBatch();
234     }
235     for (String anyoneRole : Arrays.asList("scan", "provisioning")) {
236       upsert
237         .setString(1, uuidFactory.create())
238         .setString(2, null)
239         .setString(3, anyoneRole)
240         .addBatch();
241     }
242     upsert
243       .execute()
244       .commit();
245   }
246
247   private static void insertGroupUsers(Context context, String adminUserUuid, Groups groups) throws SQLException {
248     truncateTable(context, "groups_users");
249
250     Upsert upsert = context.prepareUpsert(createInsertStatement("groups_users", "user_uuid", "group_uuid"));
251     upsert
252       .setString(1, adminUserUuid)
253       .setString(2, groups.getUserGroupUuid())
254       .addBatch();
255     upsert
256       .setString(1, adminUserUuid)
257       .setString(2, groups.getAdminGroupUuid())
258       .addBatch();
259     upsert
260       .execute()
261       .commit();
262   }
263
264   private static void truncateTable(Context context, String table) throws SQLException {
265     context.prepareUpsert("truncate table " + table).execute().commit();
266   }
267
268   private static String createInsertStatement(String tableName, String firstColumn, String... otherColumns) {
269     return "insert into " + tableName + " " +
270       "(" + concat(of(firstColumn), stream(otherColumns)).collect(joining(",")) + ")" +
271       " values" +
272       " (" + concat(of(firstColumn), stream(otherColumns)).map(t -> "?").collect(joining(",")) + ")";
273   }
274
275 }