Browse Source

SONAR-8134 Remove check of authorization in PermissionUpdater

so that Compute Engine can call it without emulating
authroization stack.
Authorization is verified directly in the api/permissions
web services.
tags/6.2-RC1
Simon Brandhof 7 years ago
parent
commit
8a475eff47
24 changed files with 313 additions and 140 deletions
  1. 9
    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. 1
    6
      server/sonar-server/src/main/java/org/sonar/server/permission/GroupPermissionChanger.java
  4. 3
    2
      server/sonar-server/src/main/java/org/sonar/server/permission/PermissionPrivilegeChecker.java
  5. 5
    0
      server/sonar-server/src/main/java/org/sonar/server/permission/PermissionUpdater.java
  6. 1
    8
      server/sonar-server/src/main/java/org/sonar/server/permission/UserPermissionChanger.java
  7. 7
    1
      server/sonar-server/src/main/java/org/sonar/server/permission/ws/AddGroupAction.java
  8. 8
    1
      server/sonar-server/src/main/java/org/sonar/server/permission/ws/AddUserAction.java
  9. 2
    2
      server/sonar-server/src/main/java/org/sonar/server/permission/ws/GroupsAction.java
  10. 0
    10
      server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionsWsModule.java
  11. 7
    1
      server/sonar-server/src/main/java/org/sonar/server/permission/ws/RemoveGroupAction.java
  12. 7
    1
      server/sonar-server/src/main/java/org/sonar/server/permission/ws/RemoveUserAction.java
  13. 21
    20
      server/sonar-server/src/main/java/org/sonar/server/permission/ws/SearchProjectPermissionsAction.java
  14. 11
    13
      server/sonar-server/src/main/java/org/sonar/server/permission/ws/SearchProjectPermissionsDataLoader.java
  15. 2
    2
      server/sonar-server/src/main/java/org/sonar/server/permission/ws/UsersAction.java
  16. 10
    0
      server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java
  17. 1
    40
      server/sonar-server/src/test/java/org/sonar/server/permission/GroupPermissionChangerTest.java
  18. 42
    7
      server/sonar-server/src/test/java/org/sonar/server/permission/ws/AddGroupActionTest.java
  19. 51
    8
      server/sonar-server/src/test/java/org/sonar/server/permission/ws/AddUserActionTest.java
  20. 2
    2
      server/sonar-server/src/test/java/org/sonar/server/permission/ws/BasePermissionWsTest.java
  21. 1
    1
      server/sonar-server/src/test/java/org/sonar/server/permission/ws/PermissionsWsModuleTest.java
  22. 70
    11
      server/sonar-server/src/test/java/org/sonar/server/permission/ws/RemoveGroupActionTest.java
  23. 48
    1
      server/sonar-server/src/test/java/org/sonar/server/permission/ws/RemoveUserActionTest.java
  24. 3
    2
      server/sonar-server/src/test/java/org/sonar/server/permission/ws/SearchProjectPermissionsActionTest.java

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

@@ -96,6 +96,10 @@ import org.sonar.server.notification.NotificationService;
import org.sonar.server.notification.email.AlertsEmailTemplate;
import org.sonar.server.notification.email.EmailNotificationChannel;
import org.sonar.server.organization.DefaultOrganizationProviderImpl;
import org.sonar.server.permission.GroupPermissionChanger;
import org.sonar.server.permission.PermissionService;
import org.sonar.server.permission.PermissionUpdater;
import org.sonar.server.permission.UserPermissionChanger;
import org.sonar.server.platform.DatabaseServerCompatibility;
import org.sonar.server.platform.DefaultServerUpgradeStatus;
import org.sonar.server.platform.ServerFileSystemImpl;
@@ -316,6 +320,11 @@ public class ComputeEngineContainerImpl implements ComputeEngineContainer {

// permissions
PermissionRepository.class,
PermissionService.class,
PermissionUpdater.class,
UserPermissionChanger.class,
GroupPermissionChanger.class,


// components
ComponentFinder.class, // used in ComponentService

+ 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
+ 74 // level 4
+ 78 // level 4
+ 4 // content of CeConfigurationModule
+ 3 // content of CeHttpModule
+ 5 // content of CeQueueModule

+ 1
- 6
server/sonar-server/src/main/java/org/sonar/server/permission/GroupPermissionChanger.java View File

@@ -25,23 +25,18 @@ import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.permission.GroupPermissionDto;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.user.UserSession;

import static org.sonar.server.permission.ws.PermissionRequestValidator.validateNotAnyoneAndAdminPermission;

public class GroupPermissionChanger {

private final DbClient dbClient;
private final UserSession userSession;

public GroupPermissionChanger(DbClient dbClient, UserSession userSession) {
public GroupPermissionChanger(DbClient dbClient) {
this.dbClient = dbClient;
this.userSession = userSession;
}

public boolean apply(DbSession dbSession, GroupPermissionChange change) {
PermissionPrivilegeChecker.checkProjectAdminUserByComponentUuid(userSession, change.getProjectUuid());

if (shouldSkip(dbSession, change)) {
return false;
}

+ 3
- 2
server/sonar-server/src/main/java/org/sonar/server/permission/PermissionPrivilegeChecker.java View File

@@ -19,6 +19,7 @@
*/
package org.sonar.server.permission;

import java.util.Optional;
import javax.annotation.Nullable;
import org.sonar.api.web.UserRole;
import org.sonar.core.permission.GlobalPermissions;
@@ -42,9 +43,9 @@ public class PermissionPrivilegeChecker {
}
}

public static void checkProjectAdminUserByComponentUuid(UserSession userSession, @Nullable String componentUuid) {
public static void checkAdministrationPermission(UserSession userSession, Optional<ProjectId> projectId) {
userSession.checkLoggedIn();
if (componentUuid == null || !userSession.hasComponentUuidPermission(UserRole.ADMIN, componentUuid)) {
if (!projectId.isPresent() || !userSession.hasComponentUuidPermission(UserRole.ADMIN, projectId.get().getUuid())) {
userSession.checkPermission(GlobalPermissions.SYSTEM_ADMIN);
}
}

+ 5
- 0
server/sonar-server/src/main/java/org/sonar/server/permission/PermissionUpdater.java View File

@@ -27,6 +27,11 @@ import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.server.issue.index.IssueAuthorizationIndexer;

/**
* Add or remove global/project permissions to a group. This class
* does not verify that caller has administration right on the related
* organization or project.
*/
public class PermissionUpdater {

private final DbClient dbClient;

+ 1
- 8
server/sonar-server/src/main/java/org/sonar/server/permission/UserPermissionChanger.java View File

@@ -26,23 +26,16 @@ import org.sonar.db.DbSession;
import org.sonar.db.permission.UserPermissionDto;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.permission.PermissionChange.Operation;
import org.sonar.server.user.UserSession;

import static org.sonar.server.permission.PermissionPrivilegeChecker.checkProjectAdminUserByComponentUuid;

public class UserPermissionChanger {

private final DbClient dbClient;
private final UserSession userSession;

public UserPermissionChanger(DbClient dbClient, UserSession userSession) {
public UserPermissionChanger(DbClient dbClient) {
this.dbClient = dbClient;
this.userSession = userSession;
}

public boolean apply(DbSession dbSession, UserPermissionChange change) {
checkProjectAdminUserByComponentUuid(userSession, change.getProjectUuid());

if (shouldSkipChange(dbSession, change)) {
return false;
}

+ 7
- 1
server/sonar-server/src/main/java/org/sonar/server/permission/ws/AddGroupAction.java View File

@@ -29,9 +29,11 @@ import org.sonar.server.permission.GroupPermissionChange;
import org.sonar.server.permission.PermissionChange;
import org.sonar.server.permission.PermissionUpdater;
import org.sonar.server.permission.ProjectId;
import org.sonar.server.user.UserSession;
import org.sonar.server.usergroups.ws.GroupIdOrAnyone;

import static java.util.Arrays.asList;
import static org.sonar.server.permission.PermissionPrivilegeChecker.checkAdministrationPermission;
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createGroupIdParameter;
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createGroupNameParameter;
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createPermissionParameter;
@@ -43,11 +45,13 @@ public class AddGroupAction implements PermissionsWsAction {
public static final String ACTION = "add_group";

private final DbClient dbClient;
private final UserSession userSession;
private final PermissionUpdater permissionUpdater;
private final PermissionWsSupport support;

public AddGroupAction(DbClient dbClient, PermissionUpdater permissionUpdater, PermissionWsSupport support) {
public AddGroupAction(DbClient dbClient, UserSession userSession, PermissionUpdater permissionUpdater, PermissionWsSupport support) {
this.dbClient = dbClient;
this.userSession = userSession;
this.permissionUpdater = permissionUpdater;
this.support = support;
}
@@ -75,6 +79,8 @@ public class AddGroupAction implements PermissionsWsAction {
GroupIdOrAnyone group = support.findGroup(dbSession, request);
Optional<ProjectId> projectId = support.findProject(dbSession, request);

checkAdministrationPermission(userSession, projectId);

PermissionChange change = new GroupPermissionChange(
PermissionChange.Operation.ADD,
request.mandatoryParam(PARAM_PERMISSION),

+ 8
- 1
server/sonar-server/src/main/java/org/sonar/server/permission/ws/AddUserAction.java View File

@@ -31,8 +31,10 @@ import org.sonar.server.permission.PermissionUpdater;
import org.sonar.server.permission.ProjectId;
import org.sonar.server.permission.UserId;
import org.sonar.server.permission.UserPermissionChange;
import org.sonar.server.user.UserSession;

import static java.util.Arrays.asList;
import static org.sonar.server.permission.PermissionPrivilegeChecker.checkAdministrationPermission;
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createOrganizationParameter;
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createPermissionParameter;
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createProjectParameters;
@@ -46,11 +48,13 @@ public class AddUserAction implements PermissionsWsAction {
public static final String ACTION = "add_user";

private final DbClient dbClient;
private final UserSession userSession;
private final PermissionUpdater permissionUpdater;
private final PermissionWsSupport support;

public AddUserAction(DbClient dbClient, PermissionUpdater permissionUpdater, PermissionWsSupport support) {
public AddUserAction(DbClient dbClient, UserSession userSession, PermissionUpdater permissionUpdater, PermissionWsSupport support) {
this.dbClient = dbClient;
this.userSession = userSession;
this.permissionUpdater = permissionUpdater;
this.support = support;
}
@@ -77,6 +81,9 @@ public class AddUserAction implements PermissionsWsAction {
UserId user = support.findUser(dbSession, request.mandatoryParam(PARAM_USER_LOGIN));
Optional<ProjectId> projectId = support.findProject(dbSession, request);
OrganizationDto org = support.findOrganization(dbSession, request.param(PARAM_ORGANIZATION_KEY));

checkAdministrationPermission(userSession, projectId);

PermissionChange change = new UserPermissionChange(
PermissionChange.Operation.ADD,
org.getUuid(),

+ 2
- 2
server/sonar-server/src/main/java/org/sonar/server/permission/ws/GroupsAction.java View File

@@ -46,7 +46,7 @@ import static java.util.Collections.emptyList;
import static org.sonar.db.permission.PermissionQuery.DEFAULT_PAGE_SIZE;
import static org.sonar.db.permission.PermissionQuery.RESULTS_MAX_SIZE;
import static org.sonar.db.permission.PermissionQuery.SEARCH_QUERY_MIN_LENGTH;
import static org.sonar.server.permission.PermissionPrivilegeChecker.checkProjectAdminUserByComponentUuid;
import static org.sonar.server.permission.PermissionPrivilegeChecker.checkAdministrationPermission;
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createPermissionParameter;
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createProjectParameters;
import static org.sonar.server.ws.WsUtils.writeProtobuf;
@@ -87,7 +87,7 @@ public class GroupsAction implements PermissionsWsAction {
public void handle(Request request, Response response) throws Exception {
try (DbSession dbSession = dbClient.openSession(false)) {
Optional<ProjectId> projectId = support.findProject(dbSession, request);
checkProjectAdminUserByComponentUuid(userSession, projectId.isPresent() ? projectId.get().getUuid() : null);
checkAdministrationPermission(userSession, projectId);

PermissionQuery query = buildPermissionQuery(request, projectId);
// TODO validatePermission(groupsRequest.getPermission(), wsProjectRef);

+ 0
- 10
server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionsWsModule.java View File

@@ -20,11 +20,6 @@
package org.sonar.server.permission.ws;

import org.sonar.core.platform.Module;
import org.sonar.db.permission.PermissionRepository;
import org.sonar.server.permission.GroupPermissionChanger;
import org.sonar.server.permission.PermissionService;
import org.sonar.server.permission.PermissionUpdater;
import org.sonar.server.permission.UserPermissionChanger;
import org.sonar.server.permission.ws.template.AddGroupToTemplateAction;
import org.sonar.server.permission.ws.template.AddProjectCreatorToTemplateAction;
import org.sonar.server.permission.ws.template.AddUserToTemplateAction;
@@ -73,11 +68,6 @@ public class PermissionsWsModule extends Module {
TemplateGroupsAction.class,
BulkApplyTemplateAction.class,
// utility classes
PermissionRepository.class,
PermissionService.class,
PermissionUpdater.class,
UserPermissionChanger.class,
GroupPermissionChanger.class,
SearchProjectPermissionsDataLoader.class,
SearchTemplatesDataLoader.class,
PermissionWsSupport.class,

+ 7
- 1
server/sonar-server/src/main/java/org/sonar/server/permission/ws/RemoveGroupAction.java View File

@@ -29,9 +29,11 @@ import org.sonar.server.permission.GroupPermissionChange;
import org.sonar.server.permission.PermissionChange;
import org.sonar.server.permission.PermissionUpdater;
import org.sonar.server.permission.ProjectId;
import org.sonar.server.user.UserSession;
import org.sonar.server.usergroups.ws.GroupIdOrAnyone;

import static java.util.Arrays.asList;
import static org.sonar.server.permission.PermissionPrivilegeChecker.checkAdministrationPermission;
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createGroupIdParameter;
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createGroupNameParameter;
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createPermissionParameter;
@@ -43,11 +45,13 @@ public class RemoveGroupAction implements PermissionsWsAction {
public static final String ACTION = "remove_group";

private final DbClient dbClient;
private final UserSession userSession;
private final PermissionUpdater permissionUpdater;
private final PermissionWsSupport support;

public RemoveGroupAction(DbClient dbClient, PermissionUpdater permissionUpdater, PermissionWsSupport support) {
public RemoveGroupAction(DbClient dbClient, UserSession userSession, PermissionUpdater permissionUpdater, PermissionWsSupport support) {
this.dbClient = dbClient;
this.userSession = userSession;
this.permissionUpdater = permissionUpdater;
this.support = support;
}
@@ -75,6 +79,8 @@ public class RemoveGroupAction implements PermissionsWsAction {
GroupIdOrAnyone group = support.findGroup(dbSession, request);
Optional<ProjectId> projectId = support.findProject(dbSession, request);

checkAdministrationPermission(userSession, projectId);

PermissionChange change = new GroupPermissionChange(
PermissionChange.Operation.REMOVE,
request.mandatoryParam(PARAM_PERMISSION),

+ 7
- 1
server/sonar-server/src/main/java/org/sonar/server/permission/ws/RemoveUserAction.java View File

@@ -31,8 +31,10 @@ import org.sonar.server.permission.PermissionUpdater;
import org.sonar.server.permission.ProjectId;
import org.sonar.server.permission.UserId;
import org.sonar.server.permission.UserPermissionChange;
import org.sonar.server.user.UserSession;

import static java.util.Arrays.asList;
import static org.sonar.server.permission.PermissionPrivilegeChecker.checkAdministrationPermission;
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createOrganizationParameter;
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createPermissionParameter;
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createProjectParameters;
@@ -46,11 +48,13 @@ public class RemoveUserAction implements PermissionsWsAction {
public static final String ACTION = "remove_user";

private final DbClient dbClient;
private final UserSession userSession;
private final PermissionUpdater permissionUpdater;
private final PermissionWsSupport support;

public RemoveUserAction(DbClient dbClient, PermissionUpdater permissionUpdater, PermissionWsSupport support) {
public RemoveUserAction(DbClient dbClient, UserSession userSession, PermissionUpdater permissionUpdater, PermissionWsSupport support) {
this.dbClient = dbClient;
this.userSession = userSession;
this.permissionUpdater = permissionUpdater;
this.support = support;
}
@@ -78,6 +82,8 @@ public class RemoveUserAction implements PermissionsWsAction {
Optional<ProjectId> projectId = support.findProject(dbSession, request);
OrganizationDto org = support.findOrganization(dbSession, request.param(PARAM_ORGANIZATION_KEY));

checkAdministrationPermission(userSession, projectId);

PermissionChange change = new UserPermissionChange(
PermissionChange.Operation.REMOVE,
org.getUuid(),

+ 21
- 20
server/sonar-server/src/main/java/org/sonar/server/permission/ws/SearchProjectPermissionsAction.java View File

@@ -19,8 +19,8 @@
*/
package org.sonar.server.permission.ws;

import com.google.common.base.Optional;
import java.util.Locale;
import java.util.Optional;
import org.sonar.api.i18n.I18n;
import org.sonar.api.resources.ResourceTypes;
import org.sonar.api.server.ws.Request;
@@ -30,7 +30,9 @@ import org.sonar.api.server.ws.WebService.Param;
import org.sonar.api.utils.Paging;
import org.sonar.core.permission.ProjectPermissions;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.component.ComponentDto;
import org.sonar.server.permission.ProjectId;
import org.sonar.server.user.UserSession;
import org.sonarqube.ws.Common;
import org.sonarqube.ws.WsPermissions.Permission;
@@ -38,9 +40,7 @@ import org.sonarqube.ws.WsPermissions.SearchProjectPermissionsWsResponse;
import org.sonarqube.ws.WsPermissions.SearchProjectPermissionsWsResponse.Project;
import org.sonarqube.ws.client.permission.SearchProjectPermissionsWsRequest;

import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdminUser;
import static org.sonar.server.permission.PermissionPrivilegeChecker.checkProjectAdminUserByComponentKey;
import static org.sonar.server.permission.PermissionPrivilegeChecker.checkProjectAdminUserByComponentUuid;
import static org.sonar.server.permission.PermissionPrivilegeChecker.checkAdministrationPermission;
import static org.sonar.server.permission.ws.PermissionRequestValidator.validateQualifier;
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createProjectParameters;
import static org.sonar.server.permission.ws.ProjectWsRef.newOptionalWsProjectRef;
@@ -60,13 +60,16 @@ public class SearchProjectPermissionsAction implements PermissionsWsAction {
private final I18n i18n;
private final ResourceTypes resourceTypes;
private final SearchProjectPermissionsDataLoader dataLoader;
private final PermissionWsSupport wsSupport;

public SearchProjectPermissionsAction(DbClient dbClient, UserSession userSession, I18n i18n, ResourceTypes resourceTypes, SearchProjectPermissionsDataLoader dataLoader) {
public SearchProjectPermissionsAction(DbClient dbClient, UserSession userSession, I18n i18n, ResourceTypes resourceTypes,
SearchProjectPermissionsDataLoader dataLoader, PermissionWsSupport wsSupport) {
this.dbClient = dbClient;
this.userSession = userSession;
this.i18n = i18n;
this.resourceTypes = resourceTypes;
this.dataLoader = dataLoader;
this.wsSupport = wsSupport;
}

@Override
@@ -97,10 +100,12 @@ public class SearchProjectPermissionsAction implements PermissionsWsAction {
}

private SearchProjectPermissionsWsResponse doHandle(SearchProjectPermissionsWsRequest request) {
checkRequestAndPermissions(request);
validateQualifier(request.getQualifier(), resourceTypes);
SearchProjectPermissionsData data = dataLoader.load(request);
return buildResponse(data);
try (DbSession dbSession = dbClient.openSession(false)) {
checkAuthorized(dbSession, request);
validateQualifier(request.getQualifier(), resourceTypes);
SearchProjectPermissionsData data = dataLoader.load(dbSession, request);
return buildResponse(data);
}
}

private static SearchProjectPermissionsWsRequest toSearchProjectPermissionsWsRequest(Request request) {
@@ -113,19 +118,15 @@ public class SearchProjectPermissionsAction implements PermissionsWsAction {
.setQuery(request.param(Param.TEXT_QUERY));
}

private void checkRequestAndPermissions(SearchProjectPermissionsWsRequest request) {
Optional<ProjectWsRef> project = newOptionalWsProjectRef(request.getProjectId(), request.getProjectKey());
boolean hasProject = project.isPresent();
boolean hasProjectUuid = hasProject && project.get().uuid() != null;
boolean hasProjectKey = hasProject && project.get().key() != null;

if (hasProjectUuid) {
checkProjectAdminUserByComponentUuid(userSession, project.get().uuid());
} else if (hasProjectKey) {
checkProjectAdminUserByComponentKey(userSession, project.get().key());
private void checkAuthorized(DbSession dbSession, SearchProjectPermissionsWsRequest request) {
com.google.common.base.Optional<ProjectWsRef> projectRef = newOptionalWsProjectRef(request.getProjectId(), request.getProjectKey());
Optional<ProjectId> projectId;
if (projectRef.isPresent()) {
projectId = Optional.of(wsSupport.findProject(dbSession, projectRef.get()));
} else {
checkGlobalAdminUser(userSession);
projectId = Optional.empty();
}
checkAdministrationPermission(userSession, projectId);
}

private SearchProjectPermissionsWsResponse buildResponse(SearchProjectPermissionsData data) {

+ 11
- 13
server/sonar-server/src/main/java/org/sonar/server/permission/ws/SearchProjectPermissionsDataLoader.java View File

@@ -38,8 +38,8 @@ import org.sonarqube.ws.client.permission.SearchProjectPermissionsWsRequest;
import static java.util.Collections.singletonList;
import static org.sonar.api.utils.Paging.forPageIndex;
import static org.sonar.server.component.ResourceTypeFunctions.RESOURCE_TYPE_TO_QUALIFIER;
import static org.sonar.server.permission.ws.SearchProjectPermissionsData.newBuilder;
import static org.sonar.server.permission.ws.ProjectWsRef.newOptionalWsProjectRef;
import static org.sonar.server.permission.ws.SearchProjectPermissionsData.newBuilder;

public class SearchProjectPermissionsDataLoader {
private final DbClient dbClient;
@@ -52,20 +52,18 @@ public class SearchProjectPermissionsDataLoader {
this.rootQualifiers = Collections2.transform(resourceTypes.getRoots(), RESOURCE_TYPE_TO_QUALIFIER).toArray(new String[resourceTypes.getRoots().size()]);
}

SearchProjectPermissionsData load(SearchProjectPermissionsWsRequest request) {
try (DbSession dbSession = dbClient.openSession(false)) {
SearchProjectPermissionsData.Builder data = newBuilder();
int countRootComponents = countRootComponents(dbSession, request);
List<ComponentDto> rootComponents = searchRootComponents(dbSession, request, paging(request, countRootComponents));
List<Long> rootComponentIds = Lists.transform(rootComponents, ComponentDto::getId);
SearchProjectPermissionsData load(DbSession dbSession, SearchProjectPermissionsWsRequest request) {
SearchProjectPermissionsData.Builder data = newBuilder();
int countRootComponents = countRootComponents(dbSession, request);
List<ComponentDto> rootComponents = searchRootComponents(dbSession, request, paging(request, countRootComponents));
List<Long> rootComponentIds = Lists.transform(rootComponents, ComponentDto::getId);

data.rootComponents(rootComponents)
.paging(paging(request, countRootComponents))
.userCountByProjectIdAndPermission(userCountByRootComponentIdAndPermission(dbSession, rootComponentIds))
.groupCountByProjectIdAndPermission(groupCountByRootComponentIdAndPermission(dbSession, rootComponentIds));
data.rootComponents(rootComponents)
.paging(paging(request, countRootComponents))
.userCountByProjectIdAndPermission(userCountByRootComponentIdAndPermission(dbSession, rootComponentIds))
.groupCountByProjectIdAndPermission(groupCountByRootComponentIdAndPermission(dbSession, rootComponentIds));

return data.build();
}
return data.build();
}

private static Paging paging(SearchProjectPermissionsWsRequest request, int total) {

+ 2
- 2
server/sonar-server/src/main/java/org/sonar/server/permission/ws/UsersAction.java View File

@@ -44,7 +44,7 @@ import static java.util.Collections.emptyList;
import static org.sonar.db.permission.PermissionQuery.DEFAULT_PAGE_SIZE;
import static org.sonar.db.permission.PermissionQuery.RESULTS_MAX_SIZE;
import static org.sonar.db.permission.PermissionQuery.SEARCH_QUERY_MIN_LENGTH;
import static org.sonar.server.permission.PermissionPrivilegeChecker.checkProjectAdminUserByComponentUuid;
import static org.sonar.server.permission.PermissionPrivilegeChecker.checkAdministrationPermission;
import static org.sonar.server.permission.ws.PermissionRequestValidator.validateGlobalPermission;
import static org.sonar.server.permission.ws.PermissionRequestValidator.validateProjectPermission;
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createPermissionParameter;
@@ -90,7 +90,7 @@ public class UsersAction implements PermissionsWsAction {
public void handle(Request request, Response response) throws Exception {
try (DbSession dbSession = dbClient.openSession(false)) {
Optional<ProjectId> projectId = support.findProject(dbSession, request);
checkProjectAdminUserByComponentUuid(userSession, projectId.isPresent() ? projectId.get().getUuid() : null);
checkAdministrationPermission(userSession, projectId);

PermissionQuery query = buildPermissionQuery(request, projectId);
List<UserDto> users = findUsers(dbSession, query);

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

@@ -33,6 +33,7 @@ import org.sonar.ce.CeModule;
import org.sonar.ce.settings.ProjectSettingsFactory;
import org.sonar.core.component.DefaultResourceTypes;
import org.sonar.core.timemachine.Periods;
import org.sonar.db.permission.PermissionRepository;
import org.sonar.server.authentication.AuthenticationModule;
import org.sonar.server.batch.BatchWsModule;
import org.sonar.server.ce.ws.CeWsModule;
@@ -135,6 +136,10 @@ import org.sonar.server.notification.NotificationService;
import org.sonar.server.notification.email.AlertsEmailTemplate;
import org.sonar.server.notification.email.EmailNotificationChannel;
import org.sonar.server.organization.ws.OrganizationsWsModule;
import org.sonar.server.permission.GroupPermissionChanger;
import org.sonar.server.permission.PermissionService;
import org.sonar.server.permission.PermissionUpdater;
import org.sonar.server.permission.UserPermissionChanger;
import org.sonar.server.permission.ws.PermissionsWsModule;
import org.sonar.server.platform.BackendCleanup;
import org.sonar.server.platform.PersistentSettings;
@@ -426,6 +431,11 @@ public class PlatformLevel4 extends PlatformLevel {

// permissions
PermissionsWsModule.class,
PermissionRepository.class,
PermissionService.class,
PermissionUpdater.class,
UserPermissionChanger.class,
GroupPermissionChanger.class,

// components
ProjectsWsModule.class,

+ 1
- 40
server/sonar-server/src/test/java/org/sonar/server/permission/GroupPermissionChangerTest.java View File

@@ -34,12 +34,9 @@ import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.organization.OrganizationTesting;
import org.sonar.db.user.GroupDto;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.usergroups.ws.GroupIdOrAnyone;

import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;

public class GroupPermissionChangerTest {

@@ -49,8 +46,7 @@ public class GroupPermissionChangerTest {
@Rule
public ExpectedException expectedException = ExpectedException.none();

private UserSessionRule userSession = UserSessionRule.standalone();
private GroupPermissionChanger underTest = new GroupPermissionChanger(db.getDbClient(), userSession);
private GroupPermissionChanger underTest = new GroupPermissionChanger(db.getDbClient());
private OrganizationDto org;
private GroupDto group;
private ComponentDto project;
@@ -66,7 +62,6 @@ public class GroupPermissionChangerTest {
public void add_permission_to_group() {
GroupIdOrAnyone groupId = new GroupIdOrAnyone(group);

loginAsAdmin();
apply(new GroupPermissionChange(PermissionChange.Operation.ADD, GlobalPermissions.QUALITY_GATE_ADMIN, null, groupId));

assertThat(db.users().selectGroupPermissions(group, null)).containsOnly(GlobalPermissions.QUALITY_GATE_ADMIN);
@@ -76,7 +71,6 @@ public class GroupPermissionChangerTest {
public void add_project_permission_to_group() {
GroupIdOrAnyone groupId = new GroupIdOrAnyone(group);

loginAsAdmin();
apply(new GroupPermissionChange(PermissionChange.Operation.ADD, UserRole.ISSUE_ADMIN, new ProjectId(project), groupId));

assertThat(db.users().selectGroupPermissions(group, null)).isEmpty();
@@ -87,7 +81,6 @@ public class GroupPermissionChangerTest {
public void add_permission_to_anyone() {
GroupIdOrAnyone groupId = new GroupIdOrAnyone(db.getDefaultOrganization().getUuid(), null);

loginAsAdmin();
apply(new GroupPermissionChange(PermissionChange.Operation.ADD, GlobalPermissions.QUALITY_GATE_ADMIN, null, groupId));

assertThat(db.users().selectGroupPermissions(group, null)).isEmpty();
@@ -98,29 +91,17 @@ public class GroupPermissionChangerTest {
public void add_project_permission_to_anyone() {
GroupIdOrAnyone groupId = new GroupIdOrAnyone(db.getDefaultOrganization().getUuid(), null);

loginAsAdmin();
apply(new GroupPermissionChange(PermissionChange.Operation.ADD, UserRole.ISSUE_ADMIN, new ProjectId(project), groupId));

assertThat(db.users().selectAnyonePermissions(null)).isEmpty();
assertThat(db.users().selectAnyonePermissions(project)).containsOnly(UserRole.ISSUE_ADMIN);
}

@Test
public void fail_to_add_permission_if_not_admin() {
GroupIdOrAnyone groupId = new GroupIdOrAnyone(db.getDefaultOrganization().getUuid(), null);

expectedException.expect(ForbiddenException.class);

userSession.login("a_guy");
underTest.apply(db.getSession(), new GroupPermissionChange(PermissionChange.Operation.ADD, UserRole.ISSUE_ADMIN, new ProjectId(project), groupId));
}

@Test
public void do_nothing_when_adding_permission_that_already_exists() {
GroupIdOrAnyone groupId = new GroupIdOrAnyone(group);
db.users().insertPermissionOnGroup(group, GlobalPermissions.QUALITY_GATE_ADMIN);

loginAsAdmin();
apply(new GroupPermissionChange(PermissionChange.Operation.ADD, GlobalPermissions.QUALITY_GATE_ADMIN, null, groupId));

assertThat(db.users().selectGroupPermissions(group, null)).containsOnly(GlobalPermissions.QUALITY_GATE_ADMIN);
@@ -133,7 +114,6 @@ public class GroupPermissionChangerTest {
expectedException.expect(BadRequestException.class);
expectedException.expectMessage("Invalid project permission 'gateadmin'. Valid values are [admin, codeviewer, issueadmin, scan, user]");

loginAsAdmin();
apply(new GroupPermissionChange(PermissionChange.Operation.ADD, GlobalPermissions.QUALITY_GATE_ADMIN, new ProjectId(project), groupId));
}

@@ -144,7 +124,6 @@ public class GroupPermissionChangerTest {
expectedException.expect(BadRequestException.class);
expectedException.expectMessage("Invalid global permission 'issueadmin'. Valid values are [admin, profileadmin, gateadmin, scan, provisioning]");

loginAsAdmin();
apply(new GroupPermissionChange(PermissionChange.Operation.ADD, UserRole.ISSUE_ADMIN, null, groupId));
}

@@ -154,7 +133,6 @@ public class GroupPermissionChangerTest {
db.users().insertPermissionOnGroup(group, GlobalPermissions.QUALITY_GATE_ADMIN);
db.users().insertPermissionOnGroup(group, GlobalPermissions.PROVISIONING);

loginAsAdmin();
apply(new GroupPermissionChange(PermissionChange.Operation.REMOVE, GlobalPermissions.QUALITY_GATE_ADMIN, null, groupId));

assertThat(db.users().selectGroupPermissions(group, null)).containsOnly(GlobalPermissions.PROVISIONING);
@@ -167,7 +145,6 @@ public class GroupPermissionChangerTest {
db.users().insertProjectPermissionOnGroup(group, UserRole.ISSUE_ADMIN, project);
db.users().insertProjectPermissionOnGroup(group, UserRole.CODEVIEWER, project);

loginAsAdmin();
apply(new GroupPermissionChange(PermissionChange.Operation.REMOVE, UserRole.ISSUE_ADMIN, new ProjectId(project), groupId));

assertThat(db.users().selectGroupPermissions(group, null)).containsOnly(GlobalPermissions.QUALITY_GATE_ADMIN);
@@ -178,23 +155,12 @@ public class GroupPermissionChangerTest {
public void do_not_fail_if_removing_a_permission_that_does_not_exist() {
GroupIdOrAnyone groupId = new GroupIdOrAnyone(group);

loginAsAdmin();
apply(new GroupPermissionChange(PermissionChange.Operation.REMOVE, UserRole.ISSUE_ADMIN, new ProjectId(project), groupId));

assertThat(db.users().selectGroupPermissions(group, null)).isEmpty();
assertThat(db.users().selectGroupPermissions(group, project)).isEmpty();
}

@Test
public void fail_to_remove_permission_if_not_admin() {
GroupIdOrAnyone groupId = new GroupIdOrAnyone(db.getDefaultOrganization().getUuid(), null);

expectedException.expect(ForbiddenException.class);

userSession.login("a_guy");
underTest.apply(db.getSession(), new GroupPermissionChange(PermissionChange.Operation.REMOVE, UserRole.ISSUE_ADMIN, new ProjectId(project), groupId));
}

@Test
public void fail_to_remove_sysadmin_permission_if_no_more_sysadmins() {
GroupIdOrAnyone groupId = new GroupIdOrAnyone(group);
@@ -203,7 +169,6 @@ public class GroupPermissionChangerTest {
expectedException.expect(BadRequestException.class);
expectedException.expectMessage("Last group with 'admin' permission. Permission cannot be removed.");

loginAsAdmin();
underTest.apply(db.getSession(), new GroupPermissionChange(PermissionChange.Operation.REMOVE, GlobalPermissions.SYSTEM_ADMIN, null, groupId));
}

@@ -211,8 +176,4 @@ public class GroupPermissionChangerTest {
underTest.apply(db.getSession(), change);
db.commit();
}

private void loginAsAdmin() {
userSession.login("admin").setGlobalPermissions(SYSTEM_ADMIN);
}
}

+ 42
- 7
server/sonar-server/src/test/java/org/sonar/server/permission/ws/AddGroupActionTest.java View File

@@ -31,6 +31,8 @@ import org.sonar.server.exceptions.ServerException;
import org.sonar.server.ws.WsTester;

import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.api.web.UserRole.ISSUE_ADMIN;
import static org.sonar.core.permission.GlobalPermissions.PROVISIONING;
import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
import static org.sonar.db.component.ComponentTesting.newProjectDto;
import static org.sonar.db.component.ComponentTesting.newView;
@@ -49,7 +51,7 @@ public class AddGroupActionTest extends BasePermissionWsTest<AddGroupAction> {

@Override
protected AddGroupAction buildWsAction() {
return new AddGroupAction(db.getDbClient(), newPermissionUpdater(), newPermissionWsSupport());
return new AddGroupAction(db.getDbClient(), userSession, newPermissionUpdater(), newPermissionWsSupport());
}

@Test
@@ -221,17 +223,50 @@ public class AddGroupActionTest extends BasePermissionWsTest<AddGroupAction> {
.execute();
}

@Test(expected = ForbiddenException.class)
public void require_admin_permission() throws Exception {
@Test
public void adding_global_permission_fails_if_not_administrator_of_organization() throws Exception {
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), "sonar-administrators");
ComponentDto project = db.components().insertComponent(newProjectDto(A_PROJECT_UUID).setKey(A_PROJECT_KEY));
userSession.login("not-admin");
userSession.login();

expectedException.expect(ForbiddenException.class);

newRequest()
.setParam(PARAM_GROUP_NAME, group.getName())
.setParam(PARAM_PERMISSION, PROVISIONING)
.execute();
}

@Test
public void adding_project_permission_fails_if_not_administrator_of_project() throws Exception {
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), "sonar-administrators");
ComponentDto project = db.components().insertProject();
userSession.login();

expectedException.expect(ForbiddenException.class);

newRequest()
.setParam(PARAM_GROUP_NAME, group.getName())
.setParam(PARAM_PERMISSION, PROVISIONING)
.setParam(PARAM_PROJECT_KEY, project.key())
.execute();
}

/**
* User is project administrator but not system administrator
*/
@Test
public void adding_project_permission_is_allowed_to_project_administrators() throws Exception {
GroupDto group = db.users().insertGroup(defaultOrganizationProvider.getDto(), "sonar-administrators");
ComponentDto project = db.components().insertProject();
userSession.login().addProjectUuidPermissions(UserRole.ADMIN, project.uuid());

newRequest()
.setParam(PARAM_GROUP_NAME, group.getName())
.setParam(PARAM_PERMISSION, SYSTEM_ADMIN)
.setParam(PARAM_PROJECT_ID, project.uuid())
.setParam(PARAM_PERMISSION, ISSUE_ADMIN)
.execute();

assertThat(db.users().selectGroupPermissions(group, project)).containsOnly(ISSUE_ADMIN);
}

private WsTester.TestRequest newRequest() {
@@ -239,7 +274,7 @@ public class AddGroupActionTest extends BasePermissionWsTest<AddGroupAction> {
}

private void loginAsAdmin() {
userSession.login("admin").setGlobalPermissions(SYSTEM_ADMIN);
userSession.login().setGlobalPermissions(SYSTEM_ADMIN);
}

}

+ 51
- 8
server/sonar-server/src/test/java/org/sonar/server/permission/ws/AddUserActionTest.java View File

@@ -25,10 +25,12 @@ import org.sonar.api.web.UserRole;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.user.UserDto;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.exceptions.ServerException;

import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.api.web.UserRole.ISSUE_ADMIN;
import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
import static org.sonar.db.component.ComponentTesting.newFileDto;
import static org.sonar.db.component.ComponentTesting.newProjectDto;
@@ -42,9 +44,6 @@ import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_U

public class AddUserActionTest extends BasePermissionWsTest<AddUserAction> {

private static final String A_PROJECT_UUID = "project-uuid";
private static final String A_PROJECT_KEY = "project-key";

private UserDto user;

@Before
@@ -54,7 +53,7 @@ public class AddUserActionTest extends BasePermissionWsTest<AddUserAction> {

@Override
protected AddUserAction buildWsAction() {
return new AddUserAction(db.getDbClient(), newPermissionUpdater(), newPermissionWsSupport());
return new AddUserAction(db.getDbClient(), userSession, newPermissionUpdater(), newPermissionWsSupport());
}

@Test
@@ -70,7 +69,7 @@ public class AddUserActionTest extends BasePermissionWsTest<AddUserAction> {

@Test
public void add_permission_to_project_referenced_by_its_id() throws Exception {
ComponentDto project = db.components().insertComponent(newProjectDto("project-uuid").setKey("project-key"));
ComponentDto project = db.components().insertProject();

loginAsAdmin();
wsTester.newPostRequest(CONTROLLER, ACTION)
@@ -85,7 +84,7 @@ public class AddUserActionTest extends BasePermissionWsTest<AddUserAction> {

@Test
public void add_permission_to_project_referenced_by_its_key() throws Exception {
ComponentDto project = db.components().insertComponent(newProjectDto("project-uuid").setKey("project-key"));
ComponentDto project = db.components().insertProject();

loginAsAdmin();
wsTester.newPostRequest(CONTROLLER, ACTION)
@@ -188,7 +187,7 @@ public class AddUserActionTest extends BasePermissionWsTest<AddUserAction> {

@Test
public void fail_when_project_uuid_and_project_key_are_provided() throws Exception {
db.components().insertComponent(newProjectDto(A_PROJECT_UUID).setKey(A_PROJECT_KEY));
db.components().insertProject();
loginAsAdmin();

expectedException.expect(BadRequestException.class);
@@ -202,7 +201,51 @@ public class AddUserActionTest extends BasePermissionWsTest<AddUserAction> {
.execute();
}

@Test
public void adding_global_permission_fails_if_not_administrator_of_organization() throws Exception {
userSession.login();

expectedException.expect(ForbiddenException.class);

wsTester.newPostRequest(CONTROLLER, ACTION)
.setParam(PARAM_USER_LOGIN, user.getLogin())
.setParam(PARAM_PERMISSION, SYSTEM_ADMIN)
.execute();
}

@Test
public void adding_project_permission_fails_if_not_administrator_of_project() throws Exception {
ComponentDto project = db.components().insertProject();
userSession.login();

expectedException.expect(ForbiddenException.class);

wsTester.newPostRequest(CONTROLLER, ACTION)
.setParam(PARAM_USER_LOGIN, user.getLogin())
.setParam(PARAM_PERMISSION, SYSTEM_ADMIN)
.setParam(PARAM_PROJECT_KEY, project.getKey())
.execute();
}

/**
* User is project administrator but not system administrator
*/
@Test
public void adding_project_permission_is_allowed_to_project_administrators() throws Exception {
ComponentDto project = db.components().insertProject();

userSession.login().addProjectUuidPermissions(UserRole.ADMIN, project.uuid());

wsTester.newPostRequest(CONTROLLER, ACTION)
.setParam(PARAM_USER_LOGIN, user.getLogin())
.setParam(PARAM_PROJECT_KEY, project.getKey())
.setParam(PARAM_PERMISSION, UserRole.ISSUE_ADMIN)
.execute();

assertThat(db.users().selectUserPermissions(user, project)).containsOnly(ISSUE_ADMIN);
}

private void loginAsAdmin() {
userSession.login("admin").setGlobalPermissions(SYSTEM_ADMIN);
userSession.login().setGlobalPermissions(SYSTEM_ADMIN);
}
}

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

@@ -76,8 +76,8 @@ public abstract class BasePermissionWsTest<A extends PermissionsWsAction> {
protected PermissionUpdater newPermissionUpdater() {
return new PermissionUpdater(db.getDbClient(),
mock(IssueAuthorizationIndexer.class),
new UserPermissionChanger(db.getDbClient(), userSession),
new GroupPermissionChanger(db.getDbClient(), userSession));
new UserPermissionChanger(db.getDbClient()),
new GroupPermissionChanger(db.getDbClient()));
}

protected PermissionTemplateDto insertTemplate() {

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

@@ -29,6 +29,6 @@ public class PermissionsWsModuleTest {
public void verify_count_of_added_components() {
ComponentContainer container = new ComponentContainer();
new PermissionsWsModule().configure(container);
assertThat(container.size()).isEqualTo(2 + 33);
assertThat(container.size()).isEqualTo(2 + 28);
}
}

+ 70
- 11
server/sonar-server/src/test/java/org/sonar/server/permission/ws/RemoveGroupActionTest.java View File

@@ -21,15 +21,18 @@ package org.sonar.server.permission.ws;

import org.junit.Before;
import org.junit.Test;
import org.sonar.api.web.UserRole;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.user.GroupDto;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.exceptions.ServerException;
import org.sonar.server.ws.WsTester;

import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.api.web.UserRole.ADMIN;
import static org.sonar.api.web.UserRole.CODEVIEWER;
import static org.sonar.api.web.UserRole.ISSUE_ADMIN;
import static org.sonar.core.permission.GlobalPermissions.PROVISIONING;
import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
@@ -46,9 +49,6 @@ import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_P

public class RemoveGroupActionTest extends BasePermissionWsTest<RemoveGroupAction> {

private static final String A_PROJECT_UUID = "project-uuid";
private static final String A_PROJECT_KEY = "project-key";

private GroupDto aGroup;

@Before
@@ -58,15 +58,15 @@ public class RemoveGroupActionTest extends BasePermissionWsTest<RemoveGroupActio

@Override
protected RemoveGroupAction buildWsAction() {
return new RemoveGroupAction(db.getDbClient(), newPermissionUpdater(), newPermissionWsSupport());
return new RemoveGroupAction(db.getDbClient(), userSession, newPermissionUpdater(), newPermissionWsSupport());
}

@Test
public void remove_permission_using_group_name() throws Exception {
db.users().insertPermissionOnGroup(aGroup, SYSTEM_ADMIN);
db.users().insertPermissionOnGroup(aGroup, PROVISIONING);

loginAsAdmin();

newRequest()
.setParam(PARAM_GROUP_NAME, aGroup.getName())
.setParam(PARAM_PERMISSION, PROVISIONING)
@@ -79,8 +79,8 @@ public class RemoveGroupActionTest extends BasePermissionWsTest<RemoveGroupActio
public void remove_permission_using_group_id() throws Exception {
db.users().insertPermissionOnGroup(aGroup, SYSTEM_ADMIN);
db.users().insertPermissionOnGroup(aGroup, PROVISIONING);

loginAsAdmin();

newRequest()
.setParam(PARAM_GROUP_ID, aGroup.getId().toString())
.setParam(PARAM_PERMISSION, PROVISIONING)
@@ -91,7 +91,7 @@ public class RemoveGroupActionTest extends BasePermissionWsTest<RemoveGroupActio

@Test
public void remove_project_permission() throws Exception {
ComponentDto project = db.components().insertComponent(newProjectDto(A_PROJECT_UUID).setKey(A_PROJECT_KEY));
ComponentDto project = db.components().insertProject();
db.users().insertPermissionOnGroup(aGroup, SYSTEM_ADMIN);
db.users().insertProjectPermissionOnGroup(aGroup, ADMIN, project);
db.users().insertProjectPermissionOnGroup(aGroup, ISSUE_ADMIN, project);
@@ -127,7 +127,7 @@ public class RemoveGroupActionTest extends BasePermissionWsTest<RemoveGroupActio

@Test
public void remove_with_project_key() throws Exception {
ComponentDto project = db.components().insertComponent(newProjectDto(A_PROJECT_UUID).setKey(A_PROJECT_KEY));
ComponentDto project = db.components().insertProject();
db.users().insertPermissionOnGroup(aGroup, SYSTEM_ADMIN);
db.users().insertProjectPermissionOnGroup(aGroup, ADMIN, project);
db.users().insertProjectPermissionOnGroup(aGroup, ISSUE_ADMIN, project);
@@ -160,6 +160,8 @@ public class RemoveGroupActionTest extends BasePermissionWsTest<RemoveGroupActio

@Test
public void fail_when_project_does_not_exist() throws Exception {
loginAsAdmin();

expectedException.expect(NotFoundException.class);
expectedException.expectMessage("Project id 'unknown-project-uuid' not found");

@@ -172,6 +174,8 @@ public class RemoveGroupActionTest extends BasePermissionWsTest<RemoveGroupActio

@Test
public void fail_when_project_project_permission_without_project() throws Exception {
loginAsAdmin();

expectedException.expect(BadRequestException.class);
expectedException.expectMessage("Invalid global permission 'issueadmin'. Valid values are [admin, profileadmin, gateadmin, scan, provisioning]");

@@ -183,7 +187,8 @@ public class RemoveGroupActionTest extends BasePermissionWsTest<RemoveGroupActio

@Test
public void fail_when_component_is_not_a_project() throws Exception {
ComponentDto file = db.components().insertComponent(newFileDto(newProjectDto(A_PROJECT_UUID), null, "file-uuid"));
ComponentDto file = db.components().insertComponent(newFileDto(newProjectDto(), null, "file-uuid"));
loginAsAdmin();

expectedException.expect(BadRequestException.class);
expectedException.expectMessage("Component 'KEY_file-uuid' (id: file-uuid) must be a project or a module.");
@@ -197,6 +202,8 @@ public class RemoveGroupActionTest extends BasePermissionWsTest<RemoveGroupActio

@Test
public void fail_when_get_request() throws Exception {
loginAsAdmin();

expectedException.expect(ServerException.class);
expectedException.expectMessage("HTTP method POST is required");

@@ -208,6 +215,8 @@ public class RemoveGroupActionTest extends BasePermissionWsTest<RemoveGroupActio

@Test
public void fail_when_group_name_is_missing() throws Exception {
loginAsAdmin();

expectedException.expect(BadRequestException.class);
expectedException.expectMessage("Group name or group id must be provided");

@@ -218,6 +227,8 @@ public class RemoveGroupActionTest extends BasePermissionWsTest<RemoveGroupActio

@Test
public void fail_when_permission_name_and_id_are_missing() throws Exception {
loginAsAdmin();

expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("The 'permission' parameter is missing");

@@ -228,6 +239,8 @@ public class RemoveGroupActionTest extends BasePermissionWsTest<RemoveGroupActio

@Test
public void fail_when_group_id_does_not_exist() throws Exception {
loginAsAdmin();

expectedException.expect(NotFoundException.class);
expectedException.expectMessage("No group with id '42'");

@@ -239,7 +252,8 @@ public class RemoveGroupActionTest extends BasePermissionWsTest<RemoveGroupActio

@Test
public void fail_when_project_uuid_and_project_key_are_provided() throws Exception {
ComponentDto project = db.components().insertComponent(newProjectDto(A_PROJECT_UUID).setKey(A_PROJECT_KEY));
ComponentDto project = db.components().insertProject();
loginAsAdmin();

expectedException.expect(BadRequestException.class);
expectedException.expectMessage("Project id or project key can be provided, not both.");
@@ -252,12 +266,57 @@ public class RemoveGroupActionTest extends BasePermissionWsTest<RemoveGroupActio
.execute();
}

@Test
public void removing_global_permission_fails_if_not_administrator_of_organization() throws Exception {
userSession.login();

expectedException.expect(ForbiddenException.class);

newRequest()
.setParam(PARAM_GROUP_NAME, aGroup.getName())
.setParam(PARAM_PERMISSION, PROVISIONING)
.execute();
}

@Test
public void removing_project_permission_fails_if_not_administrator_of_project() throws Exception {
ComponentDto project = db.components().insertProject();
userSession.login();

expectedException.expect(ForbiddenException.class);

newRequest()
.setParam(PARAM_GROUP_NAME, aGroup.getName())
.setParam(PARAM_PERMISSION, PROVISIONING)
.setParam(PARAM_PROJECT_KEY, project.key())
.execute();
}

/**
* User is project administrator but not system administrator
*/
@Test
public void removing_project_permission_is_allowed_to_project_administrators() throws Exception {
ComponentDto project = db.components().insertProject();
db.users().insertProjectPermissionOnGroup(aGroup, CODEVIEWER, project);
db.users().insertProjectPermissionOnGroup(aGroup, ISSUE_ADMIN, project);

userSession.login().addProjectUuidPermissions(UserRole.ADMIN, project.uuid());
newRequest()
.setParam(PARAM_GROUP_NAME, aGroup.getName())
.setParam(PARAM_PROJECT_ID, project.uuid())
.setParam(PARAM_PERMISSION, ISSUE_ADMIN)
.execute();

assertThat(db.users().selectGroupPermissions(aGroup, project)).containsOnly(CODEVIEWER);
}

private WsTester.TestRequest newRequest() {
return wsTester.newPostRequest(CONTROLLER, ACTION);
}

private void loginAsAdmin() {
userSession.login("admin").setGlobalPermissions(SYSTEM_ADMIN);
userSession.login().setGlobalPermissions(SYSTEM_ADMIN);
}

}

+ 48
- 1
server/sonar-server/src/test/java/org/sonar/server/permission/ws/RemoveUserActionTest.java View File

@@ -21,9 +21,11 @@ package org.sonar.server.permission.ws;

import org.junit.Before;
import org.junit.Test;
import org.sonar.api.web.UserRole;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.user.UserDto;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.exceptions.ServerException;

@@ -59,7 +61,7 @@ public class RemoveUserActionTest extends BasePermissionWsTest<RemoveUserAction>

@Override
protected RemoveUserAction buildWsAction() {
return new RemoveUserAction(db.getDbClient(), newPermissionUpdater(), newPermissionWsSupport());
return new RemoveUserAction(db.getDbClient(), userSession, newPermissionUpdater(), newPermissionWsSupport());
}

@Test
@@ -228,6 +230,51 @@ public class RemoveUserActionTest extends BasePermissionWsTest<RemoveUserAction>
.execute();
}

@Test
public void removing_global_permission_fails_if_not_administrator_of_organization() throws Exception {
userSession.login();

expectedException.expect(ForbiddenException.class);

wsTester.newPostRequest(CONTROLLER, ACTION)
.setParam(PARAM_USER_LOGIN, user.getLogin())
.setParam(PARAM_PERMISSION, PROVISIONING)
.execute();
}

@Test
public void removing_project_permission_fails_if_not_administrator_of_project() throws Exception {
ComponentDto project = db.components().insertProject();
userSession.login();

expectedException.expect(ForbiddenException.class);

wsTester.newPostRequest(CONTROLLER, ACTION)
.setParam(PARAM_USER_LOGIN, user.getLogin())
.setParam(PARAM_PERMISSION, ISSUE_ADMIN)
.setParam(PARAM_PROJECT_KEY, project.key())
.execute();
}

/**
* User is project administrator but not system administrator
*/
@Test
public void removing_project_permission_is_allowed_to_project_administrators() throws Exception {
ComponentDto project = db.components().insertProject();
db.users().insertProjectPermissionOnUser(user, CODEVIEWER, project);
db.users().insertProjectPermissionOnUser(user, ISSUE_ADMIN, project);
userSession.login().addProjectUuidPermissions(UserRole.ADMIN, project.uuid());

wsTester.newPostRequest(CONTROLLER, ACTION)
.setParam(PARAM_USER_LOGIN, user.getLogin())
.setParam(PARAM_PROJECT_ID, project.uuid())
.setParam(PARAM_PERMISSION, ISSUE_ADMIN)
.execute();

assertThat(db.users().selectUserPermissions(user, project)).containsOnly(CODEVIEWER);
}

private void loginAsAdmin() {
userSession.login("admin").setGlobalPermissions(SYSTEM_ADMIN);
}

+ 3
- 2
server/sonar-server/src/test/java/org/sonar/server/permission/ws/SearchProjectPermissionsActionTest.java View File

@@ -65,8 +65,9 @@ public class SearchProjectPermissionsActionTest extends BasePermissionWsTest<Sea
protected SearchProjectPermissionsAction buildWsAction() {
i18n.setProjectPermissions();
ResourceTypesRule rootResourceTypes = newRootResourceTypes();
SearchProjectPermissionsDataLoader dataLoader = new SearchProjectPermissionsDataLoader(db.getDbClient(), newPermissionWsSupport(), rootResourceTypes);
return new SearchProjectPermissionsAction(db.getDbClient(), userSession, i18n, rootResourceTypes, dataLoader);
PermissionWsSupport wsSupport = newPermissionWsSupport();
SearchProjectPermissionsDataLoader dataLoader = new SearchProjectPermissionsDataLoader(db.getDbClient(), wsSupport, rootResourceTypes);
return new SearchProjectPermissionsAction(db.getDbClient(), userSession, i18n, rootResourceTypes, dataLoader, wsSupport);
}

@Test

Loading…
Cancel
Save