mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-13 17:05:43 +01:00
merge
This commit is contained in:
@@ -8,6 +8,7 @@ import de.otto.edison.hal.Links;
|
||||
import sonia.scm.plugin.AvailablePlugin;
|
||||
import sonia.scm.plugin.InstalledPlugin;
|
||||
import sonia.scm.plugin.PluginManager;
|
||||
import sonia.scm.plugin.PluginPermissions;
|
||||
import sonia.scm.web.VndMediaType;
|
||||
|
||||
import javax.inject.Inject;
|
||||
@@ -68,8 +69,12 @@ public class PendingPluginResource {
|
||||
List<PluginDto> updateDtos = updatePlugins.map(i -> mapper.mapInstalled(i, pending)).collect(toList());
|
||||
List<PluginDto> uninstallDtos = uninstallPlugins.map(i -> mapper.mapInstalled(i, pending)).collect(toList());
|
||||
|
||||
if (!installDtos.isEmpty() || !updateDtos.isEmpty() || !uninstallDtos.isEmpty()) {
|
||||
if (
|
||||
PluginPermissions.manage().isPermitted() &&
|
||||
(!installDtos.isEmpty() || !updateDtos.isEmpty() || !uninstallDtos.isEmpty())
|
||||
) {
|
||||
linksBuilder.single(link("execute", resourceLinks.pendingPluginCollection().executePending()));
|
||||
linksBuilder.single(link("cancel", resourceLinks.pendingPluginCollection().cancelPending()));
|
||||
}
|
||||
|
||||
Embedded.Builder embedded = Embedded.embeddedBuilder();
|
||||
|
||||
@@ -743,6 +743,10 @@ class ResourceLinks {
|
||||
return pendingPluginCollectionLinkBuilder.method("pendingPlugins").parameters().method("executePending").parameters().href();
|
||||
}
|
||||
|
||||
String cancelPending() {
|
||||
return pendingPluginCollectionLinkBuilder.method("pendingPlugins").parameters().method("cancelPending").parameters().href();
|
||||
}
|
||||
|
||||
String self() {
|
||||
return pendingPluginCollectionLinkBuilder.method("pendingPlugins").parameters().method("getPending").parameters().href();
|
||||
}
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
package sonia.scm.api.v2.resources;
|
||||
|
||||
import com.google.inject.util.Providers;
|
||||
import org.apache.shiro.ShiroException;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
import org.apache.shiro.util.ThreadContext;
|
||||
import org.jboss.resteasy.core.Dispatcher;
|
||||
import org.jboss.resteasy.mock.MockDispatcherFactory;
|
||||
import org.jboss.resteasy.mock.MockHttpRequest;
|
||||
import org.jboss.resteasy.mock.MockHttpResponse;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
@@ -19,6 +24,8 @@ import sonia.scm.plugin.PluginInformation;
|
||||
import sonia.scm.plugin.PluginManager;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.ext.ExceptionMapper;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
@@ -44,6 +51,9 @@ class PendingPluginResourceTest {
|
||||
@Mock
|
||||
PluginDtoMapper mapper;
|
||||
|
||||
@Mock
|
||||
Subject subject;
|
||||
|
||||
@InjectMocks
|
||||
PendingPluginResource pendingPluginResource;
|
||||
|
||||
@@ -52,6 +62,7 @@ class PendingPluginResourceTest {
|
||||
@BeforeEach
|
||||
void prepareEnvironment() {
|
||||
dispatcher = MockDispatcherFactory.createDispatcher();
|
||||
dispatcher.getProviderFactory().register(new PermissionExceptionMapper());
|
||||
PluginRootResource pluginRootResource = new PluginRootResource(null, null, Providers.of(pendingPluginResource));
|
||||
dispatcher.getRegistry().addSingletonResource(pluginRootResource);
|
||||
}
|
||||
@@ -70,6 +81,20 @@ class PendingPluginResourceTest {
|
||||
});
|
||||
}
|
||||
|
||||
@Nested
|
||||
class withAuthorization {
|
||||
|
||||
@BeforeEach
|
||||
void bindSubject() {
|
||||
ThreadContext.bind(subject);
|
||||
lenient().when(subject.isPermitted("plugin:manage")).thenReturn(true);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void unbindSubject() {
|
||||
ThreadContext.unbindSubject();
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldGetEmptyPluginListsWithoutInstallLinkWhenNoPendingPluginsPresent() throws URISyntaxException, UnsupportedEncodingException {
|
||||
AvailablePlugin availablePlugin = createAvailablePlugin("not-pending-plugin");
|
||||
@@ -85,7 +110,7 @@ class PendingPluginResourceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldGetPendingAvailablePluginListWithInstallLink() throws URISyntaxException, UnsupportedEncodingException {
|
||||
void shouldGetPendingAvailablePluginListWithInstallAndCancelLink() throws URISyntaxException, UnsupportedEncodingException {
|
||||
AvailablePlugin availablePlugin = createAvailablePlugin("pending-available-plugin");
|
||||
when(availablePlugin.isPending()).thenReturn(true);
|
||||
when(pluginManager.getAvailable()).thenReturn(singletonList(availablePlugin));
|
||||
@@ -96,6 +121,7 @@ class PendingPluginResourceTest {
|
||||
assertThat(response.getStatus()).isEqualTo(HttpServletResponse.SC_OK);
|
||||
assertThat(response.getContentAsString()).contains("\"new\":[{\"name\":\"pending-available-plugin\"");
|
||||
assertThat(response.getContentAsString()).contains("\"execute\":{\"href\":\"/v2/plugins/pending/execute\"}");
|
||||
assertThat(response.getContentAsString()).contains("\"cancel\":{\"href\":\"/v2/plugins/pending/cancel\"}");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -149,6 +175,46 @@ class PendingPluginResourceTest {
|
||||
verify(pluginManager).cancelPending();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Nested
|
||||
class WithoutAuthorization {
|
||||
|
||||
@BeforeEach
|
||||
void bindSubject() {
|
||||
ThreadContext.bind(subject);
|
||||
when(subject.isPermitted("plugin:manage")).thenReturn(false);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void unbindSubject() {
|
||||
ThreadContext.unbindSubject();
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldGetPendingAvailablePluginListWithoutInstallAndCancelLink() throws URISyntaxException, UnsupportedEncodingException {
|
||||
AvailablePlugin availablePlugin = createAvailablePlugin("pending-available-plugin");
|
||||
when(availablePlugin.isPending()).thenReturn(true);
|
||||
when(pluginManager.getAvailable()).thenReturn(singletonList(availablePlugin));
|
||||
|
||||
MockHttpRequest request = MockHttpRequest.get("/v2/plugins/pending");
|
||||
dispatcher.invoke(request, response);
|
||||
|
||||
assertThat(response.getStatus()).isEqualTo(HttpServletResponse.SC_OK);
|
||||
assertThat(response.getContentAsString()).contains("\"new\":[{\"name\":\"pending-available-plugin\"");
|
||||
assertThat(response.getContentAsString()).doesNotContain("\"execute\":{\"href\":\"/v2/plugins/pending/execute\"}");
|
||||
assertThat(response.getContentAsString()).doesNotContain("\"cancel\":{\"href\":\"/v2/plugins/pending/cancel\"}");
|
||||
}
|
||||
}
|
||||
|
||||
static class PermissionExceptionMapper implements ExceptionMapper<ShiroException> {
|
||||
|
||||
@Override
|
||||
public Response toResponse(ShiroException exception) {
|
||||
return Response.status(401).entity(exception.getMessage()).build();
|
||||
}
|
||||
}
|
||||
|
||||
private AvailablePlugin createAvailablePlugin(String name) {
|
||||
PluginInformation pluginInformation = new PluginInformation();
|
||||
pluginInformation.setName(name);
|
||||
|
||||
Reference in New Issue
Block a user