From a50808c9a385d75daaeae79168b37c15194b2617 Mon Sep 17 00:00:00 2001 From: =?utf8?q?S=C3=A9bastien=20Lesaint?= Date: Wed, 25 Jan 2017 16:27:18 +0100 Subject: [PATCH] SONAR-8690 read and write default templates from ORGANIZATIONS table --- .../container/ComputeEngineContainerImpl.java | 2 + .../ComputeEngineContainerImplTest.java | 2 +- .../server/component/ComponentUpdater.java | 3 +- .../DefaultPermissionTemplates.java | 36 -- .../permission/PermissionTemplateService.java | 34 +- .../permission/ws/PermissionsWsModule.java | 4 +- .../DefaultPermissionTemplateFinder.java | 119 ------ .../ws/template/DefaultTemplatesResolver.java | 60 +++ .../DefaultTemplatesResolverImpl.java | 52 +++ .../ws/template/DeleteTemplateAction.java | 49 ++- .../ws/template/SearchTemplatesAction.java | 19 +- .../ws/template/SearchTemplatesData.java | 12 +- .../template/SearchTemplatesDataLoader.java | 18 +- .../ws/template/SetDefaultTemplateAction.java | 30 +- .../platformlevel/PlatformLevel4.java | 2 + .../startup/RegisterPermissionTemplates.java | 83 ++-- .../search_project_permissions-example.json | 20 +- .../ws/template/search_templates-example.json | 43 -- .../component/ComponentUpdaterTest.java | 19 +- .../PermissionTemplateServiceTest.java | 132 +++--- .../permission/ws/BasePermissionWsTest.java | 10 +- .../ws/PermissionsWsModuleTest.java | 3 +- .../ws/template/ApplyTemplateActionTest.java | 4 +- .../template/BulkApplyTemplateActionTest.java | 19 +- .../DefaultPermissionTemplateFinderTest.java | 99 ----- .../DefaultTemplatesResolverImplTest.java | 77 ++++ .../DefaultTemplatesResolverRule.java | 79 ++++ .../ws/template/DeleteTemplateActionTest.java | 382 +++++++++++++++--- .../template/SearchTemplatesActionTest.java | 183 +++++---- .../ws/template/SearchTemplatesDataTest.java | 3 +- .../SetDefaultTemplateActionTest.java | 125 ++++-- .../server/project/ws/CreateActionTest.java | 19 +- .../RegisterPermissionTemplatesTest.java | 59 ++- ...ission_template_by_component_id-result.xml | 115 ------ ...lt_permission_template_by_component_id.xml | 99 ----- ...hould_apply_permission_template-result.xml | 109 ----- .../display_all_project_permissions.json | 29 -- .../SearchTemplatesActionTest/empty.json | 17 - .../db/organization/DefaultTemplates.java | 32 +- .../db/organization/OrganizationDao.java | 2 +- .../db/organization/OrganizationMapper.xml | 8 +- .../db/organization/DefaultTemplatesTest.java | 22 +- .../db/organization/OrganizationDaoTest.java | 14 +- .../db/organization/OrganizationDbTester.java | 9 + .../template/PermissionTemplateDbTester.java | 14 + 45 files changed, 1135 insertions(+), 1136 deletions(-) delete mode 100644 server/sonar-server/src/main/java/org/sonar/server/permission/DefaultPermissionTemplates.java delete mode 100644 server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/DefaultPermissionTemplateFinder.java create mode 100644 server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/DefaultTemplatesResolver.java create mode 100644 server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/DefaultTemplatesResolverImpl.java delete mode 100644 server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/DefaultPermissionTemplateFinderTest.java create mode 100644 server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/DefaultTemplatesResolverImplTest.java create mode 100644 server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/DefaultTemplatesResolverRule.java delete mode 100644 server/sonar-server/src/test/resources/org/sonar/server/permission/PermissionTemplateServiceTest/apply_default_permission_template_by_component_id-result.xml delete mode 100644 server/sonar-server/src/test/resources/org/sonar/server/permission/PermissionTemplateServiceTest/apply_default_permission_template_by_component_id.xml delete mode 100644 server/sonar-server/src/test/resources/org/sonar/server/permission/PermissionTemplateServiceTest/should_apply_permission_template-result.xml diff --git a/server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java b/server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java index 5d607377b71..13206c0a8cd 100644 --- a/server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java +++ b/server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java @@ -102,6 +102,7 @@ import org.sonar.server.permission.PermissionTemplateService; import org.sonar.server.permission.PermissionUpdater; import org.sonar.server.permission.UserPermissionChanger; import org.sonar.server.permission.index.PermissionIndexer; +import org.sonar.server.permission.ws.template.DefaultTemplatesResolverImpl; import org.sonar.server.platform.DatabaseServerCompatibility; import org.sonar.server.platform.DefaultServerUpgradeStatus; import org.sonar.server.platform.ServerFileSystemImpl; @@ -327,6 +328,7 @@ public class ComputeEngineContainerImpl implements ComputeEngineContainer { UserIndex.class, // permissions + DefaultTemplatesResolverImpl.class, PermissionTemplateService.class, PermissionUpdater.class, UserPermissionChanger.class, diff --git a/server/sonar-ce/src/test/java/org/sonar/ce/container/ComputeEngineContainerImplTest.java b/server/sonar-ce/src/test/java/org/sonar/ce/container/ComputeEngineContainerImplTest.java index 91e41ffdcba..55a562597c0 100644 --- a/server/sonar-ce/src/test/java/org/sonar/ce/container/ComputeEngineContainerImplTest.java +++ b/server/sonar-ce/src/test/java/org/sonar/ce/container/ComputeEngineContainerImplTest.java @@ -88,7 +88,7 @@ public class ComputeEngineContainerImplTest { assertThat(picoContainer.getComponentAdapters()) .hasSize( CONTAINER_ITSELF - + 77 // level 4 + + 78 // level 4 + 4 // content of CeConfigurationModule + 3 // content of CeHttpModule + 5 // content of CeQueueModule diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/ComponentUpdater.java b/server/sonar-server/src/main/java/org/sonar/server/component/ComponentUpdater.java index 6664ac22e2c..1267089f86c 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/component/ComponentUpdater.java +++ b/server/sonar-server/src/main/java/org/sonar/server/component/ComponentUpdater.java @@ -122,7 +122,8 @@ public class ComponentUpdater { private void handlePermissionTemplate(DbSession dbSession, ComponentDto componentDto, String organizationUuid, @Nullable Long userId) { permissionTemplateService.applyDefault(dbSession, organizationUuid, componentDto, userId); - if (componentDto.qualifier().equals(PROJECT) && permissionTemplateService.hasDefaultTemplateWithPermissionOnProjectCreator(dbSession, organizationUuid, componentDto)) { + if (componentDto.qualifier().equals(PROJECT) + && permissionTemplateService.hasDefaultTemplateWithPermissionOnProjectCreator(dbSession, organizationUuid, componentDto)) { favoriteUpdater.add(dbSession, componentDto, userId); } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/DefaultPermissionTemplates.java b/server/sonar-server/src/main/java/org/sonar/server/permission/DefaultPermissionTemplates.java deleted file mode 100644 index 590ebd5c414..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/DefaultPermissionTemplates.java +++ /dev/null @@ -1,36 +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.server.permission; - -import static java.lang.String.format; - -public class DefaultPermissionTemplates { - public static final String DEFAULT_TEMPLATE_PROPERTY = "sonar.permission.template.default"; - public static final String DEFAULT_TEMPLATE_KEY = "default_template"; - private static final String DEFAULT_ROOT_QUALIFIER_TEMPLATE_PATTERN = "sonar.permission.template.%s.default"; - - private DefaultPermissionTemplates() { - // utility class - } - - public static String defaultRootQualifierTemplateProperty(String qualifier) { - return format(DEFAULT_ROOT_QUALIFIER_TEMPLATE_PATTERN, qualifier); - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionTemplateService.java b/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionTemplateService.java index 364ef3d2828..507e1df05d3 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionTemplateService.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionTemplateService.java @@ -28,7 +28,6 @@ import java.util.Set; import javax.annotation.CheckForNull; import javax.annotation.Nullable; import org.apache.commons.lang.StringUtils; -import org.sonar.api.config.Settings; import org.sonar.api.resources.Qualifiers; import org.sonar.api.server.ServerSide; import org.sonar.core.component.ComponentKeys; @@ -38,6 +37,7 @@ import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.component.ComponentDto; import org.sonar.db.component.ResourceDto; +import org.sonar.db.organization.DefaultTemplates; import org.sonar.db.permission.GroupPermissionDto; import org.sonar.db.permission.UserPermissionDto; import org.sonar.db.permission.template.PermissionTemplateCharacteristicDto; @@ -45,9 +45,12 @@ import org.sonar.db.permission.template.PermissionTemplateDto; import org.sonar.db.permission.template.PermissionTemplateGroupDto; import org.sonar.db.permission.template.PermissionTemplateUserDto; import org.sonar.server.permission.index.PermissionIndexer; +import org.sonar.server.permission.ws.template.DefaultTemplatesResolver; +import org.sonar.server.permission.ws.template.DefaultTemplatesResolverImpl; import org.sonar.server.user.UserSession; import static com.google.common.base.Preconditions.checkArgument; +import static java.lang.String.format; import static java.util.Arrays.asList; import static java.util.Collections.singletonList; import static org.sonar.api.security.DefaultGroups.isAnyone; @@ -58,15 +61,16 @@ import static org.sonar.server.ws.WsUtils.checkFoundWithOptional; public class PermissionTemplateService { private final DbClient dbClient; - private final Settings settings; private final PermissionIndexer permissionIndexer; private final UserSession userSession; + private final DefaultTemplatesResolver defaultTemplatesResolver; - public PermissionTemplateService(DbClient dbClient, Settings settings, PermissionIndexer permissionIndexer, UserSession userSession) { + public PermissionTemplateService(DbClient dbClient, PermissionIndexer permissionIndexer, UserSession userSession, + DefaultTemplatesResolver defaultTemplatesResolver) { this.dbClient = dbClient; - this.settings = settings; this.permissionIndexer = permissionIndexer; this.userSession = userSession; + this.defaultTemplatesResolver = defaultTemplatesResolver; } /** @@ -206,16 +210,22 @@ public class PermissionTemplateService { if (matchingTemplates.size() == 1) { return matchingTemplates.get(0); } - String qualifierTemplateKey = settings.getString("sonar.permission.template." + component.qualifier() + ".default"); - if (!StringUtils.isBlank(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"); + DefaultTemplates defaultTemplates = dbClient.organizationDao().getDefaultTemplates(dbSession, organizationUuid) + .orElseThrow(() -> new IllegalStateException( + format("No Default templates defined for organization with uuid '%s'", organizationUuid))); + + String qualifier = component.qualifier(); + DefaultTemplatesResolverImpl.ResolvedDefaultTemplates resolvedDefaultTemplates = defaultTemplatesResolver.resolve(defaultTemplates); + if (Qualifiers.PROJECT.equals(qualifier)) { + return dbClient.permissionTemplateDao().selectByUuid(dbSession, resolvedDefaultTemplates.getProject()); + } else if (Qualifiers.VIEW.equals(qualifier)) { + String viewDefaultTemplateUuid = resolvedDefaultTemplates.getView().orElseThrow( + () -> new IllegalStateException("Attempt to create a view when Governance plugin is not installed")); + return dbClient.permissionTemplateDao().selectByUuid(dbSession, viewDefaultTemplateUuid); + } else { + throw new IllegalArgumentException(format("Qualifier '%s' is not supported", qualifier)); } - return dbClient.permissionTemplateDao().selectByUuid(dbSession, defaultTemplateKey); } private static void checkAtMostOneMatchForComponentKey(String componentKey, List matchingTemplates) { 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 2204f7f6b6e..b0c33919700 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 @@ -26,7 +26,6 @@ import org.sonar.server.permission.ws.template.AddUserToTemplateAction; import org.sonar.server.permission.ws.template.ApplyTemplateAction; import org.sonar.server.permission.ws.template.BulkApplyTemplateAction; import org.sonar.server.permission.ws.template.CreateTemplateAction; -import org.sonar.server.permission.ws.template.DefaultPermissionTemplateFinder; import org.sonar.server.permission.ws.template.DeleteTemplateAction; import org.sonar.server.permission.ws.template.RemoveGroupFromTemplateAction; import org.sonar.server.permission.ws.template.RemoveProjectCreatorFromTemplateAction; @@ -70,7 +69,6 @@ public class PermissionsWsModule extends Module { // utility classes SearchProjectPermissionsDataLoader.class, SearchTemplatesDataLoader.class, - PermissionWsSupport.class, - DefaultPermissionTemplateFinder.class); + PermissionWsSupport.class); } } 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 deleted file mode 100644 index 6607fa66ca9..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/DefaultPermissionTemplateFinder.java +++ /dev/null @@ -1,119 +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.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.ResourceType; -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; - -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(ResourceType::getQualifier) - .transform(new QualifierToDefaultTemplate(settings)) - .toSortedSet(natural()); - } - - public List getDefaultTemplatesByQualifier() { - return from(resourceTypes.getRoots()) - .transform(ResourceType::getQualifier) - .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) { - return effectiveTemplateUuid(settings, qualifier); - } - } - - 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/DefaultTemplatesResolver.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/DefaultTemplatesResolver.java new file mode 100644 index 00000000000..732c9eddbf2 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/DefaultTemplatesResolver.java @@ -0,0 +1,60 @@ +/* + * 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 javax.annotation.Nullable; +import javax.annotation.concurrent.Immutable; +import org.sonar.db.organization.DefaultTemplates; + +import static java.util.Objects.requireNonNull; +import static java.util.Optional.ofNullable; + +public interface DefaultTemplatesResolver { + /** + * Resolve the effective default templates uuid for the specified {@link DefaultTemplates}. + *
    + *
  • {@link ResolvedDefaultTemplates#project} is always the same as {@link DefaultTemplates#projectUuid}
  • + *
  • when Governance is not installed, {@link ResolvedDefaultTemplates#view} is always {@code null}
  • + *
  • when Governance is not installed, {@link ResolvedDefaultTemplates#view} is {@link DefaultTemplates#viewUuid} + * when it is non {@code null}, otherwise it is {@link DefaultTemplates#projectUuid}
  • + *
+ */ + ResolvedDefaultTemplates resolve(DefaultTemplates defaultTemplates); + + @Immutable + final class ResolvedDefaultTemplates { + private final String project; + private final String view; + + ResolvedDefaultTemplates(String project, @Nullable String view) { + this.project = requireNonNull(project, "project can't be null"); + this.view = view; + } + + public String getProject() { + return project; + } + + public Optional getView() { + return ofNullable(view); + } + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/DefaultTemplatesResolverImpl.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/DefaultTemplatesResolverImpl.java new file mode 100644 index 00000000000..45c8a37ece8 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/DefaultTemplatesResolverImpl.java @@ -0,0 +1,52 @@ +/* + * 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 org.sonar.api.resources.Qualifiers; +import org.sonar.api.resources.ResourceType; +import org.sonar.api.resources.ResourceTypes; +import org.sonar.db.organization.DefaultTemplates; + +import static java.util.Optional.ofNullable; + +public class DefaultTemplatesResolverImpl implements DefaultTemplatesResolver { + private final ResourceTypes resourceTypes; + + public DefaultTemplatesResolverImpl(ResourceTypes resourceTypes) { + this.resourceTypes = resourceTypes; + } + + @Override + public ResolvedDefaultTemplates resolve(DefaultTemplates defaultTemplates) { + String projectDefaultTemplate = defaultTemplates.getProjectUuid(); + + return new ResolvedDefaultTemplates( + projectDefaultTemplate, + isViewsEnabled(resourceTypes) ? ofNullable(defaultTemplates.getViewUuid()).orElse(projectDefaultTemplate) : null); + } + + private static boolean isViewsEnabled(ResourceTypes resourceTypes) { + return resourceTypes.getRoots() + .stream() + .map(ResourceType::getQualifier) + .anyMatch(Qualifiers.VIEW::equals); + } + +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/DeleteTemplateAction.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/DeleteTemplateAction.java index 4d99118bd1a..f1ff7df0def 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/DeleteTemplateAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/DeleteTemplateAction.java @@ -19,12 +19,12 @@ */ package org.sonar.server.permission.ws.template; -import java.util.Set; 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.organization.DefaultTemplates; import org.sonar.db.permission.template.PermissionTemplateDto; import org.sonar.server.permission.ws.PermissionWsSupport; import org.sonar.server.permission.ws.PermissionsWsAction; @@ -34,6 +34,7 @@ import org.sonarqube.ws.client.permission.DeleteTemplateWsRequest; import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdmin; 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.WsUtils.checkFoundWithOptional; 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; @@ -43,13 +44,13 @@ public class DeleteTemplateAction implements PermissionsWsAction { private final DbClient dbClient; private final UserSession userSession; private final PermissionWsSupport finder; - private final DefaultPermissionTemplateFinder defaultPermissionTemplateFinder; + private final DefaultTemplatesResolver defaultTemplatesResolver; - public DeleteTemplateAction(DbClient dbClient, UserSession userSession, PermissionWsSupport support, DefaultPermissionTemplateFinder defaultPermissionTemplateFinder) { + public DeleteTemplateAction(DbClient dbClient, UserSession userSession, PermissionWsSupport support, DefaultTemplatesResolver defaultTemplatesResolver) { this.dbClient = dbClient; this.userSession = userSession; this.finder = support; - this.defaultPermissionTemplateFinder = defaultPermissionTemplateFinder; + this.defaultTemplatesResolver = defaultTemplatesResolver; } @Override @@ -66,6 +67,7 @@ public class DeleteTemplateAction implements PermissionsWsAction { @Override public void handle(Request request, Response response) throws Exception { + userSession.checkLoggedIn(); doHandle(toDeleteTemplateWsRequest(request)); response.noContent(); } @@ -76,12 +78,45 @@ public class DeleteTemplateAction implements PermissionsWsAction { request.getTemplateId(), request.getOrganization(), request.getTemplateName())); checkGlobalAdmin(userSession, template.getOrganizationUuid()); - checkTemplateUuidIsNotDefault(template.getUuid()); + DefaultTemplates defaultTemplates = retrieveDefaultTemplates(dbSession, template); + + checkTemplateUuidIsNotDefault(template, defaultTemplates); dbClient.permissionTemplateDao().deleteById(dbSession, template.getId()); + updateViewDefaultTemplateWhenGovernanceIsNotInstalled(dbSession, template, defaultTemplates); + dbSession.commit(); } } + /** + * The default template for view can be removed when Governance is not installed. To avoid keeping a reference + * to a non existing template, we update the default templates. + */ + private void updateViewDefaultTemplateWhenGovernanceIsNotInstalled(DbSession dbSession, PermissionTemplateDto template, DefaultTemplates defaultTemplates) { + String viewDefaultTemplateUuid = defaultTemplates.getViewUuid(); + if (viewDefaultTemplateUuid != null && viewDefaultTemplateUuid.equals(template.getUuid())) { + defaultTemplates.setViewUuid(null); + dbClient.organizationDao().setDefaultTemplates(dbSession, template.getOrganizationUuid(), defaultTemplates); + } + } + + private DefaultTemplates retrieveDefaultTemplates(DbSession dbSession, PermissionTemplateDto template) { + return checkFoundWithOptional( + dbClient.organizationDao().getDefaultTemplates(dbSession, template.getOrganizationUuid()), + "Can't find default templates of Organization with uuid '%s' to which template with uuid '%s' belongs", + template.getOrganizationUuid(), template.getUuid()); + } + + private void checkTemplateUuidIsNotDefault(PermissionTemplateDto template, DefaultTemplates defaultTemplates) { + DefaultTemplatesResolverImpl.ResolvedDefaultTemplates resolvedDefaultTemplates = defaultTemplatesResolver.resolve(defaultTemplates); + checkRequest(!resolvedDefaultTemplates.getProject().equals(template.getUuid()), + "It is not possible to delete the default permission template for projects"); + resolvedDefaultTemplates.getView() + .ifPresent(viewDefaultTemplateUuid -> checkRequest( + !viewDefaultTemplateUuid.equals(template.getUuid()), + "It is not possible to delete the default permission template for views")); + } + private static DeleteTemplateWsRequest toDeleteTemplateWsRequest(Request request) { return new DeleteTemplateWsRequest() .setTemplateId(request.param(PARAM_TEMPLATE_ID)) @@ -89,8 +124,4 @@ public class DeleteTemplateAction implements PermissionsWsAction { .setTemplateName(request.param(PARAM_TEMPLATE_NAME)); } - private void checkTemplateUuidIsNotDefault(String key) { - Set defaultTemplateUuids = defaultPermissionTemplateFinder.getDefaultTemplateUuids(); - checkRequest(!defaultTemplateUuids.contains(key), "It is not possible to delete a default template"); - } } 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 index adb3453cbfa..cfeb7b67289 100644 --- 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 @@ -21,6 +21,7 @@ package org.sonar.server.permission.ws.template; import java.util.Locale; import org.sonar.api.i18n.I18n; +import org.sonar.api.resources.Qualifiers; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; @@ -107,12 +108,18 @@ public class SearchTemplatesAction implements PermissionsWsAction { private static void buildDefaultTemplatesResponse(SearchTemplatesWsResponse.Builder response, SearchTemplatesData data) { TemplateIdQualifier.Builder templateUuidQualifierBuilder = TemplateIdQualifier.newBuilder(); - for (DefaultPermissionTemplateFinder.TemplateUuidQualifier templateUuidQualifier : data.defaultTemplates()) { - response.addDefaultTemplates(templateUuidQualifierBuilder - .clear() - .setQualifier(templateUuidQualifier.getQualifier()) - .setTemplateId(templateUuidQualifier.getTemplateUuid())); - } + + DefaultTemplatesResolverImpl.ResolvedDefaultTemplates resolvedDefaultTemplates = data.defaultTemplates(); + response.addDefaultTemplates(templateUuidQualifierBuilder + .setQualifier(Qualifiers.PROJECT) + .setTemplateId(resolvedDefaultTemplates.getProject())); + + resolvedDefaultTemplates.getView() + .ifPresent(viewDefaultTemplate -> response.addDefaultTemplates( + templateUuidQualifierBuilder + .clear() + .setQualifier(Qualifiers.VIEW) + .setTemplateId(viewDefaultTemplate))); } private static void buildTemplatesResponse(WsPermissions.SearchTemplatesWsResponse.Builder response, SearchTemplatesData data) { 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 index abe58c471d4..17d77374928 100644 --- 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 @@ -22,7 +22,7 @@ package org.sonar.server.permission.ws.template; import com.google.common.collect.Table; import java.util.List; import org.sonar.db.permission.template.PermissionTemplateDto; -import org.sonar.server.permission.ws.template.DefaultPermissionTemplateFinder.TemplateUuidQualifier; +import org.sonar.server.permission.ws.template.DefaultTemplatesResolver.ResolvedDefaultTemplates; import static com.google.common.base.MoreObjects.firstNonNull; import static com.google.common.base.Preconditions.checkState; @@ -31,14 +31,14 @@ import static com.google.common.collect.ImmutableTable.copyOf; class SearchTemplatesData { private final List templates; - private final List defaultTemplates; + private final ResolvedDefaultTemplates defaultTemplates; private final Table userCountByTemplateIdAndPermission; private final Table groupCountByTemplateIdAndPermission; private final Table withProjectCreatorByTemplateIdAndPermission; private SearchTemplatesData(Builder builder) { this.templates = copyOf(builder.templates); - this.defaultTemplates = copyOf(builder.defaultTemplates); + this.defaultTemplates = builder.defaultTemplates; this.userCountByTemplateIdAndPermission = copyOf(builder.userCountByTemplateIdAndPermission); this.groupCountByTemplateIdAndPermission = copyOf(builder.groupCountByTemplateIdAndPermission); this.withProjectCreatorByTemplateIdAndPermission = copyOf(builder.withProjectCreatorByTemplateIdAndPermission); @@ -52,7 +52,7 @@ class SearchTemplatesData { return templates; } - public List defaultTemplates() { + public ResolvedDefaultTemplates defaultTemplates() { return defaultTemplates; } @@ -70,7 +70,7 @@ class SearchTemplatesData { public static class Builder { private List templates; - private List defaultTemplates; + private ResolvedDefaultTemplates defaultTemplates; private Table userCountByTemplateIdAndPermission; private Table groupCountByTemplateIdAndPermission; private Table withProjectCreatorByTemplateIdAndPermission; @@ -94,7 +94,7 @@ class SearchTemplatesData { return this; } - public Builder defaultTemplates(List defaultTemplates) { + public Builder defaultTemplates(ResolvedDefaultTemplates defaultTemplates) { this.defaultTemplates = defaultTemplates; 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 index c14d0a2be89..1f29aadc869 100644 --- 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 @@ -25,31 +25,37 @@ import com.google.common.collect.TreeBasedTable; import java.util.List; import org.sonar.db.DbClient; import org.sonar.db.DbSession; +import org.sonar.db.organization.DefaultTemplates; import org.sonar.db.permission.template.CountByTemplateAndPermissionDto; import org.sonar.db.permission.template.PermissionTemplateCharacteristicDto; import org.sonar.db.permission.template.PermissionTemplateDto; -import org.sonar.server.permission.ws.template.DefaultPermissionTemplateFinder.TemplateUuidQualifier; +import org.sonar.server.permission.ws.template.DefaultTemplatesResolver.ResolvedDefaultTemplates; import org.sonarqube.ws.client.permission.SearchTemplatesWsRequest; import static org.sonar.server.permission.ws.template.SearchTemplatesData.builder; +import static org.sonar.server.ws.WsUtils.checkFoundWithOptional; public class SearchTemplatesDataLoader { private final DbClient dbClient; - private final DefaultPermissionTemplateFinder defaultPermissionTemplateFinder; + private final DefaultTemplatesResolver defaultTemplatesResolver; - public SearchTemplatesDataLoader(DbClient dbClient, DefaultPermissionTemplateFinder defaultPermissionTemplateFinder) { + public SearchTemplatesDataLoader(DbClient dbClient, DefaultTemplatesResolver defaultTemplatesResolver) { this.dbClient = dbClient; - this.defaultPermissionTemplateFinder = defaultPermissionTemplateFinder; + this.defaultTemplatesResolver = defaultTemplatesResolver; } public SearchTemplatesData load(DbSession dbSession, SearchTemplatesWsRequest request) { SearchTemplatesData.Builder data = builder(); List templates = searchTemplates(dbSession, request); List templateIds = Lists.transform(templates, PermissionTemplateDto::getId); - List defaultTemplates = defaultPermissionTemplateFinder.getDefaultTemplatesByQualifier(); + + DefaultTemplates defaultTemplates = checkFoundWithOptional( + dbClient.organizationDao().getDefaultTemplates(dbSession, request.getOrganizationUuid()), + "No Default templates for organization with uuid '%s'", request.getOrganizationUuid()); + ResolvedDefaultTemplates resolvedDefaultTemplates = defaultTemplatesResolver.resolve(defaultTemplates); data.templates(templates) - .defaultTemplates(defaultTemplates) + .defaultTemplates(resolvedDefaultTemplates) .userCountByTemplateIdAndPermission(userCountByTemplateIdAndPermission(dbSession, templateIds)) .groupCountByTemplateIdAndPermission(groupCountByTemplateIdAndPermission(dbSession, templateIds)) .withProjectCreatorByTemplateIdAndPermission(withProjectCreatorsByTemplateIdAndPermission(dbSession, templateIds)); 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 index d6c0bf8b45c..20a96d4dc44 100644 --- 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 @@ -27,20 +27,21 @@ 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.organization.DefaultTemplates; +import org.sonar.db.organization.OrganizationDao; import org.sonar.db.permission.template.PermissionTemplateDto; import org.sonar.server.permission.ws.PermissionWsSupport; import org.sonar.server.permission.ws.PermissionsWsAction; -import org.sonar.server.platform.PersistentSettings; import org.sonar.server.user.UserSession; import org.sonarqube.ws.client.permission.SetDefaultTemplateWsRequest; -import static org.sonar.server.permission.DefaultPermissionTemplates.defaultRootQualifierTemplateProperty; import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdmin; import static org.sonar.server.permission.ws.PermissionRequestValidator.validateQualifier; 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.sonar.server.ws.WsParameterBuilder.QualifierParameterContext.newQualifierParameterContext; +import static org.sonar.server.ws.WsUtils.checkFoundWithOptional; 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; @@ -50,16 +51,14 @@ public class SetDefaultTemplateAction implements PermissionsWsAction { private final DbClient dbClient; private final PermissionWsSupport wsSupport; private final ResourceTypes resourceTypes; - private final PersistentSettings settings; private final UserSession userSession; private final I18n i18n; - public SetDefaultTemplateAction(DbClient dbClient, PermissionWsSupport wsSupport, ResourceTypes resourceTypes, PersistentSettings settings, UserSession userSession, - I18n i18n) { + public SetDefaultTemplateAction(DbClient dbClient, PermissionWsSupport wsSupport, ResourceTypes resourceTypes, + UserSession userSession, I18n i18n) { this.dbClient = dbClient; this.wsSupport = wsSupport; this.resourceTypes = resourceTypes; - this.settings = settings; this.userSession = userSession; this.i18n = i18n; } @@ -90,7 +89,7 @@ public class SetDefaultTemplateAction implements PermissionsWsAction { PermissionTemplateDto template = findTemplate(dbSession, request); checkGlobalAdmin(userSession, template.getOrganizationUuid()); validateQualifier(qualifier, resourceTypes); - setDefaultTemplateUuid(dbSession, template.getUuid(), qualifier); + setDefaultTemplateUuid(dbSession, template, qualifier); dbSession.commit(); } } @@ -108,7 +107,18 @@ public class SetDefaultTemplateAction implements PermissionsWsAction { request.getOrganization(), request.getTemplateName())); } - private void setDefaultTemplateUuid(DbSession dbSession, String templateUuid, String qualifier) { - settings.saveProperty(dbSession, defaultRootQualifierTemplateProperty(qualifier), templateUuid); + private void setDefaultTemplateUuid(DbSession dbSession, PermissionTemplateDto permissionTemplateDto, String qualifier) { + String organizationUuid = permissionTemplateDto.getOrganizationUuid(); + OrganizationDao organizationDao = dbClient.organizationDao(); + + DefaultTemplates defaultTemplates = checkFoundWithOptional( + organizationDao.getDefaultTemplates(dbSession, organizationUuid), + "No Default templates for organization with uuid '%s'", organizationUuid); + if (Qualifiers.PROJECT.equals(qualifier)) { + defaultTemplates.setProjectUuid(permissionTemplateDto.getUuid()); + } else if (Qualifiers.VIEW.equals(qualifier)) { + defaultTemplates.setViewUuid(permissionTemplateDto.getUuid()); + } + organizationDao.setDefaultTemplates(dbSession, organizationUuid, defaultTemplates); } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java index a5dc9695fa1..6c22c8f0436 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java +++ b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java @@ -93,6 +93,7 @@ import org.sonar.server.permission.PermissionUpdater; import org.sonar.server.permission.UserPermissionChanger; import org.sonar.server.permission.index.PermissionIndexer; import org.sonar.server.permission.ws.PermissionsWsModule; +import org.sonar.server.permission.ws.template.DefaultTemplatesResolverImpl; import org.sonar.server.platform.BackendCleanup; import org.sonar.server.platform.PersistentSettings; import org.sonar.server.platform.ServerLogging; @@ -349,6 +350,7 @@ public class PlatformLevel4 extends PlatformLevel { UserGroupsModule.class, // permissions + DefaultTemplatesResolverImpl.class, PermissionsWsModule.class, PermissionTemplateService.class, PermissionUpdater.class, diff --git a/server/sonar-server/src/main/java/org/sonar/server/startup/RegisterPermissionTemplates.java b/server/sonar-server/src/main/java/org/sonar/server/startup/RegisterPermissionTemplates.java index 435c39e574c..750f1a7e8ba 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/startup/RegisterPermissionTemplates.java +++ b/server/sonar-server/src/main/java/org/sonar/server/startup/RegisterPermissionTemplates.java @@ -22,7 +22,6 @@ package org.sonar.server.startup; import java.util.Date; import java.util.Optional; import javax.annotation.Nullable; -import org.sonar.api.resources.Qualifiers; import org.sonar.api.security.DefaultGroups; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; @@ -30,76 +29,58 @@ import org.sonar.api.utils.log.Profiler; import org.sonar.api.web.UserRole; import org.sonar.db.DbClient; import org.sonar.db.DbSession; -import org.sonar.db.loadedtemplate.LoadedTemplateDto; +import org.sonar.db.organization.DefaultTemplates; import org.sonar.db.permission.template.PermissionTemplateDto; import org.sonar.db.user.GroupDto; import org.sonar.server.organization.DefaultOrganizationProvider; -import org.sonar.server.platform.PersistentSettings; - -import static org.sonar.db.loadedtemplate.LoadedTemplateDto.PERMISSION_TEMPLATE_TYPE; -import static org.sonar.server.permission.DefaultPermissionTemplates.DEFAULT_TEMPLATE_KEY; -import static org.sonar.server.permission.DefaultPermissionTemplates.DEFAULT_TEMPLATE_PROPERTY; -import static org.sonar.server.permission.DefaultPermissionTemplates.defaultRootQualifierTemplateProperty; public class RegisterPermissionTemplates { private static final Logger LOG = Loggers.get(RegisterPermissionTemplates.class); + private static final String DEFAULT_TEMPLATE_UUID = "default_template"; private final DbClient dbClient; - private final PersistentSettings settings; private final DefaultOrganizationProvider defaultOrganizationProvider; - public RegisterPermissionTemplates(DbClient dbClient, PersistentSettings settings, DefaultOrganizationProvider defaultOrganizationProvider) { + public RegisterPermissionTemplates(DbClient dbClient, DefaultOrganizationProvider defaultOrganizationProvider) { this.dbClient = dbClient; - this.settings = settings; this.defaultOrganizationProvider = defaultOrganizationProvider; } public void start() { Profiler profiler = Profiler.create(Loggers.get(getClass())).startInfo("Register permission templates"); - boolean shouldRegister = shouldRegister(); - - if (hasExistingPermissionsConfig()) { - // needs to be done at each startup in the case a plugin has just been installed. The default property must be the project one - String defaultProjectPermissionTemplateUuid = settings.getString(defaultRootQualifierTemplateProperty(Qualifiers.PROJECT)); - setDefaultProperty(defaultProjectPermissionTemplateUuid); - } else if (shouldRegister) { - PermissionTemplateDto template = insertDefaultTemplate(); - setDefaultProperty(template.getUuid()); - } - if (shouldRegister) { - registerInitialization(); + try (DbSession dbSession = dbClient.openSession(false)) { + String defaultOrganizationUuid = defaultOrganizationProvider.get().getUuid(); + Optional defaultTemplates = dbClient.organizationDao().getDefaultTemplates(dbSession, defaultOrganizationUuid); + if (!defaultTemplates.isPresent()) { + PermissionTemplateDto defaultTemplate = getOrInsertDefaultTemplate(dbSession, defaultOrganizationUuid); + dbClient.organizationDao().setDefaultTemplates(dbSession, defaultOrganizationUuid, new DefaultTemplates().setProjectUuid(defaultTemplate.getUuid())); + dbSession.commit(); + } } profiler.stopDebug(); } - private boolean hasExistingPermissionsConfig() { - return settings.getString(defaultRootQualifierTemplateProperty(Qualifiers.PROJECT)) != null; - } - - private boolean shouldRegister() { - return dbClient.loadedTemplateDao().countByTypeAndKey(PERMISSION_TEMPLATE_TYPE, DEFAULT_TEMPLATE_KEY) == 0; - } - - private PermissionTemplateDto insertDefaultTemplate() { - try (DbSession dbSession = dbClient.openSession(false)) { - String orgUuid = defaultOrganizationProvider.get().getUuid(); - - PermissionTemplateDto template = new PermissionTemplateDto() - .setOrganizationUuid(orgUuid) - .setName("Default template") - .setUuid(DEFAULT_TEMPLATE_KEY) - .setDescription("This permission template will be used as default when no other permission configuration is available") - .setCreatedAt(new Date()) - .setUpdatedAt(new Date()); - - dbClient.permissionTemplateDao().insert(dbSession, template); - insertDefaultGroupPermissions(dbSession, template); - dbSession.commit(); - return template; + private PermissionTemplateDto getOrInsertDefaultTemplate(DbSession dbSession, String defaultOrganizationUuid) { + PermissionTemplateDto permissionTemplateDto = dbClient.permissionTemplateDao().selectByUuid(dbSession, DEFAULT_TEMPLATE_UUID); + if (permissionTemplateDto != null) { + return permissionTemplateDto; } + + PermissionTemplateDto template = new PermissionTemplateDto() + .setOrganizationUuid(defaultOrganizationUuid) + .setName("Default template") + .setUuid(DEFAULT_TEMPLATE_UUID) + .setDescription("This permission template will be used as default when no other permission configuration is available") + .setCreatedAt(new Date()) + .setUpdatedAt(new Date()); + + dbClient.permissionTemplateDao().insert(dbSession, template); + insertDefaultGroupPermissions(dbSession, template); + dbSession.commit(); + return template; } private void insertDefaultGroupPermissions(DbSession dbSession, PermissionTemplateDto template) { @@ -122,12 +103,4 @@ public class RegisterPermissionTemplates { } } - private void registerInitialization() { - LoadedTemplateDto loadedTemplate = new LoadedTemplateDto(DEFAULT_TEMPLATE_KEY, PERMISSION_TEMPLATE_TYPE); - dbClient.loadedTemplateDao().insert(loadedTemplate); - } - - private void setDefaultProperty(String defaultTemplate) { - settings.saveProperty(DEFAULT_TEMPLATE_PROPERTY, defaultTemplate); - } } diff --git a/server/sonar-server/src/main/resources/org/sonar/server/permission/ws/search_project_permissions-example.json b/server/sonar-server/src/main/resources/org/sonar/server/permission/ws/search_project_permissions-example.json index 43480d67f96..8d936d8d7f4 100644 --- a/server/sonar-server/src/main/resources/org/sonar/server/permission/ws/search_project_permissions-example.json +++ b/server/sonar-server/src/main/resources/org/sonar/server/permission/ws/search_project_permissions-example.json @@ -2,7 +2,7 @@ "paging": { "pageIndex": 1, "pageSize": 25, - "total": 4 + "total": 3 }, "projects": [ { @@ -36,24 +36,6 @@ } ] }, - { - "id": "4e607bf9-7ed0-484a-946d-d58ba7dab2fb", - "key": "simon-brandhof", - "name": "Simon Brandhof", - "qualifier": "DEV", - "permissions": [ - { - "key": "admin", - "usersCount": 0, - "groupsCount": 1 - }, - { - "key": "issueadmin", - "usersCount": 1, - "groupsCount": 0 - } - ] - }, { "id": "752d8bfd-420c-4a83-a4e5-8ab19b13c8fc", "key": "Java", 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 index 3534f1620a6..643c7bf9111 100644 --- 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 @@ -1,44 +1,5 @@ { "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": "admin", - "usersCount": 0, - "groupsCount": 0, - "withProjectCreator": false - }, - { - "key": "codeviewer", - "usersCount": 0, - "groupsCount": 0, - "withProjectCreator": false - }, - { - "key": "issueadmin", - "usersCount": 0, - "groupsCount": 0, - "withProjectCreator": false - }, - { - "key": "scan", - "usersCount": 0, - "groupsCount": 0, - "withProjectCreator": false - }, - { - "key": "user", - "usersCount": 0, - "groupsCount": 1, - "withProjectCreator": false - } - ] - }, { "id": "AU-Tpxb--iU5OvuD2FLy", "name": "Default template for Projects", @@ -127,10 +88,6 @@ { "templateId": "AU-TpxcA-iU5OvuD2FLz", "qualifier": "VW" - }, - { - "templateId": "AU-TpxcA-iU5OvuD2FL0", - "qualifier": "DEV" } ] } diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/ComponentUpdaterTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/ComponentUpdaterTest.java index 63c6ce890b7..9d0e10ce441 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/component/ComponentUpdaterTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/component/ComponentUpdaterTest.java @@ -26,7 +26,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.sonar.api.config.MapSettings; -import org.sonar.api.config.Settings; import org.sonar.api.utils.System2; import org.sonar.db.DbClient; import org.sonar.db.DbSession; @@ -48,6 +47,7 @@ import org.sonar.server.measure.index.ProjectMeasuresIndexDefinition; import org.sonar.server.measure.index.ProjectMeasuresIndexer; import org.sonar.server.permission.PermissionTemplateService; import org.sonar.server.permission.index.PermissionIndexer; +import org.sonar.server.permission.ws.template.DefaultTemplatesResolverRule; import org.sonar.server.view.index.ViewIndexDefinition; import static com.google.common.collect.Lists.newArrayList; @@ -75,26 +75,23 @@ public class ComponentUpdaterTest { @Rule public ExpectedException expectedException = ExpectedException.none(); - @Rule public DbTester db = DbTester.create(system2); - @Rule public EsTester es = new EsTester( new ComponentIndexDefinition(new MapSettings()), new ProjectMeasuresIndexDefinition(new MapSettings()), new IssueIndexDefinition(new MapSettings()), new ViewIndexDefinition(new MapSettings())); - @Rule public I18nRule i18n = new I18nRule().put("qualifier.TRK", "Project"); - - private Settings settings = new MapSettings(); + @Rule + public DefaultTemplatesResolverRule defaultTemplatesResolver = DefaultTemplatesResolverRule.withoutGovernance(); private PermissionTemplateDto permissionTemplateDto; ComponentUpdater underTest = new ComponentUpdater(db.getDbClient(), i18n, system2, - new PermissionTemplateService(db.getDbClient(), settings, new PermissionIndexer(db.getDbClient(), es.client()), null), + new PermissionTemplateService(db.getDbClient(), new PermissionIndexer(db.getDbClient(), es.client()), null, defaultTemplatesResolver), new FavoriteUpdater(db.getDbClient()), new ProjectMeasuresIndexer(system2, db.getDbClient(), es.client()), new ComponentIndexer(db.getDbClient(), es.client())); @@ -102,7 +99,7 @@ public class ComponentUpdaterTest { @Before public void setUp() throws Exception { permissionTemplateDto = db.permissionTemplates().insertTemplate(db.getDefaultOrganization()); - setTemplateAsDefault(permissionTemplateDto); + db.organizations().setDefaultTemplates(db.getDefaultOrganization(), permissionTemplateDto.getUuid(), null); } @Test @@ -305,6 +302,8 @@ public class ComponentUpdaterTest { @Test public void create_view() { + defaultTemplatesResolver.installGovernance(); + ComponentDto view = underTest.create(db.getSession(), NewComponent.newComponentBuilder() .setKey("view-key") @@ -324,8 +323,4 @@ public class ComponentUpdaterTest { assertThat(es.getIds(ViewIndexDefinition.INDEX, ViewIndexDefinition.TYPE_VIEW)).isEmpty(); } - private void setTemplateAsDefault(PermissionTemplateDto permissionTemplateDto) { - settings.appendProperty("sonar.permission.template.default", permissionTemplateDto.getUuid()); - } - } diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/PermissionTemplateServiceTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/PermissionTemplateServiceTest.java index cc54ef95f22..35386dca956 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/permission/PermissionTemplateServiceTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/permission/PermissionTemplateServiceTest.java @@ -21,14 +21,13 @@ package org.sonar.server.permission; import java.util.List; 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.config.MapSettings; import org.sonar.api.config.Settings; import org.sonar.api.resources.Qualifiers; -import org.sonar.api.utils.System2; +import org.sonar.api.utils.internal.AlwaysIncreasingSystem2; import org.sonar.api.web.UserRole; import org.sonar.db.DbSession; import org.sonar.db.DbTester; @@ -39,126 +38,125 @@ import org.sonar.db.permission.template.PermissionTemplateDto; import org.sonar.db.user.GroupDto; import org.sonar.db.user.UserDto; import org.sonar.server.permission.index.PermissionIndexer; +import org.sonar.server.permission.ws.template.DefaultTemplatesResolverRule; import org.sonar.server.tester.UserSessionRule; 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.core.permission.GlobalPermissions.SCAN_EXECUTION; -import static org.sonar.db.component.ComponentTesting.newProjectDto; -import static org.sonar.db.organization.OrganizationTesting.newOrganizationDto; -import static org.sonar.db.user.GroupTesting.newGroupDto; public class PermissionTemplateServiceTest { - private static final OrganizationDto ORGANIZATION = newOrganizationDto().setUuid("org1"); - private static final ComponentDto PROJECT = newProjectDto(ORGANIZATION).setId(123L).setUuid("THE_PROJECT_UUID"); - private static final long NOW = 123456789L; - @Rule public ExpectedException throwable = ExpectedException.none(); - - private System2 system2 = mock(System2.class); - @Rule - public DbTester dbTester = DbTester.create(system2); + public DbTester dbTester = DbTester.create(new AlwaysIncreasingSystem2()); + @Rule + public DefaultTemplatesResolverRule defaultTemplatesResolver = DefaultTemplatesResolverRule.withGovernance(); private UserSessionRule userSession = UserSessionRule.standalone(); private PermissionTemplateDbTester templateDb = dbTester.permissionTemplates(); private DbSession session = dbTester.getSession(); private Settings settings = new MapSettings(); private PermissionIndexer permissionIndexer = mock(PermissionIndexer.class); - private PermissionTemplateService underTest = new PermissionTemplateService(dbTester.getDbClient(), settings, - permissionIndexer, userSession); - - @Before - public void setUp() { - when(system2.now()).thenReturn(NOW); - } + private PermissionTemplateService underTest = new PermissionTemplateService(dbTester.getDbClient(), permissionIndexer, userSession, defaultTemplatesResolver); @Test public void apply_permission_template() { - dbTester.prepareDbUnit(getClass(), "should_apply_permission_template.xml"); - - assertThat(selectProjectPermissionsOfGroup("org1", 100L, PROJECT)).isEmpty(); - assertThat(selectProjectPermissionsOfGroup("org1", 101L, PROJECT)).isEmpty(); - assertThat(selectProjectPermissionsOfGroup("org1", null, PROJECT)).isEmpty(); - assertThat(selectProjectPermissionsOfUser(200L, PROJECT)).isEmpty(); - - PermissionTemplateDto template = dbTester.getDbClient().permissionTemplateDao().selectByUuid(session, "default_20130101_010203"); - underTest.apply(session, template, singletonList(PROJECT)); - - assertThat(selectProjectPermissionsOfGroup("org1", 100L, PROJECT)).containsOnly("admin", "issueadmin"); - assertThat(selectProjectPermissionsOfGroup("org1", 101L, PROJECT)).containsOnly("user", "codeviewer"); - assertThat(selectProjectPermissionsOfGroup("org1", null, PROJECT)).containsOnly("user", "codeviewer"); - assertThat(selectProjectPermissionsOfUser(200L, PROJECT)).containsOnly("admin"); - - checkAuthorizationUpdatedAtIsUpdated(); + OrganizationDto organization = dbTester.organizations().insert(); + ComponentDto project = dbTester.components().insertProject(organization); + GroupDto adminGroup = dbTester.users().insertGroup(organization); + GroupDto userGroup = dbTester.users().insertGroup(organization); + UserDto user = dbTester.users().insertUser(); + dbTester.users().insertPermissionOnGroup(adminGroup, "admin"); + dbTester.users().insertPermissionOnGroup(userGroup, "user"); + dbTester.users().insertPermissionOnUser(organization, user, "admin"); + PermissionTemplateDto permissionTemplate = dbTester.permissionTemplates().insertTemplate(organization); + dbTester.permissionTemplates().addGroupToTemplate(permissionTemplate, adminGroup, "admin"); + dbTester.permissionTemplates().addGroupToTemplate(permissionTemplate, adminGroup, "issueadmin"); + dbTester.permissionTemplates().addGroupToTemplate(permissionTemplate, userGroup, "user"); + dbTester.permissionTemplates().addGroupToTemplate(permissionTemplate, userGroup, "codeviewer"); + dbTester.permissionTemplates().addAnyoneToTemplate(permissionTemplate, "user"); + dbTester.permissionTemplates().addAnyoneToTemplate(permissionTemplate, "codeviewer"); + dbTester.permissionTemplates().addUserToTemplate(permissionTemplate, user, "admin"); + + assertThat(selectProjectPermissionsOfGroup(organization, adminGroup, project)).isEmpty(); + assertThat(selectProjectPermissionsOfGroup(organization, userGroup, project)).isEmpty(); + assertThat(selectProjectPermissionsOfGroup(organization, null, project)).isEmpty(); + assertThat(selectProjectPermissionsOfUser(user, project)).isEmpty(); + + underTest.apply(session, permissionTemplate, singletonList(project)); + + assertThat(selectProjectPermissionsOfGroup(organization, adminGroup, project)).containsOnly("admin", "issueadmin"); + assertThat(selectProjectPermissionsOfGroup(organization, userGroup, project)).containsOnly("user", "codeviewer"); + assertThat(selectProjectPermissionsOfGroup(organization, null, project)).containsOnly("user", "codeviewer"); + assertThat(selectProjectPermissionsOfUser(user, project)).containsOnly("admin"); + + checkAuthorizationUpdatedAtIsUpdated(project); } - private List selectProjectPermissionsOfGroup(String organizationUuid, @Nullable Long groupId, ComponentDto project) { + private List selectProjectPermissionsOfGroup(OrganizationDto organizationDto, @Nullable GroupDto groupDto, ComponentDto project) { return dbTester.getDbClient().groupPermissionDao().selectProjectPermissionsOfGroup(session, - organizationUuid, groupId != null ? groupId : null, project.getId()); + organizationDto.getUuid(), groupDto != null ? groupDto.getId() : null, project.getId()); } - private List selectProjectPermissionsOfUser(long userId, ComponentDto project) { + private List selectProjectPermissionsOfUser(UserDto userDto, ComponentDto project) { return dbTester.getDbClient().userPermissionDao().selectProjectPermissionsOfUser(session, - userId, project.getId()); + userDto.getId(), project.getId()); } @Test public void would_user_have_permission_with_default_permission_template() { + OrganizationDto organization = dbTester.organizations().insert(); UserDto user = dbTester.users().insertUser(); - GroupDto group = dbTester.users().insertGroup(newGroupDto()); + GroupDto group = dbTester.users().insertGroup(organization); dbTester.users().insertMember(group, user); - PermissionTemplateDto template = templateDb.insertTemplate(); - setDefaultTemplateUuid(template.getUuid()); + PermissionTemplateDto template = templateDb.insertTemplate(organization); + dbTester.organizations().setDefaultTemplates(organization, template.getUuid(), null); templateDb.addProjectCreatorToTemplate(template.getId(), SCAN_EXECUTION); templateDb.addUserToTemplate(template.getId(), user.getId(), UserRole.USER); templateDb.addGroupToTemplate(template.getId(), group.getId(), UserRole.CODEVIEWER); templateDb.addGroupToTemplate(template.getId(), null, UserRole.ISSUE_ADMIN); // authenticated user - checkWouldUserHavePermission(template.getOrganizationUuid(), user.getId(), UserRole.ADMIN, false); - checkWouldUserHavePermission(template.getOrganizationUuid(), user.getId(), SCAN_EXECUTION, true); - checkWouldUserHavePermission(template.getOrganizationUuid(), user.getId(), UserRole.USER, true); - checkWouldUserHavePermission(template.getOrganizationUuid(), user.getId(), UserRole.CODEVIEWER, true); - checkWouldUserHavePermission(template.getOrganizationUuid(), user.getId(), UserRole.ISSUE_ADMIN, true); + checkWouldUserHavePermission(organization, user.getId(), UserRole.ADMIN, false); + checkWouldUserHavePermission(organization, user.getId(), SCAN_EXECUTION, true); + checkWouldUserHavePermission(organization, user.getId(), UserRole.USER, true); + checkWouldUserHavePermission(organization, user.getId(), UserRole.CODEVIEWER, true); + checkWouldUserHavePermission(organization, user.getId(), UserRole.ISSUE_ADMIN, true); // anonymous user - checkWouldUserHavePermission(template.getOrganizationUuid(), null, UserRole.ADMIN, false); - checkWouldUserHavePermission(template.getOrganizationUuid(), null, SCAN_EXECUTION, false); - checkWouldUserHavePermission(template.getOrganizationUuid(), null, UserRole.USER, false); - checkWouldUserHavePermission(template.getOrganizationUuid(), null, UserRole.CODEVIEWER, false); - checkWouldUserHavePermission(template.getOrganizationUuid(), null, UserRole.ISSUE_ADMIN, true); + checkWouldUserHavePermission(organization, null, UserRole.ADMIN, false); + checkWouldUserHavePermission(organization, null, SCAN_EXECUTION, false); + checkWouldUserHavePermission(organization, null, UserRole.USER, false); + checkWouldUserHavePermission(organization, null, UserRole.CODEVIEWER, false); + checkWouldUserHavePermission(organization, null, UserRole.ISSUE_ADMIN, true); } @Test public void would_user_have_permission_with_unknown_default_permission_template() { - setDefaultTemplateUuid("UNKNOWN_TEMPLATE_UUID"); + dbTester.organizations().setDefaultTemplates(dbTester.getDefaultOrganization(), "UNKNOWN_TEMPLATE_UUID", null); - checkWouldUserHavePermission(dbTester.getDefaultOrganization().getUuid(), null, UserRole.ADMIN, false); + checkWouldUserHavePermission(dbTester.getDefaultOrganization(), null, UserRole.ADMIN, false); } @Test public void would_user_have_permission_with_empty_template() { - PermissionTemplateDto template = templateDb.insertTemplate(); - setDefaultTemplateUuid(template.getUuid()); - - checkWouldUserHavePermission(template.getOrganizationUuid(), null, UserRole.ADMIN, false); - } + PermissionTemplateDto template = templateDb.insertTemplate(dbTester.getDefaultOrganization()); + dbTester.organizations().setDefaultTemplates(dbTester.getDefaultOrganization(), template.getUuid(), null); - private void checkWouldUserHavePermission(String organizationUuid, @Nullable Long userId, String permission, boolean expectedResult) { - assertThat(underTest.wouldUserHavePermissionWithDefaultTemplate(session, organizationUuid, userId, permission, null, "PROJECT_KEY", Qualifiers.PROJECT)).isEqualTo(expectedResult); + checkWouldUserHavePermission(dbTester.getDefaultOrganization(), null, UserRole.ADMIN, false); } - private void checkAuthorizationUpdatedAtIsUpdated() { - assertThat(dbTester.getDbClient().componentDao().selectOrFailById(session, PROJECT.getId()).getAuthorizationUpdatedAt()).isEqualTo(NOW); + private void checkWouldUserHavePermission(OrganizationDto organization, @Nullable Long userId, String permission, boolean expectedResult) { + assertThat(underTest.wouldUserHavePermissionWithDefaultTemplate(session, organization.getUuid(), userId, permission, null, "PROJECT_KEY", Qualifiers.PROJECT)) + .isEqualTo(expectedResult); } - private void setDefaultTemplateUuid(String templateUuid) { - settings.setProperty("sonar.permission.template.default", templateUuid); + private void checkAuthorizationUpdatedAtIsUpdated(ComponentDto project) { + assertThat(dbTester.getDbClient().componentDao().selectOrFailById(session, project.getId()).getAuthorizationUpdatedAt()) + .isNotNull(); } } 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 89b839e86eb..565e55b0907 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 @@ -73,7 +73,7 @@ public abstract class BasePermissionWsTest { } protected ResourceTypesRule newRootResourceTypes() { - return new ResourceTypesRule().setRootQualifiers(Qualifiers.PROJECT, Qualifiers.VIEW, "DEV"); + return new ResourceTypesRule().setRootQualifiers(Qualifiers.PROJECT, Qualifiers.VIEW); } protected PermissionUpdater newPermissionUpdater() { @@ -110,11 +110,15 @@ public abstract class BasePermissionWsTest { return db.getDbClient().permissionTemplateDao().selectByName(db.getSession(), db.getDefaultOrganization().getUuid(), name); } - protected PermissionTemplateDto addTemplateToDefaultOrganization() { + protected PermissionTemplateDto addTemplate(OrganizationDto organizationDto) { PermissionTemplateDto dto = newPermissionTemplateDto() - .setOrganizationUuid(db.getDefaultOrganization().getUuid()); + .setOrganizationUuid(organizationDto.getUuid()); db.getDbClient().permissionTemplateDao().insert(db.getSession(), dto); db.commit(); return dto; } + + protected PermissionTemplateDto addTemplateToDefaultOrganization() { + return addTemplate(db.getDefaultOrganization()); + } } 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 0f0e343f919..ac26093eb35 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 @@ -23,12 +23,13 @@ import org.junit.Test; import org.sonar.core.platform.ComponentContainer; import static org.assertj.core.api.Assertions.assertThat; +import static org.sonar.core.platform.ComponentContainer.COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER; public class PermissionsWsModuleTest { @Test public void verify_count_of_added_components() { ComponentContainer container = new ComponentContainer(); new PermissionsWsModule().configure(container); - assertThat(container.size()).isEqualTo(2 + 28); + assertThat(container.size()).isEqualTo(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 27); } } 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 index 6bd549add74..87fc2067f07 100644 --- 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 @@ -64,6 +64,8 @@ public class ApplyTemplateActionTest extends BasePermissionWsTest { + @org.junit.Rule + public DefaultTemplatesResolverRule defaultTemplatesResolver = DefaultTemplatesResolverRule.withoutGovernance(); + private UserDto user1; private UserDto user2; private GroupDto group1; @@ -59,8 +60,8 @@ public class BulkApplyTemplateActionTest extends BasePermissionWsTest 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.setProperty(DEFAULT_TEMPLATE_PROPERTY, "default-template-uuid"); - underTest = new DefaultPermissionTemplateFinder(settings, resourceTypes); - - Set result = underTest.getDefaultTemplateUuids(); - - assertThat(result).containsOnly("default-template-uuid"); - } - - @Test - public void get_default_project_template_uuid_if_no_property_for_views() { - settings - .setProperty(DEFAULT_TEMPLATE_PROPERTY, "default-template-uuid") - .setProperty(defaultRootQualifierTemplateProperty(Qualifiers.PROJECT), "default-project-template-uuid") - .setProperty(defaultRootQualifierTemplateProperty("DEV"), "default-dev-template-uuid"); - - List result = underTest.getDefaultTemplatesByQualifier(); - - assertThat(result).extracting(TemplateUuidQualifier::getQualifier, TemplateUuidQualifier::getTemplateUuid) - .containsOnly( - tuple(Qualifiers.PROJECT, "default-project-template-uuid"), - tuple(Qualifiers.VIEW, "default-project-template-uuid"), - tuple("DEV", "default-dev-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/DefaultTemplatesResolverImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/DefaultTemplatesResolverImplTest.java new file mode 100644 index 00000000000..87f13c7f5fe --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/DefaultTemplatesResolverImplTest.java @@ -0,0 +1,77 @@ +/* + * 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.stream.Stream; +import org.junit.Test; +import org.sonar.api.resources.Qualifiers; +import org.sonar.api.resources.ResourceType; +import org.sonar.api.resources.ResourceTypeTree; +import org.sonar.api.resources.ResourceTypes; +import org.sonar.db.organization.DefaultTemplates; + +import static org.assertj.core.api.Assertions.assertThat; + +public class DefaultTemplatesResolverImplTest { + + private static final ResourceTypes RESOURCE_TYPES_WITHOUT_VIEWS = new ResourceTypes(new ResourceTypeTree[] { + ResourceTypeTree.builder().addType(ResourceType.builder(Qualifiers.PROJECT).build()).build() + }); + private static final ResourceTypes RESOURCE_TYPES_WITH_VIEWS = new ResourceTypes(new ResourceTypeTree[] { + ResourceTypeTree.builder().addType(ResourceType.builder(Qualifiers.PROJECT).build()).build(), + ResourceTypeTree.builder().addType(ResourceType.builder(Qualifiers.VIEW).build()).build() + }); + private DefaultTemplatesResolverImpl underTestWithoutViews = new DefaultTemplatesResolverImpl(RESOURCE_TYPES_WITHOUT_VIEWS); + private DefaultTemplatesResolverImpl underTestWithViews = new DefaultTemplatesResolverImpl(RESOURCE_TYPES_WITH_VIEWS); + + @Test + public void project_is_project_of_DefaultTemplates_no_matter_if_views_is_installed() { + Stream.of( + new DefaultTemplates().setProjectUuid("foo").setViewUuid(null), + new DefaultTemplates().setProjectUuid("foo").setViewUuid("bar")).forEach( + defaultTemplates -> { + assertThat(underTestWithoutViews.resolve(defaultTemplates).getProject()).isEqualTo("foo"); + assertThat(underTestWithViews.resolve(defaultTemplates).getProject()).isEqualTo("foo"); + }); + } + + @Test + public void view_is_empty_no_matter_view_in_DefaultTemplates_if_views_is_not_installed() { + DefaultTemplates defaultTemplatesNoView = new DefaultTemplates().setProjectUuid("foo").setViewUuid(null); + DefaultTemplates defaultTemplatesView = new DefaultTemplates().setProjectUuid("foo").setViewUuid("bar"); + + assertThat(underTestWithoutViews.resolve(defaultTemplatesNoView).getView()).isEmpty(); + assertThat(underTestWithoutViews.resolve(defaultTemplatesView).getView()).isEmpty(); + } + + @Test + public void view_is_project_of_DefaultTemplates_if_view_in_DefaultTemplates_is_null_and_views_is_installed() { + DefaultTemplates defaultTemplates = new DefaultTemplates().setProjectUuid("foo").setViewUuid(null); + + assertThat(underTestWithViews.resolve(defaultTemplates).getView()).contains("foo"); + } + + @Test + public void view_is_view_of_DefaultTemplates_if_view_in_DefaultTemplates_is_not_null_and_views_is_installed() { + DefaultTemplates defaultTemplates = new DefaultTemplates().setProjectUuid("foo").setViewUuid("bar"); + + assertThat(underTestWithViews.resolve(defaultTemplates).getView()).contains("bar"); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/DefaultTemplatesResolverRule.java b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/DefaultTemplatesResolverRule.java new file mode 100644 index 00000000000..0241a9feee6 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/DefaultTemplatesResolverRule.java @@ -0,0 +1,79 @@ +/* + * 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 org.junit.rules.ExternalResource; +import org.sonar.api.resources.Qualifiers; +import org.sonar.api.resources.ResourceType; +import org.sonar.api.resources.ResourceTypeTree; +import org.sonar.api.resources.ResourceTypes; +import org.sonar.db.organization.DefaultTemplates; + +public class DefaultTemplatesResolverRule extends ExternalResource implements DefaultTemplatesResolver { + private static final DefaultTemplatesResolver WITH_VIEWS = new DefaultTemplatesResolverImpl( + new ResourceTypes(new ResourceTypeTree[] { + ResourceTypeTree.builder() + .addType(ResourceType.builder(Qualifiers.PROJECT).build()) + .build(), + ResourceTypeTree.builder() + .addType(ResourceType.builder(Qualifiers.VIEW).build()) + .build()})); + private static final DefaultTemplatesResolver WITHOUT_VIEWS = new DefaultTemplatesResolverImpl( + new ResourceTypes(new ResourceTypeTree[] {ResourceTypeTree.builder() + .addType(ResourceType.builder(Qualifiers.PROJECT).build()) + .build()})); + + private final boolean governanceInitiallyInstalled; + private boolean governanceInstalled; + + private DefaultTemplatesResolverRule(boolean governanceInitiallyInstalled) { + this.governanceInitiallyInstalled = governanceInitiallyInstalled; + this.governanceInstalled = governanceInitiallyInstalled; + } + + @Override + protected void before() throws Throwable { + this.governanceInstalled = governanceInitiallyInstalled; + } + + public void installGovernance() { + this.governanceInstalled = true; + } + + public void uninstallGovernance() { + this.governanceInstalled = false; + } + + public static DefaultTemplatesResolverRule withoutGovernance() { + return new DefaultTemplatesResolverRule(false); + } + + public static DefaultTemplatesResolverRule withGovernance() { + return new DefaultTemplatesResolverRule(true); + } + + @Override + public DefaultTemplatesResolverImpl.ResolvedDefaultTemplates resolve(DefaultTemplates defaultTemplates) { + if (governanceInstalled) { + return WITH_VIEWS.resolve(defaultTemplates); + } + return WITHOUT_VIEWS.resolve(defaultTemplates); + } +} 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 index 7b13da6be19..cf621f8e255 100644 --- 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 @@ -19,126 +19,375 @@ */ package org.sonar.server.permission.ws.template; -import java.util.Collections; -import java.util.Date; +import java.util.Arrays; 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.resources.Qualifiers; +import org.sonar.api.utils.internal.AlwaysIncreasingSystem2; import org.sonar.api.web.UserRole; -import org.sonar.core.permission.GlobalPermissions; -import org.sonar.db.permission.template.PermissionTemplateCharacteristicDto; +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.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.BasePermissionWsTest; +import org.sonar.server.organization.TestDefaultOrganizationProvider; +import org.sonar.server.permission.ws.PermissionWsSupport; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.usergroups.ws.GroupWsSupport; import org.sonar.server.ws.TestRequest; import org.sonar.server.ws.TestResponse; +import org.sonar.server.ws.WsActionTester; -import static com.google.common.primitives.Longs.asList; 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.assertj.core.api.Assertions.fail; +import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN; +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; -public class DeleteTemplateActionTest extends BasePermissionWsTest { +public class DeleteTemplateActionTest { - private DefaultPermissionTemplateFinder defaultTemplatePermissionFinder = mock(DefaultPermissionTemplateFinder.class); - private PermissionTemplateDto template; + @Rule + public DbTester db = DbTester.create(new AlwaysIncreasingSystem2()); + @Rule + public ExpectedException expectedException = ExpectedException.none(); - @Override - protected DeleteTemplateAction buildWsAction() { - return new DeleteTemplateAction(db.getDbClient(), userSession, newPermissionWsSupport(), defaultTemplatePermissionFinder); - } + private UserSessionRule userSession = UserSessionRule.standalone(); + private DbClient dbClient = db.getDbClient(); + private final ResourceTypesRule resourceTypes = new ResourceTypesRule().setRootQualifiers(Qualifiers.PROJECT); + private final ResourceTypesRule resourceTypesWithViews = new ResourceTypesRule().setRootQualifiers(Qualifiers.PROJECT, Qualifiers.VIEW); + private DefaultTemplatesResolver defaultTemplatesResolver = new DefaultTemplatesResolverImpl(resourceTypes); + private DefaultTemplatesResolver defaultTemplatesResolverWithViews = new DefaultTemplatesResolverImpl(resourceTypesWithViews); + + private WsActionTester underTestWithoutViews; + private WsActionTester underTestWithViews; @Before - public void setUp() { - loginAsAdminOnDefaultOrganization(); - when(defaultTemplatePermissionFinder.getDefaultTemplateUuids()).thenReturn(Collections.emptySet()); - template = insertTemplateAndAssociatedPermissions(); + public void setUp() throws Exception { + GroupWsSupport groupWsSupport = new GroupWsSupport(dbClient, TestDefaultOrganizationProvider.from(db)); + this.underTestWithoutViews = new WsActionTester(new DeleteTemplateAction(dbClient, userSession, + new PermissionWsSupport(dbClient, new ComponentFinder(dbClient), groupWsSupport, resourceTypes), + defaultTemplatesResolver)); + this.underTestWithViews = new WsActionTester(new DeleteTemplateAction(dbClient, userSession, + new PermissionWsSupport(dbClient, new ComponentFinder(dbClient), groupWsSupport, resourceTypesWithViews), + defaultTemplatesResolverWithViews)); } @Test public void delete_template_in_db() throws Exception { - TestResponse result = newRequest(template.getUuid()); + runOnAllUnderTests((underTest) -> { + OrganizationDto organization = db.organizations().insert(); + PermissionTemplateDto template = insertTemplateAndAssociatedPermissions(organization); + db.organizations().setDefaultTemplates(organization, "foo", "bar"); + loginAsAdmin(organization); - assertThat(result.getInput()).isEmpty(); - assertThat(db.getDbClient().permissionTemplateDao().selectByUuid(db.getSession(), template.getUuid())).isNull(); + TestResponse result = newRequestByUuid(underTest, template.getUuid()); + + assertThat(result.getInput()).isEmpty(); + assertTemplateDoesNotExist(template); + }); } @Test public void delete_template_by_name_case_insensitive() throws Exception { - newRequest() - .setParam(PARAM_TEMPLATE_NAME, template.getName().toUpperCase()) - .execute(); + runOnAllUnderTests((underTest) -> { + OrganizationDto organization = db.organizations().insert(); + db.organizations().setDefaultTemplates(organization, "project def template uuid", "view def template uuid"); + PermissionTemplateDto template = insertTemplateAndAssociatedPermissions(organization); + loginAsAdmin(organization); + newRequestByName(underTest, organization, template); - assertThat(db.getDbClient().permissionTemplateDao().selectByUuid(db.getSession(), template.getUuid())).isNull(); + assertTemplateDoesNotExist(template); + }); + } + + @Test + public void delete_template_by_name_returns_empty_when_no_organization_is_provided_and_templates_does_not_belong_to_default_organization() throws Exception { + OrganizationDto organization = db.organizations().insert(); + db.organizations().setDefaultTemplates(organization, "project def template uuid", "view def template uuid"); + PermissionTemplateDto template = insertTemplateAndAssociatedPermissions(organization); + loginAsAdmin(organization); + + runOnAllUnderTests((underTest) -> { + try { + newRequestByName(underTest, null, template); + fail("NotFoundException should have been raised"); + } catch (NotFoundException e) { + assertThat(e).hasMessage("Permission template with name '" + template.getName() + "' is not found (case insensitive)"); + } + }); + } + + @Test + public void delete_template_by_name_returns_empty_when_wrong_organization_is_provided() throws Exception { + OrganizationDto organization = db.organizations().insert(); + db.organizations().setDefaultTemplates(organization, "project def template uuid", "view def template uuid"); + PermissionTemplateDto template = insertTemplateAndAssociatedPermissions(organization); + OrganizationDto otherOrganization = db.organizations().insert(); + loginAsAdmin(organization); + + runOnAllUnderTests((underTest) -> { + try { + newRequestByName(underTest, otherOrganization, template); + fail("NotFoundException should have been raised"); + } catch (NotFoundException e) { + assertThat(e).hasMessage("Permission template with name '" + template.getName() + "' is not found (case insensitive)"); + } + }); + } + + @Test + public void fail_if_uuid_is_not_known_without_views() throws Exception { + userSession.login(); + + expectedException.expect(NotFoundException.class); + + newRequestByUuid(underTestWithoutViews, "unknown-template-uuid"); } @Test - public void fail_if_uuid_is_not_known() throws Exception { + public void fail_if_uuid_is_not_known_with_views() throws Exception { + userSession.login(); + expectedException.expect(NotFoundException.class); - newRequest("unknown-template-uuid"); + newRequestByUuid(underTestWithViews, "unknown-template-uuid"); } @Test - public void fail_if_template_is_default() throws Exception { - when(defaultTemplatePermissionFinder.getDefaultTemplateUuids()).thenReturn(newSet(template.getUuid())); + public void fail_to_delete_by_uuid_if_template_is_default_template_for_project_without_views() throws Exception { + fail_to_delete_by_uuid_if_template_is_default_template_for_project(this.underTestWithoutViews); + } + + @Test + public void fail_to_delete_by_uuid_if_template_is_default_template_for_project_with_views() throws Exception { + fail_to_delete_by_uuid_if_template_is_default_template_for_project(this.underTestWithViews); + } + + private void fail_to_delete_by_uuid_if_template_is_default_template_for_project(WsActionTester underTest) throws Exception { + OrganizationDto organization = db.organizations().insert(); + PermissionTemplateDto template = insertTemplateAndAssociatedPermissions(organization); + db.organizations().setDefaultTemplates(organization, template.getUuid(), "view def template uuid"); + loginAsAdmin(organization); expectedException.expect(BadRequestException.class); - expectedException.expectMessage("It is not possible to delete a default template"); + expectedException.expectMessage("It is not possible to delete the default permission template for projects"); + + newRequestByUuid(underTest, template.getUuid()); + } + + @Test + public void fail_to_delete_by_name_if_template_is_default_template_for_project_without_views() throws Exception { + fail_to_delete_by_name_if_template_is_default_template_for_project(this.underTestWithoutViews); + } + + @Test + public void fail_to_delete_by_name_if_template_is_default_template_for_project_with_views() throws Exception { + fail_to_delete_by_name_if_template_is_default_template_for_project(this.underTestWithViews); + } + + private void fail_to_delete_by_name_if_template_is_default_template_for_project(WsActionTester underTest) throws Exception { + OrganizationDto organization = db.organizations().insert(); + PermissionTemplateDto template = insertTemplateAndAssociatedPermissions(organization); + db.organizations().setDefaultTemplates(organization, template.getUuid(), "view def template uuid"); + loginAsAdmin(organization); + + expectedException.expect(BadRequestException.class); + expectedException.expectMessage("It is not possible to delete the default permission template for projects"); + + newRequestByName(underTest, organization.getKey(), template.getName()); + } + + @Test + public void fail_to_delete_by_uuid_if_template_is_default_template_for_view_with_views() throws Exception { + OrganizationDto organization = db.organizations().insert(); + PermissionTemplateDto template = insertTemplateAndAssociatedPermissions(organization); + db.organizations().setDefaultTemplates(organization, "project def template uuid", template.getUuid()); + loginAsAdmin(organization); + + expectedException.expect(BadRequestException.class); + expectedException.expectMessage("It is not possible to delete the default permission template for views"); + + newRequestByUuid(this.underTestWithViews, template.getUuid()); + } + + @Test + public void default_template_for_views_can_be_deleted_by_uuid_if_views_is_not_installed_and_default_template_for_views_is_reset() throws Exception { + OrganizationDto organization = db.organizations().insert(); + PermissionTemplateDto template = insertTemplateAndAssociatedPermissions(organization); + db.organizations().setDefaultTemplates(organization, "project def template uuid", template.getUuid()); + loginAsAdmin(organization); + + newRequestByUuid(this.underTestWithoutViews, template.getUuid()); + + assertTemplateDoesNotExist(template); + + assertThat(db.getDbClient().organizationDao().getDefaultTemplates(db.getSession(), organization.getUuid()) + .get().getViewUuid()) + .isNull(); + } + + @Test + public void fail_to_delete_by_uuid_if_not_logged_in_without_views() throws Exception { + expectedException.expect(UnauthorizedException.class); + + newRequestByUuid(underTestWithoutViews, "uuid"); + } + + @Test + public void fail_to_delete_by_uuid_if_not_logged_in_with_views() throws Exception { + expectedException.expect(UnauthorizedException.class); - newRequest(template.getUuid()); + newRequestByUuid(underTestWithViews, "uuid"); } @Test - public void fail_if_not_logged_in() throws Exception { + public void fail_to_delete_by_name_if_not_logged_in_without_views() throws Exception { expectedException.expect(UnauthorizedException.class); - userSession.anonymous(); - newRequest(template.getUuid()); + newRequestByName(underTestWithoutViews, "whatever", "name"); } @Test - public void fail_if_not_admin() throws Exception { + public void fail_to_delete_by_name_if_not_logged_in_with_views() throws Exception { + expectedException.expect(UnauthorizedException.class); + + newRequestByName(underTestWithViews, "whatever", "name"); + } + + @Test + public void fail_to_delete_by_uuid_if_not_admin_without_views() throws Exception { + OrganizationDto organization = db.organizations().insert(); + PermissionTemplateDto template = insertTemplateAndAssociatedPermissions(organization); + userSession.login(); + + expectedException.expect(ForbiddenException.class); + + newRequestByUuid(underTestWithoutViews, template.getUuid()); + } + + @Test + public void fail_to_delete_by_uuid_if_not_admin_with_views() throws Exception { + OrganizationDto organization = db.organizations().insert(); + PermissionTemplateDto template = insertTemplateAndAssociatedPermissions(organization); + userSession.login(); + + expectedException.expect(ForbiddenException.class); + + newRequestByUuid(underTestWithViews, template.getUuid()); + } + + @Test + public void fail_to_delete_by_name_if_not_admin_without_views() throws Exception { + OrganizationDto organization = db.organizations().insert(); + PermissionTemplateDto template = db.permissionTemplates().insertTemplate(organization); + userSession.login(); + expectedException.expect(ForbiddenException.class); - userSession.login().setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); - newRequest(template.getUuid()); + newRequestByName(underTestWithoutViews, organization.getKey(), template.getName()); } @Test - public void fail_if_uuid_is_not_provided() throws Exception { + public void fail_to_delete_by_name_if_not_admin_with_views() throws Exception { + OrganizationDto organization = db.organizations().insert(); + PermissionTemplateDto template = db.permissionTemplates().insertTemplate(PermissionTemplateTesting.newPermissionTemplateDto() + .setOrganizationUuid(organization.getUuid()) + .setName("the name")); + userSession.login(); + + expectedException.expect(ForbiddenException.class); + + newRequestByName(underTestWithViews, organization, template); + } + + @Test + public void fail_if_neither_uuid_nor_name_is_provided_without_views() throws Exception { + userSession.login(); + expectedException.expect(BadRequestException.class); - newRequest(null); + newRequestByUuid(underTestWithoutViews, null); } @Test - public void delete_perm_tpl_characteristic_when_delete_template() throws Exception { - db.getDbClient().permissionTemplateCharacteristicDao().insert(db.getSession(), new PermissionTemplateCharacteristicDto() - .setPermission(UserRole.USER) - .setTemplateId(template.getId()) - .setWithProjectCreator(true) - .setCreatedAt(new Date().getTime()) - .setUpdatedAt(new Date().getTime())); - db.commit(); + public void fail_if_neither_uuid_nor_name_is_provided_with_views() throws Exception { + userSession.login(); - newRequest(template.getUuid()); + expectedException.expect(BadRequestException.class); - assertThat(db.getDbClient().permissionTemplateCharacteristicDao().selectByTemplateIds(db.getSession(), asList(template.getId()))).isEmpty(); + newRequestByUuid(underTestWithViews, null); } - private PermissionTemplateDto insertTemplateAndAssociatedPermissions() { - PermissionTemplateDto dto = addTemplateToDefaultOrganization(); + @Test + public void fail_if_both_uuid_and_name_are_provided_without_views() throws Exception { + userSession.login(); + + expectedException.expect(BadRequestException.class); + + underTestWithoutViews.newRequest().setMethod("POST") + .setParam(PARAM_TEMPLATE_ID, "uuid") + .setParam(PARAM_TEMPLATE_NAME, "name") + .execute(); + } + + @Test + public void fail_if_both_uuid_and_name_are_provided_with_views() throws Exception { + userSession.login(); + + expectedException.expect(BadRequestException.class); + + underTestWithViews.newRequest().setMethod("POST") + .setParam(PARAM_TEMPLATE_ID, "uuid") + .setParam(PARAM_TEMPLATE_NAME, "name") + .execute(); + } + + // @Test + // public void delete_perm_tpl_characteristic_when_delete_template() throws Exception { + // db.getDbClient().permissionTemplateCharacteristicDao().insert(db.getSession(), new PermissionTemplateCharacteristicDto() + // .setPermission(UserRole.USER) + // .setTemplateId(template.getId()) + // .setWithProjectCreator(true) + // .setCreatedAt(new Date().getTime()) + // .setUpdatedAt(new Date().getTime())); + // db.commit(); + // + // newRequest(template.getUuid()); + // + // assertThat(db.getDbClient().permissionTemplateCharacteristicDao().selectByTemplateIds(db.getSession(), + // asList(template.getId()))).isEmpty(); + // } + + private UserSessionRule loginAsAdmin(OrganizationDto organization) { + return userSession.login().addOrganizationPermission(organization.getUuid(), SYSTEM_ADMIN); + } + + private void runOnAllUnderTests(ConsumerWithException consumer) throws Exception { + for (WsActionTester underTest : Arrays.asList(underTestWithoutViews, underTestWithViews)) { + consumer.accept(underTest); + } + } + + private interface ConsumerWithException { + void accept(T e) throws Exception; + } + + private PermissionTemplateDto insertTemplateAndAssociatedPermissions(OrganizationDto organization) { + PermissionTemplateDto dto = db.permissionTemplates().insertTemplate(organization); UserDto user = db.getDbClient().userDao().insert(db.getSession(), UserTesting.newUserDto().setActive(true)); GroupDto group = db.getDbClient().groupDao().insert(db.getSession(), GroupTesting.newGroupDto()); db.getDbClient().permissionTemplateDao().insertUserPermission(db.getSession(), dto.getId(), user.getId(), UserRole.ADMIN); @@ -147,13 +396,36 @@ public class DeleteTemplateActionTest extends BasePermissionWsTest { @@ -58,39 +54,41 @@ public class SearchTemplatesActionTest extends BasePermissionWsTest { + private DbClient dbClient = db.getDbClient(); private I18nRule i18n = new I18nRule(); - private PersistentSettings persistentSettings = new PersistentSettings(new MapSettings(), db.getDbClient(), new SettingsChangeNotifier()); - private PermissionTemplateDto template; @Override protected SetDefaultTemplateAction buildWsAction() { - return new SetDefaultTemplateAction(db.getDbClient(), newPermissionWsSupport(), newRootResourceTypes(), persistentSettings, userSession, i18n); + return new SetDefaultTemplateAction(db.getDbClient(), newPermissionWsSupport(), newRootResourceTypes(), userSession, i18n); } - @Before - public void setUp() { - DbClient dbClient = db.getDbClient(); - 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"); - loginAsAdminOnDefaultOrganization(); - - template = dbClient.permissionTemplateDao().insert(db.getSession(), PermissionTemplateTesting.newPermissionTemplateDto() - .setOrganizationUuid(db.getDefaultOrganization().getUuid()) - .setUuid("permission-template-uuid")); - db.commit(); + @Test + public void update_project_default_template() throws Exception { + db.organizations().setDefaultTemplates(db.getDefaultOrganization(), "project-template-uuid", "view-template-uuid"); + PermissionTemplateDto template = insertTemplate(db.getDefaultOrganization()); + loginAsAdmin(db.getDefaultOrganization()); + + newRequest(template.getUuid(), Qualifiers.PROJECT); + + assertDefaultTemplates(db.getDefaultOrganization(), template.getUuid(), "view-template-uuid"); } @Test - public void update_settings_for_project_qualifier() throws Exception { + public void update_project_default_template_without_qualifier_param() throws Exception { + OrganizationDto organization = db.organizations().insert(); + db.organizations().setDefaultTemplates(organization, "any-project-template-uuid", "any-view-template-uuid"); + PermissionTemplateDto template = insertTemplate(organization); + loginAsAdmin(organization); + // default value is project qualifier's value - String result = newRequest(template.getUuid(), null); + 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"); + assertDefaultTemplates(organization, template.getUuid(), "any-view-template-uuid"); } @Test - public void update_settings_for_project_qualifier_by_template_name() throws Exception { + public void update_project_default_template_by_template_name() throws Exception { + OrganizationDto organization = db.organizations().insert(); + db.organizations().setDefaultTemplates(organization, "bar", "roh"); + PermissionTemplateDto template = insertTemplate(organization); + loginAsAdmin(organization); + newRequest() + .setParam(PARAM_ORGANIZATION_KEY, organization.getKey()) .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"); + assertDefaultTemplates(organization, template.getUuid(), "roh"); } @Test - public void update_settings_of_views_property() throws Exception { + public void update_view_default_template() throws Exception { + OrganizationDto organization = db.organizations().insert(); + db.organizations().setDefaultTemplates(organization, "foo", null); + PermissionTemplateDto template = insertTemplate(organization); + loginAsAdmin(organization); + 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"); + assertDefaultTemplates(organization, "foo", template.getUuid()); } @Test public void fail_if_anonymous() throws Exception { - expectedException.expect(UnauthorizedException.class); + OrganizationDto organization = db.organizations().insert(); + PermissionTemplateDto template = insertTemplate(organization); userSession.anonymous(); + expectedException.expect(UnauthorizedException.class); + newRequest(template.getUuid(), PROJECT); } @Test public void fail_if_not_admin() throws Exception { - expectedException.expect(ForbiddenException.class); + OrganizationDto organization = db.organizations().insert(); + PermissionTemplateDto template = insertTemplate(organization); userSession.login().setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); - newRequest(template.getUuid(), PROJECT); + expectedException.expect(ForbiddenException.class); + + newRequest(template.getUuid(), null); } @Test @@ -140,12 +145,28 @@ public class SetDefaultTemplateActionTest extends BasePermissionWsTest new IllegalStateException("No default templates for organization with uuid '" + organizationDto.getUuid() + "'")); + + assertThat(defaultTemplates.getProjectUuid()).isEqualTo(projectDefaultTemplateUuid); + assertThat(defaultTemplates.getViewUuid()).isEqualTo(viewDefaultTemplateUuid); + } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/project/ws/CreateActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/project/ws/CreateActionTest.java index 102916b9b7e..988ce6aad6f 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/project/ws/CreateActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/project/ws/CreateActionTest.java @@ -28,7 +28,6 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.sonar.api.config.MapSettings; -import org.sonar.api.config.Settings; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.System2; import org.sonar.db.DbTester; @@ -50,6 +49,7 @@ import org.sonar.server.organization.DefaultOrganizationProvider; import org.sonar.server.organization.TestDefaultOrganizationProvider; import org.sonar.server.permission.PermissionTemplateService; import org.sonar.server.permission.index.PermissionIndexer; +import org.sonar.server.permission.ws.template.DefaultTemplatesResolverRule; import org.sonar.server.tester.UserSessionRule; import org.sonar.server.ws.TestRequest; import org.sonar.server.ws.WsActionTester; @@ -79,30 +79,25 @@ public class CreateActionTest { @Rule public ExpectedException expectedException = ExpectedException.none(); - @Rule public DbTester db = DbTester.create(system2); - @Rule public EsTester es = new EsTester(new ComponentIndexDefinition(new MapSettings()), new ProjectMeasuresIndexDefinition(new MapSettings())); - @Rule public UserSessionRule userSession = UserSessionRule.standalone(); - @Rule public I18nRule i18n = new I18nRule().put("qualifier.TRK", "Project"); - - private Settings settings = new MapSettings(); + @Rule + public DefaultTemplatesResolverRule defaultTemplatesResolver = DefaultTemplatesResolverRule.withoutGovernance(); private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db); - private PermissionTemplateDto permissionTemplateDto; private WsActionTester ws = new WsActionTester( new CreateAction( db.getDbClient(), userSession, new ComponentUpdater(db.getDbClient(), i18n, system2, - new PermissionTemplateService(db.getDbClient(), settings, new PermissionIndexer(db.getDbClient(), es.client()), userSession), + new PermissionTemplateService(db.getDbClient(), new PermissionIndexer(db.getDbClient(), es.client()), userSession, defaultTemplatesResolver), new FavoriteUpdater(db.getDbClient()), new ProjectMeasuresIndexer(system2, db.getDbClient(), es.client()), new ComponentIndexer(db.getDbClient(), es.client())), @@ -111,7 +106,7 @@ public class CreateActionTest { @Before public void setUp() throws Exception { permissionTemplateDto = db.permissionTemplates().insertTemplate(db.getDefaultOrganization()); - setTemplateAsDefault(permissionTemplateDto); + db.organizations().setDefaultTemplates(db.getDefaultOrganization(), permissionTemplateDto.getUuid(), null); } @Test @@ -315,8 +310,4 @@ public class CreateActionTest { } } - private void setTemplateAsDefault(PermissionTemplateDto permissionTemplateDto) { - settings.appendProperty("sonar.permission.template.default", permissionTemplateDto.getUuid()); - } - } diff --git a/server/sonar-server/src/test/java/org/sonar/server/startup/RegisterPermissionTemplatesTest.java b/server/sonar-server/src/test/java/org/sonar/server/startup/RegisterPermissionTemplatesTest.java index 7f6a53c4e86..e917164c62c 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/startup/RegisterPermissionTemplatesTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/startup/RegisterPermissionTemplatesTest.java @@ -21,44 +21,34 @@ package org.sonar.server.startup; import java.util.List; import java.util.Objects; +import java.util.Optional; import org.junit.Rule; import org.junit.Test; -import org.sonar.api.resources.Qualifiers; import org.sonar.api.security.DefaultGroups; import org.sonar.api.utils.System2; import org.sonar.api.utils.log.LogTester; import org.sonar.api.utils.log.LoggerLevel; import org.sonar.api.web.UserRole; import org.sonar.db.DbTester; -import org.sonar.db.loadedtemplate.LoadedTemplateDto; +import org.sonar.db.organization.DefaultTemplates; import org.sonar.db.permission.template.PermissionTemplateDto; import org.sonar.db.permission.template.PermissionTemplateGroupDto; import org.sonar.server.organization.DefaultOrganizationProvider; import org.sonar.server.organization.TestDefaultOrganizationProvider; -import org.sonar.server.platform.PersistentSettings; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.sonar.server.permission.DefaultPermissionTemplates.DEFAULT_TEMPLATE_KEY; -import static org.sonar.server.permission.DefaultPermissionTemplates.DEFAULT_TEMPLATE_PROPERTY; -import static org.sonar.server.permission.DefaultPermissionTemplates.defaultRootQualifierTemplateProperty; +import static org.sonar.db.permission.template.PermissionTemplateTesting.newPermissionTemplateDto; public class RegisterPermissionTemplatesTest { + private static final String DEFAULT_TEMPLATE_UUID = "default_template"; @Rule public DbTester db = DbTester.create(System2.INSTANCE); - @Rule public LogTester logTester = new LogTester(); - private PersistentSettings settings = mock(PersistentSettings.class); private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db); - private RegisterPermissionTemplates underTest = new RegisterPermissionTemplates(db.getDbClient(), settings, defaultOrganizationProvider); + private RegisterPermissionTemplates underTest = new RegisterPermissionTemplates(db.getDbClient(), defaultOrganizationProvider); @Test public void insert_default_permission_template_if_fresh_install() { @@ -76,8 +66,7 @@ public class RegisterPermissionTemplatesTest { expectGroupPermission(groupPermissions, UserRole.CODEVIEWER, DefaultGroups.ANYONE); expectGroupPermission(groupPermissions, UserRole.USER, DefaultGroups.ANYONE); - // template is marked as default - verify(settings).saveProperty(DEFAULT_TEMPLATE_PROPERTY, defaultTemplate.getUuid()); + verifyDefaultTemplates(); assertThat(logTester.logs(LoggerLevel.ERROR)).isEmpty(); } @@ -94,39 +83,36 @@ public class RegisterPermissionTemplatesTest { expectGroupPermission(groupPermissions, UserRole.CODEVIEWER, DefaultGroups.ANYONE); expectGroupPermission(groupPermissions, UserRole.USER, DefaultGroups.ANYONE); - // marked as default - verify(settings).saveProperty(DEFAULT_TEMPLATE_PROPERTY, defaultTemplate.getUuid()); + verifyDefaultTemplates(); assertThat(logTester.logs(LoggerLevel.ERROR)).contains("Cannot setup default permission for group: sonar-administrators"); } @Test - public void do_not_create_default_template_if_already_exists() { - markTaskAsAlreadyExecuted(); + public void do_not_create_default_template_if_already_exists_but_register_when_it_is_not() { + db.permissionTemplates().insertTemplate(newPermissionTemplateDto() + .setOrganizationUuid(db.getDefaultOrganization().getUuid()) + .setUuid(DEFAULT_TEMPLATE_UUID)); underTest.start(); - assertThat(selectTemplate()).isNull(); - verify(settings, never()).saveProperty(eq(DEFAULT_TEMPLATE_PROPERTY), anyString()); - assertThat(logTester.logs(LoggerLevel.ERROR)).isEmpty(); + verifyDefaultTemplates(); } @Test - public void reference_TRK_template_as_default_when_present() { - when(settings.getString(defaultRootQualifierTemplateProperty(Qualifiers.PROJECT))).thenReturn("my_projects_template"); - markTaskAsAlreadyExecuted(); + public void do_not_fail_if_default_template_exists_and_is_registered() { + db.permissionTemplates().insertTemplate(newPermissionTemplateDto() + .setOrganizationUuid(db.getDefaultOrganization().getUuid()) + .setUuid(DEFAULT_TEMPLATE_UUID)); + db.organizations().setDefaultTemplates(db.getDefaultOrganization(), DEFAULT_TEMPLATE_UUID, null); underTest.start(); - verify(settings).saveProperty(DEFAULT_TEMPLATE_PROPERTY, "my_projects_template"); - } - - private void markTaskAsAlreadyExecuted() { - db.getDbClient().loadedTemplateDao().insert(new LoadedTemplateDto(DEFAULT_TEMPLATE_KEY, LoadedTemplateDto.PERMISSION_TEMPLATE_TYPE)); + verifyDefaultTemplates(); } private PermissionTemplateDto selectTemplate() { - return db.getDbClient().permissionTemplateDao().selectByUuid(db.getSession(), DEFAULT_TEMPLATE_KEY); + return db.getDbClient().permissionTemplateDao().selectByUuid(db.getSession(), DEFAULT_TEMPLATE_UUID); } private List selectGroupPermissions(PermissionTemplateDto template) { @@ -139,4 +125,11 @@ public class RegisterPermissionTemplatesTest { groupPermissions.stream().anyMatch(gp -> gp.getPermission().equals(expectedPermission) && Objects.equals(gp.getGroupName(), expectedGroupName))) .isTrue(); } + + private void verifyDefaultTemplates() { + Optional defaultTemplates = db.getDbClient().organizationDao().getDefaultTemplates(db.getSession(), db.getDefaultOrganization().getUuid()); + assertThat(defaultTemplates) + .isPresent(); + assertThat(defaultTemplates.get().getProjectUuid()).isEqualTo(DEFAULT_TEMPLATE_UUID); + } } diff --git a/server/sonar-server/src/test/resources/org/sonar/server/permission/PermissionTemplateServiceTest/apply_default_permission_template_by_component_id-result.xml b/server/sonar-server/src/test/resources/org/sonar/server/permission/PermissionTemplateServiceTest/apply_default_permission_template_by_component_id-result.xml deleted file mode 100644 index c0a3eef5b84..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/permission/PermissionTemplateServiceTest/apply_default_permission_template_by_component_id-result.xml +++ /dev/null @@ -1,115 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/server/sonar-server/src/test/resources/org/sonar/server/permission/PermissionTemplateServiceTest/apply_default_permission_template_by_component_id.xml b/server/sonar-server/src/test/resources/org/sonar/server/permission/PermissionTemplateServiceTest/apply_default_permission_template_by_component_id.xml deleted file mode 100644 index 3e46a6e11a3..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/permission/PermissionTemplateServiceTest/apply_default_permission_template_by_component_id.xml +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/server/sonar-server/src/test/resources/org/sonar/server/permission/PermissionTemplateServiceTest/should_apply_permission_template-result.xml b/server/sonar-server/src/test/resources/org/sonar/server/permission/PermissionTemplateServiceTest/should_apply_permission_template-result.xml deleted file mode 100644 index 7667cf5e407..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/permission/PermissionTemplateServiceTest/should_apply_permission_template-result.xml +++ /dev/null @@ -1,109 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/server/sonar-server/src/test/resources/org/sonar/server/permission/ws/template/SearchTemplatesActionTest/display_all_project_permissions.json b/server/sonar-server/src/test/resources/org/sonar/server/permission/ws/template/SearchTemplatesActionTest/display_all_project_permissions.json index 5e6ebd09de0..e69de29bb2d 100644 --- a/server/sonar-server/src/test/resources/org/sonar/server/permission/ws/template/SearchTemplatesActionTest/display_all_project_permissions.json +++ b/server/sonar-server/src/test/resources/org/sonar/server/permission/ws/template/SearchTemplatesActionTest/display_all_project_permissions.json @@ -1,29 +0,0 @@ -{ - "permissions": [ - { - "key": "admin", - "name": "Administer", - "description": "Ability to access project settings and perform administration tasks. (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)" - }, - { - "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": "scan", - "name": "Execute Analysis", - "description": "Ability to execute analyses, and to get all settings required to perform the analysis, even the secured ones like the scm account password, the jira account password, and so on." - }, - { - "key": "user", - "name": "Browse", - "description": "Ability to access a project, browse its measures, and create/edit issues for it." - } - ] -} 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 index a3041228330..e69de29bb2d 100644 --- 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 @@ -1,17 +0,0 @@ -{ - "permissionTemplates": [], - "defaultTemplates": [ - { - "templateId": "AU-Tpxb--iU5OvuD2FLy", - "qualifier": "TRK" - }, - { - "templateId": "AU-TpxcA-iU5OvuD2FLz", - "qualifier": "VW" - }, - { - "templateId": "AU-TpxcA-iU5OvuD2FL0", - "qualifier": "DEV" - } - ] -} diff --git a/sonar-db/src/main/java/org/sonar/db/organization/DefaultTemplates.java b/sonar-db/src/main/java/org/sonar/db/organization/DefaultTemplates.java index 6a7b4ef288c..c6a0a1a619b 100644 --- a/sonar-db/src/main/java/org/sonar/db/organization/DefaultTemplates.java +++ b/sonar-db/src/main/java/org/sonar/db/organization/DefaultTemplates.java @@ -25,35 +25,39 @@ import javax.annotation.Nullable; import static java.util.Objects.requireNonNull; public class DefaultTemplates { - private String project; - private String view; + private String projectUuid; + private String viewUuid; - @CheckForNull - public String getProject() { - return project; + public String getProjectUuid() { + checkProjectNotNull(this.projectUuid); + return this.projectUuid; } - public DefaultTemplates setProject(String project) { - requireNonNull(project, "project default template can't be null"); - this.project = project; + public DefaultTemplates setProjectUuid(String projectUuid) { + checkProjectNotNull(projectUuid); + this.projectUuid = projectUuid; return this; } + private static void checkProjectNotNull(String project) { + requireNonNull(project, "defaultTemplates.project can't be null"); + } + @CheckForNull - public String getView() { - return view; + public String getViewUuid() { + return viewUuid; } - public DefaultTemplates setView(@Nullable String view) { - this.view = view; + public DefaultTemplates setViewUuid(@Nullable String viewUuid) { + this.viewUuid = viewUuid; return this; } @Override public String toString() { return "DefaultTemplates{" + - "project='" + project + '\'' + - ", view='" + view + '\'' + + "projectUuid='" + projectUuid + '\'' + + ", viewUuid='" + viewUuid + '\'' + '}'; } } diff --git a/sonar-db/src/main/java/org/sonar/db/organization/OrganizationDao.java b/sonar-db/src/main/java/org/sonar/db/organization/OrganizationDao.java index 17ee6afe7a8..04ead578809 100644 --- a/sonar-db/src/main/java/org/sonar/db/organization/OrganizationDao.java +++ b/sonar-db/src/main/java/org/sonar/db/organization/OrganizationDao.java @@ -115,6 +115,6 @@ public class OrganizationDao implements Dao { private static void checkDefaultTemplates(DefaultTemplates defaultTemplates) { requireNonNull(defaultTemplates, "defaultTemplates can't be null"); - requireNonNull(defaultTemplates.getProject(), "defaultTemplates.project can't be null"); + requireNonNull(defaultTemplates.getProjectUuid()); } } diff --git a/sonar-db/src/main/resources/org/sonar/db/organization/OrganizationMapper.xml b/sonar-db/src/main/resources/org/sonar/db/organization/OrganizationMapper.xml index 15de61bfaaa..6b39c43e7f0 100644 --- a/sonar-db/src/main/resources/org/sonar/db/organization/OrganizationMapper.xml +++ b/sonar-db/src/main/resources/org/sonar/db/organization/OrganizationMapper.xml @@ -14,8 +14,8 @@ - org.default_perm_template_project as "project", - org.default_perm_template_view as "view" + org.default_perm_template_project as "projectUuid", + org.default_perm_template_view as "viewUuid"