*/
package org.sonar.server.plugins.ws;
-import java.net.HttpURLConnection;
import java.util.Objects;
import java.util.Optional;
-
import org.sonar.api.config.Configuration;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
import org.sonar.core.extension.PluginRiskConsent;
-import org.sonar.server.exceptions.ServerException;
+import org.sonar.core.platform.EditionProvider.Edition;
+import org.sonar.core.platform.PlatformEditionProvider;
import org.sonar.server.plugins.PluginDownloader;
import org.sonar.server.plugins.UpdateCenterMatrixFactory;
import org.sonar.server.user.UserSession;
*/
public class InstallAction implements PluginsWsAction {
+ private static final String BR_HTML_TAG = "<br/>";
private static final String PARAM_KEY = "key";
private final UpdateCenterMatrixFactory updateCenterFactory;
private final PluginDownloader pluginDownloader;
private final UserSession userSession;
private final Configuration configuration;
+ private final PlatformEditionProvider editionProvider;
public InstallAction(UpdateCenterMatrixFactory updateCenterFactory, PluginDownloader pluginDownloader,
- UserSession userSession, Configuration configuration) {
+ UserSession userSession, Configuration configuration,
+ PlatformEditionProvider editionProvider) {
this.updateCenterFactory = updateCenterFactory;
this.pluginDownloader = pluginDownloader;
this.userSession = userSession;
this.configuration = configuration;
+ this.editionProvider = editionProvider;
}
@Override
.setPost(true)
.setSince("5.2")
.setDescription("Installs the latest version of a plugin specified by its key." +
- "<br/>" +
+ BR_HTML_TAG +
"Plugin information is retrieved from Update Center." +
- "<br/>" +
+ BR_HTML_TAG +
+ "Fails if used on commercial editions or plugin risk consent has not been accepted." +
+ BR_HTML_TAG +
"Requires user to be authenticated with Administer System permissions")
.setHandler(this);
@Override
public void handle(Request request, Response response) throws Exception {
userSession.checkIsSystemAdministrator();
+ checkEdition();
+
if (!hasPluginInstallConsent()) {
throw new IllegalArgumentException("Can't install plugin without accepting firstly plugins risk consent");
}
response.noContent();
}
+ private void checkEdition() {
+ Edition edition = editionProvider.get().orElse(Edition.COMMUNITY);
+ if (!Edition.COMMUNITY.equals(edition)) {
+ throw new IllegalArgumentException("This WS is unsupported in commercial edition. Please install plugin manually.");
+ }
+ }
+
private boolean hasPluginInstallConsent() {
Optional<String> pluginRiskConsent = configuration.get(PLUGINS_RISK_CONSENT);
return pluginRiskConsent.filter(s -> PluginRiskConsent.valueOf(s) == PluginRiskConsent.ACCEPTED).isPresent();
import com.tngtech.java.junit.dataprovider.DataProvider;
import com.tngtech.java.junit.dataprovider.DataProviderRunner;
import com.tngtech.java.junit.dataprovider.UseDataProvider;
-
import java.util.Optional;
-
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
-import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.sonar.api.config.Configuration;
import org.sonar.api.server.ws.WebService;
import org.sonar.core.extension.PluginRiskConsent;
+import org.sonar.core.platform.EditionProvider.Edition;
+import org.sonar.core.platform.PlatformEditionProvider;
import org.sonar.server.exceptions.ForbiddenException;
-import org.sonar.server.exceptions.ServerException;
import org.sonar.server.plugins.PluginDownloader;
import org.sonar.server.plugins.UpdateCenterMatrixFactory;
import org.sonar.server.tester.UserSessionRule;
+import org.sonar.server.ws.TestRequest;
import org.sonar.server.ws.TestResponse;
import org.sonar.server.ws.WsActionTester;
import org.sonar.updatecenter.common.Plugin;
@Rule
public UserSessionRule userSessionRule = UserSessionRule.standalone();
- @Rule
- public ExpectedException expectedException = ExpectedException.none();
private UpdateCenterMatrixFactory updateCenterFactory = mock(UpdateCenterMatrixFactory.class);
private UpdateCenter updateCenter = mock(UpdateCenter.class);
private PluginDownloader pluginDownloader = mock(PluginDownloader.class);
private Configuration configuration = mock(Configuration.class);
- private InstallAction underTest = new InstallAction(updateCenterFactory, pluginDownloader, userSessionRule, configuration);
+ private PlatformEditionProvider editionProvider = mock(PlatformEditionProvider.class);
+ private InstallAction underTest = new InstallAction(updateCenterFactory, pluginDownloader, userSessionRule, configuration,
+ editionProvider);
private WsActionTester tester = new WsActionTester(underTest);
@Before
public void wireMocks() {
+ when(editionProvider.get()).thenReturn(Optional.of(Edition.COMMUNITY));
when(updateCenterFactory.getUpdateCenter(anyBoolean())).thenReturn(Optional.of(updateCenter));
when(configuration.get(PLUGINS_RISK_CONSENT)).thenReturn(Optional.of(PluginRiskConsent.ACCEPTED.name()));
}
@Test
public void request_fails_with_ForbiddenException_when_user_is_not_logged_in() {
- expectedException.expect(ForbiddenException.class);
- expectedException.expectMessage("Insufficient privileges");
-
- tester.newRequest().execute();
+ TestRequest wsRequest = tester.newRequest();
+ assertThatThrownBy(wsRequest::execute)
+ .isInstanceOf(ForbiddenException.class)
+ .hasMessage("Insufficient privileges");
}
@Test
public void request_fails_with_ForbiddenException_when_user_is_not_system_administrator() {
userSessionRule.logIn().setNonSystemAdministrator();
- expectedException.expect(ForbiddenException.class);
- expectedException.expectMessage("Insufficient privileges");
-
- tester.newRequest().execute();
+ TestRequest request = tester.newRequest();
+ assertThatThrownBy(request::execute)
+ .isInstanceOf(ForbiddenException.class)
+ .hasMessage("Insufficient privileges");
+ ;
}
@Test
@Test
public void IAE_is_raised_when_key_param_is_not_provided() {
logInAsSystemAdministrator();
- expectedException.expect(IllegalArgumentException.class);
- tester.newRequest().execute();
+ TestRequest request = tester.newRequest();
+ assertThatThrownBy(request::execute)
+ .isInstanceOf(IllegalArgumentException.class);
}
@Test
public void IAE_is_raised_when_there_is_no_available_plugin_for_the_key() {
logInAsSystemAdministrator();
- expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("No plugin with key 'pluginKey'");
- tester.newRequest()
- .setParam(KEY_PARAM, PLUGIN_KEY)
- .execute();
+ TestRequest request = tester.newRequest()
+ .setParam(KEY_PARAM, PLUGIN_KEY);
+
+ assertThatThrownBy(request::execute)
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("No plugin with key 'pluginKey'");
}
@Test
.setLicense(license)
.setOrganization(organization), version), PluginUpdate.Status.COMPATIBLE)));
- expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("SonarSource commercial plugin with key '" + PLUGIN_KEY + "' can only be installed as part of a SonarSource edition");
-
- tester.newRequest()
- .setParam(KEY_PARAM, PLUGIN_KEY)
- .execute();
+ TestRequest request = tester.newRequest()
+ .setParam(KEY_PARAM, PLUGIN_KEY);
+ assertThatThrownBy(request::execute)
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessage("SonarSource commercial plugin with key '" + PLUGIN_KEY + "' can only be installed as part of a SonarSource edition");
}
@DataProvider
public static Object[][] editionBundledOrganizationAndLicense() {
- return new Object[][]{
+ return new Object[][] {
{"SonarSource", "SonarSource"},
{"SonarSource", "Commercial"},
{"sonarsource", "SOnArSOURCE"}
};
}
+ @Test
+ public void IAE_is_raised_when_WS_used_on_commercial_edition() {
+ logInAsSystemAdministrator();
+ Version version = Version.create("1.0");
+ when(updateCenter.findAvailablePlugins()).thenReturn(ImmutableList.of(
+ PluginUpdate.createWithStatus(new Release(Plugin.factory(PLUGIN_KEY), version), PluginUpdate.Status.COMPATIBLE)));
+
+ when(editionProvider.get()).thenReturn(Optional.of(Edition.DEVELOPER));
+
+ TestRequest request = tester.newRequest()
+ .setParam(KEY_PARAM, PLUGIN_KEY);
+ assertThatThrownBy(request::execute)
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessage("This WS is unsupported in commercial edition. Please install plugin manually.");
+ }
+
@Test
public void IAE_is_raised_when_update_center_is_unavailable() {
logInAsSystemAdministrator();
when(updateCenterFactory.getUpdateCenter(anyBoolean())).thenReturn(Optional.empty());
- expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("No plugin with key 'pluginKey'");
-
- tester.newRequest()
- .setParam(KEY_PARAM, PLUGIN_KEY)
- .execute();
+ TestRequest request = tester.newRequest()
+ .setParam(KEY_PARAM, PLUGIN_KEY);
+ assertThatThrownBy(request::execute)
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessageContaining("No plugin with key 'pluginKey'");
}
@Test
when(configuration.get(PLUGINS_RISK_CONSENT)).thenReturn(Optional.of(PluginRiskConsent.NOT_ACCEPTED.name()));
- assertThatThrownBy(() -> tester.newRequest()
- .setParam(KEY_PARAM, PLUGIN_KEY)
- .execute())
+ TestRequest request = tester.newRequest()
+ .setParam(KEY_PARAM, PLUGIN_KEY);
+ assertThatThrownBy(request::execute)
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Can't install plugin without accepting firstly plugins risk consent");