mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-15 09:46:16 +01:00
Better rest
This commit is contained in:
@@ -33,6 +33,7 @@ public class VndMediaType {
|
|||||||
public static final String REPOSITORY_COLLECTION = PREFIX + "repositoryCollection" + SUFFIX;
|
public static final String REPOSITORY_COLLECTION = PREFIX + "repositoryCollection" + SUFFIX;
|
||||||
public static final String BRANCH_COLLECTION = PREFIX + "branchCollection" + SUFFIX;
|
public static final String BRANCH_COLLECTION = PREFIX + "branchCollection" + SUFFIX;
|
||||||
public static final String CONFIG = PREFIX + "config" + SUFFIX;
|
public static final String CONFIG = PREFIX + "config" + SUFFIX;
|
||||||
|
public static final String REPOSITORY_PERMISSION_COLLECTION = PREFIX + "repositoryPermissionCollection" + SUFFIX;
|
||||||
public static final String REPOSITORY_TYPE_COLLECTION = PREFIX + "repositoryTypeCollection" + SUFFIX;
|
public static final String REPOSITORY_TYPE_COLLECTION = PREFIX + "repositoryTypeCollection" + SUFFIX;
|
||||||
public static final String REPOSITORY_TYPE = PREFIX + "repositoryType" + SUFFIX;
|
public static final String REPOSITORY_TYPE = PREFIX + "repositoryType" + SUFFIX;
|
||||||
public static final String UI_PLUGIN = PREFIX + "uiPlugin" + SUFFIX;
|
public static final String UI_PLUGIN = PREFIX + "uiPlugin" + SUFFIX;
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package sonia.scm.api.v2.resources;
|
||||||
|
|
||||||
|
import de.otto.edison.hal.HalRepresentation;
|
||||||
|
import de.otto.edison.hal.Links;
|
||||||
|
import sonia.scm.security.RepositoryRole;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
public class AvailableRepositoryPermissionsDto extends HalRepresentation {
|
||||||
|
private final Collection<String> availableVerbs;
|
||||||
|
private final Collection<RepositoryRole> availableRoles;
|
||||||
|
|
||||||
|
public AvailableRepositoryPermissionsDto(Collection<String> availableVerbs, Collection<RepositoryRole> availableRoles) {
|
||||||
|
this.availableVerbs = availableVerbs;
|
||||||
|
this.availableRoles = availableRoles;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<String> getAvailableVerbs() {
|
||||||
|
return availableVerbs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<RepositoryRole> getAvailableRoles() {
|
||||||
|
return availableRoles;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("squid:S1185") // We want to have this method available in this package
|
||||||
|
protected HalRepresentation add(Links links) {
|
||||||
|
return super.add(links);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ package sonia.scm.api.v2.resources;
|
|||||||
|
|
||||||
import com.webcohesion.enunciate.metadata.rs.ResponseCode;
|
import com.webcohesion.enunciate.metadata.rs.ResponseCode;
|
||||||
import com.webcohesion.enunciate.metadata.rs.StatusCodes;
|
import com.webcohesion.enunciate.metadata.rs.StatusCodes;
|
||||||
|
import de.otto.edison.hal.Links;
|
||||||
import sonia.scm.security.RepositoryPermissionProvider;
|
import sonia.scm.security.RepositoryPermissionProvider;
|
||||||
import sonia.scm.web.VndMediaType;
|
import sonia.scm.web.VndMediaType;
|
||||||
|
|
||||||
@@ -9,7 +10,6 @@ import javax.inject.Inject;
|
|||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.Produces;
|
import javax.ws.rs.Produces;
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RESTful Web Service Resource to get available repository types.
|
* RESTful Web Service Resource to get available repository types.
|
||||||
@@ -20,31 +20,24 @@ public class RepositoryPermissionResource {
|
|||||||
static final String PATH = "v2/repositoryPermissions/";
|
static final String PATH = "v2/repositoryPermissions/";
|
||||||
|
|
||||||
private final RepositoryPermissionProvider repositoryPermissionProvider;
|
private final RepositoryPermissionProvider repositoryPermissionProvider;
|
||||||
|
private final ResourceLinks resourceLinks;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public RepositoryPermissionResource(RepositoryPermissionProvider repositoryPermissionProvider) {
|
public RepositoryPermissionResource(RepositoryPermissionProvider repositoryPermissionProvider, ResourceLinks resourceLinks) {
|
||||||
this.repositoryPermissionProvider = repositoryPermissionProvider;
|
this.repositoryPermissionProvider = repositoryPermissionProvider;
|
||||||
|
this.resourceLinks = resourceLinks;
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Path("verbs")
|
@Path("")
|
||||||
@StatusCodes({
|
@StatusCodes({
|
||||||
@ResponseCode(code = 200, condition = "success"),
|
@ResponseCode(code = 200, condition = "success"),
|
||||||
@ResponseCode(code = 500, condition = "internal server error")
|
@ResponseCode(code = 500, condition = "internal server error")
|
||||||
})
|
})
|
||||||
@Produces(VndMediaType.REPOSITORY_TYPE_COLLECTION)
|
@Produces(VndMediaType.REPOSITORY_PERMISSION_COLLECTION)
|
||||||
public Collection<String> getRepositoryPermissionVerbs() {
|
public AvailableRepositoryPermissionsDto get() {
|
||||||
return repositoryPermissionProvider.availableVerbs();
|
AvailableRepositoryPermissionsDto dto = new AvailableRepositoryPermissionsDto(repositoryPermissionProvider.availableVerbs(), repositoryPermissionProvider.availableRoles());
|
||||||
}
|
dto.add(Links.linkingTo().self(resourceLinks.availableRepositoryPermissions().self()).build());
|
||||||
|
return dto;
|
||||||
@GET
|
|
||||||
@Path("roles")
|
|
||||||
@StatusCodes({
|
|
||||||
@ResponseCode(code = 200, condition = "success"),
|
|
||||||
@ResponseCode(code = 500, condition = "internal server error")
|
|
||||||
})
|
|
||||||
@Produces(VndMediaType.REPOSITORY_TYPE_COLLECTION)
|
|
||||||
public Collection getRepositoryRoles() {
|
|
||||||
return repositoryPermissionProvider.availableRoles();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -639,14 +639,30 @@ class ResourceLinks {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static class PermissionsLinks {
|
static class PermissionsLinks {
|
||||||
private final LinkBuilder permissionsLlinkBuilder;
|
private final LinkBuilder permissionsLinkBuilder;
|
||||||
|
|
||||||
PermissionsLinks(ScmPathInfo scmPathInfo) {
|
PermissionsLinks(ScmPathInfo scmPathInfo) {
|
||||||
this.permissionsLlinkBuilder = new LinkBuilder(scmPathInfo, GlobalPermissionResource.class);
|
this.permissionsLinkBuilder = new LinkBuilder(scmPathInfo, GlobalPermissionResource.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
String self() {
|
String self() {
|
||||||
return permissionsLlinkBuilder.method("getAll").parameters().href();
|
return permissionsLinkBuilder.method("getAll").parameters().href();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public AvailableRepositoryPermissionLinks availableRepositoryPermissions() {
|
||||||
|
return new AvailableRepositoryPermissionLinks(scmPathInfoStore.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
static class AvailableRepositoryPermissionLinks {
|
||||||
|
private final LinkBuilder linkBuilder;
|
||||||
|
|
||||||
|
AvailableRepositoryPermissionLinks(ScmPathInfo scmPathInfo) {
|
||||||
|
this.linkBuilder = new LinkBuilder(scmPathInfo, RepositoryPermissionResource.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
String self() {
|
||||||
|
return linkBuilder.method("get").parameters().href();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
<verb>push</verb>
|
<verb>push</verb>
|
||||||
<verb>permissionRead</verb>
|
<verb>permissionRead</verb>
|
||||||
<verb>permissionWrite</verb>
|
<verb>permissionWrite</verb>
|
||||||
|
<verb>*</verb>
|
||||||
</verbs>
|
</verbs>
|
||||||
<roles>
|
<roles>
|
||||||
<role>
|
<role>
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ public class ResourceLinksMock {
|
|||||||
when(resourceLinks.index()).thenReturn(new ResourceLinks.IndexLinks(uriInfo));
|
when(resourceLinks.index()).thenReturn(new ResourceLinks.IndexLinks(uriInfo));
|
||||||
when(resourceLinks.merge()).thenReturn(new ResourceLinks.MergeLinks(uriInfo));
|
when(resourceLinks.merge()).thenReturn(new ResourceLinks.MergeLinks(uriInfo));
|
||||||
when(resourceLinks.permissions()).thenReturn(new ResourceLinks.PermissionsLinks(uriInfo));
|
when(resourceLinks.permissions()).thenReturn(new ResourceLinks.PermissionsLinks(uriInfo));
|
||||||
|
when(resourceLinks.availableRepositoryPermissions()).thenReturn(new ResourceLinks.AvailableRepositoryPermissionLinks(uriInfo));
|
||||||
|
|
||||||
return resourceLinks;
|
return resourceLinks;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import org.junit.jupiter.api.BeforeEach;
|
|||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import sonia.scm.plugin.PluginLoader;
|
import sonia.scm.plugin.PluginLoader;
|
||||||
import sonia.scm.repository.RepositoryPermissions;
|
import sonia.scm.repository.RepositoryPermissions;
|
||||||
import sonia.scm.store.ConfigurationEntryStoreFactory;
|
|
||||||
import sonia.scm.util.ClassLoaders;
|
import sonia.scm.util.ClassLoaders;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
@@ -25,7 +24,6 @@ class RepositoryPermissionProviderTest {
|
|||||||
void init() {
|
void init() {
|
||||||
PluginLoader pluginLoader = mock(PluginLoader.class);
|
PluginLoader pluginLoader = mock(PluginLoader.class);
|
||||||
when(pluginLoader.getUberClassLoader()).thenReturn(ClassLoaders.getContextClassLoader(DefaultSecuritySystem.class));
|
when(pluginLoader.getUberClassLoader()).thenReturn(ClassLoaders.getContextClassLoader(DefaultSecuritySystem.class));
|
||||||
ConfigurationEntryStoreFactory configurationEntryStoreFactory = mock(ConfigurationEntryStoreFactory.class);
|
|
||||||
repositoryPermissionProvider = new RepositoryPermissionProvider(pluginLoader);
|
repositoryPermissionProvider = new RepositoryPermissionProvider(pluginLoader);
|
||||||
allVerbsFromRepositoryClass = Arrays.stream(RepositoryPermissions.class.getDeclaredFields())
|
allVerbsFromRepositoryClass = Arrays.stream(RepositoryPermissions.class.getDeclaredFields())
|
||||||
.filter(field -> field.getName().startsWith("ACTION_"))
|
.filter(field -> field.getName().startsWith("ACTION_"))
|
||||||
@@ -37,13 +35,11 @@ class RepositoryPermissionProviderTest {
|
|||||||
@Test
|
@Test
|
||||||
void shouldReadAvailableRoles() {
|
void shouldReadAvailableRoles() {
|
||||||
assertThat(repositoryPermissionProvider.availableRoles()).isNotEmpty();
|
assertThat(repositoryPermissionProvider.availableRoles()).isNotEmpty();
|
||||||
assertThat(repositoryPermissionProvider.availableRoles()).allSatisfy(this::eitherStarOrOnlyAvailableVerbs);
|
assertThat(repositoryPermissionProvider.availableRoles()).allSatisfy(this::containsOnlyAvailableVerbs);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void eitherStarOrOnlyAvailableVerbs(RepositoryRole role) {
|
private void containsOnlyAvailableVerbs(RepositoryRole role) {
|
||||||
if (!role.getVerbs().contains("*") || role.getVerbs().size() > 1) {
|
assertThat(role.getVerbs()).isSubsetOf(repositoryPermissionProvider.availableVerbs());
|
||||||
assertThat(role.getVerbs()).isSubsetOf(allVerbsFromRepositoryClass);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
Reference in New Issue
Block a user