Class:
		- DSpaceObjectRestPermissionEvaluatorPlugin
		- DSpaceObjectUtils - this class contain the method that permit to find some DSpaceObject by UUID
This commit is contained in:
Mykhaylo Boychuk
2019-12-09 16:30:07 +01:00
parent fbdee987c9
commit 0178c6b490
6 changed files with 128 additions and 39 deletions

View File

@@ -21,10 +21,9 @@ import org.apache.log4j.Logger;
import org.dspace.app.rest.converter.ConverterService; import org.dspace.app.rest.converter.ConverterService;
import org.dspace.app.rest.model.DSpaceObjectRest; import org.dspace.app.rest.model.DSpaceObjectRest;
import org.dspace.app.rest.utils.ContextUtil; import org.dspace.app.rest.utils.ContextUtil;
import org.dspace.app.rest.utils.DSpaceObjectUtils;
import org.dspace.app.rest.utils.Utils; import org.dspace.app.rest.utils.Utils;
import org.dspace.content.DSpaceObject; 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.core.Context;
import org.dspace.discovery.SearchServiceException; import org.dspace.discovery.SearchServiceException;
import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.InitializingBean;
@@ -55,7 +54,7 @@ public class UUIDLookupRestController implements InitializingBean {
public static final String PARAM = "uuid"; public static final String PARAM = "uuid";
@Autowired @Autowired
private ContentServiceFactory contentServiceFactory; private DSpaceObjectUtils dspaceObjectUtil;
@Autowired @Autowired
private Utils utils; private Utils utils;
@@ -91,17 +90,14 @@ public class UUIDLookupRestController implements InitializingBean {
Context context = null; Context context = null;
try { try {
context = ContextUtil.obtainContext(request); context = ContextUtil.obtainContext(request);
for (DSpaceObjectService<? extends DSpaceObject> dSpaceObjectService : contentServiceFactory DSpaceObject dso = dspaceObjectUtil.findDSpaceObject(context, uuid);
.getDSpaceObjectServices()) { if (dso != null) {
DSpaceObject dso = dSpaceObjectService.find(context, uuid); DSpaceObjectRest dsor = converter.toRest(dso, utils.obtainProjection());
if (dso != null) { URI link = linkTo(dsor.getController(), dsor.getCategory(), dsor.getTypePlural()).slash(dsor.getId())
DSpaceObjectRest dsor = converter.toRest(dso, utils.obtainProjection()); .toUri();
URI link = linkTo(dsor.getController(), dsor.getCategory(), dsor.getTypePlural()) response.setStatus(HttpServletResponse.SC_FOUND);
.slash(dsor.getId()).toUri(); response.sendRedirect(link.toString());
response.setStatus(HttpServletResponse.SC_FOUND); return;
response.sendRedirect(link.toString());
return;
}
} }
response.setStatus(HttpServletResponse.SC_NOT_FOUND); response.setStatus(HttpServletResponse.SC_NOT_FOUND);
} finally { } finally {

View File

@@ -78,7 +78,7 @@ public class ResourcePolicyRestRepository extends DSpaceRestRepository<ResourceP
return ResourcePolicyRest.class; return ResourcePolicyRest.class;
} }
@PreAuthorize("hasAuthority('AUTHENTICATED')") @PreAuthorize("hasPermission(#resourceUuid, 'dspaceObject', 'ADMIN')")
@SearchRestMethod(name = "resource") @SearchRestMethod(name = "resource")
public Page<ResourcePolicyRest> resource(@Parameter(value = "uuid", required = true) UUID resourceUuid, public Page<ResourcePolicyRest> resource(@Parameter(value = "uuid", required = true) UUID resourceUuid,
@Parameter(value = "action", required = false) String action, Pageable pageable) { @Parameter(value = "action", required = false) String action, Pageable pageable) {
@@ -103,7 +103,7 @@ public class ResourcePolicyRestRepository extends DSpaceRestRepository<ResourceP
return converter.toRestPage(resourcePolisies, pageable, total, utils.obtainProjection(true)); return converter.toRestPage(resourcePolisies, pageable, total, utils.obtainProjection(true));
} }
@PreAuthorize("hasAuthority('AUTHENTICATED')") @PreAuthorize("hasPermission(#epersonUuid, 'EPERSON', 'READ')")
@SearchRestMethod(name = "eperson") @SearchRestMethod(name = "eperson")
public Page<ResourcePolicyRest> eperson(@Parameter(value = "uuid", required = true) UUID epersonUuid, public Page<ResourcePolicyRest> eperson(@Parameter(value = "uuid", required = true) UUID epersonUuid,
@Parameter(value = "resource", required = false) UUID resourceUuid, Pageable pageable) { @Parameter(value = "resource", required = false) UUID resourceUuid, Pageable pageable) {
@@ -131,7 +131,7 @@ public class ResourcePolicyRestRepository extends DSpaceRestRepository<ResourceP
return converter.toRestPage(resourcePolisies, pageable, total, utils.obtainProjection(true)); return converter.toRestPage(resourcePolisies, pageable, total, utils.obtainProjection(true));
} }
@PreAuthorize("hasAuthority('AUTHENTICATED')") @PreAuthorize("hasPermission(#groupUuid, 'GROUP', 'READ')")
@SearchRestMethod(name = "group") @SearchRestMethod(name = "group")
public Page<ResourcePolicyRest> group(@Parameter(value = "uuid", required = true) UUID groupUuid, public Page<ResourcePolicyRest> group(@Parameter(value = "uuid", required = true) UUID groupUuid,
@Parameter(value = "resource", required = false) UUID resourceUuid, Pageable pageable) { @Parameter(value = "resource", required = false) UUID resourceUuid, Pageable pageable) {

View File

@@ -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;
}
}

View File

@@ -17,7 +17,8 @@ public enum DSpaceRestPermission {
READ(Constants.READ), READ(Constants.READ),
WRITE(Constants.WRITE), WRITE(Constants.WRITE),
DELETE(Constants.DELETE), DELETE(Constants.DELETE),
ADD(Constants.ADD); ADD(Constants.ADD),
ADMIN(Constants.ADMIN);
private int dspaceApiActionId; private int dspaceApiActionId;

View File

@@ -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<? extends DSpaceObject> dSpaceObjectService :
contentServiceFactory.getDSpaceObjectServices()) {
DSpaceObject dso = dSpaceObjectService.find(context, uuid);
if (dso != null) {
return dso;
}
}
return null;
}
}

View File

@@ -386,7 +386,7 @@ public class ResourcePolicyRestRepositoryIT extends AbstractControllerIntegratio
String authToken = getAuthToken(eperson1.getEmail(), "qwerty01"); String authToken = getAuthToken(eperson1.getEmail(), "qwerty01");
getClient(authToken).perform(get("/api/authz/resourcepolicies/search/eperson") getClient(authToken).perform(get("/api/authz/resourcepolicies/search/eperson")
.param("uuid", eperson1.getID().toString()) .param("uuid", eperson2.getID().toString())
.param("resource", community2.getID().toString())) .param("resource", community2.getID().toString()))
.andExpect(status().isForbidden()); .andExpect(status().isForbidden());
} }
@@ -410,7 +410,7 @@ public class ResourcePolicyRestRepositoryIT extends AbstractControllerIntegratio
ResourcePolicy firstResourcePolicyOfEPerson1 = ResourcePolicyBuilder.createResourcePolicy(context) ResourcePolicy firstResourcePolicyOfEPerson1 = ResourcePolicyBuilder.createResourcePolicy(context)
.withDspaceObject(community) .withDspaceObject(community)
.withAction(Constants.WRITE) .withAction(Constants.ADMIN)
.withPolicyType(ResourcePolicy.TYPE_CUSTOM) .withPolicyType(ResourcePolicy.TYPE_CUSTOM)
.withUser(eperson1).build(); .withUser(eperson1).build();
@@ -443,7 +443,7 @@ public class ResourcePolicyRestRepositoryIT extends AbstractControllerIntegratio
} }
@Test @Test
public void searchResourcePoliciesOfOneResourceWithActionTest() throws Exception { public void searchResourcePoliciesOfOneResourceIsOwnerTest() throws Exception {
context.turnOffAuthorisationSystem(); context.turnOffAuthorisationSystem();
EPerson eperson1 = EPersonBuilder.createEPerson(context) EPerson eperson1 = EPersonBuilder.createEPerson(context)
@@ -463,13 +463,7 @@ public class ResourcePolicyRestRepositoryIT extends AbstractControllerIntegratio
ResourcePolicy firstResourcePolicyOfEPerson1 = ResourcePolicyBuilder.createResourcePolicy(context) ResourcePolicy firstResourcePolicyOfEPerson1 = ResourcePolicyBuilder.createResourcePolicy(context)
.withDspaceObject(collection) .withDspaceObject(collection)
.withAction(Constants.WRITE) .withAction(Constants.ADMIN)
.withPolicyType(ResourcePolicy.TYPE_CUSTOM)
.withUser(eperson1).build();
ResourcePolicy secondResourcePolicyOfEPerson1 = ResourcePolicyBuilder.createResourcePolicy(context)
.withDspaceObject(collection)
.withAction(Constants.ADD)
.withPolicyType(ResourcePolicy.TYPE_CUSTOM) .withPolicyType(ResourcePolicy.TYPE_CUSTOM)
.withUser(eperson1).build(); .withUser(eperson1).build();
@@ -487,13 +481,18 @@ public class ResourcePolicyRestRepositoryIT extends AbstractControllerIntegratio
.param("action", "ADD")) .param("action", "ADD"))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(content().contentType(contentType)) .andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.resourcepolicies",Matchers.containsInAnyOrder( .andExpect(jsonPath("$._embedded.resourcepolicies",Matchers.contains(
ResoucePolicyMatcher.matchResourcePolicy(secondResourcePolicyOfEPerson1),
ResoucePolicyMatcher.matchResourcePolicy(firstResourcePolicyOfEPerson2) ResoucePolicyMatcher.matchResourcePolicy(firstResourcePolicyOfEPerson2)
))) )))
.andExpect(jsonPath("$._links.self.href", .andExpect(jsonPath("$._links.self.href",
Matchers.containsString("api/authz/resourcepolicies/search/resource"))) 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))); .andExpect(jsonPath("$.page.totalElements", is(0)));
} }
@Test @Test
public void searchResoucesPoliciesByResourceUuidForbiddenTest() throws Exception { public void searchResoucesPoliciesByResourceUuidForbiddenTest() throws Exception {
context.turnOffAuthorisationSystem(); context.turnOffAuthorisationSystem();
@@ -591,6 +591,7 @@ public class ResourcePolicyRestRepositoryIT extends AbstractControllerIntegratio
.andExpect(status().isForbidden()); .andExpect(status().isForbidden());
} }
@Test @Test
public void searchResourcePolicyByGroupUuidTest() throws Exception { public void searchResourcePolicyByGroupUuidTest() throws Exception {
context.turnOffAuthorisationSystem(); context.turnOffAuthorisationSystem();
@@ -603,12 +604,6 @@ public class ResourcePolicyRestRepositoryIT extends AbstractControllerIntegratio
.withGroupMembership(group1) .withGroupMembership(group1)
.build(); .build();
EPerson eperson2 = EPersonBuilder.createEPerson(context)
.withEmail("eperson2@mail.com")
.withPassword("qwerty02")
.withGroupMembership(group1)
.build();
Community community = CommunityBuilder.createCommunity(context) Community community = CommunityBuilder.createCommunity(context)
.withName("My community") .withName("My community")
.build(); .build();
@@ -624,11 +619,11 @@ public class ResourcePolicyRestRepositoryIT extends AbstractControllerIntegratio
ResourcePolicy secondResourcePolicyOfGroup1 = ResourcePolicyBuilder.createResourcePolicy(context) ResourcePolicy secondResourcePolicyOfGroup1 = ResourcePolicyBuilder.createResourcePolicy(context)
.withDspaceObject(community) .withDspaceObject(community)
.withAction(Constants.REMOVE) .withAction(Constants.READ)
.withGroup(group1).build(); .withGroup(group1).build();
ResourcePolicy collectionResourcePolicyOfGroup1 = ResourcePolicyBuilder.createResourcePolicy(context) ResourcePolicy collectionResourcePolicyOfGroup1 = ResourcePolicyBuilder.createResourcePolicy(context)
.withDspaceObject(community) .withDspaceObject(collection)
.withAction(Constants.WRITE) .withAction(Constants.WRITE)
.withGroup(group1).build(); .withGroup(group1).build();