Browse Source

SONAR-6892 WS permissions/search_project_permissions filter by qualifier

tags/5.3-RC1
Teryk Bellahsene 8 years ago
parent
commit
0a8a13500a

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

@@ -21,10 +21,12 @@
package org.sonar.server.permission.ws;

import com.google.common.base.Optional;
import com.google.common.collect.FluentIterable;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import javax.annotation.Nullable;
import org.sonar.api.resources.ResourceTypes;
import org.sonar.core.permission.GlobalPermissions;
import org.sonar.core.permission.ProjectPermissions;
import org.sonar.server.exceptions.BadRequestException;
@@ -33,10 +35,11 @@ import static com.google.common.base.Strings.isNullOrEmpty;
import static java.lang.String.format;
import static org.apache.commons.lang.StringUtils.isBlank;
import static org.sonar.api.security.DefaultGroups.isAnyone;
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_KEY_PATTERN;
import static org.sonar.server.component.ResourceTypeFunctions.RESOURCE_TYPE_TO_QUALIFIER;
import static org.sonar.server.ws.WsUtils.checkRequest;
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PERMISSION;
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_KEY_PATTERN;
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_QUALIFIER;
import static org.sonar.server.ws.WsUtils.checkRequest;

public class PermissionRequestValidator {
public static final String MSG_TEMPLATE_WITH_SAME_NAME = "A template with the name '%s' already exists (case insensitive).";
@@ -79,6 +82,17 @@ public class PermissionRequestValidator {
format("The '%s' parameter must be one of %s. '%s' was passed.", PARAM_QUALIFIER, rootQualifiers, qualifier));
}

public static void validateQualifier(@Nullable String qualifier, ResourceTypes resourceTypes) {
if (qualifier == null) {
return;
}
Set<String> rootQualifiers = FluentIterable.from(resourceTypes.getRoots())
.transform(RESOURCE_TYPE_TO_QUALIFIER)
.toSet();
checkRequest(rootQualifiers.contains(qualifier),
format("The '%s' parameter must be one of %s. '%s' was passed.", PARAM_QUALIFIER, rootQualifiers, qualifier));
}

public static void validateProjectPattern(@Nullable String projectPattern) {
if (isNullOrEmpty(projectPattern)) {
return;

+ 89
- 12
server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionsWsParametersBuilder.java View File

@@ -20,12 +20,32 @@

package org.sonar.server.permission.ws;

import java.util.Set;
import org.sonar.api.i18n.I18n;
import org.sonar.api.resources.ResourceTypes;
import org.sonar.api.server.ws.WebService.NewAction;
import org.sonar.api.server.ws.WebService.NewParam;
import org.sonar.core.permission.GlobalPermissions;
import org.sonar.core.permission.ProjectPermissions;
import org.sonar.core.util.Uuids;
import org.sonar.server.user.UserSession;

import static com.google.common.collect.FluentIterable.from;
import static com.google.common.collect.Ordering.natural;
import static java.lang.String.format;
import static org.sonar.server.component.ResourceTypeFunctions.RESOURCE_TYPE_TO_QUALIFIER;
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_DESCRIPTION;
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_GROUP_ID;
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_GROUP_NAME;
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_ID;
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PERMISSION;
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_ID;
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_KEY;
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_KEY_PATTERN;
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_QUALIFIER;
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_TEMPLATE_ID;
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_TEMPLATE_NAME;
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_USER_LOGIN;

public class PermissionsWsParametersBuilder {

@@ -47,25 +67,25 @@ public class PermissionsWsParametersBuilder {
}

public static void createPermissionParameter(NewAction action) {
action.createParam(org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PERMISSION)
action.createParam(PARAM_PERMISSION)
.setDescription(PERMISSION_PARAM_DESCRIPTION)
.setRequired(true);
}

public static void createProjectPermissionParameter(NewAction action) {
action.createParam(org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PERMISSION)
action.createParam(PARAM_PERMISSION)
.setDescription(PROJECT_PERMISSION_PARAM_DESCRIPTION)
.setRequired(true);
}

public static void createGroupNameParameter(NewAction action) {
action.createParam(org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_GROUP_NAME)
action.createParam(PARAM_GROUP_NAME)
.setDescription("Group name or 'anyone' (case insensitive)")
.setExampleValue("sonar-administrators");
}

public static void createGroupIdParameter(NewAction action) {
action.createParam(org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_GROUP_ID)
action.createParam(PARAM_GROUP_ID)
.setDescription("Group id")
.setExampleValue("42");
}
@@ -76,19 +96,19 @@ public class PermissionsWsParametersBuilder {
}

private static void createProjectIdParameter(NewAction action) {
action.createParam(org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_ID)
action.createParam(PARAM_PROJECT_ID)
.setDescription("Project id")
.setExampleValue("ce4c03d6-430f-40a9-b777-ad877c00aa4d");
}

private static void createProjectKeyParameter(NewAction action) {
action.createParam(org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_KEY)
action.createParam(PARAM_PROJECT_KEY)
.setDescription("Project key")
.setExampleValue("org.apache.hbas:hbase");
}

public static void createUserLoginParameter(NewAction action) {
action.createParam(org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_USER_LOGIN)
action.createParam(PARAM_USER_LOGIN)
.setRequired(true)
.setDescription("User login")
.setExampleValue("g.hopper");
@@ -100,33 +120,90 @@ public class PermissionsWsParametersBuilder {
}

private static void createTemplateIdParameter(NewAction action) {
action.createParam(org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_TEMPLATE_ID)
action.createParam(PARAM_TEMPLATE_ID)
.setDescription("Template id")
.setExampleValue(Uuids.UUID_EXAMPLE_01);
}

private static void createTemplateNameParameter(NewAction action) {
action.createParam(org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_TEMPLATE_NAME)
action.createParam(PARAM_TEMPLATE_NAME)
.setDescription("Template name")
.setExampleValue("Default Permission Template for Projects");
}

public static void createTemplateProjectKeyPatternParameter(NewAction action) {
action.createParam(org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_KEY_PATTERN)
action.createParam(PARAM_PROJECT_KEY_PATTERN)
.setDescription("Project key pattern. Must be a valid Java regular expression")
.setExampleValue(".*\\.finance\\..*");
}

public static void createTemplateDescriptionParameter(NewAction action) {
action.createParam(org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_DESCRIPTION)
action.createParam(PARAM_DESCRIPTION)
.setDescription("Description")
.setExampleValue("Permissions for all projects related to the financial service");
}

public static void createIdParameter(NewAction action) {
action.createParam(org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_ID)
action.createParam(PARAM_ID)
.setRequired(true)
.setDescription("Id")
.setExampleValue("af8cb8cc-1e78-4c4e-8c00-ee8e814009a5");
}

public static NewParam createQualifierParameter(NewAction action, QualifierParameterContext context) {
return action.createParam(PARAM_QUALIFIER)
.setDescription("Project qualifier. Filter the results with the specified qualifier. Possible values are:" + buildRootQualifiersDescription(context))
.setPossibleValues(getRootQualifiers(context.getResourceTypes()));
}

private static Set<String> getRootQualifiers(ResourceTypes resourceTypes) {
return from(resourceTypes.getRoots())
.transform(RESOURCE_TYPE_TO_QUALIFIER)
.toSortedSet(natural());
}

private static String buildRootQualifiersDescription(QualifierParameterContext context) {
StringBuilder description = new StringBuilder();
description.append("<ul>");
String qualifierPattern = "<li>%s - %s</li>";
for (String qualifier : getRootQualifiers(context.getResourceTypes())) {
description.append(format(qualifierPattern, qualifier, qualifierLabel(context, qualifier)));
}
description.append("</ul>");

return description.toString();
}

private static String qualifierLabel(QualifierParameterContext context, String qualifier) {
String qualifiersPropertyPrefix = "qualifiers.";
return context.getI18n().message(context.getUserSession().locale(), qualifiersPropertyPrefix + qualifier, "");
}

public static class QualifierParameterContext {
private final I18n i18n;
private final ResourceTypes resourceTypes;
private final UserSession userSession;

private QualifierParameterContext(UserSession userSession, I18n i18n, ResourceTypes resourceTypes) {
this.i18n = i18n;
this.resourceTypes = resourceTypes;
this.userSession = userSession;
}

public static QualifierParameterContext newQualifierParameterContext(UserSession userSession, I18n i18n, ResourceTypes resourceTypes) {
return new QualifierParameterContext(userSession, i18n, resourceTypes);
}

public I18n getI18n() {
return i18n;
}

public ResourceTypes getResourceTypes() {
return resourceTypes;
}

public UserSession getUserSession() {
return userSession;
}
}
}

+ 12
- 1
server/sonar-server/src/main/java/org/sonar/server/permission/ws/SearchProjectPermissionsAction.java View File

@@ -22,6 +22,7 @@ package org.sonar.server.permission.ws;

import com.google.common.base.Optional;
import org.sonar.api.i18n.I18n;
import org.sonar.api.resources.ResourceTypes;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
@@ -41,11 +42,15 @@ 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.ws.PermissionRequestValidator.validateQualifier;
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.QualifierParameterContext.newQualifierParameterContext;
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createProjectParameter;
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createQualifierParameter;
import static org.sonar.server.permission.ws.WsProjectRef.newOptionalWsProjectRef;
import static org.sonar.server.ws.WsUtils.writeProtobuf;
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_ID;
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_KEY;
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_QUALIFIER;

public class SearchProjectPermissionsAction implements PermissionsWsAction {
private static final String PROPERTY_PREFIX = "projects_role.";
@@ -54,12 +59,14 @@ public class SearchProjectPermissionsAction implements PermissionsWsAction {
private final DbClient dbClient;
private final UserSession userSession;
private final I18n i18n;
private final ResourceTypes resourceTypes;
private final SearchProjectPermissionsDataLoader dataLoader;

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

@@ -75,6 +82,8 @@ public class SearchProjectPermissionsAction implements PermissionsWsAction {
.setHandler(this);

createProjectParameter(action);
createQualifierParameter(action, newQualifierParameterContext(userSession, i18n, resourceTypes))
.setSince("5.3");
}

@Override
@@ -87,6 +96,7 @@ public class SearchProjectPermissionsAction implements PermissionsWsAction {
checkRequestAndPermissions(request);
DbSession dbSession = dbClient.openSession(false);
try {
validateQualifier(request.getQualifier(), resourceTypes);
SearchProjectPermissionsData data = dataLoader.load(request);
return buildResponse(data);
} finally {
@@ -98,6 +108,7 @@ public class SearchProjectPermissionsAction implements PermissionsWsAction {
return new SearchProjectPermissionsWsRequest()
.setProjectId(request.param(PARAM_PROJECT_ID))
.setProjectKey(request.param(PARAM_PROJECT_KEY))
.setQualifier(request.param(PARAM_QUALIFIER))
.setPage(request.mandatoryParamAsInt(Param.PAGE))
.setPageSize(request.mandatoryParamAsInt(Param.PAGE_SIZE))
.setQuery(request.param(Param.TEXT_QUERY));

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

@@ -29,6 +29,7 @@ import com.google.common.collect.TreeBasedTable;
import java.util.Collection;
import java.util.List;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.apache.ibatis.session.ResultContext;
import org.apache.ibatis.session.ResultHandler;
import org.sonar.api.resources.ResourceTypes;
@@ -39,6 +40,7 @@ import org.sonar.db.component.ComponentDto;
import org.sonar.db.permission.CountByProjectAndPermissionDto;
import org.sonarqube.ws.client.permission.SearchProjectPermissionsWsRequest;

import static java.util.Collections.singleton;
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;
@@ -60,7 +62,7 @@ public class SearchProjectPermissionsDataLoader {
DbSession dbSession = dbClient.openSession(false);
try {
SearchProjectPermissionsData.Builder data = newBuilder();
int countRootComponents = countRootComponents(dbSession, rootQualifiers, request);
int countRootComponents = countRootComponents(dbSession, qualifiers(request.getQualifier()), request);
List<ComponentDto> rootComponents = searchRootComponents(dbSession, request, paging(request, countRootComponents));
List<Long> rootComponentIds = Lists.transform(rootComponents, ComponentToIdFunction.INSTANCE);

@@ -93,7 +95,13 @@ public class SearchProjectPermissionsDataLoader {
return singletonList(finder.getRootComponentOrModule(dbSession, project.get()));
}

return dbClient.componentDao().selectComponents(dbSession, rootQualifiers, paging.offset(), paging.pageSize(), query);
return dbClient.componentDao().selectComponents(dbSession, qualifiers(request.getQualifier()), paging.offset(), paging.pageSize(), query);
}

private Collection<String> qualifiers(@Nullable String requestQualifier) {
return requestQualifier == null
? rootQualifiers
: singleton(requestQualifier);
}

private Table<Long, String, Integer> userCountByRootComponentIdAndPermission(DbSession dbSession, List<Long> rootComponentIds) {

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

@@ -20,7 +20,6 @@

package org.sonar.server.permission.ws.template;

import java.util.Set;
import org.sonar.api.i18n.I18n;
import org.sonar.api.resources.Qualifiers;
import org.sonar.api.resources.ResourceTypes;
@@ -36,13 +35,11 @@ import org.sonar.server.platform.PersistentSettings;
import org.sonar.server.user.UserSession;
import org.sonarqube.ws.client.permission.SetDefaultTemplateWsRequest;

import static com.google.common.collect.FluentIterable.from;
import static com.google.common.collect.Ordering.natural;
import static java.lang.String.format;
import static org.sonar.server.component.ResourceTypeFunctions.RESOURCE_TYPE_TO_QUALIFIER;
import static org.sonar.server.permission.DefaultPermissionTemplates.defaultRootQualifierTemplateProperty;
import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdminUser;
import static org.sonar.server.permission.ws.PermissionRequestValidator.validateQualifier;
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.QualifierParameterContext.newQualifierParameterContext;
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createQualifierParameter;
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createTemplateParameters;
import static org.sonar.server.permission.ws.WsTemplateRef.newTemplateRef;
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_QUALIFIER;
@@ -77,11 +74,8 @@ public class SetDefaultTemplateAction implements PermissionsWsAction {
.setHandler(this);

createTemplateParameters(action);

action.createParam(PARAM_QUALIFIER)
.setDescription("Project qualifier. Possible values are:" + buildRootQualifiersDescription())
.setDefaultValue(Qualifiers.PROJECT)
.setPossibleValues(getRootQualifiers());
createQualifierParameter(action, newQualifierParameterContext(userSession, i18n, resourceTypes))
.setDefaultValue(Qualifiers.PROJECT);
}

@Override
@@ -95,7 +89,7 @@ public class SetDefaultTemplateAction implements PermissionsWsAction {

String qualifier = request.getQualifier();
PermissionTemplateDto template = getTemplate(request);
validateQualifier(qualifier, getRootQualifiers());
validateQualifier(qualifier, resourceTypes);
setDefaultTemplateUuid(template.getUuid(), qualifier);
}

@@ -106,29 +100,6 @@ public class SetDefaultTemplateAction implements PermissionsWsAction {
.setTemplateName(request.param(PARAM_TEMPLATE_NAME));
}

private Set<String> getRootQualifiers() {
return from(resourceTypes.getRoots())
.transform(RESOURCE_TYPE_TO_QUALIFIER)
.toSortedSet(natural());
}

private String buildRootQualifiersDescription() {
StringBuilder description = new StringBuilder();
description.append("<ul>");
String qualifierPattern = "<li>%s - %s</li>";
for (String qualifier : getRootQualifiers()) {
description.append(format(qualifierPattern, qualifier, i18n(qualifier)));
}
description.append("</ul>");

return description.toString();
}

private String i18n(String qualifier) {
String qualifiersPropertyPrefix = "qualifiers.";
return i18n.message(userSession.locale(), qualifiersPropertyPrefix + qualifier, "");
}

private PermissionTemplateDto getTemplate(SetDefaultTemplateWsRequest request) {
DbSession dbSession = dbClient.openSession(false);
try {

+ 37
- 23
server/sonar-server/src/test/java/org/sonar/server/permission/ws/SearchProjectPermissionsActionTest.java View File

@@ -20,15 +20,14 @@

package org.sonar.server.permission.ws;

import java.util.List;
import java.io.IOException;
import javax.annotation.Nullable;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.rules.ExpectedException;
import org.sonar.api.resources.Qualifiers;
import org.sonar.api.resources.ResourceType;
import org.sonar.api.resources.ResourceTypes;
import org.sonar.api.utils.System2;
import org.sonar.api.web.UserRole;
import org.sonar.core.permission.GlobalPermissions;
@@ -36,6 +35,7 @@ import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ResourceTypesRule;
import org.sonar.db.user.GroupDto;
import org.sonar.db.user.GroupRoleDto;
import org.sonar.db.user.UserDto;
@@ -46,12 +46,13 @@ import org.sonar.server.exceptions.UnauthorizedException;
import org.sonar.server.i18n.I18nRule;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.usergroups.ws.UserGroupFinder;
import org.sonar.server.ws.TestResponse;
import org.sonar.server.ws.WsActionTester;
import org.sonar.test.DbTests;
import org.sonarqube.ws.MediaTypes;
import org.sonarqube.ws.WsPermissions.SearchProjectPermissionsWsResponse;

import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.sonar.api.server.ws.WebService.Param.PAGE;
import static org.sonar.api.server.ws.WebService.Param.PAGE_SIZE;
import static org.sonar.api.server.ws.WebService.Param.TEXT_QUERY;
@@ -61,9 +62,11 @@ import static org.sonar.db.component.ComponentTesting.newProjectDto;
import static org.sonar.db.component.ComponentTesting.newView;
import static org.sonar.db.user.GroupTesting.newGroupDto;
import static org.sonar.db.user.UserTesting.newUserDto;
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_ID;
import static org.sonar.test.JsonAssert.assertJson;
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_ID;
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_QUALIFIER;

@Category(DbTests.class)
public class SearchProjectPermissionsActionTest {
@Rule
public ExpectedException expectedException = ExpectedException.none();
@@ -76,21 +79,20 @@ public class SearchProjectPermissionsActionTest {
I18nRule i18n = new I18nRule();
DbClient dbClient = db.getDbClient();
DbSession dbSession = db.getSession();
ResourceTypes resourceTypes = mock(ResourceTypes.class);
ResourceTypesRule resourceTypes = new ResourceTypesRule();
SearchProjectPermissionsDataLoader dataLoader;

SearchProjectPermissionsAction underTest;

@Before
public void setUp() {
resourceTypes = mock(ResourceTypes.class);
when(resourceTypes.getRoots()).thenReturn(rootResourceTypes());
resourceTypes.setRootQualifiers(Qualifiers.PROJECT, Qualifiers.VIEW, "DEV");
ComponentFinder componentFinder = new ComponentFinder(dbClient);
PermissionDependenciesFinder finder = new PermissionDependenciesFinder(dbClient, componentFinder, new UserGroupFinder(dbClient), resourceTypes);
i18n.setProjectPermissions();

dataLoader = new SearchProjectPermissionsDataLoader(dbClient, finder, resourceTypes);
underTest = new SearchProjectPermissionsAction(dbClient, userSession, i18n, dataLoader);
underTest = new SearchProjectPermissionsAction(dbClient, userSession, i18n, resourceTypes, dataLoader);

ws = new WsActionTester(underTest);

@@ -220,15 +222,15 @@ public class SearchProjectPermissionsActionTest {

@Test
public void result_depends_of_root_types() {
ResourceType projectResourceType = ResourceType.builder(Qualifiers.PROJECT).build();
when(resourceTypes.getRoots()).thenReturn(asList(projectResourceType));
resourceTypes.setRootQualifiers(Qualifiers.PROJECT);
insertComponent(newView("view-uuid"));
insertComponent(newDeveloper("developer-name"));
insertComponent(newProjectDto("project-uuid"));
commit();
dataLoader = new SearchProjectPermissionsDataLoader(dbClient, new PermissionDependenciesFinder(dbClient, new ComponentFinder(dbClient), new UserGroupFinder(dbClient), resourceTypes),
dataLoader = new SearchProjectPermissionsDataLoader(dbClient,
new PermissionDependenciesFinder(dbClient, new ComponentFinder(dbClient), new UserGroupFinder(dbClient), resourceTypes),
resourceTypes);
underTest = new SearchProjectPermissionsAction(dbClient, userSession, i18n, dataLoader);
underTest = new SearchProjectPermissionsAction(dbClient, userSession, i18n, resourceTypes, dataLoader);
ws = new WsActionTester(underTest);

String result = ws.newRequest().execute().getInput();
@@ -238,6 +240,26 @@ public class SearchProjectPermissionsActionTest {
.doesNotContain("developer-name");
}

@Test
public void filter_by_qualifier() throws IOException {
insertComponent(newView("view-uuid"));
insertComponent(newDeveloper("developer-name"));
insertComponent(newProjectDto("project-uuid"));
commit();

TestResponse wsResponse = ws.newRequest()
.setMediaType(MediaTypes.PROTOBUF)
.setParam(PARAM_QUALIFIER, Qualifiers.PROJECT)
.execute();
SearchProjectPermissionsWsResponse result = SearchProjectPermissionsWsResponse.parseFrom(wsResponse.getInputStream());

assertThat(result.getProjectsList())
.extracting("id")
.contains("project-uuid")
.doesNotContain("view-uuid")
.doesNotContain("developer-name");
}

@Test
public void fail_if_not_logged_in() {
expectedException.expect(UnauthorizedException.class);
@@ -312,12 +334,4 @@ public class SearchProjectPermissionsActionTest {
private void commit() {
dbSession.commit();
}

private static List<ResourceType> rootResourceTypes() {
ResourceType project = ResourceType.builder(Qualifiers.PROJECT).build();
ResourceType view = ResourceType.builder(Qualifiers.VIEW).build();
ResourceType dev = ResourceType.builder("DEV").build();

return asList(project, view, dev);
}
}

+ 1
- 0
sonar-ws/src/main/java/org/sonarqube/ws/client/permission/PermissionsWsClient.java View File

@@ -166,6 +166,7 @@ public class PermissionsWsClient {
newGetRequest(action("search_project_permissions"))
.setParam(PARAM_PROJECT_ID, request.getProjectId())
.setParam(PARAM_PROJECT_KEY, request.getProjectKey())
.setParam(PARAM_QUALIFIER, request.getQualifier())
.setParam("p", request.getPage())
.setParam("ps", request.getPageSize())
.setParam("q", request.getQuery()),

+ 11
- 0
sonar-ws/src/main/java/org/sonarqube/ws/client/permission/SearchProjectPermissionsWsRequest.java View File

@@ -26,6 +26,7 @@ import javax.annotation.Nullable;
public class SearchProjectPermissionsWsRequest {
private String projectId;
private String projectKey;
private String qualifier;
private Integer page;
private Integer pageSize;
private String query;
@@ -79,4 +80,14 @@ public class SearchProjectPermissionsWsRequest {
this.query = query;
return this;
}

@CheckForNull
public String getQualifier() {
return qualifier;
}

public SearchProjectPermissionsWsRequest setQualifier(@Nullable String qualifier) {
this.qualifier = qualifier;
return this;
}
}

Loading…
Cancel
Save