Merge pull request #9768 from 4Science/DURACOM-222

Expose the item submitter over the REST endpoint `/api/core/items/<:uuid>/submitter`
This commit is contained in:
kshepherd
2024-09-02 11:36:37 +02:00
committed by GitHub
4 changed files with 191 additions and 2 deletions

View File

@@ -52,6 +52,10 @@ import com.fasterxml.jackson.annotation.JsonProperty;
@LinkRest(
name = ItemRest.THUMBNAIL,
method = "getThumbnail"
),
@LinkRest(
name = ItemRest.SUBMITTER,
method = "getItemSubmitter"
)
})
public class ItemRest extends DSpaceObjectRest {
@@ -69,6 +73,8 @@ public class ItemRest extends DSpaceObjectRest {
public static final String TEMPLATE_ITEM_OF = "templateItemOf";
public static final String THUMBNAIL = "thumbnail";
public static final String SUBMITTER = "submitter";
private boolean inArchive = false;
private boolean discoverable = false;
private boolean withdrawn = false;

View File

@@ -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 jakarta.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);
}
}
}

View File

@@ -4696,4 +4696,124 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest {
.andExpect(jsonPath("$.status", notNullValue()));
}
@Test
public void findSubmitterByAdminTest() 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())));
}
@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());
}
}

View File

@@ -58,7 +58,8 @@ public class ItemMatcher {
"version",
"relationships[]",
"templateItemOf",
"thumbnail"
"thumbnail",
"submitter"
);
}
@@ -76,7 +77,8 @@ public class ItemMatcher {
"self",
"version",
"templateItemOf",
"thumbnail"
"thumbnail",
"submitter"
);
}