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