From 7cf20f2b86d3c605728862f5859d38a6414df28b Mon Sep 17 00:00:00 2001 From: eskander Date: Tue, 3 Sep 2024 13:57:07 +0300 Subject: [PATCH 1/3] [DSC-1487] Expose the item submitter over the REST --- .../org/dspace/app/rest/model/ItemRest.java | 6 ++ .../ItemSubmitterLinkRepository.java | 61 +++++++++++++++++++ .../dspace/app/rest/ItemRestRepositoryIT.java | 45 ++++++++++++++ .../dspace/app/rest/matcher/ItemMatcher.java | 6 +- 4 files changed, 116 insertions(+), 2 deletions(-) create mode 100644 dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ItemSubmitterLinkRepository.java diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ItemRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ItemRest.java index ed14790f737e..d3343c42dd65 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ItemRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ItemRest.java @@ -56,6 +56,10 @@ @LinkRest( name = ItemRest.THUMBNAIL, method = "getThumbnail" + ), + @LinkRest( + name = ItemRest.SUBMITTER, + method = "getItemSubmitter" ) }) public class ItemRest extends DSpaceObjectRest { @@ -74,6 +78,8 @@ public class ItemRest extends DSpaceObjectRest { public static final String METRICS = "metrics"; public static final String THUMBNAIL = "thumbnail"; + public static final String SUBMITTER = "submitter"; + private boolean inArchive = false; private boolean discoverable = false; private boolean withdrawn = false; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ItemSubmitterLinkRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ItemSubmitterLinkRepository.java new file mode 100644 index 000000000000..28ea7da32e1c --- /dev/null +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ItemSubmitterLinkRepository.java @@ -0,0 +1,61 @@ +/** + * 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.repository; + +import java.sql.SQLException; +import java.util.UUID; +import javax.annotation.Nullable; +import javax.servlet.http.HttpServletRequest; + +import org.dspace.app.rest.model.EPersonRest; +import org.dspace.app.rest.model.ItemRest; +import org.dspace.app.rest.projection.Projection; +import org.dspace.content.Item; +import org.dspace.content.service.ItemService; +import org.dspace.core.Context; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Pageable; +import org.springframework.data.rest.webmvc.ResourceNotFoundException; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Component; + +/** + * Link repository for "submitter" subresource of an item. + */ +@Component(ItemRest.CATEGORY + "." + ItemRest.PLURAL_NAME + "." + ItemRest.SUBMITTER) +public class ItemSubmitterLinkRepository extends AbstractDSpaceRestRepository + implements LinkRestRepository { + + @Autowired + ItemService itemService; + + /** + * Retrieve the submitter for an item. + * + * @param request - The current request + * @param id - The item ID for which to retrieve the submitter + * @param optionalPageable - optional pageable object + * @param projection - the current projection + * @return the submitter for the item + */ + @PreAuthorize("hasPermission(#id, 'ITEM', 'READ')") + public EPersonRest getItemSubmitter(@Nullable HttpServletRequest request, UUID id, + @Nullable Pageable optionalPageable, Projection projection) { + try { + Context context = obtainContext(); + Item item = itemService.find(context, id); + if (item == null) { + throw new ResourceNotFoundException("No such item: " + id); + } + + return converter.toRest(item.getSubmitter(), projection); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } +} \ No newline at end of file diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java index 609e5c55df28..a09ad89bb4cd 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java @@ -5455,4 +5455,49 @@ public void findAccessStatusForItemTest() throws Exception { .andExpect(jsonPath("$.status", notNullValue())); } + @Test + public void findSubmitterTest() throws Exception { + context.turnOffAuthorisationSystem(); + + //** GIVEN ** + //1. A community-collection structure with one parent community with sub-community and two collections. + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity) + .withName("Sub Community") + .build(); + Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build(); + + EPerson submitter = EPersonBuilder.createEPerson(context) + .withEmail("testone@mail.com") + .withPassword(password) + .withCanLogin(true) + .build(); + + context.setCurrentUser(submitter); + + //2. Three public items that are readable by Anonymous with different subjects + Item publicItem = ItemBuilder.createItem(context, col1) + .withTitle("Public item 1") + .withIssueDate("2017-10-17") + .withAuthor("Smith, Donald") + .withSubject("ExtraEntry") + .build(); + + context.restoreAuthSystemState(); + + String token = getAuthToken(admin.getEmail(), password); + + getClient(token).perform(get("/api/core/items/" + publicItem.getID()) + .param("projection", "full")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", ItemMatcher.matchFullEmbeds())); + + getClient(token).perform(get("/api/core/items/" + publicItem.getID() + "/submitter")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.id", is(submitter.getID().toString()))) + .andExpect(jsonPath("$.email", is(submitter.getEmail()))); + } + } diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/ItemMatcher.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/ItemMatcher.java index bff84684d6f4..3ee0a75b4a90 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/ItemMatcher.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/ItemMatcher.java @@ -59,7 +59,8 @@ public static Matcher matchFullEmbeds() { "metrics", "relationships[]", "templateItemOf", - "thumbnail" + "thumbnail", + "submitter" ); } @@ -78,7 +79,8 @@ public static Matcher matchLinks(UUID uuid) { "version", "metrics", "templateItemOf", - "thumbnail" + "thumbnail", + "submitter" ); } From bfc0a9be86d137630312130fbd9520f5c73cd9fa Mon Sep 17 00:00:00 2001 From: eskander Date: Tue, 3 Sep 2024 13:57:38 +0300 Subject: [PATCH 2/3] [DSC-1487] add more ITs --- .../dspace/app/rest/ItemRestRepositoryIT.java | 77 ++++++++++++++++++- 1 file changed, 76 insertions(+), 1 deletion(-) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java index a09ad89bb4cd..8e27e047e6b5 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ItemRestRepositoryIT.java @@ -5456,7 +5456,7 @@ public void findAccessStatusForItemTest() throws Exception { } @Test - public void findSubmitterTest() throws Exception { + public void findSubmitterByAdminTest() throws Exception { context.turnOffAuthorisationSystem(); //** GIVEN ** @@ -5500,4 +5500,79 @@ public void findSubmitterTest() throws Exception { .andExpect(jsonPath("$.email", is(submitter.getEmail()))); } + @Test + public void findSubmitterWithoutReadAccessTest() throws Exception { + context.turnOffAuthorisationSystem(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); + + EPerson submitter = EPersonBuilder.createEPerson(context) + .withEmail("testone@mail.com") + .withPassword(password) + .withCanLogin(true) + .build(); + + context.setCurrentUser(submitter); + + Item publicItem = ItemBuilder.createItem(context, col1) + .withTitle("Public item 1") + .withIssueDate("2017-10-17") + .withAuthor("Smith, Donald") + .withSubject("ExtraEntry") + .build(); + + context.restoreAuthSystemState(); + + String token = getAuthToken(eperson.getEmail(), password); + + getClient(token).perform(get("/api/core/items/" + publicItem.getID()) + .param("projection", "full")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", ItemMatcher.matchFullEmbeds())); + +// find submitter by user has no read access + getClient(token).perform(get("/api/core/items/" + publicItem.getID() + "/submitter")) + .andExpect(status().isNoContent()); + } + + @Test + public void findSubmitterByAnonymousTest() throws Exception { + context.turnOffAuthorisationSystem(); + + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build(); + + EPerson submitter = EPersonBuilder.createEPerson(context) + .withEmail("testone@mail.com") + .withPassword(password) + .withCanLogin(true) + .build(); + + context.setCurrentUser(submitter); + + Item publicItem = ItemBuilder.createItem(context, col1) + .withTitle("Public item 1") + .withIssueDate("2017-10-17") + .withAuthor("Smith, Donald") + .withSubject("ExtraEntry") + .build(); + + context.restoreAuthSystemState(); + + getClient().perform(get("/api/core/items/" + publicItem.getID()) + .param("projection", "full")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", ItemMatcher.matchFullEmbeds())); + + getClient().perform(get("/api/core/items/" + publicItem.getID() + "/submitter")) + .andExpect(status().isNoContent()); + } + } From 0e06a91eed23bc3fd98dc2d07cb21b6e15c05513 Mon Sep 17 00:00:00 2001 From: Nikita Krivonosov Date: Wed, 2 Oct 2024 17:41:55 +0200 Subject: [PATCH 3/3] [DSC-1487] fixed component name for ItemSubmitterLinkRepository --- .../dspace/app/rest/repository/ItemSubmitterLinkRepository.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ItemSubmitterLinkRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ItemSubmitterLinkRepository.java index 28ea7da32e1c..ea32f0ae57b4 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ItemSubmitterLinkRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ItemSubmitterLinkRepository.java @@ -27,7 +27,7 @@ /** * Link repository for "submitter" subresource of an item. */ -@Component(ItemRest.CATEGORY + "." + ItemRest.PLURAL_NAME + "." + ItemRest.SUBMITTER) +@Component(ItemRest.CATEGORY + "." + ItemRest.NAME + "." + ItemRest.SUBMITTER) public class ItemSubmitterLinkRepository extends AbstractDSpaceRestRepository implements LinkRestRepository {