aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulien Lancelot <julien.lancelot@sonarsource.com>2017-04-28 10:11:18 +0200
committerJulien Lancelot <julien.lancelot@sonarsource.com>2017-04-28 18:36:09 +0200
commitb700e83c77136ebacb4465d5cb403e46bb51abc8 (patch)
tree7f6942ce9afd0410019f53a8eaaf659276b81502
parent70ff3c22c1f2da24601ec099fa48a55ca5a9f035 (diff)
downloadsonarqube-b700e83c77136ebacb4465d5cb403e46bb51abc8.tar.gz
sonarqube-b700e83c77136ebacb4465d5cb403e46bb51abc8.zip
SONAR-9124 Allow preventing create private in api/projects/create
-rw-r--r--it/it-tests/src/test/java/it/organization/BillingTest.java26
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/project/ws/CreateAction.java1
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/project/ws/CreateActionTest.java142
3 files changed, 120 insertions, 49 deletions
diff --git a/it/it-tests/src/test/java/it/organization/BillingTest.java b/it/it-tests/src/test/java/it/organization/BillingTest.java
index ef90a697432..79dd8fe8ca8 100644
--- a/it/it-tests/src/test/java/it/organization/BillingTest.java
+++ b/it/it-tests/src/test/java/it/organization/BillingTest.java
@@ -188,6 +188,32 @@ public class BillingTest {
}
}
+ @Test
+ public void does_not_fail_to_create_private_project() {
+ String organizationKey = createOrganization();
+ String projectKey = newProjectKey();
+ setServerProperty(orchestrator, "sonar.billing.preventUpdatingProjectsVisibilityToPrivate", "false");
+
+ adminClient.projects().create(CreateRequest.builder().setKey(projectKey).setName(projectKey).setOrganization(organizationKey).setVisibility("public").build());
+
+ assertWsResponseAsAdmin(new GetRequest("api/navigation/component").setParam("componentKey", projectKey), "\"visibility\":\"public\"");
+ }
+
+ @Test
+ public void fail_to_create_private_project() {
+ String organizationKey = createOrganization();
+ String projectKey = newProjectKey();
+ setServerProperty(orchestrator, "sonar.billing.preventUpdatingProjectsVisibilityToPrivate", "true");
+
+ try {
+ adminClient.projects().create(CreateRequest.builder().setKey(projectKey).setName(projectKey).setOrganization(organizationKey).setVisibility("private").build());
+ fail();
+ } catch (HttpException ex) {
+ assertThat(ex.code()).isEqualTo(400);
+ assertThat(ex.content()).contains(format("Organization %s cannot use private project", organizationKey));
+ }
+ }
+
private static String createOrganization() {
String key = newOrganizationKey();
adminClient.organizations().create(new CreateWsRequest.Builder().setKey(key).setName(key).build()).getOrganization();
diff --git a/server/sonar-server/src/main/java/org/sonar/server/project/ws/CreateAction.java b/server/sonar-server/src/main/java/org/sonar/server/project/ws/CreateAction.java
index 84974174d53..4a3c14fbb0a 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/project/ws/CreateAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/project/ws/CreateAction.java
@@ -119,6 +119,7 @@ public class CreateAction implements ProjectsWsAction {
userSession.checkPermission(PROVISION_PROJECTS, organization);
String visibility = request.getVisibility();
Boolean changeToPrivate = visibility == null ? dbClient.organizationDao().getNewProjectPrivate(dbSession, organization) : "private".equals(visibility);
+ support.checkCanUpdateProjectsVisibility(organization, changeToPrivate);
ComponentDto componentDto = componentUpdater.create(dbSession, newComponentBuilder()
.setOrganizationUuid(organization.getUuid())
diff --git a/server/sonar-server/src/test/java/org/sonar/server/project/ws/CreateActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/project/ws/CreateActionTest.java
index 897741709cf..44b6226c6a8 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/project/ws/CreateActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/project/ws/CreateActionTest.java
@@ -20,6 +20,7 @@
package org.sonar.server.project.ws;
import org.assertj.core.api.Assertions;
+import org.assertj.core.api.AssertionsForClassTypes;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
@@ -35,6 +36,9 @@ import org.sonar.server.component.ComponentUpdater;
import org.sonar.server.component.NewComponent;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.ForbiddenException;
+import org.sonar.server.organization.BillingValidations;
+import org.sonar.server.organization.BillingValidations.BillingValidationsException;
+import org.sonar.server.organization.BillingValidationsProxy;
import org.sonar.server.organization.DefaultOrganizationProvider;
import org.sonar.server.organization.TestDefaultOrganizationProvider;
import org.sonar.server.tester.UserSessionRule;
@@ -46,19 +50,21 @@ import org.sonarqube.ws.client.project.CreateRequest;
import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.sonar.core.util.Protobuf.setNullable;
import static org.sonar.db.permission.OrganizationPermission.PROVISION_PROJECTS;
import static org.sonar.server.project.Visibility.PRIVATE;
-import static org.sonar.server.project.ws.CreateAction.PARAM_VISIBILITY;
import static org.sonar.server.project.ws.ProjectsWsSupport.PARAM_ORGANIZATION;
import static org.sonar.test.JsonAssert.assertJson;
import static org.sonarqube.ws.client.WsRequest.Method.POST;
import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_BRANCH;
import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_NAME;
import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_PROJECT;
+import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_VISIBILITY;
public class CreateActionTest {
@@ -76,10 +82,11 @@ public class CreateActionTest {
private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db);
private ComponentUpdater componentUpdater = mock(ComponentUpdater.class, Mockito.RETURNS_MOCKS);
+ private BillingValidationsProxy billingValidations = mock(BillingValidationsProxy.class);
private WsActionTester ws = new WsActionTester(
new CreateAction(
- new ProjectsWsSupport(db.getDbClient()),
+ new ProjectsWsSupport(db.getDbClient(), billingValidations),
db.getDbClient(), userSession,
componentUpdater,
defaultOrganizationProvider));
@@ -132,59 +139,41 @@ public class CreateActionTest {
}
@Test
- public void fail_when_project_already_exists() throws Exception {
+ public void apply_project_visibility_public() {
OrganizationDto organization = db.organizations().insert();
- when(componentUpdater.create(any(DbSession.class), any(NewComponent.class), anyInt())).thenThrow(BadRequestException.create("already exists"));
userSession.addPermission(PROVISION_PROJECTS, organization);
+ expectSuccessfulCallToComponentUpdater();
- expectedException.expect(BadRequestException.class);
-
- call(CreateRequest.builder()
- .setOrganization(organization.getKey())
- .setKey(DEFAULT_PROJECT_KEY)
- .setName(DEFAULT_PROJECT_NAME)
- .build());
- }
-
- @Test
- public void fail_when_missing_project_parameter() throws Exception {
- expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("The 'project' parameter is missing");
-
- call(CreateRequest.builder().setName(DEFAULT_PROJECT_NAME).build());
- }
-
- @Test
- public void fail_when_missing_name_parameter() throws Exception {
- expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("The 'name' parameter is missing");
-
- call(CreateRequest.builder().setKey(DEFAULT_PROJECT_KEY).build());
- }
-
- @Test
- public void fail_when_missing_create_project_permission() throws Exception {
- expectedException.expect(ForbiddenException.class);
+ CreateWsResponse result = ws.newRequest()
+ .setParam("key", DEFAULT_PROJECT_KEY)
+ .setParam("name", DEFAULT_PROJECT_NAME)
+ .setParam("organization", organization.getKey())
+ .setParam("visibility", "public")
+ .executeProtobuf(CreateWsResponse.class);
- call(CreateRequest.builder().setKey(DEFAULT_PROJECT_KEY).setName(DEFAULT_PROJECT_NAME).build());
+ assertThat(result.getProject().getVisibility()).isEqualTo("public");
}
@Test
- public void test_example() {
- userSession.addPermission(PROVISION_PROJECTS, db.getDefaultOrganization());
+ public void apply_project_visibility_private() {
+ OrganizationDto organization = db.organizations().insert();
+ userSession.addPermission(PROVISION_PROJECTS, organization);
expectSuccessfulCallToComponentUpdater();
- String result = ws.newRequest()
+ CreateWsResponse result = ws.newRequest()
.setParam("key", DEFAULT_PROJECT_KEY)
.setParam("name", DEFAULT_PROJECT_NAME)
- .execute().getInput();
+ .setParam("organization", organization.getKey())
+ .setParam("visibility", PRIVATE.getLabel())
+ .executeProtobuf(CreateWsResponse.class);
- assertJson(result).isSimilarTo(getClass().getResource("create-example.json"));
+ assertThat(result.getProject().getVisibility()).isEqualTo("private");
}
@Test
- public void apply_project_visibility_public() {
+ public void apply_default_project_visibility_public() {
OrganizationDto organization = db.organizations().insert();
+ db.organizations().setNewProjectPrivate(organization, false);
userSession.addPermission(PROVISION_PROJECTS, organization);
expectSuccessfulCallToComponentUpdater();
@@ -192,15 +181,15 @@ public class CreateActionTest {
.setParam("key", DEFAULT_PROJECT_KEY)
.setParam("name", DEFAULT_PROJECT_NAME)
.setParam("organization", organization.getKey())
- .setParam("visibility", "public")
.executeProtobuf(CreateWsResponse.class);
assertThat(result.getProject().getVisibility()).isEqualTo("public");
}
@Test
- public void apply_project_visibility_private() {
+ public void apply_default_project_visibility_private() {
OrganizationDto organization = db.organizations().insert();
+ db.organizations().setNewProjectPrivate(organization, true);
userSession.addPermission(PROVISION_PROJECTS, organization);
expectSuccessfulCallToComponentUpdater();
@@ -208,42 +197,97 @@ public class CreateActionTest {
.setParam("key", DEFAULT_PROJECT_KEY)
.setParam("name", DEFAULT_PROJECT_NAME)
.setParam("organization", organization.getKey())
- .setParam("visibility", PRIVATE.getLabel())
.executeProtobuf(CreateWsResponse.class);
assertThat(result.getProject().getVisibility()).isEqualTo("private");
}
@Test
- public void apply_default_project_visibility_public() {
+ public void does_not_fail_to_create_public_projects_when_organization_is_not_allowed_to_use_private_projects() {
OrganizationDto organization = db.organizations().insert();
- db.organizations().setNewProjectPrivate(organization, false);
userSession.addPermission(PROVISION_PROJECTS, organization);
expectSuccessfulCallToComponentUpdater();
+ doThrow(new BillingValidationsException("This organization cannot use project private")).when(billingValidations)
+ .checkCanUpdateProjectVisibility(any(BillingValidations.Organization.class), eq(true));
CreateWsResponse result = ws.newRequest()
.setParam("key", DEFAULT_PROJECT_KEY)
.setParam("name", DEFAULT_PROJECT_NAME)
.setParam("organization", organization.getKey())
+ .setParam("visibility", "public")
.executeProtobuf(CreateWsResponse.class);
- assertThat(result.getProject().getVisibility()).isEqualTo("public");
+ AssertionsForClassTypes.assertThat(result.getProject().getVisibility()).isEqualTo("public");
}
@Test
- public void apply_default_project_visibility_private() {
+ public void fail_to_create_private_projects_when_organization_is_not_allowed_to_use_private_projects() {
OrganizationDto organization = db.organizations().insert();
- db.organizations().setNewProjectPrivate(organization, true);
userSession.addPermission(PROVISION_PROJECTS, organization);
expectSuccessfulCallToComponentUpdater();
+ doThrow(new BillingValidationsException("This organization cannot use project private")).when(billingValidations)
+ .checkCanUpdateProjectVisibility(any(BillingValidations.Organization.class), eq(true));
- CreateWsResponse result = ws.newRequest()
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("This organization cannot use project private");
+
+ ws.newRequest()
.setParam("key", DEFAULT_PROJECT_KEY)
.setParam("name", DEFAULT_PROJECT_NAME)
.setParam("organization", organization.getKey())
+ .setParam("visibility", "private")
.executeProtobuf(CreateWsResponse.class);
+ }
- assertThat(result.getProject().getVisibility()).isEqualTo("private");
+ @Test
+ public void fail_when_project_already_exists() throws Exception {
+ OrganizationDto organization = db.organizations().insert();
+ when(componentUpdater.create(any(DbSession.class), any(NewComponent.class), anyInt())).thenThrow(BadRequestException.create("already exists"));
+ userSession.addPermission(PROVISION_PROJECTS, organization);
+
+ expectedException.expect(BadRequestException.class);
+
+ call(CreateRequest.builder()
+ .setOrganization(organization.getKey())
+ .setKey(DEFAULT_PROJECT_KEY)
+ .setName(DEFAULT_PROJECT_NAME)
+ .build());
+ }
+
+ @Test
+ public void fail_when_missing_project_parameter() throws Exception {
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("The 'project' parameter is missing");
+
+ call(CreateRequest.builder().setName(DEFAULT_PROJECT_NAME).build());
+ }
+
+ @Test
+ public void fail_when_missing_name_parameter() throws Exception {
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("The 'name' parameter is missing");
+
+ call(CreateRequest.builder().setKey(DEFAULT_PROJECT_KEY).build());
+ }
+
+ @Test
+ public void fail_when_missing_create_project_permission() throws Exception {
+ expectedException.expect(ForbiddenException.class);
+
+ call(CreateRequest.builder().setKey(DEFAULT_PROJECT_KEY).setName(DEFAULT_PROJECT_NAME).build());
+ }
+
+ @Test
+ public void test_example() {
+ userSession.addPermission(PROVISION_PROJECTS, db.getDefaultOrganization());
+ expectSuccessfulCallToComponentUpdater();
+
+ String result = ws.newRequest()
+ .setParam("key", DEFAULT_PROJECT_KEY)
+ .setParam("name", DEFAULT_PROJECT_NAME)
+ .execute().getInput();
+
+ assertJson(result).isSimilarTo(getClass().getResource("create-example.json"));
}
@Test