Browse Source

SONAR-8690 read and write default templates from ORGANIZATIONS table

tags/6.3-RC1
Sébastien Lesaint 7 years ago
parent
commit
a50808c9a3
45 changed files with 1135 additions and 1136 deletions
  1. 2
    0
      server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java
  2. 1
    1
      server/sonar-ce/src/test/java/org/sonar/ce/container/ComputeEngineContainerImplTest.java
  3. 2
    1
      server/sonar-server/src/main/java/org/sonar/server/component/ComponentUpdater.java
  4. 0
    36
      server/sonar-server/src/main/java/org/sonar/server/permission/DefaultPermissionTemplates.java
  5. 22
    12
      server/sonar-server/src/main/java/org/sonar/server/permission/PermissionTemplateService.java
  6. 1
    3
      server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionsWsModule.java
  7. 0
    119
      server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/DefaultPermissionTemplateFinder.java
  8. 60
    0
      server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/DefaultTemplatesResolver.java
  9. 52
    0
      server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/DefaultTemplatesResolverImpl.java
  10. 40
    9
      server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/DeleteTemplateAction.java
  11. 13
    6
      server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/SearchTemplatesAction.java
  12. 6
    6
      server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/SearchTemplatesData.java
  13. 12
    6
      server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/SearchTemplatesDataLoader.java
  14. 20
    10
      server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/SetDefaultTemplateAction.java
  15. 2
    0
      server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java
  16. 28
    55
      server/sonar-server/src/main/java/org/sonar/server/startup/RegisterPermissionTemplates.java
  17. 1
    19
      server/sonar-server/src/main/resources/org/sonar/server/permission/ws/search_project_permissions-example.json
  18. 0
    43
      server/sonar-server/src/main/resources/org/sonar/server/permission/ws/template/search_templates-example.json
  19. 7
    12
      server/sonar-server/src/test/java/org/sonar/server/component/ComponentUpdaterTest.java
  20. 65
    67
      server/sonar-server/src/test/java/org/sonar/server/permission/PermissionTemplateServiceTest.java
  21. 7
    3
      server/sonar-server/src/test/java/org/sonar/server/permission/ws/BasePermissionWsTest.java
  22. 2
    1
      server/sonar-server/src/test/java/org/sonar/server/permission/ws/PermissionsWsModuleTest.java
  23. 3
    1
      server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/ApplyTemplateActionTest.java
  24. 9
    10
      server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/BulkApplyTemplateActionTest.java
  25. 0
    99
      server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/DefaultPermissionTemplateFinderTest.java
  26. 77
    0
      server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/DefaultTemplatesResolverImplTest.java
  27. 79
    0
      server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/DefaultTemplatesResolverRule.java
  28. 327
    55
      server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/DeleteTemplateActionTest.java
  29. 115
    68
      server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/SearchTemplatesActionTest.java
  30. 1
    2
      server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/SearchTemplatesDataTest.java
  31. 82
    43
      server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/SetDefaultTemplateActionTest.java
  32. 5
    14
      server/sonar-server/src/test/java/org/sonar/server/project/ws/CreateActionTest.java
  33. 26
    33
      server/sonar-server/src/test/java/org/sonar/server/startup/RegisterPermissionTemplatesTest.java
  34. 0
    115
      server/sonar-server/src/test/resources/org/sonar/server/permission/PermissionTemplateServiceTest/apply_default_permission_template_by_component_id-result.xml
  35. 0
    99
      server/sonar-server/src/test/resources/org/sonar/server/permission/PermissionTemplateServiceTest/apply_default_permission_template_by_component_id.xml
  36. 0
    109
      server/sonar-server/src/test/resources/org/sonar/server/permission/PermissionTemplateServiceTest/should_apply_permission_template-result.xml
  37. 0
    29
      server/sonar-server/src/test/resources/org/sonar/server/permission/ws/template/SearchTemplatesActionTest/display_all_project_permissions.json
  38. 0
    17
      server/sonar-server/src/test/resources/org/sonar/server/permission/ws/template/SearchTemplatesActionTest/empty.json
  39. 18
    14
      sonar-db/src/main/java/org/sonar/db/organization/DefaultTemplates.java
  40. 1
    1
      sonar-db/src/main/java/org/sonar/db/organization/OrganizationDao.java
  41. 4
    4
      sonar-db/src/main/resources/org/sonar/db/organization/OrganizationMapper.xml
  42. 15
    7
      sonar-db/src/test/java/org/sonar/db/organization/DefaultTemplatesTest.java
  43. 7
    7
      sonar-db/src/test/java/org/sonar/db/organization/OrganizationDaoTest.java
  44. 9
    0
      sonar-db/src/test/java/org/sonar/db/organization/OrganizationDbTester.java
  45. 14
    0
      sonar-db/src/test/java/org/sonar/db/permission/template/PermissionTemplateDbTester.java

+ 2
- 0
server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java View File

@@ -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,

+ 1
- 1
server/sonar-ce/src/test/java/org/sonar/ce/container/ComputeEngineContainerImplTest.java View File

@@ -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

+ 2
- 1
server/sonar-server/src/main/java/org/sonar/server/component/ComponentUpdater.java View File

@@ -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);
}
}

+ 0
- 36
server/sonar-server/src/main/java/org/sonar/server/permission/DefaultPermissionTemplates.java View File

@@ -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);
}
}

+ 22
- 12
server/sonar-server/src/main/java/org/sonar/server/permission/PermissionTemplateService.java View File

@@ -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<PermissionTemplateDto> matchingTemplates) {

+ 1
- 3
server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionsWsModule.java View File

@@ -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);
}
}

+ 0
- 119
server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/DefaultPermissionTemplateFinder.java View File

@@ -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<String> getDefaultTemplateUuids() {
return from(resourceTypes.getRoots())
.transform(ResourceType::getQualifier)
.transform(new QualifierToDefaultTemplate(settings))
.toSortedSet(natural());
}

public List<TemplateUuidQualifier> 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<String, String> {
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<String, TemplateUuidQualifier> {
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;
}
}

}

+ 60
- 0
server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/DefaultTemplatesResolver.java View File

@@ -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}.
* <ul>
* <li>{@link ResolvedDefaultTemplates#project} is always the same as {@link DefaultTemplates#projectUuid}</li>
* <li>when Governance is not installed, {@link ResolvedDefaultTemplates#view} is always {@code null}</li>
* <li>when Governance is not installed, {@link ResolvedDefaultTemplates#view} is {@link DefaultTemplates#viewUuid}
* when it is non {@code null}, otherwise it is {@link DefaultTemplates#projectUuid}</li>
* </ul>
*/
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<String> getView() {
return ofNullable(view);
}
}
}

+ 52
- 0
server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/DefaultTemplatesResolverImpl.java View File

@@ -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);
}

}

+ 40
- 9
server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/DeleteTemplateAction.java View File

@@ -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<String> defaultTemplateUuids = defaultPermissionTemplateFinder.getDefaultTemplateUuids();
checkRequest(!defaultTemplateUuids.contains(key), "It is not possible to delete a default template");
}
}

+ 13
- 6
server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/SearchTemplatesAction.java View File

@@ -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) {

+ 6
- 6
server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/SearchTemplatesData.java View File

@@ -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<PermissionTemplateDto> templates;
private final List<TemplateUuidQualifier> defaultTemplates;
private final ResolvedDefaultTemplates defaultTemplates;
private final Table<Long, String, Integer> userCountByTemplateIdAndPermission;
private final Table<Long, String, Integer> groupCountByTemplateIdAndPermission;
private final Table<Long, String, Boolean> 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<TemplateUuidQualifier> defaultTemplates() {
public ResolvedDefaultTemplates defaultTemplates() {
return defaultTemplates;
}

@@ -70,7 +70,7 @@ class SearchTemplatesData {

public static class Builder {
private List<PermissionTemplateDto> templates;
private List<TemplateUuidQualifier> defaultTemplates;
private ResolvedDefaultTemplates defaultTemplates;
private Table<Long, String, Integer> userCountByTemplateIdAndPermission;
private Table<Long, String, Integer> groupCountByTemplateIdAndPermission;
private Table<Long, String, Boolean> withProjectCreatorByTemplateIdAndPermission;
@@ -94,7 +94,7 @@ class SearchTemplatesData {
return this;
}

public Builder defaultTemplates(List<TemplateUuidQualifier> defaultTemplates) {
public Builder defaultTemplates(ResolvedDefaultTemplates defaultTemplates) {
this.defaultTemplates = defaultTemplates;
return this;
}

+ 12
- 6
server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/SearchTemplatesDataLoader.java View File

@@ -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<PermissionTemplateDto> templates = searchTemplates(dbSession, request);
List<Long> templateIds = Lists.transform(templates, PermissionTemplateDto::getId);
List<TemplateUuidQualifier> 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));

+ 20
- 10
server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/SetDefaultTemplateAction.java View File

@@ -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);
}
}

+ 2
- 0
server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java View File

@@ -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,

+ 28
- 55
server/sonar-server/src/main/java/org/sonar/server/startup/RegisterPermissionTemplates.java View File

@@ -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> 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);
}
}

+ 1
- 19
server/sonar-server/src/main/resources/org/sonar/server/permission/ws/search_project_permissions-example.json View File

@@ -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",

+ 0
- 43
server/sonar-server/src/main/resources/org/sonar/server/permission/ws/template/search_templates-example.json View File

@@ -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"
}
]
}

+ 7
- 12
server/sonar-server/src/test/java/org/sonar/server/component/ComponentUpdaterTest.java View File

@@ -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());
}

}

+ 65
- 67
server/sonar-server/src/test/java/org/sonar/server/permission/PermissionTemplateServiceTest.java View File

@@ -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<String> selectProjectPermissionsOfGroup(String organizationUuid, @Nullable Long groupId, ComponentDto project) {
private List<String> 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<String> selectProjectPermissionsOfUser(long userId, ComponentDto project) {
private List<String> 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();
}

}

+ 7
- 3
server/sonar-server/src/test/java/org/sonar/server/permission/ws/BasePermissionWsTest.java View File

@@ -73,7 +73,7 @@ public abstract class BasePermissionWsTest<A extends PermissionsWsAction> {
}

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<A extends PermissionsWsAction> {
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());
}
}

+ 2
- 1
server/sonar-server/src/test/java/org/sonar/server/permission/ws/PermissionsWsModuleTest.java View File

@@ -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);
}
}

+ 3
- 1
server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/ApplyTemplateActionTest.java View File

@@ -64,6 +64,8 @@ public class ApplyTemplateActionTest extends BasePermissionWsTest<ApplyTemplateA
new IssueIndexDefinition(new MapSettings()),
new ProjectMeasuresIndexDefinition(new MapSettings()),
new ComponentIndexDefinition(new MapSettings()));
@Rule
public DefaultTemplatesResolverRule defaultTemplatesResolver = DefaultTemplatesResolverRule.withoutGovernance();

private UserDto user1;
private UserDto user2;
@@ -78,7 +80,7 @@ public class ApplyTemplateActionTest extends BasePermissionWsTest<ApplyTemplateA
@Override
protected ApplyTemplateAction buildWsAction() {
PermissionTemplateService permissionTemplateService = new PermissionTemplateService(db.getDbClient(),
new MapSettings(), permissionIndexer, userSession);
permissionIndexer, userSession, defaultTemplatesResolver);
return new ApplyTemplateAction(db.getDbClient(), userSession, permissionTemplateService, newPermissionWsSupport());
}


+ 9
- 10
server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/BulkApplyTemplateActionTest.java View File

@@ -22,7 +22,6 @@ package org.sonar.server.permission.ws.template;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.sonar.api.config.MapSettings;
import org.sonar.api.server.ws.WebService.Param;
import org.sonar.api.web.UserRole;
import org.sonar.db.component.ComponentDto;
@@ -40,7 +39,6 @@ import org.sonar.server.permission.ws.BasePermissionWsTest;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.sonar.db.component.ComponentTesting.newDeveloper;
import static org.sonar.db.component.ComponentTesting.newProjectDto;
import static org.sonar.db.component.ComponentTesting.newView;
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_QUALIFIER;
@@ -49,6 +47,9 @@ import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_T

public class BulkApplyTemplateActionTest extends BasePermissionWsTest<BulkApplyTemplateAction> {

@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<BulkApplyT

@Override
protected BulkApplyTemplateAction buildWsAction() {
PermissionTemplateService permissionTemplateService = new PermissionTemplateService(db.getDbClient(), new MapSettings(),
issuePermissionIndexer, userSession);
PermissionTemplateService permissionTemplateService = new PermissionTemplateService(db.getDbClient(),
issuePermissionIndexer, userSession, defaultTemplatesResolver);
return new BulkApplyTemplateAction(db.getDbClient(), userSession, permissionTemplateService, newPermissionWsSupport(), new I18nRule(), newRootResourceTypes());
}

@@ -91,18 +92,16 @@ public class BulkApplyTemplateActionTest extends BasePermissionWsTest<BulkApplyT
OrganizationDto organization = db.getDefaultOrganization();
ComponentDto project = db.components().insertComponent(newProjectDto(organization));
ComponentDto view = db.components().insertComponent(newView(organization));
ComponentDto developer = db.components().insertComponent(newDeveloper(organization, "developer-name"));
db.users().insertProjectPermissionOnUser(user1, UserRole.ADMIN, developer);
db.users().insertProjectPermissionOnUser(user2, UserRole.ADMIN, developer);
db.users().insertProjectPermissionOnGroup(group1, UserRole.ADMIN, developer);
db.users().insertProjectPermissionOnGroup(group2, UserRole.ADMIN, developer);
db.users().insertProjectPermissionOnUser(user1, UserRole.ADMIN, view);
db.users().insertProjectPermissionOnUser(user2, UserRole.ADMIN, view);
db.users().insertProjectPermissionOnGroup(group1, UserRole.ADMIN, view);
db.users().insertProjectPermissionOnGroup(group2, UserRole.ADMIN, view);
loginAsAdminOnDefaultOrganization();

newRequest().setParam(PARAM_TEMPLATE_ID, template1.getUuid()).execute();

assertTemplate1AppliedToProject(project);
assertTemplate1AppliedToProject(view);
assertTemplate1AppliedToProject(developer);
}

@Test

+ 0
- 99
server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/DefaultPermissionTemplateFinderTest.java View File

@@ -1,99 +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 java.util.List;
import java.util.Set;
import org.junit.Before;
import org.junit.Test;
import org.sonar.api.config.MapSettings;
import org.sonar.api.config.Settings;
import org.sonar.api.resources.Qualifiers;
import org.sonar.api.resources.ResourceType;
import org.sonar.api.resources.ResourceTypes;
import org.sonar.server.permission.ws.template.DefaultPermissionTemplateFinder.TemplateUuidQualifier;

import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.groups.Tuple.tuple;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.sonar.server.permission.DefaultPermissionTemplates.DEFAULT_TEMPLATE_PROPERTY;
import static org.sonar.server.permission.DefaultPermissionTemplates.defaultRootQualifierTemplateProperty;

public class DefaultPermissionTemplateFinderTest {

private ResourceTypes resourceTypes = mock(ResourceTypes.class);
private Settings settings = new MapSettings();
private DefaultPermissionTemplateFinder underTest;

@Before
public void setUp() {
underTest = new DefaultPermissionTemplateFinder(settings, resourceTypes);
when(resourceTypes.getRoots()).thenReturn(rootResourceTypes());
}

@Test
public void get_default_template_uuids_in_settings() {
settings
.setProperty(DEFAULT_TEMPLATE_PROPERTY, "default-template-uuid")
.setProperty(defaultRootQualifierTemplateProperty(Qualifiers.PROJECT), "default-project-template-uuid")
.setProperty(defaultRootQualifierTemplateProperty("DEV"), "default-dev-template-uuid")
.setProperty(defaultRootQualifierTemplateProperty(Qualifiers.VIEW), "default-view-template-uuid");

Set<String> 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<String> 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<TemplateUuidQualifier> 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<ResourceType> 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);
}
}

+ 77
- 0
server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/DefaultTemplatesResolverImplTest.java View File

@@ -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");
}
}

+ 79
- 0
server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/DefaultTemplatesResolverRule.java View File

@@ -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);
}
}

+ 327
- 55
server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/DeleteTemplateActionTest.java View File

@@ -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<DeleteTemplateAction> {
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<WsActionTester> consumer) throws Exception {
for (WsActionTester underTest : Arrays.asList(underTestWithoutViews, underTestWithViews)) {
consumer.accept(underTest);
}
}

private interface ConsumerWithException<T> {
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<DeleteTemplat
return dto;
}

private TestResponse newRequest(@Nullable String id) throws Exception {
TestRequest request = newRequest();
private TestResponse newRequestByUuid(WsActionTester actionTester, @Nullable String id) throws Exception {
TestRequest request = actionTester.newRequest().setMethod("POST");
if (id != null) {
request.setParam(PARAM_TEMPLATE_ID, id);
}
return request.execute();
}

private TestResponse newRequestByName(WsActionTester actionTester, @Nullable OrganizationDto organizationDto, @Nullable PermissionTemplateDto permissionTemplateDto)
throws Exception {
return newRequestByName(
actionTester,
organizationDto == null ? null : organizationDto.getKey(),
permissionTemplateDto == null ? null : permissionTemplateDto.getName());
}

private TestResponse newRequestByName(WsActionTester actionTester, @Nullable String organizationKey, @Nullable String name) throws Exception {
TestRequest request = actionTester.newRequest().setMethod("POST");
if (organizationKey != null) {
request.setParam(PARAM_ORGANIZATION_KEY, organizationKey);
}
if (name != null) {
request.setParam(PARAM_TEMPLATE_NAME, name);
}

return request.execute();
}

private void assertTemplateDoesNotExist(PermissionTemplateDto template) {
assertThat(db.getDbClient().permissionTemplateDao().selectByUuid(db.getSession(), template.getUuid())).isNull();
}

}

+ 115
- 68
server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/SearchTemplatesActionTest.java View File

@@ -23,8 +23,6 @@ import java.util.Date;
import javax.annotation.Nullable;
import org.junit.Before;
import org.junit.Test;
import org.sonar.api.config.MapSettings;
import org.sonar.api.config.Settings;
import org.sonar.api.resources.Qualifiers;
import org.sonar.api.web.UserRole;
import org.sonar.db.DbClient;
@@ -38,6 +36,8 @@ import org.sonar.db.user.UserDto;
import org.sonar.server.exceptions.UnauthorizedException;
import org.sonar.server.i18n.I18nRule;
import org.sonar.server.permission.ws.BasePermissionWsTest;
import org.sonar.server.ws.TestRequest;
import org.sonar.server.ws.WsActionTester;
import org.sonarqube.ws.MediaTypes;
import org.sonarqube.ws.WsPermissions;

@@ -46,11 +46,7 @@ import static org.sonar.api.server.ws.WebService.Param.TEXT_QUERY;
import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
import static org.sonar.core.util.Uuids.UUID_EXAMPLE_01;
import static org.sonar.core.util.Uuids.UUID_EXAMPLE_02;
import static org.sonar.core.util.Uuids.UUID_EXAMPLE_03;
import static org.sonar.db.permission.template.PermissionTemplateTesting.newPermissionTemplateDto;
import static org.sonar.db.user.GroupTesting.newGroupDto;
import static org.sonar.db.user.UserTesting.newUserDto;
import static org.sonar.server.permission.DefaultPermissionTemplates.defaultRootQualifierTemplateProperty;
import static org.sonar.test.JsonAssert.assertJson;

public class SearchTemplatesActionTest extends BasePermissionWsTest<SearchTemplatesAction> {
@@ -58,39 +54,41 @@ public class SearchTemplatesActionTest extends BasePermissionWsTest<SearchTempla
private I18nRule i18n = new I18nRule();
private DbClient dbClient = db.getDbClient();
private DbSession dbSession = db.getSession();
private ResourceTypesRule resourceTypes = new ResourceTypesRule().setRootQualifiers(Qualifiers.PROJECT, Qualifiers.VIEW, "DEV");
private ResourceTypesRule resourceTypesWithViews = new ResourceTypesRule().setRootQualifiers(Qualifiers.PROJECT, Qualifiers.VIEW);
private ResourceTypesRule resourceTypesWithoutViews = new ResourceTypesRule().setRootQualifiers(Qualifiers.PROJECT);

private WsActionTester underTestWithoutViews;

@Override
protected SearchTemplatesAction buildWsAction() {
Settings settings = new MapSettings();
settings.setProperty(defaultRootQualifierTemplateProperty(Qualifiers.PROJECT), UUID_EXAMPLE_01);
settings.setProperty(defaultRootQualifierTemplateProperty(Qualifiers.VIEW), UUID_EXAMPLE_02);
settings.setProperty(defaultRootQualifierTemplateProperty("DEV"), UUID_EXAMPLE_03);

DefaultPermissionTemplateFinder defaultPermissionTemplateFinder = new DefaultPermissionTemplateFinder(settings, resourceTypes);
SearchTemplatesDataLoader dataLoader = new SearchTemplatesDataLoader(dbClient, defaultPermissionTemplateFinder);
return new SearchTemplatesAction(dbClient, userSession, i18n, newPermissionWsSupport(), dataLoader);
DefaultTemplatesResolver defaultTemplatesResolverWithViews = new DefaultTemplatesResolverImpl(resourceTypesWithViews);
SearchTemplatesDataLoader dataLoaderWithViews = new SearchTemplatesDataLoader(dbClient, defaultTemplatesResolverWithViews);
SearchTemplatesAction searchTemplatesAction = new SearchTemplatesAction(dbClient, userSession, i18n, newPermissionWsSupport(), dataLoaderWithViews);
return searchTemplatesAction;
}

@Before
public void setUp() {
DefaultTemplatesResolver defaultTemplatesResolverWithViews = new DefaultTemplatesResolverImpl(resourceTypesWithoutViews);
SearchTemplatesDataLoader dataLoaderWithViews = new SearchTemplatesDataLoader(dbClient, defaultTemplatesResolverWithViews);
underTestWithoutViews = new WsActionTester(new SearchTemplatesAction(dbClient, userSession, i18n, newPermissionWsSupport(), dataLoaderWithViews));
i18n.setProjectPermissions();
userSession.login().addOrganizationPermission(db.getDefaultOrganization().getUuid(), SYSTEM_ADMIN);
}

@Test
public void search_project_permissions() {
PermissionTemplateDto projectTemplate = insertProjectTemplateOnDefaultOrganization();
PermissionTemplateDto viewsTemplate = insertViewsTemplate();
PermissionTemplateDto developerTemplate = insertDeveloperTemplate();
OrganizationDto organization = db.getDefaultOrganization();
PermissionTemplateDto projectTemplate = insertProjectTemplate(organization);
PermissionTemplateDto viewsTemplate = insertViewsTemplate(organization);

UserDto user1 = insertUser(newUserDto());
UserDto user2 = insertUser(newUserDto());
UserDto user3 = insertUser(newUserDto());
UserDto user1 = db.users().insertUser();
UserDto user2 = db.users().insertUser();
UserDto user3 = db.users().insertUser();

GroupDto group1 = insertGroup(newGroupDto());
GroupDto group2 = insertGroup(newGroupDto());
GroupDto group3 = insertGroup(newGroupDto());
GroupDto group1 = db.users().insertGroup(organization);
GroupDto group2 = db.users().insertGroup(organization);
GroupDto group3 = db.users().insertGroup(organization);

addUserToTemplate(projectTemplate.getId(), user1.getId(), UserRole.ISSUE_ADMIN);
addUserToTemplate(projectTemplate.getId(), user2.getId(), UserRole.ISSUE_ADMIN);
@@ -105,9 +103,7 @@ public class SearchTemplatesActionTest extends BasePermissionWsTest<SearchTempla
addGroupToTemplate(viewsTemplate.getId(), group2.getId(), UserRole.ISSUE_ADMIN);
addGroupToTemplate(viewsTemplate.getId(), group3.getId(), UserRole.ISSUE_ADMIN);

addGroupToTemplate(developerTemplate.getId(), group1.getId(), UserRole.USER);

db.commit();
db.organizations().setDefaultTemplates(organization, projectTemplate.getUuid(), viewsTemplate.getUuid());

String result = newRequest().execute().getInput();

@@ -117,23 +113,54 @@ public class SearchTemplatesActionTest extends BasePermissionWsTest<SearchTempla
}

@Test
public void empty_result() {
String result = newRequest().execute().getInput();
public void empty_result_with_views() {
db.organizations().setDefaultTemplates(db.getDefaultOrganization(), "AU-Tpxb--iU5OvuD2FLy", "AU-TpxcA-iU5OvuD2FLz");
String result = newRequest(wsTester).execute().getInput();

assertJson(result)
.withStrictArrayOrder()
.ignoreFields("permissions")
.isSimilarTo(getClass().getResource("SearchTemplatesActionTest/empty.json"));
.isSimilarTo("{" +
" \"permissionTemplates\": []," +
" \"defaultTemplates\": [" +
" {" +
" \"templateId\": \"AU-Tpxb--iU5OvuD2FLy\"," +
" \"qualifier\": \"TRK\"" +
" }," +
" {" +
" \"templateId\": \"AU-TpxcA-iU5OvuD2FLz\"," +
" \"qualifier\": \"VW\"" +
" }" +
" ]" +
"}");
}

@Test
public void empty_result_without_views() {
db.organizations().setDefaultTemplates(db.getDefaultOrganization(), "AU-Tpxb--iU5OvuD2FLy", "AU-TpxcA-iU5OvuD2FLz");
String result = newRequest(underTestWithoutViews).execute().getInput();

assertJson(result)
.withStrictArrayOrder()
.ignoreFields("permissions")
.isSimilarTo("{" +
" \"permissionTemplates\": []," +
" \"defaultTemplates\": [" +
" {" +
" \"templateId\": \"AU-Tpxb--iU5OvuD2FLy\"," +
" \"qualifier\": \"TRK\"" +
" }" +
" ]" +
"}");
}

@Test
public void search_by_name_in_default_organization() {
insertProjectTemplateOnDefaultOrganization();
insertViewsTemplate();
insertDeveloperTemplate();
db.commit();
db.organizations().setDefaultTemplates(db.getDefaultOrganization(), "foo", null);
insertProjectTemplate(db.getDefaultOrganization());
insertViewsTemplate(db.getDefaultOrganization());

String result = newRequest()
String result = newRequest(wsTester)
.setParam(TEXT_QUERY, "views")
.execute()
.getInput();
@@ -146,16 +173,18 @@ public class SearchTemplatesActionTest extends BasePermissionWsTest<SearchTempla
@Test
public void search_in_organization() throws Exception {
OrganizationDto org = db.organizations().insert();
db.organizations().setDefaultTemplates(org, "foo", null);
PermissionTemplateDto templateInOrg = insertProjectTemplate(org);
insertProjectTemplateOnDefaultOrganization();
insertProjectTemplate(db.getDefaultOrganization());
db.commit();
userSession.addOrganizationPermission(org.getUuid(), SYSTEM_ADMIN);

WsPermissions.SearchTemplatesWsResponse result = WsPermissions.SearchTemplatesWsResponse.parseFrom(newRequest()
.setParam("organization", org.getKey())
.setMediaType(MediaTypes.PROTOBUF)
.execute()
.getInputStream());
WsPermissions.SearchTemplatesWsResponse result = WsPermissions.SearchTemplatesWsResponse.parseFrom(
newRequest(underTestWithoutViews)
.setParam("organization", org.getKey())
.setMediaType(MediaTypes.PROTOBUF)
.execute()
.getInputStream());

assertThat(result.getPermissionTemplatesCount()).isEqualTo(1);
assertThat(result.getPermissionTemplates(0).getId()).isEqualTo(templateInOrg.getUuid());
@@ -171,16 +200,45 @@ public class SearchTemplatesActionTest extends BasePermissionWsTest<SearchTempla

@Test
public void display_all_project_permissions() {
db.organizations().setDefaultTemplates(db.getDefaultOrganization(), "foo", "bar");

String result = newRequest().execute().getInput();

assertJson(result)
.withStrictArrayOrder()
.ignoreFields("defaultTemplates", "permissionTemplates")
.isSimilarTo(getClass().getResource("SearchTemplatesActionTest/display_all_project_permissions.json"));
}

private PermissionTemplateDto insertProjectTemplateOnDefaultOrganization() {
return insertProjectTemplate(db.getDefaultOrganization());
.isSimilarTo(
"{" +
" \"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.\"" +
" }" +
" ]" +
"}");
}

private PermissionTemplateDto insertProjectTemplate(OrganizationDto org) {
@@ -194,9 +252,9 @@ public class SearchTemplatesActionTest extends BasePermissionWsTest<SearchTempla
.setUpdatedAt(new Date(1_000_000_000_000L)));
}

private PermissionTemplateDto insertViewsTemplate() {
private PermissionTemplateDto insertViewsTemplate(OrganizationDto organization) {
return insertTemplate(newPermissionTemplateDto()
.setOrganizationUuid(db.getDefaultOrganization().getUuid())
.setOrganizationUuid(organization.getUuid())
.setUuid(UUID_EXAMPLE_02)
.setName("Default template for Views")
.setDescription("Template for new views")
@@ -205,35 +263,20 @@ public class SearchTemplatesActionTest extends BasePermissionWsTest<SearchTempla
.setUpdatedAt(new Date(1_100_000_000_000L)));
}

private PermissionTemplateDto insertDeveloperTemplate() {
return insertTemplate(newPermissionTemplateDto()
.setOrganizationUuid(db.getDefaultOrganization().getUuid())
.setUuid(UUID_EXAMPLE_03)
.setName("Default template for Developers")
.setKeyPattern(".*sonar.developer.*")
.setDescription(null)
.setCreatedAt(new Date(1_100_500_000_000L))
.setUpdatedAt(new Date(1_100_900_000_000L)));
}

private PermissionTemplateDto insertTemplate(PermissionTemplateDto template) {
return dbClient.permissionTemplateDao().insert(db.getSession(), template);
}

private GroupDto insertGroup(GroupDto groupDto) {
return dbClient.groupDao().insert(db.getSession(), groupDto);
}

private UserDto insertUser(UserDto userDto) {
return dbClient.userDao().insert(db.getSession(), userDto.setActive(true));
PermissionTemplateDto insert = dbClient.permissionTemplateDao().insert(db.getSession(), template);
db.getSession().commit();
return insert;
}

private void addGroupToTemplate(long templateId, @Nullable Long groupId, String permission) {
dbClient.permissionTemplateDao().insertGroupPermission(db.getSession(), templateId, groupId, permission);
db.getSession().commit();
}

private void addUserToTemplate(long templateId, long userId, String permission) {
dbClient.permissionTemplateDao().insertUserPermission(db.getSession(), templateId, userId, permission);
db.getSession().commit();
}

private void addPermissionTemplateWithProjectCreator(long templateId, String permission) {
@@ -245,4 +288,8 @@ public class SearchTemplatesActionTest extends BasePermissionWsTest<SearchTempla
.setUpdatedAt(2_000_000_000L));
db.commit();
}

private TestRequest newRequest(WsActionTester underTest) {
return underTest.newRequest().setMethod("POST");
}
}

+ 1
- 2
server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/SearchTemplatesDataTest.java View File

@@ -23,7 +23,6 @@ import com.google.common.collect.HashBasedTable;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.resources.Qualifiers;

import static java.util.Collections.singletonList;
import static org.sonar.db.permission.template.PermissionTemplateTesting.newPermissionTemplateDto;
@@ -33,7 +32,7 @@ public class SearchTemplatesDataTest {
public ExpectedException expectedException = ExpectedException.none();

SearchTemplatesData.Builder underTest = SearchTemplatesData.builder()
.defaultTemplates(singletonList(new DefaultPermissionTemplateFinder.TemplateUuidQualifier("template_uuid", Qualifiers.PROJECT)))
.defaultTemplates(new DefaultTemplatesResolverImpl.ResolvedDefaultTemplates("template_uuid", null))
.templates(singletonList(newPermissionTemplateDto()))
.userCountByTemplateIdAndPermission(HashBasedTable.create())
.groupCountByTemplateIdAndPermission(HashBasedTable.create())

+ 82
- 43
server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/SetDefaultTemplateActionTest.java View File

@@ -20,12 +20,13 @@
package org.sonar.server.permission.ws.template;

import javax.annotation.Nullable;
import org.junit.Before;
import org.junit.Test;
import org.sonar.api.config.MapSettings;
import org.sonar.api.resources.Qualifiers;
import org.sonar.core.permission.GlobalPermissions;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.organization.DefaultTemplates;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.permission.template.PermissionTemplateDto;
import org.sonar.db.permission.template.PermissionTemplateTesting;
import org.sonar.server.exceptions.BadRequestException;
@@ -34,94 +35,98 @@ import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.exceptions.UnauthorizedException;
import org.sonar.server.i18n.I18nRule;
import org.sonar.server.permission.ws.BasePermissionWsTest;
import org.sonar.server.platform.PersistentSettings;
import org.sonar.server.platform.SettingsChangeNotifier;
import org.sonar.server.ws.TestRequest;

import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.api.resources.Qualifiers.PROJECT;
import static org.sonar.api.resources.Qualifiers.VIEW;
import static org.sonar.server.permission.DefaultPermissionTemplates.DEFAULT_TEMPLATE_PROPERTY;
import static org.sonar.server.permission.DefaultPermissionTemplates.defaultRootQualifierTemplateProperty;
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_ORGANIZATION_KEY;
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_QUALIFIER;
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_TEMPLATE_ID;
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_TEMPLATE_NAME;

public class SetDefaultTemplateActionTest extends BasePermissionWsTest<SetDefaultTemplateAction> {

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<SetDefaul

@Test
public void fail_if_qualifier_is_not_root() throws Exception {
OrganizationDto organization = db.organizations().insert();
PermissionTemplateDto template = insertTemplate(organization);
loginAsAdmin(organization);

expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Value of parameter 'qualifier' (FIL) must be one of: [DEV, TRK, VW]");
expectedException.expectMessage("Value of parameter 'qualifier' (FIL) must be one of: [TRK, VW]");

newRequest(template.getUuid(), Qualifiers.FILE);
}

@Test
public void fail_if_organization_has_no_default_templates() throws Exception {
OrganizationDto organization = db.organizations().insert();
PermissionTemplateDto template = insertTemplate(organization);
loginAsAdmin(organization);

expectedException.expect(NotFoundException.class);
expectedException.expectMessage("No Default templates for organization with uuid '" + organization.getUuid() + "'");

newRequest(template.getUuid(), null);
}

private String newRequest(@Nullable String templateUuid, @Nullable String qualifier) throws Exception {
TestRequest request = newRequest();
if (templateUuid != null) {
@@ -157,4 +178,22 @@ public class SetDefaultTemplateActionTest extends BasePermissionWsTest<SetDefaul

return request.execute().getInput();
}

private PermissionTemplateDto insertTemplate(OrganizationDto organization) {
PermissionTemplateDto res = dbClient.permissionTemplateDao().insert(db.getSession(), PermissionTemplateTesting.newPermissionTemplateDto()
.setOrganizationUuid(organization.getUuid())
.setUuid("permission-template-uuid"));
db.commit();
return res;
}

private void assertDefaultTemplates(OrganizationDto organizationDto,
@Nullable String projectDefaultTemplateUuid, @Nullable String viewDefaultTemplateUuid) {
DbSession dbSession = db.getSession();
DefaultTemplates defaultTemplates = db.getDbClient().organizationDao().getDefaultTemplates(dbSession, organizationDto.getUuid())
.orElseThrow(() -> new IllegalStateException("No default templates for organization with uuid '" + organizationDto.getUuid() + "'"));

assertThat(defaultTemplates.getProjectUuid()).isEqualTo(projectDefaultTemplateUuid);
assertThat(defaultTemplates.getViewUuid()).isEqualTo(viewDefaultTemplateUuid);
}
}

+ 5
- 14
server/sonar-server/src/test/java/org/sonar/server/project/ws/CreateActionTest.java View File

@@ -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());
}

}

+ 26
- 33
server/sonar-server/src/test/java/org/sonar/server/startup/RegisterPermissionTemplatesTest.java View File

@@ -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<PermissionTemplateGroupDto> 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> defaultTemplates = db.getDbClient().organizationDao().getDefaultTemplates(db.getSession(), db.getDefaultOrganization().getUuid());
assertThat(defaultTemplates)
.isPresent();
assertThat(defaultTemplates.get().getProjectUuid()).isEqualTo(DEFAULT_TEMPLATE_UUID);
}
}

+ 0
- 115
server/sonar-server/src/test/resources/org/sonar/server/permission/PermissionTemplateServiceTest/apply_default_permission_template_by_component_id-result.xml View File

@@ -1,115 +0,0 @@
<dataset>

<groups id="100"
name="sonar-administrators"
organization_uuid="org1"/>
<groups id="101"
name="sonar-users"
organization_uuid="org1"/>

<users id="200"
login="marius"
name="Marius"
email="[null]"
active="[true]"
is_root="[false]"/>
<users id="201"
login="janette"
name="Janette"
email="[null]"
active="[true]"
is_root="[false]"/>

<!-- on other resources -->
<group_roles id="1"
group_id="100"
resource_id="1"
role="admin"
organization_uuid="org1"/>
<group_roles id="2"
group_id="101"
resource_id="1"
role="user"
organization_uuid="org1"/>
<user_roles id="1"
user_id="200"
resource_id="1"
role="admin"
organization_uuid="org1"/>

<!-- new groups permissions : sonar-administrators (admin), sonar-users (user & codeviewer), Anyone (user & codeviewer) -->
<group_roles id="3"
group_id="100"
resource_id="123"
role="admin"
organization_uuid="org1"/>
<group_roles id="4"
group_id="101"
resource_id="123"
role="user"
organization_uuid="org1"/>
<group_roles id="5"
group_id="[null]"
resource_id="123"
role="user"
organization_uuid="org1"/>
<group_roles id="6"
group_id="101"
resource_id="123"
role="codeviewer"
organization_uuid="org1"/>
<group_roles id="7"
group_id="[null]"
resource_id="123"
role="codeviewer"
organization_uuid="org1"/>
<group_roles id="8"
group_id="100"
resource_id="123"
role="issueadmin"
organization_uuid="org1"/>

<!-- new user permission : marius (admin) & janette (user) -->
<user_roles id="2"
user_id="200"
resource_id="123"
role="admin"
organization_uuid="org1"/>

<!-- default permission template for all qualifiers -->
<permission_templates id="1"
name="default"
kee="default_20130101_010203"
organization_uuid="org1"/>

<perm_templates_groups id="1"
template_id="1"
group_id="100"
permission_reference="admin"/>
<perm_templates_groups id="2"
template_id="1"
group_id="101"
permission_reference="user"/>
<perm_templates_groups id="3"
template_id="1"
group_id="[null]"
permission_reference="user"/>
<perm_templates_groups id="4"
template_id="1"
group_id="101"
permission_reference="codeviewer"/>
<perm_templates_groups id="5"
template_id="1"
group_id="[null]"
permission_reference="codeviewer"/>
<perm_templates_groups id="6"
template_id="1"
group_id="100"
permission_reference="issueadmin"/>

<perm_templates_users id="1"
template_id="1"
user_id="200"
permission_reference="admin"/>

</dataset>

+ 0
- 99
server/sonar-server/src/test/resources/org/sonar/server/permission/PermissionTemplateServiceTest/apply_default_permission_template_by_component_id.xml View File

@@ -1,99 +0,0 @@
<dataset>
<projects organization_uuid="org1"
uuid="A"
uuid_path="NOT_USED"
root_uuid="A"
scope="PRJ"
qualifier="TRK"
kee="org.struts:struts"
name="Struts"
description="the description"
long_name="Apache Struts"
enabled="[true]"
language="java"
copy_component_uuid="[null]"
developer_uuid="[null]"
path="[null]"
authorization_updated_at="123456789"
id="123"/>

<groups id="100"
name="sonar-administrators"
organization_uuid="org1"/>
<groups id="101"
name="sonar-users"
organization_uuid="org1"/>

<users id="200"
login="marius"
name="Marius"
email="[null]"
active="[true]"
is_root="[false]"/>

<!-- on other resources -->
<group_roles id="1"
group_id="100"
resource_id="1"
role="admin"
organization_uuid="org1"/>
<group_roles id="2"
group_id="101"
resource_id="1"
role="user"
organization_uuid="org1"/>
<user_roles id="1"
user_id="200"
resource_id="1"
role="admin"
organization_uuid="org1"/>

<!-- default permission template for all qualifiers -->
<permission_templates id="1"
name="default"
kee="default_20130101_010203"
organization_uuid="org1"/>

<perm_templates_groups id="1"
template_id="1"
group_id="100"
permission_reference="admin"/>
<perm_templates_groups id="2"
template_id="1"
group_id="101"
permission_reference="user"/>
<perm_templates_groups id="3"
template_id="1"
group_id="[null]"
permission_reference="user"/>
<perm_templates_groups id="4"
template_id="1"
group_id="101"
permission_reference="codeviewer"/>
<perm_templates_groups id="5"
template_id="1"
group_id="[null]"
permission_reference="codeviewer"/>
<perm_templates_groups id="6"
template_id="1"
group_id="100"
permission_reference="issueadmin"/>

<perm_templates_users id="1"
template_id="1"
user_id="200"
permission_reference="admin"/>

<perm_tpl_characteristics id="1"
template_id="1"
permission_key="user"
with_project_creator="[true]"
created_at="1234567890"
updated_at="123457890"/>
<perm_tpl_characteristics id="2"
template_id="2"
permission_key="user"
with_project_creator="[false]"
created_at="1234567890"
updated_at="1234567890"/>
</dataset>

+ 0
- 109
server/sonar-server/src/test/resources/org/sonar/server/permission/PermissionTemplateServiceTest/should_apply_permission_template-result.xml View File

@@ -1,109 +0,0 @@
<dataset>

<groups id="100"
name="sonar-administrators"
organization_uuid="org1"/>
<groups id="101"
name="sonar-users"
organization_uuid="org1"/>

<users id="200"
login="marius"
name="Marius"
email="[null]"
active="[true]"
is_root="[false]"/>

<!-- on other resources -->
<group_roles id="1"
group_id="100"
resource_id="1"
role="admin"
organization_uuid="org1"/>
<group_roles id="2"
group_id="101"
resource_id="1"
role="user"
organization_uuid="org1"/>
<user_roles id="1"
user_id="200"
resource_id="1"
role="admin"
organization_uuid="org1"/>

<!-- new groups permissions : sonar-administrators (admin), sonar-users (user & codeviewer), Anyone (user & codeviewer) -->
<group_roles id="3"
group_id="100"
resource_id="123"
role="admin"
organization_uuid="org1"/>
<group_roles id="4"
group_id="101"
resource_id="123"
role="user"
organization_uuid="org1"/>
<group_roles id="5"
group_id="[null]"
resource_id="123"
role="user"
organization_uuid="org1"/>
<group_roles id="6"
group_id="101"
resource_id="123"
role="codeviewer"
organization_uuid="org1"/>
<group_roles id="7"
group_id="[null]"
resource_id="123"
role="codeviewer"
organization_uuid="org1"/>
<group_roles id="8"
group_id="100"
resource_id="123"
role="issueadmin"
organization_uuid="org1"/>

<!-- new user permission : marius (admin) -->
<user_roles id="2"
user_id="200"
resource_id="123"
role="admin"
organization_uuid="org1"/>

<!-- default permission template for all qualifiers -->
<permission_templates id="1"
name="default"
kee="default_20130101_010203"
organization_uuid="org1"/>

<perm_templates_groups id="1"
template_id="1"
group_id="100"
permission_reference="admin"/>
<perm_templates_groups id="2"
template_id="1"
group_id="101"
permission_reference="user"/>
<perm_templates_groups id="3"
template_id="1"
group_id="[null]"
permission_reference="user"/>
<perm_templates_groups id="4"
template_id="1"
group_id="101"
permission_reference="codeviewer"/>
<perm_templates_groups id="5"
template_id="1"
group_id="[null]"
permission_reference="codeviewer"/>
<perm_templates_groups id="6"
template_id="1"
group_id="100"
permission_reference="issueadmin"/>

<perm_templates_users id="1"
template_id="1"
user_id="200"
permission_reference="admin"/>

</dataset>

+ 0
- 29
server/sonar-server/src/test/resources/org/sonar/server/permission/ws/template/SearchTemplatesActionTest/display_all_project_permissions.json View File

@@ -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."
}
]
}

+ 0
- 17
server/sonar-server/src/test/resources/org/sonar/server/permission/ws/template/SearchTemplatesActionTest/empty.json View File

@@ -1,17 +0,0 @@
{
"permissionTemplates": [],
"defaultTemplates": [
{
"templateId": "AU-Tpxb--iU5OvuD2FLy",
"qualifier": "TRK"
},
{
"templateId": "AU-TpxcA-iU5OvuD2FLz",
"qualifier": "VW"
},
{
"templateId": "AU-TpxcA-iU5OvuD2FL0",
"qualifier": "DEV"
}
]
}

+ 18
- 14
sonar-db/src/main/java/org/sonar/db/organization/DefaultTemplates.java View File

@@ -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 + '\'' +
'}';
}
}

+ 1
- 1
sonar-db/src/main/java/org/sonar/db/organization/OrganizationDao.java View File

@@ -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());
}
}

+ 4
- 4
sonar-db/src/main/resources/org/sonar/db/organization/OrganizationMapper.xml View File

@@ -14,8 +14,8 @@
</sql>

<sql id="defaultTemplatesColumns">
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"
</sql>
<select id="selectByUuid" resultType="Organization">
@@ -139,8 +139,8 @@
<update id="updateDefaultTemplates">
update organizations
set
default_perm_template_project = #{defaultTemplates.project, jdbcType=VARCHAR},
default_perm_template_view = #{defaultTemplates.view, jdbcType=VARCHAR},
default_perm_template_project = #{defaultTemplates.projectUuid, jdbcType=VARCHAR},
default_perm_template_view = #{defaultTemplates.viewUuid, jdbcType=VARCHAR},
updated_at = #{now, jdbcType=BIGINT}
where
uuid = #{organizationUuid, jdbcType=VARCHAR}

+ 15
- 7
sonar-db/src/test/java/org/sonar/db/organization/DefaultTemplatesTest.java View File

@@ -34,22 +34,30 @@ public class DefaultTemplatesTest {
@Test
public void setProject_throws_NPE_if_argument_is_null() {
expectedException.expect(NullPointerException.class);
expectedException.expectMessage("project default template can't be null");
expectedException.expectMessage("defaultTemplates.project can't be null");

underTest.setProject(null);
underTest.setProjectUuid(null);
}

@Test
public void getProject_throws_NPE_if_project_is_null() {
expectedException.expect(NullPointerException.class);
expectedException.expectMessage("defaultTemplates.project can't be null");

underTest.getProjectUuid();
}

@Test
public void setView_accepts_null() {
underTest.setView(null);
underTest.setViewUuid(null);
}

@Test
public void check_toString() {
assertThat(underTest.toString()).isEqualTo("DefaultTemplates{project='null', view='null'}");
assertThat(underTest.toString()).isEqualTo("DefaultTemplates{projectUuid='null', viewUuid='null'}");
underTest
.setProject("a project")
.setView("a view");
assertThat(underTest.toString()).isEqualTo("DefaultTemplates{project='a project', view='a view'}");
.setProjectUuid("a project")
.setViewUuid("a view");
assertThat(underTest.toString()).isEqualTo("DefaultTemplates{projectUuid='a project', viewUuid='a view'}");
}
}

+ 7
- 7
sonar-db/src/test/java/org/sonar/db/organization/OrganizationDaoTest.java View File

@@ -460,7 +460,7 @@ public class OrganizationDaoTest {
@Test
public void getDefaultTemplates_returns_data_when_project_default_templates_column_is_not_null() {
insertOrganization(ORGANIZATION_DTO_1);
underTest.setDefaultTemplates(dbSession, ORGANIZATION_DTO_1.getUuid(), new DefaultTemplates().setProject("foo"));
underTest.setDefaultTemplates(dbSession, ORGANIZATION_DTO_1.getUuid(), new DefaultTemplates().setProjectUuid("foo"));

verifyGetDefaultTemplates(ORGANIZATION_DTO_1, "foo", null);
}
@@ -492,7 +492,7 @@ public class OrganizationDaoTest {
@Test
public void getDefaultTemplates_is_case_sensitive() {
insertOrganization(ORGANIZATION_DTO_1);
underTest.setDefaultTemplates(dbSession, ORGANIZATION_DTO_1.getUuid(), new DefaultTemplates().setProject("foo").setView("bar"));
underTest.setDefaultTemplates(dbSession, ORGANIZATION_DTO_1.getUuid(), new DefaultTemplates().setProjectUuid("foo").setViewUuid("bar"));

assertThat(underTest.getDefaultTemplates(dbSession, ORGANIZATION_DTO_1.getUuid().toUpperCase(Locale.ENGLISH)))
.isEmpty();
@@ -503,7 +503,7 @@ public class OrganizationDaoTest {
expectedException.expect(NullPointerException.class);
expectedException.expectMessage("uuid can't be null");

underTest.setDefaultTemplates(dbSession, null, new DefaultTemplates().setProject("p"));
underTest.setDefaultTemplates(dbSession, null, new DefaultTemplates().setProjectUuid("p"));
}

@Test
@@ -527,7 +527,7 @@ public class OrganizationDaoTest {
expectedException.expect(NullPointerException.class);
expectedException.expectMessage("defaultTemplates.project can't be null");

underTest.setDefaultTemplates(dbSession, "uuid", new DefaultTemplates().setView("foo"));
underTest.setDefaultTemplates(dbSession, "uuid", new DefaultTemplates().setViewUuid("foo"));
}

@Test
@@ -731,7 +731,7 @@ public class OrganizationDaoTest {
}

private void setDefaultTemplate(OrganizationDto organizationDto1, @Nullable String project, @Nullable String view) {
underTest.setDefaultTemplates(dbSession, organizationDto1.getUuid(), new DefaultTemplates().setProject(project).setView(view));
underTest.setDefaultTemplates(dbSession, organizationDto1.getUuid(), new DefaultTemplates().setProjectUuid(project).setViewUuid(view));
dbSession.commit();
}

@@ -792,7 +792,7 @@ public class OrganizationDaoTest {
Optional<DefaultTemplates> optional = underTest.getDefaultTemplates(dbSession, organizationDto.getUuid());
assertThat(optional).isNotEmpty();
DefaultTemplates defaultTemplates = optional.get();
assertThat(defaultTemplates.getProject()).isEqualTo(expectedProject);
assertThat(defaultTemplates.getView()).isEqualTo(expectedView);
assertThat(defaultTemplates.getProjectUuid()).isEqualTo(expectedProject);
assertThat(defaultTemplates.getViewUuid()).isEqualTo(expectedView);
}
}

+ 9
- 0
sonar-db/src/test/java/org/sonar/db/organization/OrganizationDbTester.java View File

@@ -19,6 +19,7 @@
*/
package org.sonar.db.organization;

import javax.annotation.Nullable;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;

@@ -53,4 +54,12 @@ public class OrganizationDbTester {
dbSession.commit();
return dto;
}

public void setDefaultTemplates(OrganizationDto defaultOrganization,
String projectDefaultTemplateUuid, @Nullable String viewDefaultTemplateUuid) {
DbSession dbSession = dbTester.getSession();
dbTester.getDbClient().organizationDao().setDefaultTemplates(dbSession, defaultOrganization.getUuid(), new DefaultTemplates().setProjectUuid(projectDefaultTemplateUuid).setViewUuid(viewDefaultTemplateUuid));
dbSession.commit();
}

}

+ 14
- 0
sonar-db/src/test/java/org/sonar/db/permission/template/PermissionTemplateDbTester.java View File

@@ -25,6 +25,8 @@ import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.user.GroupDto;
import org.sonar.db.user.UserDto;

import static org.sonar.db.permission.template.PermissionTemplateTesting.newPermissionTemplateCharacteristicDto;
import static org.sonar.db.permission.template.PermissionTemplateTesting.newPermissionTemplateDto;
@@ -55,11 +57,23 @@ public class PermissionTemplateDbTester {
return templateInDb;
}

public void addGroupToTemplate(PermissionTemplateDto permissionTemplate, GroupDto group, String permission) {
addGroupToTemplate(permissionTemplate.getId(), group.getId(), permission);
}

public void addGroupToTemplate(long templateId, @Nullable Long groupId, String permission) {
dbClient.permissionTemplateDao().insertGroupPermission(dbSession, templateId, groupId, permission);
db.commit();
}

public void addAnyoneToTemplate(PermissionTemplateDto permissionTemplate, String permission) {
addGroupToTemplate(permissionTemplate.getId(), null, permission);
}

public void addUserToTemplate(PermissionTemplateDto permissionTemplate, UserDto user, String permission) {
addUserToTemplate(permissionTemplate.getId(), user.getId(), permission);
}

public void addUserToTemplate(long templateId, long userId, String permission) {
dbClient.permissionTemplateDao().insertUserPermission(dbSession, templateId, userId, permission);
db.commit();

Loading…
Cancel
Save