mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-08 10:34:25 +00:00
Merge branch 'main' into CST-5997-LiveImportFrom-Pubmed-NotWorking
This commit is contained in:
@@ -657,6 +657,15 @@ public class Context implements AutoCloseable {
|
|||||||
return myGroups;
|
return myGroups;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a set of all of the special groups uuids that current user is a member of.
|
||||||
|
*
|
||||||
|
* @return list of special groups uuids
|
||||||
|
*/
|
||||||
|
public Set<UUID> getSpecialGroupUuids() {
|
||||||
|
return CollectionUtils.isEmpty(specialGroups) ? Set.of() : specialGroups;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Temporary change the user bound to the context, empty the special groups that
|
* Temporary change the user bound to the context, empty the special groups that
|
||||||
* are retained to allow subsequent restore
|
* are retained to allow subsequent restore
|
||||||
|
@@ -113,9 +113,11 @@ public abstract class IndexFactoryImpl<T extends IndexableObject, S> implements
|
|||||||
log.info("Full text is larger than the configured limit (discovery.solr.fulltext.charLimit)."
|
log.info("Full text is larger than the configured limit (discovery.solr.fulltext.charLimit)."
|
||||||
+ " Only the first {} characters were indexed.", charLimit);
|
+ " Only the first {} characters were indexed.", charLimit);
|
||||||
} else {
|
} else {
|
||||||
|
log.error("Tika parsing error. Could not index full text.", saxe);
|
||||||
throw new IOException("Tika parsing error. Could not index full text.", saxe);
|
throw new IOException("Tika parsing error. Could not index full text.", saxe);
|
||||||
}
|
}
|
||||||
} catch (TikaException ex) {
|
} catch (TikaException ex) {
|
||||||
|
log.error("Tika parsing error. Could not index full text.", ex);
|
||||||
throw new IOException("Tika parsing error. Could not index full text.", ex);
|
throw new IOException("Tika parsing error. Could not index full text.", ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -569,4 +569,9 @@ public class EPersonServiceImpl extends DSpaceObjectServiceImpl<EPerson> impleme
|
|||||||
public int countTotal(Context context) throws SQLException {
|
public int countTotal(Context context) throws SQLException {
|
||||||
return ePersonDAO.countRows(context);
|
return ePersonDAO.countRows(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName(EPerson dso) {
|
||||||
|
return dso.getName();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -829,4 +829,9 @@ public class GroupServiceImpl extends DSpaceObjectServiceImpl<Group> implements
|
|||||||
final MetadataField metadataField) throws SQLException {
|
final MetadataField metadataField) throws SQLException {
|
||||||
return groupDAO.findByMetadataField(context, searchValue, metadataField);
|
return groupDAO.findByMetadataField(context, searchValue, metadataField);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName(Group dso) {
|
||||||
|
return dso.getName();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -72,7 +72,12 @@ public class DSpaceOAIDataProvider {
|
|||||||
|
|
||||||
private DSpaceResumptionTokenFormatter resumptionTokenFormat = new DSpaceResumptionTokenFormatter();
|
private DSpaceResumptionTokenFormatter resumptionTokenFormat = new DSpaceResumptionTokenFormatter();
|
||||||
|
|
||||||
@RequestMapping({"", "/"})
|
@RequestMapping("")
|
||||||
|
public void index(HttpServletResponse response, HttpServletRequest request) throws IOException {
|
||||||
|
response.sendRedirect(request.getRequestURI() + "/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping({"/"})
|
||||||
public String indexAction(HttpServletResponse response, Model model) throws ServletException {
|
public String indexAction(HttpServletResponse response, Model model) throws ServletException {
|
||||||
try {
|
try {
|
||||||
XOAIManager manager = xoaiManagerResolver.getManager();
|
XOAIManager manager = xoaiManagerResolver.getManager();
|
||||||
|
@@ -153,8 +153,9 @@ public class BitstreamRestController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
org.dspace.app.rest.utils.BitstreamResource bitstreamResource =
|
org.dspace.app.rest.utils.BitstreamResource bitstreamResource =
|
||||||
new org.dspace.app.rest.utils.BitstreamResource(
|
new org.dspace.app.rest.utils.BitstreamResource(name, uuid,
|
||||||
name, uuid, currentUser != null ? currentUser.getID() : null, citationEnabledForBitstream);
|
currentUser != null ? currentUser.getID() : null,
|
||||||
|
context.getSpecialGroupUuids(), citationEnabledForBitstream);
|
||||||
|
|
||||||
//We have all the data we need, close the connection to the database so that it doesn't stay open during
|
//We have all the data we need, close the connection to the database so that it doesn't stay open during
|
||||||
//download/streaming
|
//download/streaming
|
||||||
|
@@ -18,10 +18,18 @@ import org.dspace.app.rest.RestResourceController;
|
|||||||
* This class acts as a data holder for the RelationshipResource
|
* This class acts as a data holder for the RelationshipResource
|
||||||
* Refer to {@link org.dspace.content.Relationship} for explanation about the properties
|
* Refer to {@link org.dspace.content.Relationship} for explanation about the properties
|
||||||
*/
|
*/
|
||||||
|
@LinksRest(links = {
|
||||||
|
@LinkRest(
|
||||||
|
name = RelationshipRest.RELATIONSHIP_TYPE,
|
||||||
|
method = "getRelationshipType"
|
||||||
|
)
|
||||||
|
})
|
||||||
public class RelationshipRest extends BaseObjectRest<Integer> {
|
public class RelationshipRest extends BaseObjectRest<Integer> {
|
||||||
public static final String NAME = "relationship";
|
public static final String NAME = "relationship";
|
||||||
public static final String CATEGORY = "core";
|
public static final String CATEGORY = "core";
|
||||||
|
|
||||||
|
public static final String RELATIONSHIP_TYPE = "relationshipType";
|
||||||
|
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
private UUID leftId;
|
private UUID leftId;
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
|
@@ -0,0 +1,56 @@
|
|||||||
|
/**
|
||||||
|
* 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 javax.annotation.Nullable;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
import org.dspace.app.rest.model.RelationshipRest;
|
||||||
|
import org.dspace.app.rest.model.RelationshipTypeRest;
|
||||||
|
import org.dspace.app.rest.projection.Projection;
|
||||||
|
import org.dspace.content.Relationship;
|
||||||
|
import org.dspace.content.RelationshipType;
|
||||||
|
import org.dspace.content.service.RelationshipService;
|
||||||
|
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 "relationshipType" subresource of an individual Relationship.
|
||||||
|
*/
|
||||||
|
@Component(RelationshipRest.CATEGORY + "." + RelationshipRest.NAME + "." + RelationshipRest.RELATIONSHIP_TYPE)
|
||||||
|
public class RelationshipTypeRelationshipLinkRepository extends AbstractDSpaceRestRepository
|
||||||
|
implements LinkRestRepository {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
RelationshipService relationshipService;
|
||||||
|
|
||||||
|
@PreAuthorize("permitAll()")
|
||||||
|
public RelationshipTypeRest getRelationshipType(@Nullable HttpServletRequest request,
|
||||||
|
Integer relationshipId,
|
||||||
|
@Nullable Pageable optionalPageable,
|
||||||
|
Projection projection) {
|
||||||
|
try {
|
||||||
|
Context context = obtainContext();
|
||||||
|
Relationship relationship = relationshipService.find(context, relationshipId);
|
||||||
|
if (relationship == null) {
|
||||||
|
throw new ResourceNotFoundException("No such relationship: " + relationshipId);
|
||||||
|
}
|
||||||
|
int total = relationshipService.countByRelationshipType(context, relationship.getRelationshipType());
|
||||||
|
Pageable pageable = utils.getPageable(optionalPageable);
|
||||||
|
RelationshipType relationshipType = relationship.getRelationshipType();
|
||||||
|
return converter.toRest(relationshipType, projection);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -11,6 +11,7 @@ import java.io.ByteArrayInputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
@@ -40,6 +41,7 @@ public class BitstreamResource extends AbstractResource {
|
|||||||
private UUID currentUserUUID;
|
private UUID currentUserUUID;
|
||||||
private boolean shouldGenerateCoverPage;
|
private boolean shouldGenerateCoverPage;
|
||||||
private byte[] file;
|
private byte[] file;
|
||||||
|
private Set<UUID> currentSpecialGroups;
|
||||||
|
|
||||||
private BitstreamService bitstreamService = ContentServiceFactory.getInstance().getBitstreamService();
|
private BitstreamService bitstreamService = ContentServiceFactory.getInstance().getBitstreamService();
|
||||||
private EPersonService ePersonService = EPersonServiceFactory.getInstance().getEPersonService();
|
private EPersonService ePersonService = EPersonServiceFactory.getInstance().getEPersonService();
|
||||||
@@ -47,11 +49,12 @@ public class BitstreamResource extends AbstractResource {
|
|||||||
new DSpace().getServiceManager()
|
new DSpace().getServiceManager()
|
||||||
.getServicesByType(CitationDocumentService.class).get(0);
|
.getServicesByType(CitationDocumentService.class).get(0);
|
||||||
|
|
||||||
public BitstreamResource(String name, UUID uuid, UUID currentUserUUID,
|
public BitstreamResource(String name, UUID uuid, UUID currentUserUUID, Set<UUID> currentSpecialGroups,
|
||||||
boolean shouldGenerateCoverPage) {
|
boolean shouldGenerateCoverPage) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.uuid = uuid;
|
this.uuid = uuid;
|
||||||
this.currentUserUUID = currentUserUUID;
|
this.currentUserUUID = currentUserUUID;
|
||||||
|
this.currentSpecialGroups = currentSpecialGroups;
|
||||||
this.shouldGenerateCoverPage = shouldGenerateCoverPage;
|
this.shouldGenerateCoverPage = shouldGenerateCoverPage;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,9 +87,8 @@ public class BitstreamResource extends AbstractResource {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InputStream getInputStream() throws IOException {
|
public InputStream getInputStream() throws IOException {
|
||||||
try (Context context = new Context()) {
|
try (Context context = initializeContext()) {
|
||||||
EPerson currentUser = ePersonService.find(context, currentUserUUID);
|
|
||||||
context.setCurrentUser(currentUser);
|
|
||||||
Bitstream bitstream = bitstreamService.find(context, uuid);
|
Bitstream bitstream = bitstreamService.find(context, uuid);
|
||||||
InputStream out;
|
InputStream out;
|
||||||
|
|
||||||
@@ -110,9 +112,7 @@ public class BitstreamResource extends AbstractResource {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long contentLength() throws IOException {
|
public long contentLength() throws IOException {
|
||||||
try (Context context = new Context()) {
|
try (Context context = initializeContext()) {
|
||||||
EPerson currentUser = ePersonService.find(context, currentUserUUID);
|
|
||||||
context.setCurrentUser(currentUser);
|
|
||||||
Bitstream bitstream = bitstreamService.find(context, uuid);
|
Bitstream bitstream = bitstreamService.find(context, uuid);
|
||||||
if (shouldGenerateCoverPage) {
|
if (shouldGenerateCoverPage) {
|
||||||
return getCoverpageByteArray(context, bitstream).length;
|
return getCoverpageByteArray(context, bitstream).length;
|
||||||
@@ -123,4 +123,12 @@ public class BitstreamResource extends AbstractResource {
|
|||||||
throw new IOException(e);
|
throw new IOException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Context initializeContext() throws SQLException {
|
||||||
|
Context context = new Context();
|
||||||
|
EPerson currentUser = ePersonService.find(context, currentUserUUID);
|
||||||
|
context.setCurrentUser(currentUser);
|
||||||
|
currentSpecialGroups.forEach(context::setSpecialGroup);
|
||||||
|
return context;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -63,9 +63,9 @@ public class OAIpmhIT extends AbstractControllerIntegrationTest {
|
|||||||
private ConfigurationService configurationService;
|
private ConfigurationService configurationService;
|
||||||
|
|
||||||
// All OAI-PMH paths that we test against
|
// All OAI-PMH paths that we test against
|
||||||
private final String ROOT_PATH = "/oai";
|
private final String ROOT_PATH = "/oai/";
|
||||||
private final String DEFAULT_CONTEXT_PATH = "request";
|
private final String DEFAULT_CONTEXT_PATH = "request";
|
||||||
private final String DEFAULT_CONTEXT = ROOT_PATH + "/" + DEFAULT_CONTEXT_PATH;
|
private final String DEFAULT_CONTEXT = ROOT_PATH + DEFAULT_CONTEXT_PATH;
|
||||||
|
|
||||||
// Mock to ensure XOAI caching is disabled for all tests (see @Before method)
|
// Mock to ensure XOAI caching is disabled for all tests (see @Before method)
|
||||||
@MockBean
|
@MockBean
|
||||||
|
@@ -684,6 +684,56 @@ public class BitstreamRestControllerIT extends AbstractControllerIntegrationTest
|
|||||||
checkNumberOfStatsRecords(bitstream, 1);
|
checkNumberOfStatsRecords(bitstream, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void restrictedSpecialGroupBitstreamTest() throws Exception {
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
parentCommunity = CommunityBuilder.createCommunity(context)
|
||||||
|
.withName("Parent Community")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity)
|
||||||
|
.withName("Collection 1")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Group restrictedGroup = GroupBuilder.createGroup(context)
|
||||||
|
.withName("Restricted Group")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
String bitstreamContent = "Private!";
|
||||||
|
try (InputStream is = IOUtils.toInputStream(bitstreamContent, CharEncoding.UTF_8)) {
|
||||||
|
|
||||||
|
Item item = ItemBuilder.createItem(context, col1)
|
||||||
|
.withTitle("item 1")
|
||||||
|
.withIssueDate("2013-01-17")
|
||||||
|
.withAuthor("Doe, John")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
bitstream = BitstreamBuilder
|
||||||
|
.createBitstream(context, item, is)
|
||||||
|
.withName("Test Embargoed Bitstream")
|
||||||
|
.withDescription("This bitstream is embargoed")
|
||||||
|
.withMimeType("text/plain")
|
||||||
|
.withReaderGroup(restrictedGroup)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
String authToken = getAuthToken(eperson.getEmail(), password);
|
||||||
|
getClient(authToken).perform(get("/api/core/bitstreams/" + bitstream.getID() + "/content"))
|
||||||
|
.andExpect(status().isForbidden());
|
||||||
|
|
||||||
|
configurationService.setProperty("authentication-password.login.specialgroup", "Restricted Group");
|
||||||
|
|
||||||
|
authToken = getAuthToken(eperson.getEmail(), password);
|
||||||
|
getClient(authToken).perform(get("/api/core/bitstreams/" + bitstream.getID() + "/content"))
|
||||||
|
.andExpect(status().isOk());
|
||||||
|
|
||||||
|
checkNumberOfStatsRecords(bitstream, 1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void restrictedGroupBitstreamAccessGrantByAdminsTest() throws Exception {
|
public void restrictedGroupBitstreamAccessGrantByAdminsTest() throws Exception {
|
||||||
context.turnOffAuthorisationSystem();
|
context.turnOffAuthorisationSystem();
|
||||||
|
@@ -3164,4 +3164,28 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
|
|||||||
.andExpect(jsonPath("$.page.totalElements", is(2)));
|
.andExpect(jsonPath("$.page.totalElements", is(2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void findTheCreatedRelationshipTypeTest() throws Exception {
|
||||||
|
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
Relationship relationship = RelationshipBuilder
|
||||||
|
.createRelationshipBuilder(context, author1, orgUnit1, isOrgUnitOfPersonRelationshipType).build();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
Integer relationshipId = relationship.getID();
|
||||||
|
getClient().perform(get("/api/core/relationships/" + relationshipId))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.id", is(relationship.getID())))
|
||||||
|
.andExpect(jsonPath("$._embedded.relationships").doesNotExist())
|
||||||
|
.andExpect(jsonPath("$._links.relationshipType.href",
|
||||||
|
containsString("/api/core/relationships/" + relationshipId + "/relationshipType"))
|
||||||
|
);
|
||||||
|
|
||||||
|
String adminToken = getAuthToken(admin.getEmail(), password);
|
||||||
|
getClient(adminToken).perform(get("/api/core/relationships/" + relationshipId + "/relationshipType"))
|
||||||
|
.andExpect(status().isOk());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user