mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-07 01:54:22 +00:00
Merge branch 'main' into CST-5303-LiveImport-3PR
This commit is contained in:
10
.github/workflows/docker.yml
vendored
10
.github/workflows/docker.yml
vendored
@@ -41,6 +41,10 @@ jobs:
|
||||
- name: Setup Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
|
||||
# https://github.com/docker/setup-qemu-action
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
|
||||
# https://github.com/docker/login-action
|
||||
- name: Login to DockerHub
|
||||
# Only login if not a PR, as PRs only trigger a Docker build and not a push
|
||||
@@ -70,6 +74,7 @@ jobs:
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile.dependencies
|
||||
platforms: linux/amd64,linux/arm64
|
||||
# For pull requests, we run the Docker build (to ensure no PR changes break the build),
|
||||
# but we ONLY do an image push to DockerHub if it's NOT a PR
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
@@ -95,6 +100,7 @@ jobs:
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile
|
||||
platforms: linux/amd64,linux/arm64
|
||||
# For pull requests, we run the Docker build (to ensure no PR changes break the build),
|
||||
# but we ONLY do an image push to DockerHub if it's NOT a PR
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
@@ -123,6 +129,7 @@ jobs:
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile.test
|
||||
platforms: linux/amd64,linux/arm64
|
||||
# For pull requests, we run the Docker build (to ensure no PR changes break the build),
|
||||
# but we ONLY do an image push to DockerHub if it's NOT a PR
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
@@ -148,9 +155,10 @@ jobs:
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile.cli
|
||||
platforms: linux/amd64,linux/arm64
|
||||
# For pull requests, we run the Docker build (to ensure no PR changes break the build),
|
||||
# but we ONLY do an image push to DockerHub if it's NOT a PR
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
# Use tags / labels provided by 'docker/metadata-action' above
|
||||
tags: ${{ steps.meta_build_cli.outputs.tags }}
|
||||
labels: ${{ steps.meta_build_cli.outputs.labels }}
|
||||
labels: ${{ steps.meta_build_cli.outputs.labels }}
|
||||
|
@@ -119,3 +119,4 @@ org.dspace.app.rest.exception.RESTEmptyWorkflowGroupException.message = Refused
|
||||
workflow group {1}. Delete the tasks and group first if you want to remove this user.
|
||||
org.dspace.app.rest.exception.EPersonNameNotProvidedException.message = The eperson.firstname and eperson.lastname values need to be filled in
|
||||
org.dspace.app.rest.exception.GroupNameNotProvidedException.message = Cannot create group, no group name is provided
|
||||
org.dspace.app.rest.exception.GroupHasPendingWorkflowTasksException.message = Cannot delete group, the associated workflow role still has pending tasks
|
||||
|
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.app.rest;
|
||||
|
||||
import static org.dspace.app.rest.utils.ContextUtil.obtainContext;
|
||||
import static org.dspace.app.rest.utils.RegexUtils.REGEX_REQUESTMAPPING_IDENTIFIER_AS_DIGIT;
|
||||
import static org.dspace.core.Constants.EPERSON;
|
||||
import static org.springframework.web.bind.annotation.RequestMethod.PUT;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.dspace.app.rest.exception.UnprocessableEntityException;
|
||||
import org.dspace.app.rest.utils.Utils;
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.authorize.ResourcePolicy;
|
||||
import org.dspace.authorize.service.ResourcePolicyService;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.eperson.EPerson;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.rest.webmvc.ControllerUtils;
|
||||
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
|
||||
import org.springframework.hateoas.RepresentationModel;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* This controller will handle all the incoming calls on the/api/authz/resourcepolicies/{id}/eperson endpoint
|
||||
* where the id corresponds to the ResourcePolicy of which you want to replace the related EPerson.
|
||||
*
|
||||
* @author Mykhaylo Boychuk (mykhaylo.boychuk@4science.com)
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api/authz/resourcepolicies" + REGEX_REQUESTMAPPING_IDENTIFIER_AS_DIGIT + "/eperson")
|
||||
public class ResourcePolicyEPersonReplaceRestController {
|
||||
|
||||
@Autowired
|
||||
private Utils utils;
|
||||
@Autowired
|
||||
private ResourcePolicyService resourcePolicyService;
|
||||
|
||||
@PreAuthorize("hasPermission(#id, 'resourcepolicy', 'ADMIN')")
|
||||
@RequestMapping(method = PUT, consumes = {"text/uri-list"})
|
||||
public ResponseEntity<RepresentationModel<?>> replaceEPersonOfResourcePolicy(@PathVariable Integer id,
|
||||
HttpServletResponse response, HttpServletRequest request) throws SQLException, AuthorizeException {
|
||||
|
||||
Context context = obtainContext(request);
|
||||
List<DSpaceObject> dsoList = utils.constructDSpaceObjectList(context, utils.getStringListFromRequest(request));
|
||||
|
||||
if (dsoList.size() != 1 || dsoList.get(0).getType() != EPERSON) {
|
||||
throw new UnprocessableEntityException(
|
||||
"The EPerson doesn't exist or the data cannot be resolved to an EPerson.");
|
||||
}
|
||||
|
||||
ResourcePolicy resourcePolicy = resourcePolicyService.find(context, id);
|
||||
if (Objects.isNull(resourcePolicy)) {
|
||||
throw new ResourceNotFoundException("ResourcePolicy with id: " + id + " not found");
|
||||
}
|
||||
|
||||
if (Objects.isNull(resourcePolicy.getEPerson())) {
|
||||
throw new UnprocessableEntityException("ResourcePolicy with id:" + id + " doesn't linked to an EPerson");
|
||||
}
|
||||
EPerson newEPerson = (EPerson) dsoList.get(0);
|
||||
resourcePolicy.setEPerson(newEPerson);
|
||||
context.commit();
|
||||
return ControllerUtils.toEmptyResponse(HttpStatus.NO_CONTENT);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.app.rest;
|
||||
|
||||
import static org.dspace.app.rest.utils.ContextUtil.obtainContext;
|
||||
import static org.dspace.app.rest.utils.RegexUtils.REGEX_REQUESTMAPPING_IDENTIFIER_AS_DIGIT;
|
||||
import static org.dspace.core.Constants.GROUP;
|
||||
import static org.springframework.web.bind.annotation.RequestMethod.PUT;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.dspace.app.rest.exception.UnprocessableEntityException;
|
||||
import org.dspace.app.rest.utils.Utils;
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.authorize.ResourcePolicy;
|
||||
import org.dspace.authorize.service.ResourcePolicyService;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.eperson.Group;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.rest.webmvc.ControllerUtils;
|
||||
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
|
||||
import org.springframework.hateoas.RepresentationModel;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* This controller will handle all the incoming calls on the/api/authz/resourcepolicies/{id}/group endpoint
|
||||
* where the id corresponds to the ResourcePolicy of which you want to replace the related Group.
|
||||
*
|
||||
* @author Mykhaylo Boychuk (mykhaylo.boychuk@4science.com)
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api/authz/resourcepolicies" + REGEX_REQUESTMAPPING_IDENTIFIER_AS_DIGIT + "/group")
|
||||
public class ResourcePolicyGroupReplaceRestController {
|
||||
|
||||
@Autowired
|
||||
private Utils utils;
|
||||
@Autowired
|
||||
private ResourcePolicyService resourcePolicyService;
|
||||
|
||||
@PreAuthorize("hasPermission(#id, 'resourcepolicy', 'ADMIN')")
|
||||
@RequestMapping(method = PUT, consumes = {"text/uri-list"})
|
||||
public ResponseEntity<RepresentationModel<?>> replaceGroupOfResourcePolicy(@PathVariable Integer id,
|
||||
HttpServletResponse response, HttpServletRequest request) throws SQLException, AuthorizeException {
|
||||
|
||||
Context context = obtainContext(request);
|
||||
List<DSpaceObject> dsoList = utils.constructDSpaceObjectList(context, utils.getStringListFromRequest(request));
|
||||
|
||||
if (dsoList.size() != 1 || dsoList.get(0).getType() != GROUP) {
|
||||
throw new UnprocessableEntityException("The Group doesn't exist or the data cannot be resolved to a Group");
|
||||
}
|
||||
|
||||
ResourcePolicy resourcePolicy = resourcePolicyService.find(context, id);
|
||||
if (Objects.isNull(resourcePolicy)) {
|
||||
throw new ResourceNotFoundException("ResourcePolicy with id: " + id + " not found!");
|
||||
}
|
||||
|
||||
if (Objects.isNull(resourcePolicy.getGroup())) {
|
||||
throw new UnprocessableEntityException("ResourcePolicy with id:" + id + " doesn't linked to Group");
|
||||
}
|
||||
|
||||
Group newGroup = (Group) dsoList.get(0);
|
||||
resourcePolicy.setGroup(newGroup);
|
||||
context.commit();
|
||||
return ControllerUtils.toEmptyResponse(HttpStatus.NO_CONTENT);
|
||||
}
|
||||
|
||||
}
|
@@ -148,6 +148,7 @@ public class DSpaceApiExceptionControllerAdvice extends ResponseEntityExceptionH
|
||||
RESTEmptyWorkflowGroupException.class,
|
||||
EPersonNameNotProvidedException.class,
|
||||
GroupNameNotProvidedException.class,
|
||||
GroupHasPendingWorkflowTasksException.class,
|
||||
})
|
||||
protected void handleCustomUnprocessableEntityException(HttpServletRequest request, HttpServletResponse response,
|
||||
TranslatableException ex) throws IOException {
|
||||
|
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
|
||||
package org.dspace.app.rest.exception;
|
||||
|
||||
import org.dspace.core.I18nUtil;
|
||||
|
||||
/**
|
||||
* <p>Extend {@link UnprocessableEntityException} to provide a specific error message
|
||||
* in the REST response. The error message is added to the response in
|
||||
* {@link DSpaceApiExceptionControllerAdvice#handleCustomUnprocessableEntityException},
|
||||
* hence it should not contain sensitive or security-compromising info.</p>
|
||||
*
|
||||
*/
|
||||
public class GroupHasPendingWorkflowTasksException
|
||||
extends UnprocessableEntityException implements TranslatableException {
|
||||
public static final String MESSAGE_KEY =
|
||||
"org.dspace.app.rest.exception.GroupHasPendingWorkflowTasksException.message";
|
||||
|
||||
public GroupHasPendingWorkflowTasksException() {
|
||||
super(I18nUtil.getMessage(MESSAGE_KEY));
|
||||
}
|
||||
|
||||
public GroupHasPendingWorkflowTasksException(Throwable cause) {
|
||||
super(I18nUtil.getMessage(MESSAGE_KEY), cause);
|
||||
}
|
||||
|
||||
public String getMessageKey() {
|
||||
return MESSAGE_KEY;
|
||||
}
|
||||
}
|
@@ -24,6 +24,7 @@ import org.apache.logging.log4j.Logger;
|
||||
import org.dspace.app.rest.Parameter;
|
||||
import org.dspace.app.rest.SearchRestMethod;
|
||||
import org.dspace.app.rest.exception.DSpaceBadRequestException;
|
||||
import org.dspace.app.rest.exception.GroupHasPendingWorkflowTasksException;
|
||||
import org.dspace.app.rest.exception.RepositoryMethodNotImplementedException;
|
||||
import org.dspace.app.rest.exception.UnprocessableEntityException;
|
||||
import org.dspace.app.rest.model.BitstreamRest;
|
||||
@@ -695,8 +696,8 @@ public class CollectionRestRepository extends DSpaceObjectRestRepository<Collect
|
||||
throws SQLException, WorkflowConfigurationException, AuthorizeException, WorkflowException, IOException {
|
||||
Group group = workflowService.getWorkflowRoleGroup(context, collection, workflowRole, null);
|
||||
if (!poolTaskService.findByGroup(context, group).isEmpty()) {
|
||||
throw new UnprocessableEntityException("The Group that was attempted to be deleted " +
|
||||
"still has Pooltasks open");
|
||||
// todo: also handle claimed tasks that would become associated with this group once returned to the pool
|
||||
throw new GroupHasPendingWorkflowTasksException();
|
||||
}
|
||||
if (group == null) {
|
||||
throw new ResourceNotFoundException("The requested Group was not found");
|
||||
|
@@ -70,6 +70,9 @@ server.servlet.encoding.force=true
|
||||
# However, you may wish to set this to "always" in your 'local.cfg' for development or debugging purposes.
|
||||
server.error.include-stacktrace = never
|
||||
|
||||
# When to include the error message in error responses (introduced in Spring 2.3.x)
|
||||
server.error.include-message = always
|
||||
|
||||
# Spring Boot proxy configuration (can be overridden in local.cfg).
|
||||
# By default, Spring Boot does not automatically use X-Forwarded-* Headers when generating links (and similar) in the
|
||||
# DSpace REST API. Three options are currently supported by Spring Boot:
|
||||
|
@@ -28,6 +28,7 @@ import org.dspace.app.rest.test.AbstractControllerIntegrationTest;
|
||||
import org.dspace.authorize.service.AuthorizeService;
|
||||
import org.dspace.builder.CollectionBuilder;
|
||||
import org.dspace.builder.CommunityBuilder;
|
||||
import org.dspace.builder.WorkspaceItemBuilder;
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.content.service.CollectionService;
|
||||
import org.dspace.core.Constants;
|
||||
@@ -2414,4 +2415,27 @@ public class CollectionGroupRestControllerIT extends AbstractControllerIntegrati
|
||||
.andExpect(status().isNotFound());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deleteCollectionWorkflowGroupWithPooledTaskTest() throws Exception {
|
||||
context.turnOffAuthorisationSystem();
|
||||
Group reviewer = workflowService.createWorkflowRoleGroup(context, collection, "reviewer");
|
||||
|
||||
// Submit an Item into the workflow -> moves to the "reviewer" step's pool.
|
||||
// The role must have at least one EPerson, otherwise the WSI gets archived immediately
|
||||
groupService.addMember(context, reviewer, eperson);
|
||||
workflowService.start(
|
||||
context,
|
||||
WorkspaceItemBuilder.createWorkspaceItem(context, collection)
|
||||
.withTitle("Dummy Item")
|
||||
.build()
|
||||
);
|
||||
|
||||
context.restoreAuthSystemState();
|
||||
|
||||
String token = getAuthToken(admin.getEmail(), password);
|
||||
|
||||
getClient(token).perform(delete("/api/core/collections/" + collection.getID() + "/workflowGroups/reviewer"))
|
||||
.andExpect(status().isUnprocessableEntity());
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -11,10 +11,13 @@ import static com.jayway.jsonpath.JsonPath.read;
|
||||
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
import static org.springframework.data.rest.webmvc.RestMediaTypes.TEXT_URI_LIST_VALUE;
|
||||
import static org.springframework.http.MediaType.parseMediaType;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
@@ -29,6 +32,7 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.dspace.app.rest.matcher.ResourcePolicyMatcher;
|
||||
import org.dspace.app.rest.model.ResourcePolicyRest;
|
||||
import org.dspace.app.rest.model.patch.AddOperation;
|
||||
@@ -2723,4 +2727,495 @@ public class ResourcePolicyRestRepositoryIT extends AbstractControllerIntegratio
|
||||
.andExpect(jsonPath("$._links.resource.href", Matchers.allOf(
|
||||
Matchers.containsString("/api/authz/resourcepolicies/search/resource"))));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void patchReplaceEPersonAdminTest() throws Exception {
|
||||
context.turnOffAuthorisationSystem();
|
||||
|
||||
EPerson newEPerson = EPersonBuilder.createEPerson(context)
|
||||
.withEmail("newEPerson@mail.com")
|
||||
.withPassword(password)
|
||||
.build();
|
||||
|
||||
parentCommunity = CommunityBuilder.createCommunity(context)
|
||||
.withName("Parent Community")
|
||||
.build();
|
||||
|
||||
Collection col = CollectionBuilder.createCollection(context, parentCommunity)
|
||||
.withName("Collection 1")
|
||||
.build();
|
||||
|
||||
ResourcePolicy resourcePolicy = ResourcePolicyBuilder.createResourcePolicy(context)
|
||||
.withAction(Constants.ADD)
|
||||
.withDspaceObject(col)
|
||||
.withUser(eperson)
|
||||
.withDescription("My Description")
|
||||
.withPolicyType(ResourcePolicy.TYPE_CUSTOM)
|
||||
.build();
|
||||
|
||||
context.restoreAuthSystemState();
|
||||
String tokenAdmin = getAuthToken(admin.getEmail(), password);
|
||||
|
||||
// verify origin resourcepolicy
|
||||
getClient(tokenAdmin).perform(get("/api/authz/resourcepolicies/" + resourcePolicy.getID()))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$._embedded.eperson.id", is(eperson.getID().toString())))
|
||||
.andExpect(jsonPath("$._embedded.group", nullValue()));
|
||||
|
||||
// update eperson of the resourcePolicy
|
||||
getClient(tokenAdmin).perform(put("/api/authz/resourcepolicies/" + resourcePolicy.getID() + "/eperson")
|
||||
.contentType(parseMediaType(TEXT_URI_LIST_VALUE))
|
||||
.content("/api/eperson/epersons/" + newEPerson.getID()))
|
||||
.andExpect(status().isNoContent());
|
||||
|
||||
// verify that the resourcePolicy is related to new eperson
|
||||
getClient(tokenAdmin).perform(get("/api/authz/resourcepolicies/" + resourcePolicy.getID()))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$._embedded.eperson.id", is(newEPerson.getID().toString())))
|
||||
.andExpect(jsonPath("$._embedded.group", nullValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void patchReplaceEPersonForbiddenTest() throws Exception {
|
||||
context.turnOffAuthorisationSystem();
|
||||
|
||||
EPerson newEPerson = EPersonBuilder.createEPerson(context)
|
||||
.withEmail("newEPerson@mail.com")
|
||||
.withPassword(password)
|
||||
.build();
|
||||
|
||||
parentCommunity = CommunityBuilder.createCommunity(context)
|
||||
.withName("Parent Community")
|
||||
.build();
|
||||
|
||||
Collection col = CollectionBuilder.createCollection(context, parentCommunity)
|
||||
.withName("Collection 1")
|
||||
.build();
|
||||
|
||||
ResourcePolicy resourcePolicy = ResourcePolicyBuilder.createResourcePolicy(context)
|
||||
.withAction(Constants.ADD)
|
||||
.withDspaceObject(col)
|
||||
.withUser(eperson)
|
||||
.withDescription("My Description")
|
||||
.withPolicyType(ResourcePolicy.TYPE_CUSTOM)
|
||||
.build();
|
||||
|
||||
context.restoreAuthSystemState();
|
||||
String tokenAdmin = getAuthToken(admin.getEmail(), password);
|
||||
String tokenEPerson = getAuthToken(eperson.getEmail(), password);
|
||||
|
||||
// verify origin resourcepolicy
|
||||
getClient(tokenAdmin).perform(get("/api/authz/resourcepolicies/" + resourcePolicy.getID()))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$._embedded.eperson.id", is(eperson.getID().toString())))
|
||||
.andExpect(jsonPath("$._embedded.group", nullValue()));
|
||||
|
||||
// try to update eperson of resourcepolicy with normal user
|
||||
getClient(tokenEPerson).perform(put("/api/authz/resourcepolicies/" + resourcePolicy.getID() + "/eperson")
|
||||
.contentType(parseMediaType(TEXT_URI_LIST_VALUE))
|
||||
.content("/api/eperson/epersons/" + newEPerson.getID()))
|
||||
.andExpect(status().isForbidden());
|
||||
|
||||
// verify that resourcepolicy hasn't been changed
|
||||
getClient(tokenAdmin).perform(get("/api/authz/resourcepolicies/" + resourcePolicy.getID()))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$._embedded.eperson.id", is(eperson.getID().toString())))
|
||||
.andExpect(jsonPath("$._embedded.group", nullValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void patchReplaceEPersonUnauthorizedTest() throws Exception {
|
||||
context.turnOffAuthorisationSystem();
|
||||
|
||||
EPerson newEPerson = EPersonBuilder.createEPerson(context)
|
||||
.withEmail("newEPerson@mail.com")
|
||||
.withPassword(password)
|
||||
.build();
|
||||
|
||||
parentCommunity = CommunityBuilder.createCommunity(context)
|
||||
.withName("Parent Community")
|
||||
.build();
|
||||
|
||||
Collection col = CollectionBuilder.createCollection(context, parentCommunity)
|
||||
.withName("Collection 1")
|
||||
.build();
|
||||
|
||||
ResourcePolicy resourcePolicy = ResourcePolicyBuilder.createResourcePolicy(context)
|
||||
.withAction(Constants.ADD)
|
||||
.withDspaceObject(col)
|
||||
.withUser(eperson)
|
||||
.withDescription("My Description")
|
||||
.withPolicyType(ResourcePolicy.TYPE_CUSTOM)
|
||||
.build();
|
||||
|
||||
context.restoreAuthSystemState();
|
||||
String tokenAdmin = getAuthToken(admin.getEmail(), password);
|
||||
|
||||
// verify origin resourcepolicy
|
||||
getClient(tokenAdmin).perform(get("/api/authz/resourcepolicies/" + resourcePolicy.getID()))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$._embedded.eperson.id", is(eperson.getID().toString())))
|
||||
.andExpect(jsonPath("$._embedded.group", nullValue()));
|
||||
|
||||
// try to update eperson of resourcepolicy with anonymous user
|
||||
getClient().perform(put("/api/authz/resourcepolicies/" + resourcePolicy.getID() + "/eperson")
|
||||
.contentType(parseMediaType(TEXT_URI_LIST_VALUE))
|
||||
.content("/api/eperson/epersons/" + newEPerson.getID()))
|
||||
.andExpect(status().isUnauthorized());
|
||||
|
||||
// verify that resourcepolicy hasn't been changed
|
||||
getClient(tokenAdmin).perform(get("/api/authz/resourcepolicies/" + resourcePolicy.getID()))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$._embedded.eperson.id", is(eperson.getID().toString())))
|
||||
.andExpect(jsonPath("$._embedded.group", nullValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void patchReplaceGroupAdminTest() throws Exception {
|
||||
context.turnOffAuthorisationSystem();
|
||||
|
||||
Group originGroup = GroupBuilder.createGroup(context)
|
||||
.withName("origin Test Group")
|
||||
.build();
|
||||
|
||||
Group newGroup = GroupBuilder.createGroup(context)
|
||||
.withName("testGroupName")
|
||||
.build();
|
||||
|
||||
parentCommunity = CommunityBuilder.createCommunity(context)
|
||||
.withName("Parent Community")
|
||||
.build();
|
||||
|
||||
Collection col = CollectionBuilder.createCollection(context, parentCommunity)
|
||||
.withName("Collection 1")
|
||||
.build();
|
||||
|
||||
ResourcePolicy resourcePolicy = ResourcePolicyBuilder.createResourcePolicy(context)
|
||||
.withAction(Constants.ADD)
|
||||
.withDspaceObject(col)
|
||||
.withGroup(originGroup)
|
||||
.withDescription("My Description")
|
||||
.withPolicyType(ResourcePolicy.TYPE_CUSTOM)
|
||||
.build();
|
||||
|
||||
context.restoreAuthSystemState();
|
||||
String tokenAdmin = getAuthToken(admin.getEmail(), password);
|
||||
|
||||
// verify origin resourcepolicy
|
||||
getClient(tokenAdmin).perform(get("/api/authz/resourcepolicies/" + resourcePolicy.getID()))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$._embedded.group.id", is(originGroup.getID().toString())))
|
||||
.andExpect(jsonPath("$._embedded.eperson", nullValue()));
|
||||
|
||||
// update group of the resourcePolicy
|
||||
getClient(tokenAdmin).perform(put("/api/authz/resourcepolicies/" + resourcePolicy.getID() + "/group")
|
||||
.contentType(parseMediaType(TEXT_URI_LIST_VALUE))
|
||||
.content("/api/eperson/groups/" + newGroup.getID()))
|
||||
.andExpect(status().isNoContent());
|
||||
|
||||
// verify that the resourcePolicy is related to new group
|
||||
getClient(tokenAdmin).perform(get("/api/authz/resourcepolicies/" + resourcePolicy.getID()))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$._embedded.group.id", is(newGroup.getID().toString())))
|
||||
.andExpect(jsonPath("$._embedded.eperson", nullValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void patchReplaceGroupForbiddenTest() throws Exception {
|
||||
context.turnOffAuthorisationSystem();
|
||||
|
||||
Group originGroup = GroupBuilder.createGroup(context)
|
||||
.withName("origin Test Group")
|
||||
.build();
|
||||
|
||||
Group newGroup = GroupBuilder.createGroup(context)
|
||||
.withName("testGroupName")
|
||||
.build();
|
||||
|
||||
parentCommunity = CommunityBuilder.createCommunity(context)
|
||||
.withName("Parent Community")
|
||||
.build();
|
||||
|
||||
Collection col = CollectionBuilder.createCollection(context, parentCommunity)
|
||||
.withName("Collection 1")
|
||||
.build();
|
||||
|
||||
ResourcePolicy resourcePolicy = ResourcePolicyBuilder.createResourcePolicy(context)
|
||||
.withAction(Constants.ADD)
|
||||
.withDspaceObject(col)
|
||||
.withGroup(originGroup)
|
||||
.withDescription("My Description")
|
||||
.withPolicyType(ResourcePolicy.TYPE_CUSTOM)
|
||||
.build();
|
||||
|
||||
context.restoreAuthSystemState();
|
||||
String tokenAdmin = getAuthToken(admin.getEmail(), password);
|
||||
String tokenEPerson = getAuthToken(eperson.getEmail(), password);
|
||||
|
||||
// verify origin resourcepolicy
|
||||
getClient(tokenAdmin).perform(get("/api/authz/resourcepolicies/" + resourcePolicy.getID()))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$._embedded.group.id", is(originGroup.getID().toString())))
|
||||
.andExpect(jsonPath("$._embedded.eperson", nullValue()));
|
||||
|
||||
// try to update group of resourcepolicy with normal user
|
||||
getClient(tokenEPerson).perform(put("/api/authz/resourcepolicies/" + resourcePolicy.getID() + "/group")
|
||||
.contentType(parseMediaType(TEXT_URI_LIST_VALUE))
|
||||
.content("/api/eperson/groups/" + newGroup.getID()))
|
||||
.andExpect(status().isForbidden());
|
||||
|
||||
// verify that resourcepolicy hasn't been changed
|
||||
getClient(tokenAdmin).perform(get("/api/authz/resourcepolicies/" + resourcePolicy.getID()))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$._embedded.group.id", is(originGroup.getID().toString())))
|
||||
.andExpect(jsonPath("$._embedded.eperson", nullValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void patchReplaceGroupUnauthorizedTest() throws Exception {
|
||||
context.turnOffAuthorisationSystem();
|
||||
|
||||
Group originGroup = GroupBuilder.createGroup(context)
|
||||
.withName("origin Test Group")
|
||||
.build();
|
||||
|
||||
Group newGroup = GroupBuilder.createGroup(context)
|
||||
.withName("testGroupName")
|
||||
.build();
|
||||
|
||||
parentCommunity = CommunityBuilder.createCommunity(context)
|
||||
.withName("Parent Community")
|
||||
.build();
|
||||
|
||||
Collection col = CollectionBuilder.createCollection(context, parentCommunity)
|
||||
.withName("Collection 1")
|
||||
.build();
|
||||
|
||||
ResourcePolicy resourcePolicy = ResourcePolicyBuilder.createResourcePolicy(context)
|
||||
.withAction(Constants.ADD)
|
||||
.withDspaceObject(col)
|
||||
.withGroup(originGroup)
|
||||
.withDescription("My Description")
|
||||
.withPolicyType(ResourcePolicy.TYPE_CUSTOM)
|
||||
.build();
|
||||
|
||||
context.restoreAuthSystemState();
|
||||
String tokenAdmin = getAuthToken(admin.getEmail(), password);
|
||||
|
||||
// verify origin resourcepolicy
|
||||
getClient(tokenAdmin).perform(get("/api/authz/resourcepolicies/" + resourcePolicy.getID()))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$._embedded.group.id", is(originGroup.getID().toString())))
|
||||
.andExpect(jsonPath("$._embedded.eperson", nullValue()));
|
||||
|
||||
// try to update group of resourcepolicy with anonymous user
|
||||
getClient().perform(put("/api/authz/resourcepolicies/" + resourcePolicy.getID() + "/group")
|
||||
.contentType(parseMediaType(TEXT_URI_LIST_VALUE))
|
||||
.content("/api/eperson/groups/" + newGroup.getID()))
|
||||
.andExpect(status().isUnauthorized());
|
||||
|
||||
// verify that resourcepolicy hasn't been changed
|
||||
getClient(tokenAdmin).perform(get("/api/authz/resourcepolicies/" + resourcePolicy.getID()))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$._embedded.group.id", is(originGroup.getID().toString())))
|
||||
.andExpect(jsonPath("$._embedded.eperson", nullValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateResourcePolicyOfEPersonToGroupTest() throws Exception {
|
||||
context.turnOffAuthorisationSystem();
|
||||
|
||||
Group group = GroupBuilder.createGroup(context)
|
||||
.withName("My group")
|
||||
.build();
|
||||
|
||||
Community community = CommunityBuilder.createCommunity(context)
|
||||
.withName("My community")
|
||||
.build();
|
||||
|
||||
ResourcePolicy resourcePolicyOfEPerson = ResourcePolicyBuilder.createResourcePolicy(context)
|
||||
.withDspaceObject(community)
|
||||
.withAction(Constants.READ)
|
||||
.withUser(eperson)
|
||||
.build();
|
||||
context.restoreAuthSystemState();
|
||||
|
||||
String authToken = getAuthToken(eperson.getEmail(), password);
|
||||
getClient(authToken).perform(get("/api/authz/resourcepolicies/" + resourcePolicyOfEPerson.getID()))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(content().contentType(contentType))
|
||||
.andExpect(jsonPath("$", is(ResourcePolicyMatcher.matchResourcePolicy(resourcePolicyOfEPerson))))
|
||||
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/authz/resourcepolicies/"
|
||||
+ resourcePolicyOfEPerson.getID())));
|
||||
|
||||
String tokenAdmin = getAuthToken(admin.getEmail(), password);
|
||||
getClient(tokenAdmin).perform(put("/api/authz/resourcepolicies/" + resourcePolicyOfEPerson.getID() + "/group")
|
||||
.contentType(parseMediaType(TEXT_URI_LIST_VALUE))
|
||||
.content("/api/eperson/groups/" + group.getID()))
|
||||
.andExpect(status().isUnprocessableEntity());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateResourcePolicyOfGroupToEPersonTest() throws Exception {
|
||||
context.turnOffAuthorisationSystem();
|
||||
|
||||
Group group = GroupBuilder.createGroup(context)
|
||||
.withName("My group")
|
||||
.build();
|
||||
|
||||
Community community = CommunityBuilder.createCommunity(context)
|
||||
.withName("My community")
|
||||
.build();
|
||||
|
||||
ResourcePolicy resourcePolicyOfGroup = ResourcePolicyBuilder.createResourcePolicy(context)
|
||||
.withDspaceObject(community)
|
||||
.withAction(Constants.ADD)
|
||||
.withGroup(group).build();
|
||||
|
||||
context.restoreAuthSystemState();
|
||||
|
||||
String tokenAdmin = getAuthToken(admin.getEmail(), password);
|
||||
getClient(tokenAdmin).perform(get("/api/authz/resourcepolicies/search/group")
|
||||
.param("uuid", group.getID().toString()))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(content().contentType(contentType))
|
||||
.andExpect(jsonPath("$._embedded.resourcepolicies", Matchers.containsInAnyOrder(
|
||||
ResourcePolicyMatcher.matchResourcePolicy(resourcePolicyOfGroup))))
|
||||
.andExpect(jsonPath("$._links.self.href", Matchers.containsString(
|
||||
"api/authz/resourcepolicies/search/group")))
|
||||
.andExpect(jsonPath("$.page.totalElements", is(1)));
|
||||
|
||||
getClient(tokenAdmin).perform(put("/api/authz/resourcepolicies/" + resourcePolicyOfGroup.getID() + "/eperson")
|
||||
.contentType(parseMediaType(TEXT_URI_LIST_VALUE))
|
||||
.content("/api/eperson/epersons/" + eperson.getID()))
|
||||
.andExpect(status().isUnprocessableEntity());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateEPersonOfNotExistingResourcePolicyTest() throws Exception {
|
||||
String tokenAdmin = getAuthToken(admin.getEmail(), password);
|
||||
getClient(tokenAdmin).perform(put("/api/authz/resourcepolicies/" + Integer.MAX_VALUE + "/eperson")
|
||||
.contentType(parseMediaType(TEXT_URI_LIST_VALUE))
|
||||
.content("/api/eperson/epersons/" + eperson.getID()))
|
||||
.andExpect(status().isNotFound());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateGroupOfNotExistingResourcePolicyTest() throws Exception {
|
||||
context.turnOffAuthorisationSystem();
|
||||
|
||||
Group group = GroupBuilder.createGroup(context)
|
||||
.withName("My group")
|
||||
.build();
|
||||
|
||||
context.restoreAuthSystemState();
|
||||
|
||||
String tokenAdmin = getAuthToken(admin.getEmail(), password);
|
||||
getClient(tokenAdmin).perform(put("/api/authz/resourcepolicies/" + Integer.MAX_VALUE + "/group")
|
||||
.contentType(parseMediaType(TEXT_URI_LIST_VALUE))
|
||||
.content("/api/eperson/groups/" + group.getID()))
|
||||
.andExpect(status().isNotFound());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateResourcePolicyOfGroupWithEmptyTest() throws Exception {
|
||||
context.turnOffAuthorisationSystem();
|
||||
|
||||
Group group = GroupBuilder.createGroup(context)
|
||||
.withName("My group")
|
||||
.build();
|
||||
|
||||
Community community = CommunityBuilder.createCommunity(context)
|
||||
.withName("My community")
|
||||
.build();
|
||||
|
||||
|
||||
ResourcePolicy resourcePolicyOfGroup = ResourcePolicyBuilder.createResourcePolicy(context)
|
||||
.withDspaceObject(community)
|
||||
.withAction(Constants.ADD)
|
||||
.withGroup(group).build();
|
||||
context.restoreAuthSystemState();
|
||||
|
||||
String tokenAdmin = getAuthToken(admin.getEmail(), password);
|
||||
getClient(tokenAdmin).perform(put("/api/authz/resourcepolicies/" + resourcePolicyOfGroup.getID() + "/group")
|
||||
.contentType(parseMediaType(TEXT_URI_LIST_VALUE))
|
||||
.content(StringUtils.EMPTY))
|
||||
.andExpect(status().isUnprocessableEntity());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateResourcePolicyOfGroupWithMultipleGroupsTest() throws Exception {
|
||||
context.turnOffAuthorisationSystem();
|
||||
|
||||
Group group1 = GroupBuilder.createGroup(context).withName("My group").build();
|
||||
Group group2 = GroupBuilder.createGroup(context).withName("My group2").build();
|
||||
|
||||
Community community = CommunityBuilder.createCommunity(context)
|
||||
.withName("My community")
|
||||
.build();
|
||||
|
||||
ResourcePolicy resourcePolicyOfGroup = ResourcePolicyBuilder.createResourcePolicy(context)
|
||||
.withDspaceObject(community)
|
||||
.withAction(Constants.ADD)
|
||||
.withGroup(group1).build();
|
||||
context.restoreAuthSystemState();
|
||||
|
||||
String tokenAdmin = getAuthToken(admin.getEmail(), password);
|
||||
getClient(tokenAdmin).perform(put("/api/authz/resourcepolicies/" + resourcePolicyOfGroup.getID() + "/group")
|
||||
.contentType(parseMediaType(TEXT_URI_LIST_VALUE))
|
||||
.content("/api/eperson/groups/" + group1.getID() +
|
||||
"\n/api/eperson/groups/" + group2.getID()))
|
||||
.andExpect(status().isUnprocessableEntity());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateResourcePolicyOfEPersonWithEmptyTest() throws Exception {
|
||||
context.turnOffAuthorisationSystem();
|
||||
|
||||
Community community = CommunityBuilder.createCommunity(context).withName("My community").build();
|
||||
|
||||
ResourcePolicy rpOfEPerson = ResourcePolicyBuilder.createResourcePolicy(context)
|
||||
.withDspaceObject(community)
|
||||
.withAction(Constants.READ)
|
||||
.withUser(eperson)
|
||||
.build();
|
||||
context.restoreAuthSystemState();
|
||||
|
||||
String tokenAdmin = getAuthToken(admin.getEmail(), password);
|
||||
getClient(tokenAdmin).perform(put("/api/authz/resourcepolicies/" + rpOfEPerson.getID() + "/eperson")
|
||||
.contentType(parseMediaType(TEXT_URI_LIST_VALUE))
|
||||
.content(StringUtils.EMPTY))
|
||||
.andExpect(status().isUnprocessableEntity());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateResourcePolicyOfEPersonWithMultipleEPersonsTest() throws Exception {
|
||||
context.turnOffAuthorisationSystem();
|
||||
|
||||
EPerson eperson1 = EPersonBuilder.createEPerson(context)
|
||||
.withEmail("eperson1@mail.com")
|
||||
.withPassword(password)
|
||||
.build();
|
||||
EPerson eperson2 = EPersonBuilder.createEPerson(context)
|
||||
.withEmail("eperson2@mail.com")
|
||||
.withPassword(password)
|
||||
.build();
|
||||
|
||||
Community community = CommunityBuilder.createCommunity(context).withName("My community").build();
|
||||
|
||||
ResourcePolicy rpOfEPerson = ResourcePolicyBuilder.createResourcePolicy(context)
|
||||
.withDspaceObject(community)
|
||||
.withAction(Constants.READ)
|
||||
.withUser(eperson)
|
||||
.build();
|
||||
context.restoreAuthSystemState();
|
||||
|
||||
String tokenAdmin = getAuthToken(admin.getEmail(), password);
|
||||
getClient(tokenAdmin).perform(put("/api/authz/resourcepolicies/" + rpOfEPerson.getID() + "/eperson")
|
||||
.contentType(parseMediaType(TEXT_URI_LIST_VALUE))
|
||||
.content("/api/eperson/epersons/" + eperson1.getID() +
|
||||
"\n/api/eperson/epersons/" + eperson2.getID()))
|
||||
.andExpect(status().isUnprocessableEntity());
|
||||
}
|
||||
|
||||
}
|
@@ -11,3 +11,4 @@ org.dspace.app.rest.exception.RESTEmptyWorkflowGroupException.message = [PL] Ref
|
||||
workflow group {1}. Delete the tasks and group first if you want to remove this user.
|
||||
org.dspace.app.rest.exception.EPersonNameNotProvidedException.message = [PL] The eperson.firstname and eperson.lastname values need to be filled in
|
||||
org.dspace.app.rest.exception.GroupNameNotProvidedException.message = [PL] Cannot create group, no group name is provided
|
||||
org.dspace.app.rest.exception.GroupHasPendingWorkflowTasksException.message = [PL] Cannot delete group, the associated workflow role still has pending tasks
|
||||
|
Reference in New Issue
Block a user