Skip to content

Commit 66af883

Browse files
ZCU-PUB/Fixed deleting the Item when used org.dspace.sword2.WorkflowManagerDefault (#934)
1 parent d0645e3 commit 66af883

2 files changed

Lines changed: 129 additions & 2 deletions

File tree

dspace-server-webapp/src/test/java/org/dspace/app/sword2/Swordv2IT.java

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,13 @@
2222
import org.dspace.builder.CollectionBuilder;
2323
import org.dspace.builder.CommunityBuilder;
2424
import org.dspace.builder.ItemBuilder;
25+
import org.dspace.builder.WorkflowItemBuilder;
26+
import org.dspace.builder.WorkspaceItemBuilder;
2527
import org.dspace.content.Collection;
2628
import org.dspace.content.Item;
29+
import org.dspace.content.WorkspaceItem;
2730
import org.dspace.services.ConfigurationService;
31+
import org.dspace.workflow.WorkflowItem;
2832
import org.junit.Assume;
2933
import org.junit.Before;
3034
import org.junit.ClassRule;
@@ -445,6 +449,105 @@ public void depositAndEditViaSwordTest() throws Exception {
445449
assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode());
446450
}
447451

452+
// test workspace delete - use org.dspace.sword2.WorkflowManagerDefault
453+
@Test
454+
public void testDeleteWorkspaceManagerDefault() throws SQLException, AuthorizeException {
455+
context.turnOffAuthorisationSystem();
456+
// Create a top level community and one Collection
457+
parentCommunity = CommunityBuilder.createCommunity(context)
458+
.withName("Parent Community")
459+
.build();
460+
// Make sure our Collection allows the "eperson" user to submit into it
461+
Collection collection = CollectionBuilder.createCollection(context, parentCommunity)
462+
.withName("Test SWORDv2 Collection")
463+
.withSubmitterGroup(eperson)
464+
.build();
465+
// Above changes MUST be committed to the database for SWORDv2 to see them.
466+
WorkspaceItem wsi = WorkspaceItemBuilder.createWorkspaceItem(context, collection)
467+
.withTitle("Test SWORDv2 Item")
468+
.withAuthor("Test, Sam")
469+
.withSubmitter(eperson)
470+
.build();
471+
context.commit();
472+
context.restoreAuthSystemState();
473+
474+
// Edit URI should also allow user to DELETE the uploaded content
475+
// The Item is in Workspace and not in workflow, so we can use the WorkflowManagerDefault to delete it.
476+
configurationService.setProperty("plugin.single.org.dspace.sword2.WorkflowManager",
477+
"org.dspace.sword2.WorkflowManagerDefault");
478+
String editLink = getURL(EDIT_PATH + "/" + wsi.getItem().getID().toString());
479+
HttpHeaders authHeaders = new HttpHeaders();
480+
authHeaders.setBasicAuth(admin.getEmail(), password);
481+
RequestEntity request = RequestEntity.delete(editLink)
482+
.headers(authHeaders)
483+
.build();
484+
ResponseEntity<String> response = responseAsString(request);
485+
configurationService.setProperty("plugin.single.org.dspace.sword2.WorkflowManager",
486+
"org.dspace.sword2.WorkflowManagerUnrestricted");
487+
488+
// Expect a 204 No Content response
489+
assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode());
490+
491+
// Verify that Edit URI now returns a 404 (using eperson login info)
492+
authHeaders = new HttpHeaders();
493+
authHeaders.setBasicAuth(eperson.getEmail(), password);
494+
request = RequestEntity.get(editLink)
495+
.accept(MediaType.valueOf("application/atom+xml"))
496+
.headers(authHeaders)
497+
.build();
498+
response = responseAsString(request);
499+
// Expect a 404 response as content was deleted
500+
assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode());
501+
}
502+
503+
// test workflow delete - use org.dspace.sword2.WorkflowManagerUnrestricted
504+
@Test
505+
public void testDeleteWorkflowManagerDefault() throws SQLException, AuthorizeException {
506+
context.turnOffAuthorisationSystem();
507+
// Create a top level community and one Collection
508+
parentCommunity = CommunityBuilder.createCommunity(context)
509+
.withName("Parent Community")
510+
.build();
511+
// Make sure our Collection allows the "eperson" user to submit into it
512+
Collection collection = CollectionBuilder.createCollection(context, parentCommunity)
513+
.withName("Test SWORDv2 Collection")
514+
.withSubmitterGroup(eperson)
515+
.build();
516+
// Above changes MUST be committed to the database for SWORDv2 to see them.
517+
WorkflowItem wfi = WorkflowItemBuilder.createWorkflowItem(context, collection)
518+
.withTitle("Test SWORDv2 Item")
519+
.withAuthor("Test, Sam")
520+
.withSubmitter(eperson)
521+
.build();
522+
context.commit();
523+
context.restoreAuthSystemState();
524+
525+
// Edit URI should allow user to DELETE the uploaded content
526+
// The item is in workflow, so we need to use the WorkflowManagerUnrestricted to delete it. It is set in the
527+
// @Before method
528+
String editLink = getURL(EDIT_PATH + "/" + wfi.getItem().getID().toString());
529+
HttpHeaders authHeaders = new HttpHeaders();
530+
authHeaders.setBasicAuth(admin.getEmail(), password);
531+
RequestEntity request = RequestEntity.delete(editLink)
532+
.headers(authHeaders)
533+
.build();
534+
ResponseEntity<String> response = responseAsString(request);
535+
536+
// Expect a 204 No Content response
537+
assertEquals(HttpStatus.NO_CONTENT, response.getStatusCode());
538+
539+
// Verify that Edit URI now returns a 404 (using eperson login info)
540+
authHeaders = new HttpHeaders();
541+
authHeaders.setBasicAuth(eperson.getEmail(), password);
542+
request = RequestEntity.get(editLink)
543+
.accept(MediaType.valueOf("application/atom+xml"))
544+
.headers(authHeaders)
545+
.build();
546+
response = responseAsString(request);
547+
// Expect a 404 response as content was deleted
548+
assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode());
549+
}
550+
448551
@Test
449552
public void editUnauthorizedTest() throws Exception {
450553
// Attempt to POST to /edit endpoint without sending authentication information

dspace-swordv2/src/main/java/org/dspace/sword2/ContainerManagerDSpace.java

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import java.util.List;
1414
import java.util.Map;
1515
import java.util.TreeMap;
16+
import java.util.UUID;
1617

1718
import org.apache.logging.log4j.Logger;
1819
import org.dspace.authorize.AuthorizeException;
@@ -25,6 +26,7 @@
2526
import org.dspace.core.Constants;
2627
import org.dspace.core.Context;
2728
import org.dspace.core.LogHelper;
29+
import org.dspace.event.Event;
2830
import org.dspace.workflow.WorkflowItem;
2931
import org.dspace.workflow.WorkflowItemService;
3032
import org.dspace.workflow.factory.WorkflowServiceFactory;
@@ -756,13 +758,19 @@ protected void doContainerDelete(SwordContext swordContext, Item item,
756758
if (wft.isItemInWorkspace(swordContext.getContext(), item)) {
757759
WorkspaceItem wsi = wft.getWorkspaceItem(context, item);
758760
workspaceItemService.deleteAll(context, wsi);
761+
// the item is deleted in the above call
759762
} else if (wft.isItemInWorkflow(context, item)) {
760763
WorkflowItem wfi = wft.getWorkflowItem(context, item);
761764
workflowItemService.deleteWrapper(context, wfi);
762765
}
763766

764-
// then delete the item
765-
itemService.delete(context, item);
767+
// then delete the item, but only if it hasn't already been deleted by the methods above.
768+
// the delete method is called in `workspaceItemService.deleteAll(context, wsi);`,
769+
// so it should not be called again here, as that would throw an exception.
770+
if (!isItemAlreadyDeleted(context, item.getID())) {
771+
itemService.delete(context, item);
772+
}
773+
766774
} catch (SQLException | IOException e) {
767775
throw new DSpaceSwordException(e);
768776
} catch (AuthorizeException e) {
@@ -788,4 +796,20 @@ private Item getDSpaceTarget(Context context, String editUrl,
788796

789797
return item;
790798
}
799+
800+
/**
801+
* Check if the item is already deleted in the context.
802+
*/
803+
private boolean isItemAlreadyDeleted(Context context, UUID itemUUID) {
804+
if (context.getEvents() == null) {
805+
return false;
806+
}
807+
808+
for (Event event : context.getEvents()) {
809+
if (event.getEventType() == Event.DELETE && event.getSubjectID().equals(itemUUID)) {
810+
return true;
811+
}
812+
}
813+
return false;
814+
}
791815
}

0 commit comments

Comments
 (0)