From: Teryk Bellahsene Date: Tue, 25 Aug 2015 15:29:19 +0000 (+0200) Subject: SONAR-6496 WS permissions/create_template create a permission template X-Git-Tag: 5.2-RC1~603 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=61050e0245725fc9fdca23825d49ccf3cfa2bba2;p=sonarqube.git SONAR-6496 WS permissions/create_template create a permission template --- diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionRequestValidator.java b/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionRequestValidator.java index 9ce5d35934b..66292b48b24 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionRequestValidator.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionRequestValidator.java @@ -20,15 +20,25 @@ package org.sonar.server.permission; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; import javax.annotation.Nullable; import org.sonar.core.permission.GlobalPermissions; import org.sonar.core.permission.ProjectPermissions; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.permission.PermissionTemplateDto; +import org.sonar.server.exceptions.BadRequestException; +import static com.google.common.base.Strings.isNullOrEmpty; import static java.lang.String.format; import static org.sonar.api.security.DefaultGroups.isAnyone; import static org.sonar.server.ws.WsUtils.checkRequest; public class PermissionRequestValidator { + public static final String MSG_TEMPLATE_WITH_SAME_NAME = "A template with the name '%s' already exists (case insensitive)."; + public static final String MSG_TEMPLATE_NAME_NOT_BLANK = "The template name must not be blank"; + private PermissionRequestValidator() { // static methods only } @@ -45,6 +55,26 @@ public class PermissionRequestValidator { public static void validateNotAnyoneAndAdminPermission(String permission, @Nullable String groupName) { checkRequest(!GlobalPermissions.SYSTEM_ADMIN.equals(permission) || !isAnyone(groupName), - String.format("It is not possible to add the '%s' permission to the '%s' group.", permission, groupName)); + format("It is not possible to add the '%s' permission to the '%s' group.", permission, groupName)); + } + + public static void validateProjectPattern(@Nullable String projectPattern) { + if (isNullOrEmpty(projectPattern)) { + return; + } + + try { + Pattern.compile(projectPattern); + } catch (PatternSyntaxException e) { + throw new BadRequestException(format("The 'projectPattern' parameter must be a valid Java regular expression. '%s' was passed", projectPattern)); + } + } + + public static void validateTemplateNameForUpdate(DbSession dbSession, DbClient dbClient, String templateName, long templateId) { + checkRequest(!templateName.isEmpty(), MSG_TEMPLATE_NAME_NOT_BLANK); + + PermissionTemplateDto permissionTemplateWithSameName = dbClient.permissionTemplateDao().selectByName(dbSession, templateName); + checkRequest(permissionTemplateWithSameName == null || permissionTemplateWithSameName.getId() == templateId, + format(MSG_TEMPLATE_WITH_SAME_NAME, templateName)); } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionTemplateService.java b/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionTemplateService.java index b5e9aec8fb3..6962215643a 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionTemplateService.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionTemplateService.java @@ -21,26 +21,31 @@ package org.sonar.server.permission; import com.google.common.collect.Lists; +import java.util.Date; import java.util.List; import java.util.Map; -import java.util.regex.Pattern; -import java.util.regex.PatternSyntaxException; import javax.annotation.CheckForNull; import javax.annotation.Nullable; -import org.apache.commons.lang.StringUtils; import org.sonar.api.server.ServerSide; +import org.sonar.api.utils.System2; +import org.sonar.api.utils.internal.Uuids; import org.sonar.core.permission.GlobalPermissions; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.permission.PermissionTemplateDao; import org.sonar.db.permission.PermissionTemplateDto; import org.sonar.db.user.GroupDto; -import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.user.UserSession; +import static java.lang.String.format; import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdminUser; import static org.sonar.server.permission.PermissionPrivilegeChecker.checkProjectAdminUserByComponentKey; +import static org.sonar.server.permission.PermissionRequestValidator.MSG_TEMPLATE_NAME_NOT_BLANK; +import static org.sonar.server.permission.PermissionRequestValidator.MSG_TEMPLATE_WITH_SAME_NAME; +import static org.sonar.server.permission.PermissionRequestValidator.validateProjectPattern; +import static org.sonar.server.permission.PermissionRequestValidator.validateTemplateNameForUpdate; +import static org.sonar.server.ws.WsUtils.checkRequest; /** * Used by ruby code
Internal.permission_templates
@@ -91,19 +96,39 @@ public class PermissionTemplateService { return permissionTemplates; } - public PermissionTemplate createPermissionTemplate(String name, @Nullable String description, @Nullable String keyPattern) { - checkGlobalAdminUser(userSession); - validateTemplateName(null, name); - validateKeyPattern(keyPattern); - PermissionTemplateDto permissionTemplateDto = permissionTemplateDao.insertPermissionTemplate(name, description, keyPattern); - return PermissionTemplate.create(permissionTemplateDto); + public PermissionTemplate createPermissionTemplate(String name, @Nullable String description, @Nullable String projectKeyPattern) { + DbSession dbSession = dbClient.openSession(false); + + try { + checkGlobalAdminUser(userSession); + validateTemplateNameForCreation(dbSession, name); + validateProjectPattern(projectKeyPattern); + Date now = new Date(System2.INSTANCE.now()); + PermissionTemplateDto permissionTemplateDto = permissionTemplateDao.insert(dbSession, new PermissionTemplateDto() + .setKee(Uuids.create()) + .setName(name) + .setKeyPattern(projectKeyPattern) + .setDescription(description) + .setCreatedAt(now) + .setUpdatedAt(now)); + dbSession.commit(); + return PermissionTemplate.create(permissionTemplateDto); + } finally { + dbClient.closeSession(dbSession); + } } - public void updatePermissionTemplate(Long templateId, String newName, @Nullable String newDescription, @Nullable String newKeyPattern) { - checkGlobalAdminUser(userSession); - validateTemplateName(templateId, newName); - validateKeyPattern(newKeyPattern); - permissionTemplateDao.updatePermissionTemplate(templateId, newName, newDescription, newKeyPattern); + public void updatePermissionTemplate(Long templateId, String newName, @Nullable String newDescription, @Nullable String projectPattern) { + DbSession dbSession = dbClient.openSession(false); + + try { + checkGlobalAdminUser(userSession); + validateTemplateNameForUpdate(dbSession, dbClient, newName, templateId); + validateProjectPattern(projectPattern); + permissionTemplateDao.update(templateId, newName, newDescription, projectPattern); + } finally { + dbClient.closeSession(dbSession); + } } public void deletePermissionTemplate(Long templateId) { @@ -186,32 +211,14 @@ public class PermissionTemplateService { } } - private void validateTemplateName(@Nullable Long templateId, String templateName) { - if (StringUtils.isEmpty(templateName)) { - String errorMsg = "Name can't be blank"; - throw new BadRequestException(errorMsg); - } - List existingTemplates = permissionTemplateDao.selectAllPermissionTemplates(); - if (existingTemplates != null) { - for (PermissionTemplateDto existingTemplate : existingTemplates) { - if ((templateId == null || !existingTemplate.getId().equals(templateId)) && (existingTemplate.getName().equals(templateName))) { - String errorMsg = "A template with that name already exists"; - throw new BadRequestException(errorMsg); - } - } - } - } + /** + * @deprecated since 5.2 + */ + @Deprecated + private void validateTemplateNameForCreation(DbSession dbSession, String templateName) { + checkRequest(!templateName.isEmpty(), MSG_TEMPLATE_NAME_NOT_BLANK); - private static void validateKeyPattern(@Nullable String keyPattern) { - if (StringUtils.isEmpty(keyPattern)) { - return; - } - try { - Pattern.compile(keyPattern); - } catch (PatternSyntaxException e) { - String errorMsg = "Invalid pattern: " + keyPattern + ". Should be a valid Java regular expression."; - throw new BadRequestException(errorMsg); - } + PermissionTemplateDto permissionTemplateWithSameName = dbClient.permissionTemplateDao().selectByName(dbSession, templateName); + checkRequest(permissionTemplateWithSameName == null, format(MSG_TEMPLATE_WITH_SAME_NAME, templateName)); } - } diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/CreateTemplateAction.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/CreateTemplateAction.java new file mode 100644 index 00000000000..1036ad990a2 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/CreateTemplateAction.java @@ -0,0 +1,134 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * SonarQube is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +package org.sonar.server.permission.ws; + +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.WebService; +import org.sonar.api.utils.System2; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.permission.PermissionTemplateDto; +import org.sonar.server.user.UserSession; +import org.sonarqube.ws.Permissions; +import org.sonarqube.ws.Permissions.PermissionTemplate; + +import static org.sonar.api.utils.DateUtils.formatDateTime; +import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdminUser; +import static org.sonar.server.permission.PermissionRequestValidator.MSG_TEMPLATE_NAME_NOT_BLANK; +import static org.sonar.server.permission.PermissionRequestValidator.MSG_TEMPLATE_WITH_SAME_NAME; +import static org.sonar.server.permission.PermissionRequestValidator.validateProjectPattern; +import static org.sonar.server.permission.ws.Parameters.PARAM_TEMPLATE_DESCRIPTION; +import static org.sonar.server.permission.ws.Parameters.PARAM_TEMPLATE_NAME; +import static org.sonar.server.permission.ws.Parameters.PARAM_TEMPLATE_PATTERN; +import static org.sonar.server.permission.ws.PermissionTemplateDtoBuilder.create; +import static org.sonar.server.ws.WsUtils.checkRequest; +import static org.sonar.server.ws.WsUtils.writeProtobuf; + +public class CreateTemplateAction implements PermissionsWsAction { + private final DbClient dbClient; + private final UserSession userSession; + private final System2 system; + + public CreateTemplateAction(DbClient dbClient, UserSession userSession, System2 system) { + this.dbClient = dbClient; + this.userSession = userSession; + this.system = system; + } + + @Override + public void define(WebService.NewController context) { + WebService.NewAction action = context.createAction("create_template") + .setDescription("Create a permission template.
" + + "It requires administration permissions to access.") + .setResponseExample(getClass().getResource("create_template-example.json")) + .setSince("5.2") + .setPost(true) + .setHandler(this); + + action.createParam(PARAM_TEMPLATE_NAME) + .setRequired(true) + .setDescription("Name") + .setExampleValue("Financial Service Permissions"); + + action.createParam(PARAM_TEMPLATE_PATTERN) + .setDescription("Project key pattern. Must be a valid Java regular expression") + .setExampleValue(".*\\.finance\\..*"); + + action.createParam(PARAM_TEMPLATE_DESCRIPTION) + .setDescription("Description") + .setExampleValue("Permissions for all projects related to the financial service"); + } + + @Override + public void handle(Request wsRequest, Response wsResponse) throws Exception { + String name = wsRequest.mandatoryParam(PARAM_TEMPLATE_NAME); + String description = wsRequest.param(PARAM_TEMPLATE_DESCRIPTION); + String projectPattern = wsRequest.param(PARAM_TEMPLATE_PATTERN); + + DbSession dbSession = dbClient.openSession(false); + try { + checkGlobalAdminUser(userSession); + validateTemplateNameForCreation(dbSession, name); + validateProjectPattern(projectPattern); + + PermissionTemplateDto permissionTemplate = insertTemplate(dbSession, name, description, projectPattern); + + Permissions.CreatePermissionTemplateResponse response = buildResponse(permissionTemplate); + writeProtobuf(response, wsRequest, wsResponse); + } finally { + dbClient.closeSession(dbSession); + } + } + + private void validateTemplateNameForCreation(DbSession dbSession, String templateName) { + checkRequest(!templateName.isEmpty(), MSG_TEMPLATE_NAME_NOT_BLANK); + + PermissionTemplateDto permissionTemplateWithSameName = dbClient.permissionTemplateDao().selectByName(dbSession, templateName); + checkRequest(permissionTemplateWithSameName == null, String.format + (MSG_TEMPLATE_WITH_SAME_NAME, templateName)); + } + + private PermissionTemplateDto insertTemplate(DbSession dbSession, String name, String description, String projectPattern) { + PermissionTemplateDto template = dbClient.permissionTemplateDao().insert(dbSession, create(system) + .setName(name) + .setDescription(description) + .setProjectKeyPattern(projectPattern) + .toDto()); + dbSession.commit(); + return template; + } + + private Permissions.CreatePermissionTemplateResponse buildResponse(PermissionTemplateDto permissionTemplate) { + PermissionTemplate.Builder permissionTemplateBuilder = PermissionTemplate.newBuilder() + .setKey(permissionTemplate.getKee()) + .setName(permissionTemplate.getName()) + .setCreatedAt(formatDateTime(permissionTemplate.getCreatedAt())) + .setUpdatedAt(formatDateTime(permissionTemplate.getUpdatedAt())); + if (permissionTemplate.getDescription() != null) { + permissionTemplateBuilder.setDescription(permissionTemplate.getDescription()); + } + if (permissionTemplate.getKeyPattern() != null) { + permissionTemplateBuilder.setProjectPattern(permissionTemplate.getKeyPattern()); + } + return Permissions.CreatePermissionTemplateResponse.newBuilder().setPermissionTemplate(permissionTemplateBuilder).build(); + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/Parameters.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/Parameters.java index e15cd93a079..a06aa8e19ab 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/Parameters.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/Parameters.java @@ -33,6 +33,9 @@ class Parameters { static final String PARAM_PROJECT_KEY = "projectKey"; static final String PARAM_USER_LOGIN = "login"; static final String PARAM_TEMPLATE_KEY = "templateKey"; + static final String PARAM_TEMPLATE_NAME = "name"; + static final String PARAM_TEMPLATE_DESCRIPTION = "description"; + static final String PARAM_TEMPLATE_PATTERN = "projectPattern"; private static final String PERMISSION_PARAM_DESCRIPTION = String.format("Permission" + "