From e89422f9a72502bae8525ab487022eecea72fa03 Mon Sep 17 00:00:00 2001 From: Teryk Bellahsene Date: Wed, 8 Jun 2016 09:05:29 +0200 Subject: [PATCH] SONAR-7723 WS api/permissions/add_project_creator_to_template --- .../permission/ws/PermissionsWsModule.java | 2 + .../AddProjectCreatorToTemplateAction.java | 123 +++++++++++++ .../ws/PermissionsWsModuleTest.java | 2 +- ...AddProjectCreatorToTemplateActionTest.java | 168 ++++++++++++++++++ .../AddProjectCreatorToTemplateWsRequest.java | 84 +++++++++ .../client/permission/PermissionsService.java | 10 +- .../permission/PermissionsServiceTest.java | 18 ++ 7 files changed, 404 insertions(+), 3 deletions(-) create mode 100644 server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/AddProjectCreatorToTemplateAction.java create mode 100644 server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/AddProjectCreatorToTemplateActionTest.java create mode 100644 sonar-ws/src/main/java/org/sonarqube/ws/client/permission/AddProjectCreatorToTemplateWsRequest.java 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 1f30fd0875f..e85ec826a51 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,7 @@ 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.AddProjectCreatorToTemplateAction; import org.sonar.server.permission.ws.template.AddUserToTemplateAction; import org.sonar.server.permission.ws.template.ApplyTemplateAction; import org.sonar.server.permission.ws.template.BulkApplyTemplateAction; @@ -50,6 +51,7 @@ public class PermissionsWsModule extends Module { RemoveUserFromTemplateAction.class, AddUserToTemplateAction.class, AddGroupToTemplateAction.class, + AddProjectCreatorToTemplateAction.class, RemoveGroupFromTemplateAction.class, CreateTemplateAction.class, UpdateTemplateAction.class, diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/AddProjectCreatorToTemplateAction.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/AddProjectCreatorToTemplateAction.java new file mode 100644 index 00000000000..2956efe5f37 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/AddProjectCreatorToTemplateAction.java @@ -0,0 +1,123 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program 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. + * + * This program 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.Optional; +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.db.permission.template.PermissionTemplateCharacteristicDto; +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.client.permission.AddProjectCreatorToTemplateWsRequest; + +import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdminUser; +import static org.sonar.server.permission.ws.PermissionRequestValidator.validateProjectPermission; +import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createProjectPermissionParameter; +import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createTemplateParameters; +import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PERMISSION; +import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_TEMPLATE_ID; +import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_TEMPLATE_NAME; + +public class AddProjectCreatorToTemplateAction implements PermissionsWsAction { + private final DbClient dbClient; + private final PermissionDependenciesFinder dependenciesFinder; + private final UserSession userSession; + private final System2 system; + + public AddProjectCreatorToTemplateAction(DbClient dbClient, PermissionDependenciesFinder dependenciesFinder, UserSession userSession, System2 system) { + this.dbClient = dbClient; + this.dependenciesFinder = dependenciesFinder; + this.userSession = userSession; + this.system = system; + } + + @Override + public void define(WebService.NewController context) { + WebService.NewAction action = context.createAction("add_project_creator_to_template") + .setDescription("Add a project creator to a permission template.
" + + "Requires the 'Administer' permission.") + .setSince("6.0") + .setPost(true) + .setHandler(this); + + createTemplateParameters(action); + createProjectPermissionParameter(action); + } + + @Override + public void handle(Request request, Response response) throws Exception { + checkGlobalAdminUser(userSession); + doHandle(toWsRequest(request)); + response.noContent(); + } + + private void doHandle(AddProjectCreatorToTemplateWsRequest request) { + DbSession dbSession = dbClient.openSession(false); + try { + PermissionTemplateDto template = dependenciesFinder.getTemplate(dbSession, WsTemplateRef.newTemplateRef(request.getTemplateId(), request.getTemplateName())); + Optional templatePermission = dbClient.permissionTemplateCharacteristicDao().selectByPermissionAndTemplateId(dbSession, request.getPermission(), + template.getId()); + if (templatePermission.isPresent()) { + updateTemplatePermission(dbSession, templatePermission.get()); + } else { + addTemplatePermission(dbSession, request, template); + } + } finally { + dbClient.closeSession(dbSession); + } + } + + private void addTemplatePermission(DbSession dbSession, AddProjectCreatorToTemplateWsRequest request, PermissionTemplateDto template) { + long now = system.now(); + dbClient.permissionTemplateCharacteristicDao().insert(dbSession, new PermissionTemplateCharacteristicDto() + .setPermission(request.getPermission()) + .setTemplateId(template.getId()) + .setWithProjectCreator(true) + .setCreatedAt(now) + .setUpdatedAt(now)); + dbSession.commit(); + } + + private void updateTemplatePermission(DbSession dbSession, PermissionTemplateCharacteristicDto templatePermission) { + PermissionTemplateCharacteristicDto targetTemplatePermission = templatePermission + .setUpdatedAt(system.now()) + .setWithProjectCreator(true); + dbClient.permissionTemplateCharacteristicDao().update(dbSession, targetTemplatePermission); + dbSession.commit(); + } + + private static AddProjectCreatorToTemplateWsRequest toWsRequest(Request request) { + AddProjectCreatorToTemplateWsRequest wsRequest = AddProjectCreatorToTemplateWsRequest.builder() + .setPermission(request.mandatoryParam(PARAM_PERMISSION)) + .setTemplateId(request.param(PARAM_TEMPLATE_ID)) + .setTemplateName(request.param(PARAM_TEMPLATE_NAME)) + .build(); + validateProjectPermission(wsRequest.getPermission()); + return wsRequest; + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/PermissionsWsModuleTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/PermissionsWsModuleTest.java index aaf3b6d3308..0f0e343f919 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/PermissionsWsModuleTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/PermissionsWsModuleTest.java @@ -29,6 +29,6 @@ public class PermissionsWsModuleTest { public void verify_count_of_added_components() { ComponentContainer container = new ComponentContainer(); new PermissionsWsModule().configure(container); - assertThat(container.size()).isEqualTo(2 + 27); + assertThat(container.size()).isEqualTo(2 + 28); } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/AddProjectCreatorToTemplateActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/AddProjectCreatorToTemplateActionTest.java new file mode 100644 index 00000000000..32483b980fc --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/AddProjectCreatorToTemplateActionTest.java @@ -0,0 +1,168 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program 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. + * + * This program 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.Optional; +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.component.ResourceTypesRule; +import org.sonar.db.permission.PermissionTemplateDto; +import org.sonar.db.permission.template.PermissionTemplateCharacteristicDto; +import org.sonar.db.permission.template.PermissionTemplateCharacteristicMapper; +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.usergroups.ws.UserGroupFinder; +import org.sonar.server.ws.TestRequest; +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.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PERMISSION; +import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_TEMPLATE_ID; +import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_TEMPLATE_NAME; + +public class AddProjectCreatorToTemplateActionTest { + @Rule + public ExpectedException expectedException = ExpectedException.none(); + @Rule + public UserSessionRule userSession = UserSessionRule.standalone(); + @Rule + public DbTester db = DbTester.create(System2.INSTANCE); + DbClient dbClient = db.getDbClient(); + DbSession dbSession = db.getSession(); + PermissionTemplateCharacteristicMapper mapper = dbSession.getMapper(PermissionTemplateCharacteristicMapper.class); + ResourceTypesRule resourceTypes = new ResourceTypesRule(); + System2 system = mock(System2.class); + + WsActionTester ws; + + PermissionTemplateDto template; + + @Before + public void setUp() { + userSession.login().setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); + when(system.now()).thenReturn(2_000_000_000L); + + ws = new WsActionTester(new AddProjectCreatorToTemplateAction(dbClient, + new PermissionDependenciesFinder(dbClient, new ComponentFinder(dbClient), new UserGroupFinder(dbClient), resourceTypes), userSession, system)); + + template = insertTemplate(); + } + + @Test + public void insert_row_when_no_template_permission() { + call(ws.newRequest() + .setParam(PARAM_PERMISSION, UserRole.ADMIN) + .setParam(PARAM_TEMPLATE_ID, template.getUuid())); + + assertThatProjectCreatorIsPresentFor(UserRole.ADMIN, template.getId()); + } + + @Test + public void update_row_when_existing_template_permission() { + PermissionTemplateCharacteristicDto insertedPermissionTemplate = dbClient.permissionTemplateCharacteristicDao().insert(dbSession, new PermissionTemplateCharacteristicDto() + .setTemplateId(template.getId()) + .setPermission(UserRole.USER) + .setWithProjectCreator(false) + .setCreatedAt(1_000_000_000L) + .setUpdatedAt(1_000_000_000L)); + db.commit(); + when(system.now()).thenReturn(3_000_000_000L); + + call(ws.newRequest() + .setParam(PARAM_PERMISSION, UserRole.USER) + .setParam(PARAM_TEMPLATE_NAME, template.getName())); + + assertThatProjectCreatorIsPresentFor(UserRole.USER, template.getId()); + PermissionTemplateCharacteristicDto updatedPermissionTemplate = mapper.selectById(insertedPermissionTemplate.getId()); + assertThat(updatedPermissionTemplate.getCreatedAt()).isEqualTo(1_000_000_000L); + assertThat(updatedPermissionTemplate.getUpdatedAt()).isEqualTo(3_000_000_000L); + } + + @Test + public void fail_when_template_does_not_exist() { + expectedException.expect(NotFoundException.class); + + call(ws.newRequest() + .setParam(PARAM_PERMISSION, UserRole.ADMIN) + .setParam(PARAM_TEMPLATE_ID, "42")); + } + + @Test + public void fail_if_permission_is_not_a_project_permission() { + expectedException.expect(BadRequestException.class); + + call(ws.newRequest() + .setParam(PARAM_PERMISSION, GlobalPermissions.DASHBOARD_SHARING) + .setParam(PARAM_TEMPLATE_ID, template.getUuid())); + } + + @Test + public void fail_if_not_authenticated() { + expectedException.expect(UnauthorizedException.class); + userSession.anonymous(); + + call(ws.newRequest() + .setParam(PARAM_PERMISSION, UserRole.ADMIN) + .setParam(PARAM_TEMPLATE_ID, template.getUuid())); + } + + @Test + public void fail_if_insufficient_privileges() { + expectedException.expect(ForbiddenException.class); + userSession.login().setGlobalPermissions(GlobalPermissions.QUALITY_GATE_ADMIN); + + call(ws.newRequest() + .setParam(PARAM_PERMISSION, UserRole.ADMIN) + .setParam(PARAM_TEMPLATE_ID, template.getUuid())); + } + + private void assertThatProjectCreatorIsPresentFor(String permission, long templateId) { + Optional templatePermission = dbClient.permissionTemplateCharacteristicDao().selectByPermissionAndTemplateId(dbSession, permission, templateId); + assertThat(templatePermission).isPresent(); + assertThat(templatePermission.get().getWithProjectCreator()).isTrue(); + } + + private PermissionTemplateDto insertTemplate() { + PermissionTemplateDto template = dbClient.permissionTemplateDao().insert(dbSession, newPermissionTemplateDto()); + db.commit(); + return template; + } + + private void call(TestRequest request) { + request.execute(); + } +} diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/permission/AddProjectCreatorToTemplateWsRequest.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/permission/AddProjectCreatorToTemplateWsRequest.java new file mode 100644 index 00000000000..cbec95d29b0 --- /dev/null +++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/permission/AddProjectCreatorToTemplateWsRequest.java @@ -0,0 +1,84 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program 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. + * + * This program 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.sonarqube.ws.client.permission; + +import javax.annotation.CheckForNull; + +import static java.util.Objects.requireNonNull; + +public class AddProjectCreatorToTemplateWsRequest { + private final String templateId; + private final String templateName; + private final String permission; + + public AddProjectCreatorToTemplateWsRequest(Builder builder) { + this.templateId = builder.templateId; + this.templateName = builder.templateName; + this.permission = requireNonNull(builder.permission); + } + + @CheckForNull + public String getTemplateId() { + return templateId; + } + + @CheckForNull + public String getTemplateName() { + return templateName; + } + + public String getPermission() { + return permission; + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + private String templateId; + private String templateName; + private String permission; + + private Builder() { + // enforce method constructor + } + + public Builder setTemplateId(String templateId) { + this.templateId = templateId; + return this; + } + + public Builder setTemplateName(String templateName) { + this.templateName = templateName; + return this; + } + + public Builder setPermission(String permission) { + this.permission = permission; + return this; + } + + public AddProjectCreatorToTemplateWsRequest build() { + return new AddProjectCreatorToTemplateWsRequest(this); + } + } +} diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/permission/PermissionsService.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/permission/PermissionsService.java index 76a553792ea..694f100d1f1 100644 --- a/sonar-ws/src/main/java/org/sonarqube/ws/client/permission/PermissionsService.java +++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/permission/PermissionsService.java @@ -97,6 +97,13 @@ public class PermissionsService extends BaseService { .setParam(PARAM_TEMPLATE_NAME, request.getTemplateName())); } + public void addProjectCreatorToTemplate(AddProjectCreatorToTemplateWsRequest request) { + call(new PostRequest(path("add_project_creator_to_template")) + .setParam(PARAM_PERMISSION, request.getPermission()) + .setParam(PARAM_TEMPLATE_ID, request.getTemplateId()) + .setParam(PARAM_TEMPLATE_NAME, request.getTemplateName())); + } + public void applyTemplate(ApplyTemplateWsRequest request) { call(new PostRequest(path("apply_template")) .setParam(PARAM_PROJECT_ID, request.getProjectId()) @@ -110,8 +117,7 @@ public class PermissionsService extends BaseService { .setParam(PARAM_TEMPLATE_ID, request.getTemplateId()) .setParam(PARAM_TEMPLATE_NAME, request.getTemplateName()) .setParam("q", request.getQuery()) - .setParam(PARAM_QUALIFIER, request.getQualifier()) - ); + .setParam(PARAM_QUALIFIER, request.getQualifier())); } public CreateTemplateWsResponse createTemplate(CreateTemplateWsRequest request) { diff --git a/sonar-ws/src/test/java/org/sonarqube/ws/client/permission/PermissionsServiceTest.java b/sonar-ws/src/test/java/org/sonarqube/ws/client/permission/PermissionsServiceTest.java index 5cdf798fbbd..e18ff730830 100644 --- a/sonar-ws/src/test/java/org/sonarqube/ws/client/permission/PermissionsServiceTest.java +++ b/sonar-ws/src/test/java/org/sonarqube/ws/client/permission/PermissionsServiceTest.java @@ -454,4 +454,22 @@ public class PermissionsServiceTest { .hasParam(PARAM_Q, QUERY_VALUE) .andNoOtherParam(); } + + @Test + public void add_project_creator_to_template() { + underTest.addProjectCreatorToTemplate(AddProjectCreatorToTemplateWsRequest.builder() + .setPermission(PERMISSION_VALUE) + .setTemplateId(TEMPLATE_ID_VALUE) + .setTemplateName(TEMPLATE_NAME_VALUE) + .build()); + + assertThat(serviceTester.getPostParser()).isNull(); + PostRequest getRequest = serviceTester.getPostRequest(); + serviceTester.assertThat(getRequest) + .hasPath("add_project_creator_to_template") + .hasParam(PARAM_PERMISSION, PERMISSION_VALUE) + .hasParam(PARAM_TEMPLATE_ID, TEMPLATE_ID_VALUE) + .hasParam(PARAM_TEMPLATE_NAME, TEMPLATE_NAME_VALUE) + .andNoOtherParam(); + } } -- 2.39.5