@@ -19,6 +19,8 @@ | |||
*/ | |||
package org.sonar.server.permission.ws.template; | |||
import java.util.Collection; | |||
import java.util.HashSet; | |||
import java.util.List; | |||
import org.sonar.api.i18n.I18n; | |||
import org.sonar.api.resources.Qualifiers; | |||
@@ -35,20 +37,28 @@ import org.sonar.db.permission.template.PermissionTemplateDto; | |||
import org.sonar.server.permission.PermissionTemplateService; | |||
import org.sonar.server.permission.ws.PermissionWsSupport; | |||
import org.sonar.server.permission.ws.PermissionsWsAction; | |||
import org.sonar.server.project.Visibility; | |||
import org.sonar.server.user.UserSession; | |||
import org.sonarqube.ws.client.permission.BulkApplyTemplateWsRequest; | |||
import static org.sonar.api.utils.DateUtils.parseDateOrDateTime; | |||
import static org.sonar.core.util.Protobuf.setNullable; | |||
import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdmin; | |||
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createTemplateParameters; | |||
import static org.sonar.server.permission.ws.template.WsTemplateRef.newTemplateRef; | |||
import static org.sonar.server.ws.WsParameterBuilder.createRootQualifiersParameter; | |||
import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001; | |||
import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_002; | |||
import static org.sonar.server.ws.WsParameterBuilder.QualifierParameterContext.newQualifierParameterContext; | |||
import static org.sonar.server.ws.WsParameterBuilder.createRootQualifiersParameter; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_ORGANIZATION; | |||
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.project.ProjectsWsParameters.PARAM_ANALYZED_BEFORE; | |||
import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_ON_PROVISIONED_ONLY; | |||
import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_PROJECTS; | |||
import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_QUALIFIERS; | |||
import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_VISIBILITY; | |||
public class BulkApplyTemplateAction implements PermissionsWsAction { | |||
@@ -91,6 +101,32 @@ public class BulkApplyTemplateAction implements PermissionsWsAction { | |||
.setDeprecatedKey(PARAM_QUALIFIER, "6.6"); | |||
createTemplateParameters(action); | |||
action | |||
.createParam(PARAM_PROJECTS) | |||
.setDescription("Comma-separated list of project keys") | |||
.setSince("6.6") | |||
.setExampleValue(String.join(",", KEY_PROJECT_EXAMPLE_001, KEY_PROJECT_EXAMPLE_002)); | |||
action.createParam(PARAM_VISIBILITY) | |||
.setDescription("Filter the projects that should be visible to everyone (%s), or only specific user/groups (%s).<br/>" + | |||
"If no visibility is specified, the default project visibility of the organization will be used.", | |||
Visibility.PUBLIC.getLabel(), Visibility.PRIVATE.getLabel()) | |||
.setRequired(false) | |||
.setInternal(true) | |||
.setSince("6.6") | |||
.setPossibleValues(Visibility.getLabels()); | |||
action.createParam(PARAM_ANALYZED_BEFORE) | |||
.setDescription("Filter the projects for which last analysis is older than the given date (exclusive).<br> " + | |||
"Format: date or datetime ISO formats.") | |||
.setSince("6.6"); | |||
action.createParam(PARAM_ON_PROVISIONED_ONLY) | |||
.setDescription("Filter the projects that are provisioned") | |||
.setBooleanPossibleValues() | |||
.setDefaultValue("false") | |||
.setSince("6.6"); | |||
} | |||
@Override | |||
@@ -118,15 +154,29 @@ public class BulkApplyTemplateAction implements PermissionsWsAction { | |||
.setTemplateId(request.param(PARAM_TEMPLATE_ID)) | |||
.setTemplateName(request.param(PARAM_TEMPLATE_NAME)) | |||
.setQualifiers(request.mandatoryParamAsStrings(PARAM_QUALIFIERS)) | |||
.setQuery(request.param(Param.TEXT_QUERY)); | |||
.setQuery(request.param(Param.TEXT_QUERY)) | |||
.setVisibility(request.param(PARAM_VISIBILITY)) | |||
.setOnProvisionedOnly(request.mandatoryParamAsBoolean(PARAM_ON_PROVISIONED_ONLY)) | |||
.setAnalyzedBefore(request.param(PARAM_ANALYZED_BEFORE)) | |||
.setProjects(request.paramAsStrings(PARAM_PROJECTS)); | |||
} | |||
private static ComponentQuery buildDbQuery(BulkApplyTemplateWsRequest request) { | |||
ComponentQuery.Builder dbQuery = ComponentQuery.builder() | |||
.setNameOrKeyQuery(request.getQuery()); | |||
setNullable(request.getQualifiers(), l -> dbQuery.setQualifiers(l.toArray(new String[0]))); | |||
return dbQuery.build(); | |||
Collection<String> qualifiers = request.getQualifiers(); | |||
ComponentQuery.Builder query = ComponentQuery.builder() | |||
.setQualifiers(qualifiers.toArray(new String[qualifiers.size()])); | |||
setNullable(request.getQuery(), q -> { | |||
query.setNameOrKeyQuery(q); | |||
query.setPartialMatchOnKey(true); | |||
return query; | |||
}); | |||
setNullable(request.getVisibility(), v -> query.setPrivate(Visibility.isPrivate(v))); | |||
setNullable(request.getAnalyzedBefore(), d -> query.setAnalyzedBefore(parseDateOrDateTime(d).getTime())); | |||
setNullable(request.isOnProvisionedOnly(), query::setOnProvisionedOnly); | |||
setNullable(request.getProjects(), keys -> query.setComponentKeys(new HashSet<>(keys))); | |||
return query.build(); | |||
} | |||
} |
@@ -41,12 +41,18 @@ import org.sonar.server.permission.PermissionTemplateService; | |||
import org.sonar.server.permission.ws.BasePermissionWsTest; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.sonar.api.utils.DateUtils.parseDate; | |||
import static org.sonar.db.component.ComponentTesting.newApplication; | |||
import static org.sonar.db.component.ComponentTesting.newView; | |||
import static org.sonar.db.component.SnapshotTesting.newAnalysis; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_ORGANIZATION; | |||
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.project.ProjectsWsParameters.PARAM_ANALYZED_BEFORE; | |||
import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_ON_PROVISIONED_ONLY; | |||
import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_PROJECTS; | |||
import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_QUALIFIERS; | |||
import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_VISIBILITY; | |||
public class BulkApplyTemplateActionTest extends BasePermissionWsTest<BulkApplyTemplateAction> { | |||
@@ -103,17 +109,14 @@ public class BulkApplyTemplateActionTest extends BasePermissionWsTest<BulkApplyT | |||
ComponentDto privateProject = db.components().insertPrivateProject(organization); | |||
ComponentDto publicProject = db.components().insertPublicProject(organization); | |||
ComponentDto view = db.components().insertView(organization); | |||
loginAsAdmin(organization); | |||
newRequest() | |||
.setParam(PARAM_TEMPLATE_ID, template1.getUuid()) | |||
.setParam(PARAM_QUALIFIERS, String.join(",", Qualifiers.PROJECT, Qualifiers.VIEW)) | |||
.execute(); | |||
assertTemplate1AppliedToPrivateProject(privateProject); | |||
assertTemplate1AppliedToPublicProject(publicProject); | |||
assertTemplate1AppliedToPublicProject(view); | |||
} | |||
@Test | |||
@@ -171,14 +174,13 @@ public class BulkApplyTemplateActionTest extends BasePermissionWsTest<BulkApplyT | |||
db.components().insertProjectAndSnapshot(publicProjectFoundByKey); | |||
ComponentDto publicProjectFoundByName = ComponentTesting.newPublicProjectDto(organization).setName("name-sonar-name"); | |||
db.components().insertProjectAndSnapshot(publicProjectFoundByName); | |||
// match must be exact on key | |||
ComponentDto projectUntouched = ComponentTesting.newPublicProjectDto(organization).setDbKey("new-sonar").setName("project-name"); | |||
ComponentDto projectUntouched = ComponentTesting.newPublicProjectDto(organization).setDbKey("new-sona").setName("project-name"); | |||
db.components().insertProjectAndSnapshot(projectUntouched); | |||
loginAsAdmin(organization); | |||
newRequest() | |||
.setParam(PARAM_TEMPLATE_ID, template1.getUuid()) | |||
.setParam(Param.TEXT_QUERY, "sonar") | |||
.setParam(Param.TEXT_QUERY, "SONAR") | |||
.execute(); | |||
assertTemplate1AppliedToPublicProject(publicProjectFoundByKey); | |||
@@ -188,18 +190,18 @@ public class BulkApplyTemplateActionTest extends BasePermissionWsTest<BulkApplyT | |||
@Test | |||
public void apply_template_by_query_on_name_and_key() throws Exception { | |||
ComponentDto privateProjectFoundByKey = ComponentTesting.newPrivateProjectDto(organization).setDbKey("sonar"); | |||
// partial match on key | |||
ComponentDto privateProjectFoundByKey = ComponentTesting.newPrivateProjectDto(organization).setDbKey("sonarqube"); | |||
db.components().insertProjectAndSnapshot(privateProjectFoundByKey); | |||
ComponentDto privateProjectFoundByName = ComponentTesting.newPrivateProjectDto(organization).setName("name-sonar-name"); | |||
db.components().insertProjectAndSnapshot(privateProjectFoundByName); | |||
// match must be exact on key | |||
ComponentDto projectUntouched = ComponentTesting.newPublicProjectDto(organization).setDbKey("new-sonar").setName("project-name"); | |||
ComponentDto projectUntouched = ComponentTesting.newPublicProjectDto(organization).setDbKey("new-sona").setName("project-name"); | |||
db.components().insertProjectAndSnapshot(projectUntouched); | |||
loginAsAdmin(organization); | |||
newRequest() | |||
.setParam(PARAM_TEMPLATE_ID, template1.getUuid()) | |||
.setParam(Param.TEXT_QUERY, "sonar") | |||
.setParam(Param.TEXT_QUERY, "SONAR") | |||
.execute(); | |||
assertTemplate1AppliedToPrivateProject(privateProjectFoundByKey); | |||
@@ -207,6 +209,78 @@ public class BulkApplyTemplateActionTest extends BasePermissionWsTest<BulkApplyT | |||
assertNoPermissionOnProject(projectUntouched); | |||
} | |||
@Test | |||
public void apply_template_by_project_keys() throws Exception { | |||
ComponentDto project1 = db.components().insertPrivateProject(organization); | |||
ComponentDto project2 = db.components().insertPrivateProject(organization); | |||
ComponentDto untouchedProject = db.components().insertPrivateProject(organization); | |||
loginAsAdmin(organization); | |||
newRequest() | |||
.setParam(PARAM_TEMPLATE_ID, template1.getUuid()) | |||
.setParam(PARAM_PROJECTS, String.join(",", project1.getKey(), project2.getKey())) | |||
.execute(); | |||
assertTemplate1AppliedToPrivateProject(project1); | |||
assertTemplate1AppliedToPrivateProject(project2); | |||
assertNoPermissionOnProject(untouchedProject); | |||
} | |||
@Test | |||
public void apply_template_by_provisioned_only() throws Exception { | |||
ComponentDto provisionedProject1 = db.components().insertPrivateProject(organization); | |||
ComponentDto provisionedProject2 = db.components().insertPrivateProject(organization); | |||
ComponentDto analyzedProject = db.components().insertPrivateProject(organization); | |||
db.components().insertSnapshot(newAnalysis(analyzedProject)); | |||
loginAsAdmin(organization); | |||
newRequest() | |||
.setParam(PARAM_TEMPLATE_ID, template1.getUuid()) | |||
.setParam(PARAM_ON_PROVISIONED_ONLY, "true") | |||
.execute(); | |||
assertTemplate1AppliedToPrivateProject(provisionedProject1); | |||
assertTemplate1AppliedToPrivateProject(provisionedProject2); | |||
assertNoPermissionOnProject(analyzedProject); | |||
} | |||
@Test | |||
public void apply_template_by_analyzed_before() throws Exception { | |||
ComponentDto oldProject1 = db.components().insertPrivateProject(organization); | |||
ComponentDto oldProject2 = db.components().insertPrivateProject(organization); | |||
ComponentDto recentProject = db.components().insertPrivateProject(organization); | |||
db.components().insertSnapshot(oldProject1, a -> a.setCreatedAt(parseDate("2015-02-03").getTime())); | |||
db.components().insertSnapshot(oldProject2, a -> a.setCreatedAt(parseDate("2016-12-11").getTime())); | |||
db.components().insertSnapshot(recentProject, a -> a.setCreatedAt(System.currentTimeMillis())); | |||
loginAsAdmin(organization); | |||
newRequest() | |||
.setParam(PARAM_TEMPLATE_ID, template1.getUuid()) | |||
.setParam(PARAM_ANALYZED_BEFORE, "2017-09-07") | |||
.execute(); | |||
assertTemplate1AppliedToPrivateProject(oldProject1); | |||
assertTemplate1AppliedToPrivateProject(oldProject2); | |||
assertNoPermissionOnProject(recentProject); | |||
} | |||
@Test | |||
public void apply_template_by_visibility() throws Exception { | |||
ComponentDto privateProject1 = db.components().insertPrivateProject(organization); | |||
ComponentDto privateProject2 = db.components().insertPrivateProject(organization); | |||
ComponentDto publicProject = db.components().insertPublicProject(organization); | |||
loginAsAdmin(organization); | |||
newRequest() | |||
.setParam(PARAM_TEMPLATE_ID, template1.getUuid()) | |||
.setParam(PARAM_VISIBILITY, "private") | |||
.execute(); | |||
assertTemplate1AppliedToPrivateProject(privateProject1); | |||
assertTemplate1AppliedToPrivateProject(privateProject2); | |||
assertNoPermissionOnProject(publicProject); | |||
} | |||
@Test | |||
public void fail_if_no_template_parameter() throws Exception { | |||
loginAsAdmin(db.getDefaultOrganization()); |
@@ -22,7 +22,9 @@ package org.sonarqube.ws.client.permission; | |||
import java.util.Collection; | |||
import javax.annotation.CheckForNull; | |||
import javax.annotation.Nullable; | |||
import org.sonar.api.resources.Qualifiers; | |||
import static java.util.Collections.singleton; | |||
import static java.util.Objects.requireNonNull; | |||
public class BulkApplyTemplateWsRequest { | |||
@@ -30,7 +32,11 @@ public class BulkApplyTemplateWsRequest { | |||
private String organization; | |||
private String templateName; | |||
private String query; | |||
private Collection<String> qualifiers; | |||
private Collection<String> qualifiers = singleton(Qualifiers.PROJECT); | |||
private String visibility; | |||
private String analyzedBefore; | |||
private boolean onProvisionedOnly = false; | |||
private Collection<String> projects; | |||
@CheckForNull | |||
public String getTemplateId() { | |||
@@ -72,7 +78,6 @@ public class BulkApplyTemplateWsRequest { | |||
return this; | |||
} | |||
@CheckForNull | |||
public Collection<String> getQualifiers() { | |||
return qualifiers; | |||
} | |||
@@ -81,4 +86,43 @@ public class BulkApplyTemplateWsRequest { | |||
this.qualifiers = requireNonNull(qualifiers); | |||
return this; | |||
} | |||
@CheckForNull | |||
public String getVisibility() { | |||
return visibility; | |||
} | |||
public BulkApplyTemplateWsRequest setVisibility(@Nullable String visibility) { | |||
this.visibility = visibility; | |||
return this; | |||
} | |||
@CheckForNull | |||
public String getAnalyzedBefore() { | |||
return analyzedBefore; | |||
} | |||
public BulkApplyTemplateWsRequest setAnalyzedBefore(@Nullable String analyzedBefore) { | |||
this.analyzedBefore = analyzedBefore; | |||
return this; | |||
} | |||
public boolean isOnProvisionedOnly() { | |||
return onProvisionedOnly; | |||
} | |||
public BulkApplyTemplateWsRequest setOnProvisionedOnly(boolean onProvisionedOnly) { | |||
this.onProvisionedOnly = onProvisionedOnly; | |||
return this; | |||
} | |||
@CheckForNull | |||
public Collection<String> getProjects() { | |||
return projects; | |||
} | |||
public BulkApplyTemplateWsRequest setProjects(@Nullable Collection<String> projects) { | |||
this.projects = projects; | |||
return this; | |||
} | |||
} |
@@ -30,6 +30,7 @@ import org.sonarqube.ws.client.BaseService; | |||
import org.sonarqube.ws.client.GetRequest; | |||
import org.sonarqube.ws.client.PostRequest; | |||
import org.sonarqube.ws.client.WsConnector; | |||
import org.sonarqube.ws.client.project.ProjectsWsParameters; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_DESCRIPTION; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_GROUP_ID; | |||
@@ -45,7 +46,6 @@ import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_Q | |||
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; | |||
import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_QUALIFIERS; | |||
public class PermissionsService extends BaseService { | |||
@@ -124,7 +124,11 @@ public class PermissionsService extends BaseService { | |||
.setParam(PARAM_TEMPLATE_ID, request.getTemplateId()) | |||
.setParam(PARAM_TEMPLATE_NAME, request.getTemplateName()) | |||
.setParam("q", request.getQuery()) | |||
.setParam(PARAM_QUALIFIERS, inlineMultipleParamValue(request.getQualifiers()))); | |||
.setParam(ProjectsWsParameters.PARAM_QUALIFIERS, inlineMultipleParamValue(request.getQualifiers())) | |||
.setParam(ProjectsWsParameters.PARAM_VISIBILITY, request.getVisibility()) | |||
.setParam(ProjectsWsParameters.PARAM_ANALYZED_BEFORE, request.getAnalyzedBefore()) | |||
.setParam(ProjectsWsParameters.PARAM_ON_PROVISIONED_ONLY, request.isOnProvisionedOnly()) | |||
.setParam(ProjectsWsParameters.PARAM_PROJECTS, inlineMultipleParamValue(request.getProjects()))); | |||
} | |||
public CreateTemplateWsResponse createTemplate(CreateTemplateWsRequest request) { |
@@ -44,7 +44,11 @@ import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_Q | |||
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; | |||
import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_ANALYZED_BEFORE; | |||
import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_ON_PROVISIONED_ONLY; | |||
import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_PROJECTS; | |||
import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_QUALIFIERS; | |||
import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_VISIBILITY; | |||
public class PermissionsServiceTest { | |||
private static final String ORGANIZATION_VALUE = "organization value"; | |||
@@ -220,7 +224,11 @@ public class PermissionsServiceTest { | |||
.setTemplateId(TEMPLATE_ID_VALUE) | |||
.setTemplateName(TEMPLATE_NAME_VALUE) | |||
.setQualifiers(Arrays.asList("TRK", "VW")) | |||
.setQuery(QUERY_VALUE)); | |||
.setQuery(QUERY_VALUE) | |||
.setVisibility("private") | |||
.setAnalyzedBefore("2017-04-01") | |||
.setOnProvisionedOnly(true) | |||
.setProjects(Arrays.asList("P1", "P2"))); | |||
assertThat(serviceTester.getPostParser()).isNull(); | |||
PostRequest postRequest = serviceTester.getPostRequest(); | |||
@@ -231,6 +239,10 @@ public class PermissionsServiceTest { | |||
.hasParam(PARAM_TEMPLATE_NAME, TEMPLATE_NAME_VALUE) | |||
.hasParam("q", QUERY_VALUE) | |||
.hasParam(PARAM_QUALIFIERS, "TRK,VW") | |||
.hasParam(PARAM_VISIBILITY, "private") | |||
.hasParam(PARAM_ANALYZED_BEFORE, "2017-04-01") | |||
.hasParam(PARAM_ON_PROVISIONED_ONLY, "true") | |||
.hasParam(PARAM_PROJECTS, "P1,P2") | |||
.andNoOtherParam(); | |||
} | |||
@@ -20,6 +20,7 @@ | |||
package org.sonarqube.tests.authorisation; | |||
import com.sonar.orchestrator.Orchestrator; | |||
import java.util.Arrays; | |||
import java.util.Optional; | |||
import org.junit.After; | |||
import org.junit.ClassRule; | |||
@@ -32,16 +33,19 @@ import org.sonarqube.tests.Category6Suite; | |||
import org.sonarqube.tests.Tester; | |||
import org.sonarqube.ws.Organizations.Organization; | |||
import org.sonarqube.ws.WsPermissions; | |||
import org.sonarqube.ws.WsPermissions.CreateTemplateWsResponse; | |||
import org.sonarqube.ws.WsProjects.CreateWsResponse.Project; | |||
import org.sonarqube.ws.WsUsers; | |||
import org.sonarqube.ws.WsUsers.CreateWsResponse; | |||
import org.sonarqube.ws.client.WsClient; | |||
import org.sonarqube.ws.client.component.SearchProjectsRequest; | |||
import org.sonarqube.ws.client.permission.AddUserToTemplateWsRequest; | |||
import org.sonarqube.ws.client.permission.ApplyTemplateWsRequest; | |||
import org.sonarqube.ws.client.permission.BulkApplyTemplateWsRequest; | |||
import org.sonarqube.ws.client.permission.CreateTemplateWsRequest; | |||
import org.sonarqube.ws.client.permission.PermissionsService; | |||
import org.sonarqube.ws.client.permission.UsersWsRequest; | |||
import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
public class PermissionTemplateTest { | |||
@@ -62,9 +66,9 @@ public class PermissionTemplateTest { | |||
@Test | |||
public void apply_permission_template_on_project() { | |||
Organization organization = tester.organizations().generate(); | |||
Project project = tester.projects().generate(organization, p -> p.setVisibility("private")); | |||
WsUsers.CreateWsResponse.User user = tester.users().generateMember(organization); | |||
WsUsers.CreateWsResponse.User anotherUser = tester.users().generateMember(organization); | |||
Project project = createPrivateProject(organization); | |||
CreateWsResponse.User user = tester.users().generateMember(organization); | |||
CreateWsResponse.User anotherUser = tester.users().generateMember(organization); | |||
assertThatUserDoesNotHavePermission(user, organization, project); | |||
assertThatUserDoesNotHavePermission(anotherUser, organization, project); | |||
@@ -80,12 +84,40 @@ public class PermissionTemplateTest { | |||
assertThat(userHasAccessToIndexedProject(anotherUser, organization, project)).isFalse(); | |||
} | |||
@Test | |||
public void bulk_apply_template_on_projects() { | |||
Organization organization = tester.organizations().generate(); | |||
CreateWsResponse.User user = tester.users().generateMember(organization); | |||
CreateWsResponse.User anotherUser = tester.users().generateMember(organization); | |||
WsPermissions.PermissionTemplate template = createTemplate(organization).getPermissionTemplate(); | |||
tester.wsClient().permissions().addUserToTemplate(new AddUserToTemplateWsRequest() | |||
.setOrganization(organization.getKey()) | |||
.setTemplateId(template.getId()) | |||
.setLogin(user.getLogin()) | |||
.setPermission("user")); | |||
Project project1 = createPrivateProject(organization); | |||
Project project2 = createPrivateProject(organization); | |||
Project untouchedProject = createPrivateProject(organization); | |||
tester.wsClient().permissions().bulkApplyTemplate(new BulkApplyTemplateWsRequest() | |||
.setOrganization(organization.getKey()) | |||
.setTemplateId(template.getId()) | |||
.setProjects(Arrays.asList(project1.getKey(), project2.getKey()))); | |||
assertThatUserDoesNotHavePermission(anotherUser, organization, untouchedProject); | |||
assertThatUserDoesNotHavePermission(anotherUser, organization, project1); | |||
assertThatUserDoesNotHavePermission(anotherUser, organization, project2); | |||
assertThatUserHasPermission(user, organization, project1); | |||
assertThatUserHasPermission(user, organization, project2); | |||
assertThatUserDoesNotHavePermission(user, organization, untouchedProject); | |||
} | |||
@Test | |||
public void indexing_errors_are_recovered_when_applying_permission_template_on_project() throws Exception { | |||
Organization organization = tester.organizations().generate(); | |||
Project project = tester.projects().generate(organization, p -> p.setVisibility("private")); | |||
WsUsers.CreateWsResponse.User user = tester.users().generateMember(organization); | |||
WsUsers.CreateWsResponse.User anotherUser = tester.users().generateMember(organization); | |||
Project project = createPrivateProject(organization); | |||
CreateWsResponse.User user = tester.users().generateMember(organization); | |||
CreateWsResponse.User anotherUser = tester.users().generateMember(organization); | |||
lockWritesOnProjectIndices(); | |||
@@ -122,7 +154,7 @@ public class PermissionTemplateTest { | |||
* Gives the read access only to the specified user. All other users and groups | |||
* loose their ability to see the project. | |||
*/ | |||
private void createAndApplyTemplate(Organization organization, Project project, WsUsers.CreateWsResponse.User user) { | |||
private void createAndApplyTemplate(Organization organization, Project project, CreateWsResponse.User user) { | |||
String templateName = "For user"; | |||
PermissionsService service = tester.wsClient().permissions(); | |||
service.createTemplate(new CreateTemplateWsRequest() | |||
@@ -140,15 +172,25 @@ public class PermissionTemplateTest { | |||
.setTemplateName(templateName)); | |||
} | |||
private void assertThatUserHasPermission(WsUsers.CreateWsResponse.User user, Organization organization, Project project) { | |||
assertThat(hasAdminPermission(user, organization, project)).isTrue(); | |||
private CreateTemplateWsResponse createTemplate(Organization organization) { | |||
return tester.wsClient().permissions().createTemplate(new CreateTemplateWsRequest() | |||
.setOrganization(organization.getKey()) | |||
.setName(randomAlphabetic(20))); | |||
} | |||
private Project createPrivateProject(Organization organization) { | |||
return tester.projects().generate(organization, p -> p.setVisibility("private")); | |||
} | |||
private void assertThatUserHasPermission(CreateWsResponse.User user, Organization organization, Project project) { | |||
assertThat(hasBrowsePermission(user, organization, project)).isTrue(); | |||
} | |||
private void assertThatUserDoesNotHavePermission(WsUsers.CreateWsResponse.User user, Organization organization, Project project) { | |||
assertThat(hasAdminPermission(user, organization, project)).isFalse(); | |||
private void assertThatUserDoesNotHavePermission(CreateWsResponse.User user, Organization organization, Project project) { | |||
assertThat(hasBrowsePermission(user, organization, project)).isFalse(); | |||
} | |||
private boolean userHasAccessToIndexedProject(WsUsers.CreateWsResponse.User user, Organization organization, Project project) { | |||
private boolean userHasAccessToIndexedProject(CreateWsResponse.User user, Organization organization, Project project) { | |||
SearchProjectsRequest request = SearchProjectsRequest.builder().setOrganization(organization.getKey()).build(); | |||
WsClient userSession = tester.as(user.getLogin()).wsClient(); | |||
return userSession.components().searchProjects(request) | |||
@@ -156,7 +198,7 @@ public class PermissionTemplateTest { | |||
.anyMatch(c -> c.getKey().equals(project.getKey())); | |||
} | |||
private boolean hasAdminPermission(WsUsers.CreateWsResponse.User user, Organization organization, Project project) { | |||
private boolean hasBrowsePermission(CreateWsResponse.User user, Organization organization, Project project) { | |||
UsersWsRequest request = new UsersWsRequest() | |||
.setOrganization(organization.getKey()) | |||
.setProjectKey(project.getKey()) |