]> source.dussan.org Git - sonarqube.git/blob
14b5b824c7fe0b0cd6fd3de2e58e0e6a92fb8819
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2024 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.permission.ws.template;
21
22 import java.util.Date;
23 import java.util.Objects;
24 import javax.annotation.CheckForNull;
25 import javax.annotation.Nullable;
26 import org.sonar.api.server.ws.Request;
27 import org.sonar.api.server.ws.Response;
28 import org.sonar.api.server.ws.WebService;
29 import org.sonar.api.utils.System2;
30 import org.sonar.db.DbClient;
31 import org.sonar.db.DbSession;
32 import org.sonar.db.permission.template.PermissionTemplateDto;
33 import org.sonar.server.exceptions.BadRequestException;
34 import org.sonar.server.permission.RequestValidator;
35 import org.sonar.server.permission.ws.PermissionWsSupport;
36 import org.sonar.server.permission.ws.PermissionsWsAction;
37 import org.sonar.server.permission.ws.WsParameters;
38 import org.sonar.server.user.UserSession;
39 import org.sonarqube.ws.Permissions.PermissionTemplate;
40 import org.sonarqube.ws.Permissions.UpdateTemplateWsResponse;
41
42 import static java.lang.String.format;
43 import static java.util.Objects.requireNonNull;
44 import static org.apache.commons.lang.StringUtils.isBlank;
45 import static org.sonar.server.exceptions.BadRequestException.checkRequest;
46 import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdmin;
47 import static org.sonar.server.permission.RequestValidator.MSG_TEMPLATE_WITH_SAME_NAME;
48 import static org.sonar.server.permission.ws.template.PermissionTemplateDtoToPermissionTemplateResponse.toPermissionTemplateResponse;
49 import static org.sonar.server.ws.WsUtils.writeProtobuf;
50 import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_DESCRIPTION;
51 import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_ID;
52 import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_NAME;
53 import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_KEY_PATTERN;
54
55 public class UpdateTemplateAction implements PermissionsWsAction {
56   private final DbClient dbClient;
57   private final UserSession userSession;
58   private final System2 system;
59   private final PermissionWsSupport wsSupport;
60
61   public UpdateTemplateAction(DbClient dbClient, UserSession userSession, System2 system, PermissionWsSupport wsSupport) {
62     this.dbClient = dbClient;
63     this.userSession = userSession;
64     this.system = system;
65     this.wsSupport = wsSupport;
66   }
67
68   private static UpdateTemplateRequest toUpdateTemplateWsRequest(Request request) {
69     return new UpdateTemplateRequest()
70       .setId(request.mandatoryParam(PARAM_ID))
71       .setName(request.param(PARAM_NAME))
72       .setDescription(request.param(PARAM_DESCRIPTION))
73       .setProjectKeyPattern(request.param(PARAM_PROJECT_KEY_PATTERN));
74   }
75
76   private static UpdateTemplateWsResponse buildResponse(PermissionTemplateDto permissionTemplate) {
77     PermissionTemplate permissionTemplateBuilder = toPermissionTemplateResponse(permissionTemplate);
78     return UpdateTemplateWsResponse.newBuilder().setPermissionTemplate(permissionTemplateBuilder).build();
79   }
80
81   @Override
82   public void define(WebService.NewController context) {
83     WebService.NewAction action = context.createAction("update_template")
84       .setDescription("Update a permission template.<br />" +
85         "Requires the following permission: 'Administer System'.")
86       .setResponseExample(getClass().getResource("update_template-example.json"))
87       .setSince("5.2")
88       .setPost(true)
89       .setHandler(this);
90
91     WsParameters.createIdParameter(action);
92
93     action.createParam(PARAM_NAME)
94       .setDescription("Name")
95       .setExampleValue("Financial Service Permissions");
96
97     WsParameters.createTemplateProjectKeyPatternParameter(action);
98     WsParameters.createTemplateDescriptionParameter(action);
99   }
100
101   @Override
102   public void handle(Request request, Response response) throws Exception {
103     UpdateTemplateWsResponse updateTemplateWsResponse = doHandle(toUpdateTemplateWsRequest(request));
104     writeProtobuf(updateTemplateWsResponse, request, response);
105   }
106
107   private UpdateTemplateWsResponse doHandle(UpdateTemplateRequest request) {
108     String uuid = request.getId();
109     String nameParam = request.getName();
110     String descriptionParam = request.getDescription();
111     String projectPatternParam = request.getProjectKeyPattern();
112
113     try (DbSession dbSession = dbClient.openSession(false)) {
114       PermissionTemplateDto templateToUpdate = getAndBuildTemplateToUpdate(dbSession, uuid, nameParam, descriptionParam, projectPatternParam);
115       checkGlobalAdmin(userSession);
116
117       validateTemplate(dbSession, templateToUpdate);
118       PermissionTemplateDto updatedTemplate = updateTemplate(dbSession, templateToUpdate);
119       dbSession.commit();
120
121       return buildResponse(updatedTemplate);
122     }
123   }
124
125   private void validateTemplate(DbSession dbSession, PermissionTemplateDto templateToUpdate) {
126     validateTemplateNameForUpdate(dbSession, templateToUpdate.getName(), templateToUpdate.getUuid());
127     RequestValidator.validateProjectPattern(templateToUpdate.getKeyPattern());
128   }
129
130   private PermissionTemplateDto getAndBuildTemplateToUpdate(DbSession dbSession, String uuid, @Nullable String newName, @Nullable String newDescription,
131     @Nullable String newProjectKeyPattern) {
132     PermissionTemplateDto templateToUpdate = wsSupport.findTemplate(dbSession, WsTemplateRef.newTemplateRef(uuid, null));
133     templateToUpdate.setName(coalesce(newName, templateToUpdate.getName()));
134     templateToUpdate.setDescription(coalesce(newDescription, templateToUpdate.getDescription()));
135     templateToUpdate.setKeyPattern(coalesce(newProjectKeyPattern, templateToUpdate.getKeyPattern()));
136     templateToUpdate.setUpdatedAt(new Date(system.now()));
137
138     return templateToUpdate;
139   }
140
141   @CheckForNull
142   private static String coalesce(@Nullable String s1, @Nullable String s2) {
143     return s1 != null ? s1 : s2;
144   }
145
146   private PermissionTemplateDto updateTemplate(DbSession dbSession, PermissionTemplateDto templateToUpdate) {
147     return dbClient.permissionTemplateDao().update(dbSession, templateToUpdate);
148   }
149
150   private void validateTemplateNameForUpdate(DbSession dbSession, String name, String uuid) {
151     BadRequestException.checkRequest(!isBlank(name), "The template name must not be blank");
152
153     PermissionTemplateDto permissionTemplateWithSameName = dbClient.permissionTemplateDao().selectByName(dbSession, name);
154     checkRequest(permissionTemplateWithSameName == null || Objects.equals(permissionTemplateWithSameName.getUuid(), uuid),
155       format(MSG_TEMPLATE_WITH_SAME_NAME, name));
156   }
157
158   private static class UpdateTemplateRequest {
159     private String id;
160     private String description;
161     private String name;
162     private String projectKeyPattern;
163
164     public String getId() {
165       return id;
166     }
167
168     public UpdateTemplateRequest setId(String id) {
169       this.id = requireNonNull(id);
170       return this;
171     }
172
173     @CheckForNull
174     public String getDescription() {
175       return description;
176     }
177
178     public UpdateTemplateRequest setDescription(@Nullable String description) {
179       this.description = description;
180       return this;
181     }
182
183     @CheckForNull
184     public String getName() {
185       return name;
186     }
187
188     public UpdateTemplateRequest setName(@Nullable String name) {
189       this.name = name;
190       return this;
191     }
192
193     @CheckForNull
194     public String getProjectKeyPattern() {
195       return projectKeyPattern;
196     }
197
198     public UpdateTemplateRequest setProjectKeyPattern(@Nullable String projectKeyPattern) {
199       this.projectKeyPattern = projectKeyPattern;
200       return this;
201     }
202   }
203 }