diff options
author | Julien Lancelot <julien.lancelot@sonarsource.com> | 2016-07-18 15:49:35 +0200 |
---|---|---|
committer | Julien Lancelot <julien.lancelot@sonarsource.com> | 2016-07-18 16:38:14 +0200 |
commit | 6b64679668f18d4ce05ad6d660ea33ebce7fa9fc (patch) | |
tree | 5a3abdadbb8c3a8f68ca8d018145ee6bffd00d9c | |
parent | 2f0e138b24b5c1ba69faa69f545a58571f2cfca2 (diff) | |
download | sonarqube-6b64679668f18d4ce05ad6d660ea33ebce7fa9fc.tar.gz sonarqube-6b64679668f18d4ce05ad6d660ea33ebce7fa9fc.zip |
SONAR-7874 api/plugins/* require administer system permission
9 files changed, 197 insertions, 52 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/AvailableAction.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/AvailableAction.java index 1fada70fc31..47d03fab07b 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/AvailableAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/AvailableAction.java @@ -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() - ); + ); } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/InstalledAction.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/InstalledAction.java index 4c1034713b6..bd81e9dd6d4 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/InstalledAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/InstalledAction.java @@ -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(); diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/PendingAction.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/PendingAction.java index 8a79908e9aa..5ee8a989ce8 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/PendingAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/PendingAction.java @@ -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(); diff --git a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/UpdatesAction.java b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/UpdatesAction.java index c2dd55ee00d..8cb5da1fe27 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/UpdatesAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/plugins/ws/UpdatesAction.java @@ -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(); diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/AvailableActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/AvailableActionTest.java index 27db1d72c2d..438065a2721 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/AvailableActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/AvailableActionTest.java @@ -20,9 +20,13 @@ 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); } + } diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/InstalledActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/InstalledActionTest.java index 2ecc8132f0c..e023f4d0067 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/InstalledActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/InstalledActionTest.java @@ -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); + } + } diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/PendingActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/PendingActionTest.java index 7b82a95890a..76a928240f7 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/PendingActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/PendingActionTest.java @@ -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); + } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/PluginsWsMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/PluginsWsMediumTest.java index b0ba63bf886..da84e11fd59 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/PluginsWsMediumTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/PluginsWsMediumTest.java @@ -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\": [" + " {" + diff --git a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/UpdatesActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/UpdatesActionTest.java index 0b4ab210e14..f13b78e722f 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/UpdatesActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/plugins/ws/UpdatesActionTest.java @@ -19,9 +19,13 @@ */ 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); + } } |