--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.organization;
+
+import org.sonar.db.DbSession;
+
+public interface OrganizationFlags {
+
+ boolean isEnabled(DbSession dbSession);
+
+ /**
+ * Ensures that {@link #isEnabled(DbSession)} is {@code true},
+ * otherwise throws {@link IllegalStateException}
+ */
+ void checkEnabled(DbSession dbSession);
+
+ void enable(DbSession dbSession);
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.organization;
+
+import java.util.Optional;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.server.property.InternalProperties;
+
+import static java.lang.String.valueOf;
+
+public class OrganizationFlagsImpl implements OrganizationFlags {
+
+ public static final String FAILURE_MESSAGE = "Organization support is disabled";
+
+ private final DbClient dbClient;
+
+ public OrganizationFlagsImpl(DbClient dbClient) {
+ this.dbClient = dbClient;
+ }
+
+ @Override
+ public boolean isEnabled(DbSession dbSession) {
+ Optional<String> value = dbClient.internalPropertiesDao().selectByKey(dbSession, InternalProperties.ORGANIZATION_ENABLED);
+ return value.map(s -> "true".equals(s)).orElse(false);
+ }
+
+ @Override
+ public void checkEnabled(DbSession dbSession) {
+ if (!isEnabled(dbSession)) {
+ throw new IllegalStateException(FAILURE_MESSAGE);
+ }
+ }
+
+ @Override
+ public void enable(DbSession dbSession) {
+ dbClient.internalPropertiesDao().save(dbSession, InternalProperties.ORGANIZATION_ENABLED, valueOf(true));
+ }
+}
import org.sonar.db.DbSession;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.server.organization.OrganizationCreation;
+import org.sonar.server.organization.OrganizationFlags;
import org.sonar.server.organization.OrganizationValidation;
import org.sonar.server.user.UserSession;
import org.sonarqube.ws.Organizations.CreateWsResponse;
private final OrganizationsWsSupport wsSupport;
private final OrganizationValidation organizationValidation;
private final OrganizationCreation organizationCreation;
+ private final OrganizationFlags organizationFlags;
public CreateAction(Settings settings, UserSession userSession, DbClient dbClient, OrganizationsWsSupport wsSupport,
- OrganizationValidation organizationValidation, OrganizationCreation organizationCreation) {
+ OrganizationValidation organizationValidation, OrganizationCreation organizationCreation, OrganizationFlags organizationFlags) {
this.settings = settings;
this.userSession = userSession;
this.dbClient = dbClient;
this.wsSupport = wsSupport;
this.organizationValidation = organizationValidation;
this.organizationCreation = organizationCreation;
+ this.organizationFlags = organizationFlags;
}
@Override
WebService.NewAction action = context.createAction(ACTION)
.setPost(true)
.setDescription("Create an organization.<br />" +
- "Requires 'Administer System' permission unless any logged in user is allowed to create an organization (see appropriate setting). Organization feature must be enabled.")
+ "Requires 'Administer System' permission unless any logged in user is allowed to create an organization (see appropriate setting). Organization support must be enabled.")
.setResponseExample(getClass().getResource("example-create.json"))
.setInternal(true)
.setSince("6.2")
String avatar = wsSupport.getAndCheckAvatar(request);
try (DbSession dbSession = dbClient.openSession(false)) {
- wsSupport.checkFeatureEnabled(dbSession);
+ organizationFlags.checkEnabled(dbSession);
OrganizationDto organization = organizationCreation.create(
dbSession,
userSession.getUserId().longValue(),
import org.sonar.server.component.ComponentCleanerService;
import org.sonar.server.organization.DefaultOrganization;
import org.sonar.server.organization.DefaultOrganizationProvider;
+import org.sonar.server.organization.OrganizationFlags;
import org.sonar.server.user.UserSession;
import static com.google.common.base.Preconditions.checkArgument;
private final DbClient dbClient;
private final DefaultOrganizationProvider defaultOrganizationProvider;
private final ComponentCleanerService componentCleanerService;
- private final OrganizationsWsSupport support;
+ private final OrganizationFlags organizationFlags;
public DeleteAction(UserSession userSession, DbClient dbClient, DefaultOrganizationProvider defaultOrganizationProvider,
- ComponentCleanerService componentCleanerService, OrganizationsWsSupport support) {
+ ComponentCleanerService componentCleanerService, OrganizationFlags organizationFlags) {
this.userSession = userSession;
this.dbClient = dbClient;
this.defaultOrganizationProvider = defaultOrganizationProvider;
this.componentCleanerService = componentCleanerService;
- this.support = support;
+ this.organizationFlags = organizationFlags;
}
@Override
WebService.NewAction action = context.createAction(ACTION)
.setPost(true)
.setDescription("Delete an organization.<br/>" +
- "Require 'Administer System' permission on the specified organization. Organization feature must be enabled.")
+ "Require 'Administer System' permission on the specified organization. Organization support must be enabled.")
.setInternal(true)
.setSince("6.2")
.setHandler(this);
userSession.checkLoggedIn();
try (DbSession dbSession = dbClient.openSession(false)) {
- support.checkFeatureEnabled(dbSession);
+ organizationFlags.checkEnabled(dbSession);
String key = request.mandatoryParam(PARAM_KEY);
preventDeletionOfDefaultOrganization(key, defaultOrganizationProvider.get());
/*
* SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
import org.sonar.db.DbSession;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.organization.DefaultOrganizationProvider;
-import org.sonar.server.property.InternalProperties;
+import org.sonar.server.organization.OrganizationFlags;
import org.sonar.server.user.UserSession;
-import static java.lang.String.valueOf;
import static java.util.Objects.requireNonNull;
import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
private final UserSession userSession;
private final DbClient dbClient;
private final DefaultOrganizationProvider defaultOrganizationProvider;
- private final OrganizationsWsSupport support;
+ private final OrganizationFlags organizationFlags;
- public EnableSupportAction(UserSession userSession, DbClient dbClient, DefaultOrganizationProvider defaultOrganizationProvider, OrganizationsWsSupport support) {
+ public EnableSupportAction(UserSession userSession, DbClient dbClient, DefaultOrganizationProvider defaultOrganizationProvider,
+ OrganizationFlags organizationFlags) {
this.userSession = userSession;
this.dbClient = dbClient;
this.defaultOrganizationProvider = defaultOrganizationProvider;
- this.support = support;
+ this.organizationFlags = organizationFlags;
}
@Override
@Override
public void handle(Request request, Response response) throws Exception {
- verifySystemAdministrator();
-
try (DbSession dbSession = dbClient.openSession(false)) {
+ verifySystemAdministrator();
verifyFeatureIsDisabled(dbSession);
flagCurrentUserAsRoot(dbSession);
enableFeature(dbSession);
}
private void verifyFeatureIsDisabled(DbSession dbSession) {
- if (support.isFeatureEnabled(dbSession)) {
+ if (organizationFlags.isEnabled(dbSession)) {
throw new BadRequestException("Organizations are already enabled");
}
}
}
private void enableFeature(DbSession dbSession) {
- dbClient.internalPropertiesDao().save(dbSession, InternalProperties.ORGANIZATION_ENABLED, valueOf(true));
+ organizationFlags.enable(dbSession);
}
}
*/
package org.sonar.server.organization.ws;
-import java.util.Optional;
import javax.annotation.CheckForNull;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.WebService;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
import org.sonar.db.organization.OrganizationDto;
-import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.organization.OrganizationValidation;
-import org.sonar.server.property.InternalProperties;
import org.sonarqube.ws.Organizations;
import static org.sonar.core.util.Protobuf.setNullable;
static final String PARAM_AVATAR_URL = "avatar";
private final OrganizationValidation organizationValidation;
- private final DbClient dbClient;
- public OrganizationsWsSupport(OrganizationValidation organizationValidation, DbClient dbClient) {
+ public OrganizationsWsSupport(OrganizationValidation organizationValidation) {
this.organizationValidation = organizationValidation;
- this.dbClient = dbClient;
}
String getAndCheckMandatoryName(Request request) {
setNullable(dto.getAvatarUrl(), builder::setAvatar);
return builder.build();
}
-
- boolean isFeatureEnabled(DbSession dbSession) {
- Optional<String> value = dbClient.internalPropertiesDao().selectByKey(dbSession, InternalProperties.ORGANIZATION_ENABLED);
- return value.isPresent() && Boolean.parseBoolean(value.get());
- }
-
- /**
- * Ensures that the organization feature is enabled, otherwise throws {@link BadRequestException}
- */
- void checkFeatureEnabled(DbSession dbSession) {
- if (!isFeatureEnabled(dbSession)) {
- throw new BadRequestException("Organizations feature is not enabled");
- }
- }
}
import org.sonar.db.DbSession;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.organization.OrganizationFlags;
import org.sonar.server.user.UserSession;
import org.sonarqube.ws.Organizations;
private final UserSession userSession;
private final OrganizationsWsSupport wsSupport;
private final DbClient dbClient;
+ private final OrganizationFlags organizationFlags;
- public UpdateAction(UserSession userSession, OrganizationsWsSupport wsSupport, DbClient dbClient) {
+ public UpdateAction(UserSession userSession, OrganizationsWsSupport wsSupport, DbClient dbClient,
+ OrganizationFlags organizationFlags) {
this.userSession = userSession;
this.wsSupport = wsSupport;
this.dbClient = dbClient;
+ this.organizationFlags = organizationFlags;
}
@Override
WebService.NewAction action = context.createAction(ACTION)
.setPost(true)
.setDescription("Update an organization.<br/>" +
- "Require 'Administer System' permission. Organization feature must be enabled.")
+ "Require 'Administer System' permission. Organization support must be enabled.")
.setInternal(true)
.setSince("6.2")
.setHandler(this);
userSession.checkLoggedIn();
try (DbSession dbSession = dbClient.openSession(false)) {
- wsSupport.checkFeatureEnabled(dbSession);
+ organizationFlags.checkEnabled(dbSession);
String key = request.mandatoryParam(PARAM_KEY);
import org.sonar.api.utils.UriReader;
import org.sonar.core.util.DefaultHttpDownloader;
import org.sonar.server.organization.DefaultOrganizationProviderImpl;
+import org.sonar.server.organization.OrganizationFlagsImpl;
import org.sonar.server.platform.ServerIdGenerator;
import org.sonar.server.platform.ServerIdLoader;
import org.sonar.server.platform.ServerIdManager;
ServerIdGenerator.class,
LogServerId.class,
DefaultHttpDownloader.class,
- DefaultOrganizationProviderImpl.class);
+ DefaultOrganizationProviderImpl.class,
+ OrganizationFlagsImpl.class);
}
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.organization;
+
+import javax.annotation.Nullable;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.db.DbTester;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class OrganizationFlagsImplTest {
+
+ @Rule
+ public DbTester db = DbTester.create();
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ private OrganizationFlagsImpl underTest = new OrganizationFlagsImpl(db.getDbClient());
+
+ @Test
+ public void isEnabled_returns_false_by_default() {
+ assertThat(underTest.isEnabled(db.getSession())).isFalse();
+ verifyInternalProperty(null);
+ }
+
+ @Test
+ public void enable_does_enable_feature_by_inserting_internal_property() {
+ underTest.enable(db.getSession());
+
+ assertThat(underTest.isEnabled(db.getSession())).isTrue();
+ verifyInternalProperty("true");
+ }
+
+ @Test
+ public void checkEnabled_throws_IllegalStateException_if_feature_is_disabled() {
+ expectedException.expect(IllegalStateException.class);
+ expectedException.expectMessage("Organization support is disabled");
+
+ underTest.checkEnabled(db.getSession());
+ }
+
+ @Test
+ public void checkEnabled_succeeds_if_feature_is_enabled() {
+ underTest.enable(db.getSession());
+
+ underTest.checkEnabled(db.getSession());
+ }
+
+ private void verifyInternalProperty(@Nullable String expectedValue) {
+ db.properties().verifyInternal("organization.enabled", expectedValue);
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.organization;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+import org.sonar.db.DbSession;
+
+import static org.sonar.server.organization.OrganizationFlagsImpl.FAILURE_MESSAGE;
+
+public class TestOrganizationFlags implements OrganizationFlags {
+
+ private final AtomicBoolean enabled = new AtomicBoolean(false);
+
+ private TestOrganizationFlags() {
+ }
+
+ @Override
+ public boolean isEnabled(DbSession dbSession) {
+ return enabled.get();
+ }
+
+ public TestOrganizationFlags setEnabled(boolean b) {
+ this.enabled.set(b);
+ return this;
+ }
+
+ @Override
+ public void enable(DbSession dbSession) {
+ setEnabled(true);
+ }
+
+ @Override
+ public void checkEnabled(DbSession dbSession) {
+ if (!isEnabled(dbSession)) {
+ throw new IllegalStateException(FAILURE_MESSAGE);
+ }
+ }
+
+ /**
+ * By default Organization support is disabled
+ */
+ public static TestOrganizationFlags standalone() {
+ return new TestOrganizationFlags();
+ }
+}
import org.sonar.api.config.Settings;
import org.sonar.api.server.ws.WebService;
import org.sonar.api.utils.System2;
+import org.sonar.api.utils.internal.AlwaysIncreasingSystem2;
import org.sonar.api.web.UserRole;
import org.sonar.core.permission.GlobalPermissions;
import org.sonar.core.util.UuidFactory;
import org.sonar.db.user.UserDto;
import org.sonar.db.user.UserMembershipDto;
import org.sonar.db.user.UserMembershipQuery;
-import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.UnauthorizedException;
import org.sonar.server.organization.OrganizationCreation;
import org.sonar.server.organization.OrganizationCreationImpl;
import org.sonar.server.organization.OrganizationValidation;
import org.sonar.server.organization.OrganizationValidationImpl;
+import org.sonar.server.organization.TestOrganizationFlags;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.TestRequest;
import org.sonar.server.ws.WsActionTester;
private UuidFactory uuidFactory = mock(UuidFactory.class);
private OrganizationValidation organizationValidation = new OrganizationValidationImpl();
private OrganizationCreation organizationCreation = new OrganizationCreationImpl(dbClient, system2, uuidFactory, organizationValidation, settings);
- private CreateAction underTest = new CreateAction(settings, userSession, dbClient, new OrganizationsWsSupport(organizationValidation, dbClient), organizationValidation, organizationCreation);
+ private TestOrganizationFlags organizationFlags = TestOrganizationFlags.standalone().setEnabled(true);
+ private CreateAction underTest = new CreateAction(settings, userSession, dbClient, new OrganizationsWsSupport(organizationValidation), organizationValidation, organizationCreation, organizationFlags);
private WsActionTester wsTester = new WsActionTester(underTest);
@Test
assertThat(action.key()).isEqualTo("create");
assertThat(action.isPost()).isTrue();
assertThat(action.description()).isEqualTo("Create an organization.<br />" +
- "Requires 'Administer System' permission unless any logged in user is allowed to create an organization (see appropriate setting). Organization feature must be enabled.");
+ "Requires 'Administer System' permission unless any logged in user is allowed to create an organization (see appropriate setting). Organization support must be enabled.");
assertThat(action.isInternal()).isTrue();
assertThat(action.since()).isEqualTo("6.2");
assertThat(action.handler()).isEqualTo(underTest);
@Test
public void verify_response_example() throws URISyntaxException, IOException {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
mockForSuccessfulInsert(Uuids.UUID_EXAMPLE_01, SOME_DATE);
String response = executeJsonRequest("Foo Company", "foo-company", "The Foo company produces quality software for Bar.", "https://www.foo.com", "https://www.foo.com/foo.png");
@Test
public void request_fails_if_user_is_not_logged_in_and_logged_in_users_cannot_create_organizations() {
- enableOrganizations();
userSession.anonymous();
expectedException.expect(ForbiddenException.class);
@Test
public void request_fails_if_user_is_not_logged_in_and_logged_in_users_can_create_organizations() {
- enableOrganizations();
userSession.anonymous();
settings.setProperty(ORGANIZATIONS_ANYONE_CAN_CREATE, true);
@Test
public void request_fails_if_user_is_not_root_and_logged_in_users_cannot_create_organizations() {
- enableOrganizations();
userSession.logIn();
expectedException.expect(ForbiddenException.class);
@Test
public void request_succeeds_if_user_is_root_and_logged_in_users_cannot_create_organizations() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
mockForSuccessfulInsert(SOME_UUID, SOME_DATE);
verifyResponseAndDb(executeRequest("foo"), SOME_UUID, "foo", "foo", SOME_DATE);
@Test
public void request_succeeds_if_user_is_root_and_logged_in_users_can_create_organizations() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
settings.setProperty(ORGANIZATIONS_ANYONE_CAN_CREATE, true);
mockForSuccessfulInsert(SOME_UUID, SOME_DATE);
@Test
public void request_succeeds_if_user_is_not_root_and_logged_in_users_can_create_organizations() {
- enableOrganizations();
userSession.logIn();
settings.setProperty(ORGANIZATIONS_ANYONE_CAN_CREATE, true);
mockForSuccessfulInsert(SOME_UUID, SOME_DATE);
@Test
public void request_fails_if_name_param_is_missing() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("The 'name' parameter is missing");
@Test
public void request_fails_if_name_is_one_char_long() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Name 'a' must be at least 2 chars long");
@Test
public void request_succeeds_if_name_is_two_chars_long() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
mockForSuccessfulInsert(SOME_UUID, SOME_DATE);
verifyResponseAndDb(executeRequest("ab"), SOME_UUID, "ab", "ab", SOME_DATE);
@Test
public void request_fails_if_name_is_65_chars_long() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Name '" + STRING_65_CHARS_LONG + "' must be at most 64 chars long");
@Test
public void request_succeeds_if_name_is_64_char_long() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
mockForSuccessfulInsert(SOME_UUID, SOME_DATE);
String name = STRING_65_CHARS_LONG.substring(0, 64);
@Test
public void request_fails_if_key_one_char_long() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Key 'a' must be at least 2 chars long");
@Test
public void request_fails_if_key_is_33_chars_long() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
String key = STRING_65_CHARS_LONG.substring(0, 33);
@Test
public void request_succeeds_if_key_is_2_chars_long() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
mockForSuccessfulInsert(SOME_UUID, SOME_DATE);
verifyResponseAndDb(executeRequest("foo", "ab"), SOME_UUID, "foo", "ab", SOME_DATE);
@Test
public void requests_succeeds_if_key_is_32_chars_long() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
mockForSuccessfulInsert(SOME_UUID, SOME_DATE);
String key = STRING_65_CHARS_LONG.substring(0, 32);
@Test
public void requests_fails_if_key_contains_non_ascii_chars_but_dash() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
requestFailsWithInvalidCharInKey("ab@");
}
@Test
public void request_fails_if_key_starts_with_a_dash() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
requestFailsWithInvalidCharInKey("-ab");
}
@Test
public void request_fails_if_key_ends_with_a_dash() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
requestFailsWithInvalidCharInKey("ab-");
}
@Test
public void request_fails_if_key_contains_space() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
requestFailsWithInvalidCharInKey("a b");
}
@Test
public void request_fails_if_key_is_specified_and_already_exists_in_DB() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
OrganizationDto org = insertOrganization("the-key");
expectedException.expect(IllegalArgumentException.class);
@Test
public void request_fails_if_key_computed_from_name_already_exists_in_DB() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
String key = STRING_65_CHARS_LONG.substring(0, 32);
insertOrganization(key);
@Test
public void request_succeeds_if_description_url_and_avatar_are_not_specified() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
mockForSuccessfulInsert(SOME_UUID, SOME_DATE);
CreateWsResponse response = executeRequest("foo", "bar", null, null, null);
@Test
public void request_succeeds_if_description_url_and_avatar_are_specified() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
mockForSuccessfulInsert(SOME_UUID, SOME_DATE);
CreateWsResponse response = executeRequest("foo", "bar", "moo", "doo", "boo");
@Test
public void request_succeeds_to_generate_key_from_name_more_then_32_chars_long() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
mockForSuccessfulInsert(SOME_UUID, SOME_DATE);
String name = STRING_65_CHARS_LONG.substring(0, 33);
@Test
public void request_generates_key_ignoring_multiple_following_spaces() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
mockForSuccessfulInsert(SOME_UUID, SOME_DATE);
String name = "ab cd";
@Test
public void request_fails_if_description_is_257_chars_long() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Description '" + STRING_257_CHARS_LONG + "' must be at most 256 chars long");
@Test
public void request_succeeds_if_description_is_256_chars_long() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
mockForSuccessfulInsert(SOME_UUID, SOME_DATE);
String description = STRING_257_CHARS_LONG.substring(0, 256);
@Test
public void request_fails_if_url_is_257_chars_long() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Url '" + STRING_257_CHARS_LONG + "' must be at most 256 chars long");
@Test
public void request_succeeds_if_url_is_256_chars_long() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
mockForSuccessfulInsert(SOME_UUID, SOME_DATE);
String url = STRING_257_CHARS_LONG.substring(0, 256);
@Test
public void request_fails_if_avatar_is_257_chars_long() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Avatar '" + STRING_257_CHARS_LONG + "' must be at most 256 chars long");
@Test
public void request_succeeds_if_avatar_is_256_chars_long() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
mockForSuccessfulInsert(SOME_UUID, SOME_DATE);
String avatar = STRING_257_CHARS_LONG.substring(0, 256);
@Test
public void request_creates_owners_group_with_all_permissions_for_new_organization_and_add_current_user_to_it() {
- enableOrganizations();
mockForSuccessfulInsert(SOME_UUID, SOME_DATE);
UserDto user = dbTester.users().makeRoot(dbTester.users().insertUser());
userSession.logIn(user).setRoot();
@Test
public void request_creates_default_template_for_owner_group_and_anyone() {
- enableOrganizations();
mockForSuccessfulInsert(SOME_UUID, SOME_DATE);
UserDto user = dbTester.users().makeRoot(dbTester.users().insertUser());
userSession.logIn(user).setRoot();
}
@Test
- public void request_fails_with_BadRequestException_if_organization_feature_is_disabled() {
+ public void request_fails_with_IllegalStateException_if_organization_feature_is_disabled() {
+ organizationFlags.setEnabled(false);
logInAsRoot();
- expectedException.expect(BadRequestException.class);
- expectedException.expectMessage("Organizations feature is not enabled");
+ expectedException.expect(IllegalStateException.class);
+ expectedException.expectMessage("Organization support is disabled");
executeJsonRequest("Foo Company", "foo-company", "The Foo company produces quality software for Bar.", "https://www.foo.com", "https://www.foo.com/foo.png");
}
return dto;
}
- private void enableOrganizations() {
- dbTester.enableOrganizations();
- }
-
private void logInAsRoot() {
userSession.logIn().setRoot();
}
-
- private void enableOrganizationsAndLogInAsRoot() {
- enableOrganizations();
- logInAsRoot();
- }
}
import org.sonar.db.user.GroupDto;
import org.sonar.db.user.UserDto;
import org.sonar.server.component.ComponentCleanerService;
-import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.exceptions.UnauthorizedException;
-import org.sonar.server.organization.OrganizationValidationImpl;
import org.sonar.server.organization.TestDefaultOrganizationProvider;
+import org.sonar.server.organization.TestOrganizationFlags;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.WsActionTester;
private DbClient dbClient = dbTester.getDbClient();
private DbSession session = dbTester.getSession();
private ComponentCleanerService componentCleanerService = mock(ComponentCleanerService.class);
- private OrganizationsWsSupport support = new OrganizationsWsSupport(new OrganizationValidationImpl(), dbClient);
- private DeleteAction underTest = new DeleteAction(userSession, dbTester.getDbClient(), TestDefaultOrganizationProvider.from(dbTester), componentCleanerService, support);
+ private TestOrganizationFlags organizationFlags = TestOrganizationFlags.standalone().setEnabled(true);
+ private TestDefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(dbTester);
+ private DeleteAction underTest = new DeleteAction(userSession, dbTester.getDbClient(), defaultOrganizationProvider, componentCleanerService, organizationFlags);
private WsActionTester wsTester = new WsActionTester(underTest);
@Test
assertThat(action.key()).isEqualTo("delete");
assertThat(action.isPost()).isTrue();
assertThat(action.description()).isEqualTo("Delete an organization.<br/>" +
- "Require 'Administer System' permission on the specified organization. Organization feature must be enabled.");
+ "Require 'Administer System' permission on the specified organization. Organization support must be enabled.");
assertThat(action.isInternal()).isTrue();
assertThat(action.since()).isEqualTo("6.2");
assertThat(action.handler()).isEqualTo(underTest);
}
@Test
- public void request_fails_with_organization_feature_is_disabled() {
+ public void request_fails_with_IllegalStateException_if_organization_feature_is_disabled() {
+ organizationFlags.setEnabled(false);
userSession.logIn();
- expectedException.expect(BadRequestException.class);
- expectedException.expectMessage("");
+ expectedException.expect(IllegalStateException.class);
+ expectedException.expectMessage("Organization support is disabled");
wsTester.newRequest().execute();
}
@Test
public void request_fails_with_UnauthorizedException_if_user_is_not_logged_in() {
- enableOrganizations();
-
expectedException.expect(UnauthorizedException.class);
expectedException.expectMessage("Authentication is required");
@Test
public void request_fails_with_IAE_if_key_param_is_missing() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("The 'key' parameter is missing");
@Test
public void request_fails_with_IAE_if_key_is_the_one_of_default_organization() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Default Organization can't be deleted");
@Test
public void request_fails_with_NotFoundException_if_organization_with_specified_key_does_not_exist() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
expectedException.expect(NotFoundException.class);
expectedException.expectMessage("Organization with key 'foo' not found");
@Test
public void request_fails_with_ForbiddenException_when_user_is_not_root_and_is_not_administrator_of_specified_organization() {
- enableOrganizations();
OrganizationDto organization = dbTester.organizations().insert();
userSession.logIn();
@Test
public void request_fails_with_ForbiddenException_when_user_is_not_root_and_is_administrator_of_other_organization() {
- enableOrganizations();
OrganizationDto organization = dbTester.organizations().insert();
logInAsAdministrator(dbTester.getDefaultOrganization());
@Test
public void request_deletes_specified_organization_if_exists_and_user_is_administrator_of_it() {
- enableOrganizations();
OrganizationDto organization = dbTester.organizations().insert();
logInAsAdministrator(organization);
@Test
public void request_deletes_specified_organization_if_exists_and_user_is_root() {
- enableOrganizations();
OrganizationDto organization = dbTester.organizations().insert();
userSession.logIn().setRoot();
@Test
public void request_also_deletes_components_of_specified_organization() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
OrganizationDto organization = dbTester.organizations().insert();
ComponentDto project = dbTester.components().insertProject(organization);
@Test
public void request_also_deletes_permissions_templates_and_permissions_and_groups_of_specified_organization() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
OrganizationDto org = dbTester.organizations().insert();
OrganizationDto otherOrg = dbTester.organizations().insert();
.execute();
}
- private void enableOrganizations() {
- dbTester.enableOrganizations();
- }
-
private void logInAsRoot() {
userSession.logIn().setRoot();
}
private void logInAsAdministrator(OrganizationDto organization) {
userSession.logIn().addOrganizationPermission(organization.getUuid(), SYSTEM_ADMIN);
}
-
- private void enableOrganizationsAndLogInAsRoot() {
- enableOrganizations();
- logInAsRoot();
- }
}
/*
* SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
import org.sonar.server.exceptions.UnauthorizedException;
import org.sonar.server.organization.DefaultOrganizationProvider;
import org.sonar.server.organization.OrganizationValidationImpl;
+import org.sonar.server.organization.OrganizationFlags;
+import org.sonar.server.organization.OrganizationFlagsImpl;
import org.sonar.server.organization.TestDefaultOrganizationProvider;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.TestResponse;
public DbTester db = DbTester.create();
private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db);
- private OrganizationsWsSupport support = new OrganizationsWsSupport(new OrganizationValidationImpl(), db.getDbClient());
- private EnableSupportAction underTest = new EnableSupportAction(userSession, db.getDbClient(), defaultOrganizationProvider, support);
+ private OrganizationFlags organizationFlags = new OrganizationFlagsImpl(db.getDbClient());
+ private EnableSupportAction underTest = new EnableSupportAction(userSession, db.getDbClient(), defaultOrganizationProvider, organizationFlags);
private WsActionTester tester = new WsActionTester(underTest);
@Test
public void enabling_support_saves_internal_property_and_flags_caller_as_root() {
UserDto user = db.users().insertUser();
UserDto otherUser = db.users().insertUser();
- db.properties().verifyInternal("organization.enabled", null);
- db.rootFlag().verify(user.getLogin(), false);
- db.rootFlag().verify(otherUser.getLogin(), false);
+ verifyFeatureEnabled(false);
+ verifyRoot(user, false);
+ verifyRoot(otherUser, false);
logInAsSystemAdministrator(user.getLogin());
call();
- db.properties().verifyInternal("organization.enabled", "true");
- db.rootFlag().verify(user.getLogin(), true);
- db.rootFlag().verify(otherUser.getLogin(), false);
+ verifyFeatureEnabled(true);
+ verifyRoot(user, true);
+ verifyRoot(otherUser, false);
}
@Test
TestResponse response = tester.newRequest().setMethod("POST").execute();
assertThat(response.getStatus()).isEqualTo(HttpURLConnection.HTTP_NO_CONTENT);
}
+
+ private void verifyFeatureEnabled(boolean enabled) {
+ assertThat(organizationFlags.isEnabled(db.getSession())).isEqualTo(enabled);
+ }
+
+ private void verifyRoot(UserDto user, boolean root) {
+ db.rootFlag().verify(user.getLogin(), root);
+ }
}
@Rule
public ExpectedException expectedException = ExpectedException.none();
- private SearchAction underTest = new SearchAction(dbTester.getDbClient(), new OrganizationsWsSupport(new OrganizationValidationImpl(), dbTester.getDbClient()));
+ private SearchAction underTest = new SearchAction(dbTester.getDbClient(), new OrganizationsWsSupport(new OrganizationValidationImpl()));
private WsActionTester wsTester = new WsActionTester(underTest);
@Test
import org.sonar.api.utils.System2;
import org.sonar.db.DbTester;
import org.sonar.db.organization.OrganizationDto;
-import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.UnauthorizedException;
import org.sonar.server.organization.OrganizationValidationImpl;
+import org.sonar.server.organization.TestOrganizationFlags;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.TestRequest;
import org.sonar.server.ws.WsActionTester;
@Rule
public ExpectedException expectedException = ExpectedException.none();
- private UpdateAction underTest = new UpdateAction(userSession, new OrganizationsWsSupport(new OrganizationValidationImpl(), dbTester.getDbClient()), dbTester.getDbClient());
+ private TestOrganizationFlags organizationFlags = TestOrganizationFlags.standalone().setEnabled(true);
+ private UpdateAction underTest = new UpdateAction(userSession, new OrganizationsWsSupport(new OrganizationValidationImpl()), dbTester.getDbClient(), organizationFlags);
private WsActionTester wsTester = new WsActionTester(underTest);
@Test
assertThat(action.key()).isEqualTo("update");
assertThat(action.isPost()).isTrue();
assertThat(action.description()).isEqualTo("Update an organization.<br/>" +
- "Require 'Administer System' permission. Organization feature must be enabled.");
+ "Require 'Administer System' permission. Organization support must be enabled.");
assertThat(action.isInternal()).isTrue();
assertThat(action.since()).isEqualTo("6.2");
assertThat(action.handler()).isEqualTo(underTest);
}
@Test
- public void request_fails_with_organization_feature_is_disabled() {
+ public void request_fails_with_IllegalStateException_if_organization_feature_is_disabled() {
+ organizationFlags.setEnabled(false);
userSession.logIn();
- expectedException.expect(BadRequestException.class);
- expectedException.expectMessage("");
+ expectedException.expect(IllegalStateException.class);
+ expectedException.expectMessage("Organization support is disabled");
wsTester.newRequest().execute();
}
@Test
public void request_succeeds_if_user_is_root() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
OrganizationDto dto = mockForSuccessfulUpdate(DATE_1, DATE_2);
verifyResponseAndDb(executeKeyRequest(dto.getKey(), "ab"), dto, "ab", DATE_2);
@Test
public void request_succeeds_if_user_is_administrator_of_specified_organization() {
- enableOrganizations();
OrganizationDto dto = mockForSuccessfulUpdate(DATE_1, DATE_2);
logInAsAdministrator(dto);
@Test
public void request_fails_with_UnauthorizedException_when_user_is_not_logged_in() {
- enableOrganizations();
-
expectedException.expect(UnauthorizedException.class);
expectedException.expectMessage("Authentication is required");
@Test
public void request_fails_if_user_is_not_root_and_is_not_organization_administrator() {
- enableOrganizations();
OrganizationDto dto = mockForSuccessfulUpdate(DATE_1, DATE_2);
userSession.logIn();
@Test
public void request_fails_if_user_is_administrator_of_another_organization() {
- enableOrganizations();
OrganizationDto org = dbTester.organizations().insert();
logInAsAdministrator(dbTester.getDefaultOrganization());
@Test
public void request_fails_if_key_is_missing() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("The 'key' parameter is missing");
@Test
public void request_with_only_key_param_succeeds_and_updates_only_updateAt_field() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
OrganizationDto dto = mockForSuccessfulUpdate(DATE_1, DATE_2);
verifyResponseAndDb(executeKeyRequest(dto.getKey(), null), dto, dto.getName(), DATE_2);
@Test
public void request_fails_if_name_is_one_char_long() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Name 'a' must be at least 2 chars long");
@Test
public void request_succeeds_if_name_is_two_chars_long() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
OrganizationDto dto = mockForSuccessfulUpdate(DATE_1, DATE_2);
verifyResponseAndDb(executeKeyRequest(dto.getKey(), "ab"), dto, "ab", DATE_2);
@Test
public void request_fails_if_name_is_65_chars_long() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Name '" + STRING_65_CHARS_LONG + "' must be at most 64 chars long");
@Test
public void request_succeeds_if_name_is_64_char_long() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
OrganizationDto dto = mockForSuccessfulUpdate(DATE_1, DATE_2);
String name = STRING_65_CHARS_LONG.substring(0, 64);
@Test
public void request_succeeds_if_description_url_and_avatar_are_not_specified() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
OrganizationDto dto = mockForSuccessfulUpdate(DATE_1, DATE_2);
Organizations.UpdateWsResponse response = executeKeyRequest(dto.getKey(), "bar", null, null, null);
@Test
public void request_succeeds_if_description_url_and_avatar_are_specified() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
OrganizationDto dto = mockForSuccessfulUpdate(DATE_1, DATE_2);
Organizations.UpdateWsResponse response = executeKeyRequest(dto.getKey(), "bar", "moo", "doo", "boo");
@Test
public void request_fails_if_description_is_257_chars_long() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Description '" + STRING_257_CHARS_LONG + "' must be at most 256 chars long");
@Test
public void request_succeeds_if_description_is_256_chars_long() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
OrganizationDto dto = mockForSuccessfulUpdate(DATE_1, DATE_2);
String description = STRING_257_CHARS_LONG.substring(0, 256);
@Test
public void request_fails_if_url_is_257_chars_long() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Url '" + STRING_257_CHARS_LONG + "' must be at most 256 chars long");
@Test
public void request_succeeds_if_url_is_256_chars_long() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
OrganizationDto dto = mockForSuccessfulUpdate(DATE_1, DATE_2);
String url = STRING_257_CHARS_LONG.substring(0, 256);
@Test
public void request_fails_if_avatar_is_257_chars_long() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Avatar '" + STRING_257_CHARS_LONG + "' must be at most 256 chars long");
@Test
public void request_succeeds_if_avatar_is_256_chars_long() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
OrganizationDto dto = mockForSuccessfulUpdate(DATE_1, DATE_2);
String avatar = STRING_257_CHARS_LONG.substring(0, 256);
@Test
public void request_removes_optional_parameters_when_associated_parameter_are_empty() {
- enableOrganizationsAndLogInAsRoot();
+ logInAsRoot();
OrganizationDto dto = mockForSuccessfulUpdate(DATE_1, DATE_2);
Organizations.UpdateWsResponse response = executeKeyRequest(dto.getKey(), "bla", "", "", "");
assertThat(newDto.getUpdatedAt()).isEqualTo(updateAt);
}
- private void enableOrganizations() {
- dbTester.enableOrganizations();
- }
-
private void logInAsRoot() {
userSession.logIn().setRoot();
}
private void logInAsAdministrator(OrganizationDto organizationDto) {
userSession.logIn().addOrganizationPermission(organizationDto.getUuid(), SYSTEM_ADMIN);
}
-
- private void enableOrganizationsAndLogInAsRoot() {
- enableOrganizations();
- logInAsRoot();
- }
}