From 6189f1973d24799939b1d689a3242820e2494da6 Mon Sep 17 00:00:00 2001 From: Simon Brandhof Date: Sun, 16 Oct 2016 23:02:45 +0200 Subject: [PATCH] SONAR-8272 SONAR-8273 organization in WS to apply permission templates --- .../server/permission/PermissionService.java | 18 ++-- .../server/permission/ws/AddGroupAction.java | 2 + .../permission/ws/PermissionWsSupport.java | 3 +- .../permission/ws/RemoveGroupAction.java | 2 + .../ws/template/ApplyTemplateAction.java | 23 +++-- .../ws/template/BulkApplyTemplateAction.java | 31 ++++--- .../permission/ws/template/WsTemplateRef.java | 20 +++-- .../server/usergroups/ws/SearchAction.java | 2 +- .../permission/ws/AddGroupActionTest.java | 9 -- .../permission/ws/AddUserActionTest.java | 31 +++---- .../permission/ws/BasePermissionWsTest.java | 27 +++++- .../permission/ws/RemoveGroupActionTest.java | 38 ++++----- .../ws/template/ApplyTemplateActionTest.java | 36 ++++---- .../template/BulkApplyTemplateActionTest.java | 17 ++-- .../template/SearchTemplatesActionTest.java | 3 + .../RegisterPermissionTemplatesTest.java | 26 +++--- .../db/permission/PermissionRepository.java | 64 +++++++------- .../template/PermissionTemplate.java | 60 ------------- .../PermissionTemplateCharacteristicDao.java | 1 + ...ermissionTemplateCharacteristicMapper.java | 2 - .../template/PermissionTemplateDao.java | 40 +-------- .../template/PermissionTemplateMapper.java | 2 +- ...PermissionTemplateCharacteristicMapper.xml | 9 -- .../template/PermissionTemplateMapper.xml | 10 ++- .../permission/PermissionRepositoryTest.java | 6 +- .../template/PermissionTemplateDaoTest.java | 84 ------------------- .../permission/ApplyTemplateWsRequest.java | 10 +++ .../BulkApplyTemplateWsRequest.java | 11 +++ 28 files changed, 228 insertions(+), 359 deletions(-) delete mode 100644 sonar-db/src/main/java/org/sonar/db/permission/template/PermissionTemplate.java diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionService.java b/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionService.java index 1c99f7b28a3..3ad1b779073 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionService.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionService.java @@ -19,6 +19,7 @@ */ package org.sonar.server.permission; +import java.util.Collection; import java.util.List; import javax.annotation.Nullable; import org.sonar.api.resources.Qualifiers; @@ -30,11 +31,11 @@ import org.sonar.db.DbSession; import org.sonar.db.component.ComponentDto; import org.sonar.db.component.ResourceDto; import org.sonar.db.permission.PermissionRepository; +import org.sonar.db.permission.template.PermissionTemplateDto; import org.sonar.server.component.ComponentFinder; import org.sonar.server.issue.index.IssueAuthorizationIndexer; import org.sonar.server.user.UserSession; -import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdminUser; import static org.sonar.server.permission.PermissionPrivilegeChecker.checkProjectAdminUserByComponentKey; @ServerSide @@ -98,20 +99,15 @@ public class PermissionService { return permissionRepository.wouldUserHavePermissionWithDefaultTemplate(dbSession, userId, permission, effectiveKey, qualifier); } - public void applyPermissionTemplate(DbSession dbSession, ApplyPermissionTemplateQuery query) { - if (query.getComponentKeys().size() == 1) { - checkProjectAdminUserByComponentKey(userSession, query.getComponentKeys().get(0)); - } else { - checkGlobalAdminUser(userSession); + public void apply(DbSession dbSession, PermissionTemplateDto template, Collection projects) { + if (projects.isEmpty()) { + return; } - // TODO apply permission templates in on query instead of on on each project - for (String componentKey : query.getComponentKeys()) { - ComponentDto component = componentFinder.getByKey(dbSession, componentKey); - permissionRepository.applyPermissionTemplate(dbSession, query.getTemplateUuid(), component); + for (ComponentDto project : projects) { + permissionRepository.apply(dbSession, template, project, null); } dbSession.commit(); - indexProjectPermissions(); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/AddGroupAction.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/AddGroupAction.java index 8fe71b5e4d3..01374676c22 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/AddGroupAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/AddGroupAction.java @@ -36,6 +36,7 @@ import static java.util.Arrays.asList; import static org.sonar.server.permission.PermissionPrivilegeChecker.checkProjectAdmin; import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createGroupIdParameter; import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createGroupNameParameter; +import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createOrganizationParameter; import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createPermissionParameter; import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createProjectParameters; import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PERMISSION; @@ -68,6 +69,7 @@ public class AddGroupAction implements PermissionsWsAction { .setHandler(this); createPermissionParameter(action); + createOrganizationParameter(action); createGroupNameParameter(action); createGroupIdParameter(action); createProjectParameters(action); diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionWsSupport.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionWsSupport.java index 239864fe868..8ecf03009fc 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionWsSupport.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionWsSupport.java @@ -103,8 +103,9 @@ public class PermissionWsSupport { dbClient.permissionTemplateDao().selectByUuid(dbSession, ref.uuid()), "Permission template with id '%s' is not found", ref.uuid()); } else { + OrganizationDto org = findOrganization(dbSession, ref.getOrganization()); return checkFound( - dbClient.permissionTemplateDao().selectByName(dbSession, ref.name()), + dbClient.permissionTemplateDao().selectByName(dbSession, org.getUuid(), ref.name()), "Permission template with name '%s' is not found (case insensitive)", ref.name()); } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/RemoveGroupAction.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/RemoveGroupAction.java index cee272fe693..017e9e2ed6e 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/RemoveGroupAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/RemoveGroupAction.java @@ -36,6 +36,7 @@ import static java.util.Arrays.asList; import static org.sonar.server.permission.PermissionPrivilegeChecker.checkProjectAdmin; import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createGroupIdParameter; import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createGroupNameParameter; +import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createOrganizationParameter; import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createPermissionParameter; import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createProjectParameters; import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PERMISSION; @@ -68,6 +69,7 @@ public class RemoveGroupAction implements PermissionsWsAction { .setHandler(this); createPermissionParameter(action); + createOrganizationParameter(action); createGroupNameParameter(action); createGroupIdParameter(action); createProjectParameters(action); 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 index 3201990c0ba..ac2215fe45b 100644 --- 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 @@ -19,6 +19,8 @@ */ package org.sonar.server.permission.ws.template; +import java.util.Collections; +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; @@ -26,13 +28,14 @@ import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.component.ComponentDto; import org.sonar.db.permission.template.PermissionTemplateDto; -import org.sonar.server.permission.ApplyPermissionTemplateQuery; import org.sonar.server.permission.PermissionService; +import org.sonar.server.permission.ProjectId; import org.sonar.server.permission.ws.PermissionWsSupport; import org.sonar.server.permission.ws.PermissionsWsAction; +import org.sonar.server.user.UserSession; import org.sonarqube.ws.client.permission.ApplyTemplateWsRequest; -import static java.util.Collections.singletonList; +import static org.sonar.server.permission.PermissionPrivilegeChecker.checkProjectAdmin; import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createProjectParameters; import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createTemplateParameters; import static org.sonar.server.permission.ws.ProjectWsRef.newWsProjectRef; @@ -44,11 +47,14 @@ import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_T public class ApplyTemplateAction implements PermissionsWsAction { private final DbClient dbClient; + private final UserSession userSession; private final PermissionService permissionService; private final PermissionWsSupport wsSupport; - public ApplyTemplateAction(DbClient dbClient, PermissionService permissionService, PermissionWsSupport wsSupport) { + public ApplyTemplateAction(DbClient dbClient, UserSession userSession, PermissionService permissionService, + PermissionWsSupport wsSupport) { this.dbClient = dbClient; + this.userSession = userSession; this.permissionService = permissionService; this.wsSupport = wsSupport; } @@ -76,13 +82,14 @@ public class ApplyTemplateAction implements PermissionsWsAction { private void doHandle(ApplyTemplateWsRequest request) { try (DbSession dbSession = dbClient.openSession(false)) { - PermissionTemplateDto template = wsSupport.findTemplate(dbSession, newTemplateRef(request.getTemplateId(), request.getTemplateName())); + PermissionTemplateDto template = wsSupport.findTemplate(dbSession, newTemplateRef( + request.getTemplateId(), request.getOrganization(), request.getTemplateName())); + ComponentDto project = wsSupport.getRootComponentOrModule(dbSession, newWsProjectRef(request.getProjectId(), request.getProjectKey())); + ProjectId projectId = new ProjectId(project); + checkProjectAdmin(userSession, template.getOrganizationUuid(), Optional.of(projectId)); - ApplyPermissionTemplateQuery query = ApplyPermissionTemplateQuery.create( - template.getUuid(), - singletonList(project.key())); - permissionService.applyPermissionTemplate(dbSession, query); + permissionService.apply(dbSession, template, Collections.singletonList(project)); } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/BulkApplyTemplateAction.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/BulkApplyTemplateAction.java index 1831ef391c1..ac1777a8a9b 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/BulkApplyTemplateAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/BulkApplyTemplateAction.java @@ -21,8 +21,8 @@ package org.sonar.server.permission.ws.template; import com.google.common.collect.Collections2; -import com.google.common.collect.Lists; import java.util.List; +import java.util.Optional; import javax.annotation.Nullable; import org.sonar.api.i18n.I18n; import org.sonar.api.resources.ResourceTypes; @@ -33,34 +33,39 @@ import org.sonar.api.server.ws.WebService.Param; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.component.ComponentDto; -import org.sonar.db.component.ComponentDtoFunctions; import org.sonar.db.component.ComponentQuery; import org.sonar.db.permission.template.PermissionTemplateDto; -import org.sonar.server.permission.ApplyPermissionTemplateQuery; import org.sonar.server.permission.PermissionService; +import org.sonar.server.permission.ProjectId; import org.sonar.server.permission.ws.PermissionWsSupport; import org.sonar.server.permission.ws.PermissionsWsAction; +import org.sonar.server.user.UserSession; import org.sonarqube.ws.client.permission.BulkApplyTemplateWsRequest; import static org.sonar.server.component.ResourceTypeFunctions.RESOURCE_TYPE_TO_QUALIFIER; +import static org.sonar.server.permission.PermissionPrivilegeChecker.checkProjectAdmin; import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createTemplateParameters; import static org.sonar.server.permission.ws.template.WsTemplateRef.newTemplateRef; import static org.sonar.server.ws.WsParameterBuilder.QualifierParameterContext.newQualifierParameterContext; import static org.sonar.server.ws.WsParameterBuilder.createRootQualifierParameter; +import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_ORGANIZATION_KEY; import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_QUALIFIER; import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_TEMPLATE_ID; import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_TEMPLATE_NAME; public class BulkApplyTemplateAction implements PermissionsWsAction { + private final DbClient dbClient; + private final UserSession userSession; private final PermissionService permissionService; private final PermissionWsSupport wsSupport; private final I18n i18n; private final ResourceTypes resourceTypes; - public BulkApplyTemplateAction(DbClient dbClient, PermissionService permissionService, PermissionWsSupport wsSupport, I18n i18n, + public BulkApplyTemplateAction(DbClient dbClient, UserSession userSession, PermissionService permissionService, PermissionWsSupport wsSupport, I18n i18n, ResourceTypes resourceTypes) { this.dbClient = dbClient; + this.userSession = userSession; this.permissionService = permissionService; this.wsSupport = wsSupport; this.i18n = i18n; @@ -95,20 +100,19 @@ public class BulkApplyTemplateAction implements PermissionsWsAction { private void doHandle(BulkApplyTemplateWsRequest request) { try (DbSession dbSession = dbClient.openSession(false)) { - PermissionTemplateDto template = wsSupport.findTemplate(dbSession, newTemplateRef(request.getTemplateId(), request.getTemplateName())); + PermissionTemplateDto template = wsSupport.findTemplate(dbSession, newTemplateRef( + request.getTemplateId(), request.getOrganization(), request.getTemplateName())); ComponentQuery componentQuery = ComponentQuery.builder() .setNameOrKeyQuery(request.getQuery()) .setQualifiers(qualifiers(request.getQualifier())) .build(); - List rootComponents = dbClient.componentDao().selectByQuery(dbSession, componentQuery, 0, Integer.MAX_VALUE); - if (rootComponents.isEmpty()) { - return; - } + List projects = dbClient.componentDao().selectByQuery(dbSession, componentQuery, 0, Integer.MAX_VALUE); - ApplyPermissionTemplateQuery query = ApplyPermissionTemplateQuery.create( - template.getUuid(), - Lists.transform(rootComponents, ComponentDtoFunctions.toKey())); - permissionService.applyPermissionTemplate(dbSession, query); + for (ComponentDto project : projects) { + ProjectId projectId = new ProjectId(project); + checkProjectAdmin(userSession, template.getOrganizationUuid(), Optional.of(projectId)); + } + permissionService.apply(dbSession, template, projects); } } @@ -121,6 +125,7 @@ public class BulkApplyTemplateAction implements PermissionsWsAction { private static BulkApplyTemplateWsRequest toBulkApplyTemplateWsRequest(Request request) { return new BulkApplyTemplateWsRequest() .setTemplateId(request.param(PARAM_TEMPLATE_ID)) + .setOrganization(request.param(PARAM_ORGANIZATION_KEY)) .setTemplateName(request.param(PARAM_TEMPLATE_NAME)) .setQualifier(request.param(PARAM_QUALIFIER)) .setQuery(request.param(Param.TEXT_QUERY)); diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/WsTemplateRef.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/WsTemplateRef.java index 3b30329d67d..596319f093c 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/WsTemplateRef.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/WsTemplateRef.java @@ -24,33 +24,38 @@ import javax.annotation.Nullable; import org.sonar.api.server.ws.Request; import static org.sonar.server.ws.WsUtils.checkRequest; +import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_ORGANIZATION_KEY; import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_TEMPLATE_ID; import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_TEMPLATE_NAME; /** - * Template from a WS request. Guaranties the template id or the template name is provided, not both. + * Reference to a template as defined by WS request. Guaranties one of template id or + * template name is provided, not both. */ public class WsTemplateRef { private final String uuid; + private final String organization; private final String name; - private WsTemplateRef(@Nullable String uuid, @Nullable String name) { + private WsTemplateRef(@Nullable String uuid, @Nullable String organization, @Nullable String name) { checkRequest(uuid != null ^ name != null, "Template name or template id must be provided, not both."); this.uuid = uuid; + this.organization = organization; this.name = name; } public static WsTemplateRef fromRequest(Request wsRequest) { String uuid = wsRequest.param(PARAM_TEMPLATE_ID); + String organization = wsRequest.param(PARAM_ORGANIZATION_KEY); String name = wsRequest.param(PARAM_TEMPLATE_NAME); - return new WsTemplateRef(uuid, name); + return new WsTemplateRef(uuid, organization, name); } - public static WsTemplateRef newTemplateRef(@Nullable String uuid, @Nullable String name) { - return new WsTemplateRef(uuid, name); + public static WsTemplateRef newTemplateRef(@Nullable String uuid, @Nullable String organization, @Nullable String name) { + return new WsTemplateRef(uuid, organization, name); } @CheckForNull @@ -58,6 +63,11 @@ public class WsTemplateRef { return this.uuid; } + @CheckForNull + public String getOrganization() { + return this.organization; + } + @CheckForNull public String name() { return this.name; diff --git a/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/SearchAction.java b/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/SearchAction.java index e5deb2e92e2..947a4431c26 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/SearchAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/SearchAction.java @@ -64,7 +64,7 @@ public class SearchAction implements UserGroupsWsAction { public void define(NewController context) { WebService.NewAction action = context.createAction("search") .setDescription("Search for user groups.
" + - "Requires to be logged.") + "Requires to be logged in.") .setHandler(this) .setResponseExample(getClass().getResource("example-search.json")) .setSince("5.2") diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/AddGroupActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/AddGroupActionTest.java index d5b8674f865..cbd1c341919 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/AddGroupActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/AddGroupActionTest.java @@ -21,7 +21,6 @@ package org.sonar.server.permission.ws; import org.junit.Test; import org.sonar.api.web.UserRole; -import org.sonar.core.permission.GlobalPermissions; import org.sonar.db.component.ComponentDto; import org.sonar.db.component.ComponentTesting; import org.sonar.db.organization.OrganizationDto; @@ -308,12 +307,4 @@ public class AddGroupActionTest extends BasePermissionWsTest { private WsTester.TestRequest newRequest() { return wsTester.newPostRequest(CONTROLLER, ACTION); } - - private void loginAsAdminOnDefaultOrganization() { - loginAsAdmin(db.getDefaultOrganization()); - } - - private void loginAsAdmin(OrganizationDto org) { - userSession.login().addOrganizationPermission(org.getUuid(), GlobalPermissions.SYSTEM_ADMIN); - } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/AddUserActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/AddUserActionTest.java index 20cf09ab098..0cea454d956 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/AddUserActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/AddUserActionTest.java @@ -23,7 +23,6 @@ import org.junit.Before; import org.junit.Test; import org.sonar.api.web.UserRole; import org.sonar.db.component.ComponentDto; -import org.sonar.db.organization.OrganizationDto; import org.sonar.db.user.UserDto; import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.ForbiddenException; @@ -59,7 +58,7 @@ public class AddUserActionTest extends BasePermissionWsTest { @Test public void add_permission_to_user() throws Exception { - loginAsAdmin(); + loginAsAdminOnDefaultOrganization(); wsTester.newPostRequest(CONTROLLER, ACTION) .setParam(PARAM_USER_LOGIN, user.getLogin()) .setParam(PARAM_PERMISSION, SYSTEM_ADMIN) @@ -72,7 +71,7 @@ public class AddUserActionTest extends BasePermissionWsTest { public void add_permission_to_project_referenced_by_its_id() throws Exception { ComponentDto project = db.components().insertProject(); - loginAsAdmin(); + loginAsAdminOnDefaultOrganization(); wsTester.newPostRequest(CONTROLLER, ACTION) .setParam(PARAM_USER_LOGIN, user.getLogin()) .setParam(PARAM_PROJECT_ID, project.uuid()) @@ -87,7 +86,7 @@ public class AddUserActionTest extends BasePermissionWsTest { public void add_permission_to_project_referenced_by_its_key() throws Exception { ComponentDto project = db.components().insertProject(); - loginAsAdmin(); + loginAsAdminOnDefaultOrganization(); wsTester.newPostRequest(CONTROLLER, ACTION) .setParam(PARAM_USER_LOGIN, user.getLogin()) .setParam(PARAM_PROJECT_KEY, project.getKey()) @@ -102,7 +101,7 @@ public class AddUserActionTest extends BasePermissionWsTest { public void add_permission_to_view() throws Exception { ComponentDto view = db.components().insertComponent(newView("view-uuid").setKey("view-key")); - loginAsAdmin(); + loginAsAdminOnDefaultOrganization(); wsTester.newPostRequest(CONTROLLER, ACTION) .setParam(PARAM_USER_LOGIN, user.getLogin()) .setParam(PARAM_PROJECT_ID, view.uuid()) @@ -115,7 +114,7 @@ public class AddUserActionTest extends BasePermissionWsTest { @Test public void fail_when_project_uuid_is_unknown() throws Exception { - loginAsAdmin(); + loginAsAdminOnDefaultOrganization(); expectedException.expect(NotFoundException.class); @@ -128,7 +127,7 @@ public class AddUserActionTest extends BasePermissionWsTest { @Test public void fail_when_project_permission_without_project() throws Exception { - loginAsAdmin(); + loginAsAdminOnDefaultOrganization(); expectedException.expect(BadRequestException.class); @@ -141,7 +140,7 @@ public class AddUserActionTest extends BasePermissionWsTest { @Test public void fail_when_component_is_not_a_project() throws Exception { db.components().insertComponent(newFileDto(newProjectDto("project-uuid"), null, "file-uuid")); - loginAsAdmin(); + loginAsAdminOnDefaultOrganization(); expectedException.expect(BadRequestException.class); @@ -154,7 +153,7 @@ public class AddUserActionTest extends BasePermissionWsTest { @Test public void fail_when_get_request() throws Exception { - loginAsAdmin(); + loginAsAdminOnDefaultOrganization(); expectedException.expect(ServerException.class); @@ -166,7 +165,7 @@ public class AddUserActionTest extends BasePermissionWsTest { @Test public void fail_when_user_login_is_missing() throws Exception { - loginAsAdmin(); + loginAsAdminOnDefaultOrganization(); expectedException.expect(IllegalArgumentException.class); @@ -177,7 +176,7 @@ public class AddUserActionTest extends BasePermissionWsTest { @Test public void fail_when_permission_is_missing() throws Exception { - loginAsAdmin(); + loginAsAdminOnDefaultOrganization(); expectedException.expect(NotFoundException.class); @@ -189,7 +188,7 @@ public class AddUserActionTest extends BasePermissionWsTest { @Test public void fail_when_project_uuid_and_project_key_are_provided() throws Exception { db.components().insertProject(); - loginAsAdmin(); + loginAsAdminOnDefaultOrganization(); expectedException.expect(BadRequestException.class); expectedException.expectMessage("Project id or project key can be provided, not both."); @@ -245,12 +244,4 @@ public class AddUserActionTest extends BasePermissionWsTest { assertThat(db.users().selectUserPermissions(user, project)).containsOnly(ISSUE_ADMIN); } - - private void loginAsAdmin() { - loginAsOrganizationAdmin(db.getDefaultOrganization()); - } - - private void loginAsOrganizationAdmin(OrganizationDto org) { - userSession.login().addOrganizationPermission(org.getUuid(), SYSTEM_ADMIN); - } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/BasePermissionWsTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/BasePermissionWsTest.java index 88e35336c9a..1d5bf920100 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/BasePermissionWsTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/BasePermissionWsTest.java @@ -27,6 +27,7 @@ import org.sonar.api.utils.System2; import org.sonar.db.DbClient; import org.sonar.db.DbTester; import org.sonar.db.component.ResourceTypesRule; +import org.sonar.db.organization.OrganizationDto; import org.sonar.db.permission.template.PermissionTemplateDto; import org.sonar.db.permission.template.PermissionTemplateTesting; import org.sonar.server.component.ComponentFinder; @@ -40,6 +41,8 @@ import org.sonar.server.usergroups.ws.GroupWsSupport; import org.sonar.server.ws.WsTester; import static org.mockito.Mockito.mock; +import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN; +import static org.sonar.db.permission.template.PermissionTemplateTesting.newPermissionTemplateDto; public abstract class BasePermissionWsTest { @@ -81,7 +84,29 @@ public abstract class BasePermissionWsTest { } protected PermissionTemplateDto insertTemplate() { - PermissionTemplateDto dto = db.getDbClient().permissionTemplateDao().insert(db.getSession(), PermissionTemplateTesting.newPermissionTemplateDto()); + PermissionTemplateDto dto = PermissionTemplateTesting.newPermissionTemplateDto() + .setOrganizationUuid(db.getDefaultOrganization().getUuid()); + dto = db.getDbClient().permissionTemplateDao().insert(db.getSession(), dto); + db.commit(); + return dto; + } + + protected void loginAsAdminOnDefaultOrganization() { + loginAsAdmin(db.getDefaultOrganization()); + } + + protected void loginAsAdmin(OrganizationDto org) { + userSession.login().addOrganizationPermission(org.getUuid(), SYSTEM_ADMIN); + } + + protected PermissionTemplateDto selectTemplateInDefaultOrganization(String name) { + return db.getDbClient().permissionTemplateDao().selectByName(db.getSession(), db.getDefaultOrganization().getUuid(), name); + } + + protected PermissionTemplateDto addTemplateToDefaultOrganization() { + PermissionTemplateDto dto = newPermissionTemplateDto() + .setOrganizationUuid(db.getDefaultOrganization().getUuid()); + db.getDbClient().permissionTemplateDao().insert(db.getSession(), dto); db.commit(); return dto; } diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/RemoveGroupActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/RemoveGroupActionTest.java index 46a2e2aff5c..6a8961bfcbe 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/RemoveGroupActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/RemoveGroupActionTest.java @@ -23,7 +23,6 @@ import org.junit.Before; import org.junit.Test; import org.sonar.api.web.UserRole; import org.sonar.db.component.ComponentDto; -import org.sonar.db.organization.OrganizationDto; import org.sonar.db.user.GroupDto; import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.ForbiddenException; @@ -66,7 +65,7 @@ public class RemoveGroupActionTest extends BasePermissionWsTest groupPermissions = defaultTemplate.getGroupPermissions(); + List groupPermissions = selectGroupPermissions(defaultTemplate); assertThat(groupPermissions).hasSize(4); expectGroupPermission(groupPermissions, UserRole.ADMIN, DefaultGroups.ADMINISTRATORS); expectGroupPermission(groupPermissions, UserRole.ISSUE_ADMIN, DefaultGroups.ADMINISTRATORS); @@ -77,7 +77,7 @@ public class RegisterPermissionTemplatesTest { expectGroupPermission(groupPermissions, UserRole.USER, DefaultGroups.ANYONE); // template is marked as default - verify(settings).saveProperty(DEFAULT_TEMPLATE_PROPERTY, defaultTemplate.getTemplate().getUuid()); + verify(settings).saveProperty(DEFAULT_TEMPLATE_PROPERTY, defaultTemplate.getUuid()); assertThat(logTester.logs(LoggerLevel.ERROR)).isEmpty(); } @@ -86,16 +86,16 @@ public class RegisterPermissionTemplatesTest { public void ignore_administrators_permissions_if_group_does_not_exist() { underTest.start(); - PermissionTemplate defaultTemplate = selectTemplate(); - assertThat(defaultTemplate.getTemplate().getName()).isEqualTo("Default template"); + PermissionTemplateDto defaultTemplate = selectTemplate(); + assertThat(defaultTemplate.getName()).isEqualTo("Default template"); - List groupPermissions = defaultTemplate.getGroupPermissions(); + List groupPermissions = selectGroupPermissions(defaultTemplate); assertThat(groupPermissions).hasSize(2); expectGroupPermission(groupPermissions, UserRole.CODEVIEWER, DefaultGroups.ANYONE); expectGroupPermission(groupPermissions, UserRole.USER, DefaultGroups.ANYONE); // marked as default - verify(settings).saveProperty(DEFAULT_TEMPLATE_PROPERTY, defaultTemplate.getTemplate().getUuid()); + verify(settings).saveProperty(DEFAULT_TEMPLATE_PROPERTY, defaultTemplate.getUuid()); assertThat(logTester.logs(LoggerLevel.ERROR)).contains("Cannot setup default permission for group: sonar-administrators"); } @@ -125,8 +125,12 @@ public class RegisterPermissionTemplatesTest { db.getDbClient().loadedTemplateDao().insert(new LoadedTemplateDto(DEFAULT_TEMPLATE_KEY, LoadedTemplateDto.PERMISSION_TEMPLATE_TYPE)); } - private PermissionTemplate selectTemplate() { - return db.getDbClient().permissionTemplateDao().selectByUuidWithUserAndGroupPermissions(db.getSession(), DEFAULT_TEMPLATE_KEY); + private PermissionTemplateDto selectTemplate() { + return db.getDbClient().permissionTemplateDao().selectByUuid(db.getSession(), DEFAULT_TEMPLATE_KEY); + } + + private List selectGroupPermissions(PermissionTemplateDto template) { + return db.getDbClient().permissionTemplateDao().selectGroupPermissionsByTemplateId(db.getSession(), template.getId()); } private void expectGroupPermission(List groupPermissions, String expectedPermission, diff --git a/sonar-db/src/main/java/org/sonar/db/permission/PermissionRepository.java b/sonar-db/src/main/java/org/sonar/db/permission/PermissionRepository.java index 05e2a39f85c..86e0d81d921 100644 --- a/sonar-db/src/main/java/org/sonar/db/permission/PermissionRepository.java +++ b/sonar-db/src/main/java/org/sonar/db/permission/PermissionRepository.java @@ -25,18 +25,19 @@ import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.stream.Collectors; +import javax.annotation.CheckForNull; import javax.annotation.Nullable; import org.apache.commons.lang.StringUtils; import org.sonar.api.config.Settings; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.component.ComponentDto; -import org.sonar.db.permission.template.PermissionTemplate; import org.sonar.db.permission.template.PermissionTemplateCharacteristicDto; import org.sonar.db.permission.template.PermissionTemplateDto; import org.sonar.db.permission.template.PermissionTemplateGroupDto; import org.sonar.db.permission.template.PermissionTemplateUserDto; +import static java.util.Arrays.asList; import static org.sonar.api.security.DefaultGroups.isAnyone; /** @@ -56,35 +57,30 @@ public class PermissionRepository { this.settings = settings; } - public void applyPermissionTemplate(DbSession session, String templateUuid, ComponentDto project) { - applyPermissionTemplate(session, templateUuid, project, null); - } - - private void applyPermissionTemplate(DbSession session, String templateUuid, ComponentDto project, @Nullable Long currentUserId) { - PermissionTemplate template = dbClient.permissionTemplateDao().selectPermissionTemplateWithPermissions(session, templateUuid); + public void apply(DbSession session, PermissionTemplateDto template, ComponentDto project, @Nullable Long currentUserId) { updateProjectAuthorizationDate(session, project.getId()); dbClient.groupPermissionDao().deleteByRootComponentId(session, project.getId()); dbClient.userPermissionDao().deleteProjectPermissions(session, project.getId()); - List usersPermissions = template.getUserPermissions(); - String organizationUuid = template.getTemplate().getOrganizationUuid(); + List usersPermissions = dbClient.permissionTemplateDao().selectUserPermissionsByTemplateId(session, template.getId()); + String organizationUuid = template.getOrganizationUuid(); usersPermissions .forEach(up -> { UserPermissionDto dto = new UserPermissionDto(organizationUuid, up.getPermission(), up.getUserId(), project.getId()); dbClient.userPermissionDao().insert(session, dto); }); - List groupsPermissions = template.getGroupPermissions(); + List groupsPermissions = dbClient.permissionTemplateDao().selectGroupPermissionsByTemplateId(session, template.getId()); groupsPermissions.forEach(gp -> { GroupPermissionDto dto = new GroupPermissionDto() - .setOrganizationUuid(template.getTemplate().getOrganizationUuid()) + .setOrganizationUuid(organizationUuid) .setGroupId(isAnyone(gp.getGroupName()) ? null : gp.getGroupId()) .setRole(gp.getPermission()) .setResourceId(project.getId()); dbClient.groupPermissionDao().insert(session, dto); }); - List characteristics = template.getCharacteristics(); + List characteristics = dbClient.permissionTemplateCharacteristicDao().selectByTemplateIds(session, asList(template.getId())); if (currentUserId != null) { Set permissionsForCurrentUserAlreadyInDb = usersPermissions.stream() .filter(userPermission -> currentUserId.equals(userPermission.getUserId())) @@ -94,19 +90,12 @@ public class PermissionRepository { .filter(PermissionTemplateCharacteristicDto::getWithProjectCreator) .filter(characteristic -> !permissionsForCurrentUserAlreadyInDb.contains(characteristic.getPermission())) .forEach(c -> { - UserPermissionDto dto = new UserPermissionDto(template.getTemplate().getOrganizationUuid(), c.getPermission(), currentUserId, project.getId()); + UserPermissionDto dto = new UserPermissionDto(organizationUuid, c.getPermission(), currentUserId, project.getId()); dbClient.userPermissionDao().insert(session, dto); }); } } - /** - * For each modification of permission on a project, update the authorization_updated_at to help ES reindex only relevant changes - */ - private void updateProjectAuthorizationDate(DbSession dbSession, long projectId) { - dbClient.resourceDao().updateAuthorizationDate(projectId, dbSession); - } - /** * Warning, this method is also used by the Developer Cockpit plugin */ @@ -116,49 +105,51 @@ public class PermissionRepository { } public void applyDefaultPermissionTemplate(DbSession dbSession, ComponentDto componentDto, @Nullable Long userId) { - String applicablePermissionTemplateKey = getApplicablePermissionTemplateKey(dbSession, componentDto.getKey(), componentDto.qualifier()); - applyPermissionTemplate(dbSession, applicablePermissionTemplateKey, componentDto, userId); + PermissionTemplateDto template = getApplicablePermissionTemplate(dbSession, componentDto); + if (template == null) { + throw new IllegalArgumentException("Can not retrieve default permission template"); + } + apply(dbSession, template, componentDto, userId); } /** * Return the permission template for the given componentKey. If no template key pattern match then consider default * permission template for the resource qualifier. */ - private String getApplicablePermissionTemplateKey(DbSession session, final String componentKey, String qualifier) { + @CheckForNull + private PermissionTemplateDto getApplicablePermissionTemplate(DbSession dbSession, ComponentDto component) { // FIXME performance issue here, we should not load all templates - List allPermissionTemplates = dbClient.permissionTemplateDao().selectAll(session); + List allPermissionTemplates = dbClient.permissionTemplateDao().selectAll(dbSession); List matchingTemplates = new ArrayList<>(); for (PermissionTemplateDto permissionTemplateDto : allPermissionTemplates) { String keyPattern = permissionTemplateDto.getKeyPattern(); - if (StringUtils.isNotBlank(keyPattern) && componentKey.matches(keyPattern)) { + if (StringUtils.isNotBlank(keyPattern) && component.getKey().matches(keyPattern)) { matchingTemplates.add(permissionTemplateDto); } } - checkAtMostOneMatchForComponentKey(componentKey, matchingTemplates); + checkAtMostOneMatchForComponentKey(component.getKey(), matchingTemplates); if (matchingTemplates.size() == 1) { - return matchingTemplates.get(0).getUuid(); + return matchingTemplates.get(0); } - String qualifierTemplateKey = settings.getString("sonar.permission.template." + qualifier + ".default"); + String qualifierTemplateKey = settings.getString("sonar.permission.template." + component.qualifier() + ".default"); if (!StringUtils.isBlank(qualifierTemplateKey)) { - return qualifierTemplateKey; + return dbClient.permissionTemplateDao().selectByUuid(dbSession, qualifierTemplateKey); } String defaultTemplateKey = settings.getString("sonar.permission.template.default"); if (StringUtils.isBlank(defaultTemplateKey)) { throw new IllegalStateException("At least one default permission template should be defined"); } - return defaultTemplateKey; + return dbClient.permissionTemplateDao().selectByUuid(dbSession, defaultTemplateKey); } public boolean wouldUserHavePermissionWithDefaultTemplate(DbSession dbSession, @Nullable Long currentUserId, String permission, String projectKey, String qualifier) { - String templateUuid = getApplicablePermissionTemplateKey(dbSession, projectKey, qualifier); - PermissionTemplateDto template = dbClient.permissionTemplateDao().selectByUuid(dbSession, templateUuid); + PermissionTemplateDto template = getApplicablePermissionTemplate(dbSession, new ComponentDto().setKey(projectKey).setQualifier(qualifier)); if (template == null) { return false; } List potentialPermissions = dbClient.permissionTemplateDao().selectPotentialPermissionsByUserIdAndTemplateId(dbSession, currentUserId, template.getId()); - return potentialPermissions.contains(permission); } @@ -178,4 +169,11 @@ public class PermissionRepository { templatesNames.toString())); } } + + /** + * For each modification of permission on a project, update the authorization_updated_at to help ES reindex only relevant changes + */ + private void updateProjectAuthorizationDate(DbSession dbSession, long projectId) { + dbClient.resourceDao().updateAuthorizationDate(projectId, dbSession); + } } diff --git a/sonar-db/src/main/java/org/sonar/db/permission/template/PermissionTemplate.java b/sonar-db/src/main/java/org/sonar/db/permission/template/PermissionTemplate.java deleted file mode 100644 index 9f62d8a583f..00000000000 --- a/sonar-db/src/main/java/org/sonar/db/permission/template/PermissionTemplate.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 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.db.permission.template; - -import java.util.List; -import org.sonar.db.permission.template.PermissionTemplateCharacteristicDto; -import org.sonar.db.permission.template.PermissionTemplateDto; -import org.sonar.db.permission.template.PermissionTemplateGroupDto; -import org.sonar.db.permission.template.PermissionTemplateUserDto; - -public class PermissionTemplate { - private final PermissionTemplateDto template; - private final List userPermissions; - private final List groupPermissions; - private final List characteristics; - - public PermissionTemplate(PermissionTemplateDto template, - List userPermissions, - List groupPermissions, - List characteristics) { - this.template = template; - this.userPermissions = userPermissions; - this.groupPermissions = groupPermissions; - this.characteristics = characteristics; - } - - public PermissionTemplateDto getTemplate() { - return template; - } - - public List getUserPermissions() { - return userPermissions; - } - - public List getGroupPermissions() { - return groupPermissions; - } - - public List getCharacteristics() { - return characteristics; - } -} diff --git a/sonar-db/src/main/java/org/sonar/db/permission/template/PermissionTemplateCharacteristicDao.java b/sonar-db/src/main/java/org/sonar/db/permission/template/PermissionTemplateCharacteristicDao.java index 05e9ff0360f..d7be52538d7 100644 --- a/sonar-db/src/main/java/org/sonar/db/permission/template/PermissionTemplateCharacteristicDao.java +++ b/sonar-db/src/main/java/org/sonar/db/permission/template/PermissionTemplateCharacteristicDao.java @@ -30,6 +30,7 @@ import static java.util.Collections.emptyList; import static java.util.Objects.requireNonNull; public class PermissionTemplateCharacteristicDao implements Dao { + public List selectByTemplateIds(DbSession dbSession, List templateIds) { return templateIds.isEmpty() ? emptyList() : mapper(dbSession).selectByTemplateIds(templateIds); } diff --git a/sonar-db/src/main/java/org/sonar/db/permission/template/PermissionTemplateCharacteristicMapper.java b/sonar-db/src/main/java/org/sonar/db/permission/template/PermissionTemplateCharacteristicMapper.java index c2bba6f8f0b..801456402b9 100644 --- a/sonar-db/src/main/java/org/sonar/db/permission/template/PermissionTemplateCharacteristicMapper.java +++ b/sonar-db/src/main/java/org/sonar/db/permission/template/PermissionTemplateCharacteristicMapper.java @@ -24,8 +24,6 @@ import java.util.List; import org.apache.ibatis.annotations.Param; public interface PermissionTemplateCharacteristicMapper { - List selectByTemplateId(long templateId); - List selectByTemplateIds(@Param("templateIds") List templateId); PermissionTemplateCharacteristicDto selectByPermissionAndTemplateId(@Param("permission") String permission, @Param("templateId") long templateId); diff --git a/sonar-db/src/main/java/org/sonar/db/permission/template/PermissionTemplateDao.java b/sonar-db/src/main/java/org/sonar/db/permission/template/PermissionTemplateDao.java index 9e234fd7796..8fda58aa11b 100644 --- a/sonar-db/src/main/java/org/sonar/db/permission/template/PermissionTemplateDao.java +++ b/sonar-db/src/main/java/org/sonar/db/permission/template/PermissionTemplateDao.java @@ -65,7 +65,7 @@ public class PermissionTemplateDao implements Dao { return executeLargeInputs(logins, l -> mapper(dbSession).selectUserPermissionsByTemplateIdAndUserLogins(templateId, l)); } - private static List selectUserPermissionsByTemplateId(DbSession dbSession, long templateId) { + public List selectUserPermissionsByTemplateId(DbSession dbSession, long templateId) { return mapper(dbSession).selectUserPermissionsByTemplateIdAndUserLogins(templateId, Collections.emptyList()); } @@ -81,7 +81,7 @@ public class PermissionTemplateDao implements Dao { return executeLargeInputs(groups, g -> mapper(dbSession).selectGroupPermissionsByTemplateIdAndGroupNames(templateId, g)); } - List selectGroupPermissionsByTemplateId(DbSession dbSession, long templateId) { + public List selectGroupPermissionsByTemplateId(DbSession dbSession, long templateId) { return mapper(dbSession).selectGroupPermissionsByTemplateIdAndGroupNames(templateId, Collections.emptyList()); } @@ -97,23 +97,6 @@ public class PermissionTemplateDao implements Dao { return mapper(session).selectByUuid(templateUuid); } - @CheckForNull - public PermissionTemplate selectByUuidWithUserAndGroupPermissions(DbSession session, String templateUuid) { - PermissionTemplateMapper mapper = mapper(session); - - PermissionTemplateDto template = mapper.selectByUuid(templateUuid); - if (template == null) { - return null; - } - - List userPermissions = selectUserPermissionsByTemplateId(session, template.getId()); - List groupPermissions = selectGroupPermissionsByTemplateId(session, template.getId()); - PermissionTemplateCharacteristicMapper characteristicMapper = session.getMapper(PermissionTemplateCharacteristicMapper.class); - List characteristics = characteristicMapper.selectByTemplateId(template.getId()); - - return new PermissionTemplate(template, userPermissions, groupPermissions, characteristics); - } - public List selectAll(DbSession session, String nameMatch) { String uppercaseNameMatch = toUppercaseSqlQuery(nameMatch); return mapper(session).selectAll(uppercaseNameMatch); @@ -226,23 +209,8 @@ public class PermissionTemplateDao implements Dao { session.commit(); } - /** - * Load permission template and load associated collections of users and groups permissions, and characteristics - */ - public PermissionTemplate selectPermissionTemplateWithPermissions(DbSession session, String templateUuid) { - PermissionTemplateDto template = selectByUuid(session, templateUuid); - if (template == null) { - throw new IllegalArgumentException("Could not retrieve permission template with uuid " + templateUuid); - } - PermissionTemplate templateWithDependencies = selectByUuidWithUserAndGroupPermissions(session, template.getUuid()); - if (templateWithDependencies == null) { - throw new IllegalArgumentException("Could not retrieve permissions for template with uuid " + templateUuid); - } - return templateWithDependencies; - } - - public PermissionTemplateDto selectByName(DbSession dbSession, String name) { - return mapper(dbSession).selectByName(name.toUpperCase(Locale.ENGLISH)); + public PermissionTemplateDto selectByName(DbSession dbSession, String organizationUuid, String name) { + return mapper(dbSession).selectByName(organizationUuid, name.toUpperCase(Locale.ENGLISH)); } public List selectPotentialPermissionsByUserIdAndTemplateId(DbSession dbSession, @Nullable Long currentUserId, long templateId) { diff --git a/sonar-db/src/main/java/org/sonar/db/permission/template/PermissionTemplateMapper.java b/sonar-db/src/main/java/org/sonar/db/permission/template/PermissionTemplateMapper.java index 68a3615c8be..7cd947b94f4 100644 --- a/sonar-db/src/main/java/org/sonar/db/permission/template/PermissionTemplateMapper.java +++ b/sonar-db/src/main/java/org/sonar/db/permission/template/PermissionTemplateMapper.java @@ -58,7 +58,7 @@ public interface PermissionTemplateMapper { void deleteByGroupId(long groupId); - PermissionTemplateDto selectByName(String name); + PermissionTemplateDto selectByName(@Param("organizationUuid") String organizationUuid, @Param("name") String name); List selectUserLoginsByQueryAndTemplate(@Param("query") PermissionQuery query, @Param("templateId") long templateId, RowBounds rowBounds); diff --git a/sonar-db/src/main/resources/org/sonar/db/permission/template/PermissionTemplateCharacteristicMapper.xml b/sonar-db/src/main/resources/org/sonar/db/permission/template/PermissionTemplateCharacteristicMapper.xml index 00050a13f19..13664b4293e 100644 --- a/sonar-db/src/main/resources/org/sonar/db/permission/template/PermissionTemplateCharacteristicMapper.xml +++ b/sonar-db/src/main/resources/org/sonar/db/permission/template/PermissionTemplateCharacteristicMapper.xml @@ -10,15 +10,6 @@ ptc.updated_at as updatedAt - - - + select - FROM permission_templates - WHERE UPPER(name)=#{templateName} + from permission_templates + where + organization_uuid = #{organizationUuid,jdbcType=VARCHAR} and + upper(name) = #{name,jdbcType=VARCHAR} diff --git a/sonar-db/src/test/java/org/sonar/db/permission/PermissionRepositoryTest.java b/sonar-db/src/test/java/org/sonar/db/permission/PermissionRepositoryTest.java index ecdf59dd0b9..4b8ea83df2a 100644 --- a/sonar-db/src/test/java/org/sonar/db/permission/PermissionRepositoryTest.java +++ b/sonar-db/src/test/java/org/sonar/db/permission/PermissionRepositoryTest.java @@ -42,12 +42,13 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION; +import static org.sonar.db.component.ComponentTesting.newProjectDto; import static org.sonar.db.user.GroupTesting.newGroupDto; public class PermissionRepositoryTest { private static final String DEFAULT_TEMPLATE = "default_20130101_010203"; - private static final ComponentDto PROJECT = new ComponentDto().setId(123L).setUuid("THE_PROJECT_UUID"); + private static final ComponentDto PROJECT = newProjectDto().setId(123L).setUuid("THE_PROJECT_UUID"); private static final long NOW = 123456789L; @Rule @@ -78,7 +79,8 @@ public class PermissionRepositoryTest { assertThat(roleDao.selectGroupPermissions(session, "Anyone", PROJECT.getId())).isEmpty(); assertThat(dbTester.getDbClient().userPermissionDao().selectPermissionsByLogin(session, "marius", PROJECT.uuid())).isEmpty(); - underTest.applyPermissionTemplate(session, "default_20130101_010203", PROJECT); + PermissionTemplateDto template = dbTester.getDbClient().permissionTemplateDao().selectByUuid(session, "default_20130101_010203"); + underTest.apply(session, template, PROJECT, null); assertThat(roleDao.selectGroupPermissions(session, "sonar-administrators", PROJECT.getId())).containsOnly("admin", "issueadmin"); assertThat(roleDao.selectGroupPermissions(session, "sonar-users", PROJECT.getId())).containsOnly("user", "codeviewer"); diff --git a/sonar-db/src/test/java/org/sonar/db/permission/template/PermissionTemplateDaoTest.java b/sonar-db/src/test/java/org/sonar/db/permission/template/PermissionTemplateDaoTest.java index d891bfda4dc..b0d5bba35b3 100644 --- a/sonar-db/src/test/java/org/sonar/db/permission/template/PermissionTemplateDaoTest.java +++ b/sonar-db/src/test/java/org/sonar/db/permission/template/PermissionTemplateDaoTest.java @@ -39,10 +39,8 @@ import org.sonar.db.user.GroupDto; import org.sonar.db.user.UserDto; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.tuple; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -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; @@ -50,7 +48,6 @@ import static org.sonar.api.web.UserRole.USER; import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION; import static org.sonar.db.permission.template.PermissionTemplateTesting.newPermissionTemplateDto; import static org.sonar.db.user.GroupTesting.newGroupDto; -import static org.sonar.db.user.UserTesting.newUserDto; public class PermissionTemplateDaoTest { @@ -82,30 +79,6 @@ public class PermissionTemplateDaoTest { db.assertDbUnitTable(getClass(), "createPermissionTemplate-result.xml", "permission_templates", "id", "name", "description"); } - @Test - public void should_select_permission_template() { - db.prepareDbUnit(getClass(), "selectPermissionTemplate.xml"); - - PermissionTemplate result = underTest.selectByUuidWithUserAndGroupPermissions(dbSession, "my_template_20130102_030405"); - - assertThat(result).isNotNull(); - PermissionTemplateDto template = result.getTemplate(); - assertThat(template.getName()).isEqualTo("my template"); - assertThat(template.getUuid()).isEqualTo("my_template_20130102_030405"); - assertThat(template.getDescription()).isEqualTo("my description"); - List usersPermissions = result.getUserPermissions(); - assertThat(usersPermissions).hasSize(3); - assertThat(usersPermissions).extracting("userId").containsOnly(1L, 2L, 1L); - assertThat(usersPermissions).extracting("userLogin").containsOnly("login1", "login2", "login2"); - assertThat(usersPermissions).extracting("userName").containsOnly("user1", "user2", "user2"); - assertThat(usersPermissions).extracting("permission").containsOnly("user_permission1", "user_permission1", "user_permission2"); - List groupsPermissions = result.getGroupPermissions(); - assertThat(groupsPermissions).hasSize(3); - assertThat(groupsPermissions).extracting("groupId").containsOnly(1L, 2L, 0L); - assertThat(groupsPermissions).extracting("groupName").containsOnly("group1", "group2", "Anyone"); - assertThat(groupsPermissions).extracting("permission").containsOnly("group_permission1", "group_permission1", "group_permission2"); - } - @Test public void should_select_permission_template_by_key() { db.prepareDbUnit(getClass(), "selectPermissionTemplate.xml"); @@ -206,63 +179,6 @@ public class PermissionTemplateDaoTest { checkTemplateTables("addNullGroupPermissionToTemplate-result.xml"); } - @Test - public void new_permission_template_with_empty_user_group_characteristics() { - PermissionTemplateDto template = underTest.insert(dbSession, newPermissionTemplateDto().setUuid("TEMPLATE_UUID")); - - PermissionTemplate result = underTest.selectByUuidWithUserAndGroupPermissions(dbSession, "TEMPLATE_UUID"); - - assertThat(result.getTemplate()) - .extracting(PermissionTemplateDto::getId, PermissionTemplateDto::getUuid, PermissionTemplateDto::getName, PermissionTemplateDto::getDescription) - .containsExactly(template.getId(), template.getUuid(), template.getName(), template.getDescription()); - - assertThat(result.getUserPermissions()).isEmpty(); - assertThat(result.getGroupPermissions()).isEmpty(); - assertThat(result.getCharacteristics()).isEmpty(); - } - - @Test - public void unknown_permission_template() { - PermissionTemplate result = underTest.selectByUuidWithUserAndGroupPermissions(dbSession, "UNKNOWN_TEMPLATE_UUID"); - - assertThat(result).isNull(); - } - - @Test - public void permission_template_with_user_group_and_characteristics() { - PermissionTemplateDto template = dbClient.permissionTemplateDao().insert(dbSession, newPermissionTemplateDto().setUuid("TEMPLATE_UUID")); - GroupDto group = db.users().insertGroup(newGroupDto()); - UserDto user = db.users().insertUser(newUserDto()); - templateDb.addGroupToTemplate(template.getId(), group.getId(), UserRole.ADMIN); - templateDb.addGroupToTemplate(template.getId(), null, UserRole.USER); - templateDb.addUserToTemplate(template.getId(), user.getId(), UserRole.CODEVIEWER); - templateDb.addProjectCreatorToTemplate(template.getId(), UserRole.USER); - - PermissionTemplate result = underTest.selectByUuidWithUserAndGroupPermissions(dbSession, "TEMPLATE_UUID"); - assertThat(result.getTemplate()) - .extracting(PermissionTemplateDto::getId, PermissionTemplateDto::getUuid, PermissionTemplateDto::getName, PermissionTemplateDto::getDescription) - .containsExactly(template.getId(), template.getUuid(), template.getName(), template.getDescription()); - assertThat(result.getCharacteristics()).hasSize(1) - .extracting(PermissionTemplateCharacteristicDto::getPermission, PermissionTemplateCharacteristicDto::getWithProjectCreator) - .containsExactly(tuple(UserRole.USER, true)); - assertThat(result.getGroupPermissions()) - .extracting(PermissionTemplateGroupDto::getGroupId, PermissionTemplateGroupDto::getGroupName, PermissionTemplateGroupDto::getPermission) - .containsOnly( - tuple(group.getId(), group.getName(), UserRole.ADMIN), - tuple(0L, ANYONE, UserRole.USER) - ); - assertThat(result.getUserPermissions()).hasSize(1) - .extracting(PermissionTemplateUserDto::getUserId, PermissionTemplateUserDto::getUserLogin, PermissionTemplateUserDto::getPermission) - .containsExactly(tuple(user.getId(), user.getLogin(), UserRole.CODEVIEWER)); - } - - @Test - public void should_fail_on_unmatched_template() { - expectedException.expect(IllegalArgumentException.class); - - underTest.selectPermissionTemplateWithPermissions(db.getSession(), "unmatched"); - } - @Test public void group_count_by_template_and_permission() { PermissionTemplateDto template1 = templateDb.insertTemplate(); diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/permission/ApplyTemplateWsRequest.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/permission/ApplyTemplateWsRequest.java index be8f363b56a..1c08ecba04c 100644 --- a/sonar-ws/src/main/java/org/sonarqube/ws/client/permission/ApplyTemplateWsRequest.java +++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/permission/ApplyTemplateWsRequest.java @@ -26,6 +26,7 @@ public class ApplyTemplateWsRequest { private String projectId; private String projectKey; private String templateId; + private String organization; private String templateName; @CheckForNull @@ -58,6 +59,15 @@ public class ApplyTemplateWsRequest { return this; } + @CheckForNull + public String getOrganization() { + return organization; + } + + public ApplyTemplateWsRequest setOrganization(@Nullable String s) { + this.organization = s; + return this; + } @CheckForNull public String getTemplateName() { return templateName; diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/permission/BulkApplyTemplateWsRequest.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/permission/BulkApplyTemplateWsRequest.java index f5271f85787..d8d7934b767 100644 --- a/sonar-ws/src/main/java/org/sonarqube/ws/client/permission/BulkApplyTemplateWsRequest.java +++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/permission/BulkApplyTemplateWsRequest.java @@ -25,6 +25,7 @@ import javax.annotation.Nullable; public class BulkApplyTemplateWsRequest { private String templateId; + private String organization; private String templateName; private String query; private String qualifier; @@ -39,6 +40,16 @@ public class BulkApplyTemplateWsRequest { return this; } + @CheckForNull + public String getOrganization() { + return organization; + } + + public BulkApplyTemplateWsRequest setOrganization(@Nullable String s) { + this.organization = s; + return this; + } + @CheckForNull public String getTemplateName() { return templateName; -- 2.39.5