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.
20 package org.sonar.server.platform.db.migration.version.v64;
22 import java.sql.SQLException;
23 import java.util.Arrays;
24 import java.util.Date;
25 import java.util.List;
26 import javax.annotation.CheckForNull;
27 import javax.annotation.Nullable;
28 import org.sonar.db.Database;
29 import org.sonar.server.platform.db.migration.step.DataChange;
30 import org.sonar.server.platform.db.migration.step.Select;
31 import org.sonar.server.platform.db.migration.version.v63.DefaultOrganizationUuidProvider;
33 import static com.google.common.base.Preconditions.checkState;
35 public class SupportPrivateProjectInDefaultPermissionTemplate extends DataChange {
36 private static final String PERMISSION_USER = "user";
37 private static final String PERMISSION_CODEVIEWER = "codeviewer";
39 private DefaultOrganizationUuidProvider defaultOrganizationUuidProvider;
41 public SupportPrivateProjectInDefaultPermissionTemplate(Database db, DefaultOrganizationUuidProvider defaultOrganizationUuidProvider) {
43 this.defaultOrganizationUuidProvider = defaultOrganizationUuidProvider;
47 protected void execute(Context context) throws SQLException {
48 String defaultOrganizationUuid = this.defaultOrganizationUuidProvider.get(context);
50 ResolvedOrganizationProperties organizationProperties = readOrganizationProperties(context, defaultOrganizationUuid);
52 int defaultGroupId = organizationProperties.defaultGroupId;
53 for (Integer groupId : Arrays.asList(organizationProperties.getProjectId(), organizationProperties.getViewId())) {
54 if (groupId != null) {
55 insertGroupPermissionIfNotPresent(context, defaultGroupId, groupId, PERMISSION_USER);
56 insertGroupPermissionIfNotPresent(context, defaultGroupId, groupId, PERMISSION_CODEVIEWER);
61 private static void insertGroupPermissionIfNotPresent(Context context, int groupId, int templateId, String permission) throws SQLException {
62 if (!groupHasPermissionInTemplate(context, templateId, groupId, permission)) {
63 insertGroupPermission(context, templateId, groupId, permission);
67 private static boolean groupHasPermissionInTemplate(Context context, int templateId, int groupId, String permission) throws SQLException {
68 List<Integer> rows = context.prepareSelect("select 1 from perm_templates_groups where" +
71 " and permission_reference=?")
72 .setInt(1, templateId)
74 .setString(3, permission)
75 .list(row -> row.getInt(1));
76 return !rows.isEmpty();
79 private static void insertGroupPermission(Context context, int templateId, int groupId, String permission) throws SQLException {
80 Date now = new Date();
81 context.prepareUpsert("insert into perm_templates_groups (group_id, template_id, permission_reference, created_at, updated_at) values (?,?,?,?,?)")
83 .setInt(2, templateId)
84 .setString(3, permission)
91 private static ResolvedOrganizationProperties readOrganizationProperties(Context context, String defaultOrganizationUuid) throws SQLException {
92 Select select = context.prepareSelect("select default_group_id, default_perm_template_project, default_perm_template_view from organizations where uuid=?")
93 .setString(1, defaultOrganizationUuid);
94 List<OrganizationProperties> rows = select
95 .list(row -> new OrganizationProperties(row.getNullableInt(1), row.getNullableString(2), row.getNullableString(3)));
96 checkState(!rows.isEmpty(), "Default organization with uuid '%s' does not exist in table ORGANIZATIONS", defaultOrganizationUuid);
97 OrganizationProperties rawProperties = rows.iterator().next();
98 checkState(rawProperties.defaultGroupId != null, "No default group id is defined for default organization (uuid=%s)", defaultOrganizationUuid);
99 checkState(rawProperties.projectUuid != null || rawProperties.viewUuid == null,
100 "Inconsistent state for default organization (uuid=%s): no project default template is defined but view default template is", defaultOrganizationUuid);
101 return new ResolvedOrganizationProperties(
102 rawProperties.defaultGroupId,
103 getPermTemplateId(context, rawProperties.projectUuid),
104 getPermTemplateId(context, rawProperties.viewUuid));
108 private static Integer getPermTemplateId(Context context, @Nullable String permissionTemplateUuid) throws SQLException {
109 if (permissionTemplateUuid == null) {
112 List<Integer> ids = context.prepareSelect("select id from permission_templates where kee=?")
113 .setString(1, permissionTemplateUuid)
114 .list(row -> row.getInt(1));
115 checkState(!ids.isEmpty(), "Permission template with uuid %s not found", permissionTemplateUuid);
116 checkState(ids.size() == 1, "Multiple permission templates found with uuid %s", permissionTemplateUuid);
117 return ids.iterator().next();
120 private static final class OrganizationProperties {
121 private final Integer defaultGroupId;
122 private final String projectUuid;
123 private final String viewUuid;
125 private OrganizationProperties(@Nullable Integer defaultGroupId, @Nullable String projectUuid, @Nullable String viewUuid) {
126 this.defaultGroupId = defaultGroupId;
127 this.projectUuid = projectUuid;
128 this.viewUuid = viewUuid;
132 private static final class ResolvedOrganizationProperties {
133 private final int defaultGroupId;
134 private final Integer projectId;
135 private final Integer viewId;
137 private ResolvedOrganizationProperties(int defaultGroupId, @Nullable Integer projectId, @Nullable Integer viewId) {
138 this.defaultGroupId = defaultGroupId;
139 this.projectId = projectId;
140 this.viewId = viewId;
143 int getDefaultGroupId() {
144 return defaultGroupId;
147 Integer getProjectId() {
153 Integer getViewId() {