case "$CATEGORY_GROUP" in
Category1)
CATEGORY=Category1 && runCategory
+ CATEGORY=authorization && runCategory
CATEGORY=measure && runCategory
CATEGORY=source && runCategory
;;
import org.junit.ClassRule;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
-import org.sonarqube.tests.authorisation.ExecuteAnalysisPermissionTest;
-import org.sonarqube.tests.authorisation.IssuePermissionTest;
-import org.sonarqube.tests.authorisation.PermissionSearchTest;
-import org.sonarqube.tests.authorisation.ProvisioningPermissionTest;
-import org.sonarqube.tests.authorisation.QualityProfileAdminPermissionTest;
import org.sonarqube.tests.projectAdministration.BackgroundTasksTest;
import org.sonarqube.tests.projectAdministration.ProjectAdministrationTest;
import org.sonarqube.tests.projectAdministration.ProjectBulkDeletionPageTest;
QualityGateUiTest.class,
QualityGateNotificationTest.class,
QualityGateOnRatingMeasuresTest.class,
- // authorisation
- ExecuteAnalysisPermissionTest.class,
- IssuePermissionTest.class,
- PermissionSearchTest.class,
- ProvisioningPermissionTest.class,
- QualityProfileAdminPermissionTest.class,
// measure
ProjectsPageTest.class
})
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.sonarqube.tests.analysis.AnalysisEsResilienceTest;
-import org.sonarqube.tests.authorisation.SystemPasscodeTest;
import org.sonarqube.tests.ce.CeShutdownTest;
import org.sonarqube.tests.ce.CeWorkersTest;
import org.sonarqube.tests.issue.IssueCreationDatePluginChangedTest;
+import org.sonarqube.tests.marketplace.UpdateCenterTest;
import org.sonarqube.tests.qualityProfile.ActiveRuleEsResilienceTest;
import org.sonarqube.tests.qualityProfile.BuiltInQualityProfilesNotificationTest;
import org.sonarqube.tests.rule.RuleEsResilienceTest;
import org.sonarqube.tests.startup.StartupIndexationTest;
import org.sonarqube.tests.telemetry.TelemetryOptOutTest;
import org.sonarqube.tests.telemetry.TelemetryUploadTest;
-import org.sonarqube.tests.marketplace.UpdateCenterTest;
import org.sonarqube.tests.user.OnboardingTest;
import org.sonarqube.tests.user.RealmAuthenticationTest;
import org.sonarqube.tests.user.SsoAuthenticationTest;
IssueCreationDatePluginChangedTest.class,
// elasticsearch
- StartupIndexationTest.class,
- SystemPasscodeTest.class
+ StartupIndexationTest.class
})
public class Category5Suite {
import org.junit.ClassRule;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
-import org.sonarqube.tests.authorisation.PermissionTemplateTest;
+import org.sonarqube.tests.authorization.PermissionTemplateTest;
import org.sonarqube.tests.ce.ReportFailureNotificationTest;
import org.sonarqube.tests.issue.IssueNotificationsTest;
import org.sonarqube.tests.issue.IssueTagsTest;
+++ /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.sonarqube.tests.authorisation;
-
-import com.sonar.orchestrator.Orchestrator;
-import com.sonar.orchestrator.build.BuildFailureException;
-import org.sonarqube.tests.Category1Suite;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.sonar.wsclient.SonarClient;
-import org.sonar.wsclient.user.UserParameters;
-import org.sonarqube.ws.client.WsClient;
-import org.sonarqube.ws.client.permission.AddGroupWsRequest;
-import org.sonarqube.ws.client.permission.AddProjectCreatorToTemplateWsRequest;
-import org.sonarqube.ws.client.permission.RemoveGroupWsRequest;
-import org.sonarqube.ws.client.project.UpdateVisibilityRequest;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.Assert.fail;
-import static util.ItUtils.newAdminWsClient;
-import static util.ItUtils.runProjectAnalysis;
-
-/**
- * SONAR-4397
- */
-public class ExecuteAnalysisPermissionTest {
-
- @ClassRule
- public static Orchestrator orchestrator = Category1Suite.ORCHESTRATOR;
-
- private final static String USER_LOGIN = "scanperm";
- private final static String USER_PASSWORD = "thewhite";
- private final static String PROJECT_KEY = "sample";
-
- private static WsClient adminWsClient;
- private static SonarClient oldAdminWsClient;
-
- @Before
- public void setUp() {
- orchestrator.resetData();
- oldAdminWsClient = orchestrator.getServer().adminWsClient();
- oldAdminWsClient.userClient().create(UserParameters.create().login(USER_LOGIN).name(USER_LOGIN).password(USER_PASSWORD).passwordConfirmation(USER_PASSWORD));
- orchestrator.getServer().provisionProject(PROJECT_KEY, "Sample");
- adminWsClient = newAdminWsClient(orchestrator);
- }
-
- @After
- public void tearDown() {
- addGlobalPermission("anyone", "scan");
- oldAdminWsClient.userClient().deactivate(USER_LOGIN);
- }
-
- @Test
- public void should_fail_if_logged_but_no_scan_permission() throws Exception {
- executeLoggedAnalysis();
-
- removeGlobalPermission("anyone", "scan");
- try {
- // Execute logged analysis, but without the "Execute Analysis" permission
- executeLoggedAnalysis();
- fail();
- } catch (BuildFailureException e) {
- assertThat(e.getResult().getLogs()).contains(
- "You're only authorized to execute a local (preview) SonarQube analysis without pushing the results to the SonarQube server. Please contact your SonarQube administrator.");
- }
-
- newAdminWsClient(orchestrator).projects().updateVisibility(UpdateVisibilityRequest.builder().setProject(PROJECT_KEY).setVisibility("private").build());
- try {
- // Execute anonymous analysis
- executeAnonymousAnalysis();
- fail();
- } catch (BuildFailureException e) {
- assertThat(e.getResult().getLogs()).contains(
- "You're not authorized to execute any SonarQube analysis. Please contact your SonarQube administrator.");
- }
- }
-
- @Test
- public void no_need_for_browse_permission_to_scan() throws Exception {
- // Do a first analysis, no error
- executeAnonymousAnalysis();
-
- // make project private
- newAdminWsClient(orchestrator).projects().updateVisibility(UpdateVisibilityRequest.builder().setProject("sample").setVisibility("private").build());
-
- // still no error
- executeAnonymousAnalysis();
- }
-
- @Test
- public void execute_analysis_with_scan_permission_only_on_project() throws Exception {
- removeGlobalPermission("anyone", "scan");
- addProjectPermission("anyone", PROJECT_KEY, "scan");
-
- executeLoggedAnalysis();
- }
-
- @Test
- public void execute_analysis_with_scan_on_default_template() {
- removeGlobalPermission("anyone", "scan");
- adminWsClient.permissions().addProjectCreatorToTemplate(AddProjectCreatorToTemplateWsRequest.builder()
- .setPermission("scan")
- .setTemplateId("default_template")
- .build());
-
- runProjectAnalysis(orchestrator, "shared/xoo-sample", "sonar.login", USER_LOGIN, "sonar.password", USER_PASSWORD, "sonar.projectKey", "ANOTHER_PROJECT_KEY");
- }
-
- private static void addProjectPermission(String groupName, String projectKey, String permission) {
- adminWsClient.permissions().addGroup(new AddGroupWsRequest().setGroupName(groupName).setProjectKey(projectKey).setPermission(permission));
- }
-
- private static void addGlobalPermission(String groupName, String permission) {
- adminWsClient.permissions().addGroup(new AddGroupWsRequest().setGroupName(groupName).setPermission(permission));
- }
-
- private static void removeProjectPermission(String groupName, String projectKey, String permission) {
- adminWsClient.permissions().removeGroup(new RemoveGroupWsRequest().setGroupName(groupName).setProjectKey(projectKey).setPermission(permission));
- }
-
- private static void removeGlobalPermission(String groupName, String permission) {
- adminWsClient.permissions().removeGroup(new RemoveGroupWsRequest().setGroupName(groupName).setPermission(permission));
- }
-
- private static void executeLoggedAnalysis() {
- runProjectAnalysis(orchestrator, "shared/xoo-sample", "sonar.login", USER_LOGIN, "sonar.password", USER_PASSWORD);
- }
-
- private static void executeAnonymousAnalysis() {
- runProjectAnalysis(orchestrator, "shared/xoo-sample");
- }
-}
+++ /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.sonarqube.tests.authorisation;
-
-import com.sonar.orchestrator.Orchestrator;
-import com.sonar.orchestrator.build.SonarScanner;
-import org.sonarqube.tests.Category1Suite;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.sonar.wsclient.SonarClient;
-import org.sonar.wsclient.base.HttpException;
-import org.sonar.wsclient.issue.Issue;
-import org.sonar.wsclient.issue.IssueQuery;
-import org.sonar.wsclient.user.UserParameters;
-import org.sonarqube.ws.Issues;
-import org.sonarqube.ws.client.WsClient;
-import org.sonarqube.ws.client.issue.BulkChangeRequest;
-import org.sonarqube.ws.client.permission.AddUserWsRequest;
-import org.sonarqube.ws.client.project.UpdateVisibilityRequest;
-import util.ItUtils;
-
-import static java.util.Arrays.asList;
-import static junit.framework.TestCase.fail;
-import static org.assertj.core.api.Assertions.assertThat;
-import static util.ItUtils.newAdminWsClient;
-import static util.ItUtils.newUserWsClient;
-import static util.ItUtils.projectDir;
-
-public class IssuePermissionTest {
-
- @ClassRule
- public static Orchestrator orchestrator = Category1Suite.ORCHESTRATOR;
- public WsClient adminWsClient = newAdminWsClient(orchestrator);
-
- @Before
- public void init() {
- orchestrator.resetData();
-
- ItUtils.restoreProfile(orchestrator, getClass().getResource("/authorisation/one-issue-per-line-profile.xml"));
-
- orchestrator.getServer().provisionProject("privateProject", "PrivateProject");
- newAdminWsClient(orchestrator).projects().updateVisibility(UpdateVisibilityRequest.builder().setProject("privateProject").setVisibility("private").build());
- orchestrator.getServer().associateProjectToQualityProfile("privateProject", "xoo", "one-issue-per-line");
- SonarScanner privateProject = SonarScanner.create(projectDir("shared/xoo-sample"))
- .setProperty("sonar.projectKey", "privateProject")
- .setProperty("sonar.projectName", "PrivateProject");
- orchestrator.executeBuild(privateProject);
-
- orchestrator.getServer().provisionProject("publicProject", "PublicProject");
- orchestrator.getServer().associateProjectToQualityProfile("publicProject", "xoo", "one-issue-per-line");
- SonarScanner publicProject = SonarScanner.create(projectDir("shared/xoo-sample"))
- .setProperty("sonar.projectKey", "publicProject")
- .setProperty("sonar.projectName", "PublicProject");
-
-
- orchestrator.executeBuild(publicProject);
- }
-
- @Test
- public void need_user_permission_on_project_to_see_issue() {
- SonarClient client = orchestrator.getServer().adminWsClient();
-
- String withBrowsePermission = "with-browse-permission";
- String withoutBrowsePermission = "without-browse-permission";
-
- try {
- client.userClient().create(UserParameters.create().login(withBrowsePermission).name(withBrowsePermission)
- .password("password").passwordConfirmation("password"));
- addUserPermission(withBrowsePermission, "privateProject", "user");
-
- client.userClient().create(UserParameters.create().login(withoutBrowsePermission).name(withoutBrowsePermission)
- .password("password").passwordConfirmation("password"));
-
- // Without user permission, a user cannot see issues on the project
- assertThat(orchestrator.getServer().wsClient(withoutBrowsePermission, "password").issueClient().find(
- IssueQuery.create().componentRoots("privateProject")).list()).isEmpty();
-
- // With user permission, a user can see issues on the project
- assertThat(orchestrator.getServer().wsClient(withBrowsePermission, "password").issueClient().find(
- IssueQuery.create().componentRoots("privateProject")).list()).isNotEmpty();
-
- } finally {
- client.userClient().deactivate(withBrowsePermission);
- client.userClient().deactivate(withoutBrowsePermission);
- }
- }
-
- /**
- * SONAR-4839
- */
- @Test
- public void need_user_permission_on_project_to_see_issue_changelog() {
- SonarClient client = orchestrator.getServer().adminWsClient();
- Issue issue = client.issueClient().find(IssueQuery.create().componentRoots("privateProject")).list().get(0);
- client.issueClient().assign(issue.key(), "admin");
-
- String withBrowsePermission = "with-browse-permission";
- String withoutBrowsePermission = "without-browse-permission";
-
- try {
- client.userClient().create(UserParameters.create().login(withBrowsePermission).name(withBrowsePermission)
- .password("password").passwordConfirmation("password"));
- addUserPermission(withBrowsePermission, "privateProject", "user");
-
- client.userClient().create(UserParameters.create().login(withoutBrowsePermission).name(withoutBrowsePermission)
- .password("password").passwordConfirmation("password"));
-
- // Without user permission, a user cannot see issue changelog on the project
- try {
- changelog(issue.key(), withoutBrowsePermission, "password");
- fail();
- } catch (Exception e) {
- assertThat(e).isInstanceOf(org.sonarqube.ws.client.HttpException.class).describedAs("403");
- }
-
- // Without user permission, a user cannot see issues on the project
- assertThat(changelog(issue.key(), withBrowsePermission, "password").getChangelogList()).isNotEmpty();
-
- } finally {
- client.userClient().deactivate(withBrowsePermission);
- client.userClient().deactivate(withoutBrowsePermission);
- }
- }
-
- /**
- * SONAR-2447
- */
- @Test
- public void need_administer_issue_permission_on_project_to_set_severity() {
- SonarClient client = orchestrator.getServer().adminWsClient();
- Issue issueOnPrivateProject = client.issueClient().find(IssueQuery.create().componentRoots("privateProject")).list().get(0);
- Issue issueOnPublicProject = client.issueClient().find(IssueQuery.create().componentRoots("publicProject")).list().get(0);
-
- String user = "user";
-
- try {
- client.userClient().create(UserParameters.create().login(user).name(user).password("password").passwordConfirmation("password"));
- addUserPermission(user, "publicProject", "issueadmin");
-
- // Without issue admin permission, a user cannot set severity on the issue
- try {
- orchestrator.getServer().wsClient(user, "password").issueClient().setSeverity(issueOnPrivateProject.key(), "BLOCKER");
- fail();
- } catch (Exception e) {
- assertThat(e).isInstanceOf(HttpException.class).describedAs("404");
- }
-
- // With issue admin permission, a user can set severity on the issue
- assertThat(orchestrator.getServer().wsClient(user, "password").issueClient().setSeverity(issueOnPublicProject.key(), "BLOCKER").severity()).isEqualTo("BLOCKER");
-
- } finally {
- client.userClient().deactivate(user);
- }
- }
-
- /**
- * SONAR-2447
- */
- @Test
- public void need_administer_issue_permission_on_project_to_flag_as_false_positive() {
- SonarClient client = orchestrator.getServer().adminWsClient();
- Issue issueOnPrivateProject = client.issueClient().find(IssueQuery.create().componentRoots("privateProject")).list().get(0);
- Issue issueOnPublicProject = client.issueClient().find(IssueQuery.create().componentRoots("publicProject")).list().get(0);
-
- String user = "user";
-
- try {
- client.userClient().create(UserParameters.create().login(user).name(user).password("password").passwordConfirmation("password"));
- addUserPermission(user, "publicProject", "issueadmin");
-
- // Without issue admin permission, a user cannot flag an issue as false positive
- try {
- orchestrator.getServer().wsClient(user, "password").issueClient().doTransition(issueOnPrivateProject.key(), "falsepositive");
- fail();
- } catch (Exception e) {
- assertThat(e).isInstanceOf(HttpException.class).describedAs("404");
- }
-
- // With issue admin permission, a user can flag an issue as false positive
- assertThat(orchestrator.getServer().wsClient(user, "password").issueClient().doTransition(issueOnPublicProject.key(), "falsepositive").status()).isEqualTo("RESOLVED");
-
- } finally {
- client.userClient().deactivate(user);
- }
- }
-
- /**
- * SONAR-2447
- */
- @Test
- public void need_administer_issue_permission_on_project_to_bulk_change_severity_and_false_positive() {
- SonarClient client = orchestrator.getServer().adminWsClient();
- Issue issueOnPrivateProject = client.issueClient().find(IssueQuery.create().componentRoots("privateProject")).list().get(0);
- Issue issueOnPublicProject = client.issueClient().find(IssueQuery.create().componentRoots("publicProject")).list().get(0);
-
- String user = "user";
-
- try {
- client.userClient().create(UserParameters.create().login(user).name(user).password("password").passwordConfirmation("password"));
- addUserPermission(user, "privateProject", "issueadmin");
-
- Issues.BulkChangeWsResponse response = makeBlockerAndFalsePositive(user, issueOnPrivateProject, issueOnPublicProject);
-
- // public project but no issueadmin permission on publicProject => issue visible but not updated
- // no user permission on privateproject => issue invisible and not updated
- assertThat(response.getTotal()).isEqualTo(1);
- assertThat(response.getSuccess()).isEqualTo(0);
- assertThat(response.getIgnored()).isEqualTo(1);
-
- addUserPermission(user, "privateProject", "user");
- response = makeBlockerAndFalsePositive(user, issueOnPrivateProject, issueOnPublicProject);
-
- // public project but no issueadmin permission on publicProject => unsuccessful on issueOnPublicProject
- // user and issueadmin permission on privateproject => successful and 1 more issue visible
- assertThat(response.getTotal()).isEqualTo(2);
- assertThat(response.getSuccess()).isEqualTo(1);
- assertThat(response.getIgnored()).isEqualTo(1);
-
- addUserPermission(user, "publicProject", "issueadmin");
- response = makeBlockerAndFalsePositive(user, issueOnPrivateProject, issueOnPublicProject);
-
- // public and issueadmin permission on publicProject => successful on issueOnPublicProject
- // issueOnPrivateProject already in specified state => unsuccessful
- assertThat(response.getTotal()).isEqualTo(2);
- assertThat(response.getSuccess()).isEqualTo(1);
- assertThat(response.getIgnored()).isEqualTo(1);
-
- response = makeBlockerAndFalsePositive(user, issueOnPrivateProject, issueOnPublicProject);
-
- // issueOnPublicProject and issueOnPrivateProject already in specified state => unsuccessful
- assertThat(response.getTotal()).isEqualTo(2);
- assertThat(response.getSuccess()).isEqualTo(0);
- assertThat(response.getIgnored()).isEqualTo(2);
- } finally {
- client.userClient().deactivate(user);
- }
- }
-
- private Issues.BulkChangeWsResponse makeBlockerAndFalsePositive(String user, Issue issueOnPrivateProject, Issue issueOnPublicProject) {
- return newUserWsClient(orchestrator, user, "password").issues()
- .bulkChange(BulkChangeRequest.builder().setIssues(asList(issueOnPrivateProject.key(), issueOnPublicProject.key()))
- .setSetSeverity("BLOCKER")
- .setDoTransition("falsepositive")
- .build());
- }
-
- private void addUserPermission(String login, String projectKey, String permission) {
- adminWsClient.permissions().addUser(
- new AddUserWsRequest()
- .setLogin(login)
- .setProjectKey(projectKey)
- .setPermission(permission));
- }
-
- private static Issues.ChangelogWsResponse changelog(String issueKey, String login, String password) {
- return newUserWsClient(orchestrator, login, password).issues().changelog(issueKey);
- }
-}
+++ /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.sonarqube.tests.authorisation;
-
-import com.sonar.orchestrator.Orchestrator;
-import com.sonar.orchestrator.build.SonarScanner;
-import org.sonarqube.tests.Category1Suite;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.sonarqube.ws.WsPermissions;
-import org.sonarqube.ws.WsPermissions.Permission;
-import org.sonarqube.ws.WsPermissions.SearchTemplatesWsResponse;
-import org.sonarqube.ws.client.PostRequest;
-import org.sonarqube.ws.client.WsClient;
-import org.sonarqube.ws.client.permission.AddGroupToTemplateWsRequest;
-import org.sonarqube.ws.client.permission.AddGroupWsRequest;
-import org.sonarqube.ws.client.permission.AddProjectCreatorToTemplateWsRequest;
-import org.sonarqube.ws.client.permission.AddUserToTemplateWsRequest;
-import org.sonarqube.ws.client.permission.AddUserWsRequest;
-import org.sonarqube.ws.client.permission.CreateTemplateWsRequest;
-import org.sonarqube.ws.client.permission.GroupsWsRequest;
-import org.sonarqube.ws.client.permission.PermissionsService;
-import org.sonarqube.ws.client.permission.RemoveGroupFromTemplateWsRequest;
-import org.sonarqube.ws.client.permission.RemoveProjectCreatorFromTemplateWsRequest;
-import org.sonarqube.ws.client.permission.RemoveUserFromTemplateWsRequest;
-import org.sonarqube.ws.client.permission.SearchTemplatesWsRequest;
-import org.sonarqube.ws.client.permission.UsersWsRequest;
-import util.ItUtils;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.tuple;
-import static util.ItUtils.newAdminWsClient;
-import static util.ItUtils.projectDir;
-
-public class PermissionSearchTest {
- @ClassRule
- public static Orchestrator orchestrator = Category1Suite.ORCHESTRATOR;
- private static WsClient adminWsClient;
- private static PermissionsService permissionsWsClient;
-
- private static final String PROJECT_KEY = "sample";
- private static final String LOGIN = "george.orwell";
- private static final String GROUP_NAME = "1984";
-
- @BeforeClass
- public static void analyzeProject() {
- orchestrator.resetData();
-
- ItUtils.restoreProfile(orchestrator, PermissionSearchTest.class.getResource("/authorisation/one-issue-per-line-profile.xml"));
-
- orchestrator.getServer().provisionProject(PROJECT_KEY, "Sample");
- orchestrator.getServer().associateProjectToQualityProfile("sample", "xoo", "one-issue-per-line");
- SonarScanner sampleProject = SonarScanner.create(projectDir("shared/xoo-sample"));
- orchestrator.executeBuild(sampleProject);
-
- adminWsClient = newAdminWsClient(orchestrator);
- permissionsWsClient = adminWsClient.permissions();
-
- createUser(LOGIN, "George Orwell");
- createGroup(GROUP_NAME);
- }
-
- @AfterClass
- public static void delete_data() {
- deactivateUser(LOGIN);
- deleteGroup(GROUP_NAME);
- }
-
- @Test
- public void permission_web_services() {
- permissionsWsClient.addUser(
- new AddUserWsRequest()
- .setPermission("admin")
- .setLogin(LOGIN));
- permissionsWsClient.addGroup(
- new AddGroupWsRequest()
- .setPermission("admin")
- .setGroupName(GROUP_NAME));
-
- WsPermissions.WsSearchGlobalPermissionsResponse searchGlobalPermissionsWsResponse = permissionsWsClient.searchGlobalPermissions();
- assertThat(searchGlobalPermissionsWsResponse.getPermissionsList().get(0).getKey()).isEqualTo("admin");
- assertThat(searchGlobalPermissionsWsResponse.getPermissionsList().get(0).getUsersCount()).isEqualTo(1);
- // by default, a group has the global admin permission
- assertThat(searchGlobalPermissionsWsResponse.getPermissionsList().get(0).getGroupsCount()).isEqualTo(2);
-
- WsPermissions.UsersWsResponse users = permissionsWsClient
- .users(new UsersWsRequest().setPermission("admin"));
- assertThat(users.getUsersList()).extracting("login").contains(LOGIN);
-
- WsPermissions.WsGroupsResponse groupsResponse = permissionsWsClient
- .groups(new GroupsWsRequest()
- .setPermission("admin"));
- assertThat(groupsResponse.getGroupsList()).extracting("name").contains(GROUP_NAME);
- }
-
- @Test
- public void template_permission_web_services() {
- WsPermissions.CreateTemplateWsResponse createTemplateWsResponse = permissionsWsClient.createTemplate(
- new CreateTemplateWsRequest()
- .setName("my-new-template")
- .setDescription("template-used-in-tests"));
- assertThat(createTemplateWsResponse.getPermissionTemplate().getName()).isEqualTo("my-new-template");
-
- permissionsWsClient.addUserToTemplate(
- new AddUserToTemplateWsRequest()
- .setPermission("admin")
- .setTemplateName("my-new-template")
- .setLogin(LOGIN));
-
- permissionsWsClient.addGroupToTemplate(
- new AddGroupToTemplateWsRequest()
- .setPermission("admin")
- .setTemplateName("my-new-template")
- .setGroupName(GROUP_NAME));
-
- permissionsWsClient.addProjectCreatorToTemplate(
- AddProjectCreatorToTemplateWsRequest.builder()
- .setPermission("admin")
- .setTemplateName("my-new-template")
- .build());
-
- SearchTemplatesWsResponse searchTemplatesWsResponse = permissionsWsClient.searchTemplates(
- new SearchTemplatesWsRequest()
- .setQuery("my-new-template"));
- assertThat(searchTemplatesWsResponse.getPermissionTemplates(0).getName()).isEqualTo("my-new-template");
- assertThat(searchTemplatesWsResponse.getPermissionTemplates(0).getPermissions(0).getKey()).isEqualTo("admin");
- assertThat(searchTemplatesWsResponse.getPermissionTemplates(0).getPermissions(0).getUsersCount()).isEqualTo(1);
- assertThat(searchTemplatesWsResponse.getPermissionTemplates(0).getPermissions(0).getGroupsCount()).isEqualTo(1);
- assertThat(searchTemplatesWsResponse.getPermissionTemplates(0).getPermissions(0).getWithProjectCreator()).isTrue();
-
- permissionsWsClient.removeGroupFromTemplate(
- new RemoveGroupFromTemplateWsRequest()
- .setPermission("admin")
- .setTemplateName("my-new-template")
- .setGroupName(GROUP_NAME));
-
- permissionsWsClient.removeUserFromTemplate(
- new RemoveUserFromTemplateWsRequest()
- .setPermission("admin")
- .setTemplateName("my-new-template")
- .setLogin(LOGIN));
-
- permissionsWsClient.removeProjectCreatorFromTemplate(
- RemoveProjectCreatorFromTemplateWsRequest.builder()
- .setPermission("admin")
- .setTemplateName("my-new-template")
- .build()
- );
-
- SearchTemplatesWsResponse clearedSearchTemplatesWsResponse = permissionsWsClient.searchTemplates(
- new SearchTemplatesWsRequest()
- .setQuery("my-new-template"));
- assertThat(clearedSearchTemplatesWsResponse.getPermissionTemplates(0).getPermissionsList())
- .extracting(Permission::getUsersCount, Permission::getGroupsCount, Permission::getWithProjectCreator)
- .hasSize(5)
- .containsOnly(tuple(0, 0, false));
- }
-
- private static void createUser(String login, String name) {
- adminWsClient.wsConnector().call(
- new PostRequest("api/users/create")
- .setParam("login", login)
- .setParam("name", name)
- .setParam("password", "123456"));
- }
-
- private static void deactivateUser(String login) {
- adminWsClient.wsConnector().call(
- new PostRequest("api/users/deactivate")
- .setParam("login", login));
- }
-
- private static void createGroup(String groupName) {
- adminWsClient.wsConnector().call(
- new PostRequest("api/user_groups/create")
- .setParam("name", groupName));
- }
-
- private static void deleteGroup(String groupName) {
- adminWsClient.wsConnector().call(
- new PostRequest("api/user_groups/delete")
- .setParam("name", groupName));
- }
-}
+++ /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.sonarqube.tests.authorisation;
-
-import com.sonar.orchestrator.Orchestrator;
-import java.util.Arrays;
-import java.util.Optional;
-import org.junit.After;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.DisableOnDebug;
-import org.junit.rules.TestRule;
-import org.junit.rules.Timeout;
-import org.sonarqube.tests.Category6Suite;
-import org.sonarqube.qa.util.Tester;
-import org.sonarqube.ws.Organizations.Organization;
-import org.sonarqube.ws.WsPermissions;
-import org.sonarqube.ws.WsPermissions.CreateTemplateWsResponse;
-import org.sonarqube.ws.WsProjects.CreateWsResponse.Project;
-import org.sonarqube.ws.WsUsers.CreateWsResponse;
-import org.sonarqube.ws.client.WsClient;
-import org.sonarqube.ws.client.component.SearchProjectsRequest;
-import org.sonarqube.ws.client.permission.AddUserToTemplateWsRequest;
-import org.sonarqube.ws.client.permission.ApplyTemplateWsRequest;
-import org.sonarqube.ws.client.permission.BulkApplyTemplateWsRequest;
-import org.sonarqube.ws.client.permission.CreateTemplateWsRequest;
-import org.sonarqube.ws.client.permission.PermissionsService;
-import org.sonarqube.ws.client.permission.UsersWsRequest;
-
-import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class PermissionTemplateTest {
- @ClassRule
- public static final Orchestrator orchestrator = Category6Suite.ORCHESTRATOR;
-
- @Rule
- public TestRule safeguard = new DisableOnDebug(Timeout.seconds(300));
- @Rule
- public Tester tester = new Tester(orchestrator)
- .setElasticsearchHttpPort(Category6Suite.SEARCH_HTTP_PORT);
-
- @After
- public void tearDown() throws Exception {
- unlockWritesOnProjectIndices();
- }
-
- @Test
- public void apply_permission_template_on_project() {
- Organization organization = tester.organizations().generate();
- Project project = createPrivateProject(organization);
- CreateWsResponse.User user = tester.users().generateMember(organization);
- CreateWsResponse.User anotherUser = tester.users().generateMember(organization);
-
- assertThatUserDoesNotHavePermission(user, organization, project);
- assertThatUserDoesNotHavePermission(anotherUser, organization, project);
- assertThat(userHasAccessToIndexedProject(user, organization, project)).isTrue();
- assertThat(userHasAccessToIndexedProject(anotherUser, organization, project)).isTrue();
-
- // create permission template that gives read permission to "user"
- createAndApplyTemplate(organization, project, user);
-
- assertThatUserHasPermission(user, organization, project);
- assertThatUserDoesNotHavePermission(anotherUser, organization, project);
- assertThat(userHasAccessToIndexedProject(user, organization, project)).isTrue();
- assertThat(userHasAccessToIndexedProject(anotherUser, organization, project)).isFalse();
- }
-
- @Test
- public void bulk_apply_template_on_projects() {
- Organization organization = tester.organizations().generate();
- CreateWsResponse.User user = tester.users().generateMember(organization);
- CreateWsResponse.User anotherUser = tester.users().generateMember(organization);
- WsPermissions.PermissionTemplate template = createTemplate(organization).getPermissionTemplate();
- tester.wsClient().permissions().addUserToTemplate(new AddUserToTemplateWsRequest()
- .setOrganization(organization.getKey())
- .setTemplateId(template.getId())
- .setLogin(user.getLogin())
- .setPermission("user"));
- Project project1 = createPrivateProject(organization);
- Project project2 = createPrivateProject(organization);
- Project untouchedProject = createPrivateProject(organization);
-
- tester.wsClient().permissions().bulkApplyTemplate(new BulkApplyTemplateWsRequest()
- .setOrganization(organization.getKey())
- .setTemplateId(template.getId())
- .setProjects(Arrays.asList(project1.getKey(), project2.getKey())));
-
- assertThatUserDoesNotHavePermission(anotherUser, organization, untouchedProject);
- assertThatUserDoesNotHavePermission(anotherUser, organization, project1);
- assertThatUserDoesNotHavePermission(anotherUser, organization, project2);
- assertThatUserHasPermission(user, organization, project1);
- assertThatUserHasPermission(user, organization, project2);
- assertThatUserDoesNotHavePermission(user, organization, untouchedProject);
- }
-
- @Test
- public void indexing_errors_are_recovered_when_applying_permission_template_on_project() throws Exception {
- Organization organization = tester.organizations().generate();
- Project project = createPrivateProject(organization);
- CreateWsResponse.User user = tester.users().generateMember(organization);
- CreateWsResponse.User anotherUser = tester.users().generateMember(organization);
-
- lockWritesOnProjectIndices();
-
- createAndApplyTemplate(organization, project, user);
-
- assertThatUserHasPermission(user, organization, project);
- assertThatUserDoesNotHavePermission(anotherUser, organization, project);
- assertThat(userHasAccessToIndexedProject(user, organization, project)).isTrue();
- // inconsistent, should be false. Waiting for ES to be updated.
- assertThat(userHasAccessToIndexedProject(user, organization, project)).isTrue();
-
- unlockWritesOnProjectIndices();
-
- boolean recovered = false;
- while (!recovered) {
- Thread.sleep(1_000L);
- recovered = !userHasAccessToIndexedProject(anotherUser, organization, project);
- }
- }
-
- private void lockWritesOnProjectIndices() throws Exception {
- tester.elasticsearch().lockWrites("issues");
- tester.elasticsearch().lockWrites("projectmeasures");
- tester.elasticsearch().lockWrites("components");
- }
-
- private void unlockWritesOnProjectIndices() throws Exception {
- tester.elasticsearch().unlockWrites("issues");
- tester.elasticsearch().unlockWrites("projectmeasures");
- tester.elasticsearch().unlockWrites("components");
- }
-
- /**
- * Gives the read access only to the specified user. All other users and groups
- * loose their ability to see the project.
- */
- private void createAndApplyTemplate(Organization organization, Project project, CreateWsResponse.User user) {
- String templateName = "For user";
- PermissionsService service = tester.wsClient().permissions();
- service.createTemplate(new CreateTemplateWsRequest()
- .setOrganization(organization.getKey())
- .setName(templateName)
- .setDescription("Give admin permissions to single user"));
- service.addUserToTemplate(new AddUserToTemplateWsRequest()
- .setOrganization(organization.getKey())
- .setLogin(user.getLogin())
- .setPermission("user")
- .setTemplateName(templateName));
- service.applyTemplate(new ApplyTemplateWsRequest()
- .setOrganization(organization.getKey())
- .setProjectKey(project.getKey())
- .setTemplateName(templateName));
- }
-
- private CreateTemplateWsResponse createTemplate(Organization organization) {
- return tester.wsClient().permissions().createTemplate(new CreateTemplateWsRequest()
- .setOrganization(organization.getKey())
- .setName(randomAlphabetic(20)));
- }
-
- private Project createPrivateProject(Organization organization) {
- return tester.projects().generate(organization, p -> p.setVisibility("private"));
- }
-
- private void assertThatUserHasPermission(CreateWsResponse.User user, Organization organization, Project project) {
- assertThat(hasBrowsePermission(user, organization, project)).isTrue();
- }
-
- private void assertThatUserDoesNotHavePermission(CreateWsResponse.User user, Organization organization, Project project) {
- assertThat(hasBrowsePermission(user, organization, project)).isFalse();
- }
-
- private boolean userHasAccessToIndexedProject(CreateWsResponse.User user, Organization organization, Project project) {
- SearchProjectsRequest request = SearchProjectsRequest.builder().setOrganization(organization.getKey()).build();
- WsClient userSession = tester.as(user.getLogin()).wsClient();
- return userSession.components().searchProjects(request)
- .getComponentsList().stream()
- .anyMatch(c -> c.getKey().equals(project.getKey()));
- }
-
- private boolean hasBrowsePermission(CreateWsResponse.User user, Organization organization, Project project) {
- UsersWsRequest request = new UsersWsRequest()
- .setOrganization(organization.getKey())
- .setProjectKey(project.getKey())
- .setPermission("user");
- WsPermissions.UsersWsResponse response = tester.wsClient().permissions().users(request);
- Optional<WsPermissions.User> found = response.getUsersList().stream()
- .filter(u -> user.getLogin().equals(u.getLogin()))
- .findFirst();
- return found.isPresent();
- }
-}
+++ /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.sonarqube.tests.authorisation;
-
-import com.sonar.orchestrator.Orchestrator;
-import org.sonarqube.tests.Category1Suite;
-import org.junit.ClassRule;
-import org.junit.Test;
-
-import static util.selenium.Selenese.runSelenese;
-
-public class PermissionTemplatesPageTest {
-
- @ClassRule
- public static Orchestrator orchestrator = Category1Suite.ORCHESTRATOR;
-
- @Test
- public void should_display_page() throws Exception {
- runSelenese(orchestrator,
- "/authorisation/PermissionTemplatesPageTest/should_display_page.html",
- "/authorisation/PermissionTemplatesPageTest/should_create.html");
- }
-
- @Test
- public void should_manage_project_creators() throws Exception {
- runSelenese(orchestrator, "/authorisation/PermissionTemplatesPageTest/should_manage_project_creators.html");
- }
-}
+++ /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.sonarqube.tests.authorisation;
-
-import com.sonar.orchestrator.Orchestrator;
-import org.sonarqube.tests.Category1Suite;
-import org.junit.AfterClass;
-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.WsProjects.CreateWsResponse.Project;
-import org.sonarqube.ws.client.HttpException;
-import org.sonarqube.ws.client.permission.AddGroupWsRequest;
-import org.sonarqube.ws.client.permission.AddUserWsRequest;
-import org.sonarqube.ws.client.permission.PermissionsService;
-import org.sonarqube.ws.client.permission.RemoveGroupWsRequest;
-import org.sonarqube.ws.client.permission.RemoveUserWsRequest;
-import org.sonarqube.ws.client.project.CreateRequest;
-import util.user.UserRule;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static util.ItUtils.newAdminWsClient;
-import static util.ItUtils.newUserWsClient;
-import static util.selenium.Selenese.runSelenese;
-
-public class ProvisioningPermissionTest {
-
- @Rule
- public ExpectedException thrown = ExpectedException.none();
-
- @ClassRule
- public static Orchestrator orchestrator = Category1Suite.ORCHESTRATOR;
-
- @ClassRule
- public static UserRule userRule = UserRule.from(orchestrator);
-
- private static final String PASSWORD = "password";
-
- private static final String ADMIN_WITH_PROVISIONING = "admin-with-provisioning";
- private static final String ADMIN_WITHOUT_PROVISIONING = "admin-without-provisioning";
- private static final String USER_WITH_PROVISIONING = "user-with-provisioning";
- private static final String USER_WITHOUT_PROVISIONING = "user-without-provisioning";
-
- private static PermissionsService permissionsWsClient;
-
- @BeforeClass
- public static void init() {
- permissionsWsClient = newAdminWsClient(orchestrator).permissions();
-
- // remove default permission "provisioning" from anyone();
- permissionsWsClient.removeGroup(new RemoveGroupWsRequest().setGroupName("anyone").setPermission("provisioning"));
-
- userRule.createUser(ADMIN_WITH_PROVISIONING, PASSWORD);
- addUserPermission(ADMIN_WITH_PROVISIONING, "admin");
- addUserPermission(ADMIN_WITH_PROVISIONING, "provisioning");
-
- userRule.createUser(ADMIN_WITHOUT_PROVISIONING, PASSWORD);
- addUserPermission(ADMIN_WITHOUT_PROVISIONING, "admin");
- removeUserPermission(ADMIN_WITHOUT_PROVISIONING, "provisioning");
-
- userRule.createUser(USER_WITH_PROVISIONING, PASSWORD);
- addUserPermission(USER_WITH_PROVISIONING, "provisioning");
-
- userRule.createUser(USER_WITHOUT_PROVISIONING, PASSWORD);
- removeUserPermission(USER_WITHOUT_PROVISIONING, "provisioning");
- }
-
- @AfterClass
- public static void restoreData() throws Exception {
- userRule.resetUsers();
- permissionsWsClient.addGroup(new AddGroupWsRequest().setGroupName("anyone").setPermission("provisioning"));
- }
-
- /**
- * SONAR-3871
- * SONAR-4709
- */
- @Test
- public void organization_administrator_cannot_provision_project_if_he_does_not_have_provisioning_permission() {
- runSelenese(orchestrator, "/authorisation/ProvisioningPermissionTest/should-not-be-able-to-provision-project.html");
- }
-
- /**
- * SONAR-3871
- * SONAR-4709
- */
- @Test
- public void organization_administrator_can_provision_project_if_he_has_provisioning_permission() {
- runSelenese(orchestrator, "/authorisation/ProvisioningPermissionTest/should-be-able-to-provision-project.html");
- }
-
- /**
- * SONAR-3871
- * SONAR-4709
- */
- @Test
- public void user_can_provision_project_through_ws_if_he_has_provisioning_permission() {
- final String newKey = "new-project";
- final String newName = "New Project";
-
- Project created = newUserWsClient(orchestrator, USER_WITH_PROVISIONING, PASSWORD).projects()
- .create(CreateRequest.builder().setKey(newKey).setName(newName).build())
- .getProject();
-
- assertThat(created).isNotNull();
- assertThat(created.getKey()).isEqualTo(newKey);
- assertThat(created.getName()).isEqualTo(newName);
- }
-
- /**
- * SONAR-3871
- * SONAR-4709
- */
- @Test
- public void user_cannot_provision_project_through_ws_if_he_does_not_have_provisioning_permission() {
- thrown.expect(HttpException.class);
- thrown.expectMessage("403");
-
- newUserWsClient(orchestrator, USER_WITHOUT_PROVISIONING, PASSWORD).projects()
- .create(CreateRequest.builder().setKey("new-project").setName("New Project").build())
- .getProject();
- }
-
- private static void addUserPermission(String login, String permission) {
- permissionsWsClient.addUser(new AddUserWsRequest().setLogin(login).setPermission(permission));
- }
-
- private static void removeUserPermission(String login, String permission) {
- permissionsWsClient.removeUser(new RemoveUserWsRequest().setLogin(login).setPermission(permission));
- }
-}
+++ /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.sonarqube.tests.authorisation;
-
-import com.sonar.orchestrator.Orchestrator;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.sonarqube.tests.Category1Suite;
-import org.sonarqube.qa.util.Tester;
-import org.sonarqube.ws.client.permission.AddUserWsRequest;
-import org.sonarqube.ws.client.qualityprofile.CreateRequest;
-import util.selenium.Selenese;
-
-import static util.ItUtils.runProjectAnalysis;
-
-/**
- * SONAR-4210
- */
-public class QualityProfileAdminPermissionTest {
-
- @ClassRule
- public static Orchestrator orchestrator = Category1Suite.ORCHESTRATOR;
-
- @Rule
- public Tester tester = new Tester(orchestrator).disableOrganizations();
-
- @Test
- public void permission_should_grant_access_to_profile() {
- runProjectAnalysis(orchestrator, "shared/xoo-sample");
-
- tester.users().generate(u -> u.setLogin("not_profileadm").setPassword("userpwd"));
- tester.users().generate(u -> u.setLogin("profileadm").setPassword("papwd"));
- tester.wsClient().permissions().addUser(new AddUserWsRequest().setLogin("profileadm").setPermission("profileadmin"));
- createProfile("xoo", "foo");
-
- Selenese.runSelenese(orchestrator,
- // Verify normal user is not allowed to do any modification
- "/authorisation/QualityProfileAdminPermissionTest/normal-user.html",
- // Verify profile admin is allowed to do modifications
- "/authorisation/QualityProfileAdminPermissionTest/profile-admin.html");
- }
-
- private void createProfile(String language, String name) {
- tester.wsClient().qualityProfiles().create(CreateRequest.builder()
- .setLanguage(language)
- .setName(name)
- .build());
- }
-
-}
+++ /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.sonarqube.tests.authorisation;
-
-import com.sonar.orchestrator.Orchestrator;
-import com.sonar.orchestrator.OrchestratorBuilder;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.Test;
-import org.sonarqube.qa.util.Tester;
-import org.sonarqube.ws.client.GetRequest;
-import org.sonarqube.ws.client.WsRequest;
-import org.sonarqube.ws.client.WsResponse;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static util.ItUtils.pluginArtifact;
-
-public class SystemPasscodeTest {
-
- private static final String VALID_PASSCODE = "123456";
- private static final String INVALID_PASSCODE = "not" + VALID_PASSCODE;
- private static final String PASSCODE_HEADER = "X-Sonar-Passcode";
-
- private static Orchestrator orchestrator;
-
- @BeforeClass
- public static void setUp() throws Exception {
- OrchestratorBuilder builder = Orchestrator.builderEnv()
- // this privileged plugin provides the WS api/system_passcode/check
- // that is used by the tests
- .addPlugin(pluginArtifact("fake-governance-plugin"))
- .setServerProperty("sonar.web.systemPasscode", VALID_PASSCODE);
- orchestrator = builder.build();
- orchestrator.start();
- }
-
- @AfterClass
- public static void stop() {
- if (orchestrator != null) {
- orchestrator.stop();
- }
- }
-
- @Rule
- public Tester tester = new Tester(orchestrator);
-
- @Test
- public void system_access_is_granted_if_valid_passcode_is_sent_through_http_header() {
- WsRequest request = newRequest()
- .setHeader(PASSCODE_HEADER, VALID_PASSCODE);
-
- WsResponse response = tester.asAnonymous().wsClient().wsConnector().call(request);
- assertThat(response.code()).isEqualTo(200);
- }
-
- @Test
- public void system_access_is_rejected_if_invalid_passcode_is_sent_through_http_header() {
- WsRequest request = newRequest()
- .setHeader(PASSCODE_HEADER, INVALID_PASSCODE);
-
- WsResponse response = tester.asAnonymous().wsClient().wsConnector().call(request);
- assertThat(response.code()).isEqualTo(401);
- }
-
- @Test
- public void system_access_is_rejected_if_passcode_is_not_sent() {
- WsRequest request = newRequest();
-
- WsResponse response = tester.asAnonymous().wsClient().wsConnector().call(request);
- assertThat(response.code()).isEqualTo(401);
- }
-
- private static GetRequest newRequest() {
- return new GetRequest("api/system_passcode/check");
- }
-}
--- /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.sonarqube.tests.authorization;
+
+import com.sonar.orchestrator.Orchestrator;
+import org.junit.ClassRule;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+import static util.ItUtils.pluginArtifact;
+import static util.ItUtils.xooPlugin;
+
+@RunWith(Suite.class)
+@Suite.SuiteClasses({
+ ExecuteAnalysisPermissionTest.class,
+ IssuePermissionTest.class,
+ PermissionSearchTest.class,
+ ProvisioningPermissionTest.class,
+ QualityProfileAdminPermissionTest.class,
+ SystemPasscodeTest.class
+})
+public class AuthorizationSuite {
+
+ @ClassRule
+ public static final Orchestrator ORCHESTRATOR = Orchestrator.builderEnv()
+ // reduce memory for Elasticsearch
+ .setServerProperty("sonar.search.javaOpts", "-Xms128m -Xmx128m")
+
+ // for SystemPasscodeTest
+ // this privileged plugin provides the WS api/system_passcode/check
+ // that is used by the tests
+ .addPlugin(pluginArtifact("fake-governance-plugin"))
+ .setServerProperty("sonar.web.systemPasscode", SystemPasscodeTest.VALID_PASSCODE)
+
+ .addPlugin(xooPlugin())
+ .build();
+
+}
--- /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.sonarqube.tests.authorization;
+
+import com.sonar.orchestrator.Orchestrator;
+import com.sonar.orchestrator.build.BuildFailureException;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonarqube.qa.util.Tester;
+import org.sonarqube.ws.client.permission.AddGroupWsRequest;
+import org.sonarqube.ws.client.permission.AddProjectCreatorToTemplateWsRequest;
+import org.sonarqube.ws.client.permission.RemoveGroupWsRequest;
+import org.sonarqube.ws.client.project.UpdateVisibilityRequest;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.fail;
+import static util.ItUtils.runProjectAnalysis;
+
+/**
+ * SONAR-4397
+ */
+public class ExecuteAnalysisPermissionTest {
+
+ private final static String USER_LOGIN = "scanperm";
+ private final static String USER_PASSWORD = "thewhite";
+ private final static String PROJECT_KEY = "sample";
+
+ @ClassRule
+ public static Orchestrator orchestrator = AuthorizationSuite.ORCHESTRATOR;
+
+ @Rule
+ public Tester tester = new Tester(orchestrator)
+ // all the tests of AuthorizationSuite must disable organizations
+ .disableOrganizations();
+
+ @Before
+ public void setUp() {
+ tester.users().generate(u -> u.setLogin(USER_LOGIN).setPassword(USER_PASSWORD));
+ orchestrator.getServer().provisionProject(PROJECT_KEY, "Sample");
+ }
+
+ @After
+ public void tearDown() {
+ addGlobalPermission("anyone", "scan");
+ }
+
+ @Test
+ public void should_fail_if_logged_but_no_scan_permission() throws Exception {
+ executeLoggedAnalysis();
+
+ removeGlobalPermission("anyone", "scan");
+ try {
+ // Execute logged analysis, but without the "Execute Analysis" permission
+ executeLoggedAnalysis();
+ fail();
+ } catch (BuildFailureException e) {
+ assertThat(e.getResult().getLogs()).contains(
+ "You're only authorized to execute a local (preview) SonarQube analysis without pushing the results to the SonarQube server. Please contact your SonarQube administrator.");
+ }
+
+ tester.wsClient().projects().updateVisibility(UpdateVisibilityRequest.builder().setProject(PROJECT_KEY).setVisibility("private").build());
+ try {
+ // Execute anonymous analysis
+ executeAnonymousAnalysis();
+ fail();
+ } catch (BuildFailureException e) {
+ assertThat(e.getResult().getLogs()).contains(
+ "You're not authorized to execute any SonarQube analysis. Please contact your SonarQube administrator.");
+ }
+ }
+
+ @Test
+ public void no_need_for_browse_permission_to_scan() throws Exception {
+ // Do a first analysis, no error
+ executeAnonymousAnalysis();
+
+ // make project private
+ tester.wsClient().projects().updateVisibility(UpdateVisibilityRequest.builder().setProject("sample").setVisibility("private").build());
+
+ // still no error
+ executeAnonymousAnalysis();
+ }
+
+ @Test
+ public void execute_analysis_with_scan_permission_only_on_project() throws Exception {
+ removeGlobalPermission("anyone", "scan");
+ addProjectPermission("anyone", PROJECT_KEY, "scan");
+
+ executeLoggedAnalysis();
+ }
+
+ @Test
+ public void execute_analysis_with_scan_on_default_template() {
+ removeGlobalPermission("anyone", "scan");
+ tester.wsClient().permissions().addProjectCreatorToTemplate(AddProjectCreatorToTemplateWsRequest.builder()
+ .setPermission("scan")
+ .setTemplateId("default_template")
+ .build());
+
+ runProjectAnalysis(orchestrator, "shared/xoo-sample", "sonar.login", USER_LOGIN, "sonar.password", USER_PASSWORD, "sonar.projectKey", "ANOTHER_PROJECT_KEY");
+ }
+
+ private void addProjectPermission(String groupName, String projectKey, String permission) {
+ tester.wsClient().permissions().addGroup(new AddGroupWsRequest().setGroupName(groupName).setProjectKey(projectKey).setPermission(permission));
+ }
+
+ private void addGlobalPermission(String groupName, String permission) {
+ tester.wsClient().permissions().addGroup(new AddGroupWsRequest().setGroupName(groupName).setPermission(permission));
+ }
+
+ private void removeGlobalPermission(String groupName, String permission) {
+ tester.wsClient().permissions().removeGroup(new RemoveGroupWsRequest().setGroupName(groupName).setPermission(permission));
+ }
+
+ private static void executeLoggedAnalysis() {
+ runProjectAnalysis(orchestrator, "shared/xoo-sample", "sonar.login", USER_LOGIN, "sonar.password", USER_PASSWORD);
+ }
+
+ private static void executeAnonymousAnalysis() {
+ runProjectAnalysis(orchestrator, "shared/xoo-sample");
+ }
+}
--- /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.sonarqube.tests.authorization;
+
+import com.sonar.orchestrator.Orchestrator;
+import com.sonar.orchestrator.build.SonarScanner;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.wsclient.SonarClient;
+import org.sonar.wsclient.base.HttpException;
+import org.sonar.wsclient.issue.Issue;
+import org.sonar.wsclient.issue.IssueQuery;
+import org.sonar.wsclient.user.UserParameters;
+import org.sonarqube.qa.util.Tester;
+import org.sonarqube.ws.Issues;
+import org.sonarqube.ws.client.issue.BulkChangeRequest;
+import org.sonarqube.ws.client.permission.AddUserWsRequest;
+import org.sonarqube.ws.client.project.UpdateVisibilityRequest;
+import util.ItUtils;
+
+import static java.util.Arrays.asList;
+import static junit.framework.TestCase.fail;
+import static org.assertj.core.api.Assertions.assertThat;
+import static util.ItUtils.newUserWsClient;
+import static util.ItUtils.projectDir;
+
+public class IssuePermissionTest {
+
+ @ClassRule
+ public static Orchestrator orchestrator = AuthorizationSuite.ORCHESTRATOR;
+
+ @Rule
+ public Tester tester = new Tester(orchestrator)
+ // all the tests of AuthorizationSuite must disable organizations
+ .disableOrganizations();
+
+ @Before
+ public void init() {
+ ItUtils.restoreProfile(orchestrator, getClass().getResource("/authorisation/one-issue-per-line-profile.xml"));
+
+ orchestrator.getServer().provisionProject("privateProject", "PrivateProject");
+ tester.wsClient().projects().updateVisibility(UpdateVisibilityRequest.builder().setProject("privateProject").setVisibility("private").build());
+ orchestrator.getServer().associateProjectToQualityProfile("privateProject", "xoo", "one-issue-per-line");
+ SonarScanner privateProject = SonarScanner.create(projectDir("shared/xoo-sample"))
+ .setProperty("sonar.projectKey", "privateProject")
+ .setProperty("sonar.projectName", "PrivateProject");
+ orchestrator.executeBuild(privateProject);
+
+ orchestrator.getServer().provisionProject("publicProject", "PublicProject");
+ orchestrator.getServer().associateProjectToQualityProfile("publicProject", "xoo", "one-issue-per-line");
+ SonarScanner publicProject = SonarScanner.create(projectDir("shared/xoo-sample"))
+ .setProperty("sonar.projectKey", "publicProject")
+ .setProperty("sonar.projectName", "PublicProject");
+
+
+ orchestrator.executeBuild(publicProject);
+ }
+
+ @Test
+ public void need_user_permission_on_project_to_see_issue() {
+ SonarClient client = orchestrator.getServer().adminWsClient();
+
+ String withBrowsePermission = "with-browse-permission";
+ String withoutBrowsePermission = "without-browse-permission";
+
+ try {
+ client.userClient().create(UserParameters.create().login(withBrowsePermission).name(withBrowsePermission)
+ .password("password").passwordConfirmation("password"));
+ addUserPermission(withBrowsePermission, "privateProject", "user");
+
+ client.userClient().create(UserParameters.create().login(withoutBrowsePermission).name(withoutBrowsePermission)
+ .password("password").passwordConfirmation("password"));
+
+ // Without user permission, a user cannot see issues on the project
+ assertThat(orchestrator.getServer().wsClient(withoutBrowsePermission, "password").issueClient().find(
+ IssueQuery.create().componentRoots("privateProject")).list()).isEmpty();
+
+ // With user permission, a user can see issues on the project
+ assertThat(orchestrator.getServer().wsClient(withBrowsePermission, "password").issueClient().find(
+ IssueQuery.create().componentRoots("privateProject")).list()).isNotEmpty();
+
+ } finally {
+ client.userClient().deactivate(withBrowsePermission);
+ client.userClient().deactivate(withoutBrowsePermission);
+ }
+ }
+
+ /**
+ * SONAR-4839
+ */
+ @Test
+ public void need_user_permission_on_project_to_see_issue_changelog() {
+ SonarClient client = orchestrator.getServer().adminWsClient();
+ Issue issue = client.issueClient().find(IssueQuery.create().componentRoots("privateProject")).list().get(0);
+ client.issueClient().assign(issue.key(), "admin");
+
+ String withBrowsePermission = "with-browse-permission";
+ String withoutBrowsePermission = "without-browse-permission";
+
+ try {
+ client.userClient().create(UserParameters.create().login(withBrowsePermission).name(withBrowsePermission)
+ .password("password").passwordConfirmation("password"));
+ addUserPermission(withBrowsePermission, "privateProject", "user");
+
+ client.userClient().create(UserParameters.create().login(withoutBrowsePermission).name(withoutBrowsePermission)
+ .password("password").passwordConfirmation("password"));
+
+ // Without user permission, a user cannot see issue changelog on the project
+ try {
+ changelog(issue.key(), withoutBrowsePermission, "password");
+ fail();
+ } catch (Exception e) {
+ assertThat(e).isInstanceOf(org.sonarqube.ws.client.HttpException.class).describedAs("403");
+ }
+
+ // Without user permission, a user cannot see issues on the project
+ assertThat(changelog(issue.key(), withBrowsePermission, "password").getChangelogList()).isNotEmpty();
+
+ } finally {
+ client.userClient().deactivate(withBrowsePermission);
+ client.userClient().deactivate(withoutBrowsePermission);
+ }
+ }
+
+ /**
+ * SONAR-2447
+ */
+ @Test
+ public void need_administer_issue_permission_on_project_to_set_severity() {
+ SonarClient client = orchestrator.getServer().adminWsClient();
+ Issue issueOnPrivateProject = client.issueClient().find(IssueQuery.create().componentRoots("privateProject")).list().get(0);
+ Issue issueOnPublicProject = client.issueClient().find(IssueQuery.create().componentRoots("publicProject")).list().get(0);
+
+ String user = "user";
+
+ try {
+ client.userClient().create(UserParameters.create().login(user).name(user).password("password").passwordConfirmation("password"));
+ addUserPermission(user, "publicProject", "issueadmin");
+
+ // Without issue admin permission, a user cannot set severity on the issue
+ try {
+ orchestrator.getServer().wsClient(user, "password").issueClient().setSeverity(issueOnPrivateProject.key(), "BLOCKER");
+ fail();
+ } catch (Exception e) {
+ assertThat(e).isInstanceOf(HttpException.class).describedAs("404");
+ }
+
+ // With issue admin permission, a user can set severity on the issue
+ assertThat(orchestrator.getServer().wsClient(user, "password").issueClient().setSeverity(issueOnPublicProject.key(), "BLOCKER").severity()).isEqualTo("BLOCKER");
+
+ } finally {
+ client.userClient().deactivate(user);
+ }
+ }
+
+ /**
+ * SONAR-2447
+ */
+ @Test
+ public void need_administer_issue_permission_on_project_to_flag_as_false_positive() {
+ SonarClient client = orchestrator.getServer().adminWsClient();
+ Issue issueOnPrivateProject = client.issueClient().find(IssueQuery.create().componentRoots("privateProject")).list().get(0);
+ Issue issueOnPublicProject = client.issueClient().find(IssueQuery.create().componentRoots("publicProject")).list().get(0);
+
+ String user = "user";
+
+ try {
+ client.userClient().create(UserParameters.create().login(user).name(user).password("password").passwordConfirmation("password"));
+ addUserPermission(user, "publicProject", "issueadmin");
+
+ // Without issue admin permission, a user cannot flag an issue as false positive
+ try {
+ orchestrator.getServer().wsClient(user, "password").issueClient().doTransition(issueOnPrivateProject.key(), "falsepositive");
+ fail();
+ } catch (Exception e) {
+ assertThat(e).isInstanceOf(HttpException.class).describedAs("404");
+ }
+
+ // With issue admin permission, a user can flag an issue as false positive
+ assertThat(orchestrator.getServer().wsClient(user, "password").issueClient().doTransition(issueOnPublicProject.key(), "falsepositive").status()).isEqualTo("RESOLVED");
+
+ } finally {
+ client.userClient().deactivate(user);
+ }
+ }
+
+ /**
+ * SONAR-2447
+ */
+ @Test
+ public void need_administer_issue_permission_on_project_to_bulk_change_severity_and_false_positive() {
+ SonarClient client = orchestrator.getServer().adminWsClient();
+ Issue issueOnPrivateProject = client.issueClient().find(IssueQuery.create().componentRoots("privateProject")).list().get(0);
+ Issue issueOnPublicProject = client.issueClient().find(IssueQuery.create().componentRoots("publicProject")).list().get(0);
+
+ String user = "user";
+
+ try {
+ client.userClient().create(UserParameters.create().login(user).name(user).password("password").passwordConfirmation("password"));
+ addUserPermission(user, "privateProject", "issueadmin");
+
+ Issues.BulkChangeWsResponse response = makeBlockerAndFalsePositive(user, issueOnPrivateProject, issueOnPublicProject);
+
+ // public project but no issueadmin permission on publicProject => issue visible but not updated
+ // no user permission on privateproject => issue invisible and not updated
+ assertThat(response.getTotal()).isEqualTo(1);
+ assertThat(response.getSuccess()).isEqualTo(0);
+ assertThat(response.getIgnored()).isEqualTo(1);
+
+ addUserPermission(user, "privateProject", "user");
+ response = makeBlockerAndFalsePositive(user, issueOnPrivateProject, issueOnPublicProject);
+
+ // public project but no issueadmin permission on publicProject => unsuccessful on issueOnPublicProject
+ // user and issueadmin permission on privateproject => successful and 1 more issue visible
+ assertThat(response.getTotal()).isEqualTo(2);
+ assertThat(response.getSuccess()).isEqualTo(1);
+ assertThat(response.getIgnored()).isEqualTo(1);
+
+ addUserPermission(user, "publicProject", "issueadmin");
+ response = makeBlockerAndFalsePositive(user, issueOnPrivateProject, issueOnPublicProject);
+
+ // public and issueadmin permission on publicProject => successful on issueOnPublicProject
+ // issueOnPrivateProject already in specified state => unsuccessful
+ assertThat(response.getTotal()).isEqualTo(2);
+ assertThat(response.getSuccess()).isEqualTo(1);
+ assertThat(response.getIgnored()).isEqualTo(1);
+
+ response = makeBlockerAndFalsePositive(user, issueOnPrivateProject, issueOnPublicProject);
+
+ // issueOnPublicProject and issueOnPrivateProject already in specified state => unsuccessful
+ assertThat(response.getTotal()).isEqualTo(2);
+ assertThat(response.getSuccess()).isEqualTo(0);
+ assertThat(response.getIgnored()).isEqualTo(2);
+ } finally {
+ client.userClient().deactivate(user);
+ }
+ }
+
+ private Issues.BulkChangeWsResponse makeBlockerAndFalsePositive(String user, Issue issueOnPrivateProject, Issue issueOnPublicProject) {
+ return newUserWsClient(orchestrator, user, "password").issues()
+ .bulkChange(BulkChangeRequest.builder().setIssues(asList(issueOnPrivateProject.key(), issueOnPublicProject.key()))
+ .setSetSeverity("BLOCKER")
+ .setDoTransition("falsepositive")
+ .build());
+ }
+
+ private void addUserPermission(String login, String projectKey, String permission) {
+ tester.wsClient().permissions().addUser(
+ new AddUserWsRequest()
+ .setLogin(login)
+ .setProjectKey(projectKey)
+ .setPermission(permission));
+ }
+
+ private static Issues.ChangelogWsResponse changelog(String issueKey, String login, String password) {
+ return newUserWsClient(orchestrator, login, password).issues().changelog(issueKey);
+ }
+}
--- /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.sonarqube.tests.authorization;
+
+import com.sonar.orchestrator.Orchestrator;
+import com.sonar.orchestrator.build.SonarScanner;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.rules.RuleChain;
+import org.sonarqube.qa.util.Tester;
+import org.sonarqube.ws.WsPermissions;
+import org.sonarqube.ws.WsPermissions.Permission;
+import org.sonarqube.ws.WsPermissions.SearchTemplatesWsResponse;
+import org.sonarqube.ws.client.PostRequest;
+import org.sonarqube.ws.client.permission.AddGroupToTemplateWsRequest;
+import org.sonarqube.ws.client.permission.AddGroupWsRequest;
+import org.sonarqube.ws.client.permission.AddProjectCreatorToTemplateWsRequest;
+import org.sonarqube.ws.client.permission.AddUserToTemplateWsRequest;
+import org.sonarqube.ws.client.permission.AddUserWsRequest;
+import org.sonarqube.ws.client.permission.CreateTemplateWsRequest;
+import org.sonarqube.ws.client.permission.GroupsWsRequest;
+import org.sonarqube.ws.client.permission.RemoveGroupFromTemplateWsRequest;
+import org.sonarqube.ws.client.permission.RemoveProjectCreatorFromTemplateWsRequest;
+import org.sonarqube.ws.client.permission.RemoveUserFromTemplateWsRequest;
+import org.sonarqube.ws.client.permission.SearchTemplatesWsRequest;
+import org.sonarqube.ws.client.permission.UsersWsRequest;
+import util.ItUtils;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.tuple;
+import static util.ItUtils.projectDir;
+
+public class PermissionSearchTest {
+
+ private static final String PROJECT_KEY = "sample";
+ private static final String LOGIN = "george.orwell";
+ private static final String GROUP_NAME = "1984";
+
+ @ClassRule
+ public static Orchestrator orchestrator = AuthorizationSuite.ORCHESTRATOR;
+
+ private static Tester tester = new Tester(orchestrator)
+ // all the tests of AuthorizationSuite must disable organizations
+ .disableOrganizations();
+
+ @ClassRule
+ public static RuleChain ruleChain = RuleChain.outerRule(orchestrator).around(tester);
+
+ @BeforeClass
+ public static void analyzeProject() {
+ ItUtils.restoreProfile(orchestrator, PermissionSearchTest.class.getResource("/authorisation/one-issue-per-line-profile.xml"));
+
+ orchestrator.getServer().provisionProject(PROJECT_KEY, "Sample");
+ orchestrator.getServer().associateProjectToQualityProfile("sample", "xoo", "one-issue-per-line");
+ SonarScanner sampleProject = SonarScanner.create(projectDir("shared/xoo-sample"));
+ orchestrator.executeBuild(sampleProject);
+ createUser(LOGIN, "George Orwell");
+ createGroup(GROUP_NAME);
+ }
+
+ @Test
+ public void permission_web_services() {
+ tester.wsClient().permissions().addUser(
+ new AddUserWsRequest()
+ .setPermission("admin")
+ .setLogin(LOGIN));
+ tester.wsClient().permissions().addGroup(
+ new AddGroupWsRequest()
+ .setPermission("admin")
+ .setGroupName(GROUP_NAME));
+
+ WsPermissions.WsSearchGlobalPermissionsResponse searchGlobalPermissionsWsResponse = tester.wsClient().permissions().searchGlobalPermissions();
+ assertThat(searchGlobalPermissionsWsResponse.getPermissionsList().get(0).getKey()).isEqualTo("admin");
+ assertThat(searchGlobalPermissionsWsResponse.getPermissionsList().get(0).getUsersCount()).isEqualTo(1);
+ // by default, a group has the global admin permission
+ assertThat(searchGlobalPermissionsWsResponse.getPermissionsList().get(0).getGroupsCount()).isEqualTo(2);
+
+ WsPermissions.UsersWsResponse users = tester.wsClient().permissions()
+ .users(new UsersWsRequest().setPermission("admin"));
+ assertThat(users.getUsersList()).extracting("login").contains(LOGIN);
+
+ WsPermissions.WsGroupsResponse groupsResponse = tester.wsClient().permissions()
+ .groups(new GroupsWsRequest()
+ .setPermission("admin"));
+ assertThat(groupsResponse.getGroupsList()).extracting("name").contains(GROUP_NAME);
+ }
+
+ @Test
+ public void template_permission_web_services() {
+ WsPermissions.CreateTemplateWsResponse createTemplateWsResponse = tester.wsClient().permissions().createTemplate(
+ new CreateTemplateWsRequest()
+ .setName("my-new-template")
+ .setDescription("template-used-in-tests"));
+ assertThat(createTemplateWsResponse.getPermissionTemplate().getName()).isEqualTo("my-new-template");
+
+ tester.wsClient().permissions().addUserToTemplate(
+ new AddUserToTemplateWsRequest()
+ .setPermission("admin")
+ .setTemplateName("my-new-template")
+ .setLogin(LOGIN));
+
+ tester.wsClient().permissions().addGroupToTemplate(
+ new AddGroupToTemplateWsRequest()
+ .setPermission("admin")
+ .setTemplateName("my-new-template")
+ .setGroupName(GROUP_NAME));
+
+ tester.wsClient().permissions().addProjectCreatorToTemplate(
+ AddProjectCreatorToTemplateWsRequest.builder()
+ .setPermission("admin")
+ .setTemplateName("my-new-template")
+ .build());
+
+ SearchTemplatesWsResponse searchTemplatesWsResponse = tester.wsClient().permissions().searchTemplates(
+ new SearchTemplatesWsRequest()
+ .setQuery("my-new-template"));
+ assertThat(searchTemplatesWsResponse.getPermissionTemplates(0).getName()).isEqualTo("my-new-template");
+ assertThat(searchTemplatesWsResponse.getPermissionTemplates(0).getPermissions(0).getKey()).isEqualTo("admin");
+ assertThat(searchTemplatesWsResponse.getPermissionTemplates(0).getPermissions(0).getUsersCount()).isEqualTo(1);
+ assertThat(searchTemplatesWsResponse.getPermissionTemplates(0).getPermissions(0).getGroupsCount()).isEqualTo(1);
+ assertThat(searchTemplatesWsResponse.getPermissionTemplates(0).getPermissions(0).getWithProjectCreator()).isTrue();
+
+ tester.wsClient().permissions().removeGroupFromTemplate(
+ new RemoveGroupFromTemplateWsRequest()
+ .setPermission("admin")
+ .setTemplateName("my-new-template")
+ .setGroupName(GROUP_NAME));
+
+ tester.wsClient().permissions().removeUserFromTemplate(
+ new RemoveUserFromTemplateWsRequest()
+ .setPermission("admin")
+ .setTemplateName("my-new-template")
+ .setLogin(LOGIN));
+
+ tester.wsClient().permissions().removeProjectCreatorFromTemplate(
+ RemoveProjectCreatorFromTemplateWsRequest.builder()
+ .setPermission("admin")
+ .setTemplateName("my-new-template")
+ .build()
+ );
+
+ SearchTemplatesWsResponse clearedSearchTemplatesWsResponse = tester.wsClient().permissions().searchTemplates(
+ new SearchTemplatesWsRequest()
+ .setQuery("my-new-template"));
+ assertThat(clearedSearchTemplatesWsResponse.getPermissionTemplates(0).getPermissionsList())
+ .extracting(Permission::getUsersCount, Permission::getGroupsCount, Permission::getWithProjectCreator)
+ .hasSize(5)
+ .containsOnly(tuple(0, 0, false));
+ }
+
+ private static void createUser(String login, String name) {
+ tester.wsClient().wsConnector().call(
+ new PostRequest("api/users/create")
+ .setParam("login", login)
+ .setParam("name", name)
+ .setParam("password", "123456"));
+ }
+
+ private static void createGroup(String groupName) {
+ tester.wsClient().wsConnector().call(
+ new PostRequest("api/user_groups/create")
+ .setParam("name", groupName));
+ }
+}
--- /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.sonarqube.tests.authorization;
+
+import com.sonar.orchestrator.Orchestrator;
+import java.util.Arrays;
+import java.util.Optional;
+import org.junit.After;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.DisableOnDebug;
+import org.junit.rules.TestRule;
+import org.junit.rules.Timeout;
+import org.sonarqube.tests.Category6Suite;
+import org.sonarqube.qa.util.Tester;
+import org.sonarqube.ws.Organizations.Organization;
+import org.sonarqube.ws.WsPermissions;
+import org.sonarqube.ws.WsPermissions.CreateTemplateWsResponse;
+import org.sonarqube.ws.WsProjects.CreateWsResponse.Project;
+import org.sonarqube.ws.WsUsers.CreateWsResponse;
+import org.sonarqube.ws.client.WsClient;
+import org.sonarqube.ws.client.component.SearchProjectsRequest;
+import org.sonarqube.ws.client.permission.AddUserToTemplateWsRequest;
+import org.sonarqube.ws.client.permission.ApplyTemplateWsRequest;
+import org.sonarqube.ws.client.permission.BulkApplyTemplateWsRequest;
+import org.sonarqube.ws.client.permission.CreateTemplateWsRequest;
+import org.sonarqube.ws.client.permission.PermissionsService;
+import org.sonarqube.ws.client.permission.UsersWsRequest;
+
+import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class PermissionTemplateTest {
+ @ClassRule
+ public static final Orchestrator orchestrator = Category6Suite.ORCHESTRATOR;
+
+ @Rule
+ public TestRule safeguard = new DisableOnDebug(Timeout.seconds(300));
+ @Rule
+ public Tester tester = new Tester(orchestrator)
+ .setElasticsearchHttpPort(Category6Suite.SEARCH_HTTP_PORT);
+
+ @After
+ public void tearDown() throws Exception {
+ unlockWritesOnProjectIndices();
+ }
+
+ @Test
+ public void apply_permission_template_on_project() {
+ Organization organization = tester.organizations().generate();
+ Project project = createPrivateProject(organization);
+ CreateWsResponse.User user = tester.users().generateMember(organization);
+ CreateWsResponse.User anotherUser = tester.users().generateMember(organization);
+
+ assertThatUserDoesNotHavePermission(user, organization, project);
+ assertThatUserDoesNotHavePermission(anotherUser, organization, project);
+ assertThat(userHasAccessToIndexedProject(user, organization, project)).isTrue();
+ assertThat(userHasAccessToIndexedProject(anotherUser, organization, project)).isTrue();
+
+ // create permission template that gives read permission to "user"
+ createAndApplyTemplate(organization, project, user);
+
+ assertThatUserHasPermission(user, organization, project);
+ assertThatUserDoesNotHavePermission(anotherUser, organization, project);
+ assertThat(userHasAccessToIndexedProject(user, organization, project)).isTrue();
+ assertThat(userHasAccessToIndexedProject(anotherUser, organization, project)).isFalse();
+ }
+
+ @Test
+ public void bulk_apply_template_on_projects() {
+ Organization organization = tester.organizations().generate();
+ CreateWsResponse.User user = tester.users().generateMember(organization);
+ CreateWsResponse.User anotherUser = tester.users().generateMember(organization);
+ WsPermissions.PermissionTemplate template = createTemplate(organization).getPermissionTemplate();
+ tester.wsClient().permissions().addUserToTemplate(new AddUserToTemplateWsRequest()
+ .setOrganization(organization.getKey())
+ .setTemplateId(template.getId())
+ .setLogin(user.getLogin())
+ .setPermission("user"));
+ Project project1 = createPrivateProject(organization);
+ Project project2 = createPrivateProject(organization);
+ Project untouchedProject = createPrivateProject(organization);
+
+ tester.wsClient().permissions().bulkApplyTemplate(new BulkApplyTemplateWsRequest()
+ .setOrganization(organization.getKey())
+ .setTemplateId(template.getId())
+ .setProjects(Arrays.asList(project1.getKey(), project2.getKey())));
+
+ assertThatUserDoesNotHavePermission(anotherUser, organization, untouchedProject);
+ assertThatUserDoesNotHavePermission(anotherUser, organization, project1);
+ assertThatUserDoesNotHavePermission(anotherUser, organization, project2);
+ assertThatUserHasPermission(user, organization, project1);
+ assertThatUserHasPermission(user, organization, project2);
+ assertThatUserDoesNotHavePermission(user, organization, untouchedProject);
+ }
+
+ @Test
+ public void indexing_errors_are_recovered_when_applying_permission_template_on_project() throws Exception {
+ Organization organization = tester.organizations().generate();
+ Project project = createPrivateProject(organization);
+ CreateWsResponse.User user = tester.users().generateMember(organization);
+ CreateWsResponse.User anotherUser = tester.users().generateMember(organization);
+
+ lockWritesOnProjectIndices();
+
+ createAndApplyTemplate(organization, project, user);
+
+ assertThatUserHasPermission(user, organization, project);
+ assertThatUserDoesNotHavePermission(anotherUser, organization, project);
+ assertThat(userHasAccessToIndexedProject(user, organization, project)).isTrue();
+ // inconsistent, should be false. Waiting for ES to be updated.
+ assertThat(userHasAccessToIndexedProject(user, organization, project)).isTrue();
+
+ unlockWritesOnProjectIndices();
+
+ boolean recovered = false;
+ while (!recovered) {
+ Thread.sleep(1_000L);
+ recovered = !userHasAccessToIndexedProject(anotherUser, organization, project);
+ }
+ }
+
+ private void lockWritesOnProjectIndices() throws Exception {
+ tester.elasticsearch().lockWrites("issues");
+ tester.elasticsearch().lockWrites("projectmeasures");
+ tester.elasticsearch().lockWrites("components");
+ }
+
+ private void unlockWritesOnProjectIndices() throws Exception {
+ tester.elasticsearch().unlockWrites("issues");
+ tester.elasticsearch().unlockWrites("projectmeasures");
+ tester.elasticsearch().unlockWrites("components");
+ }
+
+ /**
+ * Gives the read access only to the specified user. All other users and groups
+ * loose their ability to see the project.
+ */
+ private void createAndApplyTemplate(Organization organization, Project project, CreateWsResponse.User user) {
+ String templateName = "For user";
+ PermissionsService service = tester.wsClient().permissions();
+ service.createTemplate(new CreateTemplateWsRequest()
+ .setOrganization(organization.getKey())
+ .setName(templateName)
+ .setDescription("Give admin permissions to single user"));
+ service.addUserToTemplate(new AddUserToTemplateWsRequest()
+ .setOrganization(organization.getKey())
+ .setLogin(user.getLogin())
+ .setPermission("user")
+ .setTemplateName(templateName));
+ service.applyTemplate(new ApplyTemplateWsRequest()
+ .setOrganization(organization.getKey())
+ .setProjectKey(project.getKey())
+ .setTemplateName(templateName));
+ }
+
+ private CreateTemplateWsResponse createTemplate(Organization organization) {
+ return tester.wsClient().permissions().createTemplate(new CreateTemplateWsRequest()
+ .setOrganization(organization.getKey())
+ .setName(randomAlphabetic(20)));
+ }
+
+ private Project createPrivateProject(Organization organization) {
+ return tester.projects().generate(organization, p -> p.setVisibility("private"));
+ }
+
+ private void assertThatUserHasPermission(CreateWsResponse.User user, Organization organization, Project project) {
+ assertThat(hasBrowsePermission(user, organization, project)).isTrue();
+ }
+
+ private void assertThatUserDoesNotHavePermission(CreateWsResponse.User user, Organization organization, Project project) {
+ assertThat(hasBrowsePermission(user, organization, project)).isFalse();
+ }
+
+ private boolean userHasAccessToIndexedProject(CreateWsResponse.User user, Organization organization, Project project) {
+ SearchProjectsRequest request = SearchProjectsRequest.builder().setOrganization(organization.getKey()).build();
+ WsClient userSession = tester.as(user.getLogin()).wsClient();
+ return userSession.components().searchProjects(request)
+ .getComponentsList().stream()
+ .anyMatch(c -> c.getKey().equals(project.getKey()));
+ }
+
+ private boolean hasBrowsePermission(CreateWsResponse.User user, Organization organization, Project project) {
+ UsersWsRequest request = new UsersWsRequest()
+ .setOrganization(organization.getKey())
+ .setProjectKey(project.getKey())
+ .setPermission("user");
+ WsPermissions.UsersWsResponse response = tester.wsClient().permissions().users(request);
+ Optional<WsPermissions.User> found = response.getUsersList().stream()
+ .filter(u -> user.getLogin().equals(u.getLogin()))
+ .findFirst();
+ return found.isPresent();
+ }
+}
--- /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.sonarqube.tests.authorization;
+
+import com.sonar.orchestrator.Orchestrator;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.rules.RuleChain;
+import org.sonarqube.qa.util.Tester;
+import org.sonarqube.ws.WsProjects.CreateWsResponse.Project;
+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.permission.RemoveUserWsRequest;
+import org.sonarqube.ws.client.project.CreateRequest;
+import util.ItUtils;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static util.selenium.Selenese.runSelenese;
+
+public class ProvisioningPermissionTest {
+
+ private static final String PASSWORD = "password";
+ private static final String ADMIN_WITH_PROVISIONING = "admin-with-provisioning";
+ private static final String ADMIN_WITHOUT_PROVISIONING = "admin-without-provisioning";
+ private static final String USER_WITH_PROVISIONING = "user-with-provisioning";
+ private static final String USER_WITHOUT_PROVISIONING = "user-without-provisioning";
+
+ @ClassRule
+ public static Orchestrator orchestrator = AuthorizationSuite.ORCHESTRATOR;
+
+ private static Tester tester = new Tester(orchestrator)
+ // all the tests of AuthorizationSuite must disable organizations
+ .disableOrganizations();
+
+ @ClassRule
+ public static RuleChain ruleChain = RuleChain.outerRule(orchestrator).around(tester);
+
+ @BeforeClass
+ public static void init() {
+ // remove default permission "provisioning" from anyone();
+ tester.wsClient().permissions().removeGroup(new RemoveGroupWsRequest().setGroupName("anyone").setPermission("provisioning"));
+
+ tester.users().generate(u -> u.setLogin(ADMIN_WITH_PROVISIONING).setPassword(PASSWORD));
+ addUserPermission(ADMIN_WITH_PROVISIONING, "admin");
+ addUserPermission(ADMIN_WITH_PROVISIONING, "provisioning");
+
+ tester.users().generate(u -> u.setLogin(ADMIN_WITHOUT_PROVISIONING).setPassword(PASSWORD));
+ addUserPermission(ADMIN_WITHOUT_PROVISIONING, "admin");
+ removeUserPermission(ADMIN_WITHOUT_PROVISIONING, "provisioning");
+
+ tester.users().generate(u -> u.setLogin(USER_WITH_PROVISIONING).setPassword(PASSWORD));
+ addUserPermission(USER_WITH_PROVISIONING, "provisioning");
+
+ tester.users().generate(u -> u.setLogin(USER_WITHOUT_PROVISIONING).setPassword(PASSWORD));
+ removeUserPermission(USER_WITHOUT_PROVISIONING, "provisioning");
+ }
+
+ @AfterClass
+ public static void restoreData() throws Exception {
+ tester.wsClient().permissions().addGroup(new AddGroupWsRequest().setGroupName("anyone").setPermission("provisioning"));
+ }
+
+ /**
+ * SONAR-3871
+ * SONAR-4709
+ */
+ @Test
+ public void organization_administrator_cannot_provision_project_if_he_does_not_have_provisioning_permission() {
+ runSelenese(orchestrator, "/authorisation/ProvisioningPermissionTest/should-not-be-able-to-provision-project.html");
+ }
+
+ /**
+ * SONAR-3871
+ * SONAR-4709
+ */
+ @Test
+ public void organization_administrator_can_provision_project_if_he_has_provisioning_permission() {
+ runSelenese(orchestrator, "/authorisation/ProvisioningPermissionTest/should-be-able-to-provision-project.html");
+ }
+
+ /**
+ * SONAR-3871
+ * SONAR-4709
+ */
+ @Test
+ public void user_can_provision_project_through_ws_if_he_has_provisioning_permission() {
+ final String newKey = "new-project";
+ final String newName = "New Project";
+
+ Project created = tester.as(USER_WITH_PROVISIONING, PASSWORD).wsClient().projects()
+ .create(CreateRequest.builder().setKey(newKey).setName(newName).build())
+ .getProject();
+
+ assertThat(created).isNotNull();
+ assertThat(created.getKey()).isEqualTo(newKey);
+ assertThat(created.getName()).isEqualTo(newName);
+ }
+
+ /**
+ * SONAR-3871
+ * SONAR-4709
+ */
+ @Test
+ public void user_cannot_provision_project_through_ws_if_he_does_not_have_provisioning_permission() {
+ ItUtils.expectForbiddenError(() -> {
+ tester.as(USER_WITHOUT_PROVISIONING, PASSWORD).wsClient().projects()
+ .create(CreateRequest.builder().setKey("new-project").setName("New Project").build())
+ .getProject();
+ });
+ }
+
+ private static void addUserPermission(String login, String permission) {
+ tester.wsClient().permissions().addUser(new AddUserWsRequest().setLogin(login).setPermission(permission));
+ }
+
+ private static void removeUserPermission(String login, String permission) {
+ tester.wsClient().permissions().removeUser(new RemoveUserWsRequest().setLogin(login).setPermission(permission));
+ }
+}
--- /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.sonarqube.tests.authorization;
+
+import com.sonar.orchestrator.Orchestrator;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonarqube.qa.util.Tester;
+import org.sonarqube.ws.client.permission.AddUserWsRequest;
+import org.sonarqube.ws.client.qualityprofile.CreateRequest;
+import util.selenium.Selenese;
+
+import static util.ItUtils.runProjectAnalysis;
+
+/**
+ * SONAR-4210
+ */
+public class QualityProfileAdminPermissionTest {
+
+ @ClassRule
+ public static Orchestrator orchestrator = AuthorizationSuite.ORCHESTRATOR;
+
+ @Rule
+ public Tester tester = new Tester(orchestrator)
+ // all the tests of AuthorizationSuite must disable organizations
+ .disableOrganizations();
+
+ @Test
+ public void permission_should_grant_access_to_profile() {
+ runProjectAnalysis(orchestrator, "shared/xoo-sample");
+
+ tester.users().generate(u -> u.setLogin("not_profileadm").setPassword("userpwd"));
+ tester.users().generate(u -> u.setLogin("profileadm").setPassword("papwd"));
+ tester.wsClient().permissions().addUser(new AddUserWsRequest().setLogin("profileadm").setPermission("profileadmin"));
+ createProfile("xoo", "foo");
+
+ Selenese.runSelenese(orchestrator,
+ // Verify normal user is not allowed to do any modification
+ "/authorisation/QualityProfileAdminPermissionTest/normal-user.html",
+ // Verify profile admin is allowed to do modifications
+ "/authorisation/QualityProfileAdminPermissionTest/profile-admin.html");
+ }
+
+ private void createProfile(String language, String name) {
+ tester.wsClient().qualityProfiles().create(CreateRequest.builder()
+ .setLanguage(language)
+ .setName(name)
+ .build());
+ }
+
+}
--- /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.sonarqube.tests.authorization;
+
+import com.sonar.orchestrator.Orchestrator;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonarqube.qa.util.Tester;
+import org.sonarqube.ws.client.GetRequest;
+import org.sonarqube.ws.client.WsRequest;
+import org.sonarqube.ws.client.WsResponse;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class SystemPasscodeTest {
+
+ static final String VALID_PASSCODE = "123456";
+ private static final String INVALID_PASSCODE = "not" + VALID_PASSCODE;
+ private static final String PASSCODE_HEADER = "X-Sonar-Passcode";
+
+ @ClassRule
+ public static Orchestrator orchestrator = AuthorizationSuite.ORCHESTRATOR;
+
+ @Rule
+ public Tester tester = new Tester(orchestrator)
+ // all the tests of AuthorizationSuite must disable organizations
+ .disableOrganizations();
+
+ @Test
+ public void system_access_is_granted_if_valid_passcode_is_sent_through_http_header() {
+ WsRequest request = newRequest()
+ .setHeader(PASSCODE_HEADER, VALID_PASSCODE);
+
+ WsResponse response = tester.asAnonymous().wsClient().wsConnector().call(request);
+ assertThat(response.code()).isEqualTo(200);
+ }
+
+ @Test
+ public void system_access_is_rejected_if_invalid_passcode_is_sent_through_http_header() {
+ WsRequest request = newRequest()
+ .setHeader(PASSCODE_HEADER, INVALID_PASSCODE);
+
+ WsResponse response = tester.asAnonymous().wsClient().wsConnector().call(request);
+ assertThat(response.code()).isEqualTo(401);
+ }
+
+ @Test
+ public void system_access_is_rejected_if_passcode_is_not_sent() {
+ WsRequest request = newRequest();
+
+ WsResponse response = tester.asAnonymous().wsClient().wsConnector().call(request);
+ assertThat(response.code()).isEqualTo(401);
+ }
+
+ private static GetRequest newRequest() {
+ return new GetRequest("api/system_passcode/check");
+ }
+}
* @deprecated replaced by {@link Tester}
*/
@Deprecated
-
public class Groups {
private List<Group> groups;
import javax.annotation.Nullable;
import org.junit.rules.ExternalResource;
import org.sonarqube.qa.util.Tester;
-import org.sonarqube.ws.Organizations;
import org.sonarqube.ws.WsUsers;
import org.sonarqube.ws.client.GetRequest;
import org.sonarqube.ws.client.PostRequest;
createUser(login, login, null, password);
}
- public WsUsers.CreateWsResponse.User createAdministrator(Organizations.Organization organization, String password) {
- WsUsers.CreateWsResponse.User user = generate(p -> p.setPassword(password));
- adminWsClient.organizations().addMember(organization.getKey(), user.getLogin());
- forOrganization(organization.getKey()).associateGroupsToUser(user.getLogin(), "Owners");
- return user;
- }
-
/**
* Create a new admin user with random login, having password same as login
*/
return login;
}
- /**
- * Create a new root user with random login, having password same as login
- */
- public String createRootUser() {
- String login = randomAlphabetic(10).toLowerCase();
- return createRootUser(login, login);
- }
-
- public String createRootUser(String login, String password) {
- createUser(login, password);
- setRoot(login);
- return login;
- }
-
public void setRoot(String login) {
adminWsClient().roots().setRoot(login);
}
- public void unsetRoot(String login) {
- adminWsClient().roots().unsetRoot(login);
- }
-
public Optional<Users.User> getUserByLogin(String login) {
return FluentIterable.from(getUsers().getUsers()).firstMatch(new MatchUserLogin(login));
}
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head profile="http://selenium-ide.openqa.org/profiles/test-case">
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
- <title>should_create</title>
-</head>
-<body>
-<table cellpadding="1" cellspacing="1" border="1">
- <tbody>
- <tr>
- <td>open</td>
- <td>/sessions/new</td>
- <td></td>
- </tr>
- <tr>
- <td>type</td>
- <td>password</td>
- <td>root-user</td>
- </tr>
- <tr>
- <td>type</td>
- <td>login</td>
- <td>root-user</td>
- </tr>
- <tr>
- <td>clickAndWait</td>
- <td>name=commit</td>
- <td></td>
- </tr>
- <tr>
- <td>open</td>
- <td>/permission_templates</td>
- <td></td>
- </tr>
- <tr>
- <td>waitForElementPresent</td>
- <td>css=.page-actions button</td>
- <td></td>
- </tr>
- <tr>
- <td>click</td>
- <td>css=.page-actions button</td>
- <td></td>
- </tr>
- <tr>
- <td>waitForElementPresent</td>
- <td>css=#permission-template-name</td>
- <td></td>
- </tr>
- <tr>
- <td>type</td>
- <td>css=#permission-template-name</td>
- <td>Custom</td>
- </tr>
- <tr>
- <td>type</td>
- <td>css=#permission-template-description</td>
- <td>Description</td>
- </tr>
- <tr>
- <td>type</td>
- <td>css=#permission-template-project-key-pattern</td>
- <td>.*</td>
- </tr>
- <tr>
- <td>click</td>
- <td>css=#permission-template-submit</td>
- <td></td>
- </tr>
- <tr>
- <td>waitForElementPresent</td>
- <td>css=tr[data-name="Custom"]</td>
- <td></td>
- </tr>
- <tr>
- <td>assertText</td>
- <td>css=tr[data-name="Custom"] .js-name</td>
- <td>*Custom*</td>
- </tr>
- <tr>
- <td>assertText</td>
- <td>css=tr[data-name="Custom"] .js-description</td>
- <td>*Description*</td>
- </tr>
- <tr>
- <td>assertText</td>
- <td>css=tr[data-name="Custom"] .js-project-key-pattern</td>
- <td>*.*</td>
- </tr>
- </tbody>
-</table>
-</body>
-</html>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head profile="http://selenium-ide.openqa.org/profiles/test-case">
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
- <title>should_display_page</title>
-</head>
-<body>
-<table cellpadding="1" cellspacing="1" border="1">
- <tbody>
- <tr>
- <td>open</td>
- <td>/sessions/new</td>
- <td></td>
-</tr>
-<tr>
- <td>type</td>
- <td>login</td>
- <td>admin</td>
-</tr>
-<tr>
- <td>type</td>
- <td>password</td>
- <td>admin</td>
-</tr>
-<tr>
- <td>clickAndWait</td>
- <td>commit</td>
- <td></td>
-</tr>
-<tr>
- <td>open</td>
- <td>/permission_templates</td>
- <td></td>
-</tr>
-<tr>
- <td>waitForElementPresent</td>
- <td>css=tr[data-id="default_template"]</td>
- <td></td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>css=tr[data-id="default_template"] .js-name</td>
- <td>*Default template*</td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>css=tr[data-id="default_template"] .js-defaults</td>
- <td>*Projects*</td>
-</tr>
-<tr>
- <td>assertText</td>
- <td>css=tr[data-id="default_template"] .js-description</td>
- <td>*This permission template will be used*</td>
-</tr>
-<tr>
- <td>assertElementPresent</td>
- <td>css=td[data-permission="user"]</td>
- <td></td>
-</tr>
-<tr>
- <td>assertElementPresent</td>
- <td>css=td[data-permission="codeviewer"]</td>
- <td></td>
-</tr>
-<tr>
- <td>assertElementPresent</td>
- <td>css=td[data-permission="issueadmin"]</td>
- <td></td>
-</tr>
-<tr>
- <td>assertElementPresent</td>
- <td>css=td[data-permission="admin"]</td>
- <td></td>
-</tr>
-<tr>
- <td>assertElementPresent</td>
- <td>css=td[data-permission="scan"]</td>
- <td></td>
-</tr>
-</tbody>
-</table>
-</body>
-</html>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head profile="http://selenium-ide.openqa.org/profiles/test-case">
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
- <title>should_manage_project_creators</title>
-</head>
-<body>
-<table cellpadding="1" cellspacing="1" border="1">
- <tbody>
-
- <tr>
- <td>open</td>
- <td>/sessions/new</td>
- <td></td>
- </tr>
- <tr>
- <td>type</td>
- <td>password</td>
- <td>admin-user</td>
- </tr>
- <tr>
- <td>type</td>
- <td>login</td>
- <td>admin-user</td>
- </tr>
- <tr>
- <td>clickAndWait</td>
- <td>name=commit</td>
- <td></td>
- </tr>
- <tr>
- <td>open</td>
- <td>/permission_templates</td>
- <td></td>
- </tr>
- <tr>
- <td>waitForElementPresent</td>
- <td>css=td[data-permission="user"]</td>
- <td></td>
- </tr>
- <tr>
- <td>click</td>
- <td>css=td[data-permission="user"] .js-update-users</td>
- <td></td>
- </tr>
- <tr>
- <td>waitForElementPresent</td>
- <td>css=#grant-to-project-creators</td>
- <td></td>
- </tr>
- <tr>
- <td>assertElementPresent</td>
- <td>css=#grant-to-project-creators:not(:checked)</td>
- <td></td>
- </tr>
- <tr>
- <td>click</td>
- <td>css=#grant-to-project-creators</td>
- <td></td>
- </tr>
- <tr>
- <td>click</td>
- <td>css=.js-modal-close</td>
- <td></td>
- </tr>
- <tr>
- <td>waitForElementPresent</td>
- <td>css=td[data-permission="user"] .js-project-creators</td>
- <td></td>
- </tr>
- <tr>
- <td>click</td>
- <td>css=td[data-permission="user"] .js-update-users</td>
- <td></td>
- </tr>
- <tr>
- <td>waitForElementPresent</td>
- <td>css=#grant-to-project-creators</td>
- <td></td>
- </tr>
- <tr>
- <td>assertElementPresent</td>
- <td>css=#grant-to-project-creators:checked</td>
- <td></td>
- </tr>
- <tr>
- <td>click</td>
- <td>css=#grant-to-project-creators</td>
- <td></td>
- </tr>
- <tr>
- <td>click</td>
- <td>css=.js-modal-close</td>
- <td></td>
- </tr>
- <tr>
- <td>waitForElementNotPresent</td>
- <td>css=td[data-permission="user"] .js-project-creators</td>
- <td></td>
- </tr>
- </tbody>
-</table>
-</body>
-</html>