it.organization.OrganizationTest.java Source code

Java tutorial

Introduction

Here is the source code for it.organization.OrganizationTest.java

Source

/*
 * 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.Category6Suite;
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.BeforeClass;
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.WsUsers;
import org.sonarqube.ws.client.HttpException;
import org.sonarqube.ws.client.PostRequest;
import org.sonarqube.ws.client.WsClient;
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 org.sonarqube.ws.client.user.GroupsRequest;
import util.user.GroupManagement;
import util.user.Groups;
import util.user.UserRule;

import static it.Category6Suite.enableOrganizationsSupport;
import static java.util.Collections.singletonList;
import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;
import static util.ItUtils.deleteOrganizationsIfExists;
import static util.ItUtils.newAdminWsClient;
import static util.ItUtils.newUserWsClient;
import static util.ItUtils.newWsClient;
import static util.ItUtils.resetSettings;
import static util.ItUtils.runProjectAnalysis;
import static util.ItUtils.setServerProperty;

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";
    private static final String USER_LOGIN = "foo";

    @ClassRule
    public static Orchestrator orchestrator = Category6Suite.ORCHESTRATOR;
    @ClassRule
    public static UserRule userRule = UserRule.from(orchestrator);
    @Rule
    public ExpectedException expectedException = ExpectedException.none();

    private WsClient adminClient = newAdminWsClient(orchestrator);
    private OrganizationService anonymousOrganizationService = newWsClient(orchestrator).organizations();
    private OrganizationService adminOrganizationService = adminClient.organizations();

    @BeforeClass
    public static void enableOrganizations() throws Exception {
        enableOrganizationsSupport();
    }

    @Before
    public void setUp() throws Exception {
        resetSettings(orchestrator, null, SETTING_ANYONE_CAN_CREATE_ORGANIZATIONS);
        deleteOrganizationsIfExists(orchestrator, KEY, "an-org");
        userRule.deactivateUsers(USER_LOGIN);
    }

    @After
    public void tearDown() throws Exception {
        deleteOrganizationsIfExists(orchestrator, KEY, "an-org");
    }

    @Test
    public void create_update_delete_organizations_and_check_security() {
        verifyOrganizationDoesNotExit(KEY);

        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());
        verifyOrganizationDoesNotExit(KEY);

        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(USER_LOGIN, USER_LOGIN);
        verifyUserNotAuthorized(USER_LOGIN, USER_LOGIN,
                service -> service.create(new CreateWsRequest.Builder().setName("An org").build()));
        verifyUserNotAuthorized(USER_LOGIN, USER_LOGIN,
                service -> service.update(new UpdateWsRequest.Builder().setKey(KEY).setName("new name").build()));
        verifyUserNotAuthorized(USER_LOGIN, USER_LOGIN, service -> service.delete(KEY));

        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(USER_LOGIN, USER_LOGIN,
                service -> service.update(new UpdateWsRequest.Builder().setKey(KEY).setName("new name").build()));
        verifyUserNotAuthorized(USER_LOGIN, USER_LOGIN, service -> service.delete(KEY));
        // clean-up
        adminOrganizationService.delete(KEY);
        verifySingleSearchResult(verifyUserAuthorized(USER_LOGIN, USER_LOGIN,
                service -> service.create(new CreateWsRequest.Builder().setName("An org").build()))
                        .getOrganization(),
                "An org", null, null, null);
    }

    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 = 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 = 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(USER_LOGIN, USER_LOGIN);

        CreateWsRequest createWsRequest = new CreateWsRequest.Builder().setName("bla bla").build();
        OrganizationService fooUserOrganizationService = newUserWsClient(orchestrator, USER_LOGIN, USER_LOGIN)
                .organizations();

        expect403HttpError(() -> fooUserOrganizationService.create(createWsRequest));

        userRule.setRoot(USER_LOGIN);
        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(USER_LOGIN);
        expect403HttpError(() -> fooUserOrganizationService.create(createWsRequest));
    }

    @Test
    public void an_organization_member_can_analyze_project() {
        verifyOrganizationDoesNotExit(KEY);

        Organizations.Organization createdOrganization = adminOrganizationService
                .create(new CreateWsRequest.Builder().setName(KEY).setKey(KEY).build()).getOrganization();
        verifySingleSearchResult(createdOrganization, KEY, null, null, null);

        userRule.createUser(USER_LOGIN, USER_LOGIN);
        userRule.removeGroups("sonar-users");
        adminOrganizationService.addMember(KEY, USER_LOGIN);
        addPermissionsToUser(KEY, USER_LOGIN, "provisioning", "scan");

        runProjectAnalysis(orchestrator, "shared/xoo-sample", "sonar.organization", KEY, "sonar.login", USER_LOGIN,
                "sonar.password", USER_LOGIN);
        ComponentsService componentsService = newUserWsClient(orchestrator, USER_LOGIN, USER_LOGIN).components();
        assertThat(searchSampleProject(KEY, componentsService).getComponentsList()).hasSize(1);
    }

    @Test
    public void by_default_anonymous_cannot_analyse_project_on_organization() {
        verifyOrganizationDoesNotExit(KEY);

        Organizations.Organization createdOrganization = adminOrganizationService
                .create(new CreateWsRequest.Builder().setName(KEY).setKey(KEY).build()).getOrganization();
        verifySingleSearchResult(createdOrganization, KEY, null, null, null);

        try {
            runProjectAnalysis(orchestrator, "shared/xoo-sample", "sonar.organization", KEY);
            fail();
        } catch (BuildFailureException e) {
            assertThat(e.getResult().getLogs()).contains("Insufficient privileges");
        }

        ComponentsService componentsService = newAdminWsClient(orchestrator).components();
        assertThat(searchSampleProject(KEY, componentsService).getComponentsCount()).isEqualTo(0);
    }

    @Test
    public void by_default_anonymous_can_browse_project_on_organization() {
        adminOrganizationService.create(new CreateWsRequest.Builder().setName(KEY).setKey(KEY).build())
                .getOrganization();

        runProjectAnalysis(orchestrator, "shared/xoo-sample", "sonar.organization", KEY, "sonar.login", "admin",
                "sonar.password", "admin");

        ComponentsService componentsService = newWsClient(orchestrator).components();
        assertThat(searchSampleProject(KEY, componentsService).getComponentsList()).hasSize(1);
    }

    private void addPermissionsToUser(String orgKeyAndName, String login, String permission,
            String... otherPermissions) {
        PermissionsService permissionsService = 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_projects_and_check_security() {
        verifyOrganizationDoesNotExit(KEY);

        Organizations.Organization createdOrganization = adminOrganizationService
                .create(new CreateWsRequest.Builder().setName(KEY).setKey(KEY).build()).getOrganization();
        verifySingleSearchResult(createdOrganization, KEY, null, null, null);

        GroupManagement groupManagement = userRule.forOrganization(KEY);

        userRule.createUser(USER_LOGIN, USER_LOGIN);
        adminOrganizationService.addMember(KEY, USER_LOGIN);
        groupManagement.createGroup("grp1");
        groupManagement.createGroup("grp2");
        groupManagement.associateGroupsToUser(USER_LOGIN, "grp1", "grp2");
        assertThat(groupManagement.getUserGroups(USER_LOGIN).getGroups()).extracting(Groups.Group::getName)
                .contains("grp1", "grp2");
        addPermissionsToUser(KEY, USER_LOGIN, "provisioning", "scan");

        runProjectAnalysis(orchestrator, "shared/xoo-sample", "sonar.organization", KEY, "sonar.login", USER_LOGIN,
                "sonar.password", USER_LOGIN);
        ComponentsService componentsService = newAdminWsClient(orchestrator).components();
        assertThat(searchSampleProject(KEY, componentsService).getComponentsList()).hasSize(1);

        adminOrganizationService.delete(KEY);

        expect404HttpError(() -> searchSampleProject(KEY, componentsService));
        verifyOrganizationDoesNotExit(KEY);
    }

    @Test
    public void return_groups_belonging_to_a_user_on_an_organization() throws Exception {
        String userLogin = randomAlphabetic(10);
        String groupName = randomAlphabetic(10);
        adminClient.organizations().create(new CreateWsRequest.Builder().setKey(KEY).setName(KEY).build())
                .getOrganization();
        userRule.createUser(userLogin, userLogin);
        adminOrganizationService.addMember(KEY, userLogin);
        adminClient.wsConnector().call(new PostRequest("api/user_groups/create").setParam("name", groupName)
                .setParam("description", groupName).setParam("organization", KEY)).failIfNotSuccessful();
        adminClient.wsConnector().call(new PostRequest("api/user_groups/add_user").setParam("login", userLogin)
                .setParam("name", groupName).setParam("organization", KEY)).failIfNotSuccessful();

        List<WsUsers.GroupsWsResponse.Group> result = adminClient.users()
                .groups(GroupsRequest.builder().setLogin(userLogin).setOrganization(KEY).build()).getGroupsList();

        assertThat(result).extracting(WsUsers.GroupsWsResponse.Group::getName).containsOnly(groupName, "Members");
    }

    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 verifyOrganizationDoesNotExit(String organizationKey) {
        Organizations.SearchWsResponse searchWsResponse = anonymousOrganizationService
                .search(new SearchWsRequest.Builder().setOrganizations(organizationKey).build());
        assertThat(searchWsResponse.getOrganizationsList()).isEmpty();
    }

    private void verifySingleSearchResult(Organizations.Organization createdOrganization, String name,
            String description, String url, String avatarUrl) {
        List<Organizations.Organization> organizations = anonymousOrganizationService
                .search(new SearchWsRequest.Builder().setOrganizations(createdOrganization.getKey()).build())
                .getOrganizationsList();
        assertThat(organizations).hasSize(1);
        Organizations.Organization searchedOrganization = organizations.get(0);
        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);
        }
    }
}