import it.analysis.SettingsEncryptionTest;
import it.analysis.TempFolderTest;
import it.measure.DecimalScaleMetricTest;
-import it.organization.OrganizationIt;
import it.plugins.VersionPluginTest;
-import it.root.RootIt;
+import it.organization.OrganizationTest;
+import it.organization.RootTest;
import it.webhook.WebhooksTest;
import org.junit.ClassRule;
import org.junit.runner.RunWith;
// measures
DecimalScaleMetricTest.class,
// organization
- OrganizationIt.class,
+ OrganizationTest.class,
// root users
- RootIt.class,
+ RootTest.class,
WebhooksTest.class
})
public class Category3Suite {
import com.sonar.orchestrator.build.SonarScanner;
import it.Category3Suite;
import javax.annotation.Nullable;
-import org.junit.AfterClass;
+import org.junit.After;
import org.junit.Before;
-import org.junit.BeforeClass;
import org.junit.ClassRule;
+import org.junit.Rule;
import org.junit.Test;
import org.sonarqube.ws.WsUserTokens;
import org.sonarqube.ws.client.WsClient;
-import org.sonarqube.ws.client.permission.AddGroupWsRequest;
import org.sonarqube.ws.client.permission.AddUserWsRequest;
-import org.sonarqube.ws.client.permission.RemoveGroupWsRequest;
import org.sonarqube.ws.client.usertoken.GenerateWsRequest;
import org.sonarqube.ws.client.usertoken.RevokeWsRequest;
import org.sonarqube.ws.client.usertoken.UserTokensService;
public class PermissionTest {
- private static final String SIMPLE_USER = "simple-user";
+ private static final String A_LOGIN = "a_login";
+ private static final String A_PASSWORD = "a_password";
@ClassRule
public static Orchestrator orchestrator = Category3Suite.ORCHESTRATOR;
- @ClassRule
- public static UserRule userRule = UserRule.from(orchestrator);
- private static WsClient adminWsClient;
+ @Rule
+ public UserRule userRule = UserRule.from(orchestrator);
- private static UserTokensService userTokensWsClient;
+ private WsClient adminWsClient;
+ private UserTokensService userTokensWsClient;
- @BeforeClass
- public static void setUp() {
- adminWsClient = newAdminWsClient(orchestrator);
- userTokensWsClient = adminWsClient.userTokens();
- resetData();
- }
+ @Before
+ public void setUp() {
+ orchestrator.resetData();
- @AfterClass
- public static void restoreAnyonePermissionToScan() throws Exception {
- addGroupPermission("Anyone", "scan");
- }
+ // enforce scanners to be authenticated
+ setServerProperty(orchestrator, "sonar.forceAuthentication", "true");
- @Before
- public void deleteData() {
- resetData();
+ adminWsClient = newAdminWsClient(orchestrator);
+ userTokensWsClient = adminWsClient.userTokens();
}
- private static void resetData() {
- orchestrator.resetData();
+ @After
+ public void tearDown() throws Exception {
resetSettings(orchestrator, null, "sonar.forceAuthentication");
- userRule.deactivateUsers(SIMPLE_USER);
- removeGroupPermission("Anyone", "scan");
+ userRule.resetUsers();
}
@Test
- public void run_analysis_with_token_authentication() {
- userRule.createUser(SIMPLE_USER, "password");
- addUserPermission(SIMPLE_USER, "scan", null);
- String tokenName = "Analyze Project";
+ public void scanner_can_authenticate_with_authentication_token() {
+ createUserWithProvisioningAndScanPermissions();
+
+ String tokenName = "For test";
WsUserTokens.GenerateWsResponse generateWsResponse = userTokensWsClient.generate(new GenerateWsRequest()
- .setLogin(SIMPLE_USER)
+ .setLogin(A_LOGIN)
.setName(tokenName));
SonarScanner sampleProject = SonarScanner.create(projectDir("shared/xoo-sample"));
sampleProject.setProperties(
BuildResult buildResult = orchestrator.executeBuild(sampleProject);
assertThat(buildResult.isSuccess()).isTrue();
- userTokensWsClient.revoke(new RevokeWsRequest().setLogin(SIMPLE_USER).setName(tokenName));
+ userTokensWsClient.revoke(new RevokeWsRequest().setLogin(A_LOGIN).setName(tokenName));
}
@Test
- public void run_analysis_with_incorrect_token() {
+ public void scanner_fails_if_authentication_token_is_not_valid() {
SonarScanner sampleProject = SonarScanner.create(projectDir("shared/xoo-sample"));
sampleProject.setProperties(
"sonar.login", "unknown-token",
* SONAR-4211 Test Sonar Runner when server requires authentication
*/
@Test
- public void should_authenticate_when_needed() {
+ public void scanner_can_authenticate_with_login_password() {
+ createUserWithProvisioningAndScanPermissions();
+
orchestrator.getServer().provisionProject("sample", "xoo-sample");
- setServerProperty(orchestrator, "sonar.forceAuthentication", "true");
BuildResult buildResult = scanQuietly("shared/xoo-sample",
"sonar.login", "",
"Not authorized. Please check the properties sonar.login and sonar.password.");
buildResult = scan("shared/xoo-sample",
- "sonar.login", "admin",
- "sonar.password", "admin");
+ "sonar.login", A_LOGIN,
+ "sonar.password", A_PASSWORD);
assertThat(buildResult.getLastStatus()).isEqualTo(0);
}
@Test
- public void run_analysis_with_authenticated_user_having_global_execute_analysis_permission() throws Exception {
- userRule.createUser(SIMPLE_USER, "password");
+ public void run_scanner_with_user_having_scan_permission_only_on_project() throws Exception {
+ userRule.createUser(A_LOGIN, A_PASSWORD);
orchestrator.getServer().provisionProject("sample", "sample");
- addUserPermission(SIMPLE_USER, "scan", null);
+ addUserPermission(A_LOGIN, "scan", "sample");
- BuildResult buildResult = scanQuietly("shared/xoo-sample", "sonar.login", SIMPLE_USER, "sonar.password", "password");
+ BuildResult buildResult = scanQuietly("shared/xoo-sample", "sonar.login", A_LOGIN, "sonar.password", A_PASSWORD);
assertThat(buildResult.isSuccess()).isTrue();
}
- @Test
- public void run_analysis_with_authenticated_user_having_execute_analysis_permission_only_on_project() throws Exception {
- userRule.createUser(SIMPLE_USER, "password");
- orchestrator.getServer().provisionProject("sample", "sample");
- addUserPermission(SIMPLE_USER, "scan", "sample");
-
- BuildResult buildResult = scanQuietly("shared/xoo-sample", "sonar.login", SIMPLE_USER, "sonar.password", "password");
-
- assertThat(buildResult.isSuccess()).isTrue();
- }
-
- @Test
- public void run_analysis_when_execute_analysis_is_set_to_anyone() throws Exception {
- addGroupPermission("Anyone", "scan");
-
- BuildResult buildResult = scanQuietly("shared/xoo-sample");
-
- assertThat(buildResult.isSuccess()).isTrue();
- }
-
- private static void addUserPermission(String login, String permission, @Nullable String projectKey) {
+ private void addUserPermission(String login, String permission, @Nullable String projectKey) {
adminWsClient.permissions().addUser(new AddUserWsRequest()
.setLogin(login)
.setPermission(permission)
.setProjectKey(projectKey));
}
- private static void addGroupPermission(String groupName, String permission) {
- adminWsClient.permissions().addGroup(new AddGroupWsRequest()
- .setGroupName(groupName)
- .setPermission(permission));
- }
-
- private static void removeGroupPermission(String groupName, String permission) {
- adminWsClient.permissions().removeGroup(new RemoveGroupWsRequest()
- .setGroupName(groupName)
- .setPermission(permission));
- }
-
private BuildResult scan(String projectPath, String... props) {
SonarScanner scanner = configureScanner(projectPath, props);
return orchestrator.executeBuild(scanner);
return SonarScanner.create(ItUtils.projectDir(projectPath))
.setProperties(props);
}
+
+ private void createUserWithProvisioningAndScanPermissions() {
+ userRule.createUser(A_LOGIN, A_PASSWORD);
+ addUserPermission(A_LOGIN, "provisioning", null);
+ addUserPermission(A_LOGIN, "scan", null);
+ }
+
}
setServerProperty(ORCHESTRATOR, "email.smtp_host.secured", "localhost");
setServerProperty(ORCHESTRATOR, "email.smtp_port.secured", Integer.toString(smtpServer.getServer().getPort()));
- // Create test user
- userRule.createUser(USER_LOGIN, "Tester", USER_EMAIL, USER_LOGIN);
-
// Send test email to the test user
newAdminWsClient(ORCHESTRATOR).wsConnector().call(new PostRequest("api/emails/send")
.setParam("to", USER_EMAIL)
.setParam("message", "This is a test message from SonarQube"))
.failIfNotSuccessful();
- // Add notifications to the test user
- WsClient wsClient = newUserWsClient(ORCHESTRATOR, USER_LOGIN, USER_PASSWORD);
- wsClient.wsConnector().call(new PostRequest("api/notifications/add")
- .setParam("type", "NewIssues")
- .setParam("channel", "EmailNotificationChannel"))
- .failIfNotSuccessful();
- wsClient.wsConnector().call(new PostRequest("api/notifications/add")
- .setParam("type", "ChangesOnMyIssue")
- .setParam("channel", "EmailNotificationChannel"))
- .failIfNotSuccessful();
- wsClient.wsConnector().call(new PostRequest("api/notifications/add")
- .setParam("type", "SQ-MyNewIssues")
- .setParam("channel", "EmailNotificationChannel"))
- .failIfNotSuccessful();
-
// We need to wait until all notifications will be delivered
waitUntilAllNotificationsAreDelivered(1);
@Before
public void prepare() {
ORCHESTRATOR.resetData();
+
+ // Create test user
+ userRule.createUser(USER_LOGIN, "Tester", USER_EMAIL, USER_LOGIN);
+
smtpServer.getMessages().clear();
issueClient = ORCHESTRATOR.getServer().adminWsClient().issueClient();
issuesService = newAdminWsClient(ORCHESTRATOR).issues();
ORCHESTRATOR.getServer().restoreProfile(FileLocation.ofClasspath("/issue/one-issue-per-line-profile.xml"));
ORCHESTRATOR.getServer().provisionProject(PROJECT_KEY, "Sample");
ORCHESTRATOR.getServer().associateProjectToQualityProfile(PROJECT_KEY, "xoo", "one-issue-per-line-profile");
+
+ // Add notifications to the test user
+ WsClient wsClient = newUserWsClient(ORCHESTRATOR, USER_LOGIN, USER_PASSWORD);
+ wsClient.wsConnector().call(new PostRequest("api/notifications/add")
+ .setParam("type", "NewIssues")
+ .setParam("channel", "EmailNotificationChannel"))
+ .failIfNotSuccessful();
+ wsClient.wsConnector().call(new PostRequest("api/notifications/add")
+ .setParam("type", "ChangesOnMyIssue")
+ .setParam("channel", "EmailNotificationChannel"))
+ .failIfNotSuccessful();
+ wsClient.wsConnector().call(new PostRequest("api/notifications/add")
+ .setParam("type", "SQ-MyNewIssues")
+ .setParam("channel", "EmailNotificationChannel"))
+ .failIfNotSuccessful();
+
}
@Test
+++ /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 it.organization;
-
-import com.sonar.orchestrator.Orchestrator;
-import com.sonar.orchestrator.build.BuildFailureException;
-import it.Category3Suite;
-import java.util.List;
-import java.util.function.Consumer;
-import java.util.function.Function;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.sonarqube.ws.Organizations;
-import org.sonarqube.ws.WsComponents;
-import org.sonarqube.ws.client.HttpException;
-import org.sonarqube.ws.client.component.ComponentsService;
-import org.sonarqube.ws.client.organization.CreateWsRequest;
-import org.sonarqube.ws.client.organization.OrganizationService;
-import org.sonarqube.ws.client.organization.SearchWsRequest;
-import org.sonarqube.ws.client.organization.UpdateWsRequest;
-import org.sonarqube.ws.client.permission.AddUserWsRequest;
-import org.sonarqube.ws.client.permission.PermissionsService;
-import util.ItUtils;
-import util.user.GroupManagement;
-import util.user.Groups;
-import util.user.UserRule;
-
-import static java.util.Collections.singletonList;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.Assert.fail;
-
-public class OrganizationIt {
- private static final String DEFAULT_ORGANIZATION_KEY = "default-organization";
- private static final String NAME = "Foo Company";
- private static final String KEY = "foo-company";
- private static final String DESCRIPTION = "the description of Foo company";
- private static final String URL = "https://www.foo.fr";
- private static final String AVATAR_URL = "https://www.foo.fr/corporate_logo.png";
- private static final String SETTING_ANYONE_CAN_CREATE_ORGANIZATIONS = "sonar.organizations.anyoneCanCreate";
-
- @ClassRule
- public static Orchestrator orchestrator = Category3Suite.ORCHESTRATOR;
- @ClassRule
- public static UserRule userRule = UserRule.from(orchestrator);
- @Rule
- public ExpectedException expectedException = ExpectedException.none();
-
- private OrganizationService anonymousOrganizationService = ItUtils.newWsClient(orchestrator).organizations();
- private OrganizationService adminOrganizationService = ItUtils.newAdminWsClient(orchestrator).organizations();
-
- @Before
- public void setUp() throws Exception {
- orchestrator.resetData();
- userRule.resetUsers();
- ItUtils.resetSettings(orchestrator, null, SETTING_ANYONE_CAN_CREATE_ORGANIZATIONS);
- }
-
- @Test
- public void create_update_delete_organizations_and_check_security() {
- verifyNoExtraOrganization();
-
- Organizations.Organization createdOrganization = adminOrganizationService.create(new CreateWsRequest.Builder()
- .setName(NAME)
- .setKey(KEY)
- .setDescription(DESCRIPTION)
- .setUrl(URL)
- .setAvatar(AVATAR_URL)
- .build())
- .getOrganization();
- assertThat(createdOrganization.getName()).isEqualTo(NAME);
- assertThat(createdOrganization.getKey()).isEqualTo(KEY);
- assertThat(createdOrganization.getDescription()).isEqualTo(DESCRIPTION);
- assertThat(createdOrganization.getUrl()).isEqualTo(URL);
- assertThat(createdOrganization.getAvatar()).isEqualTo(AVATAR_URL);
-
- verifySingleSearchResult(createdOrganization, NAME, DESCRIPTION, URL, AVATAR_URL);
-
- // update by id
- adminOrganizationService.update(new UpdateWsRequest.Builder()
- .setKey(createdOrganization.getKey())
- .setName("new name")
- .setDescription("new description")
- .setUrl("new url")
- .setAvatar("new avatar url")
- .build());
- verifySingleSearchResult(createdOrganization, "new name", "new description", "new url", "new avatar url");
-
- // update by key
- adminOrganizationService.update(new UpdateWsRequest.Builder()
- .setKey(createdOrganization.getKey())
- .setName("new name 2")
- .setDescription("new description 2")
- .setUrl("new url 2")
- .setAvatar("new avatar url 2")
- .build());
- verifySingleSearchResult(createdOrganization, "new name 2", "new description 2", "new url 2", "new avatar url 2");
-
- // remove optional fields
- adminOrganizationService.update(new UpdateWsRequest.Builder()
- .setKey(createdOrganization.getKey())
- .setName("new name 3")
- .setDescription("")
- .setUrl("")
- .setAvatar("")
- .build());
- verifySingleSearchResult(createdOrganization, "new name 3", null, null, null);
-
- // delete organization
- adminOrganizationService.delete(createdOrganization.getKey());
- verifyNoExtraOrganization();
-
- adminOrganizationService.create(new CreateWsRequest.Builder()
- .setName(NAME)
- .setKey(KEY)
- .build())
- .getOrganization();
- verifySingleSearchResult(createdOrganization, NAME, null, null, null);
-
- // verify anonymous can't create update nor delete an organization by default
- verifyAnonymousNotAuthorized(service -> service.create(new CreateWsRequest.Builder().setName("An org").build()));
- verifyUserNotAuthenticated(service -> service.update(new UpdateWsRequest.Builder().setKey(KEY).setName("new name").build()));
- verifyUserNotAuthenticated(service -> service.delete(KEY));
-
- // verify logged in user without any permission can't create update nor delete an organization by default
- userRule.createUser("john", "doh");
- verifyUserNotAuthorized("john", "doh", service -> service.create(new CreateWsRequest.Builder().setName("An org").build()));
- verifyUserNotAuthorized("john", "doh", service -> service.update(new UpdateWsRequest.Builder().setKey(KEY).setName("new name").build()));
- verifyUserNotAuthorized("john", "doh", service -> service.delete(KEY));
-
- ItUtils.setServerProperty(orchestrator, SETTING_ANYONE_CAN_CREATE_ORGANIZATIONS, "true");
- // verify anonymous still can't create update nor delete an organization if property is true
- verifyUserNotAuthenticated(service -> service.create(new CreateWsRequest.Builder().setName("An org").build()));
- verifyUserNotAuthenticated(service -> service.update(new UpdateWsRequest.Builder().setKey(KEY).setName("new name").build()));
- verifyUserNotAuthenticated(service -> service.delete(KEY));
-
- // verify logged in user without any permission can't create nor update nor delete an organization if property is true
- verifyUserNotAuthorized("john", "doh", service -> service.update(new UpdateWsRequest.Builder().setKey(KEY).setName("new name").build()));
- verifyUserNotAuthorized("john", "doh", service -> service.delete(KEY));
- // clean-up
- adminOrganizationService.delete(KEY);
- verifySingleSearchResult(
- verifyUserAuthorized("john", "doh", service -> service.create(new CreateWsRequest.Builder().setName("An org").build())).getOrganization(),
- "An org", null, null, null);
-
- // clean-up
- adminOrganizationService.delete("an-org");
- }
-
- private void verifyAnonymousNotAuthorized(Consumer<OrganizationService> consumer) {
- try {
- consumer.accept(anonymousOrganizationService);
- fail("An HttpException should have been raised");
- } catch (HttpException e) {
- assertThat(e.code()).isEqualTo(403);
- }
- }
-
- private void verifyUserNotAuthenticated(Consumer<OrganizationService> consumer) {
- try {
- consumer.accept(anonymousOrganizationService);
- fail("An HttpException should have been raised");
- } catch (HttpException e) {
- assertThat(e.code()).isEqualTo(401);
- }
- }
-
- private void verifyUserNotAuthorized(String login, String password, Consumer<OrganizationService> consumer) {
- try {
- OrganizationService organizationService = ItUtils.newUserWsClient(orchestrator, login, password).organizations();
- consumer.accept(organizationService);
- fail("An HttpException should have been raised");
- } catch (HttpException e) {
- assertThat(e.code()).isEqualTo(403);
- }
- }
-
- private <T> T verifyUserAuthorized(String login, String password, Function<OrganizationService, T> consumer) {
- OrganizationService organizationService = ItUtils.newUserWsClient(orchestrator, login, password).organizations();
- return consumer.apply(organizationService);
- }
-
- @Test
- public void create_generates_key_from_name() {
- // create organization without key
- String name = "Foo Company to keyize";
- String expectedKey = "foo-company-to-keyize";
- Organizations.Organization createdOrganization = adminOrganizationService.create(new CreateWsRequest.Builder()
- .setName(name)
- .build())
- .getOrganization();
- assertThat(createdOrganization.getKey()).isEqualTo(expectedKey);
- verifySingleSearchResult(createdOrganization, name, null, null, null);
-
- // clean-up
- adminOrganizationService.delete(expectedKey);
- }
-
- @Test
- public void default_organization_can_not_be_deleted() {
- try {
- adminOrganizationService.delete(DEFAULT_ORGANIZATION_KEY);
- fail("a HttpException should have been raised");
- } catch (HttpException e) {
- assertThat(e.code()).isEqualTo(400);
- }
- }
-
- @Test
- public void create_fails_if_user_is_not_root() {
- userRule.createUser("foo", "bar");
-
- CreateWsRequest createWsRequest = new CreateWsRequest.Builder()
- .setName("bla bla")
- .build();
- OrganizationService fooUserOrganizationService = ItUtils.newUserWsClient(orchestrator, "foo", "bar").organizations();
-
- expect403HttpError(() -> fooUserOrganizationService.create(createWsRequest));
-
- userRule.setRoot("foo");
- assertThat(fooUserOrganizationService.create(createWsRequest).getOrganization().getKey()).isEqualTo("bla-bla");
-
- // delete org, attempt recreate when no root anymore and ensure it can't anymore
- fooUserOrganizationService.delete("bla-bla");
- userRule.unsetRoot("foo");
- expect403HttpError(() -> fooUserOrganizationService.create(createWsRequest));
- }
-
- @Test
- public void an_organization_member_can_analyze_project() {
- verifyNoExtraOrganization();
-
- String orgKeyAndName = "org-key";
- Organizations.Organization createdOrganization = adminOrganizationService.create(new CreateWsRequest.Builder()
- .setName(orgKeyAndName)
- .setKey(orgKeyAndName)
- .build())
- .getOrganization();
- verifySingleSearchResult(createdOrganization, orgKeyAndName, null, null, null);
-
- userRule.createUser("bob", "bob");
- userRule.removeGroups("sonar-users");
- addPermissionsToUser(orgKeyAndName, "bob", "provisioning", "scan");
-
- ItUtils.runProjectAnalysis(orchestrator, "shared/xoo-sample",
- "sonar.organization", orgKeyAndName, "sonar.login", "bob", "sonar.password", "bob");
- ComponentsService componentsService = ItUtils.newAdminWsClient(orchestrator).components();
- assertThat(searchSampleProject(orgKeyAndName, componentsService).getComponentsList()).hasSize(1);
-
- adminOrganizationService.delete(orgKeyAndName);
- }
-
- @Test
- public void by_default_anonymous_cannot_analyse_project_on_organization() {
- verifyNoExtraOrganization();
-
- String orgKeyAndName = "org-key";
- Organizations.Organization createdOrganization = adminOrganizationService.create(new CreateWsRequest.Builder()
- .setName(orgKeyAndName)
- .setKey(orgKeyAndName)
- .build())
- .getOrganization();
- verifySingleSearchResult(createdOrganization, orgKeyAndName, null, null, null);
-
- try {
- ItUtils.runProjectAnalysis(orchestrator, "shared/xoo-sample",
- "sonar.organization", orgKeyAndName);
- fail();
- } catch (BuildFailureException e) {
- assertThat(e.getResult().getLogs()).contains("Insufficient privileges");
- }
-
- ComponentsService componentsService = ItUtils.newAdminWsClient(orchestrator).components();
- assertThat(searchSampleProject(orgKeyAndName, componentsService).getComponentsCount()).isEqualTo(0);
- adminOrganizationService.delete(orgKeyAndName);
- }
-
- private void addPermissionsToUser(String orgKeyAndName, String login, String permission, String... otherPermissions) {
- PermissionsService permissionsService = ItUtils.newAdminWsClient(orchestrator).permissions();
- permissionsService.addUser(new AddUserWsRequest().setLogin(login).setOrganization(orgKeyAndName).setPermission(permission));
- for (String otherPermission : otherPermissions) {
- permissionsService.addUser(new AddUserWsRequest().setLogin(login).setOrganization(orgKeyAndName).setPermission(otherPermission));
- }
- }
-
- @Test
- public void deleting_an_organization_also_deletes_group_permissions_and_projects_and_check_security() {
- verifyNoExtraOrganization();
-
- String orgKeyAndName = "org-key";
- Organizations.Organization createdOrganization = adminOrganizationService.create(new CreateWsRequest.Builder()
- .setName(orgKeyAndName)
- .setKey(orgKeyAndName)
- .build())
- .getOrganization();
- verifySingleSearchResult(createdOrganization, orgKeyAndName, null, null, null);
-
- GroupManagement groupManagement = userRule.forOrganization(orgKeyAndName);
-
- userRule.createUser("bob", "bob");
- groupManagement.createGroup("grp1");
- groupManagement.createGroup("grp2");
- groupManagement.associateGroupsToUser("bob", "grp1", "grp2");
- assertThat(groupManagement.getUserGroups("bob").getGroups())
- .extracting(Groups.Group::getName)
- .contains("grp1", "grp2");
- addPermissionsToUser(orgKeyAndName, "bob", "provisioning", "scan");
-
- ItUtils.runProjectAnalysis(orchestrator, "shared/xoo-sample",
- "sonar.organization", orgKeyAndName, "sonar.login", "bob", "sonar.password", "bob");
- ComponentsService componentsService = ItUtils.newAdminWsClient(orchestrator).components();
- assertThat(searchSampleProject(orgKeyAndName, componentsService).getComponentsList()).hasSize(1);
-
- adminOrganizationService.delete(orgKeyAndName);
-
- expect404HttpError(() -> searchSampleProject(orgKeyAndName, componentsService));
- assertThat(groupManagement.getUserGroups("bob").getGroups())
- .extracting(Groups.Group::getName)
- .doesNotContain("grp1", "grp2");
-
- verifyNoExtraOrganization();
- }
-
- private WsComponents.SearchWsResponse searchSampleProject(String organizationKey, ComponentsService componentsService) {
- return componentsService
- .search(new org.sonarqube.ws.client.component.SearchWsRequest()
- .setOrganization(organizationKey)
- .setQualifiers(singletonList("TRK"))
- .setQuery("sample"));
- }
-
- private void expect403HttpError(Runnable runnable) {
- try {
- runnable.run();
- fail("Ws call should have failed");
- } catch (HttpException e) {
- assertThat(e.code()).isEqualTo(403);
- }
- }
-
- private void expect404HttpError(Runnable runnable) {
- try {
- runnable.run();
- fail("Ws call should have failed");
- } catch (HttpException e) {
- assertThat(e.code()).isEqualTo(404);
- }
- }
-
- private void verifyNoExtraOrganization() {
- Organizations.SearchWsResponse searchWsResponse = anonymousOrganizationService.search(new SearchWsRequest.Builder().build());
- List<Organizations.Organization> organizationsList = searchWsResponse.getOrganizationsList();
- assertThat(organizationsList).hasSize(1);
- assertThat(organizationsList.iterator().next().getKey()).isEqualTo(DEFAULT_ORGANIZATION_KEY);
- }
-
- private void verifySingleSearchResult(Organizations.Organization createdOrganization, String name, String description, String url,
- String avatarUrl) {
- List<Organizations.Organization> organizations = anonymousOrganizationService.search(new SearchWsRequest.Builder()
- .build()).getOrganizationsList();
- assertThat(organizations).hasSize(2);
- Organizations.Organization searchedOrganization = organizations.stream()
- .filter(organization -> !DEFAULT_ORGANIZATION_KEY.equals(organization.getKey()))
- .findFirst()
- .get();
- assertThat(searchedOrganization.getKey()).isEqualTo(createdOrganization.getKey());
- assertThat(searchedOrganization.getName()).isEqualTo(name);
- if (description == null) {
- assertThat(searchedOrganization.hasDescription()).isFalse();
- } else {
- assertThat(searchedOrganization.getDescription()).isEqualTo(description);
- }
- if (url == null) {
- assertThat(searchedOrganization.hasUrl()).isFalse();
- } else {
- assertThat(searchedOrganization.getUrl()).isEqualTo(url);
- }
- if (avatarUrl == null) {
- assertThat(searchedOrganization.hasAvatar()).isFalse();
- } else {
- assertThat(searchedOrganization.getAvatar()).isEqualTo(avatarUrl);
- }
- }
-}
--- /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 it.organization;
+
+import com.sonar.orchestrator.Orchestrator;
+import com.sonar.orchestrator.build.BuildFailureException;
+import it.Category3Suite;
+import java.util.Collections;
+import java.util.List;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonarqube.ws.Organizations;
+import org.sonarqube.ws.WsComponents;
+import org.sonarqube.ws.client.HttpException;
+import org.sonarqube.ws.client.component.ComponentsService;
+import org.sonarqube.ws.client.organization.CreateWsRequest;
+import org.sonarqube.ws.client.organization.OrganizationService;
+import org.sonarqube.ws.client.organization.SearchWsRequest;
+import org.sonarqube.ws.client.organization.UpdateWsRequest;
+import org.sonarqube.ws.client.permission.AddUserWsRequest;
+import org.sonarqube.ws.client.permission.PermissionsService;
+import util.ItUtils;
+import util.user.GroupManagement;
+import util.user.Groups;
+import util.user.UserRule;
+
+import static java.util.Collections.singletonList;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.fail;
+
+public class OrganizationTest {
+ private static final String DEFAULT_ORGANIZATION_KEY = "default-organization";
+ private static final String NAME = "Foo Company";
+ private static final String KEY = "foo-company";
+ private static final String DESCRIPTION = "the description of Foo company";
+ private static final String URL = "https://www.foo.fr";
+ private static final String AVATAR_URL = "https://www.foo.fr/corporate_logo.png";
+ private static final String SETTING_ANYONE_CAN_CREATE_ORGANIZATIONS = "sonar.organizations.anyoneCanCreate";
+
+ @ClassRule
+ public static Orchestrator orchestrator = Category3Suite.ORCHESTRATOR;
+ @ClassRule
+ public static UserRule userRule = UserRule.from(orchestrator);
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ private OrganizationService anonymousOrganizationService = ItUtils.newWsClient(orchestrator).organizations();
+ private OrganizationService adminOrganizationService = ItUtils.newAdminWsClient(orchestrator).organizations();
+
+ @Before
+ public void setUp() throws Exception {
+ orchestrator.resetData();
+ userRule.resetUsers();
+ ItUtils.resetSettings(orchestrator, null, SETTING_ANYONE_CAN_CREATE_ORGANIZATIONS);
+ orchestrator.getServer().post("api/organizations/enable_support", Collections.emptyMap());
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ orchestrator.resetData();
+ }
+
+ @Test
+ public void create_update_delete_organizations_and_check_security() {
+ verifyNoExtraOrganization();
+
+ Organizations.Organization createdOrganization = adminOrganizationService.create(new CreateWsRequest.Builder()
+ .setName(NAME)
+ .setKey(KEY)
+ .setDescription(DESCRIPTION)
+ .setUrl(URL)
+ .setAvatar(AVATAR_URL)
+ .build())
+ .getOrganization();
+ assertThat(createdOrganization.getName()).isEqualTo(NAME);
+ assertThat(createdOrganization.getKey()).isEqualTo(KEY);
+ assertThat(createdOrganization.getDescription()).isEqualTo(DESCRIPTION);
+ assertThat(createdOrganization.getUrl()).isEqualTo(URL);
+ assertThat(createdOrganization.getAvatar()).isEqualTo(AVATAR_URL);
+
+ verifySingleSearchResult(createdOrganization, NAME, DESCRIPTION, URL, AVATAR_URL);
+
+ // update by id
+ adminOrganizationService.update(new UpdateWsRequest.Builder()
+ .setKey(createdOrganization.getKey())
+ .setName("new name")
+ .setDescription("new description")
+ .setUrl("new url")
+ .setAvatar("new avatar url")
+ .build());
+ verifySingleSearchResult(createdOrganization, "new name", "new description", "new url", "new avatar url");
+
+ // update by key
+ adminOrganizationService.update(new UpdateWsRequest.Builder()
+ .setKey(createdOrganization.getKey())
+ .setName("new name 2")
+ .setDescription("new description 2")
+ .setUrl("new url 2")
+ .setAvatar("new avatar url 2")
+ .build());
+ verifySingleSearchResult(createdOrganization, "new name 2", "new description 2", "new url 2", "new avatar url 2");
+
+ // remove optional fields
+ adminOrganizationService.update(new UpdateWsRequest.Builder()
+ .setKey(createdOrganization.getKey())
+ .setName("new name 3")
+ .setDescription("")
+ .setUrl("")
+ .setAvatar("")
+ .build());
+ verifySingleSearchResult(createdOrganization, "new name 3", null, null, null);
+
+ // delete organization
+ adminOrganizationService.delete(createdOrganization.getKey());
+ verifyNoExtraOrganization();
+
+ adminOrganizationService.create(new CreateWsRequest.Builder()
+ .setName(NAME)
+ .setKey(KEY)
+ .build())
+ .getOrganization();
+ verifySingleSearchResult(createdOrganization, NAME, null, null, null);
+
+ // verify anonymous can't create update nor delete an organization by default
+ verifyAnonymousNotAuthorized(service -> service.create(new CreateWsRequest.Builder().setName("An org").build()));
+ verifyUserNotAuthenticated(service -> service.update(new UpdateWsRequest.Builder().setKey(KEY).setName("new name").build()));
+ verifyUserNotAuthenticated(service -> service.delete(KEY));
+
+ // verify logged in user without any permission can't create update nor delete an organization by default
+ userRule.createUser("john", "doh");
+ verifyUserNotAuthorized("john", "doh", service -> service.create(new CreateWsRequest.Builder().setName("An org").build()));
+ verifyUserNotAuthorized("john", "doh", service -> service.update(new UpdateWsRequest.Builder().setKey(KEY).setName("new name").build()));
+ verifyUserNotAuthorized("john", "doh", service -> service.delete(KEY));
+
+ ItUtils.setServerProperty(orchestrator, SETTING_ANYONE_CAN_CREATE_ORGANIZATIONS, "true");
+ // verify anonymous still can't create update nor delete an organization if property is true
+ verifyUserNotAuthenticated(service -> service.create(new CreateWsRequest.Builder().setName("An org").build()));
+ verifyUserNotAuthenticated(service -> service.update(new UpdateWsRequest.Builder().setKey(KEY).setName("new name").build()));
+ verifyUserNotAuthenticated(service -> service.delete(KEY));
+
+ // verify logged in user without any permission can't create nor update nor delete an organization if property is true
+ verifyUserNotAuthorized("john", "doh", service -> service.update(new UpdateWsRequest.Builder().setKey(KEY).setName("new name").build()));
+ verifyUserNotAuthorized("john", "doh", service -> service.delete(KEY));
+ // clean-up
+ adminOrganizationService.delete(KEY);
+ verifySingleSearchResult(
+ verifyUserAuthorized("john", "doh", service -> service.create(new CreateWsRequest.Builder().setName("An org").build())).getOrganization(),
+ "An org", null, null, null);
+
+ // clean-up
+ adminOrganizationService.delete("an-org");
+ }
+
+ private void verifyAnonymousNotAuthorized(Consumer<OrganizationService> consumer) {
+ try {
+ consumer.accept(anonymousOrganizationService);
+ fail("An HttpException should have been raised");
+ } catch (HttpException e) {
+ assertThat(e.code()).isEqualTo(403);
+ }
+ }
+
+ private void verifyUserNotAuthenticated(Consumer<OrganizationService> consumer) {
+ try {
+ consumer.accept(anonymousOrganizationService);
+ fail("An HttpException should have been raised");
+ } catch (HttpException e) {
+ assertThat(e.code()).isEqualTo(401);
+ }
+ }
+
+ private void verifyUserNotAuthorized(String login, String password, Consumer<OrganizationService> consumer) {
+ try {
+ OrganizationService organizationService = ItUtils.newUserWsClient(orchestrator, login, password).organizations();
+ consumer.accept(organizationService);
+ fail("An HttpException should have been raised");
+ } catch (HttpException e) {
+ assertThat(e.code()).isEqualTo(403);
+ }
+ }
+
+ private <T> T verifyUserAuthorized(String login, String password, Function<OrganizationService, T> consumer) {
+ OrganizationService organizationService = ItUtils.newUserWsClient(orchestrator, login, password).organizations();
+ return consumer.apply(organizationService);
+ }
+
+ @Test
+ public void create_generates_key_from_name() {
+ // create organization without key
+ String name = "Foo Company to keyize";
+ String expectedKey = "foo-company-to-keyize";
+ Organizations.Organization createdOrganization = adminOrganizationService.create(new CreateWsRequest.Builder()
+ .setName(name)
+ .build())
+ .getOrganization();
+ assertThat(createdOrganization.getKey()).isEqualTo(expectedKey);
+ verifySingleSearchResult(createdOrganization, name, null, null, null);
+
+ // clean-up
+ adminOrganizationService.delete(expectedKey);
+ }
+
+ @Test
+ public void default_organization_can_not_be_deleted() {
+ try {
+ adminOrganizationService.delete(DEFAULT_ORGANIZATION_KEY);
+ fail("a HttpException should have been raised");
+ } catch (HttpException e) {
+ assertThat(e.code()).isEqualTo(400);
+ }
+ }
+
+ @Test
+ public void create_fails_if_user_is_not_root() {
+ userRule.createUser("foo", "bar");
+
+ CreateWsRequest createWsRequest = new CreateWsRequest.Builder()
+ .setName("bla bla")
+ .build();
+ OrganizationService fooUserOrganizationService = ItUtils.newUserWsClient(orchestrator, "foo", "bar").organizations();
+
+ expect403HttpError(() -> fooUserOrganizationService.create(createWsRequest));
+
+ userRule.setRoot("foo");
+ assertThat(fooUserOrganizationService.create(createWsRequest).getOrganization().getKey()).isEqualTo("bla-bla");
+
+ // delete org, attempt recreate when no root anymore and ensure it can't anymore
+ fooUserOrganizationService.delete("bla-bla");
+ userRule.unsetRoot("foo");
+ expect403HttpError(() -> fooUserOrganizationService.create(createWsRequest));
+ }
+
+ @Test
+ public void an_organization_member_can_analyze_project() {
+ verifyNoExtraOrganization();
+
+ String orgKeyAndName = "org-key";
+ Organizations.Organization createdOrganization = adminOrganizationService.create(new CreateWsRequest.Builder()
+ .setName(orgKeyAndName)
+ .setKey(orgKeyAndName)
+ .build())
+ .getOrganization();
+ verifySingleSearchResult(createdOrganization, orgKeyAndName, null, null, null);
+
+ userRule.createUser("bob", "bob");
+ userRule.removeGroups("sonar-users");
+ addPermissionsToUser(orgKeyAndName, "bob", "provisioning", "scan");
+
+ ItUtils.runProjectAnalysis(orchestrator, "shared/xoo-sample",
+ "sonar.organization", orgKeyAndName, "sonar.login", "bob", "sonar.password", "bob");
+ ComponentsService componentsService = ItUtils.newAdminWsClient(orchestrator).components();
+ assertThat(searchSampleProject(orgKeyAndName, componentsService).getComponentsList()).hasSize(1);
+
+ adminOrganizationService.delete(orgKeyAndName);
+ }
+
+ @Test
+ public void by_default_anonymous_cannot_analyse_project_on_organization() {
+ verifyNoExtraOrganization();
+
+ String orgKeyAndName = "org-key";
+ Organizations.Organization createdOrganization = adminOrganizationService.create(new CreateWsRequest.Builder()
+ .setName(orgKeyAndName)
+ .setKey(orgKeyAndName)
+ .build())
+ .getOrganization();
+ verifySingleSearchResult(createdOrganization, orgKeyAndName, null, null, null);
+
+ try {
+ ItUtils.runProjectAnalysis(orchestrator, "shared/xoo-sample",
+ "sonar.organization", orgKeyAndName);
+ fail();
+ } catch (BuildFailureException e) {
+ assertThat(e.getResult().getLogs()).contains("Insufficient privileges");
+ }
+
+ ComponentsService componentsService = ItUtils.newAdminWsClient(orchestrator).components();
+ assertThat(searchSampleProject(orgKeyAndName, componentsService).getComponentsCount()).isEqualTo(0);
+ adminOrganizationService.delete(orgKeyAndName);
+ }
+
+ private void addPermissionsToUser(String orgKeyAndName, String login, String permission, String... otherPermissions) {
+ PermissionsService permissionsService = ItUtils.newAdminWsClient(orchestrator).permissions();
+ permissionsService.addUser(new AddUserWsRequest().setLogin(login).setOrganization(orgKeyAndName).setPermission(permission));
+ for (String otherPermission : otherPermissions) {
+ permissionsService.addUser(new AddUserWsRequest().setLogin(login).setOrganization(orgKeyAndName).setPermission(otherPermission));
+ }
+ }
+
+ @Test
+ public void deleting_an_organization_also_deletes_group_permissions_and_projects_and_check_security() {
+ verifyNoExtraOrganization();
+
+ String orgKeyAndName = "org-key";
+ Organizations.Organization createdOrganization = adminOrganizationService.create(new CreateWsRequest.Builder()
+ .setName(orgKeyAndName)
+ .setKey(orgKeyAndName)
+ .build())
+ .getOrganization();
+ verifySingleSearchResult(createdOrganization, orgKeyAndName, null, null, null);
+
+ GroupManagement groupManagement = userRule.forOrganization(orgKeyAndName);
+
+ userRule.createUser("bob", "bob");
+ groupManagement.createGroup("grp1");
+ groupManagement.createGroup("grp2");
+ groupManagement.associateGroupsToUser("bob", "grp1", "grp2");
+ assertThat(groupManagement.getUserGroups("bob").getGroups())
+ .extracting(Groups.Group::getName)
+ .contains("grp1", "grp2");
+ addPermissionsToUser(orgKeyAndName, "bob", "provisioning", "scan");
+
+ ItUtils.runProjectAnalysis(orchestrator, "shared/xoo-sample",
+ "sonar.organization", orgKeyAndName, "sonar.login", "bob", "sonar.password", "bob");
+ ComponentsService componentsService = ItUtils.newAdminWsClient(orchestrator).components();
+ assertThat(searchSampleProject(orgKeyAndName, componentsService).getComponentsList()).hasSize(1);
+
+ adminOrganizationService.delete(orgKeyAndName);
+
+ expect404HttpError(() -> searchSampleProject(orgKeyAndName, componentsService));
+ assertThat(groupManagement.getUserGroups("bob").getGroups())
+ .extracting(Groups.Group::getName)
+ .doesNotContain("grp1", "grp2");
+
+ verifyNoExtraOrganization();
+ }
+
+ private WsComponents.SearchWsResponse searchSampleProject(String organizationKey, ComponentsService componentsService) {
+ return componentsService
+ .search(new org.sonarqube.ws.client.component.SearchWsRequest()
+ .setOrganization(organizationKey)
+ .setQualifiers(singletonList("TRK"))
+ .setQuery("sample"));
+ }
+
+ private void expect403HttpError(Runnable runnable) {
+ try {
+ runnable.run();
+ fail("Ws call should have failed");
+ } catch (HttpException e) {
+ assertThat(e.code()).isEqualTo(403);
+ }
+ }
+
+ private void expect404HttpError(Runnable runnable) {
+ try {
+ runnable.run();
+ fail("Ws call should have failed");
+ } catch (HttpException e) {
+ assertThat(e.code()).isEqualTo(404);
+ }
+ }
+
+ private void verifyNoExtraOrganization() {
+ Organizations.SearchWsResponse searchWsResponse = anonymousOrganizationService.search(new SearchWsRequest.Builder().build());
+ List<Organizations.Organization> organizationsList = searchWsResponse.getOrganizationsList();
+ assertThat(organizationsList).hasSize(1);
+ assertThat(organizationsList.iterator().next().getKey()).isEqualTo(DEFAULT_ORGANIZATION_KEY);
+ }
+
+ private void verifySingleSearchResult(Organizations.Organization createdOrganization, String name, String description, String url,
+ String avatarUrl) {
+ List<Organizations.Organization> organizations = anonymousOrganizationService.search(new SearchWsRequest.Builder()
+ .build()).getOrganizationsList();
+ assertThat(organizations).hasSize(2);
+ Organizations.Organization searchedOrganization = organizations.stream()
+ .filter(organization -> !DEFAULT_ORGANIZATION_KEY.equals(organization.getKey()))
+ .findFirst()
+ .get();
+ assertThat(searchedOrganization.getKey()).isEqualTo(createdOrganization.getKey());
+ assertThat(searchedOrganization.getName()).isEqualTo(name);
+ if (description == null) {
+ assertThat(searchedOrganization.hasDescription()).isFalse();
+ } else {
+ assertThat(searchedOrganization.getDescription()).isEqualTo(description);
+ }
+ if (url == null) {
+ assertThat(searchedOrganization.hasUrl()).isFalse();
+ } else {
+ assertThat(searchedOrganization.getUrl()).isEqualTo(url);
+ }
+ if (avatarUrl == null) {
+ assertThat(searchedOrganization.hasAvatar()).isFalse();
+ } else {
+ assertThat(searchedOrganization.getAvatar()).isEqualTo(avatarUrl);
+ }
+ }
+}
--- /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 it.organization;
+
+import com.sonar.orchestrator.Orchestrator;
+import it.Category3Suite;
+import java.sql.SQLException;
+import java.util.Collections;
+import org.junit.After;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonarqube.ws.WsRoot;
+import org.sonarqube.ws.client.HttpException;
+import org.sonarqube.ws.client.WsClient;
+import util.user.UserRule;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.fail;
+import static util.ItUtils.newAdminWsClient;
+import static util.ItUtils.newUserWsClient;
+import static util.ItUtils.newWsClient;
+
+public class RootTest {
+ @ClassRule
+ public static Orchestrator orchestrator = Category3Suite.ORCHESTRATOR;
+ @Rule
+ public UserRule userRule = UserRule.from(orchestrator);
+
+ @After
+ public void tearDown() {
+ orchestrator.resetData();
+ }
+
+ @Test
+ public void nobody_is_root_by_default() {
+ // anonymous
+ verifyHttpError(() -> newWsClient(orchestrator).rootService().search(), 403);
+
+ // admin
+ verifyHttpError(() -> newAdminWsClient(orchestrator).rootService().search(), 403);
+ }
+
+ @Test
+ public void system_administrator_is_flagged_as_root_when_he_enables_organization_support() {
+ enableOrganizationSupport();
+
+ assertThat(newAdminWsClient(orchestrator).rootService().search().getRootsList())
+ .extracting(WsRoot.Root::getLogin)
+ .containsOnly(UserRule.ADMIN_LOGIN);
+ }
+
+ @Test
+ public void a_root_can_flag_other_user_as_root() {
+ enableOrganizationSupport();
+
+ userRule.createUser("bar", "foo");
+ userRule.setRoot("bar");
+
+ assertThat(newAdminWsClient(orchestrator).rootService().search().getRootsList())
+ .extracting(WsRoot.Root::getLogin)
+ .containsOnly(UserRule.ADMIN_LOGIN, "bar");
+ }
+
+ @Test
+ public void last_root_can_not_be_unset_root() throws SQLException {
+ enableOrganizationSupport();
+
+ verifyHttpError(() -> newAdminWsClient(orchestrator).rootService().unsetRoot(UserRule.ADMIN_LOGIN), 400);
+ }
+
+ @Test
+ public void root_can_be_set_and_unset_via_web_services() {
+ enableOrganizationSupport();
+
+ userRule.createUser("root1", "bar");
+ userRule.createUser("root2", "bar");
+ WsClient root1WsClient = newUserWsClient(orchestrator, "root1", "bar");
+ WsClient root2WsClient = newUserWsClient(orchestrator, "root2", "bar");
+
+ // non root can not set or unset root another user not itself
+ verifyHttpError(() -> root1WsClient.rootService().setRoot("root2"), 403);
+ verifyHttpError(() -> root1WsClient.rootService().setRoot("root1"), 403);
+ verifyHttpError(() -> root1WsClient.rootService().unsetRoot("root1"), 403);
+ verifyHttpError(() -> root2WsClient.rootService().unsetRoot("root1"), 403);
+ verifyHttpError(() -> root2WsClient.rootService().unsetRoot("root2"), 403);
+ // admin (the first root) sets root1 as root
+ newAdminWsClient(orchestrator).rootService().setRoot("root1");
+ // root1 can set root root2
+ root1WsClient.rootService().setRoot("root2");
+ // root2 can unset root root1
+ root2WsClient.rootService().unsetRoot("root1");
+ // root2 can unset root itself as it's not the last root
+ root2WsClient.rootService().unsetRoot("root2");
+ }
+
+ private void enableOrganizationSupport() {
+ orchestrator.getServer().post("api/organizations/enable_support", Collections.emptyMap());
+ }
+
+ private static void verifyHttpError(Runnable runnable, int expectedErrorCode) {
+ try {
+ runnable.run();
+ fail("Ws Call should have failed with http code " + expectedErrorCode);
+ } catch (HttpException e) {
+ assertThat(e.code()).isEqualTo(expectedErrorCode);
+ }
+ }
+}
+++ /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 it.root;
-
-import com.sonar.orchestrator.Orchestrator;
-import it.Category3Suite;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import org.junit.After;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.sonarqube.ws.WsRoot;
-import org.sonarqube.ws.client.HttpException;
-import org.sonarqube.ws.client.WsClient;
-import util.user.UserRule;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.fail;
-import static util.ItUtils.newAdminWsClient;
-import static util.ItUtils.newUserWsClient;
-import static util.ItUtils.newWsClient;
-
-public class RootIt {
- @ClassRule
- public static Orchestrator orchestrator = Category3Suite.ORCHESTRATOR;
- @Rule
- public UserRule userRule = UserRule.from(orchestrator);
-
- @After
- public void tearDown() throws Exception {
- userRule.resetUsers();
- }
-
- @Test
- public void by_default_admin_is_the_only_root() {
- // must be root to call search WS
- verifyHttpError(() -> newWsClient(orchestrator).rootService().search(), 403);
-
- assertThat(newAdminWsClient(orchestrator).rootService().search().getRootsList())
- .extracting(WsRoot.Root::getLogin)
- .containsOnly(UserRule.ADMIN_LOGIN);
-
- userRule.createUser("bar", "foo");
- userRule.setRoot("bar");
-
- assertThat(newAdminWsClient(orchestrator).rootService().search().getRootsList())
- .extracting(WsRoot.Root::getLogin)
- .containsOnly(UserRule.ADMIN_LOGIN, "bar");
- }
-
- @Test
- public void last_root_can_not_be_unset_root() throws SQLException {
- try (Connection connection = orchestrator.getDatabase().openConnection();
- PreparedStatement preparedStatement = createSelectActiveRootUsers(connection);
- ResultSet resultSet = preparedStatement.executeQuery()) {
- assertThat(resultSet.next()).as("There should be active root user").isTrue();
- assertThat(resultSet.getString(1)).isEqualTo(UserRule.ADMIN_LOGIN);
- assertThat(resultSet.next()).as("There shouldn't be more than one active root user").isFalse();
- }
-
- verifyHttpError(() -> newAdminWsClient(orchestrator).rootService().unsetRoot(UserRule.ADMIN_LOGIN), 400);
- }
-
- private static void verifyHttpError(Runnable runnable, int expectedErrorCode) {
- try {
- runnable.run();
- fail("Ws Call should have failed with http code " + expectedErrorCode);
- } catch (HttpException e) {
- assertThat(e.code()).isEqualTo(expectedErrorCode);
- }
- }
-
- @Test
- public void root_can_be_set_and_unset_via_web_services() {
- userRule.createUser("root1", "bar");
- userRule.createUser("root2", "bar");
- WsClient root1WsClient = newUserWsClient(orchestrator, "root1", "bar");
- WsClient root2WsClient = newUserWsClient(orchestrator, "root2", "bar");
-
- // non root can not set or unset root another user not itself
- verifyHttpError(() -> root1WsClient.rootService().setRoot("root2"), 403);
- verifyHttpError(() -> root1WsClient.rootService().setRoot("root1"), 403);
- verifyHttpError(() -> root1WsClient.rootService().unsetRoot("root1"), 403);
- verifyHttpError(() -> root2WsClient.rootService().unsetRoot("root1"), 403);
- verifyHttpError(() -> root2WsClient.rootService().unsetRoot("root2"), 403);
- // admin (the first root) sets root1 as root
- newAdminWsClient(orchestrator).rootService().setRoot("root1");
- // root1 can set root root2
- root1WsClient.rootService().setRoot("root2");
- // root2 can unset root root1
- root2WsClient.rootService().unsetRoot("root1");
- // root2 can unset root itself as it's not the last root
- root2WsClient.rootService().unsetRoot("root2");
- }
-
- private static PreparedStatement createSelectActiveRootUsers(Connection connection) throws SQLException {
- PreparedStatement preparedStatement = connection.prepareStatement("select login from users where is_root = ? and active = ?");
- preparedStatement.setBoolean(1, true);
- preparedStatement.setBoolean(2, true);
- return preparedStatement;
- }
-}
truncateAnalysisTables(connection);
deleteManualRules(connection);
+ truncateInternalProperties(null, null, connection);
+ truncateUsers(null, null, connection);
+ truncateOrganizations(null, null, connection);
} catch (SQLException e) {
throw new IllegalStateException("Fail to reset data", e);
}
// commit is useless on some databases
connection.commit();
}
+ // "admin" is not flagged as root by default
+ try (PreparedStatement preparedStatement = connection.prepareStatement("update users set is_root=?")) {
+ preparedStatement.setBoolean(1, false);
+ preparedStatement.execute();
+ // commit is useless on some databases
+ connection.commit();
+ }
}
/**
}
@Test
- public void enable_does_enable_feature_by_inserting_internal_property() {
+ public void enable_does_enable_support_by_inserting_internal_property() {
underTest.enable(db.getSession());
assertThat(underTest.isEnabled(db.getSession())).isTrue();