Do not list available plugins in REST API when they are installed

This commit is contained in:
Rene Pfeuffer
2019-09-11 17:01:47 +02:00
parent 0fdd1cea17
commit 67d924f5b4
2 changed files with 50 additions and 8 deletions

View File

@@ -4,7 +4,7 @@ import com.webcohesion.enunciate.metadata.rs.ResponseCode;
import com.webcohesion.enunciate.metadata.rs.StatusCodes; import com.webcohesion.enunciate.metadata.rs.StatusCodes;
import com.webcohesion.enunciate.metadata.rs.TypeHint; import com.webcohesion.enunciate.metadata.rs.TypeHint;
import sonia.scm.plugin.AvailablePlugin; import sonia.scm.plugin.AvailablePlugin;
import sonia.scm.plugin.InstalledPluginDescriptor; import sonia.scm.plugin.InstalledPlugin;
import sonia.scm.plugin.PluginManager; import sonia.scm.plugin.PluginManager;
import sonia.scm.plugin.PluginPermissions; import sonia.scm.plugin.PluginPermissions;
import sonia.scm.web.VndMediaType; import sonia.scm.web.VndMediaType;
@@ -19,6 +19,7 @@ import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Collectors;
import static sonia.scm.ContextEntry.ContextBuilder.entity; import static sonia.scm.ContextEntry.ContextBuilder.entity;
import static sonia.scm.NotFoundException.notFound; import static sonia.scm.NotFoundException.notFound;
@@ -51,10 +52,15 @@ public class AvailablePluginResource {
@Produces(VndMediaType.PLUGIN_COLLECTION) @Produces(VndMediaType.PLUGIN_COLLECTION)
public Response getAvailablePlugins() { public Response getAvailablePlugins() {
PluginPermissions.read().check(); PluginPermissions.read().check();
List<AvailablePlugin> available = pluginManager.getAvailable(); List<InstalledPlugin> installed = pluginManager.getInstalled();
List<AvailablePlugin> available = pluginManager.getAvailable().stream().filter(a -> notInstalled(a, installed)).collect(Collectors.toList());
return Response.ok(collectionMapper.mapAvailable(available)).build(); return Response.ok(collectionMapper.mapAvailable(available)).build();
} }
private boolean notInstalled(AvailablePlugin a, List<InstalledPlugin> installed) {
return installed.stream().noneMatch(installedPlugin -> installedPlugin.getDescriptor().getInformation().getName().equals(a.getDescriptor().getInformation().getName()));
}
/** /**
* Returns available plugin. * Returns available plugin.
* *

View File

@@ -18,6 +18,8 @@ import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoExtension;
import sonia.scm.plugin.AvailablePlugin; import sonia.scm.plugin.AvailablePlugin;
import sonia.scm.plugin.AvailablePluginDescriptor; import sonia.scm.plugin.AvailablePluginDescriptor;
import sonia.scm.plugin.InstalledPlugin;
import sonia.scm.plugin.InstalledPluginDescriptor;
import sonia.scm.plugin.PluginCondition; import sonia.scm.plugin.PluginCondition;
import sonia.scm.plugin.PluginInformation; import sonia.scm.plugin.PluginInformation;
import sonia.scm.plugin.PluginManager; import sonia.scm.plugin.PluginManager;
@@ -25,7 +27,6 @@ import sonia.scm.web.VndMediaType;
import javax.inject.Provider; import javax.inject.Provider;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.util.Collections; import java.util.Collections;
@@ -34,6 +35,7 @@ import java.util.Optional;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
@@ -90,9 +92,10 @@ class AvailablePluginResourceTest {
@Test @Test
void getAvailablePlugins() throws URISyntaxException, UnsupportedEncodingException { void getAvailablePlugins() throws URISyntaxException, UnsupportedEncodingException {
AvailablePlugin plugin = createPlugin(); AvailablePlugin plugin = createAvailablePlugin();
when(pluginManager.getAvailable()).thenReturn(Collections.singletonList(plugin)); when(pluginManager.getAvailable()).thenReturn(Collections.singletonList(plugin));
when(pluginManager.getInstalled()).thenReturn(Collections.emptyList());
when(collectionMapper.mapAvailable(Collections.singletonList(plugin))).thenReturn(new MockedResultDto()); when(collectionMapper.mapAvailable(Collections.singletonList(plugin))).thenReturn(new MockedResultDto());
MockHttpRequest request = MockHttpRequest.get("/v2/plugins/available"); MockHttpRequest request = MockHttpRequest.get("/v2/plugins/available");
@@ -105,13 +108,32 @@ class AvailablePluginResourceTest {
assertThat(response.getContentAsString()).contains("\"marker\":\"x\""); assertThat(response.getContentAsString()).contains("\"marker\":\"x\"");
} }
@Test
void shouldNotReturnInstalledPlugins() throws URISyntaxException, UnsupportedEncodingException {
AvailablePlugin availablePlugin = createAvailablePlugin();
InstalledPlugin installedPlugin = createInstalledPlugin();
when(pluginManager.getAvailable()).thenReturn(Collections.singletonList(availablePlugin));
when(pluginManager.getInstalled()).thenReturn(Collections.singletonList(installedPlugin));
lenient().when(collectionMapper.mapAvailable(Collections.singletonList(availablePlugin))).thenReturn(new MockedResultDto());
MockHttpRequest request = MockHttpRequest.get("/v2/plugins/available");
request.accept(VndMediaType.PLUGIN_COLLECTION);
MockHttpResponse response = new MockHttpResponse();
dispatcher.invoke(request, response);
assertThat(HttpServletResponse.SC_OK).isEqualTo(response.getStatus());
assertThat(response.getContentAsString()).doesNotContain("\"marker\":\"x\"");
}
@Test @Test
void getAvailablePlugin() throws UnsupportedEncodingException, URISyntaxException { void getAvailablePlugin() throws UnsupportedEncodingException, URISyntaxException {
PluginInformation pluginInformation = new PluginInformation(); PluginInformation pluginInformation = new PluginInformation();
pluginInformation.setName("pluginName"); pluginInformation.setName("pluginName");
pluginInformation.setVersion("2.0.0"); pluginInformation.setVersion("2.0.0");
AvailablePlugin plugin = createPlugin(pluginInformation); AvailablePlugin plugin = createAvailablePlugin(pluginInformation);
when(pluginManager.getAvailable("pluginName")).thenReturn(Optional.of(plugin)); when(pluginManager.getAvailable("pluginName")).thenReturn(Optional.of(plugin));
@@ -152,17 +174,31 @@ class AvailablePluginResourceTest {
} }
} }
private AvailablePlugin createPlugin() { private AvailablePlugin createAvailablePlugin() {
return createPlugin(new PluginInformation()); PluginInformation pluginInformation = new PluginInformation();
pluginInformation.setName("scm-some-plugin");
return createAvailablePlugin(pluginInformation);
} }
private AvailablePlugin createPlugin(PluginInformation pluginInformation) { private AvailablePlugin createAvailablePlugin(PluginInformation pluginInformation) {
AvailablePluginDescriptor descriptor = new AvailablePluginDescriptor( AvailablePluginDescriptor descriptor = new AvailablePluginDescriptor(
pluginInformation, new PluginCondition(), Collections.emptySet(), "https://download.hitchhiker.com", null pluginInformation, new PluginCondition(), Collections.emptySet(), "https://download.hitchhiker.com", null
); );
return new AvailablePlugin(descriptor); return new AvailablePlugin(descriptor);
} }
private InstalledPlugin createInstalledPlugin() {
PluginInformation pluginInformation = new PluginInformation();
pluginInformation.setName("scm-some-plugin");
return createInstalledPlugin(pluginInformation);
}
private InstalledPlugin createInstalledPlugin(PluginInformation pluginInformation) {
InstalledPluginDescriptor descriptor = mock(InstalledPluginDescriptor.class);
lenient().when(descriptor.getInformation()).thenReturn(pluginInformation);
return new InstalledPlugin(descriptor, null, null, null, false);
}
@Nested @Nested
class WithoutAuthorization { class WithoutAuthorization {