]> source.dussan.org Git - sonarqube.git/commitdiff
Add category authorization to integration tests
authorSimon Brandhof <simon.brandhof@sonarsource.com>
Sat, 11 Nov 2017 17:21:25 +0000 (18:21 +0100)
committerEric Hartmann <hartmann.eric@gmail.Com>
Tue, 14 Nov 2017 12:10:17 +0000 (13:10 +0100)
25 files changed:
cix.sh
tests/src/test/java/org/sonarqube/tests/Category1Suite.java
tests/src/test/java/org/sonarqube/tests/Category5Suite.java
tests/src/test/java/org/sonarqube/tests/Category6Suite.java
tests/src/test/java/org/sonarqube/tests/authorisation/ExecuteAnalysisPermissionTest.java [deleted file]
tests/src/test/java/org/sonarqube/tests/authorisation/IssuePermissionTest.java [deleted file]
tests/src/test/java/org/sonarqube/tests/authorisation/PermissionSearchTest.java [deleted file]
tests/src/test/java/org/sonarqube/tests/authorisation/PermissionTemplateTest.java [deleted file]
tests/src/test/java/org/sonarqube/tests/authorisation/PermissionTemplatesPageTest.java [deleted file]
tests/src/test/java/org/sonarqube/tests/authorisation/ProvisioningPermissionTest.java [deleted file]
tests/src/test/java/org/sonarqube/tests/authorisation/QualityProfileAdminPermissionTest.java [deleted file]
tests/src/test/java/org/sonarqube/tests/authorisation/SystemPasscodeTest.java [deleted file]
tests/src/test/java/org/sonarqube/tests/authorization/AuthorizationSuite.java [new file with mode: 0644]
tests/src/test/java/org/sonarqube/tests/authorization/ExecuteAnalysisPermissionTest.java [new file with mode: 0644]
tests/src/test/java/org/sonarqube/tests/authorization/IssuePermissionTest.java [new file with mode: 0644]
tests/src/test/java/org/sonarqube/tests/authorization/PermissionSearchTest.java [new file with mode: 0644]
tests/src/test/java/org/sonarqube/tests/authorization/PermissionTemplateTest.java [new file with mode: 0644]
tests/src/test/java/org/sonarqube/tests/authorization/ProvisioningPermissionTest.java [new file with mode: 0644]
tests/src/test/java/org/sonarqube/tests/authorization/QualityProfileAdminPermissionTest.java [new file with mode: 0644]
tests/src/test/java/org/sonarqube/tests/authorization/SystemPasscodeTest.java [new file with mode: 0644]
tests/src/test/java/util/user/Groups.java
tests/src/test/java/util/user/UserRule.java
tests/src/test/resources/authorisation/PermissionTemplatesPageTest/should_create.html [deleted file]
tests/src/test/resources/authorisation/PermissionTemplatesPageTest/should_display_page.html [deleted file]
tests/src/test/resources/authorisation/PermissionTemplatesPageTest/should_manage_project_creators.html [deleted file]

diff --git a/cix.sh b/cix.sh
index 62b06de33c9fa262a23bb32426d450bff3045533..2830bc82ab4f75f8a45fa6a77bbe1d305240003e 100755 (executable)
--- a/cix.sh
+++ b/cix.sh
@@ -33,6 +33,7 @@ case "$RUN_ACTIVITY" in
       case "$CATEGORY_GROUP" in
         Category1)
           CATEGORY=Category1 && runCategory
+          CATEGORY=authorization && runCategory
           CATEGORY=measure && runCategory
           CATEGORY=source && runCategory
           ;;
index 8fbbe37567da154a9b8dd8875bff92323e8e47f0..2cc1da3ed4a100e16007573b85f0c4b635c12ed6 100644 (file)
@@ -23,11 +23,6 @@ import com.sonar.orchestrator.Orchestrator;
 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;
@@ -67,12 +62,6 @@ import static util.ItUtils.xooPlugin;
   QualityGateUiTest.class,
   QualityGateNotificationTest.class,
   QualityGateOnRatingMeasuresTest.class,
-  // authorisation
-  ExecuteAnalysisPermissionTest.class,
-  IssuePermissionTest.class,
-  PermissionSearchTest.class,
-  ProvisioningPermissionTest.class,
-  QualityProfileAdminPermissionTest.class,
   // measure
   ProjectsPageTest.class
 })
index 85125797af0209bd7a4558aac214ea81622db297..a5bc316c09f6b7953f26da36393a04bb76b01ce2 100644 (file)
@@ -22,10 +22,10 @@ package org.sonarqube.tests;
 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;
@@ -36,7 +36,6 @@ import org.sonarqube.tests.settings.SettingsTestRestartingOrchestrator;
 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;
@@ -72,8 +71,7 @@ import org.sonarqube.tests.user.UserEsResilienceTest;
   IssueCreationDatePluginChangedTest.class,
 
   // elasticsearch
-  StartupIndexationTest.class,
-  SystemPasscodeTest.class
+  StartupIndexationTest.class
 })
 public class Category5Suite {
 
index a7cec719ffc3763bac643c53236d703dc8ee92a3..aca8c327b4ceb93da67b06c3e1805097d16cb83b 100644 (file)
@@ -25,7 +25,7 @@ import java.net.InetAddress;
 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;
diff --git a/tests/src/test/java/org/sonarqube/tests/authorisation/ExecuteAnalysisPermissionTest.java b/tests/src/test/java/org/sonarqube/tests/authorisation/ExecuteAnalysisPermissionTest.java
deleted file mode 100644 (file)
index 65f1a52..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * 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");
-  }
-}
diff --git a/tests/src/test/java/org/sonarqube/tests/authorisation/IssuePermissionTest.java b/tests/src/test/java/org/sonarqube/tests/authorisation/IssuePermissionTest.java
deleted file mode 100644 (file)
index 21f39e7..0000000
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * 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);
-  }
-}
diff --git a/tests/src/test/java/org/sonarqube/tests/authorisation/PermissionSearchTest.java b/tests/src/test/java/org/sonarqube/tests/authorisation/PermissionSearchTest.java
deleted file mode 100644 (file)
index 7698aa3..0000000
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * 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));
-  }
-}
diff --git a/tests/src/test/java/org/sonarqube/tests/authorisation/PermissionTemplateTest.java b/tests/src/test/java/org/sonarqube/tests/authorisation/PermissionTemplateTest.java
deleted file mode 100644 (file)
index b0a82a8..0000000
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * 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();
-  }
-}
diff --git a/tests/src/test/java/org/sonarqube/tests/authorisation/PermissionTemplatesPageTest.java b/tests/src/test/java/org/sonarqube/tests/authorisation/PermissionTemplatesPageTest.java
deleted file mode 100644 (file)
index f94a50b..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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");
-  }
-}
diff --git a/tests/src/test/java/org/sonarqube/tests/authorisation/ProvisioningPermissionTest.java b/tests/src/test/java/org/sonarqube/tests/authorisation/ProvisioningPermissionTest.java
deleted file mode 100644 (file)
index a71af6e..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * 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));
-  }
-}
diff --git a/tests/src/test/java/org/sonarqube/tests/authorisation/QualityProfileAdminPermissionTest.java b/tests/src/test/java/org/sonarqube/tests/authorisation/QualityProfileAdminPermissionTest.java
deleted file mode 100644 (file)
index b96d5cc..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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());
-  }
-
-}
diff --git a/tests/src/test/java/org/sonarqube/tests/authorisation/SystemPasscodeTest.java b/tests/src/test/java/org/sonarqube/tests/authorisation/SystemPasscodeTest.java
deleted file mode 100644 (file)
index b7fabd3..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * 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");
-  }
-}
diff --git a/tests/src/test/java/org/sonarqube/tests/authorization/AuthorizationSuite.java b/tests/src/test/java/org/sonarqube/tests/authorization/AuthorizationSuite.java
new file mode 100644 (file)
index 0000000..cee2d04
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * 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();
+
+}
diff --git a/tests/src/test/java/org/sonarqube/tests/authorization/ExecuteAnalysisPermissionTest.java b/tests/src/test/java/org/sonarqube/tests/authorization/ExecuteAnalysisPermissionTest.java
new file mode 100644 (file)
index 0000000..78f8cfc
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * 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");
+  }
+}
diff --git a/tests/src/test/java/org/sonarqube/tests/authorization/IssuePermissionTest.java b/tests/src/test/java/org/sonarqube/tests/authorization/IssuePermissionTest.java
new file mode 100644 (file)
index 0000000..910bb61
--- /dev/null
@@ -0,0 +1,277 @@
+/*
+ * 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);
+  }
+}
diff --git a/tests/src/test/java/org/sonarqube/tests/authorization/PermissionSearchTest.java b/tests/src/test/java/org/sonarqube/tests/authorization/PermissionSearchTest.java
new file mode 100644 (file)
index 0000000..703544e
--- /dev/null
@@ -0,0 +1,182 @@
+/*
+ * 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));
+  }
+}
diff --git a/tests/src/test/java/org/sonarqube/tests/authorization/PermissionTemplateTest.java b/tests/src/test/java/org/sonarqube/tests/authorization/PermissionTemplateTest.java
new file mode 100644 (file)
index 0000000..66b925d
--- /dev/null
@@ -0,0 +1,212 @@
+/*
+ * 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();
+  }
+}
diff --git a/tests/src/test/java/org/sonarqube/tests/authorization/ProvisioningPermissionTest.java b/tests/src/test/java/org/sonarqube/tests/authorization/ProvisioningPermissionTest.java
new file mode 100644 (file)
index 0000000..27c5b61
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * 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));
+  }
+}
diff --git a/tests/src/test/java/org/sonarqube/tests/authorization/QualityProfileAdminPermissionTest.java b/tests/src/test/java/org/sonarqube/tests/authorization/QualityProfileAdminPermissionTest.java
new file mode 100644 (file)
index 0000000..97d784d
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * 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());
+  }
+
+}
diff --git a/tests/src/test/java/org/sonarqube/tests/authorization/SystemPasscodeTest.java b/tests/src/test/java/org/sonarqube/tests/authorization/SystemPasscodeTest.java
new file mode 100644 (file)
index 0000000..5ec92f4
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * 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");
+  }
+}
index 8aa1f63c869f1ea06b6bd1c7608f2281dfb8221d..32ef4f27250c996e92af1afffdf739e2feef0734 100644 (file)
@@ -27,7 +27,6 @@ import org.sonarqube.qa.util.Tester;
  * @deprecated replaced by {@link Tester}
  */
 @Deprecated
-
 public class Groups {
 
   private List<Group> groups;
index 994e4a0c2e71409a358b36d9081acf1aeb5c01a6..beb07e114d23bb12cc516f9649d3a384cdb50d65 100644 (file)
@@ -31,7 +31,6 @@ import javax.annotation.Nonnull;
 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;
@@ -139,13 +138,6 @@ public class UserRule extends ExternalResource implements GroupManagement {
     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
    */
@@ -161,28 +153,10 @@ public class UserRule extends ExternalResource implements GroupManagement {
     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));
   }
diff --git a/tests/src/test/resources/authorisation/PermissionTemplatesPageTest/should_create.html b/tests/src/test/resources/authorisation/PermissionTemplatesPageTest/should_create.html
deleted file mode 100644 (file)
index 5265dab..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-<?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=&quot;Custom&quot;]</td>
-    <td></td>
-  </tr>
-  <tr>
-    <td>assertText</td>
-    <td>css=tr[data-name=&quot;Custom&quot;] .js-name</td>
-    <td>*Custom*</td>
-  </tr>
-  <tr>
-    <td>assertText</td>
-    <td>css=tr[data-name=&quot;Custom&quot;] .js-description</td>
-    <td>*Description*</td>
-  </tr>
-  <tr>
-    <td>assertText</td>
-    <td>css=tr[data-name=&quot;Custom&quot;] .js-project-key-pattern</td>
-    <td>*.*</td>
-  </tr>
-  </tbody>
-</table>
-</body>
-</html>
diff --git a/tests/src/test/resources/authorisation/PermissionTemplatesPageTest/should_display_page.html b/tests/src/test/resources/authorisation/PermissionTemplatesPageTest/should_display_page.html
deleted file mode 100644 (file)
index 2e05e15..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-<?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=&quot;default_template&quot;]</td>
-       <td></td>
-</tr>
-<tr>
-       <td>assertText</td>
-       <td>css=tr[data-id=&quot;default_template&quot;] .js-name</td>
-       <td>*Default template*</td>
-</tr>
-<tr>
-       <td>assertText</td>
-       <td>css=tr[data-id=&quot;default_template&quot;] .js-defaults</td>
-       <td>*Projects*</td>
-</tr>
-<tr>
-       <td>assertText</td>
-       <td>css=tr[data-id=&quot;default_template&quot;] .js-description</td>
-       <td>*This permission template will be used*</td>
-</tr>
-<tr>
-       <td>assertElementPresent</td>
-       <td>css=td[data-permission=&quot;user&quot;]</td>
-       <td></td>
-</tr>
-<tr>
-       <td>assertElementPresent</td>
-       <td>css=td[data-permission=&quot;codeviewer&quot;]</td>
-       <td></td>
-</tr>
-<tr>
-       <td>assertElementPresent</td>
-       <td>css=td[data-permission=&quot;issueadmin&quot;]</td>
-       <td></td>
-</tr>
-<tr>
-       <td>assertElementPresent</td>
-       <td>css=td[data-permission=&quot;admin&quot;]</td>
-       <td></td>
-</tr>
-<tr>
-       <td>assertElementPresent</td>
-       <td>css=td[data-permission=&quot;scan&quot;]</td>
-       <td></td>
-</tr>
-</tbody>
-</table>
-</body>
-</html>
diff --git a/tests/src/test/resources/authorisation/PermissionTemplatesPageTest/should_manage_project_creators.html b/tests/src/test/resources/authorisation/PermissionTemplatesPageTest/should_manage_project_creators.html
deleted file mode 100644 (file)
index d6226cb..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-<?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=&quot;user&quot;]</td>
-    <td></td>
-  </tr>
-  <tr>
-    <td>click</td>
-    <td>css=td[data-permission=&quot;user&quot;] .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=&quot;user&quot;] .js-project-creators</td>
-    <td></td>
-  </tr>
-  <tr>
-    <td>click</td>
-    <td>css=td[data-permission=&quot;user&quot;] .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=&quot;user&quot;] .js-project-creators</td>
-    <td></td>
-  </tr>
-  </tbody>
-</table>
-</body>
-</html>