From: Teryk Bellahsene Date: Mon, 7 Sep 2015 15:00:10 +0000 (+0200) Subject: Add template package in the permission.ws package X-Git-Tag: 5.2-RC1~231 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=ae64fe3edb2f5e96a2d40c8bce24bae4fa7fd4a2;p=sonarqube.git Add template package in the permission.ws package --- diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/AddGroupToTemplateAction.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/AddGroupToTemplateAction.java deleted file mode 100644 index 741b4dcf189..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/AddGroupToTemplateAction.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * 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 javax.annotation.Nullable; -import org.sonar.api.server.ws.Request; -import org.sonar.api.server.ws.Response; -import org.sonar.api.server.ws.WebService; -import org.sonar.db.DbClient; -import org.sonar.db.DbSession; -import org.sonar.db.permission.PermissionQuery; -import org.sonar.db.permission.PermissionTemplateDto; -import org.sonar.db.user.GroupDto; -import org.sonar.server.user.UserSession; - -import static org.sonar.api.security.DefaultGroups.ANYONE; -import static org.sonar.db.user.GroupMembershipQuery.IN; -import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdminUser; -import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_PERMISSION; -import static org.sonar.server.permission.ws.WsPermissionParameters.createGroupIdParameter; -import static org.sonar.server.permission.ws.WsPermissionParameters.createGroupNameParameter; -import static org.sonar.server.permission.ws.WsPermissionParameters.createProjectPermissionParameter; -import static org.sonar.server.permission.ws.WsPermissionParameters.createTemplateParameters; -import static org.sonar.server.permission.ws.PermissionRequestValidator.validateNotAnyoneAndAdminPermission; -import static org.sonar.server.permission.ws.PermissionRequestValidator.validateProjectPermission; - -public class AddGroupToTemplateAction implements PermissionsWsAction { - private final DbClient dbClient; - private final PermissionDependenciesFinder dependenciesFinder; - private final UserSession userSession; - - public AddGroupToTemplateAction(DbClient dbClient, PermissionDependenciesFinder dependenciesFinder, UserSession userSession) { - this.dbClient = dbClient; - this.dependenciesFinder = dependenciesFinder; - this.userSession = userSession; - } - - @Override - public void define(WebService.NewController context) { - WebService.NewAction action = context - .createAction("add_group_to_template") - .setPost(true) - .setSince("5.2") - .setDescription("Add a group to a permission template.
" + - "The group id or group name must be provided.
" + - "It requires administration permissions to access.") - .setHandler(this); - - createTemplateParameters(action); - createProjectPermissionParameter(action); - createGroupIdParameter(action); - createGroupNameParameter(action); - } - - @Override - public void handle(Request wsRequest, Response wsResponse) throws Exception { - checkGlobalAdminUser(userSession); - - String permission = wsRequest.mandatoryParam(PARAM_PERMISSION); - WsGroupRef group = WsGroupRef.fromRequest(wsRequest); - - DbSession dbSession = dbClient.openSession(false); - try { - validateProjectPermission(permission); - validateNotAnyoneAndAdminPermission(permission, group.name()); - - PermissionTemplateDto template = dependenciesFinder.getTemplate(dbSession, WsTemplateRef.fromRequest(wsRequest)); - GroupDto groupDto = dependenciesFinder.getGroup(dbSession, group); - - if (!groupAlreadyAdded(dbSession, template.getId(), groupDto, permission)) { - Long groupId = groupDto == null ? null : groupDto.getId(); - dbClient.permissionTemplateDao().insertGroupPermission(dbSession, template.getId(), groupId, permission); - } - } finally { - dbClient.closeSession(dbSession); - } - - wsResponse.noContent(); - } - - private boolean groupAlreadyAdded(DbSession dbSession, long templateId, @Nullable GroupDto group, String permission) { - String groupName = group == null ? ANYONE : group.getName(); - PermissionQuery permissionQuery = PermissionQuery.builder().membership(IN).permission(permission).build(); - return dbClient.permissionTemplateDao().hasGroup(dbSession, permissionQuery, templateId, groupName); - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/AddUserToTemplateAction.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/AddUserToTemplateAction.java deleted file mode 100644 index 16a2f53a0f9..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/AddUserToTemplateAction.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * 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 com.google.common.base.Predicate; -import java.util.List; -import org.sonar.api.server.ws.Request; -import org.sonar.api.server.ws.Response; -import org.sonar.api.server.ws.WebService; -import org.sonar.db.DbClient; -import org.sonar.db.DbSession; -import org.sonar.db.permission.PermissionQuery; -import org.sonar.db.permission.PermissionTemplateDto; -import org.sonar.db.permission.UserWithPermissionDto; -import org.sonar.db.user.UserDto; -import org.sonar.server.user.UserSession; - -import static com.google.common.collect.FluentIterable.from; -import static org.sonar.db.user.GroupMembershipQuery.IN; -import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdminUser; -import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_PERMISSION; -import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_USER_LOGIN; -import static org.sonar.server.permission.ws.WsPermissionParameters.createProjectPermissionParameter; -import static org.sonar.server.permission.ws.WsPermissionParameters.createTemplateParameters; -import static org.sonar.server.permission.ws.WsPermissionParameters.createUserLoginParameter; -import static org.sonar.server.permission.ws.PermissionRequestValidator.validateProjectPermission; - -public class AddUserToTemplateAction implements PermissionsWsAction { - private final DbClient dbClient; - private final PermissionDependenciesFinder dependenciesFinder; - private final UserSession userSession; - - public AddUserToTemplateAction(DbClient dbClient, PermissionDependenciesFinder dependenciesFinder, UserSession userSession) { - this.dbClient = dbClient; - this.dependenciesFinder = dependenciesFinder; - this.userSession = userSession; - } - - @Override - public void define(WebService.NewController context) { - WebService.NewAction action = context - .createAction("add_user_to_template") - .setPost(true) - .setSince("5.2") - .setDescription("Add a user to a permission template.
" + - "It requires administration permissions to access.") - .setHandler(this); - - createTemplateParameters(action); - createProjectPermissionParameter(action); - createUserLoginParameter(action); - } - - @Override - public void handle(Request wsRequest, Response wsResponse) throws Exception { - checkGlobalAdminUser(userSession); - - String permission = wsRequest.mandatoryParam(PARAM_PERMISSION); - final String userLogin = wsRequest.mandatoryParam(PARAM_USER_LOGIN); - - DbSession dbSession = dbClient.openSession(false); - try { - validateProjectPermission(permission); - PermissionTemplateDto template = dependenciesFinder.getTemplate(dbSession, WsTemplateRef.fromRequest(wsRequest)); - UserDto user = dependenciesFinder.getUser(dbSession, userLogin); - - if (!isUserAlreadyAdded(dbSession, template.getId(), userLogin, permission)) { - dbClient.permissionTemplateDao().insertUserPermission(dbSession, template.getId(), user.getId(), permission); - } - } finally { - dbClient.closeSession(dbSession); - } - - wsResponse.noContent(); - } - - private boolean isUserAlreadyAdded(DbSession dbSession, long templateId, String userLogin, String permission) { - PermissionQuery permissionQuery = PermissionQuery.builder().permission(permission).membership(IN).build(); - List usersWithPermission = dbClient.permissionTemplateDao().selectUsers(dbSession, permissionQuery, templateId, 0, Integer.MAX_VALUE); - return from(usersWithPermission).anyMatch(new HasUserPredicate(userLogin)); - } - - private static class HasUserPredicate implements Predicate { - private final String userLogin; - - public HasUserPredicate(String userLogin) { - this.userLogin = userLogin; - } - - @Override - public boolean apply(UserWithPermissionDto userWithPermission) { - return userLogin.equals(userWithPermission.getLogin()); - } - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/ApplyTemplateAction.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/ApplyTemplateAction.java deleted file mode 100644 index 7556a66d110..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/ApplyTemplateAction.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * 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.db.DbClient; -import org.sonar.db.DbSession; -import org.sonar.db.component.ComponentDto; -import org.sonar.db.permission.PermissionTemplateDto; -import org.sonar.server.permission.ApplyPermissionTemplateQuery; -import org.sonar.server.permission.PermissionService; - -import static java.util.Collections.singletonList; -import static org.sonar.server.permission.ws.WsPermissionParameters.createProjectParameter; -import static org.sonar.server.permission.ws.WsPermissionParameters.createTemplateParameters; - -public class ApplyTemplateAction implements PermissionsWsAction { - private final DbClient dbClient; - private final PermissionService permissionService; - private final PermissionDependenciesFinder finder; - - public ApplyTemplateAction(DbClient dbClient, PermissionService permissionService, PermissionDependenciesFinder finder) { - this.dbClient = dbClient; - this.permissionService = permissionService; - this.finder = finder; - } - - @Override - public void define(WebService.NewController context) { - WebService.NewAction action = context.createAction("apply_template") - .setDescription("Apply a permission template to one or several projects.
" + - "The project id or project key must be provided.
" + - "It requires administration permissions to access.") - .setPost(true) - .setSince("5.2") - .setHandler(this); - - createTemplateParameters(action); - createProjectParameter(action); - } - - @Override - public void handle(Request wsRequest, Response wsResponse) throws Exception { - DbSession dbSession = dbClient.openSession(false); - try { - PermissionTemplateDto template = finder.getTemplate(dbSession, WsTemplateRef.fromRequest(wsRequest)); - ComponentDto project = finder.getProject(dbSession, WsProjectRef.fromRequest(wsRequest)); - - ApplyPermissionTemplateQuery query = ApplyPermissionTemplateQuery.create( - template.getUuid(), - singletonList(project.key())); - permissionService.applyPermissionTemplate(query); - } finally { - dbClient.closeSession(dbSession); - } - - wsResponse.noContent(); - } -} 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 deleted file mode 100644 index 69f2f6fbe18..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/CreateTemplateAction.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * 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.WsPermissions.PermissionTemplate; -import org.sonarqube.ws.WsPermissions.WsCreatePermissionTemplateResponse; - -import static java.lang.String.format; -import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdminUser; -import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_DESCRIPTION; -import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_NAME; -import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_PATTERN; -import static org.sonar.server.permission.ws.WsPermissionParameters.createTemplateDescriptionParameter; -import static org.sonar.server.permission.ws.WsPermissionParameters.createTemplateProjectKeyPatternParameter; -import static org.sonar.server.permission.ws.PermissionRequestValidator.MSG_TEMPLATE_WITH_SAME_NAME; -import static org.sonar.server.permission.ws.PermissionRequestValidator.validateProjectPattern; -import static org.sonar.server.permission.ws.PermissionRequestValidator.validateTemplateNameFormat; -import static org.sonar.server.permission.ws.PermissionTemplateDtoBuilder.create; -import static org.sonar.server.permission.ws.PermissionTemplateDtoToPermissionTemplateResponse.toPermissionTemplateResponse; -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_NAME) - .setRequired(true) - .setDescription("Name") - .setExampleValue("Financial Service Permissions"); - - createTemplateProjectKeyPatternParameter(action); - createTemplateDescriptionParameter(action); - } - - @Override - public void handle(Request wsRequest, Response wsResponse) throws Exception { - String name = wsRequest.mandatoryParam(PARAM_NAME); - String description = wsRequest.param(PARAM_DESCRIPTION); - String projectPattern = wsRequest.param(PARAM_PATTERN); - - DbSession dbSession = dbClient.openSession(false); - try { - checkGlobalAdminUser(userSession); - validateTemplateNameForCreation(dbSession, name); - validateProjectPattern(projectPattern); - - PermissionTemplateDto permissionTemplate = insertTemplate(dbSession, name, description, projectPattern); - - WsCreatePermissionTemplateResponse response = buildResponse(permissionTemplate); - writeProtobuf(response, wsRequest, wsResponse); - } finally { - dbClient.closeSession(dbSession); - } - } - - private void validateTemplateNameForCreation(DbSession dbSession, String name) { - validateTemplateNameFormat(name); - - PermissionTemplateDto permissionTemplateWithSameName = dbClient.permissionTemplateDao().selectByName(dbSession, name); - checkRequest(permissionTemplateWithSameName == null, format(MSG_TEMPLATE_WITH_SAME_NAME, name)); - } - - 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 static WsCreatePermissionTemplateResponse buildResponse(PermissionTemplateDto permissionTemplateDto) { - PermissionTemplate permissionTemplateBuilder = toPermissionTemplateResponse(permissionTemplateDto); - return WsCreatePermissionTemplateResponse.newBuilder().setPermissionTemplate(permissionTemplateBuilder).build(); - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/DefaultPermissionTemplateFinder.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/DefaultPermissionTemplateFinder.java deleted file mode 100644 index d1381b44be2..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/DefaultPermissionTemplateFinder.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * 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 com.google.common.base.Function; -import java.util.List; -import java.util.Set; -import javax.annotation.Nonnull; -import org.sonar.api.config.Settings; -import org.sonar.api.resources.Qualifiers; -import org.sonar.api.resources.ResourceTypes; - -import static com.google.common.collect.FluentIterable.from; -import static com.google.common.collect.Ordering.natural; -import static org.sonar.server.permission.DefaultPermissionTemplates.DEFAULT_TEMPLATE_PROPERTY; -import static org.sonar.server.permission.DefaultPermissionTemplates.defaultRootQualifierTemplateProperty; -import static org.sonar.server.permission.ws.ResourceTypeToQualifier.RESOURCE_TYPE_TO_QUALIFIER; - -public class DefaultPermissionTemplateFinder { - private final Settings settings; - private final ResourceTypes resourceTypes; - - public DefaultPermissionTemplateFinder(Settings settings, ResourceTypes resourceTypes) { - this.settings = settings; - this.resourceTypes = resourceTypes; - } - - Set getDefaultTemplateUuids() { - return from(resourceTypes.getRoots()) - .transform(RESOURCE_TYPE_TO_QUALIFIER) - .transform(new QualifierToDefaultTemplate(settings)) - .toSortedSet(natural()); - } - - List getDefaultTemplatesByQualifier() { - return from(resourceTypes.getRoots()) - .transform(RESOURCE_TYPE_TO_QUALIFIER) - .transform(new QualifierToTemplateUuidQualifier(settings)) - .toList(); - } - - static class TemplateUuidQualifier { - private final String templateUuid; - private final String qualifier; - - TemplateUuidQualifier(String templateUuid, String qualifier) { - this.templateUuid = templateUuid; - this.qualifier = qualifier; - } - - public String getTemplateUuid() { - return templateUuid; - } - - public String getQualifier() { - return qualifier; - } - } - - private static class QualifierToDefaultTemplate implements Function { - private final Settings settings; - - QualifierToDefaultTemplate(Settings settings) { - this.settings = settings; - } - - @Override - public String apply(@Nonnull String qualifier) { - String effectiveTemplateUuid = effectiveTemplateUuid(settings, qualifier); - return effectiveTemplateUuid; - } - } - - private static class QualifierToTemplateUuidQualifier implements Function { - private final Settings settings; - - QualifierToTemplateUuidQualifier(Settings settings) { - this.settings = settings; - } - - @Override - public TemplateUuidQualifier apply(@Nonnull String qualifier) { - String effectiveTemplateUuid = effectiveTemplateUuid(settings, qualifier); - - return new TemplateUuidQualifier(effectiveTemplateUuid, qualifier); - } - } - - private static String effectiveTemplateUuid(Settings settings, String qualifier) { - String qualifierTemplateUuid = settings.getString(defaultRootQualifierTemplateProperty(qualifier)); - String projectTemplateUuid = settings.getString(defaultRootQualifierTemplateProperty(Qualifiers.PROJECT)); - String defaultTemplateUuid = settings.getString(DEFAULT_TEMPLATE_PROPERTY); - - if (qualifierTemplateUuid != null) { - return qualifierTemplateUuid; - } else if (projectTemplateUuid != null) { - return projectTemplateUuid; - } else { - return defaultTemplateUuid; - } - } - -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/DeleteTemplateAction.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/DeleteTemplateAction.java index 4acc8fcdff6..4813560a92c 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/DeleteTemplateAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/DeleteTemplateAction.java @@ -27,6 +27,7 @@ import org.sonar.api.server.ws.WebService; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.permission.PermissionTemplateDto; +import org.sonar.server.permission.ws.template.DefaultPermissionTemplateFinder; import org.sonar.server.user.UserSession; import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdminUser; diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionChangeBuilder.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionChangeBuilder.java index 2049200bbe4..3418bfe0413 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionChangeBuilder.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionChangeBuilder.java @@ -33,7 +33,7 @@ public class PermissionChangeBuilder { this.dependenciesFinder = dependenciesFinder; } - PermissionChange buildUserPermissionChange(DbSession dbSession, PermissionRequest request) { + public PermissionChange buildUserPermissionChange(DbSession dbSession, PermissionRequest request) { PermissionChange permissionChange = new PermissionChange() .setPermission(request.permission()) .setUserLogin(request.userLogin()); @@ -42,7 +42,7 @@ public class PermissionChangeBuilder { return permissionChange; } - PermissionChange buildGroupPermissionChange(DbSession dbSession, PermissionRequest request) { + public PermissionChange buildGroupPermissionChange(DbSession dbSession, PermissionRequest request) { String groupName = dependenciesFinder.getGroupName(dbSession, request); PermissionChange permissionChange = new PermissionChange() diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionDependenciesFinder.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionDependenciesFinder.java index fd56efbd8b0..9838e66f733 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionDependenciesFinder.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionDependenciesFinder.java @@ -47,7 +47,7 @@ public class PermissionDependenciesFinder { /** * @throws org.sonar.server.exceptions.NotFoundException if a project identifier is provided but it's not found */ - Optional searchProject(DbSession dbSession, PermissionRequest request) { + public Optional searchProject(DbSession dbSession, PermissionRequest request) { if (!request.project().isPresent()) { return Optional.absent(); } @@ -56,11 +56,11 @@ public class PermissionDependenciesFinder { return Optional.of(componentFinder.getProjectByUuidOrKey(dbSession, wsProjectRef.uuid(), wsProjectRef.key())); } - ComponentDto getProject(DbSession dbSession, WsProjectRef projectRef) { + public ComponentDto getProject(DbSession dbSession, WsProjectRef projectRef) { return componentFinder.getProjectByUuidOrKey(dbSession, projectRef.uuid(), projectRef.key()); } - String getGroupName(DbSession dbSession, PermissionRequest request) { + public String getGroupName(DbSession dbSession, PermissionRequest request) { GroupDto group = getGroup(dbSession, request.group()); return group == null ? ANYONE : group.getName(); @@ -71,7 +71,7 @@ public class PermissionDependenciesFinder { * @return null if it's the anyone group */ @CheckForNull - GroupDto getGroup(DbSession dbSession, WsGroupRef group) { + public GroupDto getGroup(DbSession dbSession, WsGroupRef group) { Long groupId = group.id(); String groupName = group.name(); @@ -94,12 +94,12 @@ public class PermissionDependenciesFinder { return groupDto; } - UserDto getUser(DbSession dbSession, String userLogin) { + public UserDto getUser(DbSession dbSession, String userLogin) { return checkFound(dbClient.userDao().selectActiveUserByLogin(dbSession, userLogin), format("User with login '%s' is not found'", userLogin)); } - PermissionTemplateDto getTemplate(DbSession dbSession, WsTemplateRef template) { + public PermissionTemplateDto getTemplate(DbSession dbSession, WsTemplateRef template) { if (template.uuid() != null) { return checkFound(dbClient.permissionTemplateDao().selectByUuid(dbSession, template.uuid()), format("Permission template with id '%s' is not found", template.uuid())); diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionQueryParser.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionQueryParser.java index 27f2c9b58c1..8f39e643329 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionQueryParser.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionQueryParser.java @@ -29,7 +29,7 @@ class PermissionQueryParser { // Utility class } - static String fromSelectionModeToMembership(String selectionModeString) { + public static String fromSelectionModeToMembership(String selectionModeString) { SelectionMode selectionMode = SelectionMode.fromParam(selectionModeString); if (SelectionMode.SELECTED == selectionMode) { return GroupMembershipQuery.IN; diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionRequest.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionRequest.java index fcce33c3cd9..11e48d6b1be 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionRequest.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionRequest.java @@ -54,7 +54,7 @@ class PermissionRequest { query = builder.query; } - static class Builder { + public static class Builder { private final Request request; @@ -72,7 +72,7 @@ class PermissionRequest { private String selected; private String query; - Builder(Request request) { + public Builder(Request request) { this.request = request; } @@ -89,17 +89,17 @@ class PermissionRequest { return new PermissionRequest(this); } - Builder withUser() { + public Builder withUser() { this.withUser = true; return this; } - Builder withGroup() { + public Builder withGroup() { this.withGroup = true; return this; } - Builder withPagination() { + public Builder withPagination() { this.withPagination = true; return this; } @@ -151,35 +151,35 @@ class PermissionRequest { } } - String permission() { + public String permission() { return permission; } - String userLogin() { + public String userLogin() { return userLogin; } - WsGroupRef group() { + public WsGroupRef group() { return group; } - Optional project() { + public Optional project() { return project; } - Integer page() { + public Integer page() { return page; } - Integer pageSize() { + public Integer pageSize() { return pageSize; } - String selected() { + public String selected() { return selected; } - String query() { + public String query() { return query; } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionTemplateDtoBuilder.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionTemplateDtoBuilder.java deleted file mode 100644 index 55702eb799d..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionTemplateDtoBuilder.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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 java.util.Date; -import org.sonar.api.utils.System2; -import org.sonar.core.util.Uuids; -import org.sonar.db.permission.PermissionTemplateDto; - -class PermissionTemplateDtoBuilder { - private final System2 system; - private String name; - private String description; - private String projectKeyPattern; - - private PermissionTemplateDtoBuilder(System2 system) { - this.system = system; - } - - static PermissionTemplateDtoBuilder create(System2 system) { - return new PermissionTemplateDtoBuilder(system); - } - - PermissionTemplateDtoBuilder setName(String name) { - this.name = name; - return this; - } - - PermissionTemplateDtoBuilder setDescription(String description) { - this.description = description; - return this; - } - - PermissionTemplateDtoBuilder setProjectKeyPattern(String projectKeyPattern) { - this.projectKeyPattern = projectKeyPattern; - return this; - } - - PermissionTemplateDto toDto() { - long now = system.now(); - return new PermissionTemplateDto() - .setName(name) - .setDescription(description) - .setKeyPattern(projectKeyPattern) - .setKee(Uuids.create()) - .setCreatedAt(new Date(now)) - .setUpdatedAt(new Date(now)); - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionTemplateDtoToPermissionTemplateResponse.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionTemplateDtoToPermissionTemplateResponse.java deleted file mode 100644 index 1b9be42037c..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionTemplateDtoToPermissionTemplateResponse.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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 com.google.common.base.Function; -import javax.annotation.Nonnull; -import org.sonar.api.utils.DateUtils; -import org.sonar.db.permission.PermissionTemplateDto; -import org.sonarqube.ws.WsPermissions.PermissionTemplate; - -class PermissionTemplateDtoToPermissionTemplateResponse { - - static PermissionTemplate toPermissionTemplateResponse(PermissionTemplateDto dto) { - return Singleton.INSTANCE.apply(dto); - } - - private enum Singleton implements Function { - INSTANCE; - @Override - public PermissionTemplate apply(@Nonnull PermissionTemplateDto permissionTemplate) { - PermissionTemplate.Builder permissionTemplateBuilder = PermissionTemplate.newBuilder() - .setId(permissionTemplate.getKee()) - .setName(permissionTemplate.getName()) - .setCreatedAt(DateUtils.formatDateTime(permissionTemplate.getCreatedAt())) - .setUpdatedAt(DateUtils.formatDateTime(permissionTemplate.getUpdatedAt())); - if (permissionTemplate.getDescription() != null) { - permissionTemplateBuilder.setDescription(permissionTemplate.getDescription()); - } - if (permissionTemplate.getKeyPattern() != null) { - permissionTemplateBuilder.setProjectKeyPattern(permissionTemplate.getKeyPattern()); - } - return permissionTemplateBuilder.build(); - } - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionsWsModule.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionsWsModule.java index 9f9ed0213dc..957ef41e692 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionsWsModule.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionsWsModule.java @@ -21,6 +21,17 @@ package org.sonar.server.permission.ws; import org.sonar.core.platform.Module; +import org.sonar.server.permission.ws.template.AddGroupToTemplateAction; +import org.sonar.server.permission.ws.template.AddUserToTemplateAction; +import org.sonar.server.permission.ws.template.ApplyTemplateAction; +import org.sonar.server.permission.ws.template.CreateTemplateAction; +import org.sonar.server.permission.ws.template.DefaultPermissionTemplateFinder; +import org.sonar.server.permission.ws.template.RemoveGroupFromTemplateAction; +import org.sonar.server.permission.ws.template.RemoveUserFromTemplateAction; +import org.sonar.server.permission.ws.template.SearchTemplatesAction; +import org.sonar.server.permission.ws.template.SearchTemplatesDataLoader; +import org.sonar.server.permission.ws.template.SetDefaultTemplateAction; +import org.sonar.server.permission.ws.template.UpdateTemplateAction; public class PermissionsWsModule extends Module { @Override diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/RemoveGroupFromTemplateAction.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/RemoveGroupFromTemplateAction.java deleted file mode 100644 index 36614093345..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/RemoveGroupFromTemplateAction.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * 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.db.DbClient; -import org.sonar.db.DbSession; -import org.sonar.db.permission.PermissionTemplateDto; -import org.sonar.db.user.GroupDto; -import org.sonar.server.user.UserSession; - -import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdminUser; -import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_PERMISSION; -import static org.sonar.server.permission.ws.WsPermissionParameters.createGroupIdParameter; -import static org.sonar.server.permission.ws.WsPermissionParameters.createGroupNameParameter; -import static org.sonar.server.permission.ws.WsPermissionParameters.createProjectPermissionParameter; -import static org.sonar.server.permission.ws.WsPermissionParameters.createTemplateParameters; -import static org.sonar.server.permission.ws.PermissionRequestValidator.validateProjectPermission; - -public class RemoveGroupFromTemplateAction implements PermissionsWsAction { - private final DbClient dbClient; - private final PermissionDependenciesFinder dependenciesFinder; - private final UserSession userSession; - - public RemoveGroupFromTemplateAction(DbClient dbClient, PermissionDependenciesFinder dependenciesFinder, UserSession userSession) { - this.dbClient = dbClient; - this.dependenciesFinder = dependenciesFinder; - this.userSession = userSession; - } - - @Override - public void define(WebService.NewController context) { - WebService.NewAction action = context - .createAction("remove_group_from_template") - .setPost(true) - .setSince("5.2") - .setDescription("Remove a group from a permission template.
" + - "The group id or group name must be provided.
" + - "It requires administration permissions to access.") - .setHandler(this); - - createTemplateParameters(action); - createProjectPermissionParameter(action); - createGroupIdParameter(action); - createGroupNameParameter(action); - } - - @Override - public void handle(Request wsRequest, Response wsResponse) throws Exception { - checkGlobalAdminUser(userSession); - - String permission = wsRequest.mandatoryParam(PARAM_PERMISSION); - WsGroupRef group = WsGroupRef.fromRequest(wsRequest); - - DbSession dbSession = dbClient.openSession(false); - try { - validateProjectPermission(permission); - - PermissionTemplateDto template = dependenciesFinder.getTemplate(dbSession, WsTemplateRef.fromRequest(wsRequest)); - GroupDto groupDto = dependenciesFinder.getGroup(dbSession, group); - - Long groupId = groupDto == null ? null : groupDto.getId(); - dbClient.permissionTemplateDao().deleteGroupPermission(dbSession, template.getId(), groupId, permission); - } finally { - dbClient.closeSession(dbSession); - } - - wsResponse.noContent(); - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/RemoveUserFromTemplateAction.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/RemoveUserFromTemplateAction.java deleted file mode 100644 index dd22e79b2a2..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/RemoveUserFromTemplateAction.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * 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.db.DbClient; -import org.sonar.db.DbSession; -import org.sonar.db.permission.PermissionTemplateDto; -import org.sonar.db.user.UserDto; -import org.sonar.server.user.UserSession; - -import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdminUser; -import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_PERMISSION; -import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_USER_LOGIN; -import static org.sonar.server.permission.ws.WsPermissionParameters.createProjectPermissionParameter; -import static org.sonar.server.permission.ws.WsPermissionParameters.createTemplateParameters; -import static org.sonar.server.permission.ws.WsPermissionParameters.createUserLoginParameter; -import static org.sonar.server.permission.ws.PermissionRequestValidator.validateProjectPermission; - -public class RemoveUserFromTemplateAction implements PermissionsWsAction { - private final DbClient dbClient; - private final PermissionDependenciesFinder dependenciesFinder; - private final UserSession userSession; - - public RemoveUserFromTemplateAction(DbClient dbClient, PermissionDependenciesFinder dependenciesFinder, UserSession userSession) { - this.dbClient = dbClient; - this.dependenciesFinder = dependenciesFinder; - this.userSession = userSession; - } - - @Override - public void define(WebService.NewController context) { - WebService.NewAction action = context - .createAction("remove_user_from_template") - .setPost(true) - .setSince("5.2") - .setDescription("Remove a user from a permission template.
" + - "It requires administration permissions to access.") - .setHandler(this); - - createTemplateParameters(action); - createProjectPermissionParameter(action); - createUserLoginParameter(action); - } - - @Override - public void handle(Request wsRequest, Response wsResponse) throws Exception { - checkGlobalAdminUser(userSession); - - String permission = wsRequest.mandatoryParam(PARAM_PERMISSION); - String userLogin = wsRequest.mandatoryParam(PARAM_USER_LOGIN); - - DbSession dbSession = dbClient.openSession(false); - try { - validateProjectPermission(permission); - PermissionTemplateDto template = dependenciesFinder.getTemplate(dbSession, WsTemplateRef.fromRequest(wsRequest)); - UserDto user = dependenciesFinder.getUser(dbSession, userLogin); - - dbClient.permissionTemplateDao().deleteUserPermission(dbSession, template.getId(), user.getId(), permission); - dbSession.commit(); - } finally { - dbClient.closeSession(dbSession); - } - - wsResponse.noContent(); - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/ResourceTypeToQualifier.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/ResourceTypeToQualifier.java index a751be79838..8c850cbd33d 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/ResourceTypeToQualifier.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/ResourceTypeToQualifier.java @@ -24,9 +24,9 @@ import com.google.common.base.Function; import javax.annotation.Nonnull; import org.sonar.api.resources.ResourceType; -class ResourceTypeToQualifier { +public class ResourceTypeToQualifier { - static final Function RESOURCE_TYPE_TO_QUALIFIER = Singleton.INSTANCE; + public static final Function RESOURCE_TYPE_TO_QUALIFIER = Singleton.INSTANCE; private enum Singleton implements Function { INSTANCE; diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/SearchProjectPermissionsDataLoader.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/SearchProjectPermissionsDataLoader.java index a3785a78598..a8489228ae6 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/SearchProjectPermissionsDataLoader.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/SearchProjectPermissionsDataLoader.java @@ -58,7 +58,7 @@ public class SearchProjectPermissionsDataLoader { this.rootQualifiers = Collections2.transform(resourceTypes.getRoots(), RESOURCE_TYPE_TO_QUALIFIER); } - public SearchProjectPermissionsData load(Request wsRequest) { + SearchProjectPermissionsData load(Request wsRequest) { DbSession dbSession = dbClient.openSession(false); try { SearchProjectPermissionsData.Builder data = newBuilder(); diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/SearchTemplatesAction.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/SearchTemplatesAction.java deleted file mode 100644 index 87abcb2ee08..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/SearchTemplatesAction.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * 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.i18n.I18n; -import org.sonar.api.server.ws.Request; -import org.sonar.api.server.ws.Response; -import org.sonar.api.server.ws.WebService; -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.user.UserSession; -import org.sonarqube.ws.WsPermissions.Permission; -import org.sonarqube.ws.WsPermissions.PermissionTemplate; -import org.sonarqube.ws.WsPermissions.WsSearchTemplatesResponse; -import org.sonarqube.ws.WsPermissions.WsSearchTemplatesResponse.TemplateIdQualifier; - -import static org.sonar.api.utils.DateUtils.formatDateTime; -import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdminUser; -import static org.sonar.server.ws.WsUtils.writeProtobuf; - -public class SearchTemplatesAction implements PermissionsWsAction { - private static final String PROPERTY_PREFIX = "projects_role."; - private static final String DESCRIPTION_SUFFIX = ".desc"; - - private final DbClient dbClient; - private final UserSession userSession; - private final I18n i18n; - private final SearchTemplatesDataLoader dataLoader; - - public SearchTemplatesAction(DbClient dbClient, UserSession userSession, I18n i18n, SearchTemplatesDataLoader dataLoader) { - this.dbClient = dbClient; - this.userSession = userSession; - this.i18n = i18n; - this.dataLoader = dataLoader; - } - - @Override - public void define(WebService.NewController context) { - context.createAction("search_templates") - .setDescription("List permission templates.
" + - "It requires administration permissions to access.") - .setResponseExample(getClass().getResource("search_templates-example.json")) - .setSince("5.2") - .addSearchQuery("defau", "permission template names") - .setHandler(this); - } - - @Override - public void handle(Request wsRequest, Response wsResponse) throws Exception { - checkGlobalAdminUser(userSession); - - DbSession dbSession = dbClient.openSession(false); - try { - SearchTemplatesData data = dataLoader.load(wsRequest); - WsSearchTemplatesResponse response = buildResponse(data); - writeProtobuf(response, wsRequest, wsResponse); - } finally { - dbClient.closeSession(dbSession); - } - } - - private WsSearchTemplatesResponse buildResponse(SearchTemplatesData data) { - WsSearchTemplatesResponse.Builder response = WsSearchTemplatesResponse.newBuilder(); - - buildTemplatesResponse(response, data); - buildDefaultTemplatesResponse(response, data); - buildPermissionsResponse(response); - - return response.build(); - } - - private static void buildDefaultTemplatesResponse(WsSearchTemplatesResponse.Builder response, SearchTemplatesData data) { - TemplateIdQualifier.Builder templateUuidQualifierBuilder = TemplateIdQualifier.newBuilder(); - for (DefaultPermissionTemplateFinder.TemplateUuidQualifier templateUuidQualifier : data.defaultTempltes()) { - response.addDefaultTemplates(templateUuidQualifierBuilder - .clear() - .setQualifier(templateUuidQualifier.getQualifier()) - .setTemplateId(templateUuidQualifier.getTemplateUuid())); - } - } - - private static void buildTemplatesResponse(WsSearchTemplatesResponse.Builder response, SearchTemplatesData data) { - Permission.Builder permissionResponse = Permission.newBuilder(); - PermissionTemplate.Builder templateBuilder = PermissionTemplate.newBuilder(); - - for (PermissionTemplateDto templateDto : data.templates()) { - templateBuilder - .clear() - .setId(templateDto.getUuid()) - .setName(templateDto.getName()) - .setCreatedAt(formatDateTime(templateDto.getCreatedAt())) - .setUpdatedAt(formatDateTime(templateDto.getUpdatedAt())); - if (templateDto.getKeyPattern() != null) { - templateBuilder.setProjectKeyPattern(templateDto.getKeyPattern()); - } - if (templateDto.getDescription() != null) { - templateBuilder.setDescription(templateDto.getDescription()); - } - for (String permission : data.permissions(templateDto.getId())) { - templateBuilder.addPermissions( - permissionResponse - .clear() - .setKey(permission) - .setUsersCount(data.userCount(templateDto.getId(), permission)) - .setGroupsCount(data.groupCount(templateDto.getId(), permission))); - } - response.addPermissionTemplates(templateBuilder); - } - } - - private void buildPermissionsResponse(WsSearchTemplatesResponse.Builder response) { - Permission.Builder permissionResponse = Permission.newBuilder(); - for (String permissionKey : ProjectPermissions.ALL) { - response.addPermissions( - permissionResponse - .clear() - .setKey(permissionKey) - .setName(i18nName(permissionKey)) - .setDescription(i18nDescriptionMessage(permissionKey)) - ); - } - } - - private String i18nDescriptionMessage(String permissionKey) { - return i18n.message(userSession.locale(), PROPERTY_PREFIX + permissionKey + DESCRIPTION_SUFFIX, ""); - } - - private String i18nName(String permissionKey) { - return i18n.message(userSession.locale(), PROPERTY_PREFIX + permissionKey, permissionKey); - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/SearchTemplatesData.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/SearchTemplatesData.java deleted file mode 100644 index dac2868fca4..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/SearchTemplatesData.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * 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 com.google.common.collect.FluentIterable; -import com.google.common.collect.Iterables; -import com.google.common.collect.Table; -import java.util.List; -import java.util.Set; -import org.sonar.db.permission.PermissionTemplateDto; -import org.sonar.server.permission.ws.DefaultPermissionTemplateFinder.TemplateUuidQualifier; - -import static com.google.common.base.Objects.firstNonNull; -import static com.google.common.base.Preconditions.checkState; -import static com.google.common.collect.ImmutableList.copyOf; -import static com.google.common.collect.ImmutableTable.copyOf; -import static com.google.common.collect.Ordering.natural; - -class SearchTemplatesData { - private final List templates; - private final List defaultTemplates; - private final Table userCountByTemplateIdAndPermission; - private final Table groupCountByTemplateIdAndPermission; - - private SearchTemplatesData(Builder builder) { - this.templates = copyOf(builder.templates); - this.defaultTemplates = copyOf(builder.defaultTemplates); - this.userCountByTemplateIdAndPermission = copyOf(builder.userCountByTemplateIdAndPermission); - this.groupCountByTemplateIdAndPermission = copyOf(builder.groupCountByTemplateIdAndPermission); - } - - public static Builder newBuilder() { - return new Builder(); - } - - public List templates() { - return templates; - } - - public List defaultTempltes() { - return defaultTemplates; - } - - public int userCount(long templateId, String permission) { - return firstNonNull(userCountByTemplateIdAndPermission.get(templateId, permission), 0); - } - - public int groupCount(long templateId, String permission) { - return firstNonNull(groupCountByTemplateIdAndPermission.get(templateId, permission), 0); - } - - public Set permissions(long templateId) { - return FluentIterable.from( - Iterables.concat( - userCountByTemplateIdAndPermission.row(templateId).keySet(), - groupCountByTemplateIdAndPermission.row(templateId).keySet() - ) - ).toSortedSet(natural()); - } - - public static class Builder { - private List templates; - private List defaultTemplates; - private Table userCountByTemplateIdAndPermission; - private Table groupCountByTemplateIdAndPermission; - - private Builder() { - // prevents instantiation outside main class - } - - public SearchTemplatesData build() { - checkState(templates != null); - checkState(defaultTemplates != null); - checkState(userCountByTemplateIdAndPermission != null); - checkState(groupCountByTemplateIdAndPermission != null); - - return new SearchTemplatesData(this); - } - - public Builder templates(List templates) { - this.templates = templates; - return this; - } - - public Builder defaultTemplates(List defaultTemplates) { - this.defaultTemplates = defaultTemplates; - return this; - } - - public Builder userCountByTemplateIdAndPermission(Table userCountByTemplateIdAndPermission) { - this.userCountByTemplateIdAndPermission = userCountByTemplateIdAndPermission; - return this; - } - - public Builder groupCountByTemplateIdAndPermission(Table groupCountByTemplateIdAndPermission) { - this.groupCountByTemplateIdAndPermission = groupCountByTemplateIdAndPermission; - return this; - } - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/SearchTemplatesDataLoader.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/SearchTemplatesDataLoader.java deleted file mode 100644 index 79a2984efdc..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/SearchTemplatesDataLoader.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * 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 com.google.common.base.Function; -import com.google.common.collect.Lists; -import com.google.common.collect.Table; -import com.google.common.collect.TreeBasedTable; -import java.util.List; -import javax.annotation.Nonnull; -import org.apache.ibatis.session.ResultContext; -import org.apache.ibatis.session.ResultHandler; -import org.sonar.api.server.ws.Request; -import org.sonar.db.DbClient; -import org.sonar.db.DbSession; -import org.sonar.db.permission.CountByTemplateAndPermissionDto; -import org.sonar.db.permission.PermissionTemplateDto; -import org.sonar.server.permission.ws.DefaultPermissionTemplateFinder.TemplateUuidQualifier; - -import static org.sonar.api.server.ws.WebService.Param.TEXT_QUERY; -import static org.sonar.server.permission.ws.SearchTemplatesData.newBuilder; - -public class SearchTemplatesDataLoader { - private final DbClient dbClient; - private final DefaultPermissionTemplateFinder defaultPermissionTemplateFinder; - - public SearchTemplatesDataLoader(DbClient dbClient, DefaultPermissionTemplateFinder defaultPermissionTemplateFinder) { - this.dbClient = dbClient; - this.defaultPermissionTemplateFinder = defaultPermissionTemplateFinder; - } - - public SearchTemplatesData load(Request wsRequest) { - DbSession dbSession = dbClient.openSession(false); - try { - SearchTemplatesData.Builder data = newBuilder(); - List templates = searchTemplates(dbSession, wsRequest); - List templateIds = Lists.transform(templates, TemplateToIdFunction.INSTANCE); - List defaultTemplates = defaultPermissionTemplateFinder.getDefaultTemplatesByQualifier(); - - data.templates(templates) - .defaultTemplates(defaultTemplates) - .userCountByTemplateIdAndPermission(userCountByTemplateIdAndPermission(dbSession, templateIds)) - .groupCountByTemplateIdAndPermission(groupCountByTemplateIdAndPermission(dbSession, templateIds)); - - return data.build(); - } finally { - dbClient.closeSession(dbSession); - } - } - - private List searchTemplates(DbSession dbSession, Request wsRequest) { - String nameMatch = wsRequest.param(TEXT_QUERY); - - return nameMatch == null ? - dbClient.permissionTemplateDao().selectAll(dbSession) - : dbClient.permissionTemplateDao().selectAll(dbSession, nameMatch); - } - - private Table userCountByTemplateIdAndPermission(DbSession dbSession, List templateIds) { - final Table userCountByTemplateIdAndPermission = TreeBasedTable.create(); - - dbClient.permissionTemplateDao().usersCountByTemplateIdAndPermission(dbSession, templateIds, new ResultHandler() { - @Override - public void handleResult(ResultContext context) { - CountByTemplateAndPermissionDto row = (CountByTemplateAndPermissionDto) context.getResultObject(); - userCountByTemplateIdAndPermission.put(row.getTemplateId(), row.getPermission(), row.getCount()); - } - }); - - return userCountByTemplateIdAndPermission; - } - - private Table groupCountByTemplateIdAndPermission(DbSession dbSession, List templateIds) { - final Table userCountByTemplateIdAndPermission = TreeBasedTable.create(); - - dbClient.permissionTemplateDao().groupsCountByTemplateIdAndPermission(dbSession, templateIds, new ResultHandler() { - @Override - public void handleResult(ResultContext context) { - CountByTemplateAndPermissionDto row = (CountByTemplateAndPermissionDto) context.getResultObject(); - userCountByTemplateIdAndPermission.put(row.getTemplateId(), row.getPermission(), row.getCount()); - } - }); - - return userCountByTemplateIdAndPermission; - } - - private enum TemplateToIdFunction implements Function { - INSTANCE; - - @Override - public Long apply(@Nonnull PermissionTemplateDto template) { - return template.getId(); - } - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/SetDefaultTemplateAction.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/SetDefaultTemplateAction.java deleted file mode 100644 index 79a54ed1e78..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/SetDefaultTemplateAction.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * 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 java.util.Set; -import org.sonar.api.i18n.I18n; -import org.sonar.api.resources.Qualifiers; -import org.sonar.api.resources.ResourceTypes; -import org.sonar.api.server.ws.Request; -import org.sonar.api.server.ws.Response; -import org.sonar.api.server.ws.WebService; -import org.sonar.db.DbClient; -import org.sonar.db.DbSession; -import org.sonar.db.permission.PermissionTemplateDto; -import org.sonar.server.platform.PersistentSettings; -import org.sonar.server.user.UserSession; - -import static com.google.common.collect.FluentIterable.from; -import static com.google.common.collect.Ordering.natural; -import static java.lang.String.format; -import static org.sonar.server.permission.DefaultPermissionTemplates.defaultRootQualifierTemplateProperty; -import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdminUser; -import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_QUALIFIER; -import static org.sonar.server.permission.ws.WsPermissionParameters.createTemplateParameters; -import static org.sonar.server.permission.ws.PermissionRequestValidator.validateQualifier; -import static org.sonar.server.permission.ws.ResourceTypeToQualifier.RESOURCE_TYPE_TO_QUALIFIER; - -public class SetDefaultTemplateAction implements PermissionsWsAction { - private final DbClient dbClient; - private final PermissionDependenciesFinder finder; - private final ResourceTypes resourceTypes; - private final PersistentSettings settings; - private final UserSession userSession; - private final I18n i18n; - - public SetDefaultTemplateAction(DbClient dbClient, PermissionDependenciesFinder finder, ResourceTypes resourceTypes, PersistentSettings settings, UserSession userSession, - I18n i18n) { - this.dbClient = dbClient; - this.finder = finder; - this.resourceTypes = resourceTypes; - this.settings = settings; - this.userSession = userSession; - this.i18n = i18n; - } - - @Override - public void define(WebService.NewController context) { - WebService.NewAction action = context.createAction("set_default_template") - .setDescription("Set a permission template as default.
" + - "It requires administration permissions to access.") - .setPost(true) - .setSince("5.2") - .setHandler(this); - - createTemplateParameters(action); - - action.createParam(PARAM_QUALIFIER) - .setDescription("Project qualifier. Possible values are:" + buildRootQualifiersDescription()) - .setDefaultValue(Qualifiers.PROJECT) - .setPossibleValues(getRootQualifiers()); - } - - @Override - public void handle(Request wsRequest, Response wsResponse) throws Exception { - checkGlobalAdminUser(userSession); - - String qualifier = wsRequest.mandatoryParam(PARAM_QUALIFIER); - - PermissionTemplateDto template = getTemplate(wsRequest); - validateQualifier(qualifier, getRootQualifiers()); - setDefaultTemplateUuid(template.getUuid(), qualifier); - wsResponse.noContent(); - } - - private Set getRootQualifiers() { - return from(resourceTypes.getRoots()) - .transform(RESOURCE_TYPE_TO_QUALIFIER) - .toSortedSet(natural()); - } - - private String buildRootQualifiersDescription() { - StringBuilder description = new StringBuilder(); - description.append("
    "); - String qualifierPattern = "
  • %s - %s
  • "; - for (String qualifier : getRootQualifiers()) { - description.append(format(qualifierPattern, qualifier, i18n(qualifier))); - } - description.append("
"); - - return description.toString(); - } - - private String i18n(String qualifier) { - String qualifiersPropertyPrefix = "qualifiers."; - return i18n.message(userSession.locale(), qualifiersPropertyPrefix + qualifier, ""); - } - - private PermissionTemplateDto getTemplate(Request wsRequest) { - DbSession dbSession = dbClient.openSession(false); - try { - return finder.getTemplate(dbSession, WsTemplateRef.fromRequest(wsRequest)); - } finally { - dbClient.closeSession(dbSession); - } - } - - private void setDefaultTemplateUuid(String templateUuid, String qualifier) { - settings.saveProperty(defaultRootQualifierTemplateProperty(qualifier), templateUuid); - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/UpdateTemplateAction.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/UpdateTemplateAction.java deleted file mode 100644 index d7ba4b5b0f5..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/UpdateTemplateAction.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * 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 java.util.Date; -import javax.annotation.Nullable; -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.WsPermissions.PermissionTemplate; -import org.sonarqube.ws.WsPermissions.WsUpdatePermissionTemplateResponse; - -import static com.google.common.base.Objects.firstNonNull; -import static java.lang.String.format; -import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdminUser; -import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_ID; -import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_DESCRIPTION; -import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_NAME; -import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_PATTERN; -import static org.sonar.server.permission.ws.WsPermissionParameters.createIdParameter; -import static org.sonar.server.permission.ws.WsPermissionParameters.createTemplateDescriptionParameter; -import static org.sonar.server.permission.ws.WsPermissionParameters.createTemplateProjectKeyPatternParameter; -import static org.sonar.server.permission.ws.PermissionRequestValidator.MSG_TEMPLATE_WITH_SAME_NAME; -import static org.sonar.server.permission.ws.PermissionRequestValidator.validateProjectPattern; -import static org.sonar.server.permission.ws.PermissionRequestValidator.validateTemplateNameFormat; -import static org.sonar.server.permission.ws.PermissionTemplateDtoToPermissionTemplateResponse.toPermissionTemplateResponse; -import static org.sonar.server.ws.WsUtils.checkRequest; -import static org.sonar.server.ws.WsUtils.writeProtobuf; - -public class UpdateTemplateAction implements PermissionsWsAction { - private final DbClient dbClient; - private final UserSession userSession; - private final System2 system; - private final PermissionDependenciesFinder finder; - - public UpdateTemplateAction(DbClient dbClient, UserSession userSession, System2 system, PermissionDependenciesFinder finder) { - this.dbClient = dbClient; - this.userSession = userSession; - this.system = system; - this.finder = finder; - } - - @Override - public void define(WebService.NewController context) { - WebService.NewAction action = context.createAction("update_template") - .setDescription("Update a permission template.
" + - "It requires administration permissions to access.") - .setResponseExample(getClass().getResource("update_template-example.json")) - .setSince("5.2") - .setPost(true) - .setHandler(this); - - createIdParameter(action); - - action.createParam(PARAM_NAME) - .setDescription("Name") - .setExampleValue("Financial Service Permissions"); - - createTemplateProjectKeyPatternParameter(action); - createTemplateDescriptionParameter(action); - } - - @Override - public void handle(Request wsRequest, Response wsResponse) throws Exception { - checkGlobalAdminUser(userSession); - - String uuid = wsRequest.mandatoryParam(PARAM_ID); - String nameParam = wsRequest.param(PARAM_NAME); - String descriptionParam = wsRequest.param(PARAM_DESCRIPTION); - String projectPatternParam = wsRequest.param(PARAM_PATTERN); - - DbSession dbSession = dbClient.openSession(false); - try { - PermissionTemplateDto templateToUpdate = getAndBuildTemplateToUpdate(dbSession, uuid, nameParam, descriptionParam, projectPatternParam); - validateTemplate(dbSession, templateToUpdate); - PermissionTemplateDto updatedTemplate = updateTemplate(dbSession, templateToUpdate); - - WsUpdatePermissionTemplateResponse response = buildResponse(updatedTemplate); - writeProtobuf(response, wsRequest, wsResponse); - } finally { - dbClient.closeSession(dbSession); - } - } - - private void validateTemplate(DbSession dbSession, PermissionTemplateDto templateToUpdate) { - validateTemplateNameForUpdate(dbSession, templateToUpdate.getName(), templateToUpdate.getId()); - validateProjectPattern(templateToUpdate.getKeyPattern()); - } - - private PermissionTemplateDto getAndBuildTemplateToUpdate(DbSession dbSession, String uuid, @Nullable String newName, @Nullable String newDescription, - @Nullable String newProjectKeyPattern) { - PermissionTemplateDto templateToUpdate = finder.getTemplate(dbSession, WsTemplateRef.newTemplateRef(uuid, null)); - templateToUpdate.setName(firstNonNull(newName, templateToUpdate.getName())); - templateToUpdate.setDescription(firstNonNull(newDescription, templateToUpdate.getDescription())); - templateToUpdate.setKeyPattern(firstNonNull(newProjectKeyPattern, templateToUpdate.getKeyPattern())); - templateToUpdate.setUpdatedAt(new Date(system.now())); - - return templateToUpdate; - } - - private PermissionTemplateDto updateTemplate(DbSession dbSession, PermissionTemplateDto templateToUpdate) { - return dbClient.permissionTemplateDao().update(dbSession, templateToUpdate); - } - - private static WsUpdatePermissionTemplateResponse buildResponse(PermissionTemplateDto permissionTemplate) { - PermissionTemplate permissionTemplateBuilder = toPermissionTemplateResponse(permissionTemplate); - return WsUpdatePermissionTemplateResponse.newBuilder().setPermissionTemplate(permissionTemplateBuilder).build(); - } - - private void validateTemplateNameForUpdate(DbSession dbSession, String name, long id) { - validateTemplateNameFormat(name); - - PermissionTemplateDto permissionTemplateWithSameName = dbClient.permissionTemplateDao().selectByName(dbSession, name); - checkRequest(permissionTemplateWithSameName == null || permissionTemplateWithSameName.getId() == id, - format(MSG_TEMPLATE_WITH_SAME_NAME, name)); - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/WsGroupRef.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/WsGroupRef.java index 2c735193a12..329b2d4f665 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/WsGroupRef.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/WsGroupRef.java @@ -31,7 +31,7 @@ import static org.sonar.server.ws.WsUtils.checkRequest; /** * Group from a WS request. Guaranties the group id or the group name is provided, not both. */ -class WsGroupRef { +public class WsGroupRef { private final Long id; private final String name; @@ -43,7 +43,7 @@ class WsGroupRef { this.name = name; } - static WsGroupRef fromRequest(Request wsRequest) { + public static WsGroupRef fromRequest(Request wsRequest) { Long id = wsRequest.paramAsLong(PARAM_GROUP_ID); String name = wsRequest.param(PARAM_GROUP_NAME); @@ -51,12 +51,12 @@ class WsGroupRef { } @CheckForNull - Long id() { + public Long id() { return this.id; } @CheckForNull - String name() { + public String name() { return this.name; } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/WsPermissionParameters.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/WsPermissionParameters.java index 274c2c2991b..41f8aeefe30 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/WsPermissionParameters.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/WsPermissionParameters.java @@ -27,23 +27,23 @@ import org.sonar.core.util.Uuids; import static java.lang.String.format; -class WsPermissionParameters { +public class WsPermissionParameters { - static final String PARAM_PERMISSION = "permission"; - static final String PARAM_GROUP_NAME = "groupName"; - static final String PARAM_GROUP_ID = "groupId"; - static final String PARAM_PROJECT_ID = "projectId"; - static final String PARAM_PROJECT_KEY = "projectKey"; - static final String PARAM_USER_LOGIN = "login"; - static final String PARAM_TEMPLATE_ID = "templateId"; - static final String PARAM_TEMPLATE_NAME = "templateName"; + public static final String PARAM_PERMISSION = "permission"; + public static final String PARAM_GROUP_NAME = "groupName"; + public static final String PARAM_GROUP_ID = "groupId"; + public static final String PARAM_PROJECT_ID = "projectId"; + public static final String PARAM_PROJECT_KEY = "projectKey"; + public static final String PARAM_USER_LOGIN = "login"; + public static final String PARAM_TEMPLATE_ID = "templateId"; + public static final String PARAM_TEMPLATE_NAME = "templateName"; - static final String PARAM_ID = "id"; - static final String PARAM_NAME = "name"; - static final String PARAM_DESCRIPTION = "description"; - static final String PARAM_PATTERN = "projectKeyPattern"; + public static final String PARAM_ID = "id"; + public static final String PARAM_NAME = "name"; + public static final String PARAM_DESCRIPTION = "description"; + public static final String PARAM_PATTERN = "projectKeyPattern"; - static final String PARAM_QUALIFIER = "qualifier"; + public static final String PARAM_QUALIFIER = "qualifier"; private static final String PERMISSION_PARAM_DESCRIPTION = format("Permission" + "
    " + @@ -62,31 +62,31 @@ class WsPermissionParameters { // static methods only } - static void createPermissionParameter(NewAction action) { + public static void createPermissionParameter(NewAction action) { action.createParam(PARAM_PERMISSION) .setDescription(PERMISSION_PARAM_DESCRIPTION) .setRequired(true); } - static void createProjectPermissionParameter(NewAction action) { + public static void createProjectPermissionParameter(NewAction action) { action.createParam(PARAM_PERMISSION) .setDescription(PROJECT_PERMISSION_PARAM_DESCRIPTION) .setRequired(true); } - static void createGroupNameParameter(NewAction action) { + public static void createGroupNameParameter(NewAction action) { action.createParam(PARAM_GROUP_NAME) .setDescription("Group name or 'anyone' (case insensitive)") .setExampleValue("sonar-administrators"); } - static void createGroupIdParameter(NewAction action) { + public static void createGroupIdParameter(NewAction action) { action.createParam(PARAM_GROUP_ID) .setDescription("Group id") .setExampleValue("42"); } - static void createProjectParameter(NewAction action) { + public static void createProjectParameter(NewAction action) { createProjectIdParameter(action); createProjectKeyParameter(action); } @@ -103,14 +103,14 @@ class WsPermissionParameters { .setExampleValue("org.apache.hbas:hbase"); } - static void createUserLoginParameter(NewAction action) { + public static void createUserLoginParameter(NewAction action) { action.createParam(PARAM_USER_LOGIN) .setRequired(true) .setDescription("User login") .setExampleValue("g.hopper"); } - static void createTemplateParameters(NewAction action) { + public static void createTemplateParameters(NewAction action) { createTemplateIdParameter(action); createTemplateNameParameter(action); } @@ -127,19 +127,19 @@ class WsPermissionParameters { .setExampleValue("Default Permission Template for Projects"); } - static void createTemplateProjectKeyPatternParameter(NewAction action) { + public static void createTemplateProjectKeyPatternParameter(NewAction action) { action.createParam(PARAM_PATTERN) .setDescription("Project key pattern. Must be a valid Java regular expression") .setExampleValue(".*\\.finance\\..*"); } - static void createTemplateDescriptionParameter(NewAction action) { + public static void createTemplateDescriptionParameter(NewAction action) { action.createParam(PARAM_DESCRIPTION) .setDescription("Description") .setExampleValue("Permissions for all projects related to the financial service"); } - static void createIdParameter(NewAction action) { + public static void createIdParameter(NewAction action) { action.createParam(PARAM_ID) .setRequired(true) .setDescription("Id") diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/WsProjectRef.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/WsProjectRef.java index feda183aba9..9e1f6989edc 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/WsProjectRef.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/WsProjectRef.java @@ -31,7 +31,7 @@ import static org.sonar.server.ws.WsUtils.checkRequest; /** * Project identifiers from a WS request. Guaranties the project id and project key are not provided at the same time. */ -class WsProjectRef { +public class WsProjectRef { private final String uuid; private final String key; @@ -41,7 +41,7 @@ class WsProjectRef { checkRequest(uuid != null ^ key != null, "Project id or project key can be provided, not both."); } - static Optional optionalFromRequest(Request wsRequest) { + public static Optional optionalFromRequest(Request wsRequest) { if (!hasProjectParam(wsRequest)) { return Optional.absent(); } @@ -49,19 +49,19 @@ class WsProjectRef { return Optional.of(new WsProjectRef(wsRequest)); } - static WsProjectRef fromRequest(Request wsRequest) { + public static WsProjectRef fromRequest(Request wsRequest) { checkRequest(hasProjectParam(wsRequest), "Project id or project key must be provided, not both."); return new WsProjectRef(wsRequest); } @CheckForNull - String uuid() { + public String uuid() { return this.uuid; } @CheckForNull - String key() { + public String key() { return this.key; } diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/WsTemplateRef.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/WsTemplateRef.java index 82377eea06d..aeb3f8c0140 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/WsTemplateRef.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/WsTemplateRef.java @@ -31,7 +31,7 @@ import static org.sonar.server.ws.WsUtils.checkRequest; /** * Template from a WS request. Guaranties the template id or the template name is provided, not both. */ -class WsTemplateRef { +public class WsTemplateRef { private final String uuid; private final String name; @@ -43,24 +43,24 @@ class WsTemplateRef { this.name = name; } - static WsTemplateRef fromRequest(Request wsRequest) { + public static WsTemplateRef fromRequest(Request wsRequest) { String uuid = wsRequest.param(PARAM_TEMPLATE_ID); String name = wsRequest.param(PARAM_TEMPLATE_NAME); return new WsTemplateRef(uuid, name); } - static WsTemplateRef newTemplateRef(@Nullable String uuid, @Nullable String name) { + public static WsTemplateRef newTemplateRef(@Nullable String uuid, @Nullable String name) { return new WsTemplateRef(uuid, name); } @CheckForNull - String uuid() { + public String uuid() { return this.uuid; } @CheckForNull - String name() { + public String name() { return this.name; } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/AddGroupToTemplateAction.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/AddGroupToTemplateAction.java new file mode 100644 index 00000000000..7b459b8cc1d --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/AddGroupToTemplateAction.java @@ -0,0 +1,108 @@ +/* + * 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.template; + +import javax.annotation.Nullable; +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.WebService; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.permission.PermissionQuery; +import org.sonar.db.permission.PermissionTemplateDto; +import org.sonar.db.user.GroupDto; +import org.sonar.server.permission.ws.PermissionDependenciesFinder; +import org.sonar.server.permission.ws.PermissionsWsAction; +import org.sonar.server.permission.ws.WsGroupRef; +import org.sonar.server.permission.ws.WsTemplateRef; +import org.sonar.server.user.UserSession; + +import static org.sonar.api.security.DefaultGroups.ANYONE; +import static org.sonar.db.user.GroupMembershipQuery.IN; +import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdminUser; +import static org.sonar.server.permission.ws.PermissionRequestValidator.validateNotAnyoneAndAdminPermission; +import static org.sonar.server.permission.ws.PermissionRequestValidator.validateProjectPermission; +import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_PERMISSION; +import static org.sonar.server.permission.ws.WsPermissionParameters.createGroupIdParameter; +import static org.sonar.server.permission.ws.WsPermissionParameters.createGroupNameParameter; +import static org.sonar.server.permission.ws.WsPermissionParameters.createProjectPermissionParameter; +import static org.sonar.server.permission.ws.WsPermissionParameters.createTemplateParameters; + +public class AddGroupToTemplateAction implements PermissionsWsAction { + private final DbClient dbClient; + private final PermissionDependenciesFinder dependenciesFinder; + private final UserSession userSession; + + public AddGroupToTemplateAction(DbClient dbClient, PermissionDependenciesFinder dependenciesFinder, UserSession userSession) { + this.dbClient = dbClient; + this.dependenciesFinder = dependenciesFinder; + this.userSession = userSession; + } + + @Override + public void define(WebService.NewController context) { + WebService.NewAction action = context + .createAction("add_group_to_template") + .setPost(true) + .setSince("5.2") + .setDescription("Add a group to a permission template.
    " + + "The group id or group name must be provided.
    " + + "It requires administration permissions to access.") + .setHandler(this); + + createTemplateParameters(action); + createProjectPermissionParameter(action); + createGroupIdParameter(action); + createGroupNameParameter(action); + } + + @Override + public void handle(Request wsRequest, Response wsResponse) throws Exception { + checkGlobalAdminUser(userSession); + + String permission = wsRequest.mandatoryParam(PARAM_PERMISSION); + WsGroupRef group = WsGroupRef.fromRequest(wsRequest); + + DbSession dbSession = dbClient.openSession(false); + try { + validateProjectPermission(permission); + validateNotAnyoneAndAdminPermission(permission, group.name()); + + PermissionTemplateDto template = dependenciesFinder.getTemplate(dbSession, WsTemplateRef.fromRequest(wsRequest)); + GroupDto groupDto = dependenciesFinder.getGroup(dbSession, group); + + if (!groupAlreadyAdded(dbSession, template.getId(), groupDto, permission)) { + Long groupId = groupDto == null ? null : groupDto.getId(); + dbClient.permissionTemplateDao().insertGroupPermission(dbSession, template.getId(), groupId, permission); + } + } finally { + dbClient.closeSession(dbSession); + } + + wsResponse.noContent(); + } + + private boolean groupAlreadyAdded(DbSession dbSession, long templateId, @Nullable GroupDto group, String permission) { + String groupName = group == null ? ANYONE : group.getName(); + PermissionQuery permissionQuery = PermissionQuery.builder().membership(IN).permission(permission).build(); + return dbClient.permissionTemplateDao().hasGroup(dbSession, permissionQuery, templateId, groupName); + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/AddUserToTemplateAction.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/AddUserToTemplateAction.java new file mode 100644 index 00000000000..c8658d3f088 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/AddUserToTemplateAction.java @@ -0,0 +1,116 @@ +/* + * 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.template; + +import com.google.common.base.Predicate; +import java.util.List; +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.WebService; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.permission.PermissionQuery; +import org.sonar.db.permission.PermissionTemplateDto; +import org.sonar.db.permission.UserWithPermissionDto; +import org.sonar.db.user.UserDto; +import org.sonar.server.permission.ws.PermissionDependenciesFinder; +import org.sonar.server.permission.ws.PermissionsWsAction; +import org.sonar.server.permission.ws.WsTemplateRef; +import org.sonar.server.user.UserSession; + +import static com.google.common.collect.FluentIterable.from; +import static org.sonar.db.user.GroupMembershipQuery.IN; +import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdminUser; +import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_PERMISSION; +import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_USER_LOGIN; +import static org.sonar.server.permission.ws.WsPermissionParameters.createProjectPermissionParameter; +import static org.sonar.server.permission.ws.WsPermissionParameters.createTemplateParameters; +import static org.sonar.server.permission.ws.WsPermissionParameters.createUserLoginParameter; +import static org.sonar.server.permission.ws.PermissionRequestValidator.validateProjectPermission; + +public class AddUserToTemplateAction implements PermissionsWsAction { + private final DbClient dbClient; + private final PermissionDependenciesFinder dependenciesFinder; + private final UserSession userSession; + + public AddUserToTemplateAction(DbClient dbClient, PermissionDependenciesFinder dependenciesFinder, UserSession userSession) { + this.dbClient = dbClient; + this.dependenciesFinder = dependenciesFinder; + this.userSession = userSession; + } + + @Override + public void define(WebService.NewController context) { + WebService.NewAction action = context + .createAction("add_user_to_template") + .setPost(true) + .setSince("5.2") + .setDescription("Add a user to a permission template.
    " + + "It requires administration permissions to access.") + .setHandler(this); + + createTemplateParameters(action); + createProjectPermissionParameter(action); + createUserLoginParameter(action); + } + + @Override + public void handle(Request wsRequest, Response wsResponse) throws Exception { + checkGlobalAdminUser(userSession); + + String permission = wsRequest.mandatoryParam(PARAM_PERMISSION); + final String userLogin = wsRequest.mandatoryParam(PARAM_USER_LOGIN); + + DbSession dbSession = dbClient.openSession(false); + try { + validateProjectPermission(permission); + PermissionTemplateDto template = dependenciesFinder.getTemplate(dbSession, WsTemplateRef.fromRequest(wsRequest)); + UserDto user = dependenciesFinder.getUser(dbSession, userLogin); + + if (!isUserAlreadyAdded(dbSession, template.getId(), userLogin, permission)) { + dbClient.permissionTemplateDao().insertUserPermission(dbSession, template.getId(), user.getId(), permission); + } + } finally { + dbClient.closeSession(dbSession); + } + + wsResponse.noContent(); + } + + private boolean isUserAlreadyAdded(DbSession dbSession, long templateId, String userLogin, String permission) { + PermissionQuery permissionQuery = PermissionQuery.builder().permission(permission).membership(IN).build(); + List usersWithPermission = dbClient.permissionTemplateDao().selectUsers(dbSession, permissionQuery, templateId, 0, Integer.MAX_VALUE); + return from(usersWithPermission).anyMatch(new HasUserPredicate(userLogin)); + } + + private static class HasUserPredicate implements Predicate { + private final String userLogin; + + public HasUserPredicate(String userLogin) { + this.userLogin = userLogin; + } + + @Override + public boolean apply(UserWithPermissionDto userWithPermission) { + return userLogin.equals(userWithPermission.getLogin()); + } + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/ApplyTemplateAction.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/ApplyTemplateAction.java new file mode 100644 index 00000000000..ab97c359cc8 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/ApplyTemplateAction.java @@ -0,0 +1,83 @@ +/* + * 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.template; + +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.WebService; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.component.ComponentDto; +import org.sonar.db.permission.PermissionTemplateDto; +import org.sonar.server.permission.ApplyPermissionTemplateQuery; +import org.sonar.server.permission.PermissionService; +import org.sonar.server.permission.ws.PermissionDependenciesFinder; +import org.sonar.server.permission.ws.PermissionsWsAction; +import org.sonar.server.permission.ws.WsProjectRef; +import org.sonar.server.permission.ws.WsTemplateRef; + +import static java.util.Collections.singletonList; +import static org.sonar.server.permission.ws.WsPermissionParameters.createProjectParameter; +import static org.sonar.server.permission.ws.WsPermissionParameters.createTemplateParameters; + +public class ApplyTemplateAction implements PermissionsWsAction { + private final DbClient dbClient; + private final PermissionService permissionService; + private final PermissionDependenciesFinder finder; + + public ApplyTemplateAction(DbClient dbClient, PermissionService permissionService, PermissionDependenciesFinder finder) { + this.dbClient = dbClient; + this.permissionService = permissionService; + this.finder = finder; + } + + @Override + public void define(WebService.NewController context) { + WebService.NewAction action = context.createAction("apply_template") + .setDescription("Apply a permission template to one or several projects.
    " + + "The project id or project key must be provided.
    " + + "It requires administration permissions to access.") + .setPost(true) + .setSince("5.2") + .setHandler(this); + + createTemplateParameters(action); + createProjectParameter(action); + } + + @Override + public void handle(Request wsRequest, Response wsResponse) throws Exception { + DbSession dbSession = dbClient.openSession(false); + try { + PermissionTemplateDto template = finder.getTemplate(dbSession, WsTemplateRef.fromRequest(wsRequest)); + ComponentDto project = finder.getProject(dbSession, WsProjectRef.fromRequest(wsRequest)); + + ApplyPermissionTemplateQuery query = ApplyPermissionTemplateQuery.create( + template.getUuid(), + singletonList(project.key())); + permissionService.applyPermissionTemplate(query); + } finally { + dbClient.closeSession(dbSession); + } + + wsResponse.noContent(); + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/CreateTemplateAction.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/CreateTemplateAction.java new file mode 100644 index 00000000000..2e949840264 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/CreateTemplateAction.java @@ -0,0 +1,122 @@ +/* + * 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.template; + +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.permission.ws.PermissionsWsAction; +import org.sonar.server.user.UserSession; +import org.sonarqube.ws.WsPermissions.PermissionTemplate; +import org.sonarqube.ws.WsPermissions.WsCreatePermissionTemplateResponse; + +import static java.lang.String.format; +import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdminUser; +import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_DESCRIPTION; +import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_NAME; +import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_PATTERN; +import static org.sonar.server.permission.ws.WsPermissionParameters.createTemplateDescriptionParameter; +import static org.sonar.server.permission.ws.WsPermissionParameters.createTemplateProjectKeyPatternParameter; +import static org.sonar.server.permission.ws.PermissionRequestValidator.MSG_TEMPLATE_WITH_SAME_NAME; +import static org.sonar.server.permission.ws.PermissionRequestValidator.validateProjectPattern; +import static org.sonar.server.permission.ws.PermissionRequestValidator.validateTemplateNameFormat; +import static org.sonar.server.permission.ws.template.PermissionTemplateDtoBuilder.create; +import static org.sonar.server.permission.ws.template.PermissionTemplateDtoToPermissionTemplateResponse.toPermissionTemplateResponse; +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_NAME) + .setRequired(true) + .setDescription("Name") + .setExampleValue("Financial Service Permissions"); + + createTemplateProjectKeyPatternParameter(action); + createTemplateDescriptionParameter(action); + } + + @Override + public void handle(Request wsRequest, Response wsResponse) throws Exception { + String name = wsRequest.mandatoryParam(PARAM_NAME); + String description = wsRequest.param(PARAM_DESCRIPTION); + String projectPattern = wsRequest.param(PARAM_PATTERN); + + DbSession dbSession = dbClient.openSession(false); + try { + checkGlobalAdminUser(userSession); + validateTemplateNameForCreation(dbSession, name); + validateProjectPattern(projectPattern); + + PermissionTemplateDto permissionTemplate = insertTemplate(dbSession, name, description, projectPattern); + + WsCreatePermissionTemplateResponse response = buildResponse(permissionTemplate); + writeProtobuf(response, wsRequest, wsResponse); + } finally { + dbClient.closeSession(dbSession); + } + } + + private void validateTemplateNameForCreation(DbSession dbSession, String name) { + validateTemplateNameFormat(name); + + PermissionTemplateDto permissionTemplateWithSameName = dbClient.permissionTemplateDao().selectByName(dbSession, name); + checkRequest(permissionTemplateWithSameName == null, format(MSG_TEMPLATE_WITH_SAME_NAME, name)); + } + + 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 static WsCreatePermissionTemplateResponse buildResponse(PermissionTemplateDto permissionTemplateDto) { + PermissionTemplate permissionTemplateBuilder = toPermissionTemplateResponse(permissionTemplateDto); + return WsCreatePermissionTemplateResponse.newBuilder().setPermissionTemplate(permissionTemplateBuilder).build(); + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/DefaultPermissionTemplateFinder.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/DefaultPermissionTemplateFinder.java new file mode 100644 index 00000000000..2ee49517dee --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/DefaultPermissionTemplateFinder.java @@ -0,0 +1,121 @@ +/* + * 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.template; + +import com.google.common.base.Function; +import java.util.List; +import java.util.Set; +import javax.annotation.Nonnull; +import org.sonar.api.config.Settings; +import org.sonar.api.resources.Qualifiers; +import org.sonar.api.resources.ResourceTypes; + +import static com.google.common.collect.FluentIterable.from; +import static com.google.common.collect.Ordering.natural; +import static org.sonar.server.permission.DefaultPermissionTemplates.DEFAULT_TEMPLATE_PROPERTY; +import static org.sonar.server.permission.DefaultPermissionTemplates.defaultRootQualifierTemplateProperty; +import static org.sonar.server.permission.ws.ResourceTypeToQualifier.RESOURCE_TYPE_TO_QUALIFIER; + +public class DefaultPermissionTemplateFinder { + private final Settings settings; + private final ResourceTypes resourceTypes; + + public DefaultPermissionTemplateFinder(Settings settings, ResourceTypes resourceTypes) { + this.settings = settings; + this.resourceTypes = resourceTypes; + } + + public Set getDefaultTemplateUuids() { + return from(resourceTypes.getRoots()) + .transform(RESOURCE_TYPE_TO_QUALIFIER) + .transform(new QualifierToDefaultTemplate(settings)) + .toSortedSet(natural()); + } + + public List getDefaultTemplatesByQualifier() { + return from(resourceTypes.getRoots()) + .transform(RESOURCE_TYPE_TO_QUALIFIER) + .transform(new QualifierToTemplateUuidQualifier(settings)) + .toList(); + } + + public static class TemplateUuidQualifier { + private final String templateUuid; + private final String qualifier; + + TemplateUuidQualifier(String templateUuid, String qualifier) { + this.templateUuid = templateUuid; + this.qualifier = qualifier; + } + + public String getTemplateUuid() { + return templateUuid; + } + + public String getQualifier() { + return qualifier; + } + } + + private static class QualifierToDefaultTemplate implements Function { + private final Settings settings; + + QualifierToDefaultTemplate(Settings settings) { + this.settings = settings; + } + + @Override + public String apply(@Nonnull String qualifier) { + String effectiveTemplateUuid = effectiveTemplateUuid(settings, qualifier); + return effectiveTemplateUuid; + } + } + + private static class QualifierToTemplateUuidQualifier implements Function { + private final Settings settings; + + QualifierToTemplateUuidQualifier(Settings settings) { + this.settings = settings; + } + + @Override + public TemplateUuidQualifier apply(@Nonnull String qualifier) { + String effectiveTemplateUuid = effectiveTemplateUuid(settings, qualifier); + + return new TemplateUuidQualifier(effectiveTemplateUuid, qualifier); + } + } + + private static String effectiveTemplateUuid(Settings settings, String qualifier) { + String qualifierTemplateUuid = settings.getString(defaultRootQualifierTemplateProperty(qualifier)); + String projectTemplateUuid = settings.getString(defaultRootQualifierTemplateProperty(Qualifiers.PROJECT)); + String defaultTemplateUuid = settings.getString(DEFAULT_TEMPLATE_PROPERTY); + + if (qualifierTemplateUuid != null) { + return qualifierTemplateUuid; + } else if (projectTemplateUuid != null) { + return projectTemplateUuid; + } else { + return defaultTemplateUuid; + } + } + +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/PermissionTemplateDtoBuilder.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/PermissionTemplateDtoBuilder.java new file mode 100644 index 00000000000..79e658da409 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/PermissionTemplateDtoBuilder.java @@ -0,0 +1,67 @@ +/* + * 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.template; + +import java.util.Date; +import org.sonar.api.utils.System2; +import org.sonar.core.util.Uuids; +import org.sonar.db.permission.PermissionTemplateDto; + +public class PermissionTemplateDtoBuilder { + private final System2 system; + private String name; + private String description; + private String projectKeyPattern; + + private PermissionTemplateDtoBuilder(System2 system) { + this.system = system; + } + + public static PermissionTemplateDtoBuilder create(System2 system) { + return new PermissionTemplateDtoBuilder(system); + } + + public PermissionTemplateDtoBuilder setName(String name) { + this.name = name; + return this; + } + + public PermissionTemplateDtoBuilder setDescription(String description) { + this.description = description; + return this; + } + + public PermissionTemplateDtoBuilder setProjectKeyPattern(String projectKeyPattern) { + this.projectKeyPattern = projectKeyPattern; + return this; + } + + public PermissionTemplateDto toDto() { + long now = system.now(); + return new PermissionTemplateDto() + .setName(name) + .setDescription(description) + .setKeyPattern(projectKeyPattern) + .setKee(Uuids.create()) + .setCreatedAt(new Date(now)) + .setUpdatedAt(new Date(now)); + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/PermissionTemplateDtoToPermissionTemplateResponse.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/PermissionTemplateDtoToPermissionTemplateResponse.java new file mode 100644 index 00000000000..28f77ac5563 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/PermissionTemplateDtoToPermissionTemplateResponse.java @@ -0,0 +1,53 @@ +/* + * 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.template; + +import com.google.common.base.Function; +import javax.annotation.Nonnull; +import org.sonar.api.utils.DateUtils; +import org.sonar.db.permission.PermissionTemplateDto; +import org.sonarqube.ws.WsPermissions.PermissionTemplate; + +public class PermissionTemplateDtoToPermissionTemplateResponse { + + public static PermissionTemplate toPermissionTemplateResponse(PermissionTemplateDto dto) { + return Singleton.INSTANCE.apply(dto); + } + + private enum Singleton implements Function { + INSTANCE; + @Override + public PermissionTemplate apply(@Nonnull PermissionTemplateDto permissionTemplate) { + PermissionTemplate.Builder permissionTemplateBuilder = PermissionTemplate.newBuilder() + .setId(permissionTemplate.getKee()) + .setName(permissionTemplate.getName()) + .setCreatedAt(DateUtils.formatDateTime(permissionTemplate.getCreatedAt())) + .setUpdatedAt(DateUtils.formatDateTime(permissionTemplate.getUpdatedAt())); + if (permissionTemplate.getDescription() != null) { + permissionTemplateBuilder.setDescription(permissionTemplate.getDescription()); + } + if (permissionTemplate.getKeyPattern() != null) { + permissionTemplateBuilder.setProjectKeyPattern(permissionTemplate.getKeyPattern()); + } + return permissionTemplateBuilder.build(); + } + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/RemoveGroupFromTemplateAction.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/RemoveGroupFromTemplateAction.java new file mode 100644 index 00000000000..d86cd253b4e --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/RemoveGroupFromTemplateAction.java @@ -0,0 +1,94 @@ +/* + * 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.template; + +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.WebService; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.permission.PermissionTemplateDto; +import org.sonar.db.user.GroupDto; +import org.sonar.server.permission.ws.PermissionDependenciesFinder; +import org.sonar.server.permission.ws.PermissionsWsAction; +import org.sonar.server.permission.ws.WsGroupRef; +import org.sonar.server.permission.ws.WsTemplateRef; +import org.sonar.server.user.UserSession; + +import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdminUser; +import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_PERMISSION; +import static org.sonar.server.permission.ws.WsPermissionParameters.createGroupIdParameter; +import static org.sonar.server.permission.ws.WsPermissionParameters.createGroupNameParameter; +import static org.sonar.server.permission.ws.WsPermissionParameters.createProjectPermissionParameter; +import static org.sonar.server.permission.ws.WsPermissionParameters.createTemplateParameters; +import static org.sonar.server.permission.ws.PermissionRequestValidator.validateProjectPermission; + +public class RemoveGroupFromTemplateAction implements PermissionsWsAction { + private final DbClient dbClient; + private final PermissionDependenciesFinder dependenciesFinder; + private final UserSession userSession; + + public RemoveGroupFromTemplateAction(DbClient dbClient, PermissionDependenciesFinder dependenciesFinder, UserSession userSession) { + this.dbClient = dbClient; + this.dependenciesFinder = dependenciesFinder; + this.userSession = userSession; + } + + @Override + public void define(WebService.NewController context) { + WebService.NewAction action = context + .createAction("remove_group_from_template") + .setPost(true) + .setSince("5.2") + .setDescription("Remove a group from a permission template.
    " + + "The group id or group name must be provided.
    " + + "It requires administration permissions to access.") + .setHandler(this); + + createTemplateParameters(action); + createProjectPermissionParameter(action); + createGroupIdParameter(action); + createGroupNameParameter(action); + } + + @Override + public void handle(Request wsRequest, Response wsResponse) throws Exception { + checkGlobalAdminUser(userSession); + + String permission = wsRequest.mandatoryParam(PARAM_PERMISSION); + WsGroupRef group = WsGroupRef.fromRequest(wsRequest); + + DbSession dbSession = dbClient.openSession(false); + try { + validateProjectPermission(permission); + + PermissionTemplateDto template = dependenciesFinder.getTemplate(dbSession, WsTemplateRef.fromRequest(wsRequest)); + GroupDto groupDto = dependenciesFinder.getGroup(dbSession, group); + + Long groupId = groupDto == null ? null : groupDto.getId(); + dbClient.permissionTemplateDao().deleteGroupPermission(dbSession, template.getId(), groupId, permission); + } finally { + dbClient.closeSession(dbSession); + } + + wsResponse.noContent(); + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/RemoveUserFromTemplateAction.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/RemoveUserFromTemplateAction.java new file mode 100644 index 00000000000..a8147e40d7b --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/RemoveUserFromTemplateAction.java @@ -0,0 +1,90 @@ +/* + * 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.template; + +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.WebService; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.permission.PermissionTemplateDto; +import org.sonar.db.user.UserDto; +import org.sonar.server.permission.ws.PermissionDependenciesFinder; +import org.sonar.server.permission.ws.PermissionsWsAction; +import org.sonar.server.permission.ws.WsTemplateRef; +import org.sonar.server.user.UserSession; + +import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdminUser; +import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_PERMISSION; +import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_USER_LOGIN; +import static org.sonar.server.permission.ws.WsPermissionParameters.createProjectPermissionParameter; +import static org.sonar.server.permission.ws.WsPermissionParameters.createTemplateParameters; +import static org.sonar.server.permission.ws.WsPermissionParameters.createUserLoginParameter; +import static org.sonar.server.permission.ws.PermissionRequestValidator.validateProjectPermission; + +public class RemoveUserFromTemplateAction implements PermissionsWsAction { + private final DbClient dbClient; + private final PermissionDependenciesFinder dependenciesFinder; + private final UserSession userSession; + + public RemoveUserFromTemplateAction(DbClient dbClient, PermissionDependenciesFinder dependenciesFinder, UserSession userSession) { + this.dbClient = dbClient; + this.dependenciesFinder = dependenciesFinder; + this.userSession = userSession; + } + + @Override + public void define(WebService.NewController context) { + WebService.NewAction action = context + .createAction("remove_user_from_template") + .setPost(true) + .setSince("5.2") + .setDescription("Remove a user from a permission template.
    " + + "It requires administration permissions to access.") + .setHandler(this); + + createTemplateParameters(action); + createProjectPermissionParameter(action); + createUserLoginParameter(action); + } + + @Override + public void handle(Request wsRequest, Response wsResponse) throws Exception { + checkGlobalAdminUser(userSession); + + String permission = wsRequest.mandatoryParam(PARAM_PERMISSION); + String userLogin = wsRequest.mandatoryParam(PARAM_USER_LOGIN); + + DbSession dbSession = dbClient.openSession(false); + try { + validateProjectPermission(permission); + PermissionTemplateDto template = dependenciesFinder.getTemplate(dbSession, WsTemplateRef.fromRequest(wsRequest)); + UserDto user = dependenciesFinder.getUser(dbSession, userLogin); + + dbClient.permissionTemplateDao().deleteUserPermission(dbSession, template.getId(), user.getId(), permission); + dbSession.commit(); + } finally { + dbClient.closeSession(dbSession); + } + + wsResponse.noContent(); + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/SearchTemplatesAction.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/SearchTemplatesAction.java new file mode 100644 index 00000000000..81ac05f93a0 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/SearchTemplatesAction.java @@ -0,0 +1,152 @@ +/* + * 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.template; + +import org.sonar.api.i18n.I18n; +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.WebService; +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.permission.ws.PermissionsWsAction; +import org.sonar.server.user.UserSession; +import org.sonarqube.ws.WsPermissions.Permission; +import org.sonarqube.ws.WsPermissions.PermissionTemplate; +import org.sonarqube.ws.WsPermissions.WsSearchTemplatesResponse; +import org.sonarqube.ws.WsPermissions.WsSearchTemplatesResponse.TemplateIdQualifier; + +import static org.sonar.api.utils.DateUtils.formatDateTime; +import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdminUser; +import static org.sonar.server.ws.WsUtils.writeProtobuf; + +public class SearchTemplatesAction implements PermissionsWsAction { + private static final String PROPERTY_PREFIX = "projects_role."; + private static final String DESCRIPTION_SUFFIX = ".desc"; + + private final DbClient dbClient; + private final UserSession userSession; + private final I18n i18n; + private final SearchTemplatesDataLoader dataLoader; + + public SearchTemplatesAction(DbClient dbClient, UserSession userSession, I18n i18n, SearchTemplatesDataLoader dataLoader) { + this.dbClient = dbClient; + this.userSession = userSession; + this.i18n = i18n; + this.dataLoader = dataLoader; + } + + @Override + public void define(WebService.NewController context) { + context.createAction("search_templates") + .setDescription("List permission templates.
    " + + "It requires administration permissions to access.") + .setResponseExample(getClass().getResource("search_templates-example.json")) + .setSince("5.2") + .addSearchQuery("defau", "permission template names") + .setHandler(this); + } + + @Override + public void handle(Request wsRequest, Response wsResponse) throws Exception { + checkGlobalAdminUser(userSession); + + DbSession dbSession = dbClient.openSession(false); + try { + SearchTemplatesData data = dataLoader.load(wsRequest); + WsSearchTemplatesResponse response = buildResponse(data); + writeProtobuf(response, wsRequest, wsResponse); + } finally { + dbClient.closeSession(dbSession); + } + } + + private WsSearchTemplatesResponse buildResponse(SearchTemplatesData data) { + WsSearchTemplatesResponse.Builder response = WsSearchTemplatesResponse.newBuilder(); + + buildTemplatesResponse(response, data); + buildDefaultTemplatesResponse(response, data); + buildPermissionsResponse(response); + + return response.build(); + } + + private static void buildDefaultTemplatesResponse(WsSearchTemplatesResponse.Builder response, SearchTemplatesData data) { + TemplateIdQualifier.Builder templateUuidQualifierBuilder = TemplateIdQualifier.newBuilder(); + for (DefaultPermissionTemplateFinder.TemplateUuidQualifier templateUuidQualifier : data.defaultTempltes()) { + response.addDefaultTemplates(templateUuidQualifierBuilder + .clear() + .setQualifier(templateUuidQualifier.getQualifier()) + .setTemplateId(templateUuidQualifier.getTemplateUuid())); + } + } + + private static void buildTemplatesResponse(WsSearchTemplatesResponse.Builder response, SearchTemplatesData data) { + Permission.Builder permissionResponse = Permission.newBuilder(); + PermissionTemplate.Builder templateBuilder = PermissionTemplate.newBuilder(); + + for (PermissionTemplateDto templateDto : data.templates()) { + templateBuilder + .clear() + .setId(templateDto.getUuid()) + .setName(templateDto.getName()) + .setCreatedAt(formatDateTime(templateDto.getCreatedAt())) + .setUpdatedAt(formatDateTime(templateDto.getUpdatedAt())); + if (templateDto.getKeyPattern() != null) { + templateBuilder.setProjectKeyPattern(templateDto.getKeyPattern()); + } + if (templateDto.getDescription() != null) { + templateBuilder.setDescription(templateDto.getDescription()); + } + for (String permission : data.permissions(templateDto.getId())) { + templateBuilder.addPermissions( + permissionResponse + .clear() + .setKey(permission) + .setUsersCount(data.userCount(templateDto.getId(), permission)) + .setGroupsCount(data.groupCount(templateDto.getId(), permission))); + } + response.addPermissionTemplates(templateBuilder); + } + } + + private void buildPermissionsResponse(WsSearchTemplatesResponse.Builder response) { + Permission.Builder permissionResponse = Permission.newBuilder(); + for (String permissionKey : ProjectPermissions.ALL) { + response.addPermissions( + permissionResponse + .clear() + .setKey(permissionKey) + .setName(i18nName(permissionKey)) + .setDescription(i18nDescriptionMessage(permissionKey)) + ); + } + } + + private String i18nDescriptionMessage(String permissionKey) { + return i18n.message(userSession.locale(), PROPERTY_PREFIX + permissionKey + DESCRIPTION_SUFFIX, ""); + } + + private String i18nName(String permissionKey) { + return i18n.message(userSession.locale(), PROPERTY_PREFIX + permissionKey, permissionKey); + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/SearchTemplatesData.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/SearchTemplatesData.java new file mode 100644 index 00000000000..b328477e35c --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/SearchTemplatesData.java @@ -0,0 +1,118 @@ +/* + * 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.template; + +import com.google.common.collect.FluentIterable; +import com.google.common.collect.Iterables; +import com.google.common.collect.Table; +import java.util.List; +import java.util.Set; +import org.sonar.db.permission.PermissionTemplateDto; +import org.sonar.server.permission.ws.template.DefaultPermissionTemplateFinder.TemplateUuidQualifier; + +import static com.google.common.base.Objects.firstNonNull; +import static com.google.common.base.Preconditions.checkState; +import static com.google.common.collect.ImmutableList.copyOf; +import static com.google.common.collect.ImmutableTable.copyOf; +import static com.google.common.collect.Ordering.natural; + +class SearchTemplatesData { + private final List templates; + private final List defaultTemplates; + private final Table userCountByTemplateIdAndPermission; + private final Table groupCountByTemplateIdAndPermission; + + private SearchTemplatesData(Builder builder) { + this.templates = copyOf(builder.templates); + this.defaultTemplates = copyOf(builder.defaultTemplates); + this.userCountByTemplateIdAndPermission = copyOf(builder.userCountByTemplateIdAndPermission); + this.groupCountByTemplateIdAndPermission = copyOf(builder.groupCountByTemplateIdAndPermission); + } + + public static Builder newBuilder() { + return new Builder(); + } + + public List templates() { + return templates; + } + + public List defaultTempltes() { + return defaultTemplates; + } + + public int userCount(long templateId, String permission) { + return firstNonNull(userCountByTemplateIdAndPermission.get(templateId, permission), 0); + } + + public int groupCount(long templateId, String permission) { + return firstNonNull(groupCountByTemplateIdAndPermission.get(templateId, permission), 0); + } + + public Set permissions(long templateId) { + return FluentIterable.from( + Iterables.concat( + userCountByTemplateIdAndPermission.row(templateId).keySet(), + groupCountByTemplateIdAndPermission.row(templateId).keySet() + ) + ).toSortedSet(natural()); + } + + public static class Builder { + private List templates; + private List defaultTemplates; + private Table userCountByTemplateIdAndPermission; + private Table groupCountByTemplateIdAndPermission; + + private Builder() { + // prevents instantiation outside main class + } + + public SearchTemplatesData build() { + checkState(templates != null); + checkState(defaultTemplates != null); + checkState(userCountByTemplateIdAndPermission != null); + checkState(groupCountByTemplateIdAndPermission != null); + + return new SearchTemplatesData(this); + } + + public Builder templates(List templates) { + this.templates = templates; + return this; + } + + public Builder defaultTemplates(List defaultTemplates) { + this.defaultTemplates = defaultTemplates; + return this; + } + + public Builder userCountByTemplateIdAndPermission(Table userCountByTemplateIdAndPermission) { + this.userCountByTemplateIdAndPermission = userCountByTemplateIdAndPermission; + return this; + } + + public Builder groupCountByTemplateIdAndPermission(Table groupCountByTemplateIdAndPermission) { + this.groupCountByTemplateIdAndPermission = groupCountByTemplateIdAndPermission; + return this; + } + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/SearchTemplatesDataLoader.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/SearchTemplatesDataLoader.java new file mode 100644 index 00000000000..dd561143f2c --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/SearchTemplatesDataLoader.java @@ -0,0 +1,113 @@ +/* + * 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.template; + +import com.google.common.base.Function; +import com.google.common.collect.Lists; +import com.google.common.collect.Table; +import com.google.common.collect.TreeBasedTable; +import java.util.List; +import javax.annotation.Nonnull; +import org.apache.ibatis.session.ResultContext; +import org.apache.ibatis.session.ResultHandler; +import org.sonar.api.server.ws.Request; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.permission.CountByTemplateAndPermissionDto; +import org.sonar.db.permission.PermissionTemplateDto; +import org.sonar.server.permission.ws.template.DefaultPermissionTemplateFinder.TemplateUuidQualifier; + +import static org.sonar.api.server.ws.WebService.Param.TEXT_QUERY; +import static org.sonar.server.permission.ws.template.SearchTemplatesData.newBuilder; + +public class SearchTemplatesDataLoader { + private final DbClient dbClient; + private final DefaultPermissionTemplateFinder defaultPermissionTemplateFinder; + + public SearchTemplatesDataLoader(DbClient dbClient, DefaultPermissionTemplateFinder defaultPermissionTemplateFinder) { + this.dbClient = dbClient; + this.defaultPermissionTemplateFinder = defaultPermissionTemplateFinder; + } + + public SearchTemplatesData load(Request wsRequest) { + DbSession dbSession = dbClient.openSession(false); + try { + SearchTemplatesData.Builder data = newBuilder(); + List templates = searchTemplates(dbSession, wsRequest); + List templateIds = Lists.transform(templates, TemplateToIdFunction.INSTANCE); + List defaultTemplates = defaultPermissionTemplateFinder.getDefaultTemplatesByQualifier(); + + data.templates(templates) + .defaultTemplates(defaultTemplates) + .userCountByTemplateIdAndPermission(userCountByTemplateIdAndPermission(dbSession, templateIds)) + .groupCountByTemplateIdAndPermission(groupCountByTemplateIdAndPermission(dbSession, templateIds)); + + return data.build(); + } finally { + dbClient.closeSession(dbSession); + } + } + + private List searchTemplates(DbSession dbSession, Request wsRequest) { + String nameMatch = wsRequest.param(TEXT_QUERY); + + return nameMatch == null ? + dbClient.permissionTemplateDao().selectAll(dbSession) + : dbClient.permissionTemplateDao().selectAll(dbSession, nameMatch); + } + + private Table userCountByTemplateIdAndPermission(DbSession dbSession, List templateIds) { + final Table userCountByTemplateIdAndPermission = TreeBasedTable.create(); + + dbClient.permissionTemplateDao().usersCountByTemplateIdAndPermission(dbSession, templateIds, new ResultHandler() { + @Override + public void handleResult(ResultContext context) { + CountByTemplateAndPermissionDto row = (CountByTemplateAndPermissionDto) context.getResultObject(); + userCountByTemplateIdAndPermission.put(row.getTemplateId(), row.getPermission(), row.getCount()); + } + }); + + return userCountByTemplateIdAndPermission; + } + + private Table groupCountByTemplateIdAndPermission(DbSession dbSession, List templateIds) { + final Table userCountByTemplateIdAndPermission = TreeBasedTable.create(); + + dbClient.permissionTemplateDao().groupsCountByTemplateIdAndPermission(dbSession, templateIds, new ResultHandler() { + @Override + public void handleResult(ResultContext context) { + CountByTemplateAndPermissionDto row = (CountByTemplateAndPermissionDto) context.getResultObject(); + userCountByTemplateIdAndPermission.put(row.getTemplateId(), row.getPermission(), row.getCount()); + } + }); + + return userCountByTemplateIdAndPermission; + } + + private enum TemplateToIdFunction implements Function { + INSTANCE; + + @Override + public Long apply(@Nonnull PermissionTemplateDto template) { + return template.getId(); + } + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/SetDefaultTemplateAction.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/SetDefaultTemplateAction.java new file mode 100644 index 00000000000..d2ffbb4d671 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/SetDefaultTemplateAction.java @@ -0,0 +1,131 @@ +/* + * 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.template; + +import java.util.Set; +import org.sonar.api.i18n.I18n; +import org.sonar.api.resources.Qualifiers; +import org.sonar.api.resources.ResourceTypes; +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.WebService; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.permission.PermissionTemplateDto; +import org.sonar.server.permission.ws.PermissionDependenciesFinder; +import org.sonar.server.permission.ws.PermissionsWsAction; +import org.sonar.server.permission.ws.WsTemplateRef; +import org.sonar.server.platform.PersistentSettings; +import org.sonar.server.user.UserSession; + +import static com.google.common.collect.FluentIterable.from; +import static com.google.common.collect.Ordering.natural; +import static java.lang.String.format; +import static org.sonar.server.permission.DefaultPermissionTemplates.defaultRootQualifierTemplateProperty; +import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdminUser; +import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_QUALIFIER; +import static org.sonar.server.permission.ws.WsPermissionParameters.createTemplateParameters; +import static org.sonar.server.permission.ws.PermissionRequestValidator.validateQualifier; +import static org.sonar.server.permission.ws.ResourceTypeToQualifier.RESOURCE_TYPE_TO_QUALIFIER; + +public class SetDefaultTemplateAction implements PermissionsWsAction { + private final DbClient dbClient; + private final PermissionDependenciesFinder finder; + private final ResourceTypes resourceTypes; + private final PersistentSettings settings; + private final UserSession userSession; + private final I18n i18n; + + public SetDefaultTemplateAction(DbClient dbClient, PermissionDependenciesFinder finder, ResourceTypes resourceTypes, PersistentSettings settings, UserSession userSession, + I18n i18n) { + this.dbClient = dbClient; + this.finder = finder; + this.resourceTypes = resourceTypes; + this.settings = settings; + this.userSession = userSession; + this.i18n = i18n; + } + + @Override + public void define(WebService.NewController context) { + WebService.NewAction action = context.createAction("set_default_template") + .setDescription("Set a permission template as default.
    " + + "It requires administration permissions to access.") + .setPost(true) + .setSince("5.2") + .setHandler(this); + + createTemplateParameters(action); + + action.createParam(PARAM_QUALIFIER) + .setDescription("Project qualifier. Possible values are:" + buildRootQualifiersDescription()) + .setDefaultValue(Qualifiers.PROJECT) + .setPossibleValues(getRootQualifiers()); + } + + @Override + public void handle(Request wsRequest, Response wsResponse) throws Exception { + checkGlobalAdminUser(userSession); + + String qualifier = wsRequest.mandatoryParam(PARAM_QUALIFIER); + + PermissionTemplateDto template = getTemplate(wsRequest); + validateQualifier(qualifier, getRootQualifiers()); + setDefaultTemplateUuid(template.getUuid(), qualifier); + wsResponse.noContent(); + } + + private Set getRootQualifiers() { + return from(resourceTypes.getRoots()) + .transform(RESOURCE_TYPE_TO_QUALIFIER) + .toSortedSet(natural()); + } + + private String buildRootQualifiersDescription() { + StringBuilder description = new StringBuilder(); + description.append("
      "); + String qualifierPattern = "
    • %s - %s
    • "; + for (String qualifier : getRootQualifiers()) { + description.append(format(qualifierPattern, qualifier, i18n(qualifier))); + } + description.append("
    "); + + return description.toString(); + } + + private String i18n(String qualifier) { + String qualifiersPropertyPrefix = "qualifiers."; + return i18n.message(userSession.locale(), qualifiersPropertyPrefix + qualifier, ""); + } + + private PermissionTemplateDto getTemplate(Request wsRequest) { + DbSession dbSession = dbClient.openSession(false); + try { + return finder.getTemplate(dbSession, WsTemplateRef.fromRequest(wsRequest)); + } finally { + dbClient.closeSession(dbSession); + } + } + + private void setDefaultTemplateUuid(String templateUuid, String qualifier) { + settings.saveProperty(defaultRootQualifierTemplateProperty(qualifier), templateUuid); + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/UpdateTemplateAction.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/UpdateTemplateAction.java new file mode 100644 index 00000000000..8eaf61cb37a --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/UpdateTemplateAction.java @@ -0,0 +1,143 @@ +/* + * 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.template; + +import java.util.Date; +import javax.annotation.Nullable; +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.permission.ws.PermissionDependenciesFinder; +import org.sonar.server.permission.ws.PermissionsWsAction; +import org.sonar.server.permission.ws.WsTemplateRef; +import org.sonar.server.user.UserSession; +import org.sonarqube.ws.WsPermissions.PermissionTemplate; +import org.sonarqube.ws.WsPermissions.WsUpdatePermissionTemplateResponse; + +import static com.google.common.base.Objects.firstNonNull; +import static java.lang.String.format; +import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdminUser; +import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_ID; +import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_DESCRIPTION; +import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_NAME; +import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_PATTERN; +import static org.sonar.server.permission.ws.WsPermissionParameters.createIdParameter; +import static org.sonar.server.permission.ws.WsPermissionParameters.createTemplateDescriptionParameter; +import static org.sonar.server.permission.ws.WsPermissionParameters.createTemplateProjectKeyPatternParameter; +import static org.sonar.server.permission.ws.PermissionRequestValidator.MSG_TEMPLATE_WITH_SAME_NAME; +import static org.sonar.server.permission.ws.PermissionRequestValidator.validateProjectPattern; +import static org.sonar.server.permission.ws.PermissionRequestValidator.validateTemplateNameFormat; +import static org.sonar.server.permission.ws.template.PermissionTemplateDtoToPermissionTemplateResponse.toPermissionTemplateResponse; +import static org.sonar.server.ws.WsUtils.checkRequest; +import static org.sonar.server.ws.WsUtils.writeProtobuf; + +public class UpdateTemplateAction implements PermissionsWsAction { + private final DbClient dbClient; + private final UserSession userSession; + private final System2 system; + private final PermissionDependenciesFinder finder; + + public UpdateTemplateAction(DbClient dbClient, UserSession userSession, System2 system, PermissionDependenciesFinder finder) { + this.dbClient = dbClient; + this.userSession = userSession; + this.system = system; + this.finder = finder; + } + + @Override + public void define(WebService.NewController context) { + WebService.NewAction action = context.createAction("update_template") + .setDescription("Update a permission template.
    " + + "It requires administration permissions to access.") + .setResponseExample(getClass().getResource("update_template-example.json")) + .setSince("5.2") + .setPost(true) + .setHandler(this); + + createIdParameter(action); + + action.createParam(PARAM_NAME) + .setDescription("Name") + .setExampleValue("Financial Service Permissions"); + + createTemplateProjectKeyPatternParameter(action); + createTemplateDescriptionParameter(action); + } + + @Override + public void handle(Request wsRequest, Response wsResponse) throws Exception { + checkGlobalAdminUser(userSession); + + String uuid = wsRequest.mandatoryParam(PARAM_ID); + String nameParam = wsRequest.param(PARAM_NAME); + String descriptionParam = wsRequest.param(PARAM_DESCRIPTION); + String projectPatternParam = wsRequest.param(PARAM_PATTERN); + + DbSession dbSession = dbClient.openSession(false); + try { + PermissionTemplateDto templateToUpdate = getAndBuildTemplateToUpdate(dbSession, uuid, nameParam, descriptionParam, projectPatternParam); + validateTemplate(dbSession, templateToUpdate); + PermissionTemplateDto updatedTemplate = updateTemplate(dbSession, templateToUpdate); + + WsUpdatePermissionTemplateResponse response = buildResponse(updatedTemplate); + writeProtobuf(response, wsRequest, wsResponse); + } finally { + dbClient.closeSession(dbSession); + } + } + + private void validateTemplate(DbSession dbSession, PermissionTemplateDto templateToUpdate) { + validateTemplateNameForUpdate(dbSession, templateToUpdate.getName(), templateToUpdate.getId()); + validateProjectPattern(templateToUpdate.getKeyPattern()); + } + + private PermissionTemplateDto getAndBuildTemplateToUpdate(DbSession dbSession, String uuid, @Nullable String newName, @Nullable String newDescription, + @Nullable String newProjectKeyPattern) { + PermissionTemplateDto templateToUpdate = finder.getTemplate(dbSession, WsTemplateRef.newTemplateRef(uuid, null)); + templateToUpdate.setName(firstNonNull(newName, templateToUpdate.getName())); + templateToUpdate.setDescription(firstNonNull(newDescription, templateToUpdate.getDescription())); + templateToUpdate.setKeyPattern(firstNonNull(newProjectKeyPattern, templateToUpdate.getKeyPattern())); + templateToUpdate.setUpdatedAt(new Date(system.now())); + + return templateToUpdate; + } + + private PermissionTemplateDto updateTemplate(DbSession dbSession, PermissionTemplateDto templateToUpdate) { + return dbClient.permissionTemplateDao().update(dbSession, templateToUpdate); + } + + private static WsUpdatePermissionTemplateResponse buildResponse(PermissionTemplateDto permissionTemplate) { + PermissionTemplate permissionTemplateBuilder = toPermissionTemplateResponse(permissionTemplate); + return WsUpdatePermissionTemplateResponse.newBuilder().setPermissionTemplate(permissionTemplateBuilder).build(); + } + + private void validateTemplateNameForUpdate(DbSession dbSession, String name, long id) { + validateTemplateNameFormat(name); + + PermissionTemplateDto permissionTemplateWithSameName = dbClient.permissionTemplateDao().selectByName(dbSession, name); + checkRequest(permissionTemplateWithSameName == null || permissionTemplateWithSameName.getId() == id, + format(MSG_TEMPLATE_WITH_SAME_NAME, name)); + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/package-info.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/package-info.java new file mode 100644 index 00000000000..a252c1b8247 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/package-info.java @@ -0,0 +1,24 @@ +/* + * 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. + */ + +@ParametersAreNonnullByDefault +package org.sonar.server.permission.ws.template; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/server/sonar-server/src/main/resources/org/sonar/server/permission/ws/create_template-example.json b/server/sonar-server/src/main/resources/org/sonar/server/permission/ws/create_template-example.json deleted file mode 100644 index 5a49450b905..00000000000 --- a/server/sonar-server/src/main/resources/org/sonar/server/permission/ws/create_template-example.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "permissionTemplate": { - "id": "af8cb8cc-1e78-4c4e-8c00-ee8e814009a5", - "name": "Finance", - "description": "Permissions for financially related projects", - "projectKeyPattern": ".*\\.finance\\..*", - "createdAt": "2015-08-25T16:18:48+0200", - "updatedAt": "2015-08-25T16:18:48+0200" - } -} diff --git a/server/sonar-server/src/main/resources/org/sonar/server/permission/ws/search_templates-example.json b/server/sonar-server/src/main/resources/org/sonar/server/permission/ws/search_templates-example.json deleted file mode 100644 index 523c5ebf1d3..00000000000 --- a/server/sonar-server/src/main/resources/org/sonar/server/permission/ws/search_templates-example.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "permissionTemplates": [ - { - "id": "AU-TpxcA-iU5OvuD2FL0", - "name": "Default template for Developers", - "projectKeyPattern": ".*sonar.developer.*", - "createdAt": "2004-11-15T07:26:40+0100", - "updatedAt": "2004-11-19T22:33:20+0100", - "permissions": [ - { - "key": "user", - "usersCount": 0, - "groupsCount": 1 - } - ] - }, - { - "id": "AU-Tpxb--iU5OvuD2FLy", - "name": "Default template for Projects", - "description": "Template for new projects", - "createdAt": "2001-09-09T03:46:40+0200", - "updatedAt": "2001-09-09T03:46:40+0200", - "permissions": [ - { - "key": "admin", - "usersCount": 0, - "groupsCount": 1 - }, - { - "key": "codeviewer", - "usersCount": 1, - "groupsCount": 0 - }, - { - "key": "issueadmin", - "usersCount": 3, - "groupsCount": 0 - } - ] - }, - { - "id": "AU-TpxcA-iU5OvuD2FLz", - "name": "Default template for Views", - "description": "Template for new views", - "projectKeyPattern": ".*sonar.views.*", - "createdAt": "2001-09-09T03:46:40+0200", - "updatedAt": "2004-11-09T12:33:20+0100", - "permissions": [ - { - "key": "issueadmin", - "usersCount": 0, - "groupsCount": 3 - }, - { - "key": "user", - "usersCount": 2, - "groupsCount": 0 - } - ] - } - ], - "defaultTemplates": [ - { - "templateId": "AU-Tpxb--iU5OvuD2FLy", - "qualifier": "TRK" - }, - { - "templateId": "AU-TpxcA-iU5OvuD2FLz", - "qualifier": "VW" - }, - { - "templateId": "AU-TpxcA-iU5OvuD2FL0", - "qualifier": "DEV" - } - ], - "permissions": [ - { - "key": "user", - "name": "Browse", - "description": "Ability to access a project, browse its measures, and create/edit issues for it." - }, - { - "key": "admin", - "name": "Administer", - "description": "Ability to access project settings and perform administration tasks. (Users will also need \"Browse\" permission)" - }, - { - "key": "issueadmin", - "name": "Administer Issues", - "description": "Grants the permission to perform advanced editing on issues: marking an issue False Positive / Won\u0027t Fix or changing an Issue\u0027s severity. (Users will also need \"Browse\" permission)" - }, - { - "key": "codeviewer", - "name": "See Source Code", - "description": "Ability to view the project\u0027s source code. (Users will also need \"Browse\" permission)" - } - ] -} diff --git a/server/sonar-server/src/main/resources/org/sonar/server/permission/ws/template/create_template-example.json b/server/sonar-server/src/main/resources/org/sonar/server/permission/ws/template/create_template-example.json new file mode 100644 index 00000000000..5a49450b905 --- /dev/null +++ b/server/sonar-server/src/main/resources/org/sonar/server/permission/ws/template/create_template-example.json @@ -0,0 +1,10 @@ +{ + "permissionTemplate": { + "id": "af8cb8cc-1e78-4c4e-8c00-ee8e814009a5", + "name": "Finance", + "description": "Permissions for financially related projects", + "projectKeyPattern": ".*\\.finance\\..*", + "createdAt": "2015-08-25T16:18:48+0200", + "updatedAt": "2015-08-25T16:18:48+0200" + } +} diff --git a/server/sonar-server/src/main/resources/org/sonar/server/permission/ws/template/search_templates-example.json b/server/sonar-server/src/main/resources/org/sonar/server/permission/ws/template/search_templates-example.json new file mode 100644 index 00000000000..523c5ebf1d3 --- /dev/null +++ b/server/sonar-server/src/main/resources/org/sonar/server/permission/ws/template/search_templates-example.json @@ -0,0 +1,98 @@ +{ + "permissionTemplates": [ + { + "id": "AU-TpxcA-iU5OvuD2FL0", + "name": "Default template for Developers", + "projectKeyPattern": ".*sonar.developer.*", + "createdAt": "2004-11-15T07:26:40+0100", + "updatedAt": "2004-11-19T22:33:20+0100", + "permissions": [ + { + "key": "user", + "usersCount": 0, + "groupsCount": 1 + } + ] + }, + { + "id": "AU-Tpxb--iU5OvuD2FLy", + "name": "Default template for Projects", + "description": "Template for new projects", + "createdAt": "2001-09-09T03:46:40+0200", + "updatedAt": "2001-09-09T03:46:40+0200", + "permissions": [ + { + "key": "admin", + "usersCount": 0, + "groupsCount": 1 + }, + { + "key": "codeviewer", + "usersCount": 1, + "groupsCount": 0 + }, + { + "key": "issueadmin", + "usersCount": 3, + "groupsCount": 0 + } + ] + }, + { + "id": "AU-TpxcA-iU5OvuD2FLz", + "name": "Default template for Views", + "description": "Template for new views", + "projectKeyPattern": ".*sonar.views.*", + "createdAt": "2001-09-09T03:46:40+0200", + "updatedAt": "2004-11-09T12:33:20+0100", + "permissions": [ + { + "key": "issueadmin", + "usersCount": 0, + "groupsCount": 3 + }, + { + "key": "user", + "usersCount": 2, + "groupsCount": 0 + } + ] + } + ], + "defaultTemplates": [ + { + "templateId": "AU-Tpxb--iU5OvuD2FLy", + "qualifier": "TRK" + }, + { + "templateId": "AU-TpxcA-iU5OvuD2FLz", + "qualifier": "VW" + }, + { + "templateId": "AU-TpxcA-iU5OvuD2FL0", + "qualifier": "DEV" + } + ], + "permissions": [ + { + "key": "user", + "name": "Browse", + "description": "Ability to access a project, browse its measures, and create/edit issues for it." + }, + { + "key": "admin", + "name": "Administer", + "description": "Ability to access project settings and perform administration tasks. (Users will also need \"Browse\" permission)" + }, + { + "key": "issueadmin", + "name": "Administer Issues", + "description": "Grants the permission to perform advanced editing on issues: marking an issue False Positive / Won\u0027t Fix or changing an Issue\u0027s severity. (Users will also need \"Browse\" permission)" + }, + { + "key": "codeviewer", + "name": "See Source Code", + "description": "Ability to view the project\u0027s source code. (Users will also need \"Browse\" permission)" + } + ] +} diff --git a/server/sonar-server/src/main/resources/org/sonar/server/permission/ws/template/update_template-example.json b/server/sonar-server/src/main/resources/org/sonar/server/permission/ws/template/update_template-example.json new file mode 100644 index 00000000000..3ef72119a12 --- /dev/null +++ b/server/sonar-server/src/main/resources/org/sonar/server/permission/ws/template/update_template-example.json @@ -0,0 +1,10 @@ +{ + "permissionTemplate": { + "id": "af8cb8cc-1e78-4c4e-8c00-ee8e814009a5", + "name": "Finance", + "description": "Permissions for financially related projects", + "projectKeyPattern": ".*\\.finance\\..*", + "createdAt": "2001-09-09T03:46:40+0200", + "updatedAt": "2015-08-25T16:18:48+0200" + } +} diff --git a/server/sonar-server/src/main/resources/org/sonar/server/permission/ws/update_template-example.json b/server/sonar-server/src/main/resources/org/sonar/server/permission/ws/update_template-example.json deleted file mode 100644 index 3ef72119a12..00000000000 --- a/server/sonar-server/src/main/resources/org/sonar/server/permission/ws/update_template-example.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "permissionTemplate": { - "id": "af8cb8cc-1e78-4c4e-8c00-ee8e814009a5", - "name": "Finance", - "description": "Permissions for financially related projects", - "projectKeyPattern": ".*\\.finance\\..*", - "createdAt": "2001-09-09T03:46:40+0200", - "updatedAt": "2015-08-25T16:18:48+0200" - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/AddGroupToTemplateActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/AddGroupToTemplateActionTest.java deleted file mode 100644 index d84111c2965..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/AddGroupToTemplateActionTest.java +++ /dev/null @@ -1,255 +0,0 @@ -/* - * 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 com.google.common.base.Function; -import java.util.List; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; -import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; -import org.sonar.core.permission.GlobalPermissions; -import org.sonar.db.DbClient; -import org.sonar.db.DbSession; -import org.sonar.db.DbTester; -import org.sonar.db.permission.GroupWithPermissionDto; -import org.sonar.db.permission.PermissionQuery; -import org.sonar.db.permission.PermissionTemplateDto; -import org.sonar.db.user.GroupDto; -import org.sonar.server.component.ComponentFinder; -import org.sonar.server.exceptions.BadRequestException; -import org.sonar.server.exceptions.ForbiddenException; -import org.sonar.server.exceptions.NotFoundException; -import org.sonar.server.exceptions.UnauthorizedException; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.ws.TestRequest; -import org.sonar.server.ws.WsActionTester; -import org.sonar.test.DbTests; - -import static com.google.common.collect.FluentIterable.from; -import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.api.security.DefaultGroups.ANYONE; -import static org.sonar.api.web.UserRole.ADMIN; -import static org.sonar.api.web.UserRole.CODEVIEWER; -import static org.sonar.api.web.UserRole.ISSUE_ADMIN; -import static org.sonar.db.permission.PermissionTemplateTesting.newPermissionTemplateDto; -import static org.sonar.db.user.GroupMembershipQuery.IN; -import static org.sonar.db.user.GroupTesting.newGroupDto; -import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_GROUP_ID; -import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_GROUP_NAME; -import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_TEMPLATE_ID; -import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_PERMISSION; -import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_TEMPLATE_NAME; - -@Category(DbTests.class) -public class AddGroupToTemplateActionTest { - - private static final String GROUP_NAME = "group-name"; - @Rule - public DbTester db = DbTester.create(System2.INSTANCE); - @Rule - public ExpectedException expectedException = ExpectedException.none(); - @Rule - public UserSessionRule userSession = UserSessionRule.standalone(); - - WsActionTester ws; - DbClient dbClient; - DbSession dbSession; - GroupDto group; - PermissionTemplateDto permissionTemplate; - - @Before - public void setUp() { - dbClient = db.getDbClient(); - dbSession = db.getSession(); - userSession.login().setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); - - PermissionDependenciesFinder dependenciesFinder = new PermissionDependenciesFinder(dbClient, new ComponentFinder(dbClient)); - ws = new WsActionTester(new AddGroupToTemplateAction(dbClient, dependenciesFinder, userSession)); - - group = insertGroup(newGroupDto().setName(GROUP_NAME)); - permissionTemplate = insertPermissionTemplate(newPermissionTemplateDto()); - commit(); - } - - @Test - public void add_group_to_template() { - newRequest(GROUP_NAME, permissionTemplate.getKee(), CODEVIEWER); - - assertThat(getGroupNamesInTemplateAndPermission(permissionTemplate.getId(), CODEVIEWER)).containsExactly(GROUP_NAME); - } - - @Test - public void add_group_to_template_by_name() { - ws.newRequest() - .setParam(PARAM_GROUP_NAME, GROUP_NAME) - .setParam(PARAM_PERMISSION, CODEVIEWER) - .setParam(PARAM_TEMPLATE_NAME, permissionTemplate.getName().toUpperCase()) - .execute(); - commit(); - - assertThat(getGroupNamesInTemplateAndPermission(permissionTemplate.getId(), CODEVIEWER)).containsExactly(GROUP_NAME); - } - - @Test - public void add_with_group_id() { - ws.newRequest() - .setParam(PARAM_TEMPLATE_ID, permissionTemplate.getKee()) - .setParam(PARAM_PERMISSION, CODEVIEWER) - .setParam(PARAM_GROUP_ID, String.valueOf(group.getId())) - .execute(); - - assertThat(getGroupNamesInTemplateAndPermission(permissionTemplate.getId(), CODEVIEWER)).containsExactly(GROUP_NAME); - } - - @Test - public void does_not_add_a_group_twice() { - newRequest(GROUP_NAME, permissionTemplate.getKee(), ISSUE_ADMIN); - newRequest(GROUP_NAME, permissionTemplate.getKee(), ISSUE_ADMIN); - - assertThat(getGroupNamesInTemplateAndPermission(permissionTemplate.getId(), ISSUE_ADMIN)).containsExactly(GROUP_NAME); - } - - @Test - public void add_anyone_group_to_template() { - newRequest(ANYONE, permissionTemplate.getKee(), CODEVIEWER); - - assertThat(getGroupNamesInTemplateAndPermission(permissionTemplate.getId(), CODEVIEWER)).containsExactly(ANYONE); - } - - @Test - public void fail_if_add_anyone_group_to_admin_permission() { - expectedException.expect(BadRequestException.class); - expectedException.expectMessage(String.format("It is not possible to add the '%s' permission to the '%s' group.", UserRole.ADMIN, ANYONE)); - - newRequest(ANYONE, permissionTemplate.getKee(), ADMIN); - } - - @Test - public void fail_if_not_a_project_permission() { - expectedException.expect(BadRequestException.class); - - newRequest(GROUP_NAME, permissionTemplate.getKee(), GlobalPermissions.PREVIEW_EXECUTION); - } - - @Test - public void fail_if_insufficient_privileges() { - expectedException.expect(ForbiddenException.class); - userSession.setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); - - newRequest(GROUP_NAME, permissionTemplate.getKee(), CODEVIEWER); - } - - @Test - public void fail_if_not_logged_in() { - expectedException.expect(UnauthorizedException.class); - userSession.anonymous(); - - newRequest(GROUP_NAME, permissionTemplate.getKee(), CODEVIEWER); - } - - @Test - public void fail_if_group_params_missing() { - expectedException.expect(BadRequestException.class); - - newRequest(null, permissionTemplate.getKee(), CODEVIEWER); - } - - @Test - public void fail_if_permission_missing() { - expectedException.expect(IllegalArgumentException.class); - - newRequest(GROUP_NAME, permissionTemplate.getKee(), null); - } - - @Test - public void fail_if_template_uuid_and_name_missing() { - expectedException.expect(BadRequestException.class); - - newRequest(GROUP_NAME, null, CODEVIEWER); - } - - @Test - public void fail_if_group_does_not_exist() { - expectedException.expect(NotFoundException.class); - expectedException.expectMessage("Group with name 'unknown-group-name' is not found"); - - newRequest("unknown-group-name", permissionTemplate.getKee(), CODEVIEWER); - } - - @Test - public void fail_if_template_key_does_not_exist() { - expectedException.expect(NotFoundException.class); - expectedException.expectMessage("Permission template with id 'unknown-key' is not found"); - - newRequest(GROUP_NAME, "unknown-key", CODEVIEWER); - } - - private void newRequest(@Nullable String groupName, @Nullable String templateKey, @Nullable String permission) { - TestRequest request = ws.newRequest(); - if (groupName != null) { - request.setParam(WsPermissionParameters.PARAM_GROUP_NAME, groupName); - } - if (templateKey != null) { - request.setParam(PARAM_TEMPLATE_ID, templateKey); - } - if (permission != null) { - request.setParam(WsPermissionParameters.PARAM_PERMISSION, permission); - } - - request.execute(); - } - - private void commit() { - dbSession.commit(); - } - - private GroupDto insertGroup(GroupDto groupDto) { - return dbClient.groupDao().insert(dbSession, groupDto); - } - - private PermissionTemplateDto insertPermissionTemplate(PermissionTemplateDto permissionTemplate) { - return dbClient.permissionTemplateDao().insert(dbSession, permissionTemplate); - } - - private List getGroupNamesInTemplateAndPermission(long templateId, String permission) { - PermissionQuery permissionQuery = PermissionQuery.builder().permission(permission).membership(IN).build(); - return from(dbClient.permissionTemplateDao() - .selectGroups(dbSession, permissionQuery, templateId)) - .transform(GroupWithPermissionToGroupName.INSTANCE) - .toList(); - } - - private enum GroupWithPermissionToGroupName implements Function { - INSTANCE; - - @Override - public String apply(@Nonnull GroupWithPermissionDto groupWithPermission) { - return groupWithPermission.getName(); - } - - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/AddUserToTemplateActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/AddUserToTemplateActionTest.java deleted file mode 100644 index 6a28cbda890..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/AddUserToTemplateActionTest.java +++ /dev/null @@ -1,224 +0,0 @@ -/* - * 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 com.google.common.base.Function; -import java.util.List; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; -import org.sonar.api.utils.System2; -import org.sonar.core.permission.GlobalPermissions; -import org.sonar.db.DbClient; -import org.sonar.db.DbSession; -import org.sonar.db.DbTester; -import org.sonar.db.permission.PermissionQuery; -import org.sonar.db.permission.PermissionTemplateDto; -import org.sonar.db.permission.UserWithPermissionDto; -import org.sonar.db.user.UserDto; -import org.sonar.server.component.ComponentFinder; -import org.sonar.server.exceptions.BadRequestException; -import org.sonar.server.exceptions.ForbiddenException; -import org.sonar.server.exceptions.NotFoundException; -import org.sonar.server.exceptions.UnauthorizedException; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.ws.TestRequest; -import org.sonar.server.ws.WsActionTester; -import org.sonar.test.DbTests; - -import static com.google.common.collect.FluentIterable.from; -import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.api.web.UserRole.CODEVIEWER; -import static org.sonar.api.web.UserRole.ISSUE_ADMIN; -import static org.sonar.db.permission.PermissionTemplateTesting.newPermissionTemplateDto; -import static org.sonar.db.user.GroupMembershipQuery.IN; -import static org.sonar.db.user.UserTesting.newUserDto; -import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_PERMISSION; -import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_TEMPLATE_NAME; -import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_USER_LOGIN; - -@Category(DbTests.class) -public class AddUserToTemplateActionTest { - - private static final String USER_LOGIN = "user-login"; - @Rule - public DbTester db = DbTester.create(System2.INSTANCE); - @Rule - public ExpectedException expectedException = ExpectedException.none(); - @Rule - public UserSessionRule userSession = UserSessionRule.standalone(); - - WsActionTester ws; - DbClient dbClient; - DbSession dbSession; - UserDto user; - PermissionTemplateDto permissionTemplate; - - @Before - public void setUp() { - dbClient = db.getDbClient(); - dbSession = db.getSession(); - userSession.login().setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); - - PermissionDependenciesFinder dependenciesFinder = new PermissionDependenciesFinder(dbClient, new ComponentFinder(dbClient)); - ws = new WsActionTester(new AddUserToTemplateAction(dbClient, dependenciesFinder, userSession)); - - user = insertUser(newUserDto().setLogin(USER_LOGIN)); - permissionTemplate = insertPermissionTemplate(newPermissionTemplateDto()); - commit(); - } - - @Test - public void add_user_to_template() { - newRequest(USER_LOGIN, permissionTemplate.getKee(), CODEVIEWER); - - assertThat(getLoginsInTemplateAndPermission(permissionTemplate.getId(), CODEVIEWER)).containsExactly(USER_LOGIN); - } - - @Test - public void add_user_to_template_by_name() { - ws.newRequest() - .setParam(PARAM_USER_LOGIN, USER_LOGIN) - .setParam(PARAM_PERMISSION, CODEVIEWER) - .setParam(PARAM_TEMPLATE_NAME, permissionTemplate.getName().toUpperCase()) - .execute(); - commit(); - - assertThat(getLoginsInTemplateAndPermission(permissionTemplate.getId(), CODEVIEWER)).containsExactly(USER_LOGIN); - } - - @Test - public void does_not_add_a_user_twice() { - newRequest(USER_LOGIN, permissionTemplate.getKee(), ISSUE_ADMIN); - newRequest(USER_LOGIN, permissionTemplate.getKee(), ISSUE_ADMIN); - - assertThat(getLoginsInTemplateAndPermission(permissionTemplate.getId(), ISSUE_ADMIN)).containsExactly(USER_LOGIN); - } - - @Test - public void fail_if_not_a_project_permission() { - expectedException.expect(BadRequestException.class); - - newRequest(USER_LOGIN, permissionTemplate.getKee(), GlobalPermissions.PREVIEW_EXECUTION); - } - - @Test - public void fail_if_insufficient_privileges() { - expectedException.expect(ForbiddenException.class); - userSession.setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); - - newRequest(USER_LOGIN, permissionTemplate.getKee(), CODEVIEWER); - } - - @Test - public void fail_if_not_logged_in() { - expectedException.expect(UnauthorizedException.class); - userSession.anonymous(); - - newRequest(USER_LOGIN, permissionTemplate.getKee(), CODEVIEWER); - } - - @Test - public void fail_if_user_missing() { - expectedException.expect(IllegalArgumentException.class); - - newRequest(null, permissionTemplate.getKee(), CODEVIEWER); - } - - @Test - public void fail_if_permission_missing() { - expectedException.expect(IllegalArgumentException.class); - - newRequest(USER_LOGIN, permissionTemplate.getKee(), null); - } - - @Test - public void fail_if_template_uuid_and_name_are_missing() { - expectedException.expect(BadRequestException.class); - - newRequest(USER_LOGIN, null, CODEVIEWER); - } - - @Test - public void fail_if_user_does_not_exist() { - expectedException.expect(NotFoundException.class); - expectedException.expectMessage("User with login 'unknown-login' is not found"); - - newRequest("unknown-login", permissionTemplate.getKee(), CODEVIEWER); - } - - @Test - public void fail_if_template_key_does_not_exist() { - expectedException.expect(NotFoundException.class); - expectedException.expectMessage("Permission template with id 'unknown-key' is not found"); - - newRequest(USER_LOGIN, "unknown-key", CODEVIEWER); - } - - private void newRequest(@Nullable String userLogin, @Nullable String templateKey, @Nullable String permission) { - TestRequest request = ws.newRequest(); - if (userLogin != null) { - request.setParam(PARAM_USER_LOGIN, userLogin); - } - if (templateKey != null) { - request.setParam(WsPermissionParameters.PARAM_TEMPLATE_ID, templateKey); - } - if (permission != null) { - request.setParam(WsPermissionParameters.PARAM_PERMISSION, permission); - } - - request.execute(); - } - - private void commit() { - dbSession.commit(); - } - - private UserDto insertUser(UserDto userDto) { - return dbClient.userDao().insert(dbSession, userDto.setActive(true)); - } - - private PermissionTemplateDto insertPermissionTemplate(PermissionTemplateDto permissionTemplate) { - return dbClient.permissionTemplateDao().insert(dbSession, permissionTemplate); - } - - private List getLoginsInTemplateAndPermission(long templateId, String permission) { - PermissionQuery permissionQuery = PermissionQuery.builder().permission(permission).membership(IN).build(); - return from(dbClient.permissionTemplateDao() - .selectUsers(dbSession, permissionQuery, templateId, 0, Integer.MAX_VALUE)) - .transform(UserWithPermissionToUserLogin.INSTANCE) - .toList(); - } - - private enum UserWithPermissionToUserLogin implements Function { - INSTANCE; - - @Override - public String apply(@Nonnull UserWithPermissionDto userWithPermission) { - return userWithPermission.getLogin(); - } - - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/ApplyTemplateActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/ApplyTemplateActionTest.java deleted file mode 100644 index 27f64b19f6e..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/ApplyTemplateActionTest.java +++ /dev/null @@ -1,314 +0,0 @@ -/* - * 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 com.google.common.base.Predicate; -import com.google.common.collect.FluentIterable; -import java.util.List; -import javax.annotation.Nullable; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; -import org.sonar.api.config.Settings; -import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; -import org.sonar.core.permission.GlobalPermissions; -import org.sonar.db.DbClient; -import org.sonar.db.DbSession; -import org.sonar.db.DbTester; -import org.sonar.db.component.ComponentDto; -import org.sonar.db.permission.GroupWithPermissionDto; -import org.sonar.db.permission.PermissionQuery; -import org.sonar.db.permission.PermissionRepository; -import org.sonar.db.permission.PermissionTemplateDto; -import org.sonar.db.permission.UserWithPermissionDto; -import org.sonar.db.user.GroupDto; -import org.sonar.db.user.GroupRoleDto; -import org.sonar.db.user.UserDto; -import org.sonar.db.user.UserRoleDto; -import org.sonar.server.component.ComponentFinder; -import org.sonar.server.exceptions.BadRequestException; -import org.sonar.server.exceptions.ForbiddenException; -import org.sonar.server.exceptions.NotFoundException; -import org.sonar.server.exceptions.UnauthorizedException; -import org.sonar.server.issue.index.IssueAuthorizationIndexer; -import org.sonar.server.permission.PermissionFinder; -import org.sonar.server.permission.PermissionService; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.ws.TestRequest; -import org.sonar.server.ws.TestResponse; -import org.sonar.server.ws.WsActionTester; -import org.sonar.test.DbTests; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.sonar.db.component.ComponentTesting.newProjectDto; -import static org.sonar.db.permission.PermissionTemplateTesting.newPermissionTemplateDto; -import static org.sonar.db.user.GroupMembershipQuery.IN; -import static org.sonar.db.user.GroupTesting.newGroupDto; -import static org.sonar.db.user.UserTesting.newUserDto; -import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_PROJECT_ID; -import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_PROJECT_KEY; -import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_TEMPLATE_ID; -import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_TEMPLATE_NAME; - -@Category(DbTests.class) -public class ApplyTemplateActionTest { - - @Rule - public DbTester db = DbTester.create(System2.INSTANCE); - @Rule - public UserSessionRule userSession = UserSessionRule.standalone(); - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - WsActionTester ws; - DbClient dbClient; - DbSession dbSession; - - UserDto user1; - UserDto user2; - GroupDto group1; - GroupDto group2; - ComponentDto project; - PermissionTemplateDto template1; - PermissionTemplateDto template2; - IssueAuthorizationIndexer issueAuthorizationIndexer = mock(IssueAuthorizationIndexer.class); - - @Before - public void setUp() { - userSession.login("login").setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); - dbClient = db.getDbClient(); - dbSession = db.getSession(); - - PermissionRepository repository = new PermissionRepository(dbClient, new Settings()); - PermissionFinder permissionFinder = new PermissionFinder(dbClient); - ComponentFinder componentFinder = new ComponentFinder(dbClient); - PermissionService permissionService = new PermissionService(dbClient, repository, issueAuthorizationIndexer, userSession, componentFinder); - PermissionDependenciesFinder permissionDependenciesFinder = new PermissionDependenciesFinder(dbClient, componentFinder); - - ApplyTemplateAction underTest = new ApplyTemplateAction(dbClient, permissionService, permissionDependenciesFinder); - ws = new WsActionTester(underTest); - - user1 = insertUser(newUserDto().setLogin("user-login-1")); - user2 = insertUser(newUserDto().setLogin("user-login-2")); - group1 = insertGroup(newGroupDto().setName("group-name-1")); - group2 = insertGroup(newGroupDto().setName("group-name-2")); - - // template 1 - template1 = insertTemplate(newPermissionTemplateDto().setUuid("permission-template-uuid-1")); - addUserToTemplate(user1, template1, UserRole.CODEVIEWER); - addUserToTemplate(user2, template1, UserRole.ISSUE_ADMIN); - addGroupToTemplate(group1, template1, UserRole.ADMIN); - addGroupToTemplate(group2, template1, UserRole.USER); - // template 2 - template2 = insertTemplate(newPermissionTemplateDto().setUuid("permission-template-uuid-2")); - addUserToTemplate(user1, template2, UserRole.USER); - addUserToTemplate(user2, template2, UserRole.USER); - addGroupToTemplate(group1, template2, UserRole.USER); - addGroupToTemplate(group2, template2, UserRole.USER); - - project = insertProject(newProjectDto("project-uuid-1")); - addUserPermissionToProject(user1, project, UserRole.ADMIN); - addUserPermissionToProject(user2, project, UserRole.ADMIN); - addGroupPermissionToProject(group1, project, UserRole.ADMIN); - addGroupPermissionToProject(group2, project, UserRole.ADMIN); - - commit(); - } - - @Test - public void apply_template_with_project_uuid() { - assertThat(selectProjectPermissionGroups(project, UserRole.ADMIN)).hasSize(2); - assertThat(selectProjectPermissionUsers(project, UserRole.ADMIN)).hasSize(2); - - newRequest(template1.getUuid(), project.uuid(), null); - - assertTemplate1AppliedToProject(); - verify(issueAuthorizationIndexer).index(); - } - - @Test - public void apply_template_with_project_uuid_by_template_name() { - ws.newRequest() - .setParam(PARAM_TEMPLATE_NAME, template1.getName().toUpperCase()) - .setParam(PARAM_PROJECT_ID, project.uuid()) - .execute(); - commit(); - - assertTemplate1AppliedToProject(); - } - - @Test - public void apply_template_with_project_key() { - newRequest(template1.getUuid(), null, project.key()); - - assertTemplate1AppliedToProject(); - } - - @Test - public void fail_when_unknown_template() { - expectedException.expect(NotFoundException.class); - expectedException.expectMessage("Permission template with id 'unknown-template-uuid' is not found"); - - newRequest("unknown-template-uuid", project.uuid(), null); - } - - @Test - public void fail_when_unknown_project_uuid() { - expectedException.expect(NotFoundException.class); - expectedException.expectMessage("Project id 'unknown-project-uuid' not found"); - - newRequest(template1.getUuid(), "unknown-project-uuid", null); - } - - @Test - public void fail_when_unknown_project_key() { - expectedException.expect(NotFoundException.class); - expectedException.expectMessage("Project key 'unknown-project-key' not found"); - - newRequest(template1.getUuid(), null, "unknown-project-key"); - } - - @Test - public void fail_when_template_is_not_provided() { - expectedException.expect(BadRequestException.class); - - newRequest(null, project.uuid(), null); - } - - @Test - public void fail_when_project_uuid_and_key_not_provided() { - expectedException.expect(BadRequestException.class); - expectedException.expectMessage("Project id or project key must be provided, not both."); - - newRequest(template1.getUuid(), null, null); - } - - @Test - public void fail_when_anonymous() { - expectedException.expect(UnauthorizedException.class); - userSession.anonymous(); - - newRequest(template1.getUuid(), project.uuid(), null); - } - - @Test - public void fail_when_insufficient_privileges() { - expectedException.expect(ForbiddenException.class); - userSession.login().setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION); - - newRequest(template1.getUuid(), project.uuid(), null); - } - - private void assertTemplate1AppliedToProject() { - assertThat(selectProjectPermissionGroups(project, UserRole.ADMIN)).extracting("name").containsExactly(group1.getName()); - assertThat(selectProjectPermissionGroups(project, UserRole.USER)).extracting("name").containsExactly(group2.getName()); - assertThat(selectProjectPermissionUsers(project, UserRole.ADMIN)).isEmpty(); - assertThat(selectProjectPermissionUsers(project, UserRole.CODEVIEWER)).extracting("login").containsExactly(user1.getLogin()); - assertThat(selectProjectPermissionUsers(project, UserRole.ISSUE_ADMIN)).extracting("login").containsExactly(user2.getLogin()); - } - - private TestResponse newRequest(@Nullable String templateUuid, @Nullable String projectUuid, @Nullable String projectKey) { - TestRequest request = ws.newRequest(); - if (templateUuid != null) { - request.setParam(PARAM_TEMPLATE_ID, templateUuid); - } - if (projectUuid != null) { - request.setParam(PARAM_PROJECT_ID, projectUuid); - } - if (projectKey != null) { - request.setParam(PARAM_PROJECT_KEY, projectKey); - } - - TestResponse result = request.execute(); - commit(); - - return result; - } - - private ComponentDto insertProject(ComponentDto project) { - dbClient.componentDao().insert(dbSession, project); - return dbClient.componentDao().selectOrFailByUuid(dbSession, project.uuid()); - } - - private PermissionTemplateDto insertTemplate(PermissionTemplateDto template) { - return dbClient.permissionTemplateDao().insert(dbSession, template); - } - - private UserDto insertUser(UserDto userDto) { - return dbClient.userDao().insert(dbSession, userDto.setActive(true)); - } - - private GroupDto insertGroup(GroupDto group) { - return dbClient.groupDao().insert(dbSession, group); - } - - private void addUserToTemplate(UserDto user, PermissionTemplateDto permissionTemplate, String permission) { - dbClient.permissionTemplateDao().insertUserPermission(dbSession, permissionTemplate.getId(), user.getId(), permission); - } - - private void addGroupToTemplate(GroupDto group, PermissionTemplateDto permissionTemplate, String permission) { - dbClient.permissionTemplateDao().insertGroupPermission(dbSession, permissionTemplate.getId(), group.getId(), permission); - } - - private void addUserPermissionToProject(UserDto user, ComponentDto project, String permission) { - dbClient.roleDao().insertUserRole(dbSession, new UserRoleDto() - .setRole(permission) - .setUserId(user.getId()) - .setResourceId(project.getId())); - } - - private void addGroupPermissionToProject(GroupDto group, ComponentDto project, String permission) { - dbClient.roleDao().insertGroupRole(dbSession, new GroupRoleDto() - .setRole(permission) - .setResourceId(project.getId()) - .setGroupId(group.getId())); - } - - private List selectProjectPermissionGroups(ComponentDto project, String permission) { - return FluentIterable.from(dbClient.permissionDao().selectGroups(dbSession, query(permission), project.getId())) - .filter(new PermissionNotNull()) - .toList(); - } - - private List selectProjectPermissionUsers(ComponentDto project, String permission) { - return dbClient.permissionDao().selectUsers(dbSession, query(permission), project.getId(), 0, Integer.MAX_VALUE); - } - - private void commit() { - dbSession.commit(); - } - - private static PermissionQuery query(String permission) { - return PermissionQuery.builder().membership(IN).permission(permission).build(); - } - - private static class PermissionNotNull implements Predicate { - @Override - public boolean apply(@Nullable GroupWithPermissionDto input) { - return input.getPermission() != null; - } - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/CreateTemplateActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/CreateTemplateActionTest.java deleted file mode 100644 index 160aebb1afe..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/CreateTemplateActionTest.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * 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 javax.annotation.Nullable; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.utils.System2; -import org.sonar.core.permission.GlobalPermissions; -import org.sonar.db.DbClient; -import org.sonar.db.DbSession; -import org.sonar.db.DbTester; -import org.sonar.db.permission.PermissionTemplateDto; -import org.sonar.server.exceptions.BadRequestException; -import org.sonar.server.exceptions.ForbiddenException; -import org.sonar.server.exceptions.UnauthorizedException; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.ws.TestRequest; -import org.sonar.server.ws.TestResponse; -import org.sonar.server.ws.WsActionTester; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.sonar.db.permission.PermissionTemplateTesting.newPermissionTemplateDto; -import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_DESCRIPTION; -import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_NAME; -import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_PATTERN; -import static org.sonar.test.JsonAssert.assertJson; - -public class CreateTemplateActionTest { - - @Rule - public DbTester db = DbTester.create(System2.INSTANCE); - @Rule - public UserSessionRule userSession = UserSessionRule.standalone(); - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - WsActionTester ws; - DbClient dbClient; - DbSession dbSession; - System2 system = mock(System2.class); - - @Before - public void setUp() { - userSession.login().setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); - when(system.now()).thenReturn(1440512328743L); - - dbClient = db.getDbClient(); - dbSession = db.getSession(); - ws = new WsActionTester(new CreateTemplateAction(dbClient, userSession, system)); - } - - @Test - public void create_full_permission_template() { - TestResponse result = newRequest("Finance", "Permissions for financially related projects", ".*\\.finance\\..*"); - - assertJson(result.getInput()) - .ignoreFields("id") - .isSimilarTo(getClass().getResource("create_template-example.json")); - PermissionTemplateDto finance = dbClient.permissionTemplateDao().selectByName(dbSession, "Finance"); - assertThat(finance.getName()).isEqualTo("Finance"); - assertThat(finance.getDescription()).isEqualTo("Permissions for financially related projects"); - assertThat(finance.getKeyPattern()).isEqualTo(".*\\.finance\\..*"); - assertThat(finance.getKee()).isNotEmpty(); - assertThat(finance.getCreatedAt().getTime()).isEqualTo(1440512328743L); - assertThat(finance.getUpdatedAt().getTime()).isEqualTo(1440512328743L); - } - - @Test - public void create_minimalist_permission_template() { - newRequest("Finance", null, null); - - PermissionTemplateDto finance = dbClient.permissionTemplateDao().selectByName(dbSession, "Finance"); - assertThat(finance.getName()).isEqualTo("Finance"); - assertThat(finance.getDescription()).isNullOrEmpty(); - assertThat(finance.getKeyPattern()).isNullOrEmpty(); - assertThat(finance.getKee()).isNotEmpty(); - assertThat(finance.getCreatedAt().getTime()).isEqualTo(1440512328743L); - assertThat(finance.getUpdatedAt().getTime()).isEqualTo(1440512328743L); - } - - @Test - public void fail_if_name_not_provided() { - expectedException.expect(IllegalArgumentException.class); - - newRequest(null, null, null); - } - - @Test - public void fail_if_name_empty() { - expectedException.expect(BadRequestException.class); - expectedException.expectMessage("The template name must not be blank"); - - newRequest("", null, null); - } - - @Test - public void fail_if_regexp_if_not_valid() { - expectedException.expect(BadRequestException.class); - expectedException.expectMessage("The 'projectKeyPattern' parameter must be a valid Java regular expression. '[azerty' was passed"); - - newRequest("Finance", null, "[azerty"); - } - - @Test - public void fail_if_name_already_exists_in_database_case_insensitive() { - expectedException.expect(BadRequestException.class); - expectedException.expectMessage("A template with the name 'Finance' already exists (case insensitive)."); - insertTemplate(newPermissionTemplateDto().setName("finance")); - commit(); - - newRequest("Finance", null, null); - } - - @Test - public void fail_if_not_logged_in() { - expectedException.expect(UnauthorizedException.class); - userSession.anonymous(); - - newRequest("Finance", null, null); - } - - @Test - public void fail_if_not_admin() { - expectedException.expect(ForbiddenException.class); - userSession.setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); - - newRequest("Finance", null, null); - } - - private PermissionTemplateDto insertTemplate(PermissionTemplateDto template) { - return dbClient.permissionTemplateDao().insert(dbSession, template); - } - - private void commit() { - dbSession.commit(); - } - - private TestResponse newRequest(@Nullable String name, @Nullable String description, @Nullable String projectPattern) { - TestRequest request = ws.newRequest(); - if (name != null) { - request.setParam(PARAM_NAME, name); - } - if (description != null) { - request.setParam(PARAM_DESCRIPTION, description); - } - if (projectPattern != null) { - request.setParam(PARAM_PATTERN, projectPattern); - } - - return request.execute(); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/DefaultPermissionTemplateFinderTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/DefaultPermissionTemplateFinderTest.java deleted file mode 100644 index 5831af38b1f..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/DefaultPermissionTemplateFinderTest.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * 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 java.util.List; -import java.util.Set; -import org.junit.Before; -import org.junit.Test; -import org.sonar.api.config.Settings; -import org.sonar.api.resources.Qualifiers; -import org.sonar.api.resources.ResourceType; -import org.sonar.api.resources.ResourceTypes; - -import static java.util.Arrays.asList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.sonar.server.permission.DefaultPermissionTemplates.DEFAULT_TEMPLATE_PROPERTY; -import static org.sonar.server.permission.DefaultPermissionTemplates.defaultRootQualifierTemplateProperty; - -public class DefaultPermissionTemplateFinderTest { - - ResourceTypes resourceTypes = mock(ResourceTypes.class); - Settings settings = new Settings(); - - DefaultPermissionTemplateFinder underTest; - - @Before - public void setUp() { - underTest = new DefaultPermissionTemplateFinder(settings, resourceTypes); - settings - .setProperty(DEFAULT_TEMPLATE_PROPERTY, "default-template-uuid") - .setProperty(defaultRootQualifierTemplateProperty(Qualifiers.PROJECT), "default-project-template-uuid") - .setProperty(defaultRootQualifierTemplateProperty("DEV"), "default-dev-template-uuid") - .setProperty(defaultRootQualifierTemplateProperty(Qualifiers.VIEW), "default-view-template-uuid"); - when(resourceTypes.getRoots()).thenReturn(rootResourceTypes()); - } - - @Test - public void get_default_template_uuids_in_settings() { - Set result = underTest.getDefaultTemplateUuids(); - - assertThat(result).containsOnly("default-project-template-uuid", "default-view-template-uuid", "default-dev-template-uuid"); - } - - @Test - public void get_default_template_uuid_if_no_property() { - settings = new Settings(); - settings.setProperty(DEFAULT_TEMPLATE_PROPERTY, "default-template-uuid"); - underTest = new DefaultPermissionTemplateFinder(settings, resourceTypes); - - Set result = underTest.getDefaultTemplateUuids(); - - assertThat(result).containsOnly("default-template-uuid"); - } - - private static List rootResourceTypes() { - ResourceType project = ResourceType.builder(Qualifiers.PROJECT).build(); - ResourceType view = ResourceType.builder(Qualifiers.VIEW).build(); - ResourceType dev = ResourceType.builder("DEV").build(); - - return asList(project, view, dev); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/DeleteTemplateActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/DeleteTemplateActionTest.java deleted file mode 100644 index 33575ba5b19..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/DeleteTemplateActionTest.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * 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 java.util.Collections; -import javax.annotation.Nullable; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; -import org.sonar.core.permission.GlobalPermissions; -import org.sonar.db.DbClient; -import org.sonar.db.DbSession; -import org.sonar.db.DbTester; -import org.sonar.db.permission.PermissionTemplateDto; -import org.sonar.db.user.GroupDto; -import org.sonar.db.user.GroupTesting; -import org.sonar.db.user.UserDto; -import org.sonar.db.user.UserTesting; -import org.sonar.server.component.ComponentFinder; -import org.sonar.server.exceptions.BadRequestException; -import org.sonar.server.exceptions.ForbiddenException; -import org.sonar.server.exceptions.NotFoundException; -import org.sonar.server.exceptions.UnauthorizedException; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.ws.TestRequest; -import org.sonar.server.ws.TestResponse; -import org.sonar.server.ws.WsActionTester; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.mockito.internal.util.collections.Sets.newSet; -import static org.sonar.db.permission.PermissionTemplateTesting.newPermissionTemplateDto; -import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_TEMPLATE_ID; -import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_TEMPLATE_NAME; - -public class DeleteTemplateActionTest { - - static final String TEMPLATE_UUID = "permission-template-uuid"; - - @Rule - public DbTester db = DbTester.create(System2.INSTANCE); - @Rule - public UserSessionRule userSession = UserSessionRule.standalone(); - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - WsActionTester ws; - DbClient dbClient; - DbSession dbSession; - DefaultPermissionTemplateFinder defaultTemplatePermissionFinder; - - PermissionTemplateDto permissionTemplate; - - @Before - public void setUp() { - userSession.login().setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); - - dbClient = db.getDbClient(); - dbSession = db.getSession(); - defaultTemplatePermissionFinder = mock(DefaultPermissionTemplateFinder.class); - when(defaultTemplatePermissionFinder.getDefaultTemplateUuids()).thenReturn(Collections.emptySet()); - PermissionDependenciesFinder finder = new PermissionDependenciesFinder(dbClient, new ComponentFinder(dbClient)); - ws = new WsActionTester(new DeleteTemplateAction(dbClient, userSession, finder, defaultTemplatePermissionFinder)); - - permissionTemplate = insertTemplateAndAssociatedPermissions(newPermissionTemplateDto().setKee(TEMPLATE_UUID)); - PermissionTemplateDto permissionTemplateInDatabase = dbClient.permissionTemplateDao().selectByUuidWithUserAndGroupPermissions(dbSession, TEMPLATE_UUID); - assertThat(permissionTemplateInDatabase.getKee()).isEqualTo(TEMPLATE_UUID); - assertThat(permissionTemplateInDatabase.getGroupsPermissions()).isNotEmpty(); - assertThat(permissionTemplateInDatabase.getUsersPermissions()).isNotEmpty(); - } - - @Test - public void delete_template_in_db() { - TestResponse result = newRequest(TEMPLATE_UUID); - - assertThat(result.getInput()).isEmpty(); - assertThat(dbClient.permissionTemplateDao().selectByUuidWithUserAndGroupPermissions(dbSession, TEMPLATE_UUID)).isNull(); - } - - @Test - public void delete_template_by_name_case_insensitive() { - ws.newRequest() - .setParam(PARAM_TEMPLATE_NAME, permissionTemplate.getName().toUpperCase()) - .execute(); - commit(); - - assertThat(dbClient.permissionTemplateDao().selectByUuidWithUserAndGroupPermissions(dbSession, TEMPLATE_UUID)).isNull(); - } - - @Test - public void fail_if_uuid_is_not_known() { - expectedException.expect(NotFoundException.class); - - newRequest("unknown-template-uuid"); - } - - @Test - public void fail_if_template_is_default() { - expectedException.expect(BadRequestException.class); - expectedException.expectMessage("It is not possible to delete a default template"); - when(defaultTemplatePermissionFinder.getDefaultTemplateUuids()).thenReturn(newSet(TEMPLATE_UUID)); - - newRequest(TEMPLATE_UUID); - } - - @Test - public void fail_if_not_logged_in() { - expectedException.expect(UnauthorizedException.class); - userSession.anonymous(); - - newRequest(TEMPLATE_UUID); - } - - @Test - public void fail_if_not_admin() { - expectedException.expect(ForbiddenException.class); - userSession.login().setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); - - newRequest(TEMPLATE_UUID); - } - - @Test - public void fail_if_uuid_is_not_provided() { - expectedException.expect(BadRequestException.class); - - newRequest(null); - } - - private PermissionTemplateDto insertTemplateAndAssociatedPermissions(PermissionTemplateDto template) { - dbClient.permissionTemplateDao().insert(dbSession, template); - UserDto user = dbClient.userDao().insert(dbSession, UserTesting.newUserDto().setActive(true)); - GroupDto group = dbClient.groupDao().insert(dbSession, GroupTesting.newGroupDto()); - dbClient.permissionTemplateDao().insertUserPermission(dbSession, template.getId(), user.getId(), UserRole.ADMIN); - dbClient.permissionTemplateDao().insertGroupPermission(dbSession, template.getId(), group.getId(), UserRole.CODEVIEWER); - commit(); - - return template; - } - - private void commit() { - dbSession.commit(); - } - - private TestResponse newRequest(@Nullable String id) { - TestRequest request = ws.newRequest(); - if (id != null) { - request.setParam(PARAM_TEMPLATE_ID, id); - } - - TestResponse result = executeRequest(request); - commit(); - return result; - } - - private static TestResponse executeRequest(TestRequest request) { - return request.execute(); - } - -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/RemoveGroupFromTemplateActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/RemoveGroupFromTemplateActionTest.java deleted file mode 100644 index 517a9885abe..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/RemoveGroupFromTemplateActionTest.java +++ /dev/null @@ -1,262 +0,0 @@ -/* - * 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 com.google.common.base.Function; -import java.util.List; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; -import org.sonar.api.utils.System2; -import org.sonar.core.permission.GlobalPermissions; -import org.sonar.db.DbClient; -import org.sonar.db.DbSession; -import org.sonar.db.DbTester; -import org.sonar.db.permission.GroupWithPermissionDto; -import org.sonar.db.permission.PermissionQuery; -import org.sonar.db.permission.PermissionTemplateDto; -import org.sonar.db.user.GroupDto; -import org.sonar.server.component.ComponentFinder; -import org.sonar.server.exceptions.BadRequestException; -import org.sonar.server.exceptions.ForbiddenException; -import org.sonar.server.exceptions.NotFoundException; -import org.sonar.server.exceptions.UnauthorizedException; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.ws.TestRequest; -import org.sonar.server.ws.WsActionTester; -import org.sonar.test.DbTests; - -import static com.google.common.collect.FluentIterable.from; -import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.api.security.DefaultGroups.ANYONE; -import static org.sonar.api.web.UserRole.CODEVIEWER; -import static org.sonar.db.permission.PermissionTemplateTesting.newPermissionTemplateDto; -import static org.sonar.db.user.GroupMembershipQuery.IN; -import static org.sonar.db.user.GroupTesting.newGroupDto; -import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_GROUP_ID; -import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_GROUP_NAME; -import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_PERMISSION; -import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_TEMPLATE_ID; -import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_TEMPLATE_NAME; - -@Category(DbTests.class) -public class RemoveGroupFromTemplateActionTest { - - private static final String GROUP_NAME = "group-name"; - private static final String PERMISSION = CODEVIEWER; - @Rule - public DbTester db = DbTester.create(System2.INSTANCE); - @Rule - public ExpectedException expectedException = ExpectedException.none(); - @Rule - public UserSessionRule userSession = UserSessionRule.standalone(); - - WsActionTester ws; - DbClient dbClient; - DbSession dbSession; - GroupDto group; - PermissionTemplateDto permissionTemplate; - - @Before - public void setUp() { - dbClient = db.getDbClient(); - dbSession = db.getSession(); - userSession.login().setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); - - PermissionDependenciesFinder dependenciesFinder = new PermissionDependenciesFinder(dbClient, new ComponentFinder(dbClient)); - ws = new WsActionTester(new RemoveGroupFromTemplateAction(dbClient, dependenciesFinder, userSession)); - - group = insertGroup(newGroupDto().setName(GROUP_NAME)); - permissionTemplate = insertPermissionTemplate(newPermissionTemplateDto()); - addGroupToPermissionTemplate(permissionTemplate.getId(), group.getId(), PERMISSION); - commit(); - } - - @Test - public void remove_group_from_template() { - assertThat(getGroupNamesInTemplateAndPermission(permissionTemplate.getId(), PERMISSION)).containsExactly(GROUP_NAME); - commit(); - - newRequest(GROUP_NAME, permissionTemplate.getKee(), PERMISSION); - - assertThat(getGroupNamesInTemplateAndPermission(permissionTemplate.getId(), PERMISSION)).isEmpty(); - } - - @Test - public void remove_group_from_template_by_name_case_insensitive() { - assertThat(getGroupNamesInTemplateAndPermission(permissionTemplate.getId(), PERMISSION)).containsExactly(GROUP_NAME); - commit(); - - ws.newRequest() - .setParam(PARAM_GROUP_NAME, GROUP_NAME) - .setParam(PARAM_PERMISSION, PERMISSION) - .setParam(PARAM_TEMPLATE_NAME, permissionTemplate.getName().toUpperCase()) - .execute(); - commit(); - - assertThat(getGroupNamesInTemplateAndPermission(permissionTemplate.getId(), PERMISSION)).isEmpty(); - } - - @Test - public void remove_group_with_group_id() { - assertThat(getGroupNamesInTemplateAndPermission(permissionTemplate.getId(), PERMISSION)).containsExactly(GROUP_NAME); - commit(); - - ws.newRequest() - .setParam(PARAM_TEMPLATE_ID, permissionTemplate.getKee()) - .setParam(PARAM_PERMISSION, PERMISSION) - .setParam(PARAM_GROUP_ID, String.valueOf(group.getId())) - .execute(); - - assertThat(getGroupNamesInTemplateAndPermission(permissionTemplate.getId(), PERMISSION)).isEmpty(); - } - - @Test - public void remove_group_twice_without_error() { - newRequest(GROUP_NAME, permissionTemplate.getKee(), PERMISSION); - newRequest(GROUP_NAME, permissionTemplate.getKee(), PERMISSION); - - assertThat(getGroupNamesInTemplateAndPermission(permissionTemplate.getId(), PERMISSION)).isEmpty(); - } - - @Test - public void remove_anyone_group_from_template() { - addGroupToPermissionTemplate(permissionTemplate.getId(), null, PERMISSION); - commit(); - - newRequest(ANYONE, permissionTemplate.getKee(), PERMISSION); - - assertThat(getGroupNamesInTemplateAndPermission(permissionTemplate.getId(), PERMISSION)).containsExactly(GROUP_NAME); - } - - @Test - public void fail_if_not_a_project_permission() { - expectedException.expect(BadRequestException.class); - - newRequest(GROUP_NAME, permissionTemplate.getKee(), GlobalPermissions.PREVIEW_EXECUTION); - } - - @Test - public void fail_if_insufficient_privileges() { - expectedException.expect(ForbiddenException.class); - userSession.setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); - - newRequest(GROUP_NAME, permissionTemplate.getKee(), PERMISSION); - } - - @Test - public void fail_if_not_logged_in() { - expectedException.expect(UnauthorizedException.class); - userSession.anonymous(); - - newRequest(GROUP_NAME, permissionTemplate.getKee(), PERMISSION); - } - - @Test - public void fail_if_group_params_missing() { - expectedException.expect(BadRequestException.class); - - newRequest(null, permissionTemplate.getKee(), PERMISSION); - } - - @Test - public void fail_if_permission_missing() { - expectedException.expect(IllegalArgumentException.class); - - newRequest(GROUP_NAME, permissionTemplate.getKee(), null); - } - - @Test - public void fail_if_template_missing() { - expectedException.expect(BadRequestException.class); - - newRequest(GROUP_NAME, null, PERMISSION); - } - - @Test - public void fail_if_group_does_not_exist() { - expectedException.expect(NotFoundException.class); - expectedException.expectMessage("Group with name 'unknown-group-name' is not found"); - - newRequest("unknown-group-name", permissionTemplate.getKee(), PERMISSION); - } - - @Test - public void fail_if_template_key_does_not_exist() { - expectedException.expect(NotFoundException.class); - expectedException.expectMessage("Permission template with id 'unknown-key' is not found"); - - newRequest(GROUP_NAME, "unknown-key", PERMISSION); - } - - private void newRequest(@Nullable String groupName, @Nullable String templateKey, @Nullable String permission) { - TestRequest request = ws.newRequest(); - if (groupName != null) { - request.setParam(WsPermissionParameters.PARAM_GROUP_NAME, groupName); - } - if (templateKey != null) { - request.setParam(PARAM_TEMPLATE_ID, templateKey); - } - if (permission != null) { - request.setParam(WsPermissionParameters.PARAM_PERMISSION, permission); - } - - request.execute(); - } - - private void commit() { - dbSession.commit(); - } - - private GroupDto insertGroup(GroupDto groupDto) { - return dbClient.groupDao().insert(dbSession, groupDto); - } - - private PermissionTemplateDto insertPermissionTemplate(PermissionTemplateDto permissionTemplate) { - return dbClient.permissionTemplateDao().insert(dbSession, permissionTemplate); - } - - private void addGroupToPermissionTemplate(long permissionTemplateId, @Nullable Long groupId, String permission) { - dbClient.permissionTemplateDao().insertGroupPermission(dbSession, permissionTemplateId, groupId, permission); - } - - private List getGroupNamesInTemplateAndPermission(long templateId, String permission) { - PermissionQuery permissionQuery = PermissionQuery.builder().permission(permission).membership(IN).build(); - return from(dbClient.permissionTemplateDao() - .selectGroups(dbSession, permissionQuery, templateId)) - .transform(GroupWithPermissionToGroupName.INSTANCE) - .toList(); - } - - private enum GroupWithPermissionToGroupName implements Function { - INSTANCE; - - @Override - public String apply(@Nonnull GroupWithPermissionDto groupWithPermission) { - return groupWithPermission.getName(); - } - - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/RemoveUserFromTemplateActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/RemoveUserFromTemplateActionTest.java deleted file mode 100644 index 7d71fdd1eb6..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/RemoveUserFromTemplateActionTest.java +++ /dev/null @@ -1,252 +0,0 @@ -/* - * 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 com.google.common.base.Function; -import java.util.List; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; -import org.sonar.api.utils.System2; -import org.sonar.core.permission.GlobalPermissions; -import org.sonar.db.DbClient; -import org.sonar.db.DbSession; -import org.sonar.db.DbTester; -import org.sonar.db.permission.PermissionQuery; -import org.sonar.db.permission.PermissionTemplateDto; -import org.sonar.db.permission.UserWithPermissionDto; -import org.sonar.db.user.UserDto; -import org.sonar.server.component.ComponentFinder; -import org.sonar.server.exceptions.BadRequestException; -import org.sonar.server.exceptions.ForbiddenException; -import org.sonar.server.exceptions.NotFoundException; -import org.sonar.server.exceptions.UnauthorizedException; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.ws.TestRequest; -import org.sonar.server.ws.WsActionTester; -import org.sonar.test.DbTests; - -import static com.google.common.collect.FluentIterable.from; -import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.api.web.UserRole.CODEVIEWER; -import static org.sonar.api.web.UserRole.ISSUE_ADMIN; -import static org.sonar.db.permission.PermissionTemplateTesting.newPermissionTemplateDto; -import static org.sonar.db.user.GroupMembershipQuery.IN; -import static org.sonar.db.user.UserTesting.newUserDto; -import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_PERMISSION; -import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_TEMPLATE_NAME; -import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_USER_LOGIN; - -@Category(DbTests.class) -public class RemoveUserFromTemplateActionTest { - - private static final String USER_LOGIN = "user-login"; - private static final String DEFAULT_PERMISSION = CODEVIEWER; - @Rule - public DbTester db = DbTester.create(System2.INSTANCE); - @Rule - public ExpectedException expectedException = ExpectedException.none(); - @Rule - public UserSessionRule userSession = UserSessionRule.standalone(); - - WsActionTester ws; - DbClient dbClient; - DbSession dbSession; - UserDto user; - PermissionTemplateDto permissionTemplate; - - @Before - public void setUp() { - dbClient = db.getDbClient(); - dbSession = db.getSession(); - userSession.login().setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); - - PermissionDependenciesFinder dependenciesFinder = new PermissionDependenciesFinder(dbClient, new ComponentFinder(dbClient)); - ws = new WsActionTester(new RemoveUserFromTemplateAction(dbClient, dependenciesFinder, userSession)); - - user = insertUser(newUserDto().setLogin(USER_LOGIN)); - permissionTemplate = insertPermissionTemplate(newPermissionTemplateDto()); - addUserToTemplate(user, permissionTemplate, DEFAULT_PERMISSION); - commit(); - } - - @Test - public void remove_user_from_template() { - newRequest(USER_LOGIN, permissionTemplate.getKee(), DEFAULT_PERMISSION); - - assertThat(getLoginsInTemplateAndPermission(permissionTemplate.getId(), DEFAULT_PERMISSION)).isEmpty(); - } - - @Test - public void remove_user_from_template_by_name_case_insensitive() { - ws.newRequest() - .setParam(PARAM_USER_LOGIN, USER_LOGIN) - .setParam(PARAM_PERMISSION, DEFAULT_PERMISSION) - .setParam(PARAM_TEMPLATE_NAME, permissionTemplate.getName().toUpperCase()) - .execute(); - commit(); - - assertThat(getLoginsInTemplateAndPermission(permissionTemplate.getId(), DEFAULT_PERMISSION)).isEmpty(); - } - - @Test - public void remove_user_from_template_twice_without_failing() { - newRequest(USER_LOGIN, permissionTemplate.getKee(), DEFAULT_PERMISSION); - newRequest(USER_LOGIN, permissionTemplate.getKee(), DEFAULT_PERMISSION); - - assertThat(getLoginsInTemplateAndPermission(permissionTemplate.getId(), DEFAULT_PERMISSION)).isEmpty(); - } - - @Test - public void keep_user_permission_not_removed() { - addUserToTemplate(user, permissionTemplate, ISSUE_ADMIN); - commit(); - - newRequest(USER_LOGIN, permissionTemplate.getKee(), DEFAULT_PERMISSION); - - assertThat(getLoginsInTemplateAndPermission(permissionTemplate.getId(), DEFAULT_PERMISSION)).isEmpty(); - assertThat(getLoginsInTemplateAndPermission(permissionTemplate.getId(), ISSUE_ADMIN)).containsExactly(user.getLogin()); - } - - @Test - public void keep_other_users_when_one_user_removed() { - UserDto newUser = insertUser(newUserDto().setLogin("new-login")); - addUserToTemplate(newUser, permissionTemplate, DEFAULT_PERMISSION); - commit(); - - newRequest(USER_LOGIN, permissionTemplate.getKee(), DEFAULT_PERMISSION); - - assertThat(getLoginsInTemplateAndPermission(permissionTemplate.getId(), DEFAULT_PERMISSION)).containsExactly("new-login"); - } - - @Test - public void fail_if_not_a_project_permission() { - expectedException.expect(BadRequestException.class); - - newRequest(USER_LOGIN, permissionTemplate.getKee(), GlobalPermissions.PREVIEW_EXECUTION); - } - - @Test - public void fail_if_insufficient_privileges() { - expectedException.expect(ForbiddenException.class); - userSession.setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); - - newRequest(USER_LOGIN, permissionTemplate.getKee(), DEFAULT_PERMISSION); - } - - @Test - public void fail_if_not_logged_in() { - expectedException.expect(UnauthorizedException.class); - userSession.anonymous(); - - newRequest(USER_LOGIN, permissionTemplate.getKee(), DEFAULT_PERMISSION); - } - - @Test - public void fail_if_user_missing() { - expectedException.expect(IllegalArgumentException.class); - - newRequest(null, permissionTemplate.getKee(), DEFAULT_PERMISSION); - } - - @Test - public void fail_if_permission_missing() { - expectedException.expect(IllegalArgumentException.class); - - newRequest(USER_LOGIN, permissionTemplate.getKee(), null); - } - - @Test - public void fail_if_template_missing() { - expectedException.expect(BadRequestException.class); - - newRequest(USER_LOGIN, null, DEFAULT_PERMISSION); - } - - @Test - public void fail_if_user_does_not_exist() { - expectedException.expect(NotFoundException.class); - expectedException.expectMessage("User with login 'unknown-login' is not found"); - - newRequest("unknown-login", permissionTemplate.getKee(), DEFAULT_PERMISSION); - } - - @Test - public void fail_if_template_key_does_not_exist() { - expectedException.expect(NotFoundException.class); - expectedException.expectMessage("Permission template with id 'unknown-key' is not found"); - - newRequest(USER_LOGIN, "unknown-key", DEFAULT_PERMISSION); - } - - private void newRequest(@Nullable String userLogin, @Nullable String templateKey, @Nullable String permission) { - TestRequest request = ws.newRequest(); - if (userLogin != null) { - request.setParam(PARAM_USER_LOGIN, userLogin); - } - if (templateKey != null) { - request.setParam(WsPermissionParameters.PARAM_TEMPLATE_ID, templateKey); - } - if (permission != null) { - request.setParam(WsPermissionParameters.PARAM_PERMISSION, permission); - } - - request.execute(); - } - - private void commit() { - dbSession.commit(); - } - - private UserDto insertUser(UserDto userDto) { - return dbClient.userDao().insert(dbSession, userDto.setActive(true)); - } - - private PermissionTemplateDto insertPermissionTemplate(PermissionTemplateDto permissionTemplate) { - return dbClient.permissionTemplateDao().insert(dbSession, permissionTemplate); - } - - private List getLoginsInTemplateAndPermission(long templateId, String permission) { - PermissionQuery permissionQuery = PermissionQuery.builder().permission(permission).membership(IN).build(); - return from(dbClient.permissionTemplateDao() - .selectUsers(dbSession, permissionQuery, templateId, 0, Integer.MAX_VALUE)) - .transform(UserWithPermissionToUserLogin.INSTANCE) - .toList(); - } - - private enum UserWithPermissionToUserLogin implements Function { - INSTANCE; - - @Override - public String apply(@Nonnull UserWithPermissionDto userWithPermission) { - return userWithPermission.getLogin(); - } - - } - - private void addUserToTemplate(UserDto user, PermissionTemplateDto permissionTemplate, String permission) { - dbClient.permissionTemplateDao().insertUserPermission(dbSession, permissionTemplate.getId(), user.getId(), permission); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/SearchTemplatesActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/SearchTemplatesActionTest.java deleted file mode 100644 index dcda8000a5e..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/SearchTemplatesActionTest.java +++ /dev/null @@ -1,249 +0,0 @@ -/* - * 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 java.util.Date; -import java.util.List; -import javax.annotation.Nullable; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Rule; -import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; -import org.sonar.api.config.Settings; -import org.sonar.api.resources.Qualifiers; -import org.sonar.api.resources.ResourceType; -import org.sonar.api.resources.ResourceTypes; -import org.sonar.api.utils.System2; -import org.sonar.api.web.UserRole; -import org.sonar.core.permission.GlobalPermissions; -import org.sonar.db.DbClient; -import org.sonar.db.DbSession; -import org.sonar.db.DbTester; -import org.sonar.db.permission.PermissionTemplateDto; -import org.sonar.db.user.GroupDto; -import org.sonar.db.user.UserDto; -import org.sonar.server.exceptions.ForbiddenException; -import org.sonar.server.exceptions.UnauthorizedException; -import org.sonar.server.i18n.I18nRule; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.ws.WsActionTester; -import org.sonar.test.DbTests; - -import static java.util.Arrays.asList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.sonar.api.server.ws.WebService.Param.TEXT_QUERY; -import static org.sonar.core.permission.GlobalPermissions.QUALITY_PROFILE_ADMIN; -import static org.sonar.core.util.Uuids.UUID_EXAMPLE_01; -import static org.sonar.core.util.Uuids.UUID_EXAMPLE_02; -import static org.sonar.core.util.Uuids.UUID_EXAMPLE_03; -import static org.sonar.db.permission.PermissionTemplateTesting.newPermissionTemplateDto; -import static org.sonar.db.user.GroupTesting.newGroupDto; -import static org.sonar.db.user.UserTesting.newUserDto; -import static org.sonar.server.permission.DefaultPermissionTemplates.defaultRootQualifierTemplateProperty; -import static org.sonar.test.JsonAssert.assertJson; - -@Category(DbTests.class) -public class SearchTemplatesActionTest { - @ClassRule - public static DbTester db = DbTester.create(System2.INSTANCE); - @Rule - public ExpectedException expectedException = ExpectedException.none(); - @Rule - public UserSessionRule userSession = UserSessionRule.standalone(); - - WsActionTester ws; - I18nRule i18n = new I18nRule(); - DbClient dbClient = db.getDbClient(); - DbSession dbSession = db.getSession(); - ResourceTypes resourceTypes = mock(ResourceTypes.class); - SearchTemplatesDataLoader dataLoader; - - SearchTemplatesAction underTest; - - @Before - public void setUp() { - db.truncateTables(); - i18n.setProjectPermissions(); - when(resourceTypes.getRoots()).thenReturn(rootResourceTypes()); - - Settings settings = new Settings(); - settings.setProperty(defaultRootQualifierTemplateProperty(Qualifiers.PROJECT), UUID_EXAMPLE_01); - settings.setProperty(defaultRootQualifierTemplateProperty(Qualifiers.VIEW), UUID_EXAMPLE_02); - settings.setProperty(defaultRootQualifierTemplateProperty("DEV"), UUID_EXAMPLE_03); - - DefaultPermissionTemplateFinder defaultPermissionTemplateFinder = new DefaultPermissionTemplateFinder(settings, resourceTypes); - - dataLoader = new SearchTemplatesDataLoader(dbClient, defaultPermissionTemplateFinder); - underTest = new SearchTemplatesAction(dbClient, userSession, i18n, dataLoader); - - ws = new WsActionTester(underTest); - - userSession.login().setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); - } - - @Test - public void search_project_permissions() { - PermissionTemplateDto projectTemplate = insertProjectTemplate(); - PermissionTemplateDto viewsTemplate = insertViewsTemplate(); - PermissionTemplateDto developerTemplate = insertDeveloperTemplate(); - - UserDto user1 = insertUser(newUserDto()); - UserDto user2 = insertUser(newUserDto()); - UserDto user3 = insertUser(newUserDto()); - - GroupDto group1 = insertGroup(newGroupDto()); - GroupDto group2 = insertGroup(newGroupDto()); - GroupDto group3 = insertGroup(newGroupDto()); - - addUserToTemplate(projectTemplate.getId(), user1.getId(), UserRole.ISSUE_ADMIN); - addUserToTemplate(projectTemplate.getId(), user2.getId(), UserRole.ISSUE_ADMIN); - addUserToTemplate(projectTemplate.getId(), user3.getId(), UserRole.ISSUE_ADMIN); - addUserToTemplate(projectTemplate.getId(), user1.getId(), UserRole.CODEVIEWER); - addGroupToTemplate(projectTemplate.getId(), group1.getId(), UserRole.ADMIN); - - addUserToTemplate(viewsTemplate.getId(), user1.getId(), UserRole.USER); - addUserToTemplate(viewsTemplate.getId(), user2.getId(), UserRole.USER); - addGroupToTemplate(viewsTemplate.getId(), group1.getId(), UserRole.ISSUE_ADMIN); - addGroupToTemplate(viewsTemplate.getId(), group2.getId(), UserRole.ISSUE_ADMIN); - addGroupToTemplate(viewsTemplate.getId(), group3.getId(), UserRole.ISSUE_ADMIN); - - addGroupToTemplate(developerTemplate.getId(), group1.getId(), UserRole.USER); - - commit(); - - String result = newRequest(); - - assertJson(result) - .withStrictArrayOrder() - .isSimilarTo(getClass().getResource("search_templates-example.json")); - } - - @Test - public void empty_result() { - String result = newRequest(); - - assertJson(result) - .withStrictArrayOrder() - .isSimilarTo(getClass().getResource("SearchTemplatesActionTest/empty.json")); - } - - @Test - public void search_by_name() { - insertProjectTemplate(); - insertViewsTemplate(); - insertDeveloperTemplate(); - commit(); - - String result = ws.newRequest() - .setParam(TEXT_QUERY, "views") - .execute().getInput(); - - assertThat(result).contains("Default template for Views") - .doesNotContain("projects") - .doesNotContain("developers"); - } - - @Test - public void fail_if_not_logged_in() { - expectedException.expect(UnauthorizedException.class); - userSession.anonymous(); - - ws.newRequest().execute(); - } - - @Test - public void fail_if_not_global_admin() { - expectedException.expect(ForbiddenException.class); - userSession.login().setGlobalPermissions(QUALITY_PROFILE_ADMIN); - - ws.newRequest().execute(); - } - - private String newRequest() { - return ws.newRequest().execute().getInput(); - } - - private PermissionTemplateDto insertProjectTemplate() { - return insertTemplate(newPermissionTemplateDto() - .setUuid(UUID_EXAMPLE_01) - .setName("Default template for Projects") - .setDescription("Template for new projects") - .setKeyPattern(null) - .setCreatedAt(new Date(1_000_000_000_000L)) - .setUpdatedAt(new Date(1_000_000_000_000L))); - } - - private PermissionTemplateDto insertViewsTemplate() { - return insertTemplate(newPermissionTemplateDto() - .setUuid(UUID_EXAMPLE_02) - .setName("Default template for Views") - .setDescription("Template for new views") - .setKeyPattern(".*sonar.views.*") - .setCreatedAt(new Date(1_000_000_000_000L)) - .setUpdatedAt(new Date(1_100_000_000_000L))); - } - - private PermissionTemplateDto insertDeveloperTemplate() { - return insertTemplate(newPermissionTemplateDto() - .setUuid(UUID_EXAMPLE_03) - .setName("Default template for Developers") - .setKeyPattern(".*sonar.developer.*") - .setDescription(null) - .setCreatedAt(new Date(1_100_500_000_000L)) - .setUpdatedAt(new Date(1_100_900_000_000L))); - } - - private PermissionTemplateDto insertTemplate(PermissionTemplateDto template) { - return dbClient.permissionTemplateDao().insert(dbSession, template); - } - - private GroupDto insertGroup(GroupDto groupDto) { - return dbClient.groupDao().insert(dbSession, groupDto); - } - - private UserDto insertUser(UserDto userDto) { - return dbClient.userDao().insert(dbSession, userDto.setActive(true)); - } - - private void addGroupToTemplate(long templateId, @Nullable Long groupId, String permission) { - dbClient.permissionTemplateDao().insertGroupPermission(dbSession, templateId, groupId, permission); - } - - private void addUserToTemplate(long templateId, long userId, String permission) { - dbClient.permissionTemplateDao().insertUserPermission(dbSession, templateId, userId, permission); - } - - private void commit() { - dbSession.commit(); - } - - private static List rootResourceTypes() { - ResourceType project = ResourceType.builder(Qualifiers.PROJECT).build(); - ResourceType view = ResourceType.builder(Qualifiers.VIEW).build(); - ResourceType dev = ResourceType.builder("DEV").build(); - - return asList(project, view, dev); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/SetDefaultTemplateActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/SetDefaultTemplateActionTest.java deleted file mode 100644 index defa13e539c..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/SetDefaultTemplateActionTest.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - * 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 java.util.List; -import java.util.Properties; -import javax.annotation.Nullable; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.junit.rules.ExpectedException; -import org.sonar.api.config.PropertyDefinitions; -import org.sonar.api.resources.Qualifiers; -import org.sonar.api.resources.ResourceType; -import org.sonar.api.resources.ResourceTypes; -import org.sonar.api.utils.System2; -import org.sonar.core.permission.GlobalPermissions; -import org.sonar.db.DbClient; -import org.sonar.db.DbTester; -import org.sonar.db.permission.PermissionTemplateDto; -import org.sonar.db.permission.PermissionTemplateTesting; -import org.sonar.server.component.ComponentFinder; -import org.sonar.server.exceptions.BadRequestException; -import org.sonar.server.exceptions.ForbiddenException; -import org.sonar.server.exceptions.NotFoundException; -import org.sonar.server.exceptions.UnauthorizedException; -import org.sonar.server.i18n.I18nRule; -import org.sonar.server.platform.PersistentSettings; -import org.sonar.server.platform.ServerSettings; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.ws.TestRequest; -import org.sonar.server.ws.WsActionTester; -import org.sonar.test.DbTests; - -import static java.util.Arrays.asList; -import static java.util.Collections.singletonList; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.sonar.api.resources.Qualifiers.PROJECT; -import static org.sonar.api.resources.Qualifiers.VIEW; -import static org.sonar.server.permission.DefaultPermissionTemplates.DEFAULT_TEMPLATE_PROPERTY; -import static org.sonar.server.permission.DefaultPermissionTemplates.defaultRootQualifierTemplateProperty; -import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_QUALIFIER; -import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_TEMPLATE_ID; -import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_TEMPLATE_NAME; - -@Category(DbTests.class) -public class SetDefaultTemplateActionTest { - @Rule - public DbTester db = DbTester.create(System2.INSTANCE); - @Rule - public UserSessionRule userSession = UserSessionRule.standalone(); - @Rule - public ExpectedException expectedException = ExpectedException.none(); - I18nRule i18n = new I18nRule(); - - WsActionTester ws; - PersistentSettings persistentSettings; - ResourceTypes resourceTypes = mock(ResourceTypes.class); - - PermissionTemplateDto template; - - @Before - public void setUp() { - DbClient dbClient = db.getDbClient(); - persistentSettings = new PersistentSettings(dbClient.propertiesDao(), new ServerSettings(new PropertyDefinitions(), new Properties())); - persistentSettings.saveProperty(DEFAULT_TEMPLATE_PROPERTY, "any-template-uuid"); - persistentSettings.saveProperty(defaultRootQualifierTemplateProperty(PROJECT), "any-template-uuid"); - persistentSettings.saveProperty(defaultRootQualifierTemplateProperty(VIEW), "any-view-template-uuid"); - persistentSettings.saveProperty(defaultRootQualifierTemplateProperty("DEV"), "any-dev-template-uuid"); - when(resourceTypes.getRoots()).thenReturn(rootResourceTypes()); - userSession.login().setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); - - ws = new WsActionTester(new SetDefaultTemplateAction( - dbClient, - new PermissionDependenciesFinder(dbClient, new ComponentFinder(dbClient)), - resourceTypes, - persistentSettings, - userSession, i18n)); - - template = dbClient.permissionTemplateDao().insert(db.getSession(), PermissionTemplateTesting.newPermissionTemplateDto().setUuid("permission-template-uuid")); - } - - @Test - public void update_settings_for_project_qualifier() { - // default value is project qualifier's value - String result = newRequest(template.getUuid(), null); - - assertThat(result).isEmpty(); - assertThat(persistentSettings.getString(DEFAULT_TEMPLATE_PROPERTY)).isEqualTo("any-template-uuid"); - assertThat(persistentSettings.getString(defaultRootQualifierTemplateProperty(PROJECT))).isEqualTo(template.getUuid()); - assertThat(persistentSettings.getString(defaultRootQualifierTemplateProperty(VIEW))).isEqualTo("any-view-template-uuid"); - assertThat(persistentSettings.getString(defaultRootQualifierTemplateProperty("DEV"))).isEqualTo("any-dev-template-uuid"); - } - - @Test - public void update_settings_for_project_qualifier_by_template_name() { - ws.newRequest() - .setParam(PARAM_TEMPLATE_NAME, template.getName().toUpperCase()) - .execute(); - db.getSession().commit(); - - assertThat(persistentSettings.getString(DEFAULT_TEMPLATE_PROPERTY)).isEqualTo("any-template-uuid"); - assertThat(persistentSettings.getString(defaultRootQualifierTemplateProperty(PROJECT))).isEqualTo(template.getUuid()); - assertThat(persistentSettings.getString(defaultRootQualifierTemplateProperty(VIEW))).isEqualTo("any-view-template-uuid"); - assertThat(persistentSettings.getString(defaultRootQualifierTemplateProperty("DEV"))).isEqualTo("any-dev-template-uuid"); - } - - @Test - public void update_settings_of_views_property() { - newRequest(template.getUuid(), VIEW); - - assertThat(persistentSettings.getString(DEFAULT_TEMPLATE_PROPERTY)).isEqualTo("any-template-uuid"); - assertThat(persistentSettings.getString(defaultRootQualifierTemplateProperty(PROJECT))).isEqualTo("any-template-uuid"); - assertThat(persistentSettings.getString(defaultRootQualifierTemplateProperty(VIEW))).isEqualTo(template.getUuid()); - assertThat(persistentSettings.getString(defaultRootQualifierTemplateProperty("DEV"))).isEqualTo("any-dev-template-uuid"); - } - - @Test - public void fail_if_anonymous() { - expectedException.expect(UnauthorizedException.class); - userSession.anonymous(); - - newRequest(template.getUuid(), PROJECT); - } - - @Test - public void fail_if_not_admin() { - expectedException.expect(ForbiddenException.class); - userSession.login().setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); - - newRequest(template.getUuid(), PROJECT); - } - - @Test - public void fail_if_template_not_provided() { - expectedException.expect(BadRequestException.class); - - newRequest(null, PROJECT); - } - - @Test - public void fail_if_template_does_not_exist() { - expectedException.expect(NotFoundException.class); - - newRequest("unknown-template-uuid", PROJECT); - } - - @Test - public void fail_if_qualifier_is_not_root() { - expectedException.expect(BadRequestException.class); - when(resourceTypes.getRoots()).thenReturn(singletonList(ResourceType.builder(PROJECT).build())); - - newRequest(template.getUuid(), VIEW); - } - - private String newRequest(@Nullable String templateUuid, @Nullable String qualifier) { - TestRequest request = ws.newRequest(); - if (templateUuid != null) { - request.setParam(PARAM_TEMPLATE_ID, templateUuid); - } - if (qualifier != null) { - request.setParam(PARAM_QUALIFIER, qualifier); - } - - return request.execute().getInput(); - } - - private static List rootResourceTypes() { - ResourceType project = ResourceType.builder(PROJECT).build(); - ResourceType view = ResourceType.builder(Qualifiers.VIEW).build(); - ResourceType dev = ResourceType.builder("DEV").build(); - - return asList(project, view, dev); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/UpdateTemplateActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/UpdateTemplateActionTest.java deleted file mode 100644 index 82d2404779c..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/UpdateTemplateActionTest.java +++ /dev/null @@ -1,237 +0,0 @@ -/* - * 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 java.util.Date; -import javax.annotation.Nullable; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.utils.System2; -import org.sonar.core.permission.GlobalPermissions; -import org.sonar.db.DbClient; -import org.sonar.db.DbSession; -import org.sonar.db.DbTester; -import org.sonar.db.permission.PermissionTemplateDto; -import org.sonar.db.user.GroupDto; -import org.sonar.server.component.ComponentFinder; -import org.sonar.server.exceptions.BadRequestException; -import org.sonar.server.exceptions.ForbiddenException; -import org.sonar.server.exceptions.NotFoundException; -import org.sonar.server.exceptions.UnauthorizedException; -import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.ws.TestRequest; -import org.sonar.server.ws.TestResponse; -import org.sonar.server.ws.WsActionTester; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.sonar.db.permission.PermissionTemplateTesting.newPermissionTemplateDto; -import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_DESCRIPTION; -import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_ID; -import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_NAME; -import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_PATTERN; -import static org.sonar.test.JsonAssert.assertJson; - -public class UpdateTemplateActionTest { - - @Rule - public DbTester db = DbTester.create(System2.INSTANCE); - @Rule - public UserSessionRule userSession = UserSessionRule.standalone(); - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - WsActionTester ws; - DbClient dbClient; - DbSession dbSession; - - PermissionTemplateDto templateDto; - - @Before - public void setUp() { - userSession.login().setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); - System2 system = mock(System2.class); - when(system.now()).thenReturn(1_440_512_328_743L); - - dbClient = db.getDbClient(); - dbSession = db.getSession(); - PermissionDependenciesFinder finder = new PermissionDependenciesFinder(dbClient, new ComponentFinder(dbClient)); - - ws = new WsActionTester(new UpdateTemplateAction(dbClient, userSession, system, finder)); - - templateDto = insertTemplate(newPermissionTemplateDto() - .setName("Permission Template Name") - .setDescription("Permission Template Description") - .setKeyPattern(".*\\.pattern\\..*") - .setCreatedAt(new Date(1_000_000_000_000L)) - .setUpdatedAt(new Date(1_000_000_000_000L))); - commit(); - } - - @Test - public void update_all_permission_template_fields() { - TestResponse result = newRequest(templateDto.getKee(), "Finance", "Permissions for financially related projects", ".*\\.finance\\..*"); - - assertJson(result.getInput()) - .ignoreFields("id") - .isSimilarTo(getClass().getResource("update_template-example.json")); - PermissionTemplateDto finance = dbClient.permissionTemplateDao().selectByName(dbSession, "Finance"); - assertThat(finance.getName()).isEqualTo("Finance"); - assertThat(finance.getDescription()).isEqualTo("Permissions for financially related projects"); - assertThat(finance.getKeyPattern()).isEqualTo(".*\\.finance\\..*"); - assertThat(finance.getKee()).isEqualTo(templateDto.getKee()); - assertThat(finance.getCreatedAt()).isEqualTo(templateDto.getCreatedAt()); - assertThat(finance.getUpdatedAt().getTime()).isEqualTo(1440512328743L); - } - - @Test - public void update_with_the_same_values() { - newRequest(templateDto.getKee(), templateDto.getName(), templateDto.getDescription(), templateDto.getKeyPattern()); - - PermissionTemplateDto updatedTemplate = dbClient.permissionTemplateDao().selectByUuid(dbSession, templateDto.getKee()); - assertThat(updatedTemplate.getName()).isEqualTo(templateDto.getName()); - assertThat(updatedTemplate.getDescription()).isEqualTo(templateDto.getDescription()); - assertThat(updatedTemplate.getKeyPattern()).isEqualTo(templateDto.getKeyPattern()); - } - - @Test - public void update_name_only() { - newRequest(templateDto.getKee(), "Finance", null, null); - - PermissionTemplateDto finance = dbClient.permissionTemplateDao().selectByName(dbSession, "Finance"); - assertThat(finance.getName()).isEqualTo("Finance"); - assertThat(finance.getDescription()).isEqualTo(templateDto.getDescription()); - assertThat(finance.getKeyPattern()).isEqualTo(templateDto.getKeyPattern()); - } - - @Test - public void fail_if_key_is_not_found() { - expectedException.expect(NotFoundException.class); - expectedException.expectMessage("Permission template with id 'unknown-key' is not found"); - - newRequest("unknown-key", null, null, null); - } - - @Test - public void fail_if_name_already_exists_in_another_template() { - expectedException.expect(BadRequestException.class); - expectedException.expectMessage("A template with the name 'My Template' already exists (case insensitive)."); - - insertTemplate(newPermissionTemplateDto() - .setName("My Template") - .setKee("my-key") - .setCreatedAt(new Date(12345789L)) - .setUpdatedAt(new Date(12345789L))); - commit(); - - newRequest(templateDto.getKee(), "My Template", null, null); - } - - @Test - public void fail_if_key_is_not_provided() { - expectedException.expect(IllegalArgumentException.class); - - newRequest(null, "Finance", null, null); - } - - @Test - public void fail_if_name_empty() { - expectedException.expect(BadRequestException.class); - expectedException.expectMessage("The template name must not be blank"); - - newRequest(templateDto.getKee(), "", null, null); - } - - @Test - public void fail_if_name_has_just_whitespaces() { - expectedException.expect(BadRequestException.class); - expectedException.expectMessage("The template name must not be blank"); - - newRequest(templateDto.getKee(), " \r\n", null, null); - } - - @Test - public void fail_if_regexp_if_not_valid() { - expectedException.expect(BadRequestException.class); - expectedException.expectMessage("The 'projectKeyPattern' parameter must be a valid Java regular expression. '[azerty' was passed"); - - newRequest(templateDto.getKee(), "Finance", null, "[azerty"); - } - - @Test - public void fail_if_name_already_exists_in_database_case_insensitive() { - expectedException.expect(BadRequestException.class); - expectedException.expectMessage("A template with the name 'Finance' already exists (case insensitive)."); - insertTemplate(newPermissionTemplateDto().setName("finance")); - commit(); - - newRequest(templateDto.getKee(), "Finance", null, null); - } - - @Test - public void fail_if_not_logged_in() { - expectedException.expect(UnauthorizedException.class); - userSession.anonymous(); - - newRequest(templateDto.getKee(), "Finance", null, null); - } - - @Test - public void fail_if_not_admin() { - expectedException.expect(ForbiddenException.class); - userSession.setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); - - newRequest(templateDto.getKee(), "Finance", null, null); - } - - private PermissionTemplateDto insertTemplate(PermissionTemplateDto template) { - return dbClient.permissionTemplateDao().insert(dbSession, template); - } - - private GroupDto insertGroup(GroupDto group) { - return dbClient.groupDao().insert(db.getSession(), group); - } - - private void commit() { - dbSession.commit(); - } - - private TestResponse newRequest(@Nullable String key, @Nullable String name, @Nullable String description, @Nullable String projectPattern) { - TestRequest request = ws.newRequest(); - if (key != null) { - request.setParam(PARAM_ID, key); - } - if (name != null) { - request.setParam(PARAM_NAME, name); - } - if (description != null) { - request.setParam(PARAM_DESCRIPTION, description); - } - if (projectPattern != null) { - request.setParam(PARAM_PATTERN, projectPattern); - } - - return request.execute(); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/AddGroupToTemplateActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/AddGroupToTemplateActionTest.java new file mode 100644 index 00000000000..006c5521436 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/AddGroupToTemplateActionTest.java @@ -0,0 +1,257 @@ +/* + * 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.template; + +import com.google.common.base.Function; +import java.util.List; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.rules.ExpectedException; +import org.sonar.api.utils.System2; +import org.sonar.api.web.UserRole; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.DbTester; +import org.sonar.db.permission.GroupWithPermissionDto; +import org.sonar.db.permission.PermissionQuery; +import org.sonar.db.permission.PermissionTemplateDto; +import org.sonar.db.user.GroupDto; +import org.sonar.server.component.ComponentFinder; +import org.sonar.server.exceptions.BadRequestException; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.exceptions.UnauthorizedException; +import org.sonar.server.permission.ws.PermissionDependenciesFinder; +import org.sonar.server.permission.ws.WsPermissionParameters; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.TestRequest; +import org.sonar.server.ws.WsActionTester; +import org.sonar.test.DbTests; + +import static com.google.common.collect.FluentIterable.from; +import static org.assertj.core.api.Assertions.assertThat; +import static org.sonar.api.security.DefaultGroups.ANYONE; +import static org.sonar.api.web.UserRole.ADMIN; +import static org.sonar.api.web.UserRole.CODEVIEWER; +import static org.sonar.api.web.UserRole.ISSUE_ADMIN; +import static org.sonar.db.permission.PermissionTemplateTesting.newPermissionTemplateDto; +import static org.sonar.db.user.GroupMembershipQuery.IN; +import static org.sonar.db.user.GroupTesting.newGroupDto; +import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_GROUP_ID; +import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_GROUP_NAME; +import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_PERMISSION; +import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_TEMPLATE_ID; +import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_TEMPLATE_NAME; + +@Category(DbTests.class) +public class AddGroupToTemplateActionTest { + + private static final String GROUP_NAME = "group-name"; + @Rule + public DbTester db = DbTester.create(System2.INSTANCE); + @Rule + public ExpectedException expectedException = ExpectedException.none(); + @Rule + public UserSessionRule userSession = UserSessionRule.standalone(); + + WsActionTester ws; + DbClient dbClient; + DbSession dbSession; + GroupDto group; + PermissionTemplateDto permissionTemplate; + + @Before + public void setUp() { + dbClient = db.getDbClient(); + dbSession = db.getSession(); + userSession.login().setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); + + PermissionDependenciesFinder dependenciesFinder = new PermissionDependenciesFinder(dbClient, new ComponentFinder(dbClient)); + ws = new WsActionTester(new AddGroupToTemplateAction(dbClient, dependenciesFinder, userSession)); + + group = insertGroup(newGroupDto().setName(GROUP_NAME)); + permissionTemplate = insertPermissionTemplate(newPermissionTemplateDto()); + commit(); + } + + @Test + public void add_group_to_template() { + newRequest(GROUP_NAME, permissionTemplate.getKee(), CODEVIEWER); + + assertThat(getGroupNamesInTemplateAndPermission(permissionTemplate.getId(), CODEVIEWER)).containsExactly(GROUP_NAME); + } + + @Test + public void add_group_to_template_by_name() { + ws.newRequest() + .setParam(PARAM_GROUP_NAME, GROUP_NAME) + .setParam(PARAM_PERMISSION, CODEVIEWER) + .setParam(PARAM_TEMPLATE_NAME, permissionTemplate.getName().toUpperCase()) + .execute(); + commit(); + + assertThat(getGroupNamesInTemplateAndPermission(permissionTemplate.getId(), CODEVIEWER)).containsExactly(GROUP_NAME); + } + + @Test + public void add_with_group_id() { + ws.newRequest() + .setParam(PARAM_TEMPLATE_ID, permissionTemplate.getKee()) + .setParam(PARAM_PERMISSION, CODEVIEWER) + .setParam(PARAM_GROUP_ID, String.valueOf(group.getId())) + .execute(); + + assertThat(getGroupNamesInTemplateAndPermission(permissionTemplate.getId(), CODEVIEWER)).containsExactly(GROUP_NAME); + } + + @Test + public void does_not_add_a_group_twice() { + newRequest(GROUP_NAME, permissionTemplate.getKee(), ISSUE_ADMIN); + newRequest(GROUP_NAME, permissionTemplate.getKee(), ISSUE_ADMIN); + + assertThat(getGroupNamesInTemplateAndPermission(permissionTemplate.getId(), ISSUE_ADMIN)).containsExactly(GROUP_NAME); + } + + @Test + public void add_anyone_group_to_template() { + newRequest(ANYONE, permissionTemplate.getKee(), CODEVIEWER); + + assertThat(getGroupNamesInTemplateAndPermission(permissionTemplate.getId(), CODEVIEWER)).containsExactly(ANYONE); + } + + @Test + public void fail_if_add_anyone_group_to_admin_permission() { + expectedException.expect(BadRequestException.class); + expectedException.expectMessage(String.format("It is not possible to add the '%s' permission to the '%s' group.", UserRole.ADMIN, ANYONE)); + + newRequest(ANYONE, permissionTemplate.getKee(), ADMIN); + } + + @Test + public void fail_if_not_a_project_permission() { + expectedException.expect(BadRequestException.class); + + newRequest(GROUP_NAME, permissionTemplate.getKee(), GlobalPermissions.PREVIEW_EXECUTION); + } + + @Test + public void fail_if_insufficient_privileges() { + expectedException.expect(ForbiddenException.class); + userSession.setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); + + newRequest(GROUP_NAME, permissionTemplate.getKee(), CODEVIEWER); + } + + @Test + public void fail_if_not_logged_in() { + expectedException.expect(UnauthorizedException.class); + userSession.anonymous(); + + newRequest(GROUP_NAME, permissionTemplate.getKee(), CODEVIEWER); + } + + @Test + public void fail_if_group_params_missing() { + expectedException.expect(BadRequestException.class); + + newRequest(null, permissionTemplate.getKee(), CODEVIEWER); + } + + @Test + public void fail_if_permission_missing() { + expectedException.expect(IllegalArgumentException.class); + + newRequest(GROUP_NAME, permissionTemplate.getKee(), null); + } + + @Test + public void fail_if_template_uuid_and_name_missing() { + expectedException.expect(BadRequestException.class); + + newRequest(GROUP_NAME, null, CODEVIEWER); + } + + @Test + public void fail_if_group_does_not_exist() { + expectedException.expect(NotFoundException.class); + expectedException.expectMessage("Group with name 'unknown-group-name' is not found"); + + newRequest("unknown-group-name", permissionTemplate.getKee(), CODEVIEWER); + } + + @Test + public void fail_if_template_key_does_not_exist() { + expectedException.expect(NotFoundException.class); + expectedException.expectMessage("Permission template with id 'unknown-key' is not found"); + + newRequest(GROUP_NAME, "unknown-key", CODEVIEWER); + } + + private void newRequest(@Nullable String groupName, @Nullable String templateKey, @Nullable String permission) { + TestRequest request = ws.newRequest(); + if (groupName != null) { + request.setParam(WsPermissionParameters.PARAM_GROUP_NAME, groupName); + } + if (templateKey != null) { + request.setParam(PARAM_TEMPLATE_ID, templateKey); + } + if (permission != null) { + request.setParam(WsPermissionParameters.PARAM_PERMISSION, permission); + } + + request.execute(); + } + + private void commit() { + dbSession.commit(); + } + + private GroupDto insertGroup(GroupDto groupDto) { + return dbClient.groupDao().insert(dbSession, groupDto); + } + + private PermissionTemplateDto insertPermissionTemplate(PermissionTemplateDto permissionTemplate) { + return dbClient.permissionTemplateDao().insert(dbSession, permissionTemplate); + } + + private List getGroupNamesInTemplateAndPermission(long templateId, String permission) { + PermissionQuery permissionQuery = PermissionQuery.builder().permission(permission).membership(IN).build(); + return from(dbClient.permissionTemplateDao() + .selectGroups(dbSession, permissionQuery, templateId)) + .transform(GroupWithPermissionToGroupName.INSTANCE) + .toList(); + } + + private enum GroupWithPermissionToGroupName implements Function { + INSTANCE; + + @Override + public String apply(@Nonnull GroupWithPermissionDto groupWithPermission) { + return groupWithPermission.getName(); + } + + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/AddUserToTemplateActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/AddUserToTemplateActionTest.java new file mode 100644 index 00000000000..2ab68a4378e --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/AddUserToTemplateActionTest.java @@ -0,0 +1,227 @@ +/* + * 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.template; + +import com.google.common.base.Function; +import java.util.List; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.rules.ExpectedException; +import org.sonar.api.utils.System2; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.DbTester; +import org.sonar.db.permission.PermissionQuery; +import org.sonar.db.permission.PermissionTemplateDto; +import org.sonar.db.permission.UserWithPermissionDto; +import org.sonar.db.user.UserDto; +import org.sonar.server.component.ComponentFinder; +import org.sonar.server.exceptions.BadRequestException; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.exceptions.UnauthorizedException; +import org.sonar.server.permission.ws.PermissionDependenciesFinder; +import org.sonar.server.permission.ws.WsPermissionParameters; +import org.sonar.server.permission.ws.template.AddUserToTemplateAction; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.TestRequest; +import org.sonar.server.ws.WsActionTester; +import org.sonar.test.DbTests; + +import static com.google.common.collect.FluentIterable.from; +import static org.assertj.core.api.Assertions.assertThat; +import static org.sonar.api.web.UserRole.CODEVIEWER; +import static org.sonar.api.web.UserRole.ISSUE_ADMIN; +import static org.sonar.db.permission.PermissionTemplateTesting.newPermissionTemplateDto; +import static org.sonar.db.user.GroupMembershipQuery.IN; +import static org.sonar.db.user.UserTesting.newUserDto; +import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_PERMISSION; +import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_TEMPLATE_NAME; +import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_USER_LOGIN; + +@Category(DbTests.class) +public class AddUserToTemplateActionTest { + + private static final String USER_LOGIN = "user-login"; + @Rule + public DbTester db = DbTester.create(System2.INSTANCE); + @Rule + public ExpectedException expectedException = ExpectedException.none(); + @Rule + public UserSessionRule userSession = UserSessionRule.standalone(); + + WsActionTester ws; + DbClient dbClient; + DbSession dbSession; + UserDto user; + PermissionTemplateDto permissionTemplate; + + @Before + public void setUp() { + dbClient = db.getDbClient(); + dbSession = db.getSession(); + userSession.login().setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); + + PermissionDependenciesFinder dependenciesFinder = new PermissionDependenciesFinder(dbClient, new ComponentFinder(dbClient)); + ws = new WsActionTester(new AddUserToTemplateAction(dbClient, dependenciesFinder, userSession)); + + user = insertUser(newUserDto().setLogin(USER_LOGIN)); + permissionTemplate = insertPermissionTemplate(newPermissionTemplateDto()); + commit(); + } + + @Test + public void add_user_to_template() { + newRequest(USER_LOGIN, permissionTemplate.getKee(), CODEVIEWER); + + assertThat(getLoginsInTemplateAndPermission(permissionTemplate.getId(), CODEVIEWER)).containsExactly(USER_LOGIN); + } + + @Test + public void add_user_to_template_by_name() { + ws.newRequest() + .setParam(PARAM_USER_LOGIN, USER_LOGIN) + .setParam(PARAM_PERMISSION, CODEVIEWER) + .setParam(PARAM_TEMPLATE_NAME, permissionTemplate.getName().toUpperCase()) + .execute(); + commit(); + + assertThat(getLoginsInTemplateAndPermission(permissionTemplate.getId(), CODEVIEWER)).containsExactly(USER_LOGIN); + } + + @Test + public void does_not_add_a_user_twice() { + newRequest(USER_LOGIN, permissionTemplate.getKee(), ISSUE_ADMIN); + newRequest(USER_LOGIN, permissionTemplate.getKee(), ISSUE_ADMIN); + + assertThat(getLoginsInTemplateAndPermission(permissionTemplate.getId(), ISSUE_ADMIN)).containsExactly(USER_LOGIN); + } + + @Test + public void fail_if_not_a_project_permission() { + expectedException.expect(BadRequestException.class); + + newRequest(USER_LOGIN, permissionTemplate.getKee(), GlobalPermissions.PREVIEW_EXECUTION); + } + + @Test + public void fail_if_insufficient_privileges() { + expectedException.expect(ForbiddenException.class); + userSession.setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); + + newRequest(USER_LOGIN, permissionTemplate.getKee(), CODEVIEWER); + } + + @Test + public void fail_if_not_logged_in() { + expectedException.expect(UnauthorizedException.class); + userSession.anonymous(); + + newRequest(USER_LOGIN, permissionTemplate.getKee(), CODEVIEWER); + } + + @Test + public void fail_if_user_missing() { + expectedException.expect(IllegalArgumentException.class); + + newRequest(null, permissionTemplate.getKee(), CODEVIEWER); + } + + @Test + public void fail_if_permission_missing() { + expectedException.expect(IllegalArgumentException.class); + + newRequest(USER_LOGIN, permissionTemplate.getKee(), null); + } + + @Test + public void fail_if_template_uuid_and_name_are_missing() { + expectedException.expect(BadRequestException.class); + + newRequest(USER_LOGIN, null, CODEVIEWER); + } + + @Test + public void fail_if_user_does_not_exist() { + expectedException.expect(NotFoundException.class); + expectedException.expectMessage("User with login 'unknown-login' is not found"); + + newRequest("unknown-login", permissionTemplate.getKee(), CODEVIEWER); + } + + @Test + public void fail_if_template_key_does_not_exist() { + expectedException.expect(NotFoundException.class); + expectedException.expectMessage("Permission template with id 'unknown-key' is not found"); + + newRequest(USER_LOGIN, "unknown-key", CODEVIEWER); + } + + private void newRequest(@Nullable String userLogin, @Nullable String templateKey, @Nullable String permission) { + TestRequest request = ws.newRequest(); + if (userLogin != null) { + request.setParam(PARAM_USER_LOGIN, userLogin); + } + if (templateKey != null) { + request.setParam(WsPermissionParameters.PARAM_TEMPLATE_ID, templateKey); + } + if (permission != null) { + request.setParam(WsPermissionParameters.PARAM_PERMISSION, permission); + } + + request.execute(); + } + + private void commit() { + dbSession.commit(); + } + + private UserDto insertUser(UserDto userDto) { + return dbClient.userDao().insert(dbSession, userDto.setActive(true)); + } + + private PermissionTemplateDto insertPermissionTemplate(PermissionTemplateDto permissionTemplate) { + return dbClient.permissionTemplateDao().insert(dbSession, permissionTemplate); + } + + private List getLoginsInTemplateAndPermission(long templateId, String permission) { + PermissionQuery permissionQuery = PermissionQuery.builder().permission(permission).membership(IN).build(); + return from(dbClient.permissionTemplateDao() + .selectUsers(dbSession, permissionQuery, templateId, 0, Integer.MAX_VALUE)) + .transform(UserWithPermissionToUserLogin.INSTANCE) + .toList(); + } + + private enum UserWithPermissionToUserLogin implements Function { + INSTANCE; + + @Override + public String apply(@Nonnull UserWithPermissionDto userWithPermission) { + return userWithPermission.getLogin(); + } + + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/ApplyTemplateActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/ApplyTemplateActionTest.java new file mode 100644 index 00000000000..d8554d9a6ad --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/ApplyTemplateActionTest.java @@ -0,0 +1,316 @@ +/* + * 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.template; + +import com.google.common.base.Predicate; +import com.google.common.collect.FluentIterable; +import java.util.List; +import javax.annotation.Nullable; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.rules.ExpectedException; +import org.sonar.api.config.Settings; +import org.sonar.api.utils.System2; +import org.sonar.api.web.UserRole; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.DbTester; +import org.sonar.db.component.ComponentDto; +import org.sonar.db.permission.GroupWithPermissionDto; +import org.sonar.db.permission.PermissionQuery; +import org.sonar.db.permission.PermissionRepository; +import org.sonar.db.permission.PermissionTemplateDto; +import org.sonar.db.permission.UserWithPermissionDto; +import org.sonar.db.user.GroupDto; +import org.sonar.db.user.GroupRoleDto; +import org.sonar.db.user.UserDto; +import org.sonar.db.user.UserRoleDto; +import org.sonar.server.component.ComponentFinder; +import org.sonar.server.exceptions.BadRequestException; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.exceptions.UnauthorizedException; +import org.sonar.server.issue.index.IssueAuthorizationIndexer; +import org.sonar.server.permission.PermissionFinder; +import org.sonar.server.permission.PermissionService; +import org.sonar.server.permission.ws.PermissionDependenciesFinder; +import org.sonar.server.permission.ws.template.ApplyTemplateAction; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.TestRequest; +import org.sonar.server.ws.TestResponse; +import org.sonar.server.ws.WsActionTester; +import org.sonar.test.DbTests; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.sonar.db.component.ComponentTesting.newProjectDto; +import static org.sonar.db.permission.PermissionTemplateTesting.newPermissionTemplateDto; +import static org.sonar.db.user.GroupMembershipQuery.IN; +import static org.sonar.db.user.GroupTesting.newGroupDto; +import static org.sonar.db.user.UserTesting.newUserDto; +import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_PROJECT_ID; +import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_PROJECT_KEY; +import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_TEMPLATE_ID; +import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_TEMPLATE_NAME; + +@Category(DbTests.class) +public class ApplyTemplateActionTest { + + @Rule + public DbTester db = DbTester.create(System2.INSTANCE); + @Rule + public UserSessionRule userSession = UserSessionRule.standalone(); + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + WsActionTester ws; + DbClient dbClient; + DbSession dbSession; + + UserDto user1; + UserDto user2; + GroupDto group1; + GroupDto group2; + ComponentDto project; + PermissionTemplateDto template1; + PermissionTemplateDto template2; + IssueAuthorizationIndexer issueAuthorizationIndexer = mock(IssueAuthorizationIndexer.class); + + @Before + public void setUp() { + userSession.login("login").setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); + dbClient = db.getDbClient(); + dbSession = db.getSession(); + + PermissionRepository repository = new PermissionRepository(dbClient, new Settings()); + PermissionFinder permissionFinder = new PermissionFinder(dbClient); + ComponentFinder componentFinder = new ComponentFinder(dbClient); + PermissionService permissionService = new PermissionService(dbClient, repository, issueAuthorizationIndexer, userSession, componentFinder); + PermissionDependenciesFinder permissionDependenciesFinder = new PermissionDependenciesFinder(dbClient, componentFinder); + + ApplyTemplateAction underTest = new ApplyTemplateAction(dbClient, permissionService, permissionDependenciesFinder); + ws = new WsActionTester(underTest); + + user1 = insertUser(newUserDto().setLogin("user-login-1")); + user2 = insertUser(newUserDto().setLogin("user-login-2")); + group1 = insertGroup(newGroupDto().setName("group-name-1")); + group2 = insertGroup(newGroupDto().setName("group-name-2")); + + // template 1 + template1 = insertTemplate(newPermissionTemplateDto().setUuid("permission-template-uuid-1")); + addUserToTemplate(user1, template1, UserRole.CODEVIEWER); + addUserToTemplate(user2, template1, UserRole.ISSUE_ADMIN); + addGroupToTemplate(group1, template1, UserRole.ADMIN); + addGroupToTemplate(group2, template1, UserRole.USER); + // template 2 + template2 = insertTemplate(newPermissionTemplateDto().setUuid("permission-template-uuid-2")); + addUserToTemplate(user1, template2, UserRole.USER); + addUserToTemplate(user2, template2, UserRole.USER); + addGroupToTemplate(group1, template2, UserRole.USER); + addGroupToTemplate(group2, template2, UserRole.USER); + + project = insertProject(newProjectDto("project-uuid-1")); + addUserPermissionToProject(user1, project, UserRole.ADMIN); + addUserPermissionToProject(user2, project, UserRole.ADMIN); + addGroupPermissionToProject(group1, project, UserRole.ADMIN); + addGroupPermissionToProject(group2, project, UserRole.ADMIN); + + commit(); + } + + @Test + public void apply_template_with_project_uuid() { + assertThat(selectProjectPermissionGroups(project, UserRole.ADMIN)).hasSize(2); + assertThat(selectProjectPermissionUsers(project, UserRole.ADMIN)).hasSize(2); + + newRequest(template1.getUuid(), project.uuid(), null); + + assertTemplate1AppliedToProject(); + verify(issueAuthorizationIndexer).index(); + } + + @Test + public void apply_template_with_project_uuid_by_template_name() { + ws.newRequest() + .setParam(PARAM_TEMPLATE_NAME, template1.getName().toUpperCase()) + .setParam(PARAM_PROJECT_ID, project.uuid()) + .execute(); + commit(); + + assertTemplate1AppliedToProject(); + } + + @Test + public void apply_template_with_project_key() { + newRequest(template1.getUuid(), null, project.key()); + + assertTemplate1AppliedToProject(); + } + + @Test + public void fail_when_unknown_template() { + expectedException.expect(NotFoundException.class); + expectedException.expectMessage("Permission template with id 'unknown-template-uuid' is not found"); + + newRequest("unknown-template-uuid", project.uuid(), null); + } + + @Test + public void fail_when_unknown_project_uuid() { + expectedException.expect(NotFoundException.class); + expectedException.expectMessage("Project id 'unknown-project-uuid' not found"); + + newRequest(template1.getUuid(), "unknown-project-uuid", null); + } + + @Test + public void fail_when_unknown_project_key() { + expectedException.expect(NotFoundException.class); + expectedException.expectMessage("Project key 'unknown-project-key' not found"); + + newRequest(template1.getUuid(), null, "unknown-project-key"); + } + + @Test + public void fail_when_template_is_not_provided() { + expectedException.expect(BadRequestException.class); + + newRequest(null, project.uuid(), null); + } + + @Test + public void fail_when_project_uuid_and_key_not_provided() { + expectedException.expect(BadRequestException.class); + expectedException.expectMessage("Project id or project key must be provided, not both."); + + newRequest(template1.getUuid(), null, null); + } + + @Test + public void fail_when_anonymous() { + expectedException.expect(UnauthorizedException.class); + userSession.anonymous(); + + newRequest(template1.getUuid(), project.uuid(), null); + } + + @Test + public void fail_when_insufficient_privileges() { + expectedException.expect(ForbiddenException.class); + userSession.login().setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION); + + newRequest(template1.getUuid(), project.uuid(), null); + } + + private void assertTemplate1AppliedToProject() { + assertThat(selectProjectPermissionGroups(project, UserRole.ADMIN)).extracting("name").containsExactly(group1.getName()); + assertThat(selectProjectPermissionGroups(project, UserRole.USER)).extracting("name").containsExactly(group2.getName()); + assertThat(selectProjectPermissionUsers(project, UserRole.ADMIN)).isEmpty(); + assertThat(selectProjectPermissionUsers(project, UserRole.CODEVIEWER)).extracting("login").containsExactly(user1.getLogin()); + assertThat(selectProjectPermissionUsers(project, UserRole.ISSUE_ADMIN)).extracting("login").containsExactly(user2.getLogin()); + } + + private TestResponse newRequest(@Nullable String templateUuid, @Nullable String projectUuid, @Nullable String projectKey) { + TestRequest request = ws.newRequest(); + if (templateUuid != null) { + request.setParam(PARAM_TEMPLATE_ID, templateUuid); + } + if (projectUuid != null) { + request.setParam(PARAM_PROJECT_ID, projectUuid); + } + if (projectKey != null) { + request.setParam(PARAM_PROJECT_KEY, projectKey); + } + + TestResponse result = request.execute(); + commit(); + + return result; + } + + private ComponentDto insertProject(ComponentDto project) { + dbClient.componentDao().insert(dbSession, project); + return dbClient.componentDao().selectOrFailByUuid(dbSession, project.uuid()); + } + + private PermissionTemplateDto insertTemplate(PermissionTemplateDto template) { + return dbClient.permissionTemplateDao().insert(dbSession, template); + } + + private UserDto insertUser(UserDto userDto) { + return dbClient.userDao().insert(dbSession, userDto.setActive(true)); + } + + private GroupDto insertGroup(GroupDto group) { + return dbClient.groupDao().insert(dbSession, group); + } + + private void addUserToTemplate(UserDto user, PermissionTemplateDto permissionTemplate, String permission) { + dbClient.permissionTemplateDao().insertUserPermission(dbSession, permissionTemplate.getId(), user.getId(), permission); + } + + private void addGroupToTemplate(GroupDto group, PermissionTemplateDto permissionTemplate, String permission) { + dbClient.permissionTemplateDao().insertGroupPermission(dbSession, permissionTemplate.getId(), group.getId(), permission); + } + + private void addUserPermissionToProject(UserDto user, ComponentDto project, String permission) { + dbClient.roleDao().insertUserRole(dbSession, new UserRoleDto() + .setRole(permission) + .setUserId(user.getId()) + .setResourceId(project.getId())); + } + + private void addGroupPermissionToProject(GroupDto group, ComponentDto project, String permission) { + dbClient.roleDao().insertGroupRole(dbSession, new GroupRoleDto() + .setRole(permission) + .setResourceId(project.getId()) + .setGroupId(group.getId())); + } + + private List selectProjectPermissionGroups(ComponentDto project, String permission) { + return FluentIterable.from(dbClient.permissionDao().selectGroups(dbSession, query(permission), project.getId())) + .filter(new PermissionNotNull()) + .toList(); + } + + private List selectProjectPermissionUsers(ComponentDto project, String permission) { + return dbClient.permissionDao().selectUsers(dbSession, query(permission), project.getId(), 0, Integer.MAX_VALUE); + } + + private void commit() { + dbSession.commit(); + } + + private static PermissionQuery query(String permission) { + return PermissionQuery.builder().membership(IN).permission(permission).build(); + } + + private static class PermissionNotNull implements Predicate { + @Override + public boolean apply(@Nullable GroupWithPermissionDto input) { + return input.getPermission() != null; + } + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/CreateTemplateActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/CreateTemplateActionTest.java new file mode 100644 index 00000000000..991600c8f54 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/CreateTemplateActionTest.java @@ -0,0 +1,175 @@ +/* + * 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.template; + +import javax.annotation.Nullable; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.utils.System2; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.DbTester; +import org.sonar.db.permission.PermissionTemplateDto; +import org.sonar.server.exceptions.BadRequestException; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.exceptions.UnauthorizedException; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.TestRequest; +import org.sonar.server.ws.TestResponse; +import org.sonar.server.ws.WsActionTester; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.sonar.db.permission.PermissionTemplateTesting.newPermissionTemplateDto; +import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_DESCRIPTION; +import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_NAME; +import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_PATTERN; +import static org.sonar.test.JsonAssert.assertJson; + +public class CreateTemplateActionTest { + + @Rule + public DbTester db = DbTester.create(System2.INSTANCE); + @Rule + public UserSessionRule userSession = UserSessionRule.standalone(); + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + WsActionTester ws; + DbClient dbClient; + DbSession dbSession; + System2 system = mock(System2.class); + + @Before + public void setUp() { + userSession.login().setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); + when(system.now()).thenReturn(1440512328743L); + + dbClient = db.getDbClient(); + dbSession = db.getSession(); + ws = new WsActionTester(new CreateTemplateAction(dbClient, userSession, system)); + } + + @Test + public void create_full_permission_template() { + TestResponse result = newRequest("Finance", "Permissions for financially related projects", ".*\\.finance\\..*"); + + assertJson(result.getInput()) + .ignoreFields("id") + .isSimilarTo(getClass().getResource("create_template-example.json")); + PermissionTemplateDto finance = dbClient.permissionTemplateDao().selectByName(dbSession, "Finance"); + assertThat(finance.getName()).isEqualTo("Finance"); + assertThat(finance.getDescription()).isEqualTo("Permissions for financially related projects"); + assertThat(finance.getKeyPattern()).isEqualTo(".*\\.finance\\..*"); + assertThat(finance.getKee()).isNotEmpty(); + assertThat(finance.getCreatedAt().getTime()).isEqualTo(1440512328743L); + assertThat(finance.getUpdatedAt().getTime()).isEqualTo(1440512328743L); + } + + @Test + public void create_minimalist_permission_template() { + newRequest("Finance", null, null); + + PermissionTemplateDto finance = dbClient.permissionTemplateDao().selectByName(dbSession, "Finance"); + assertThat(finance.getName()).isEqualTo("Finance"); + assertThat(finance.getDescription()).isNullOrEmpty(); + assertThat(finance.getKeyPattern()).isNullOrEmpty(); + assertThat(finance.getKee()).isNotEmpty(); + assertThat(finance.getCreatedAt().getTime()).isEqualTo(1440512328743L); + assertThat(finance.getUpdatedAt().getTime()).isEqualTo(1440512328743L); + } + + @Test + public void fail_if_name_not_provided() { + expectedException.expect(IllegalArgumentException.class); + + newRequest(null, null, null); + } + + @Test + public void fail_if_name_empty() { + expectedException.expect(BadRequestException.class); + expectedException.expectMessage("The template name must not be blank"); + + newRequest("", null, null); + } + + @Test + public void fail_if_regexp_if_not_valid() { + expectedException.expect(BadRequestException.class); + expectedException.expectMessage("The 'projectKeyPattern' parameter must be a valid Java regular expression. '[azerty' was passed"); + + newRequest("Finance", null, "[azerty"); + } + + @Test + public void fail_if_name_already_exists_in_database_case_insensitive() { + expectedException.expect(BadRequestException.class); + expectedException.expectMessage("A template with the name 'Finance' already exists (case insensitive)."); + insertTemplate(newPermissionTemplateDto().setName("finance")); + commit(); + + newRequest("Finance", null, null); + } + + @Test + public void fail_if_not_logged_in() { + expectedException.expect(UnauthorizedException.class); + userSession.anonymous(); + + newRequest("Finance", null, null); + } + + @Test + public void fail_if_not_admin() { + expectedException.expect(ForbiddenException.class); + userSession.setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); + + newRequest("Finance", null, null); + } + + private PermissionTemplateDto insertTemplate(PermissionTemplateDto template) { + return dbClient.permissionTemplateDao().insert(dbSession, template); + } + + private void commit() { + dbSession.commit(); + } + + private TestResponse newRequest(@Nullable String name, @Nullable String description, @Nullable String projectPattern) { + TestRequest request = ws.newRequest(); + if (name != null) { + request.setParam(PARAM_NAME, name); + } + if (description != null) { + request.setParam(PARAM_DESCRIPTION, description); + } + if (projectPattern != null) { + request.setParam(PARAM_PATTERN, projectPattern); + } + + return request.execute(); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/DefaultPermissionTemplateFinderTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/DefaultPermissionTemplateFinderTest.java new file mode 100644 index 00000000000..2e8e6219703 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/DefaultPermissionTemplateFinderTest.java @@ -0,0 +1,83 @@ +/* + * 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.template; + +import java.util.List; +import java.util.Set; +import org.junit.Before; +import org.junit.Test; +import org.sonar.api.config.Settings; +import org.sonar.api.resources.Qualifiers; +import org.sonar.api.resources.ResourceType; +import org.sonar.api.resources.ResourceTypes; +import org.sonar.server.permission.ws.template.DefaultPermissionTemplateFinder; + +import static java.util.Arrays.asList; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.sonar.server.permission.DefaultPermissionTemplates.DEFAULT_TEMPLATE_PROPERTY; +import static org.sonar.server.permission.DefaultPermissionTemplates.defaultRootQualifierTemplateProperty; + +public class DefaultPermissionTemplateFinderTest { + + ResourceTypes resourceTypes = mock(ResourceTypes.class); + Settings settings = new Settings(); + + DefaultPermissionTemplateFinder underTest; + + @Before + public void setUp() { + underTest = new DefaultPermissionTemplateFinder(settings, resourceTypes); + settings + .setProperty(DEFAULT_TEMPLATE_PROPERTY, "default-template-uuid") + .setProperty(defaultRootQualifierTemplateProperty(Qualifiers.PROJECT), "default-project-template-uuid") + .setProperty(defaultRootQualifierTemplateProperty("DEV"), "default-dev-template-uuid") + .setProperty(defaultRootQualifierTemplateProperty(Qualifiers.VIEW), "default-view-template-uuid"); + when(resourceTypes.getRoots()).thenReturn(rootResourceTypes()); + } + + @Test + public void get_default_template_uuids_in_settings() { + Set result = underTest.getDefaultTemplateUuids(); + + assertThat(result).containsOnly("default-project-template-uuid", "default-view-template-uuid", "default-dev-template-uuid"); + } + + @Test + public void get_default_template_uuid_if_no_property() { + settings = new Settings(); + settings.setProperty(DEFAULT_TEMPLATE_PROPERTY, "default-template-uuid"); + underTest = new DefaultPermissionTemplateFinder(settings, resourceTypes); + + Set result = underTest.getDefaultTemplateUuids(); + + assertThat(result).containsOnly("default-template-uuid"); + } + + private static List rootResourceTypes() { + ResourceType project = ResourceType.builder(Qualifiers.PROJECT).build(); + ResourceType view = ResourceType.builder(Qualifiers.VIEW).build(); + ResourceType dev = ResourceType.builder("DEV").build(); + + return asList(project, view, dev); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/DeleteTemplateActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/DeleteTemplateActionTest.java new file mode 100644 index 00000000000..8515de5e20f --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/DeleteTemplateActionTest.java @@ -0,0 +1,184 @@ +/* + * 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.template; + +import java.util.Collections; +import javax.annotation.Nullable; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.utils.System2; +import org.sonar.api.web.UserRole; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.DbTester; +import org.sonar.db.permission.PermissionTemplateDto; +import org.sonar.db.user.GroupDto; +import org.sonar.db.user.GroupTesting; +import org.sonar.db.user.UserDto; +import org.sonar.db.user.UserTesting; +import org.sonar.server.component.ComponentFinder; +import org.sonar.server.exceptions.BadRequestException; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.exceptions.UnauthorizedException; +import org.sonar.server.permission.ws.DeleteTemplateAction; +import org.sonar.server.permission.ws.PermissionDependenciesFinder; +import org.sonar.server.permission.ws.template.DefaultPermissionTemplateFinder; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.TestRequest; +import org.sonar.server.ws.TestResponse; +import org.sonar.server.ws.WsActionTester; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.mockito.internal.util.collections.Sets.newSet; +import static org.sonar.db.permission.PermissionTemplateTesting.newPermissionTemplateDto; +import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_TEMPLATE_ID; +import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_TEMPLATE_NAME; + +public class DeleteTemplateActionTest { + + static final String TEMPLATE_UUID = "permission-template-uuid"; + + @Rule + public DbTester db = DbTester.create(System2.INSTANCE); + @Rule + public UserSessionRule userSession = UserSessionRule.standalone(); + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + WsActionTester ws; + DbClient dbClient; + DbSession dbSession; + DefaultPermissionTemplateFinder defaultTemplatePermissionFinder; + + PermissionTemplateDto permissionTemplate; + + @Before + public void setUp() { + userSession.login().setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); + + dbClient = db.getDbClient(); + dbSession = db.getSession(); + defaultTemplatePermissionFinder = mock(DefaultPermissionTemplateFinder.class); + when(defaultTemplatePermissionFinder.getDefaultTemplateUuids()).thenReturn(Collections.emptySet()); + PermissionDependenciesFinder finder = new PermissionDependenciesFinder(dbClient, new ComponentFinder(dbClient)); + ws = new WsActionTester(new DeleteTemplateAction(dbClient, userSession, finder, defaultTemplatePermissionFinder)); + + permissionTemplate = insertTemplateAndAssociatedPermissions(newPermissionTemplateDto().setKee(TEMPLATE_UUID)); + PermissionTemplateDto permissionTemplateInDatabase = dbClient.permissionTemplateDao().selectByUuidWithUserAndGroupPermissions(dbSession, TEMPLATE_UUID); + assertThat(permissionTemplateInDatabase.getKee()).isEqualTo(TEMPLATE_UUID); + assertThat(permissionTemplateInDatabase.getGroupsPermissions()).isNotEmpty(); + assertThat(permissionTemplateInDatabase.getUsersPermissions()).isNotEmpty(); + } + + @Test + public void delete_template_in_db() { + TestResponse result = newRequest(TEMPLATE_UUID); + + assertThat(result.getInput()).isEmpty(); + assertThat(dbClient.permissionTemplateDao().selectByUuidWithUserAndGroupPermissions(dbSession, TEMPLATE_UUID)).isNull(); + } + + @Test + public void delete_template_by_name_case_insensitive() { + ws.newRequest() + .setParam(PARAM_TEMPLATE_NAME, permissionTemplate.getName().toUpperCase()) + .execute(); + commit(); + + assertThat(dbClient.permissionTemplateDao().selectByUuidWithUserAndGroupPermissions(dbSession, TEMPLATE_UUID)).isNull(); + } + + @Test + public void fail_if_uuid_is_not_known() { + expectedException.expect(NotFoundException.class); + + newRequest("unknown-template-uuid"); + } + + @Test + public void fail_if_template_is_default() { + expectedException.expect(BadRequestException.class); + expectedException.expectMessage("It is not possible to delete a default template"); + when(defaultTemplatePermissionFinder.getDefaultTemplateUuids()).thenReturn(newSet(TEMPLATE_UUID)); + + newRequest(TEMPLATE_UUID); + } + + @Test + public void fail_if_not_logged_in() { + expectedException.expect(UnauthorizedException.class); + userSession.anonymous(); + + newRequest(TEMPLATE_UUID); + } + + @Test + public void fail_if_not_admin() { + expectedException.expect(ForbiddenException.class); + userSession.login().setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); + + newRequest(TEMPLATE_UUID); + } + + @Test + public void fail_if_uuid_is_not_provided() { + expectedException.expect(BadRequestException.class); + + newRequest(null); + } + + private PermissionTemplateDto insertTemplateAndAssociatedPermissions(PermissionTemplateDto template) { + dbClient.permissionTemplateDao().insert(dbSession, template); + UserDto user = dbClient.userDao().insert(dbSession, UserTesting.newUserDto().setActive(true)); + GroupDto group = dbClient.groupDao().insert(dbSession, GroupTesting.newGroupDto()); + dbClient.permissionTemplateDao().insertUserPermission(dbSession, template.getId(), user.getId(), UserRole.ADMIN); + dbClient.permissionTemplateDao().insertGroupPermission(dbSession, template.getId(), group.getId(), UserRole.CODEVIEWER); + commit(); + + return template; + } + + private void commit() { + dbSession.commit(); + } + + private TestResponse newRequest(@Nullable String id) { + TestRequest request = ws.newRequest(); + if (id != null) { + request.setParam(PARAM_TEMPLATE_ID, id); + } + + TestResponse result = executeRequest(request); + commit(); + return result; + } + + private static TestResponse executeRequest(TestRequest request) { + return request.execute(); + } + +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/RemoveGroupFromTemplateActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/RemoveGroupFromTemplateActionTest.java new file mode 100644 index 00000000000..e372afa7f9f --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/RemoveGroupFromTemplateActionTest.java @@ -0,0 +1,264 @@ +/* + * 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.template; + +import com.google.common.base.Function; +import java.util.List; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.rules.ExpectedException; +import org.sonar.api.utils.System2; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.DbTester; +import org.sonar.db.permission.GroupWithPermissionDto; +import org.sonar.db.permission.PermissionQuery; +import org.sonar.db.permission.PermissionTemplateDto; +import org.sonar.db.user.GroupDto; +import org.sonar.server.component.ComponentFinder; +import org.sonar.server.exceptions.BadRequestException; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.exceptions.UnauthorizedException; +import org.sonar.server.permission.ws.PermissionDependenciesFinder; +import org.sonar.server.permission.ws.WsPermissionParameters; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.TestRequest; +import org.sonar.server.ws.WsActionTester; +import org.sonar.test.DbTests; + +import static com.google.common.collect.FluentIterable.from; +import static org.assertj.core.api.Assertions.assertThat; +import static org.sonar.api.security.DefaultGroups.ANYONE; +import static org.sonar.api.web.UserRole.CODEVIEWER; +import static org.sonar.db.permission.PermissionTemplateTesting.newPermissionTemplateDto; +import static org.sonar.db.user.GroupMembershipQuery.IN; +import static org.sonar.db.user.GroupTesting.newGroupDto; +import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_GROUP_ID; +import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_GROUP_NAME; +import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_PERMISSION; +import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_TEMPLATE_ID; +import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_TEMPLATE_NAME; + +@Category(DbTests.class) +public class RemoveGroupFromTemplateActionTest { + + private static final String GROUP_NAME = "group-name"; + private static final String PERMISSION = CODEVIEWER; + @Rule + public DbTester db = DbTester.create(System2.INSTANCE); + @Rule + public ExpectedException expectedException = ExpectedException.none(); + @Rule + public UserSessionRule userSession = UserSessionRule.standalone(); + + WsActionTester ws; + DbClient dbClient; + DbSession dbSession; + GroupDto group; + PermissionTemplateDto permissionTemplate; + + @Before + public void setUp() { + dbClient = db.getDbClient(); + dbSession = db.getSession(); + userSession.login().setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); + + PermissionDependenciesFinder dependenciesFinder = new PermissionDependenciesFinder(dbClient, new ComponentFinder(dbClient)); + ws = new WsActionTester(new RemoveGroupFromTemplateAction(dbClient, dependenciesFinder, userSession)); + + group = insertGroup(newGroupDto().setName(GROUP_NAME)); + permissionTemplate = insertPermissionTemplate(newPermissionTemplateDto()); + addGroupToPermissionTemplate(permissionTemplate.getId(), group.getId(), PERMISSION); + commit(); + } + + @Test + public void remove_group_from_template() { + assertThat(getGroupNamesInTemplateAndPermission(permissionTemplate.getId(), PERMISSION)).containsExactly(GROUP_NAME); + commit(); + + newRequest(GROUP_NAME, permissionTemplate.getKee(), PERMISSION); + + assertThat(getGroupNamesInTemplateAndPermission(permissionTemplate.getId(), PERMISSION)).isEmpty(); + } + + @Test + public void remove_group_from_template_by_name_case_insensitive() { + assertThat(getGroupNamesInTemplateAndPermission(permissionTemplate.getId(), PERMISSION)).containsExactly(GROUP_NAME); + commit(); + + ws.newRequest() + .setParam(PARAM_GROUP_NAME, GROUP_NAME) + .setParam(PARAM_PERMISSION, PERMISSION) + .setParam(PARAM_TEMPLATE_NAME, permissionTemplate.getName().toUpperCase()) + .execute(); + commit(); + + assertThat(getGroupNamesInTemplateAndPermission(permissionTemplate.getId(), PERMISSION)).isEmpty(); + } + + @Test + public void remove_group_with_group_id() { + assertThat(getGroupNamesInTemplateAndPermission(permissionTemplate.getId(), PERMISSION)).containsExactly(GROUP_NAME); + commit(); + + ws.newRequest() + .setParam(PARAM_TEMPLATE_ID, permissionTemplate.getKee()) + .setParam(PARAM_PERMISSION, PERMISSION) + .setParam(PARAM_GROUP_ID, String.valueOf(group.getId())) + .execute(); + + assertThat(getGroupNamesInTemplateAndPermission(permissionTemplate.getId(), PERMISSION)).isEmpty(); + } + + @Test + public void remove_group_twice_without_error() { + newRequest(GROUP_NAME, permissionTemplate.getKee(), PERMISSION); + newRequest(GROUP_NAME, permissionTemplate.getKee(), PERMISSION); + + assertThat(getGroupNamesInTemplateAndPermission(permissionTemplate.getId(), PERMISSION)).isEmpty(); + } + + @Test + public void remove_anyone_group_from_template() { + addGroupToPermissionTemplate(permissionTemplate.getId(), null, PERMISSION); + commit(); + + newRequest(ANYONE, permissionTemplate.getKee(), PERMISSION); + + assertThat(getGroupNamesInTemplateAndPermission(permissionTemplate.getId(), PERMISSION)).containsExactly(GROUP_NAME); + } + + @Test + public void fail_if_not_a_project_permission() { + expectedException.expect(BadRequestException.class); + + newRequest(GROUP_NAME, permissionTemplate.getKee(), GlobalPermissions.PREVIEW_EXECUTION); + } + + @Test + public void fail_if_insufficient_privileges() { + expectedException.expect(ForbiddenException.class); + userSession.setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); + + newRequest(GROUP_NAME, permissionTemplate.getKee(), PERMISSION); + } + + @Test + public void fail_if_not_logged_in() { + expectedException.expect(UnauthorizedException.class); + userSession.anonymous(); + + newRequest(GROUP_NAME, permissionTemplate.getKee(), PERMISSION); + } + + @Test + public void fail_if_group_params_missing() { + expectedException.expect(BadRequestException.class); + + newRequest(null, permissionTemplate.getKee(), PERMISSION); + } + + @Test + public void fail_if_permission_missing() { + expectedException.expect(IllegalArgumentException.class); + + newRequest(GROUP_NAME, permissionTemplate.getKee(), null); + } + + @Test + public void fail_if_template_missing() { + expectedException.expect(BadRequestException.class); + + newRequest(GROUP_NAME, null, PERMISSION); + } + + @Test + public void fail_if_group_does_not_exist() { + expectedException.expect(NotFoundException.class); + expectedException.expectMessage("Group with name 'unknown-group-name' is not found"); + + newRequest("unknown-group-name", permissionTemplate.getKee(), PERMISSION); + } + + @Test + public void fail_if_template_key_does_not_exist() { + expectedException.expect(NotFoundException.class); + expectedException.expectMessage("Permission template with id 'unknown-key' is not found"); + + newRequest(GROUP_NAME, "unknown-key", PERMISSION); + } + + private void newRequest(@Nullable String groupName, @Nullable String templateKey, @Nullable String permission) { + TestRequest request = ws.newRequest(); + if (groupName != null) { + request.setParam(WsPermissionParameters.PARAM_GROUP_NAME, groupName); + } + if (templateKey != null) { + request.setParam(PARAM_TEMPLATE_ID, templateKey); + } + if (permission != null) { + request.setParam(WsPermissionParameters.PARAM_PERMISSION, permission); + } + + request.execute(); + } + + private void commit() { + dbSession.commit(); + } + + private GroupDto insertGroup(GroupDto groupDto) { + return dbClient.groupDao().insert(dbSession, groupDto); + } + + private PermissionTemplateDto insertPermissionTemplate(PermissionTemplateDto permissionTemplate) { + return dbClient.permissionTemplateDao().insert(dbSession, permissionTemplate); + } + + private void addGroupToPermissionTemplate(long permissionTemplateId, @Nullable Long groupId, String permission) { + dbClient.permissionTemplateDao().insertGroupPermission(dbSession, permissionTemplateId, groupId, permission); + } + + private List getGroupNamesInTemplateAndPermission(long templateId, String permission) { + PermissionQuery permissionQuery = PermissionQuery.builder().permission(permission).membership(IN).build(); + return from(dbClient.permissionTemplateDao() + .selectGroups(dbSession, permissionQuery, templateId)) + .transform(GroupWithPermissionToGroupName.INSTANCE) + .toList(); + } + + private enum GroupWithPermissionToGroupName implements Function { + INSTANCE; + + @Override + public String apply(@Nonnull GroupWithPermissionDto groupWithPermission) { + return groupWithPermission.getName(); + } + + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/RemoveUserFromTemplateActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/RemoveUserFromTemplateActionTest.java new file mode 100644 index 00000000000..588e651dc84 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/RemoveUserFromTemplateActionTest.java @@ -0,0 +1,255 @@ +/* + * 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.template; + +import com.google.common.base.Function; +import java.util.List; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.rules.ExpectedException; +import org.sonar.api.utils.System2; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.DbTester; +import org.sonar.db.permission.PermissionQuery; +import org.sonar.db.permission.PermissionTemplateDto; +import org.sonar.db.permission.UserWithPermissionDto; +import org.sonar.db.user.UserDto; +import org.sonar.server.component.ComponentFinder; +import org.sonar.server.exceptions.BadRequestException; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.exceptions.UnauthorizedException; +import org.sonar.server.permission.ws.PermissionDependenciesFinder; +import org.sonar.server.permission.ws.WsPermissionParameters; +import org.sonar.server.permission.ws.template.RemoveUserFromTemplateAction; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.TestRequest; +import org.sonar.server.ws.WsActionTester; +import org.sonar.test.DbTests; + +import static com.google.common.collect.FluentIterable.from; +import static org.assertj.core.api.Assertions.assertThat; +import static org.sonar.api.web.UserRole.CODEVIEWER; +import static org.sonar.api.web.UserRole.ISSUE_ADMIN; +import static org.sonar.db.permission.PermissionTemplateTesting.newPermissionTemplateDto; +import static org.sonar.db.user.GroupMembershipQuery.IN; +import static org.sonar.db.user.UserTesting.newUserDto; +import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_PERMISSION; +import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_TEMPLATE_NAME; +import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_USER_LOGIN; + +@Category(DbTests.class) +public class RemoveUserFromTemplateActionTest { + + private static final String USER_LOGIN = "user-login"; + private static final String DEFAULT_PERMISSION = CODEVIEWER; + @Rule + public DbTester db = DbTester.create(System2.INSTANCE); + @Rule + public ExpectedException expectedException = ExpectedException.none(); + @Rule + public UserSessionRule userSession = UserSessionRule.standalone(); + + WsActionTester ws; + DbClient dbClient; + DbSession dbSession; + UserDto user; + PermissionTemplateDto permissionTemplate; + + @Before + public void setUp() { + dbClient = db.getDbClient(); + dbSession = db.getSession(); + userSession.login().setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); + + PermissionDependenciesFinder dependenciesFinder = new PermissionDependenciesFinder(dbClient, new ComponentFinder(dbClient)); + ws = new WsActionTester(new RemoveUserFromTemplateAction(dbClient, dependenciesFinder, userSession)); + + user = insertUser(newUserDto().setLogin(USER_LOGIN)); + permissionTemplate = insertPermissionTemplate(newPermissionTemplateDto()); + addUserToTemplate(user, permissionTemplate, DEFAULT_PERMISSION); + commit(); + } + + @Test + public void remove_user_from_template() { + newRequest(USER_LOGIN, permissionTemplate.getKee(), DEFAULT_PERMISSION); + + assertThat(getLoginsInTemplateAndPermission(permissionTemplate.getId(), DEFAULT_PERMISSION)).isEmpty(); + } + + @Test + public void remove_user_from_template_by_name_case_insensitive() { + ws.newRequest() + .setParam(PARAM_USER_LOGIN, USER_LOGIN) + .setParam(PARAM_PERMISSION, DEFAULT_PERMISSION) + .setParam(PARAM_TEMPLATE_NAME, permissionTemplate.getName().toUpperCase()) + .execute(); + commit(); + + assertThat(getLoginsInTemplateAndPermission(permissionTemplate.getId(), DEFAULT_PERMISSION)).isEmpty(); + } + + @Test + public void remove_user_from_template_twice_without_failing() { + newRequest(USER_LOGIN, permissionTemplate.getKee(), DEFAULT_PERMISSION); + newRequest(USER_LOGIN, permissionTemplate.getKee(), DEFAULT_PERMISSION); + + assertThat(getLoginsInTemplateAndPermission(permissionTemplate.getId(), DEFAULT_PERMISSION)).isEmpty(); + } + + @Test + public void keep_user_permission_not_removed() { + addUserToTemplate(user, permissionTemplate, ISSUE_ADMIN); + commit(); + + newRequest(USER_LOGIN, permissionTemplate.getKee(), DEFAULT_PERMISSION); + + assertThat(getLoginsInTemplateAndPermission(permissionTemplate.getId(), DEFAULT_PERMISSION)).isEmpty(); + assertThat(getLoginsInTemplateAndPermission(permissionTemplate.getId(), ISSUE_ADMIN)).containsExactly(user.getLogin()); + } + + @Test + public void keep_other_users_when_one_user_removed() { + UserDto newUser = insertUser(newUserDto().setLogin("new-login")); + addUserToTemplate(newUser, permissionTemplate, DEFAULT_PERMISSION); + commit(); + + newRequest(USER_LOGIN, permissionTemplate.getKee(), DEFAULT_PERMISSION); + + assertThat(getLoginsInTemplateAndPermission(permissionTemplate.getId(), DEFAULT_PERMISSION)).containsExactly("new-login"); + } + + @Test + public void fail_if_not_a_project_permission() { + expectedException.expect(BadRequestException.class); + + newRequest(USER_LOGIN, permissionTemplate.getKee(), GlobalPermissions.PREVIEW_EXECUTION); + } + + @Test + public void fail_if_insufficient_privileges() { + expectedException.expect(ForbiddenException.class); + userSession.setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); + + newRequest(USER_LOGIN, permissionTemplate.getKee(), DEFAULT_PERMISSION); + } + + @Test + public void fail_if_not_logged_in() { + expectedException.expect(UnauthorizedException.class); + userSession.anonymous(); + + newRequest(USER_LOGIN, permissionTemplate.getKee(), DEFAULT_PERMISSION); + } + + @Test + public void fail_if_user_missing() { + expectedException.expect(IllegalArgumentException.class); + + newRequest(null, permissionTemplate.getKee(), DEFAULT_PERMISSION); + } + + @Test + public void fail_if_permission_missing() { + expectedException.expect(IllegalArgumentException.class); + + newRequest(USER_LOGIN, permissionTemplate.getKee(), null); + } + + @Test + public void fail_if_template_missing() { + expectedException.expect(BadRequestException.class); + + newRequest(USER_LOGIN, null, DEFAULT_PERMISSION); + } + + @Test + public void fail_if_user_does_not_exist() { + expectedException.expect(NotFoundException.class); + expectedException.expectMessage("User with login 'unknown-login' is not found"); + + newRequest("unknown-login", permissionTemplate.getKee(), DEFAULT_PERMISSION); + } + + @Test + public void fail_if_template_key_does_not_exist() { + expectedException.expect(NotFoundException.class); + expectedException.expectMessage("Permission template with id 'unknown-key' is not found"); + + newRequest(USER_LOGIN, "unknown-key", DEFAULT_PERMISSION); + } + + private void newRequest(@Nullable String userLogin, @Nullable String templateKey, @Nullable String permission) { + TestRequest request = ws.newRequest(); + if (userLogin != null) { + request.setParam(PARAM_USER_LOGIN, userLogin); + } + if (templateKey != null) { + request.setParam(WsPermissionParameters.PARAM_TEMPLATE_ID, templateKey); + } + if (permission != null) { + request.setParam(WsPermissionParameters.PARAM_PERMISSION, permission); + } + + request.execute(); + } + + private void commit() { + dbSession.commit(); + } + + private UserDto insertUser(UserDto userDto) { + return dbClient.userDao().insert(dbSession, userDto.setActive(true)); + } + + private PermissionTemplateDto insertPermissionTemplate(PermissionTemplateDto permissionTemplate) { + return dbClient.permissionTemplateDao().insert(dbSession, permissionTemplate); + } + + private List getLoginsInTemplateAndPermission(long templateId, String permission) { + PermissionQuery permissionQuery = PermissionQuery.builder().permission(permission).membership(IN).build(); + return from(dbClient.permissionTemplateDao() + .selectUsers(dbSession, permissionQuery, templateId, 0, Integer.MAX_VALUE)) + .transform(UserWithPermissionToUserLogin.INSTANCE) + .toList(); + } + + private enum UserWithPermissionToUserLogin implements Function { + INSTANCE; + + @Override + public String apply(@Nonnull UserWithPermissionDto userWithPermission) { + return userWithPermission.getLogin(); + } + + } + + private void addUserToTemplate(UserDto user, PermissionTemplateDto permissionTemplate, String permission) { + dbClient.permissionTemplateDao().insertUserPermission(dbSession, permissionTemplate.getId(), user.getId(), permission); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/SearchTemplatesActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/SearchTemplatesActionTest.java new file mode 100644 index 00000000000..230b5424443 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/SearchTemplatesActionTest.java @@ -0,0 +1,249 @@ +/* + * 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.template; + +import java.util.Date; +import java.util.List; +import javax.annotation.Nullable; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.rules.ExpectedException; +import org.sonar.api.config.Settings; +import org.sonar.api.resources.Qualifiers; +import org.sonar.api.resources.ResourceType; +import org.sonar.api.resources.ResourceTypes; +import org.sonar.api.utils.System2; +import org.sonar.api.web.UserRole; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.DbTester; +import org.sonar.db.permission.PermissionTemplateDto; +import org.sonar.db.user.GroupDto; +import org.sonar.db.user.UserDto; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.exceptions.UnauthorizedException; +import org.sonar.server.i18n.I18nRule; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.WsActionTester; +import org.sonar.test.DbTests; + +import static java.util.Arrays.asList; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.sonar.api.server.ws.WebService.Param.TEXT_QUERY; +import static org.sonar.core.permission.GlobalPermissions.QUALITY_PROFILE_ADMIN; +import static org.sonar.core.util.Uuids.UUID_EXAMPLE_01; +import static org.sonar.core.util.Uuids.UUID_EXAMPLE_02; +import static org.sonar.core.util.Uuids.UUID_EXAMPLE_03; +import static org.sonar.db.permission.PermissionTemplateTesting.newPermissionTemplateDto; +import static org.sonar.db.user.GroupTesting.newGroupDto; +import static org.sonar.db.user.UserTesting.newUserDto; +import static org.sonar.server.permission.DefaultPermissionTemplates.defaultRootQualifierTemplateProperty; +import static org.sonar.test.JsonAssert.assertJson; + +@Category(DbTests.class) +public class SearchTemplatesActionTest { + @ClassRule + public static DbTester db = DbTester.create(System2.INSTANCE); + @Rule + public ExpectedException expectedException = ExpectedException.none(); + @Rule + public UserSessionRule userSession = UserSessionRule.standalone(); + + WsActionTester ws; + I18nRule i18n = new I18nRule(); + DbClient dbClient = db.getDbClient(); + DbSession dbSession = db.getSession(); + ResourceTypes resourceTypes = mock(ResourceTypes.class); + SearchTemplatesDataLoader dataLoader; + + SearchTemplatesAction underTest; + + @Before + public void setUp() { + db.truncateTables(); + i18n.setProjectPermissions(); + when(resourceTypes.getRoots()).thenReturn(rootResourceTypes()); + + Settings settings = new Settings(); + settings.setProperty(defaultRootQualifierTemplateProperty(Qualifiers.PROJECT), UUID_EXAMPLE_01); + settings.setProperty(defaultRootQualifierTemplateProperty(Qualifiers.VIEW), UUID_EXAMPLE_02); + settings.setProperty(defaultRootQualifierTemplateProperty("DEV"), UUID_EXAMPLE_03); + + DefaultPermissionTemplateFinder defaultPermissionTemplateFinder = new DefaultPermissionTemplateFinder(settings, resourceTypes); + + dataLoader = new SearchTemplatesDataLoader(dbClient, defaultPermissionTemplateFinder); + underTest = new SearchTemplatesAction(dbClient, userSession, i18n, dataLoader); + + ws = new WsActionTester(underTest); + + userSession.login().setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); + } + + @Test + public void search_project_permissions() { + PermissionTemplateDto projectTemplate = insertProjectTemplate(); + PermissionTemplateDto viewsTemplate = insertViewsTemplate(); + PermissionTemplateDto developerTemplate = insertDeveloperTemplate(); + + UserDto user1 = insertUser(newUserDto()); + UserDto user2 = insertUser(newUserDto()); + UserDto user3 = insertUser(newUserDto()); + + GroupDto group1 = insertGroup(newGroupDto()); + GroupDto group2 = insertGroup(newGroupDto()); + GroupDto group3 = insertGroup(newGroupDto()); + + addUserToTemplate(projectTemplate.getId(), user1.getId(), UserRole.ISSUE_ADMIN); + addUserToTemplate(projectTemplate.getId(), user2.getId(), UserRole.ISSUE_ADMIN); + addUserToTemplate(projectTemplate.getId(), user3.getId(), UserRole.ISSUE_ADMIN); + addUserToTemplate(projectTemplate.getId(), user1.getId(), UserRole.CODEVIEWER); + addGroupToTemplate(projectTemplate.getId(), group1.getId(), UserRole.ADMIN); + + addUserToTemplate(viewsTemplate.getId(), user1.getId(), UserRole.USER); + addUserToTemplate(viewsTemplate.getId(), user2.getId(), UserRole.USER); + addGroupToTemplate(viewsTemplate.getId(), group1.getId(), UserRole.ISSUE_ADMIN); + addGroupToTemplate(viewsTemplate.getId(), group2.getId(), UserRole.ISSUE_ADMIN); + addGroupToTemplate(viewsTemplate.getId(), group3.getId(), UserRole.ISSUE_ADMIN); + + addGroupToTemplate(developerTemplate.getId(), group1.getId(), UserRole.USER); + + commit(); + + String result = newRequest(); + + assertJson(result) + .withStrictArrayOrder() + .isSimilarTo(getClass().getResource("search_templates-example.json")); + } + + @Test + public void empty_result() { + String result = newRequest(); + + assertJson(result) + .withStrictArrayOrder() + .isSimilarTo(getClass().getResource("SearchTemplatesActionTest/empty.json")); + } + + @Test + public void search_by_name() { + insertProjectTemplate(); + insertViewsTemplate(); + insertDeveloperTemplate(); + commit(); + + String result = ws.newRequest() + .setParam(TEXT_QUERY, "views") + .execute().getInput(); + + assertThat(result).contains("Default template for Views") + .doesNotContain("projects") + .doesNotContain("developers"); + } + + @Test + public void fail_if_not_logged_in() { + expectedException.expect(UnauthorizedException.class); + userSession.anonymous(); + + ws.newRequest().execute(); + } + + @Test + public void fail_if_not_global_admin() { + expectedException.expect(ForbiddenException.class); + userSession.login().setGlobalPermissions(QUALITY_PROFILE_ADMIN); + + ws.newRequest().execute(); + } + + private String newRequest() { + return ws.newRequest().execute().getInput(); + } + + private PermissionTemplateDto insertProjectTemplate() { + return insertTemplate(newPermissionTemplateDto() + .setUuid(UUID_EXAMPLE_01) + .setName("Default template for Projects") + .setDescription("Template for new projects") + .setKeyPattern(null) + .setCreatedAt(new Date(1_000_000_000_000L)) + .setUpdatedAt(new Date(1_000_000_000_000L))); + } + + private PermissionTemplateDto insertViewsTemplate() { + return insertTemplate(newPermissionTemplateDto() + .setUuid(UUID_EXAMPLE_02) + .setName("Default template for Views") + .setDescription("Template for new views") + .setKeyPattern(".*sonar.views.*") + .setCreatedAt(new Date(1_000_000_000_000L)) + .setUpdatedAt(new Date(1_100_000_000_000L))); + } + + private PermissionTemplateDto insertDeveloperTemplate() { + return insertTemplate(newPermissionTemplateDto() + .setUuid(UUID_EXAMPLE_03) + .setName("Default template for Developers") + .setKeyPattern(".*sonar.developer.*") + .setDescription(null) + .setCreatedAt(new Date(1_100_500_000_000L)) + .setUpdatedAt(new Date(1_100_900_000_000L))); + } + + private PermissionTemplateDto insertTemplate(PermissionTemplateDto template) { + return dbClient.permissionTemplateDao().insert(dbSession, template); + } + + private GroupDto insertGroup(GroupDto groupDto) { + return dbClient.groupDao().insert(dbSession, groupDto); + } + + private UserDto insertUser(UserDto userDto) { + return dbClient.userDao().insert(dbSession, userDto.setActive(true)); + } + + private void addGroupToTemplate(long templateId, @Nullable Long groupId, String permission) { + dbClient.permissionTemplateDao().insertGroupPermission(dbSession, templateId, groupId, permission); + } + + private void addUserToTemplate(long templateId, long userId, String permission) { + dbClient.permissionTemplateDao().insertUserPermission(dbSession, templateId, userId, permission); + } + + private void commit() { + dbSession.commit(); + } + + private static List rootResourceTypes() { + ResourceType project = ResourceType.builder(Qualifiers.PROJECT).build(); + ResourceType view = ResourceType.builder(Qualifiers.VIEW).build(); + ResourceType dev = ResourceType.builder("DEV").build(); + + return asList(project, view, dev); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/SetDefaultTemplateActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/SetDefaultTemplateActionTest.java new file mode 100644 index 00000000000..6031f41268a --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/SetDefaultTemplateActionTest.java @@ -0,0 +1,198 @@ +/* + * 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.template; + +import java.util.List; +import java.util.Properties; +import javax.annotation.Nullable; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.rules.ExpectedException; +import org.sonar.api.config.PropertyDefinitions; +import org.sonar.api.resources.Qualifiers; +import org.sonar.api.resources.ResourceType; +import org.sonar.api.resources.ResourceTypes; +import org.sonar.api.utils.System2; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.db.DbClient; +import org.sonar.db.DbTester; +import org.sonar.db.permission.PermissionTemplateDto; +import org.sonar.db.permission.PermissionTemplateTesting; +import org.sonar.server.component.ComponentFinder; +import org.sonar.server.exceptions.BadRequestException; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.exceptions.UnauthorizedException; +import org.sonar.server.i18n.I18nRule; +import org.sonar.server.permission.ws.PermissionDependenciesFinder; +import org.sonar.server.permission.ws.template.SetDefaultTemplateAction; +import org.sonar.server.platform.PersistentSettings; +import org.sonar.server.platform.ServerSettings; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.TestRequest; +import org.sonar.server.ws.WsActionTester; +import org.sonar.test.DbTests; + +import static java.util.Arrays.asList; +import static java.util.Collections.singletonList; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.sonar.api.resources.Qualifiers.PROJECT; +import static org.sonar.api.resources.Qualifiers.VIEW; +import static org.sonar.server.permission.DefaultPermissionTemplates.DEFAULT_TEMPLATE_PROPERTY; +import static org.sonar.server.permission.DefaultPermissionTemplates.defaultRootQualifierTemplateProperty; +import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_QUALIFIER; +import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_TEMPLATE_ID; +import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_TEMPLATE_NAME; + +@Category(DbTests.class) +public class SetDefaultTemplateActionTest { + @Rule + public DbTester db = DbTester.create(System2.INSTANCE); + @Rule + public UserSessionRule userSession = UserSessionRule.standalone(); + @Rule + public ExpectedException expectedException = ExpectedException.none(); + I18nRule i18n = new I18nRule(); + + WsActionTester ws; + PersistentSettings persistentSettings; + ResourceTypes resourceTypes = mock(ResourceTypes.class); + + PermissionTemplateDto template; + + @Before + public void setUp() { + DbClient dbClient = db.getDbClient(); + persistentSettings = new PersistentSettings(dbClient.propertiesDao(), new ServerSettings(new PropertyDefinitions(), new Properties())); + persistentSettings.saveProperty(DEFAULT_TEMPLATE_PROPERTY, "any-template-uuid"); + persistentSettings.saveProperty(defaultRootQualifierTemplateProperty(PROJECT), "any-template-uuid"); + persistentSettings.saveProperty(defaultRootQualifierTemplateProperty(VIEW), "any-view-template-uuid"); + persistentSettings.saveProperty(defaultRootQualifierTemplateProperty("DEV"), "any-dev-template-uuid"); + when(resourceTypes.getRoots()).thenReturn(rootResourceTypes()); + userSession.login().setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); + + ws = new WsActionTester(new SetDefaultTemplateAction( + dbClient, + new PermissionDependenciesFinder(dbClient, new ComponentFinder(dbClient)), + resourceTypes, + persistentSettings, + userSession, i18n)); + + template = dbClient.permissionTemplateDao().insert(db.getSession(), PermissionTemplateTesting.newPermissionTemplateDto().setUuid("permission-template-uuid")); + } + + @Test + public void update_settings_for_project_qualifier() { + // default value is project qualifier's value + String result = newRequest(template.getUuid(), null); + + assertThat(result).isEmpty(); + assertThat(persistentSettings.getString(DEFAULT_TEMPLATE_PROPERTY)).isEqualTo("any-template-uuid"); + assertThat(persistentSettings.getString(defaultRootQualifierTemplateProperty(PROJECT))).isEqualTo(template.getUuid()); + assertThat(persistentSettings.getString(defaultRootQualifierTemplateProperty(VIEW))).isEqualTo("any-view-template-uuid"); + assertThat(persistentSettings.getString(defaultRootQualifierTemplateProperty("DEV"))).isEqualTo("any-dev-template-uuid"); + } + + @Test + public void update_settings_for_project_qualifier_by_template_name() { + ws.newRequest() + .setParam(PARAM_TEMPLATE_NAME, template.getName().toUpperCase()) + .execute(); + db.getSession().commit(); + + assertThat(persistentSettings.getString(DEFAULT_TEMPLATE_PROPERTY)).isEqualTo("any-template-uuid"); + assertThat(persistentSettings.getString(defaultRootQualifierTemplateProperty(PROJECT))).isEqualTo(template.getUuid()); + assertThat(persistentSettings.getString(defaultRootQualifierTemplateProperty(VIEW))).isEqualTo("any-view-template-uuid"); + assertThat(persistentSettings.getString(defaultRootQualifierTemplateProperty("DEV"))).isEqualTo("any-dev-template-uuid"); + } + + @Test + public void update_settings_of_views_property() { + newRequest(template.getUuid(), VIEW); + + assertThat(persistentSettings.getString(DEFAULT_TEMPLATE_PROPERTY)).isEqualTo("any-template-uuid"); + assertThat(persistentSettings.getString(defaultRootQualifierTemplateProperty(PROJECT))).isEqualTo("any-template-uuid"); + assertThat(persistentSettings.getString(defaultRootQualifierTemplateProperty(VIEW))).isEqualTo(template.getUuid()); + assertThat(persistentSettings.getString(defaultRootQualifierTemplateProperty("DEV"))).isEqualTo("any-dev-template-uuid"); + } + + @Test + public void fail_if_anonymous() { + expectedException.expect(UnauthorizedException.class); + userSession.anonymous(); + + newRequest(template.getUuid(), PROJECT); + } + + @Test + public void fail_if_not_admin() { + expectedException.expect(ForbiddenException.class); + userSession.login().setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); + + newRequest(template.getUuid(), PROJECT); + } + + @Test + public void fail_if_template_not_provided() { + expectedException.expect(BadRequestException.class); + + newRequest(null, PROJECT); + } + + @Test + public void fail_if_template_does_not_exist() { + expectedException.expect(NotFoundException.class); + + newRequest("unknown-template-uuid", PROJECT); + } + + @Test + public void fail_if_qualifier_is_not_root() { + expectedException.expect(BadRequestException.class); + when(resourceTypes.getRoots()).thenReturn(singletonList(ResourceType.builder(PROJECT).build())); + + newRequest(template.getUuid(), VIEW); + } + + private String newRequest(@Nullable String templateUuid, @Nullable String qualifier) { + TestRequest request = ws.newRequest(); + if (templateUuid != null) { + request.setParam(PARAM_TEMPLATE_ID, templateUuid); + } + if (qualifier != null) { + request.setParam(PARAM_QUALIFIER, qualifier); + } + + return request.execute().getInput(); + } + + private static List rootResourceTypes() { + ResourceType project = ResourceType.builder(PROJECT).build(); + ResourceType view = ResourceType.builder(Qualifiers.VIEW).build(); + ResourceType dev = ResourceType.builder("DEV").build(); + + return asList(project, view, dev); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/UpdateTemplateActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/UpdateTemplateActionTest.java new file mode 100644 index 00000000000..515fa91123d --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/UpdateTemplateActionTest.java @@ -0,0 +1,238 @@ +/* + * 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.template; + +import java.util.Date; +import javax.annotation.Nullable; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.utils.System2; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.DbTester; +import org.sonar.db.permission.PermissionTemplateDto; +import org.sonar.db.user.GroupDto; +import org.sonar.server.component.ComponentFinder; +import org.sonar.server.exceptions.BadRequestException; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.exceptions.UnauthorizedException; +import org.sonar.server.permission.ws.PermissionDependenciesFinder; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.TestRequest; +import org.sonar.server.ws.TestResponse; +import org.sonar.server.ws.WsActionTester; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.sonar.db.permission.PermissionTemplateTesting.newPermissionTemplateDto; +import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_DESCRIPTION; +import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_ID; +import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_NAME; +import static org.sonar.server.permission.ws.WsPermissionParameters.PARAM_PATTERN; +import static org.sonar.test.JsonAssert.assertJson; + +public class UpdateTemplateActionTest { + + @Rule + public DbTester db = DbTester.create(System2.INSTANCE); + @Rule + public UserSessionRule userSession = UserSessionRule.standalone(); + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + WsActionTester ws; + DbClient dbClient; + DbSession dbSession; + + PermissionTemplateDto templateDto; + + @Before + public void setUp() { + userSession.login().setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); + System2 system = mock(System2.class); + when(system.now()).thenReturn(1_440_512_328_743L); + + dbClient = db.getDbClient(); + dbSession = db.getSession(); + PermissionDependenciesFinder finder = new PermissionDependenciesFinder(dbClient, new ComponentFinder(dbClient)); + + ws = new WsActionTester(new UpdateTemplateAction(dbClient, userSession, system, finder)); + + templateDto = insertTemplate(newPermissionTemplateDto() + .setName("Permission Template Name") + .setDescription("Permission Template Description") + .setKeyPattern(".*\\.pattern\\..*") + .setCreatedAt(new Date(1_000_000_000_000L)) + .setUpdatedAt(new Date(1_000_000_000_000L))); + commit(); + } + + @Test + public void update_all_permission_template_fields() { + TestResponse result = newRequest(templateDto.getKee(), "Finance", "Permissions for financially related projects", ".*\\.finance\\..*"); + + assertJson(result.getInput()) + .ignoreFields("id") + .isSimilarTo(getClass().getResource("update_template-example.json")); + PermissionTemplateDto finance = dbClient.permissionTemplateDao().selectByName(dbSession, "Finance"); + assertThat(finance.getName()).isEqualTo("Finance"); + assertThat(finance.getDescription()).isEqualTo("Permissions for financially related projects"); + assertThat(finance.getKeyPattern()).isEqualTo(".*\\.finance\\..*"); + assertThat(finance.getKee()).isEqualTo(templateDto.getKee()); + assertThat(finance.getCreatedAt()).isEqualTo(templateDto.getCreatedAt()); + assertThat(finance.getUpdatedAt().getTime()).isEqualTo(1440512328743L); + } + + @Test + public void update_with_the_same_values() { + newRequest(templateDto.getKee(), templateDto.getName(), templateDto.getDescription(), templateDto.getKeyPattern()); + + PermissionTemplateDto updatedTemplate = dbClient.permissionTemplateDao().selectByUuid(dbSession, templateDto.getKee()); + assertThat(updatedTemplate.getName()).isEqualTo(templateDto.getName()); + assertThat(updatedTemplate.getDescription()).isEqualTo(templateDto.getDescription()); + assertThat(updatedTemplate.getKeyPattern()).isEqualTo(templateDto.getKeyPattern()); + } + + @Test + public void update_name_only() { + newRequest(templateDto.getKee(), "Finance", null, null); + + PermissionTemplateDto finance = dbClient.permissionTemplateDao().selectByName(dbSession, "Finance"); + assertThat(finance.getName()).isEqualTo("Finance"); + assertThat(finance.getDescription()).isEqualTo(templateDto.getDescription()); + assertThat(finance.getKeyPattern()).isEqualTo(templateDto.getKeyPattern()); + } + + @Test + public void fail_if_key_is_not_found() { + expectedException.expect(NotFoundException.class); + expectedException.expectMessage("Permission template with id 'unknown-key' is not found"); + + newRequest("unknown-key", null, null, null); + } + + @Test + public void fail_if_name_already_exists_in_another_template() { + expectedException.expect(BadRequestException.class); + expectedException.expectMessage("A template with the name 'My Template' already exists (case insensitive)."); + + insertTemplate(newPermissionTemplateDto() + .setName("My Template") + .setKee("my-key") + .setCreatedAt(new Date(12345789L)) + .setUpdatedAt(new Date(12345789L))); + commit(); + + newRequest(templateDto.getKee(), "My Template", null, null); + } + + @Test + public void fail_if_key_is_not_provided() { + expectedException.expect(IllegalArgumentException.class); + + newRequest(null, "Finance", null, null); + } + + @Test + public void fail_if_name_empty() { + expectedException.expect(BadRequestException.class); + expectedException.expectMessage("The template name must not be blank"); + + newRequest(templateDto.getKee(), "", null, null); + } + + @Test + public void fail_if_name_has_just_whitespaces() { + expectedException.expect(BadRequestException.class); + expectedException.expectMessage("The template name must not be blank"); + + newRequest(templateDto.getKee(), " \r\n", null, null); + } + + @Test + public void fail_if_regexp_if_not_valid() { + expectedException.expect(BadRequestException.class); + expectedException.expectMessage("The 'projectKeyPattern' parameter must be a valid Java regular expression. '[azerty' was passed"); + + newRequest(templateDto.getKee(), "Finance", null, "[azerty"); + } + + @Test + public void fail_if_name_already_exists_in_database_case_insensitive() { + expectedException.expect(BadRequestException.class); + expectedException.expectMessage("A template with the name 'Finance' already exists (case insensitive)."); + insertTemplate(newPermissionTemplateDto().setName("finance")); + commit(); + + newRequest(templateDto.getKee(), "Finance", null, null); + } + + @Test + public void fail_if_not_logged_in() { + expectedException.expect(UnauthorizedException.class); + userSession.anonymous(); + + newRequest(templateDto.getKee(), "Finance", null, null); + } + + @Test + public void fail_if_not_admin() { + expectedException.expect(ForbiddenException.class); + userSession.setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); + + newRequest(templateDto.getKee(), "Finance", null, null); + } + + private PermissionTemplateDto insertTemplate(PermissionTemplateDto template) { + return dbClient.permissionTemplateDao().insert(dbSession, template); + } + + private GroupDto insertGroup(GroupDto group) { + return dbClient.groupDao().insert(db.getSession(), group); + } + + private void commit() { + dbSession.commit(); + } + + private TestResponse newRequest(@Nullable String key, @Nullable String name, @Nullable String description, @Nullable String projectPattern) { + TestRequest request = ws.newRequest(); + if (key != null) { + request.setParam(PARAM_ID, key); + } + if (name != null) { + request.setParam(PARAM_NAME, name); + } + if (description != null) { + request.setParam(PARAM_DESCRIPTION, description); + } + if (projectPattern != null) { + request.setParam(PARAM_PATTERN, projectPattern); + } + + return request.execute(); + } +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/permission/ws/SearchTemplatesActionTest/empty.json b/server/sonar-server/src/test/resources/org/sonar/server/permission/ws/SearchTemplatesActionTest/empty.json deleted file mode 100644 index 985f39eaa92..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/permission/ws/SearchTemplatesActionTest/empty.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "permissionTemplates": [], - "defaultTemplates": [ - { - "templateId": "AU-Tpxb--iU5OvuD2FLy", - "qualifier": "TRK" - }, - { - "templateId": "AU-TpxcA-iU5OvuD2FLz", - "qualifier": "VW" - }, - { - "templateId": "AU-TpxcA-iU5OvuD2FL0", - "qualifier": "DEV" - } - ], - "permissions": [ - { - "key": "user", - "name": "Browse", - "description": "Ability to access a project, browse its measures, and create/edit issues for it." - }, - { - "key": "admin", - "name": "Administer", - "description": "Ability to access project settings and perform administration tasks. (Users will also need \"Browse\" permission)" - }, - { - "key": "issueadmin", - "name": "Administer Issues", - "description": "Grants the permission to perform advanced editing on issues: marking an issue False Positive / Won't Fix or changing an Issue's severity. (Users will also need \"Browse\" permission)" - }, - { - "key": "codeviewer", - "name": "See Source Code", - "description": "Ability to view the project's source code. (Users will also need \"Browse\" permission)" - } - ] -} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/permission/ws/template/SearchTemplatesActionTest/empty.json b/server/sonar-server/src/test/resources/org/sonar/server/permission/ws/template/SearchTemplatesActionTest/empty.json new file mode 100644 index 00000000000..985f39eaa92 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/permission/ws/template/SearchTemplatesActionTest/empty.json @@ -0,0 +1,39 @@ +{ + "permissionTemplates": [], + "defaultTemplates": [ + { + "templateId": "AU-Tpxb--iU5OvuD2FLy", + "qualifier": "TRK" + }, + { + "templateId": "AU-TpxcA-iU5OvuD2FLz", + "qualifier": "VW" + }, + { + "templateId": "AU-TpxcA-iU5OvuD2FL0", + "qualifier": "DEV" + } + ], + "permissions": [ + { + "key": "user", + "name": "Browse", + "description": "Ability to access a project, browse its measures, and create/edit issues for it." + }, + { + "key": "admin", + "name": "Administer", + "description": "Ability to access project settings and perform administration tasks. (Users will also need \"Browse\" permission)" + }, + { + "key": "issueadmin", + "name": "Administer Issues", + "description": "Grants the permission to perform advanced editing on issues: marking an issue False Positive / Won't Fix or changing an Issue's severity. (Users will also need \"Browse\" permission)" + }, + { + "key": "codeviewer", + "name": "See Source Code", + "description": "Ability to view the project's source code. (Users will also need \"Browse\" permission)" + } + ] +}