Implement community feedbacks

This commit is contained in:
Mykhaylo
2021-09-28 19:02:51 +02:00
parent 5c52a6926f
commit f6e23f2061
16 changed files with 211 additions and 81 deletions

View File

@@ -97,7 +97,7 @@ public class BitstreamServiceImpl extends DSpaceObjectServiceImpl<Bitstream> imp
@Override @Override
public Bitstream clone(Context context, Bitstream bitstream) public Bitstream clone(Context context, Bitstream bitstream)
throws SQLException { throws SQLException, AuthorizeException {
// Create a new bitstream with a new ID. // Create a new bitstream with a new ID.
Bitstream clonedBitstream = bitstreamDAO.create(context, new Bitstream()); Bitstream clonedBitstream = bitstreamDAO.create(context, new Bitstream());
// Set the internal identifier, file size, checksum, and // Set the internal identifier, file size, checksum, and
@@ -107,18 +107,7 @@ public class BitstreamServiceImpl extends DSpaceObjectServiceImpl<Bitstream> imp
clonedBitstream.setChecksum(bitstream.getChecksum()); clonedBitstream.setChecksum(bitstream.getChecksum());
clonedBitstream.setChecksumAlgorithm(bitstream.getChecksumAlgorithm()); clonedBitstream.setChecksumAlgorithm(bitstream.getChecksumAlgorithm());
clonedBitstream.setFormat(bitstream.getBitstreamFormat()); clonedBitstream.setFormat(bitstream.getBitstreamFormat());
update(context, clonedBitstream);
try {
//Update our bitstream but turn off the authorization system since permissions
//haven't been set at this point in time.
context.turnOffAuthorisationSystem();
update(context, clonedBitstream);
} catch (AuthorizeException e) {
log.error(e);
//Can never happen since we turn off authorization before we update
} finally {
context.restoreAuthSystemState();
}
return clonedBitstream; return clonedBitstream;
} }

View File

@@ -54,7 +54,7 @@ public interface BitstreamService extends DSpaceObjectService<Bitstream>, DSpace
* @return the clone * @return the clone
* @throws SQLException if database error * @throws SQLException if database error
*/ */
public Bitstream clone(Context context, Bitstream bitstream) throws SQLException; public Bitstream clone(Context context, Bitstream bitstream) throws SQLException, AuthorizeException;
/** /**
* Create a new bitstream, with a new ID. The checksum and file size are * Create a new bitstream, with a new ID. The checksum and file size are

View File

@@ -350,20 +350,30 @@ public class BitstreamStorageServiceImpl implements BitstreamStorageService, Ini
*/ */
@Override @Override
public Bitstream clone(Context context, Bitstream bitstream) throws SQLException, IOException, AuthorizeException { public Bitstream clone(Context context, Bitstream bitstream) throws SQLException, IOException, AuthorizeException {
Bitstream clonedBitstream = bitstreamService.clone(context, bitstream); Bitstream clonedBitstream = null;
clonedBitstream.setStoreNumber(bitstream.getStoreNumber()); try {
// Update our bitstream but turn off the authorization system since permissions
// haven't been set at this point in time.
context.turnOffAuthorisationSystem();
clonedBitstream = bitstreamService.clone(context, bitstream);
clonedBitstream.setStoreNumber(bitstream.getStoreNumber());
List<MetadataValue> metadataValues = bitstreamService List<MetadataValue> metadataValues = bitstreamService.getMetadata(bitstream, Item.ANY, Item.ANY, Item.ANY,
.getMetadata(bitstream, Item.ANY, Item.ANY, Item.ANY, Item.ANY); Item.ANY);
for (MetadataValue metadataValue : metadataValues) { for (MetadataValue metadataValue : metadataValues) {
bitstreamService.addMetadata(context, clonedBitstream, metadataValue.getMetadataField(), bitstreamService.addMetadata(context, clonedBitstream, metadataValue.getMetadataField(),
metadataValue.getLanguage(), metadataValue.getValue(), metadataValue.getAuthority(), metadataValue.getLanguage(), metadataValue.getValue(), metadataValue.getAuthority(),
metadataValue.getConfidence()); metadataValue.getConfidence());
}
bitstreamService.update(context, clonedBitstream);
} catch (AuthorizeException e) {
log.error(e);
// Can never happen since we turn off authorization before we update
} finally {
context.restoreAuthSystemState();
} }
bitstreamService.update(context, clonedBitstream);
return clonedBitstream; return clonedBitstream;
} }
/** /**

View File

@@ -21,7 +21,7 @@ import javax.persistence.OrderBy;
import javax.persistence.SequenceGenerator; import javax.persistence.SequenceGenerator;
import javax.persistence.Table; import javax.persistence.Table;
import com.amazonaws.util.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.dspace.core.Context; import org.dspace.core.Context;
import org.dspace.core.ReloadableEntity; import org.dspace.core.ReloadableEntity;
import org.hibernate.proxy.HibernateProxyHelper; import org.hibernate.proxy.HibernateProxyHelper;
@@ -94,7 +94,7 @@ public class VersionHistory implements ReloadableEntity<Integer> {
* @return true if the last version in submission, otherwise false. * @return true if the last version in submission, otherwise false.
*/ */
public boolean hasDraftVersion() { public boolean hasDraftVersion() {
if (!CollectionUtils.isNullOrEmpty(versions) && Objects.nonNull(versions.get(0).getItem())) { if (CollectionUtils.isNotEmpty(versions) && Objects.nonNull(versions.get(0).getItem())) {
return !versions.get(0).getItem().isArchived(); return !versions.get(0).getItem().isArchived();
} }
return false; return false;

View File

@@ -55,6 +55,7 @@ public class CanCreateVersionFeature implements AuthorizationFeature {
} }
Item item = itemService.find(context, UUID.fromString(((ItemRest) object).getUuid())); Item item = itemService.find(context, UUID.fromString(((ItemRest) object).getUuid()));
if (Objects.nonNull(item)) { if (Objects.nonNull(item)) {
// The property versioning.block.entity is used to disable versioning for items with EntityType
boolean isBlockEntity = configurationService.getBooleanProperty("versioning.block.entity", true); boolean isBlockEntity = configurationService.getBooleanProperty("versioning.block.entity", true);
boolean hasEntityType = StringUtils.isNotBlank(itemService. boolean hasEntityType = StringUtils.isNotBlank(itemService.
getMetadataFirstValue(item, "dspace", "entity", "type", Item.ANY)); getMetadataFirstValue(item, "dspace", "entity", "type", Item.ANY));

View File

@@ -49,7 +49,8 @@ public class ItemVersionLinkRepository extends AbstractDSpaceRestRepository
* itemUuid param as UUID * itemUuid param as UUID
* @throws SQLException If something goes wrong * @throws SQLException If something goes wrong
*/ */
@PreAuthorize("hasPermission(@extractorOf.getVersionIdByItemUUID(#request, #itemUuid), 'VERSION', 'READ')") @PreAuthorize("hasPermission(@extractorOf.getVersionIdByItemUUID(#request, #itemUuid), 'VERSION', 'READ') || " +
"@extractorOf.getVersionIdByItemUUID(#request, #itemUuid) == null" )
public VersionRest getItemVersion(@Nullable HttpServletRequest request, public VersionRest getItemVersion(@Nullable HttpServletRequest request,
UUID itemUuid, UUID itemUuid,
@Nullable Pageable optionalPageable, @Nullable Pageable optionalPageable,

View File

@@ -60,6 +60,16 @@ public class ExtractorOfAInprogressSubmissionInformations {
@Autowired @Autowired
private RequestService requestService; private RequestService requestService;
/**
* This method is used on security checks, given a versionHistory id,
* it searches the latest version and checks if there is
* a Workspace/Workflow item in progress submission,
* if yes return the id of this one, otherwise returns null.
*
* @param request The current request
* @param versionHistoryId VersionHistoryId
* @return
*/
public Integer getAInprogressSubmissionID(@Nullable HttpServletRequest request, Integer versionHistoryId) { public Integer getAInprogressSubmissionID(@Nullable HttpServletRequest request, Integer versionHistoryId) {
Context context = getContext(request); Context context = getContext(request);
if (Objects.nonNull(versionHistoryId)) { if (Objects.nonNull(versionHistoryId)) {
@@ -67,11 +77,11 @@ public class ExtractorOfAInprogressSubmissionInformations {
VersionHistory versionHistory = versionHistoryService.find(context, versionHistoryId); VersionHistory versionHistory = versionHistoryService.find(context, versionHistoryId);
if (Objects.nonNull(versionHistory)) { if (Objects.nonNull(versionHistory)) {
Version oldestVersion = versionHistoryService.getLatestVersion(context, versionHistory); Version oldestVersion = versionHistoryService.getLatestVersion(context, versionHistory);
WorkflowItem workflowItem = workflowItemService.findByItem(context, oldestVersion.getItem());
WorkspaceItem workspaceItem = workspaceItemService.findByItem(context, oldestVersion.getItem()); WorkspaceItem workspaceItem = workspaceItemService.findByItem(context, oldestVersion.getItem());
if (Objects.nonNull(workspaceItem)) { if (Objects.nonNull(workspaceItem)) {
return workspaceItem.getID(); return workspaceItem.getID();
} }
WorkflowItem workflowItem = workflowItemService.findByItem(context, oldestVersion.getItem());
if (Objects.nonNull(workflowItem)) { if (Objects.nonNull(workflowItem)) {
return workflowItem.getID(); return workflowItem.getID();
} }
@@ -83,6 +93,15 @@ public class ExtractorOfAInprogressSubmissionInformations {
return null; return null;
} }
/**
* This method is used on security checks, given a versionHistory id,
* it searches the latest version and checks if there is a Workspace/Workflow item in progress submission,
* if yes return the rest name - 'workspaceitem' or 'workflowitem', otherwise it returns the empty string.
*
* @param request The current request
* @param versionHistoryId VersionHistoryId
* @return
*/
public String getAInprogressSubmissionTarget(@Nullable HttpServletRequest request, Integer versionHistoryId) { public String getAInprogressSubmissionTarget(@Nullable HttpServletRequest request, Integer versionHistoryId) {
Context context = getContext(request); Context context = getContext(request);
if (Objects.nonNull(versionHistoryId)) { if (Objects.nonNull(versionHistoryId)) {
@@ -90,12 +109,10 @@ public class ExtractorOfAInprogressSubmissionInformations {
VersionHistory versionHistory = versionHistoryService.find(context, versionHistoryId); VersionHistory versionHistory = versionHistoryService.find(context, versionHistoryId);
if (Objects.nonNull(versionHistory)) { if (Objects.nonNull(versionHistory)) {
Version oldestVersion = versionHistoryService.getLatestVersion(context, versionHistory); Version oldestVersion = versionHistoryService.getLatestVersion(context, versionHistory);
WorkflowItem workflowItem = workflowItemService.findByItem(context, oldestVersion.getItem()); if (Objects.nonNull(workspaceItemService.findByItem(context, oldestVersion.getItem()))) {
WorkspaceItem workspaceItem = workspaceItemService.findByItem(context, oldestVersion.getItem());
if (Objects.nonNull(workspaceItem)) {
return WorkspaceItemRest.NAME; return WorkspaceItemRest.NAME;
} }
if (Objects.nonNull(workflowItem)) { if (Objects.nonNull(workflowItemService.findByItem(context, oldestVersion.getItem()))) {
return WorkflowItemRest.NAME; return WorkflowItemRest.NAME;
} }
} }
@@ -106,6 +123,14 @@ public class ExtractorOfAInprogressSubmissionInformations {
return StringUtils.EMPTY; return StringUtils.EMPTY;
} }
/**
* This method is used on security checks, given an item UUID,
* it searches the relative version, if version exist return its id, otherwise returns null.
*
* @param request The current request
* @param uuid Item uuid
* @return
*/
public Integer getVersionIdByItemUUID(@Nullable HttpServletRequest request, UUID uuid) { public Integer getVersionIdByItemUUID(@Nullable HttpServletRequest request, UUID uuid) {
Context context = getContext(request); Context context = getContext(request);
if (Objects.nonNull(uuid)) { if (Objects.nonNull(uuid)) {

View File

@@ -26,6 +26,8 @@ import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
/** /**
* This class evaluate ADMIN permissions to patch operation over a Version.
*
* @author Mykhaylo Boychuk (mykhaylo.boychuk at 4science.it) * @author Mykhaylo Boychuk (mykhaylo.boychuk at 4science.it)
*/ */
@Component @Component

View File

@@ -4175,8 +4175,6 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest {
getClient().perform(get("/api/core/items/" + item.getID() + "/version")) getClient().perform(get("/api/core/items/" + item.getID() + "/version"))
.andExpect(status().isUnauthorized()); .andExpect(status().isUnauthorized());
configurationService.setProperty("versioning.item.history.view.admin", true);
} }
@Test @Test
@@ -4207,8 +4205,47 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest {
String epersonToken = getAuthToken(eperson.getEmail(), password); String epersonToken = getAuthToken(eperson.getEmail(), password);
getClient(epersonToken).perform(get("/api/core/items/" + item.getID() + "/version")) getClient(epersonToken).perform(get("/api/core/items/" + item.getID() + "/version"))
.andExpect(status().isForbidden()); .andExpect(status().isForbidden());
}
configurationService.setProperty("versioning.item.history.view.admin", true); @Test
public void findVersionForItemAndProprtyHistoryViewAdminIsDisabledTest() throws Exception {
configurationService.setProperty("versioning.item.history.view.admin", false);
context.turnOffAuthorisationSystem();
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community")
.build();
Collection col = CollectionBuilder.createCollection(context, parentCommunity)
.withName("Collection test")
.build();
Item item = ItemBuilder.createItem(context, col)
.withTitle("Public test item")
.withIssueDate("2021-04-27")
.withAuthor("Doe, John")
.withSubject("ExtraEntry")
.build();
VersionBuilder.createVersion(context, item, "test").build();
context.restoreAuthSystemState();
String epersonToken = getAuthToken(eperson.getEmail(), password);
getClient(epersonToken).perform(get("/api/core/items/" + item.getID() + "/version"))
.andExpect(status().isOk())
.andExpect(jsonPath("$", Matchers.allOf(
hasJsonPath("$.version", is(1)),
hasJsonPath("$.summary", emptyOrNullString()),
hasJsonPath("$.type", is("version"))
)))
.andExpect(jsonPath("$._links.versionhistory.href",
Matchers.containsString("api/versioning/versions/1/versionhistory")))
.andExpect(jsonPath("$._links.item.href",
Matchers.containsString("api/versioning/versions/1/item")))
.andExpect(jsonPath("$._links.self.href",
Matchers.containsString("api/versioning/versions/1")));
} }
@Test @Test
@@ -4242,4 +4279,32 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest {
.andExpect(status().isBadRequest()); .andExpect(status().isBadRequest());
} }
@Test
public void findVersionForItemWithoutVersionsTest() throws Exception {
context.turnOffAuthorisationSystem();
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community")
.build();
Collection col = CollectionBuilder.createCollection(context, parentCommunity)
.withName("Collection test")
.build();
Item item = ItemBuilder.createItem(context, col)
.withTitle("Public test item")
.withIssueDate("2021-04-27")
.withAuthor("Doe, John")
.withSubject("ExtraEntry")
.build();
item.setSubmitter(eperson);
context.restoreAuthSystemState();
String epersonToken = getAuthToken(eperson.getEmail(), password);
getClient(epersonToken).perform(get("/api/core/items/" + item.getID() + "/version"))
.andExpect(status().isNoContent());
}
} }

View File

@@ -10,6 +10,7 @@ package org.dspace.app.rest;
import static com.jayway.jsonpath.JsonPath.read; import static com.jayway.jsonpath.JsonPath.read;
import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.containsInRelativeOrder;
import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.is;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
@@ -43,6 +44,7 @@ import org.dspace.versioning.service.VersionHistoryService;
import org.dspace.versioning.service.VersioningService; import org.dspace.versioning.service.VersioningService;
import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem; import org.dspace.xmlworkflow.storedcomponents.XmlWorkflowItem;
import org.hamcrest.Matchers; import org.hamcrest.Matchers;
import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -93,6 +95,13 @@ public class VersionHistoryRestRepositoryIT extends AbstractControllerIntegratio
context.restoreAuthSystemState(); context.restoreAuthSystemState();
} }
@After
public void cleanup() throws SQLException, AuthorizeException {
context.turnOffAuthorisationSystem();
versionHistoryService.delete(context, versionHistory);
context.restoreAuthSystemState();
}
@Test @Test
public void findOnePublicVersionHistoryTest() throws Exception { public void findOnePublicVersionHistoryTest() throws Exception {
getClient().perform(get("/api/versioning/versionhistories/" + versionHistory.getID())) getClient().perform(get("/api/versioning/versionhistories/" + versionHistory.getID()))
@@ -135,9 +144,6 @@ public class VersionHistoryRestRepositoryIT extends AbstractControllerIntegratio
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(jsonPath("$.draftVersion", Matchers.is(true))) .andExpect(jsonPath("$.draftVersion", Matchers.is(true)))
.andExpect(jsonPath("$", is(VersionHistoryMatcher.matchEntry(versionHistory)))); .andExpect(jsonPath("$", is(VersionHistoryMatcher.matchEntry(versionHistory))));
configurationService.setProperty("versioning.item.history.view.admin", false);
} }
@Test @Test
@@ -147,8 +153,6 @@ public class VersionHistoryRestRepositoryIT extends AbstractControllerIntegratio
String token = getAuthToken(eperson.getEmail(), password); String token = getAuthToken(eperson.getEmail(), password);
getClient(token).perform(get("/api/versioning/versionhistories/" + versionHistory.getID())) getClient(token).perform(get("/api/versioning/versionhistories/" + versionHistory.getID()))
.andExpect(status().isForbidden()); .andExpect(status().isForbidden());
configurationService.setProperty("versioning.item.history.view.admin", false);
} }
@Test @Test
@@ -184,17 +188,17 @@ public class VersionHistoryRestRepositoryIT extends AbstractControllerIntegratio
.withSubject("ExtraEntry") .withSubject("ExtraEntry")
.build(); .build();
Version version = VersionBuilder.createVersion(context, item, "test").build(); Version version2 = VersionBuilder.createVersion(context, item, "test").build();
VersionHistory versionHistory = versionHistoryService.findByItem(context, item); VersionHistory versionHistory = versionHistoryService.findByItem(context, item);
Version version2 = versioningService.getVersion(context, item); Version version = versioningService.getVersion(context, item);
context.turnOffAuthorisationSystem(); context.turnOffAuthorisationSystem();
String tokenAdmin = getAuthToken(admin.getEmail(), password); String tokenAdmin = getAuthToken(admin.getEmail(), password);
getClient(tokenAdmin).perform(get("/api/versioning/versionhistories/" + versionHistory.getID() + "/versions")) getClient(tokenAdmin).perform(get("/api/versioning/versionhistories/" + versionHistory.getID() + "/versions"))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.versions", containsInAnyOrder( .andExpect(jsonPath("$._embedded.versions", containsInRelativeOrder(
VersionMatcher.matchEntry(version), VersionMatcher.matchEntry(version2),
VersionMatcher.matchEntry(version2) VersionMatcher.matchEntry(version)
))); )));
context.turnOffAuthorisationSystem(); context.turnOffAuthorisationSystem();
@@ -203,10 +207,10 @@ public class VersionHistoryRestRepositoryIT extends AbstractControllerIntegratio
getClient(tokenAdmin).perform(get("/api/versioning/versionhistories/" + versionHistory.getID() + "/versions")) getClient(tokenAdmin).perform(get("/api/versioning/versionhistories/" + versionHistory.getID() + "/versions"))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.versions", containsInAnyOrder( .andExpect(jsonPath("$._embedded.versions", containsInRelativeOrder(
VersionMatcher.matchEntry(version), VersionMatcher.matchEntry(version3),
VersionMatcher.matchEntry(version2), VersionMatcher.matchEntry(version2),
VersionMatcher.matchEntry(version3) VersionMatcher.matchEntry(version)
))); )));
} }
@@ -235,8 +239,6 @@ public class VersionHistoryRestRepositoryIT extends AbstractControllerIntegratio
getClient().perform(get("/api/versioning/versionhistories/" + versionHistory.getID() + "/versions")) getClient().perform(get("/api/versioning/versionhistories/" + versionHistory.getID() + "/versions"))
.andExpect(status().isUnauthorized()); .andExpect(status().isUnauthorized());
configurationService.setProperty("versioning.item.history.view.admin", true);
} }
@Test @Test

View File

@@ -18,12 +18,15 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import org.apache.commons.io.IOUtils;
import org.dspace.app.rest.authorization.Authorization; import org.dspace.app.rest.authorization.Authorization;
import org.dspace.app.rest.authorization.AuthorizationFeature; import org.dspace.app.rest.authorization.AuthorizationFeature;
import org.dspace.app.rest.authorization.AuthorizationFeatureService; import org.dspace.app.rest.authorization.AuthorizationFeatureService;
@@ -40,6 +43,8 @@ import org.dspace.app.rest.model.patch.ReplaceOperation;
import org.dspace.app.rest.projection.DefaultProjection; import org.dspace.app.rest.projection.DefaultProjection;
import org.dspace.app.rest.test.AbstractControllerIntegrationTest; import org.dspace.app.rest.test.AbstractControllerIntegrationTest;
import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeException;
import org.dspace.builder.BitstreamBuilder;
import org.dspace.builder.BundleBuilder;
import org.dspace.builder.CollectionBuilder; import org.dspace.builder.CollectionBuilder;
import org.dspace.builder.CommunityBuilder; import org.dspace.builder.CommunityBuilder;
import org.dspace.builder.EPersonBuilder; import org.dspace.builder.EPersonBuilder;
@@ -47,6 +52,7 @@ import org.dspace.builder.ItemBuilder;
import org.dspace.builder.VersionBuilder; import org.dspace.builder.VersionBuilder;
import org.dspace.builder.WorkflowItemBuilder; import org.dspace.builder.WorkflowItemBuilder;
import org.dspace.builder.WorkspaceItemBuilder; import org.dspace.builder.WorkspaceItemBuilder;
import org.dspace.content.Bundle;
import org.dspace.content.Collection; import org.dspace.content.Collection;
import org.dspace.content.Community; import org.dspace.content.Community;
import org.dspace.content.Item; import org.dspace.content.Item;
@@ -503,7 +509,8 @@ public class VersionRestRepositoryIT extends AbstractControllerIntegrationTest {
hasJsonPath("$.summary", is("check first version")), hasJsonPath("$.summary", is("check first version")),
hasJsonPath("$.submitterName", is("first (admin) last (admin)")), hasJsonPath("$.submitterName", is("first (admin) last (admin)")),
hasJsonPath("$.type", is("version")) hasJsonPath("$.type", is("version"))
))); )))
.andDo(result -> idRef.set(read(result.getResponse().getContentAsString(), "$.id")));
} finally { } finally {
VersionBuilder.delete(idRef.get()); VersionBuilder.delete(idRef.get());
} }
@@ -654,7 +661,6 @@ public class VersionRestRepositoryIT extends AbstractControllerIntegrationTest {
} finally { } finally {
VersionBuilder.delete(idRef.get()); VersionBuilder.delete(idRef.get());
} }
configurationService.setProperty("versioning.submitterCanCreateNewVersion", false);
} }
@Test @Test
@@ -717,8 +723,6 @@ public class VersionRestRepositoryIT extends AbstractControllerIntegrationTest {
.contentType(MediaType.parseMediaType(RestMediaTypes.TEXT_URI_LIST_VALUE)) .contentType(MediaType.parseMediaType(RestMediaTypes.TEXT_URI_LIST_VALUE))
.content("/api/core/items/" + itemA.getID())) .content("/api/core/items/" + itemA.getID()))
.andExpect(status().isForbidden()); .andExpect(status().isForbidden());
configurationService.setProperty("versioning.block.entity", "");
} }
@Test @Test
@@ -762,8 +766,6 @@ public class VersionRestRepositoryIT extends AbstractControllerIntegrationTest {
} finally { } finally {
VersionBuilder.delete(idRef.get()); VersionBuilder.delete(idRef.get());
} }
configurationService.setProperty("versioning.block.entity", "");
} }
@Test @Test
@@ -809,8 +811,6 @@ public class VersionRestRepositoryIT extends AbstractControllerIntegrationTest {
} finally { } finally {
VersionBuilder.delete(idRef.get()); VersionBuilder.delete(idRef.get());
} }
configurationService.setProperty("versioning.submitterCanCreateNewVersion", false);
configurationService.setProperty("versioning.block.entity", "");
} }
@Test @Test
@@ -1434,4 +1434,58 @@ public class VersionRestRepositoryIT extends AbstractControllerIntegrationTest {
Matchers.is(AuthorizationMatcher.matchAuthorization(admin2ItemA)))); Matchers.is(AuthorizationMatcher.matchAuthorization(admin2ItemA))));
} }
@Test
public void createFirstVersionItemWithBitstreamBySubmitterTest() throws Exception {
configurationService.setProperty("versioning.submitterCanCreateNewVersion", true);
context.turnOffAuthorisationSystem();
Community rootCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community")
.build();
Collection col = CollectionBuilder.createCollection(context, rootCommunity)
.withName("Collection 1")
.withSubmitterGroup(eperson)
.build();
Item itemA = ItemBuilder.createItem(context, col)
.withTitle("Public item")
.withIssueDate("2021-04-19")
.withAuthor("Doe, John")
.withSubject("ExtraEntry")
.build();
itemA.setSubmitter(eperson);
Bundle bundle = BundleBuilder.createBundle(context, itemA).withName("Bundle 0").build();
String bitstreamContent = "ThisIsSomeDummyText";
try (InputStream is = IOUtils.toInputStream(bitstreamContent, StandardCharsets.UTF_8)) {
BitstreamBuilder.createBitstream(context, bundle, is)
.withName("Bitstream0")
.withMimeType("text/plain")
.build();
}
context.restoreAuthSystemState();
AtomicReference<Integer> idRef = new AtomicReference<Integer>();
String epersonToken = getAuthToken(eperson.getEmail(), password);
try {
getClient(epersonToken).perform(post("/api/versioning/versions")
.param("summary", "test summary!")
.contentType(MediaType.parseMediaType(RestMediaTypes.TEXT_URI_LIST_VALUE))
.content("/api/core/items/" + itemA.getID()))
.andExpect(status().isCreated())
.andExpect(jsonPath("$", Matchers.allOf(
hasJsonPath("$.version", is(2)),
hasJsonPath("$.summary", is("test summary!")),
hasJsonPath("$.type", is("version"))
)))
.andDo(result -> idRef.set(read(result.getResponse().getContentAsString(), "$.id")));
} finally {
VersionBuilder.delete(idRef.get());
}
}
} }

View File

@@ -144,8 +144,6 @@ public class CanCreateVersionFeatureIT extends AbstractControllerIntegrationTest
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(jsonPath("$.page.totalElements", greaterThan(0))) .andExpect(jsonPath("$.page.totalElements", greaterThan(0)))
.andExpect(jsonPath("$._embedded").exists()); .andExpect(jsonPath("$._embedded").exists());
configurationService.setProperty("versioning.submitterCanCreateNewVersion", false);
} }
@Test @Test
@@ -214,8 +212,6 @@ public class CanCreateVersionFeatureIT extends AbstractControllerIntegrationTest
getClient(tokenUser).perform(get("/api/authz/authorizations/" + user2ItemB.getID())) getClient(tokenUser).perform(get("/api/authz/authorizations/" + user2ItemB.getID()))
.andExpect(status().isNotFound()); .andExpect(status().isNotFound());
configurationService.setProperty("versioning.submitterCanCreateNewVersion", false);
} }
@Test @Test
@@ -351,8 +347,6 @@ public class CanCreateVersionFeatureIT extends AbstractControllerIntegrationTest
getClient(tokenEPerson).perform(get("/api/authz/authorizations/" + eperson2ItemA.getID())) getClient(tokenEPerson).perform(get("/api/authz/authorizations/" + eperson2ItemA.getID()))
.andExpect(status().isNotFound()); .andExpect(status().isNotFound());
configurationService.setProperty("versioning.block.entity", "");
} }
@Test @Test
@@ -400,8 +394,6 @@ public class CanCreateVersionFeatureIT extends AbstractControllerIntegrationTest
getClient(tokenEPerson).perform(get("/api/authz/authorizations/" + eperson2ItemA.getID())) getClient(tokenEPerson).perform(get("/api/authz/authorizations/" + eperson2ItemA.getID()))
.andExpect(status().isNotFound()); .andExpect(status().isNotFound());
configurationService.setProperty("versioning.block.entity", "");
} }
@Test @Test
@@ -449,9 +441,6 @@ public class CanCreateVersionFeatureIT extends AbstractControllerIntegrationTest
getClient(tokenEPerson).perform(get("/api/authz/authorizations/" + eperson2ItemA.getID())) getClient(tokenEPerson).perform(get("/api/authz/authorizations/" + eperson2ItemA.getID()))
.andExpect(status().isNotFound()); .andExpect(status().isNotFound());
configurationService.setProperty("versioning.block.entity", "");
configurationService.setProperty("versioning.submitterCanCreateNewVersion", true);
} }
} }

View File

@@ -304,8 +304,6 @@ public class CanDeleteVersionFeatureIT extends AbstractControllerIntegrationTest
getClient().perform(get("/api/authz/authorizations/" + anonymous2ItemA.getID())) getClient().perform(get("/api/authz/authorizations/" + anonymous2ItemA.getID()))
.andExpect(status().isNotFound()); .andExpect(status().isNotFound());
configurationService.setProperty("versioning.block.entity", "");
} }
@Test @Test
@@ -356,8 +354,6 @@ public class CanDeleteVersionFeatureIT extends AbstractControllerIntegrationTest
getClient().perform(get("/api/authz/authorizations/" + anonymous2ItemA.getID())) getClient().perform(get("/api/authz/authorizations/" + anonymous2ItemA.getID()))
.andExpect(status().isNotFound()); .andExpect(status().isNotFound());
configurationService.setProperty("versioning.block.entity", "");
} }
} }

View File

@@ -261,8 +261,6 @@ public class CanEditVersionFeatureIT extends AbstractControllerIntegrationTest {
getClient(tokenAdmin).perform(get("/api/authz/authorizations/" + adminToVersion.getID())) getClient(tokenAdmin).perform(get("/api/authz/authorizations/" + adminToVersion.getID()))
.andExpect(status().isNotFound()); .andExpect(status().isNotFound());
configurationService.setProperty("versioning.block.entity", "");
} }
@Test @Test
@@ -343,8 +341,6 @@ public class CanEditVersionFeatureIT extends AbstractControllerIntegrationTest {
getClient().perform(get("/api/authz/authorizations/" + anonymousToVersion.getID())) getClient().perform(get("/api/authz/authorizations/" + anonymousToVersion.getID()))
.andExpect(status().isNotFound()); .andExpect(status().isNotFound());
configurationService.setProperty("versioning.block.entity", "");
} }
} }

View File

@@ -290,8 +290,6 @@ public class CanManageVersionsFeatureIT extends AbstractControllerIntegrationTes
getClient(tokenAdminCol2).perform(get("/api/authz/authorizations/" + adminOfCol2ToItemA.getID())) getClient(tokenAdminCol2).perform(get("/api/authz/authorizations/" + adminOfCol2ToItemA.getID()))
.andExpect(status().isNotFound()); .andExpect(status().isNotFound());
configurationService.setProperty("versioning.block.entity", "");
} }
@Test @Test
@@ -383,8 +381,6 @@ public class CanManageVersionsFeatureIT extends AbstractControllerIntegrationTes
getClient(tokenAdminCol2).perform(get("/api/authz/authorizations/" + adminOfCol2ToItemA.getID())) getClient(tokenAdminCol2).perform(get("/api/authz/authorizations/" + adminOfCol2ToItemA.getID()))
.andExpect(status().isNotFound()); .andExpect(status().isNotFound());
configurationService.setProperty("versioning.block.entity", "");
} }
} }

View File

@@ -16,3 +16,7 @@ versioning.item.history.include.submitter=false
# If you want to allow submitters to create new versions of there items, set # If you want to allow submitters to create new versions of there items, set
# the property submitterCanCreateNewVersion true. # the property submitterCanCreateNewVersion true.
# versioning.submitterCanCreateNewVersion=false # versioning.submitterCanCreateNewVersion=false
# The property versioning.block.entity is used to disable versioning
# for items with EntityType, the default value is true if it unset.
# versioning.block.entity=