]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-7874 api/plugins/* require administer system permission
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Mon, 18 Jul 2016 13:49:35 +0000 (15:49 +0200)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Mon, 18 Jul 2016 14:38:14 +0000 (16:38 +0200)
server/sonar-server/src/main/java/org/sonar/server/plugins/ws/AvailableAction.java
server/sonar-server/src/main/java/org/sonar/server/plugins/ws/InstalledAction.java
server/sonar-server/src/main/java/org/sonar/server/plugins/ws/PendingAction.java
server/sonar-server/src/main/java/org/sonar/server/plugins/ws/UpdatesAction.java
server/sonar-server/src/test/java/org/sonar/server/plugins/ws/AvailableActionTest.java
server/sonar-server/src/test/java/org/sonar/server/plugins/ws/InstalledActionTest.java
server/sonar-server/src/test/java/org/sonar/server/plugins/ws/PendingActionTest.java
server/sonar-server/src/test/java/org/sonar/server/plugins/ws/PluginsWsMediumTest.java
server/sonar-server/src/test/java/org/sonar/server/plugins/ws/UpdatesActionTest.java

index 1fada70fc3131900ce1975be9e7e87d1315df8d3..47d03fab07ba23dda4fc2242127b32000f69cf7f 100644 (file)
@@ -28,9 +28,11 @@ import org.sonar.api.server.ws.Response;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.api.utils.text.JsonWriter;
 import org.sonar.server.plugins.UpdateCenterMatrixFactory;
+import org.sonar.server.user.UserSession;
 import org.sonar.updatecenter.common.PluginUpdate;
 import org.sonar.updatecenter.common.UpdateCenter;
 
+import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
 import static org.sonar.server.plugins.ws.PluginWSCommons.NAME_KEY_PLUGIN_UPDATE_ORDERING;
 
 public class AvailableAction implements PluginsWsAction {
@@ -38,10 +40,12 @@ public class AvailableAction implements PluginsWsAction {
   private static final boolean DO_NOT_FORCE_REFRESH = false;
   private static final String ARRAY_PLUGINS = "plugins";
 
+  private final UserSession userSession;
   private final UpdateCenterMatrixFactory updateCenterFactory;
   private final PluginWSCommons pluginWSCommons;
 
-  public AvailableAction(UpdateCenterMatrixFactory updateCenterFactory, PluginWSCommons pluginWSCommons) {
+  public AvailableAction(UserSession userSession, UpdateCenterMatrixFactory updateCenterFactory, PluginWSCommons pluginWSCommons) {
+    this.userSession = userSession;
     this.updateCenterFactory = updateCenterFactory;
     this.pluginWSCommons = pluginWSCommons;
   }
@@ -59,7 +63,8 @@ public class AvailableAction implements PluginsWsAction {
         "<li>INCOMPATIBLE: plugin is not compatible with current SonarQube instance.</li>" +
         "<li>REQUIRES_SYSTEM_UPGRADE: plugin requires SonarQube to be upgraded before being installed.</li>" +
         "<li>DEPS_REQUIRE_SYSTEM_UPGRADE: at least one plugin on which the plugin is dependent requires SonarQube to be upgraded.</li>" +
-        "</ul>")
+        "</ul>.<br/>" +
+        "Require 'Administer System' permission.")
       .setSince("5.2")
       .setHandler(this)
       .setResponseExample(Resources.getResource(this.getClass(), "example-available_plugins.json"));
@@ -67,6 +72,7 @@ public class AvailableAction implements PluginsWsAction {
 
   @Override
   public void handle(Request request, Response response) throws Exception {
+    userSession.checkPermission(SYSTEM_ADMIN);
     JsonWriter jsonWriter = response.newJsonWriter();
     jsonWriter.beginObject();
 
@@ -93,7 +99,7 @@ public class AvailableAction implements PluginsWsAction {
     return ImmutableSortedSet.copyOf(
       NAME_KEY_PLUGIN_UPDATE_ORDERING,
       updateCenter.findAvailablePlugins()
-      );
+    );
   }
 
 }
index 4c1034713b6dd7fd55f4e7da76db00238dc07ecb..bd81e9dd6d4d2bbc0ef8d58e4274a3e0ffab9806 100644 (file)
@@ -32,11 +32,13 @@ import org.sonar.api.utils.text.JsonWriter;
 import org.sonar.core.platform.PluginInfo;
 import org.sonar.server.plugins.ServerPluginRepository;
 import org.sonar.server.plugins.UpdateCenterMatrixFactory;
+import org.sonar.server.user.UserSession;
 import org.sonar.updatecenter.common.Plugin;
 
 import static com.google.common.collect.ImmutableSortedSet.copyOf;
 import static java.lang.String.format;
 import static java.util.Collections.singleton;
+import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
 import static org.sonar.server.plugins.ws.PluginWSCommons.NAME_KEY_PLUGIN_METADATA_COMPARATOR;
 import static org.sonar.server.plugins.ws.PluginWSCommons.compatiblePluginsByKey;
 
@@ -47,11 +49,13 @@ public class InstalledAction implements PluginsWsAction {
   private static final String ARRAY_PLUGINS = "plugins";
   private static final String FIELD_CATEGORY = "category";
 
+  private final UserSession userSession;
   private final ServerPluginRepository pluginRepository;
   private final PluginWSCommons pluginWSCommons;
   private final UpdateCenterMatrixFactory updateCenterMatrixFactory;
 
-  public InstalledAction(ServerPluginRepository pluginRepository, PluginWSCommons pluginWSCommons, UpdateCenterMatrixFactory updateCenterMatrixFactory) {
+  public InstalledAction(UserSession userSession, ServerPluginRepository pluginRepository, PluginWSCommons pluginWSCommons, UpdateCenterMatrixFactory updateCenterMatrixFactory) {
+    this.userSession = userSession;
     this.pluginRepository = pluginRepository;
     this.pluginWSCommons = pluginWSCommons;
     this.updateCenterMatrixFactory = updateCenterMatrixFactory;
@@ -60,7 +64,8 @@ public class InstalledAction implements PluginsWsAction {
   @Override
   public void define(WebService.NewController controller) {
     WebService.NewAction action = controller.createAction("installed")
-      .setDescription("Get the list of all the plugins installed on the SonarQube instance, sorted by plugin name")
+      .setDescription("Get the list of all the plugins installed on the SonarQube instance, sorted by plugin name.<br/>" +
+        "Require 'Administer System' permission.")
       .setSince("5.2")
       .setHandler(this)
       .setResponseExample(Resources.getResource(this.getClass(), "example-installed_plugins.json"));
@@ -75,6 +80,7 @@ public class InstalledAction implements PluginsWsAction {
 
   @Override
   public void handle(Request request, Response response) throws Exception {
+    userSession.checkPermission(SYSTEM_ADMIN);
     Collection<PluginInfo> pluginInfoList = searchPluginInfoList();
 
     JsonWriter jsonWriter = response.newJsonWriter();
index 8a79908e9aaadbc8cc2729415380c63f3477bf69..5ee8a989ce80549c02815a2960118719e2981f9e 100644 (file)
@@ -35,11 +35,13 @@ import org.sonar.core.platform.PluginInfo;
 import org.sonar.server.plugins.PluginDownloader;
 import org.sonar.server.plugins.ServerPluginRepository;
 import org.sonar.server.plugins.UpdateCenterMatrixFactory;
+import org.sonar.server.user.UserSession;
 import org.sonar.updatecenter.common.Plugin;
 
 import static com.google.common.collect.FluentIterable.from;
 import static com.google.common.collect.ImmutableSet.copyOf;
 import static com.google.common.io.Resources.getResource;
+import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
 import static org.sonar.server.plugins.ws.PluginWSCommons.compatiblePluginsByKey;
 
 /**
@@ -51,14 +53,16 @@ public class PendingAction implements PluginsWsAction {
   private static final String ARRAY_REMOVING = "removing";
   private static final String ARRAY_UPDATING = "updating";
 
+  private final UserSession userSession;
   private final PluginDownloader pluginDownloader;
   private final ServerPluginRepository installer;
   private final PluginWSCommons pluginWSCommons;
   private final UpdateCenterMatrixFactory updateCenterMatrixFactory;
 
-  public PendingAction(PluginDownloader pluginDownloader,
-    ServerPluginRepository installer,
-    PluginWSCommons pluginWSCommons, UpdateCenterMatrixFactory updateCenterMatrixFactory) {
+  public PendingAction(UserSession userSession, PluginDownloader pluginDownloader,
+                       ServerPluginRepository installer,
+                       PluginWSCommons pluginWSCommons, UpdateCenterMatrixFactory updateCenterMatrixFactory) {
+    this.userSession = userSession;
     this.pluginDownloader = pluginDownloader;
     this.installer = installer;
     this.pluginWSCommons = pluginWSCommons;
@@ -68,7 +72,8 @@ public class PendingAction implements PluginsWsAction {
   @Override
   public void define(WebService.NewController controller) {
     controller.createAction("pending")
-      .setDescription("Get the list of plugins which will either be installed or removed at the next startup of the SonarQube instance, sorted by plugin name")
+      .setDescription("Get the list of plugins which will either be installed or removed at the next startup of the SonarQube instance, sorted by plugin name.<br/>" +
+        "Require 'Administer System' permission.")
       .setSince("5.2")
       .setHandler(this)
       .setResponseExample(getResource(this.getClass(), "example-pending_plugins.json"));
@@ -76,6 +81,7 @@ public class PendingAction implements PluginsWsAction {
 
   @Override
   public void handle(Request request, Response response) throws Exception {
+    userSession.checkPermission(SYSTEM_ADMIN);
     ImmutableMap<String, Plugin> compatiblePluginsByKey = compatiblePluginsByKey(updateCenterMatrixFactory);
 
     JsonWriter jsonWriter = response.newJsonWriter();
index c2dd55ee00dbc07eb843cebe29209cd6eb6501e9..8cb5da1fe2713af71ceeb2e3ff2d099dacea5466 100644 (file)
@@ -33,10 +33,13 @@ import org.sonar.api.server.ws.WebService;
 import org.sonar.api.utils.text.JsonWriter;
 import org.sonar.server.plugins.UpdateCenterMatrixFactory;
 import org.sonar.server.plugins.ws.PluginUpdateAggregator.PluginUpdateAggregate;
+import org.sonar.server.user.UserSession;
 import org.sonar.updatecenter.common.Plugin;
 import org.sonar.updatecenter.common.PluginUpdate;
 import org.sonar.updatecenter.common.UpdateCenter;
 
+import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
+
 /**
  * Implementation of the {@code updates} action for the Plugins WebService.
  */
@@ -55,13 +58,15 @@ public class UpdatesAction implements PluginsWsAction {
     }
   });
 
+  private final UserSession userSession;
   private final UpdateCenterMatrixFactory updateCenterMatrixFactory;
   private final PluginWSCommons pluginWSCommons;
   private final PluginUpdateAggregator aggregator;
 
-  public UpdatesAction(UpdateCenterMatrixFactory updateCenterMatrixFactory,
-    PluginWSCommons pluginWSCommons,
-    PluginUpdateAggregator aggregator) {
+  public UpdatesAction(UserSession userSession, UpdateCenterMatrixFactory updateCenterMatrixFactory,
+                       PluginWSCommons pluginWSCommons,
+                       PluginUpdateAggregator aggregator) {
+    this.userSession = userSession;
     this.updateCenterMatrixFactory = updateCenterMatrixFactory;
     this.pluginWSCommons = pluginWSCommons;
     this.aggregator = aggregator;
@@ -76,7 +81,8 @@ public class UpdatesAction implements PluginsWsAction {
         "<br/>" +
         "Plugin information is retrieved from Update Center. Date and time at which Update Center was last refreshed is provided in the response." +
         "<br/>" +
-        "Update status values are: [COMPATIBLE, INCOMPATIBLE, REQUIRES_UPGRADE, DEPS_REQUIRE_UPGRADE]")
+        "Update status values are: [COMPATIBLE, INCOMPATIBLE, REQUIRES_UPGRADE, DEPS_REQUIRE_UPGRADE]<br/>." +
+        "Require 'Administer System' permission.")
       .setSince("5.2")
       .setHandler(this)
       .setResponseExample(Resources.getResource(this.getClass(), "example-updates_plugins.json"));
@@ -84,6 +90,7 @@ public class UpdatesAction implements PluginsWsAction {
 
   @Override
   public void handle(Request request, Response response) throws Exception {
+    userSession.checkPermission(SYSTEM_ADMIN);
     JsonWriter jsonWriter = response.newJsonWriter();
     jsonWriter.beginObject();
 
index 27db1d72c2d4f86b61506e581b0890212dfce55b..438065a272100d9d92f62047e58ba3c9e367d269 100644 (file)
 package org.sonar.server.plugins.ws;
 
 import com.google.common.base.Optional;
+import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.ExpectedException;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.api.utils.DateUtils;
+import org.sonar.server.exceptions.ForbiddenException;
+import org.sonar.server.tester.UserSessionRule;
 import org.sonar.server.ws.WsTester;
 import org.sonar.updatecenter.common.Plugin;
 import org.sonar.updatecenter.common.PluginUpdate;
@@ -33,6 +37,8 @@ import static com.google.common.collect.ImmutableList.of;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Matchers.anyBoolean;
 import static org.mockito.Mockito.when;
+import static org.sonar.core.permission.GlobalPermissions.DASHBOARD_SHARING;
+import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
 import static org.sonar.test.JsonAssert.assertJson;
 import static org.sonar.updatecenter.common.PluginUpdate.Status.COMPATIBLE;
 import static org.sonar.updatecenter.common.PluginUpdate.Status.DEPENDENCIES_REQUIRE_SONAR_UPGRADE;
@@ -57,10 +63,17 @@ public class AvailableActionTest extends AbstractUpdateCenterBasedPluginsWsActio
     .addOutgoingDependency(release(PLUGIN_1, "0.3.6"))
     .addOutgoingDependency(release(PLUGIN_2, "1.0.0"));
 
-  private AvailableAction underTest = new AvailableAction(updateCenterFactory, new PluginWSCommons());
+  @Rule
+  public UserSessionRule userSession = UserSessionRule.standalone();
+
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
+
+  private AvailableAction underTest = new AvailableAction(userSession, updateCenterFactory, new PluginWSCommons());
 
   @Test
   public void action_available_is_defined() {
+    loggedAsAdmin();
     WsTester wsTester = new WsTester();
     WebService.NewController newController = wsTester.context().createController(DUMMY_CONTROLLER_KEY);
 
@@ -78,6 +91,7 @@ public class AvailableActionTest extends AbstractUpdateCenterBasedPluginsWsActio
 
   @Test
   public void empty_array_is_returned_when_there_is_no_plugin_available() throws Exception {
+    loggedAsAdmin();
     underTest.handle(request, response);
 
     assertJson(response.outputAsString()).withStrictArrayOrder().isSimilarTo(JSON_EMPTY_PLUGIN_LIST);
@@ -85,6 +99,7 @@ public class AvailableActionTest extends AbstractUpdateCenterBasedPluginsWsActio
 
   @Test
   public void empty_array_is_returned_when_update_center_is_not_accessible() throws Exception {
+    loggedAsAdmin();
     when(updateCenterFactory.getUpdateCenter(anyBoolean())).thenReturn(Optional.<UpdateCenter>absent());
 
     underTest.handle(request, response);
@@ -94,9 +109,10 @@ public class AvailableActionTest extends AbstractUpdateCenterBasedPluginsWsActio
 
   @Test
   public void verify_properties_displayed_in_json_per_plugin() throws Exception {
+    loggedAsAdmin();
     when(updateCenter.findAvailablePlugins()).thenReturn(of(
       pluginUpdate(FULL_PROPERTIES_PLUGIN_RELEASE, COMPATIBLE)
-      ));
+    ));
 
     underTest.handle(request, response);
 
@@ -105,28 +121,40 @@ public class AvailableActionTest extends AbstractUpdateCenterBasedPluginsWsActio
 
   @Test
   public void status_COMPATIBLE_is_displayed_COMPATIBLE_in_JSON() throws Exception {
+    loggedAsAdmin();
     checkStatusDisplayedInJson(COMPATIBLE, "COMPATIBLE");
   }
 
   @Test
   public void status_INCOMPATIBLE_is_displayed_INCOMPATIBLE_in_JSON() throws Exception {
+    loggedAsAdmin();
     checkStatusDisplayedInJson(INCOMPATIBLE, "INCOMPATIBLE");
   }
 
   @Test
   public void status_REQUIRE_SONAR_UPGRADE_is_displayed_REQUIRES_SYSTEM_UPGRADE_in_JSON() throws Exception {
+    loggedAsAdmin();
     checkStatusDisplayedInJson(REQUIRE_SONAR_UPGRADE, "REQUIRES_SYSTEM_UPGRADE");
   }
 
   @Test
   public void status_DEPENDENCIES_REQUIRE_SONAR_UPGRADE_is_displayed_DEPS_REQUIRE_SYSTEM_UPGRADE_in_JSON() throws Exception {
+    loggedAsAdmin();
     checkStatusDisplayedInJson(DEPENDENCIES_REQUIRE_SONAR_UPGRADE, "DEPS_REQUIRE_SYSTEM_UPGRADE");
   }
 
+  @Test
+  public void fail_when_user_is_not_admin() throws Exception {
+    userSession.login("user").setGlobalPermissions(DASHBOARD_SHARING);
+
+    expectedException.expect(ForbiddenException.class);
+    underTest.handle(request, response);
+  }
+
   private void checkStatusDisplayedInJson(PluginUpdate.Status status, String expectedValue) throws Exception {
     when(updateCenter.findAvailablePlugins()).thenReturn(of(
       pluginUpdate(release(PLUGIN_1, "1.0.0"), status)
-      ));
+    ));
 
     underTest.handle(request, response);
 
@@ -140,17 +168,11 @@ public class AvailableActionTest extends AbstractUpdateCenterBasedPluginsWsActio
         "    }" +
         "  ]" +
         "}"
-      );
+    );
   }
 
-  @Test
-  public void plugins_are_sorted_by_name_then_key_and_made_unique() {
-    when(updateCenter.findAvailablePlugins()).thenReturn(of(
-      pluginUpdate("key2", "name2"),
-      pluginUpdate("key1", "name2"),
-      pluginUpdate("key2", "name2"),
-      pluginUpdate("key0", "name0"),
-      pluginUpdate("key1", "name1")
-      ));
+  private void loggedAsAdmin() {
+    userSession.login("admin").setGlobalPermissions(SYSTEM_ADMIN);
   }
+
 }
index 2ecc8132f0cdf11b64bc9d92d6ea05207dfad40b..e023f4d0067f9ca3b95107dc73d1ed9171be06c9 100644 (file)
@@ -24,13 +24,16 @@ import java.io.File;
 import java.util.Arrays;
 import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.ExpectedException;
 import org.junit.rules.TemporaryFolder;
 import org.sonar.api.server.ws.Request;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.api.server.ws.WebService.Param;
 import org.sonar.core.platform.PluginInfo;
+import org.sonar.server.exceptions.ForbiddenException;
 import org.sonar.server.plugins.ServerPluginRepository;
 import org.sonar.server.plugins.UpdateCenterMatrixFactory;
+import org.sonar.server.tester.UserSessionRule;
 import org.sonar.server.ws.WsTester;
 import org.sonar.updatecenter.common.Plugin;
 import org.sonar.updatecenter.common.UpdateCenter;
@@ -43,6 +46,8 @@ import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verifyZeroInteractions;
 import static org.mockito.Mockito.when;
+import static org.sonar.core.permission.GlobalPermissions.DASHBOARD_SHARING;
+import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
 import static org.sonar.test.JsonAssert.assertJson;
 
 public class InstalledActionTest {
@@ -55,16 +60,25 @@ public class InstalledActionTest {
   @Rule
   public TemporaryFolder temp = new TemporaryFolder();
 
+  @Rule
+  public UserSessionRule userSession = UserSessionRule.standalone();
+
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
+
   ServerPluginRepository pluginRepository = mock(ServerPluginRepository.class);
   UpdateCenterMatrixFactory updateCenterMatrixFactory = mock(UpdateCenterMatrixFactory.class, RETURNS_DEEP_STUBS);
 
-  InstalledAction underTest = new InstalledAction(pluginRepository, new PluginWSCommons(), updateCenterMatrixFactory);
+  InstalledAction underTest = new InstalledAction(userSession, pluginRepository, new PluginWSCommons(), updateCenterMatrixFactory);
 
   Request request = mock(Request.class);
   WsTester.TestResponse response = new WsTester.TestResponse();
 
+
+
   @Test
   public void action_installed_is_defined() {
+    loggedAsSystemAdmin();
     WsTester wsTester = new WsTester();
     WebService.NewController newController = wsTester.context().createController(DUMMY_CONTROLLER_KEY);
 
@@ -82,6 +96,7 @@ public class InstalledActionTest {
 
   @Test
   public void empty_array_is_returned_when_there_is_not_plugin_installed() throws Exception {
+    loggedAsSystemAdmin();
     underTest.handle(request, response);
 
     assertJson(response.outputAsString()).withStrictArrayOrder().isSimilarTo(JSON_EMPTY_PLUGIN_LIST);
@@ -89,6 +104,7 @@ public class InstalledActionTest {
 
   @Test
   public void empty_array_when_update_center_is_unavailable() throws Exception {
+    loggedAsSystemAdmin();
     when(updateCenterMatrixFactory.getUpdateCenter(false)).thenReturn(Optional.<UpdateCenter>absent());
 
     underTest.handle(request, response);
@@ -98,6 +114,7 @@ public class InstalledActionTest {
 
   @Test
   public void empty_fields_are_not_serialized_to_json() throws Exception {
+    loggedAsSystemAdmin();
     when(pluginRepository.getPluginInfos()).thenReturn(
       of(new PluginInfo("").setName("")));
 
@@ -108,6 +125,7 @@ public class InstalledActionTest {
 
   @Test
   public void verify_properties_displayed_in_json_per_plugin() throws Exception {
+    loggedAsSystemAdmin();
     String jarFilename = getClass().getSimpleName() + "/" + "some.jar";
     when(pluginRepository.getPluginInfos()).thenReturn(of(
       new PluginInfo("plugKey")
@@ -122,7 +140,7 @@ public class InstalledActionTest {
         .setImplementationBuild("sou_rev_sha1")
         .setJarFile(new File(getClass().getResource(jarFilename).toURI()))
       )
-      );
+    );
 
     underTest.handle(request, response);
 
@@ -145,11 +163,12 @@ public class InstalledActionTest {
         "    }" +
         "  ]" +
         "}"
-      );
+    );
   }
 
   @Test
   public void category_is_returned_when_in_additional_fields() throws Exception {
+    loggedAsSystemAdmin();
     String jarFilename = getClass().getSimpleName() + "/" + "some.jar";
     when(pluginRepository.getPluginInfos()).thenReturn(of(
       new PluginInfo("plugKey")
@@ -201,6 +220,7 @@ public class InstalledActionTest {
 
   @Test
   public void plugins_are_sorted_by_name_then_key_and_only_one_plugin_can_have_a_specific_name() throws Exception {
+    loggedAsSystemAdmin();
     when(pluginRepository.getPluginInfos()).thenReturn(
       of(
         plugin("A", "name2"),
@@ -208,7 +228,7 @@ public class InstalledActionTest {
         plugin("C", "name0"),
         plugin("D", "name0")
       )
-      );
+    );
 
     underTest.handle(request, response);
 
@@ -222,17 +242,18 @@ public class InstalledActionTest {
         "    {\"key\": \"A\"}" +
         "  ]" +
         "}"
-      );
+    );
   }
 
   @Test
   public void only_one_plugin_can_have_a_specific_name_and_key() throws Exception {
+    loggedAsSystemAdmin();
     when(pluginRepository.getPluginInfos()).thenReturn(
       of(
         plugin("A", "name2"),
         plugin("A", "name2")
       )
-      );
+    );
 
     underTest.handle(request, response);
 
@@ -243,11 +264,24 @@ public class InstalledActionTest {
         "    {\"key\": \"A\"}" +
         "  ]" +
         "}"
-      );
+    );
     assertThat(response.outputAsString()).containsOnlyOnce("name2");
   }
 
+  @Test
+  public void fail_when_user_is_not_sys_admin() throws Exception {
+    userSession.login("user").setGlobalPermissions(DASHBOARD_SHARING);
+
+    expectedException.expect(ForbiddenException.class);
+    underTest.handle(request, response);
+  }
+
   private PluginInfo plugin(String key, String name) {
     return new PluginInfo(key).setName(name).setVersion(Version.create("1.0"));
   }
+
+  private void loggedAsSystemAdmin() {
+    userSession.login("admin").setGlobalPermissions(SYSTEM_ADMIN);
+  }
+
 }
index 7b82a95890a2ad05839380be6f0df0545d6201e1..76a928240f70fe0cac8c2030a6543e96bd713420 100644 (file)
@@ -22,13 +22,17 @@ package org.sonar.server.plugins.ws;
 import com.google.common.base.Optional;
 import java.util.ArrayList;
 import java.util.List;
+import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.ExpectedException;
 import org.sonar.api.server.ws.Request;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.core.platform.PluginInfo;
+import org.sonar.server.exceptions.ForbiddenException;
 import org.sonar.server.plugins.PluginDownloader;
 import org.sonar.server.plugins.ServerPluginRepository;
 import org.sonar.server.plugins.UpdateCenterMatrixFactory;
+import org.sonar.server.tester.UserSessionRule;
 import org.sonar.server.ws.WsTester;
 import org.sonar.updatecenter.common.Plugin;
 import org.sonar.updatecenter.common.UpdateCenter;
@@ -39,21 +43,30 @@ import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
+import static org.sonar.core.permission.GlobalPermissions.DASHBOARD_SHARING;
+import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
 import static org.sonar.test.JsonAssert.assertJson;
 
 public class PendingActionTest {
 
   private static final String DUMMY_CONTROLLER_KEY = "dummy";
 
+  @Rule
+  public UserSessionRule userSession = UserSessionRule.standalone();
+
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
+
   PluginDownloader pluginDownloader = mock(PluginDownloader.class);
   ServerPluginRepository serverPluginRepository = mock(ServerPluginRepository.class);
   UpdateCenterMatrixFactory updateCenterMatrixFactory = mock(UpdateCenterMatrixFactory.class, RETURNS_DEEP_STUBS);
-  PendingAction underTest = new PendingAction(pluginDownloader, serverPluginRepository, new PluginWSCommons(), updateCenterMatrixFactory);
+  PendingAction underTest = new PendingAction(userSession, pluginDownloader, serverPluginRepository, new PluginWSCommons(), updateCenterMatrixFactory);
   Request request = mock(Request.class);
   WsTester.TestResponse response = new WsTester.TestResponse();
 
   @Test
   public void action_pending_is_defined() {
+    loggedAsSystemAdmin();
     WsTester wsTester = new WsTester();
     WebService.NewController newController = wsTester.context().createController(DUMMY_CONTROLLER_KEY);
 
@@ -71,6 +84,7 @@ public class PendingActionTest {
 
   @Test
   public void empty_arrays_are_returned_when_there_nothing_pending() throws Exception {
+    loggedAsSystemAdmin();
     underTest.handle(request, response);
 
     assertJson(response.outputAsString()).withStrictArrayOrder().isSimilarTo(
@@ -79,11 +93,12 @@ public class PendingActionTest {
         "  \"removing\": []," +
         "  \"updating\": []" +
         "}"
-      );
+    );
   }
 
   @Test
   public void empty_arrays_are_returned_when_update_center_is_unavailable() throws Exception {
+    loggedAsSystemAdmin();
     when(updateCenterMatrixFactory.getUpdateCenter(false)).thenReturn(Optional.<UpdateCenter>absent());
 
     underTest.handle(request, response);
@@ -94,11 +109,12 @@ public class PendingActionTest {
         "  \"removing\": []," +
         "  \"updating\": []" +
         "}"
-      );
+    );
   }
 
   @Test
   public void verify_properties_displayed_in_json_per_installing_plugin() throws Exception {
+    loggedAsSystemAdmin();
     newUpdateCenter("scmgit");
     when(pluginDownloader.getDownloadedPlugins()).thenReturn(of(newScmGitPluginInfo()));
 
@@ -125,11 +141,12 @@ public class PendingActionTest {
         "  \"removing\": []," +
         "  \"updating\": []" +
         "}"
-      );
+    );
   }
 
   @Test
   public void verify_properties_displayed_in_json_per_removing_plugin() throws Exception {
+    loggedAsSystemAdmin();
     when(serverPluginRepository.getUninstalledPlugins()).thenReturn(of(newScmGitPluginInfo()));
 
     underTest.handle(request, response);
@@ -154,11 +171,12 @@ public class PendingActionTest {
         "    }" +
         "  ]" +
         "}"
-      );
+    );
   }
 
   @Test
   public void verify_properties_displayed_in_json_per_updating_plugin() throws Exception {
+    loggedAsSystemAdmin();
     newUpdateCenter("scmgit");
     when(serverPluginRepository.getPluginInfos()).thenReturn(of(newScmGitPluginInfo()));
     when(pluginDownloader.getDownloadedPlugins()).thenReturn(of(newScmGitPluginInfo()));
@@ -181,6 +199,7 @@ public class PendingActionTest {
 
   @Test
   public void verify_properties_displayed_in_json_per_installing_removing_and_updating_plugins() throws Exception {
+    loggedAsSystemAdmin();
     PluginInfo installed = newPluginInfo("java");
     PluginInfo removedPlugin = newPluginInfo("js");
     PluginInfo newPlugin = newPluginInfo("php");
@@ -218,11 +237,12 @@ public class PendingActionTest {
 
   @Test
   public void installing_plugins_are_sorted_by_name_then_key_and_are_unique() throws Exception {
+    loggedAsSystemAdmin();
     when(pluginDownloader.getDownloadedPlugins()).thenReturn(of(
       newPluginInfo(0).setName("Foo"),
       newPluginInfo(3).setName("Bar"),
       newPluginInfo(2).setName("Bar")
-      ));
+    ));
 
     underTest.handle(request, response);
 
@@ -246,16 +266,17 @@ public class PendingActionTest {
         "  \"removing\": []," +
         "  \"updating\": []" +
         "}"
-      );
+    );
   }
 
   @Test
   public void removing_plugins_are_sorted_and_unique() throws Exception {
+    loggedAsSystemAdmin();
     when(serverPluginRepository.getUninstalledPlugins()).thenReturn(of(
       newPluginInfo(0).setName("Foo"),
       newPluginInfo(3).setName("Bar"),
       newPluginInfo(2).setName("Bar")
-      ));
+    ));
 
     underTest.handle(request, response);
 
@@ -279,10 +300,18 @@ public class PendingActionTest {
         "    }" +
         "  ]" +
         "}"
-      );
+    );
   }
 
-  public PluginInfo newScmGitPluginInfo() {
+  @Test
+  public void fail_when_user_is_not_sys_admin() throws Exception {
+    userSession.login("user").setGlobalPermissions(DASHBOARD_SHARING);
+
+    expectedException.expect(ForbiddenException.class);
+    underTest.handle(request, response);
+  }
+
+  private PluginInfo newScmGitPluginInfo() {
     return new PluginInfo("scmgit")
       .setName("Git")
       .setDescription("Git SCM Provider.")
@@ -295,11 +324,11 @@ public class PendingActionTest {
       .setImplementationBuild("9ce9d330c313c296fab051317cc5ad4b26319e07");
   }
 
-  public PluginInfo newPluginInfo(String key){
+  private PluginInfo newPluginInfo(String key) {
     return new PluginInfo(key);
   }
 
-  private UpdateCenter newUpdateCenter(String... pluginKeys){
+  private UpdateCenter newUpdateCenter(String... pluginKeys) {
     UpdateCenter updateCenter = mock(UpdateCenter.class);
     when(updateCenterMatrixFactory.getUpdateCenter(false)).thenReturn(Optional.of(updateCenter));
     List<Plugin> plugins = new ArrayList<>();
@@ -310,7 +339,11 @@ public class PendingActionTest {
     return updateCenter;
   }
 
-  public PluginInfo newPluginInfo(int id) {
+  private PluginInfo newPluginInfo(int id) {
     return new PluginInfo("key" + id).setName("name" + id);
   }
+
+  private void loggedAsSystemAdmin() {
+    userSession.login("admin").setGlobalPermissions(SYSTEM_ADMIN);
+  }
 }
index b0ba63bf886ae4599c7e1044444f4a745e57b47d..da84e11fd59f657b9c369d647b25617ccf74202e 100644 (file)
@@ -28,11 +28,12 @@ import org.junit.ClassRule;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
-import org.sonar.core.permission.GlobalPermissions;
 import org.sonar.server.tester.ServerTester;
 import org.sonar.server.tester.UserSessionRule;
 import org.sonar.server.ws.WsTester;
 
+import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
+
 public class PluginsWsMediumTest {
   private static final String ENCODING = "UTF-8";
 
@@ -52,6 +53,7 @@ public class PluginsWsMediumTest {
     WsTester wsTester = new WsTester(serverTester.get(PluginsWs.class));
 
     // 1 - check what's installed, available and pending
+    userSessionRule.login().setGlobalPermissions(SYSTEM_ADMIN);
     wsTester.newGetRequest("api/plugins", "installed").execute().assertJson("{" +
       "  \"plugins\": [" +
       "    {" +
@@ -79,8 +81,7 @@ public class PluginsWsMediumTest {
 
     wsTester.newGetRequest("api/plugins", "pending").execute().assertJson("{\"installing\":[],\"removing\":[],\"updating\":[]}");
 
-    // 2 - login as admin and install one plugin, update another, verify pending status in the process
-    userSessionRule.login().setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN);
+    // 2 - install one plugin, update another, verify pending status in the process
     wsTester.newPostRequest("api/plugins", "update").setParam("key", "decoy").execute().assertNoContent();
 
     wsTester.newGetRequest("api/plugins", "pending").execute().assertJson("{" +
@@ -116,6 +117,7 @@ public class PluginsWsMediumTest {
     wsTester = restartServerTester();
 
     // 4 - make sure plugin is installed
+    userSessionRule.login().setGlobalPermissions(SYSTEM_ADMIN);
     wsTester.newGetRequest("api/plugins", "installed").execute().assertJson("{" +
       "  \"plugins\": [" +
       "    {" +
@@ -130,8 +132,7 @@ public class PluginsWsMediumTest {
       "}"
       );
 
-    // 5 - login as admin again and uninstall a plugin, verify pending status in the process
-    userSessionRule.login().setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN);
+    // 5 - uninstall a plugin, verify pending status in the process
     wsTester.newPostRequest("api/plugins", "uninstall").setParam("key", "foo").execute().assertNoContent();
 
     wsTester.newGetRequest("api/plugins", "pending").execute().assertJson("{" +
@@ -149,6 +150,7 @@ public class PluginsWsMediumTest {
     wsTester = restartServerTester();
 
     // 7 - make sure plugin has been uninstalled
+    userSessionRule.login().setGlobalPermissions(SYSTEM_ADMIN);
     wsTester.newGetRequest("api/plugins", "installed").execute().assertJson("{" +
       "  \"plugins\": [" +
       "    {" +
index 0b4ab210e14ba71b676c52472e9e53f1b56d11de..f13b78e722f2c19bf57ec9a6d1c68ee72d7d9c08 100644 (file)
  */
 package org.sonar.server.plugins.ws;
 
+import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.ExpectedException;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.api.utils.DateUtils;
+import org.sonar.server.exceptions.ForbiddenException;
+import org.sonar.server.tester.UserSessionRule;
 import org.sonar.server.ws.WsTester;
 import org.sonar.updatecenter.common.Plugin;
 import org.sonar.updatecenter.common.Release;
@@ -29,6 +33,8 @@ import org.sonar.updatecenter.common.Release;
 import static com.google.common.collect.ImmutableList.of;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.when;
+import static org.sonar.core.permission.GlobalPermissions.DASHBOARD_SHARING;
+import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
 import static org.sonar.test.JsonAssert.assertJson;
 import static org.sonar.updatecenter.common.PluginUpdate.Status.COMPATIBLE;
 import static org.sonar.updatecenter.common.PluginUpdate.Status.INCOMPATIBLE;
@@ -70,12 +76,19 @@ public class UpdatesActionTest extends AbstractUpdateCenterBasedPluginsWsActionT
 
     .addOutgoingDependency(release(JAVA_PLUGIN, "1.0"));
 
-  private UpdatesAction underTest = new UpdatesAction(updateCenterFactory,
+  @Rule
+  public UserSessionRule userSession = UserSessionRule.standalone();
+
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
+
+  private UpdatesAction underTest = new UpdatesAction(userSession, updateCenterFactory,
     new PluginWSCommons(), new PluginUpdateAggregator()
     );
 
   @Test
   public void action_updatable_is_defined() {
+    loggedAsSystemAdmin();
     WsTester wsTester = new WsTester();
     WebService.NewController newController = wsTester.context().createController(DUMMY_CONTROLLER_KEY);
 
@@ -93,6 +106,7 @@ public class UpdatesActionTest extends AbstractUpdateCenterBasedPluginsWsActionT
 
   @Test
   public void empty_array_is_returned_when_there_is_no_plugin_available() throws Exception {
+    loggedAsSystemAdmin();
     underTest.handle(request, response);
 
     assertJson(response.outputAsString()).withStrictArrayOrder().isSimilarTo(JSON_EMPTY_PLUGIN_LIST);
@@ -100,6 +114,7 @@ public class UpdatesActionTest extends AbstractUpdateCenterBasedPluginsWsActionT
 
   @Test
   public void verify_response_against_example() throws Exception {
+    loggedAsSystemAdmin();
     when(updateCenter.findPluginUpdates()).thenReturn(of(
       pluginUpdate(ABAP_32, COMPATIBLE),
       pluginUpdate(ABAP_31, INCOMPATIBLE),
@@ -113,6 +128,7 @@ public class UpdatesActionTest extends AbstractUpdateCenterBasedPluginsWsActionT
 
   @Test
   public void status_COMPATIBLE_is_displayed_COMPATIBLE_in_JSON() throws Exception {
+    loggedAsSystemAdmin();
     when(updateCenter.findPluginUpdates()).thenReturn(of(
       pluginUpdate(release(PLUGIN_1, "1.0.0"), COMPATIBLE)
       ));
@@ -136,6 +152,7 @@ public class UpdatesActionTest extends AbstractUpdateCenterBasedPluginsWsActionT
 
   @Test
   public void plugins_are_sorted_by_name_and_made_unique() throws Exception {
+    loggedAsSystemAdmin();
     when(updateCenter.findPluginUpdates()).thenReturn(of(
       pluginUpdate("key2", "name2"),
       pluginUpdate("key2", "name2"),
@@ -164,4 +181,16 @@ public class UpdatesActionTest extends AbstractUpdateCenterBasedPluginsWsActionT
         "}"
       );
   }
+
+  @Test
+  public void fail_when_user_is_not_sys_admin() throws Exception {
+    userSession.login("user").setGlobalPermissions(DASHBOARD_SHARING);
+
+    expectedException.expect(ForbiddenException.class);
+    underTest.handle(request, response);
+  }
+
+  private void loggedAsSystemAdmin() {
+    userSession.login("admin").setGlobalPermissions(SYSTEM_ADMIN);
+  }
 }