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