Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,21 @@
import static org.junit.Assert.assertNotNull;

import java.nio.file.Path;
import java.sql.SQLException;
import java.util.List;

import org.dspace.app.rest.test.AbstractWebClientIntegrationTest;
import org.dspace.authorize.AuthorizeException;
import org.dspace.builder.CollectionBuilder;
import org.dspace.builder.CommunityBuilder;
import org.dspace.builder.ItemBuilder;
import org.dspace.builder.WorkflowItemBuilder;
import org.dspace.builder.WorkspaceItemBuilder;
import org.dspace.content.Collection;
import org.dspace.content.Item;
import org.dspace.content.WorkspaceItem;
import org.dspace.services.ConfigurationService;
import org.dspace.workflow.WorkflowItem;
import org.junit.Assume;
import org.junit.Before;
import org.junit.ClassRule;
Expand Down Expand Up @@ -364,6 +370,105 @@ public void depositAndEditViaSwordTest() throws Exception {
assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode());
}

// test workspace delete - use org.dspace.sword2.WorkflowManagerDefault
@Test
public void testDeleteWorkspaceManagerDefault() throws SQLException, AuthorizeException {
context.turnOffAuthorisationSystem();
// Create a top level community and one Collection
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community")
.build();
// Make sure our Collection allows the "eperson" user to submit into it
Collection collection = CollectionBuilder.createCollection(context, parentCommunity)
.withName("Test SWORDv2 Collection")
.withSubmitterGroup(eperson)
.build();
// Above changes MUST be committed to the database for SWORDv2 to see them.
WorkspaceItem wsi = WorkspaceItemBuilder.createWorkspaceItem(context, collection)
.withTitle("Test SWORDv2 Item")
.withAuthor("Test, Sam")
.withSubmitter(eperson)
.build();
context.commit();
context.restoreAuthSystemState();

// Edit URI should also allow user to DELETE the uploaded content
// The Item is in Workspace and not in workflow, so we can use the WorkflowManagerDefault to delete it.
configurationService.setProperty("plugin.single.org.dspace.sword2.WorkflowManager",
"org.dspace.sword2.WorkflowManagerDefault");
String editLink = getURL(EDIT_PATH + "/" + wsi.getItem().getID().toString());
HttpHeaders authHeaders = new HttpHeaders();
authHeaders.setBasicAuth(admin.getEmail(), password);
RequestEntity request = RequestEntity.delete(editLink)
.headers(authHeaders)
.build();
ResponseEntity<String> response = responseAsString(request);
configurationService.setProperty("plugin.single.org.dspace.sword2.WorkflowManager",
"org.dspace.sword2.WorkflowManagerUnrestricted");

// Expect a 204 No Content response
assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode());

// Verify that Edit URI now returns a 404 (using eperson login info)
authHeaders = new HttpHeaders();
authHeaders.setBasicAuth(eperson.getEmail(), password);
request = RequestEntity.get(editLink)
.accept(MediaType.valueOf("application/atom+xml"))
.headers(authHeaders)
.build();
response = responseAsString(request);
// Expect a 404 response as content was deleted
assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode());
}

// test workflow delete - use org.dspace.sword2.WorkflowManagerUnrestricted
@Test
public void testDeleteWorkflowManagerDefault() throws SQLException, AuthorizeException {
context.turnOffAuthorisationSystem();
// Create a top level community and one Collection
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community")
.build();
// Make sure our Collection allows the "eperson" user to submit into it
Collection collection = CollectionBuilder.createCollection(context, parentCommunity)
.withName("Test SWORDv2 Collection")
.withSubmitterGroup(eperson)
.build();
// Above changes MUST be committed to the database for SWORDv2 to see them.
WorkflowItem wfi = WorkflowItemBuilder.createWorkflowItem(context, collection)
.withTitle("Test SWORDv2 Item")
.withAuthor("Test, Sam")
.withSubmitter(eperson)
.build();
context.commit();
context.restoreAuthSystemState();

// Edit URI should allow user to DELETE the uploaded content
// The item is in workflow, so we need to use the WorkflowManagerUnrestricted to delete it. It is set in the
// @Before method
String editLink = getURL(EDIT_PATH + "/" + wfi.getItem().getID().toString());
HttpHeaders authHeaders = new HttpHeaders();
authHeaders.setBasicAuth(admin.getEmail(), password);
RequestEntity request = RequestEntity.delete(editLink)
.headers(authHeaders)
.build();
ResponseEntity<String> response = responseAsString(request);

// Expect a 204 No Content response
assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode());

// Verify that Edit URI now returns a 404 (using eperson login info)
authHeaders = new HttpHeaders();
authHeaders.setBasicAuth(eperson.getEmail(), password);
request = RequestEntity.get(editLink)
.accept(MediaType.valueOf("application/atom+xml"))
.headers(authHeaders)
.build();
response = responseAsString(request);
// Expect a 404 response as content was deleted
assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode());
}

@Test
public void editUnauthorizedTest() throws Exception {
// Attempt to POST to /edit endpoint without sending authentication information
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.UUID;

import org.apache.logging.log4j.Logger;
import org.dspace.authorize.AuthorizeException;
Expand All @@ -25,6 +26,7 @@
import org.dspace.core.Constants;
import org.dspace.core.Context;
import org.dspace.core.LogHelper;
import org.dspace.event.Event;
import org.dspace.workflow.WorkflowItem;
import org.dspace.workflow.WorkflowItemService;
import org.dspace.workflow.factory.WorkflowServiceFactory;
Expand Down Expand Up @@ -756,13 +758,19 @@ protected void doContainerDelete(SwordContext swordContext, Item item,
if (wft.isItemInWorkspace(swordContext.getContext(), item)) {
WorkspaceItem wsi = wft.getWorkspaceItem(context, item);
workspaceItemService.deleteAll(context, wsi);
// the item is deleted in the above call
} else if (wft.isItemInWorkflow(context, item)) {
WorkflowItem wfi = wft.getWorkflowItem(context, item);
workflowItemService.deleteWrapper(context, wfi);
}

// then delete the item
itemService.delete(context, item);
// then delete the item, but only if it hasn't already been deleted by the methods above.
// the delete method is called in `workspaceItemService.deleteAll(context, wsi);`,
// so it should not be called again here, as that would throw an exception.
if (!isItemAlreadyDeleted(context, item.getID())) {
itemService.delete(context, item);
}

} catch (SQLException | IOException e) {
throw new DSpaceSwordException(e);
} catch (AuthorizeException e) {
Expand All @@ -788,4 +796,20 @@ private Item getDSpaceTarget(Context context, String editUrl,

return item;
}

/**
* Check if the item is already deleted in the context.
*/
private boolean isItemAlreadyDeleted(Context context, UUID itemUUID) {
if (context.getEvents() == null) {
return false;
}

for (Event event : context.getEvents()) {
if (event.getEventType() == Event.DELETE && event.getSubjectID().equals(itemUUID)) {
return true;
}
}
return false;
}
}