diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/UUIDLookupRestController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/UUIDLookupRestController.java index 91555ae026..b20848b3e4 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/UUIDLookupRestController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/UUIDLookupRestController.java @@ -21,10 +21,9 @@ import org.apache.log4j.Logger; import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.model.DSpaceObjectRest; import org.dspace.app.rest.utils.ContextUtil; +import org.dspace.app.rest.utils.DSpaceObjectUtils; import org.dspace.app.rest.utils.Utils; import org.dspace.content.DSpaceObject; -import org.dspace.content.factory.ContentServiceFactory; -import org.dspace.content.service.DSpaceObjectService; import org.dspace.core.Context; import org.dspace.discovery.SearchServiceException; import org.springframework.beans.factory.InitializingBean; @@ -55,7 +54,7 @@ public class UUIDLookupRestController implements InitializingBean { public static final String PARAM = "uuid"; @Autowired - private ContentServiceFactory contentServiceFactory; + private DSpaceObjectUtils dspaceObjectUtil; @Autowired private Utils utils; @@ -91,17 +90,14 @@ public class UUIDLookupRestController implements InitializingBean { Context context = null; try { context = ContextUtil.obtainContext(request); - for (DSpaceObjectService dSpaceObjectService : contentServiceFactory - .getDSpaceObjectServices()) { - DSpaceObject dso = dSpaceObjectService.find(context, uuid); - if (dso != null) { - DSpaceObjectRest dsor = converter.toRest(dso, utils.obtainProjection()); - URI link = linkTo(dsor.getController(), dsor.getCategory(), dsor.getTypePlural()) - .slash(dsor.getId()).toUri(); - response.setStatus(HttpServletResponse.SC_FOUND); - response.sendRedirect(link.toString()); - return; - } + DSpaceObject dso = dspaceObjectUtil.findDSpaceObject(context, uuid); + if (dso != null) { + DSpaceObjectRest dsor = converter.toRest(dso, utils.obtainProjection()); + URI link = linkTo(dsor.getController(), dsor.getCategory(), dsor.getTypePlural()).slash(dsor.getId()) + .toUri(); + response.setStatus(HttpServletResponse.SC_FOUND); + response.sendRedirect(link.toString()); + return; } response.setStatus(HttpServletResponse.SC_NOT_FOUND); } finally { diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ResourcePolicyRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ResourcePolicyRestRepository.java index e26c5be680..cf7d0ac777 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ResourcePolicyRestRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ResourcePolicyRestRepository.java @@ -78,7 +78,7 @@ public class ResourcePolicyRestRepository extends DSpaceRestRepository resource(@Parameter(value = "uuid", required = true) UUID resourceUuid, @Parameter(value = "action", required = false) String action, Pageable pageable) { @@ -103,7 +103,7 @@ public class ResourcePolicyRestRepository extends DSpaceRestRepository eperson(@Parameter(value = "uuid", required = true) UUID epersonUuid, @Parameter(value = "resource", required = false) UUID resourceUuid, Pageable pageable) { @@ -131,7 +131,7 @@ public class ResourcePolicyRestRepository extends DSpaceRestRepository group(@Parameter(value = "uuid", required = true) UUID groupUuid, @Parameter(value = "resource", required = false) UUID resourceUuid, Pageable pageable) { diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/DSpaceObjectRestPermissionEvaluatorPlugin.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/DSpaceObjectRestPermissionEvaluatorPlugin.java new file mode 100644 index 0000000000..fd39ae869a --- /dev/null +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/DSpaceObjectRestPermissionEvaluatorPlugin.java @@ -0,0 +1,61 @@ +package org.dspace.app.rest.security; + +import java.io.Serializable; +import java.sql.SQLException; +import java.util.UUID; + +import org.apache.commons.lang3.StringUtils; +import org.dspace.app.rest.utils.ContextUtil; +import org.dspace.app.rest.utils.DSpaceObjectUtils; +import org.dspace.authorize.service.AuthorizeService; +import org.dspace.content.DSpaceObject; +import org.dspace.core.Context; +import org.dspace.services.RequestService; +import org.dspace.services.model.Request; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.Authentication; +import org.springframework.stereotype.Component; + +@Component +public class DSpaceObjectRestPermissionEvaluatorPlugin extends RestObjectPermissionEvaluatorPlugin { + + private static final Logger log = LoggerFactory.getLogger(ResourcePolicyRestPermissionEvaluatorPlugin.class); + + public static final String DSPACE_OBJECT = "dspaceObject"; + + @Autowired + AuthorizeService authorizeService; + + @Autowired + private RequestService requestService; + + @Autowired + private DSpaceObjectUtils dspaceObjectUtil; + + @Override + public boolean hasDSpacePermission(Authentication authentication, Serializable targetId, String targetType, + DSpaceRestPermission permission) { + + DSpaceRestPermission restPermission = DSpaceRestPermission.convert(permission); + + if (!DSpaceRestPermission.ADMIN.equals(restPermission) + || !StringUtils.equalsIgnoreCase(targetType, DSPACE_OBJECT)) { + return false; + } + + Request request = requestService.getCurrentRequest(); + Context context = ContextUtil.obtainContext(request.getServletRequest()); + + try { + UUID dsoUuid = UUID.fromString(targetId.toString()); + DSpaceObject dso = dspaceObjectUtil.findDSpaceObject(context, dsoUuid); + return authorizeService.isAdmin(context, dso); + } catch (SQLException e) { + log.error(e.getMessage(), e); + } + return false; + } + +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/DSpaceRestPermission.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/DSpaceRestPermission.java index 3dd19ce30a..0f7b4912ce 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/DSpaceRestPermission.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/DSpaceRestPermission.java @@ -17,7 +17,8 @@ public enum DSpaceRestPermission { READ(Constants.READ), WRITE(Constants.WRITE), DELETE(Constants.DELETE), - ADD(Constants.ADD); + ADD(Constants.ADD), + ADMIN(Constants.ADMIN); private int dspaceApiActionId; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/DSpaceObjectUtils.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/DSpaceObjectUtils.java new file mode 100644 index 0000000000..e1c779ddba --- /dev/null +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/DSpaceObjectUtils.java @@ -0,0 +1,36 @@ +package org.dspace.app.rest.utils; + +import java.sql.SQLException; +import java.util.UUID; + +import org.dspace.content.DSpaceObject; +import org.dspace.content.factory.ContentServiceFactory; +import org.dspace.content.service.DSpaceObjectService; +import org.dspace.core.Context; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + + +/** + * + * + * @author Mykhaylo Boychuk (4science.it) + */ +@Component +public class DSpaceObjectUtils { + + @Autowired + private ContentServiceFactory contentServiceFactory; + + public DSpaceObject findDSpaceObject(Context context, UUID uuid) throws SQLException { + for (DSpaceObjectService dSpaceObjectService : + contentServiceFactory.getDSpaceObjectServices()) { + DSpaceObject dso = dSpaceObjectService.find(context, uuid); + if (dso != null) { + return dso; + } + } + return null; + } + +} diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ResourcePolicyRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ResourcePolicyRestRepositoryIT.java index 02e4aba87c..6ad82cd358 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ResourcePolicyRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ResourcePolicyRestRepositoryIT.java @@ -386,7 +386,7 @@ public class ResourcePolicyRestRepositoryIT extends AbstractControllerIntegratio String authToken = getAuthToken(eperson1.getEmail(), "qwerty01"); getClient(authToken).perform(get("/api/authz/resourcepolicies/search/eperson") - .param("uuid", eperson1.getID().toString()) + .param("uuid", eperson2.getID().toString()) .param("resource", community2.getID().toString())) .andExpect(status().isForbidden()); } @@ -410,7 +410,7 @@ public class ResourcePolicyRestRepositoryIT extends AbstractControllerIntegratio ResourcePolicy firstResourcePolicyOfEPerson1 = ResourcePolicyBuilder.createResourcePolicy(context) .withDspaceObject(community) - .withAction(Constants.WRITE) + .withAction(Constants.ADMIN) .withPolicyType(ResourcePolicy.TYPE_CUSTOM) .withUser(eperson1).build(); @@ -443,7 +443,7 @@ public class ResourcePolicyRestRepositoryIT extends AbstractControllerIntegratio } @Test - public void searchResourcePoliciesOfOneResourceWithActionTest() throws Exception { + public void searchResourcePoliciesOfOneResourceIsOwnerTest() throws Exception { context.turnOffAuthorisationSystem(); EPerson eperson1 = EPersonBuilder.createEPerson(context) @@ -463,13 +463,7 @@ public class ResourcePolicyRestRepositoryIT extends AbstractControllerIntegratio ResourcePolicy firstResourcePolicyOfEPerson1 = ResourcePolicyBuilder.createResourcePolicy(context) .withDspaceObject(collection) - .withAction(Constants.WRITE) - .withPolicyType(ResourcePolicy.TYPE_CUSTOM) - .withUser(eperson1).build(); - - ResourcePolicy secondResourcePolicyOfEPerson1 = ResourcePolicyBuilder.createResourcePolicy(context) - .withDspaceObject(collection) - .withAction(Constants.ADD) + .withAction(Constants.ADMIN) .withPolicyType(ResourcePolicy.TYPE_CUSTOM) .withUser(eperson1).build(); @@ -487,13 +481,18 @@ public class ResourcePolicyRestRepositoryIT extends AbstractControllerIntegratio .param("action", "ADD")) .andExpect(status().isOk()) .andExpect(content().contentType(contentType)) - .andExpect(jsonPath("$._embedded.resourcepolicies",Matchers.containsInAnyOrder( - ResoucePolicyMatcher.matchResourcePolicy(secondResourcePolicyOfEPerson1), + .andExpect(jsonPath("$._embedded.resourcepolicies",Matchers.contains( ResoucePolicyMatcher.matchResourcePolicy(firstResourcePolicyOfEPerson2) ))) .andExpect(jsonPath("$._links.self.href", Matchers.containsString("api/authz/resourcepolicies/search/resource"))) - .andExpect(jsonPath("$.page.totalElements", is(2))); + .andExpect(jsonPath("$.page.totalElements", is(1))); + + String authToken2 = getAuthToken(eperson2.getEmail(), "qwerty02"); + getClient(authToken2).perform(get("/api/authz/resourcepolicies/search/resource") + .param("uuid", collection.getID().toString()) + .param("action", "ADD")) + .andExpect(status().isForbidden()); } /** @@ -552,6 +551,7 @@ public class ResourcePolicyRestRepositoryIT extends AbstractControllerIntegratio .andExpect(jsonPath("$.page.totalElements", is(0))); } + @Test public void searchResoucesPoliciesByResourceUuidForbiddenTest() throws Exception { context.turnOffAuthorisationSystem(); @@ -591,6 +591,7 @@ public class ResourcePolicyRestRepositoryIT extends AbstractControllerIntegratio .andExpect(status().isForbidden()); } + @Test public void searchResourcePolicyByGroupUuidTest() throws Exception { context.turnOffAuthorisationSystem(); @@ -603,12 +604,6 @@ public class ResourcePolicyRestRepositoryIT extends AbstractControllerIntegratio .withGroupMembership(group1) .build(); - EPerson eperson2 = EPersonBuilder.createEPerson(context) - .withEmail("eperson2@mail.com") - .withPassword("qwerty02") - .withGroupMembership(group1) - .build(); - Community community = CommunityBuilder.createCommunity(context) .withName("My community") .build(); @@ -624,11 +619,11 @@ public class ResourcePolicyRestRepositoryIT extends AbstractControllerIntegratio ResourcePolicy secondResourcePolicyOfGroup1 = ResourcePolicyBuilder.createResourcePolicy(context) .withDspaceObject(community) - .withAction(Constants.REMOVE) + .withAction(Constants.READ) .withGroup(group1).build(); ResourcePolicy collectionResourcePolicyOfGroup1 = ResourcePolicyBuilder.createResourcePolicy(context) - .withDspaceObject(community) + .withDspaceObject(collection) .withAction(Constants.WRITE) .withGroup(group1).build();