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.platform.PluginInfo;
import org.sonar.server.plugins.PluginUninstaller;
+import org.sonar.server.plugins.ServerPluginRepository;
import org.sonar.server.user.UserSession;
+import static java.lang.String.format;
+import static org.sonar.server.plugins.edition.EditionBundledPlugins.isEditionBundled;
+
/**
* Implementation of the {@code uninstall} action for the Plugins WebService.
*/
public class UninstallAction implements PluginsWsAction {
private static final String PARAM_KEY = "key";
+ private final ServerPluginRepository serverPluginRepository;
private final PluginUninstaller pluginUninstaller;
private final UserSession userSession;
- public UninstallAction(PluginUninstaller pluginUninstaller, UserSession userSession) {
+ public UninstallAction(ServerPluginRepository serverPluginRepository, PluginUninstaller pluginUninstaller, UserSession userSession) {
+ this.serverPluginRepository = serverPluginRepository;
this.pluginUninstaller = pluginUninstaller;
this.userSession = userSession;
}
userSession.checkIsSystemAdministrator();
String key = request.mandatoryParam(PARAM_KEY);
- pluginUninstaller.uninstall(key);
+ PluginInfo pluginInfo = serverPluginRepository.getPluginInfo(key);
+ if (pluginInfo != null) {
+ if (isEditionBundled(pluginInfo)) {
+ throw new IllegalArgumentException(format(
+ "SonarSource commercial plugin with key '%s' can only be uninstalled as part of a SonarSource edition",
+ pluginInfo.getKey()));
+ }
+ pluginUninstaller.uninstall(key);
+ }
response.noContent();
}
*/
package org.sonar.server.plugins.ws;
+import com.tngtech.java.junit.dataprovider.DataProvider;
+import com.tngtech.java.junit.dataprovider.DataProviderRunner;
+import com.tngtech.java.junit.dataprovider.UseDataProvider;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
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.PluginUninstaller;
+import org.sonar.server.plugins.ServerPluginRepository;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.WsTester;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+@RunWith(DataProviderRunner.class)
public class UninstallActionTest {
private static final String DUMMY_CONTROLLER_KEY = "dummy";
private static final String CONTROLLER_KEY = "api/plugins";
@Rule
public ExpectedException expectedException = ExpectedException.none();
+ private ServerPluginRepository serverPluginRepository = mock(ServerPluginRepository.class);
private PluginUninstaller pluginUninstaller = mock(PluginUninstaller.class);
- private UninstallAction underTest = new UninstallAction(pluginUninstaller, userSessionRule);
+ private UninstallAction underTest = new UninstallAction(serverPluginRepository, pluginUninstaller, userSessionRule);
private WsTester wsTester = new WsTester(new PluginsWs(underTest));
private Request invalidRequest = wsTester.newGetRequest(CONTROLLER_KEY, ACTION_KEY);
underTest.handle(invalidRequest, response);
}
+ @Test
+ public void do_not_attempt_uninstall_if_no_plugin_in_repository_for_specified_key() throws Exception {
+ logInAsSystemAdministrator();
+ when(serverPluginRepository.getPluginInfo(PLUGIN_KEY)).thenReturn(null);
+
+ underTest.handle(validRequest, response);
+
+ verifyZeroInteractions(pluginUninstaller);
+ }
+
+ @Test
+ @UseDataProvider("editionBundledOrganizationAndLicense")
+ public void IAE_is_raised_when_plugin_is_installed_and_is_edition_bundled(String organization, String license) throws Exception {
+ logInAsSystemAdministrator();
+ when(serverPluginRepository.getPluginInfo(PLUGIN_KEY))
+ .thenReturn(new PluginInfo(PLUGIN_KEY)
+ .setOrganizationName(organization)
+ .setLicense(license));
+
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("SonarSource commercial plugin with key '" + PLUGIN_KEY + "' can only be uninstalled as part of a SonarSource edition");
+
+ underTest.handle(validRequest, response);
+ }
+
+ @DataProvider
+ public static Object[][] editionBundledOrganizationAndLicense() {
+ return new Object[][] {
+ {"SonarSource", "SonarSource"},
+ {"SonarSource", "Commercial"},
+ {"sonarsource", "SOnArSOURCE"}
+ };
+ }
+
@Test
public void if_plugin_is_installed_uninstallation_is_triggered() throws Exception {
logInAsSystemAdministrator();
+ when(serverPluginRepository.getPluginInfo(PLUGIN_KEY)).thenReturn(new PluginInfo(PLUGIN_KEY));
underTest.handle(validRequest, response);