Merge pull request #2680 from atmire/w2p-68732_list-version-history

Read only versioning endpoints
This commit is contained in:
Tim Donohue
2020-03-20 10:37:20 -05:00
committed by GitHub
26 changed files with 1690 additions and 0 deletions

View File

@@ -0,0 +1,78 @@
/**
* 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.converter;
import java.sql.SQLException;
import org.apache.log4j.Logger;
import org.dspace.app.rest.model.VersionRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.app.rest.utils.ContextUtil;
import org.dspace.authorize.service.AuthorizeService;
import org.dspace.core.Context;
import org.dspace.eperson.EPerson;
import org.dspace.services.ConfigurationService;
import org.dspace.services.RequestService;
import org.dspace.services.model.Request;
import org.dspace.versioning.Version;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* This is the converter that takes care of the conversion between {@link Version} and {@link VersionRest}
*/
@Component
public class VersionConverter implements DSpaceConverter<Version, VersionRest> {
private static final Logger log = Logger.getLogger(VersionConverter.class);
@Autowired
private AuthorizeService authorizeService;
@Autowired
private ConfigurationService configurationService;
@Autowired
private RequestService requestService;
@Override
public VersionRest convert(Version modelObject, Projection projection) {
VersionRest versionRest = new VersionRest();
versionRest.setCreated(modelObject.getVersionDate());
versionRest.setId(modelObject.getID());
versionRest.setSummary(modelObject.getSummary());
setSubmitterName(modelObject, versionRest);
versionRest.setVersion(modelObject.getVersionNumber());
versionRest.setProjection(projection);
return versionRest;
}
private void setSubmitterName(Version modelObject, VersionRest versionRest) {
Context context = null;
Request currentRequest = requestService.getCurrentRequest();
if (currentRequest != null) {
context = ContextUtil.obtainContext(currentRequest.getHttpServletRequest());
}
try {
if ((context != null && authorizeService.isAdmin(context)) || configurationService
.getBooleanProperty("versioning.item.history.include.submitter")) {
EPerson submitter = modelObject.getEPerson();
if (submitter != null) {
versionRest.setSubmitterName(submitter.getFullName());
}
}
} catch (SQLException e) {
log.error(e.getMessage(), e);
}
}
@Override
public Class<Version> getModelClass() {
return Version.class;
}
}

View File

@@ -0,0 +1,32 @@
/**
* 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.converter;
import org.dspace.app.rest.model.VersionHistoryRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.versioning.VersionHistory;
import org.springframework.stereotype.Component;
/**
* This is the Converter that takes care of the conversion between {@link VersionHistory} and {@link VersionHistoryRest}
*/
@Component
public class VersionHistoryConverter implements DSpaceConverter<VersionHistory, VersionHistoryRest> {
@Override
public VersionHistoryRest convert(VersionHistory modelObject, Projection projection) {
VersionHistoryRest versionHistoryRest = new VersionHistoryRest();
versionHistoryRest.setId(modelObject.getID());
return versionHistoryRest;
}
@Override
public Class<VersionHistory> getModelClass() {
return VersionHistory.class;
}
}

View File

@@ -33,6 +33,10 @@ import com.fasterxml.jackson.annotation.JsonProperty;
name = ItemRest.RELATIONSHIPS,
method = "getRelationships"
),
@LinkRest(
name = ItemRest.VERSION,
method = "getItemVersion"
),
@LinkRest(
name = ItemRest.TEMPLATE_ITEM_OF,
method = "getTemplateItemOf"
@@ -47,6 +51,7 @@ public class ItemRest extends DSpaceObjectRest {
public static final String MAPPED_COLLECTIONS = "mappedCollections";
public static final String OWNING_COLLECTION = "owningCollection";
public static final String RELATIONSHIPS = "relationships";
public static final String VERSION = "version";
public static final String TEMPLATE_ITEM_OF = "templateItemOf";
private boolean inArchive = false;

View File

@@ -31,6 +31,7 @@ public interface RestModel extends Serializable {
public static final String SYSTEM = "system";
public static final String WORKFLOW = "workflow";
public static final String AUTHORIZATION = "authz";
public static final String VERSIONING = "versioning";
public String getType();

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.model;
import org.dspace.app.rest.RestResourceController;
/**
* The REST object for the {@link org.dspace.versioning.VersionHistory} object
*/
@LinksRest(links = {
@LinkRest(
name = VersionHistoryRest.VERSIONS,
method = "getVersions"
)
})
public class VersionHistoryRest extends BaseObjectRest<Integer> {
private Integer id;
public static final String NAME = "versionhistory";
public static final String CATEGORY = RestAddressableModel.VERSIONING;
public static final String VERSIONS = "versions";
@Override
public String getCategory() {
return CATEGORY;
}
@Override
public Class getController() {
return RestResourceController.class;
}
@Override
public String getType() {
return NAME;
}
/**
* Generic getter for the id
* @return the id value of this VersionHistoryRest
*/
@Override
public Integer getId() {
return id;
}
/**
* Generic setter for the id
* @param id The id to be set on this VersionHistoryRest
*/
@Override
public void setId(Integer id) {
this.id = id;
}
}

View File

@@ -0,0 +1,140 @@
/**
* 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.model;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonInclude;
import org.dspace.app.rest.RestResourceController;
/**
* The REST object for the {@link org.dspace.versioning.Version} objects
*/
@LinksRest(links = {
@LinkRest(
name = VersionRest.VERSION_HISTORY,
method = "getVersionHistory"
),
@LinkRest(
name = VersionRest.ITEM,
method = "getVersionItem"
)
})
public class VersionRest extends BaseObjectRest<Integer> {
public static final String NAME = "version";
public static final String CATEGORY = RestAddressableModel.VERSIONING;
public static final String VERSION_HISTORY = "versionhistory";
public static final String ITEM = "item";
private Integer id;
private Integer version;
private Date created;
private String summary;
@JsonInclude(JsonInclude.Include.NON_NULL)
private String submitterName;
/**
* Generic getter for the id
* @return the id value of this VersionRest
*/
@Override
public Integer getId() {
return id;
}
/**
* Generic setter for the id
* @param id The id to be set on this VersionRest
*/
@Override
public void setId(Integer id) {
this.id = id;
}
/**
* Generic getter for the version
* @return the version value of this VersionRest
*/
public Integer getVersion() {
return version;
}
/**
* Generic setter for the version
* @param version The version to be set on this VersionRest
*/
public void setVersion(Integer version) {
this.version = version;
}
/**
* Generic getter for the created
* @return the created value of this VersionRest
*/
public Date getCreated() {
return created;
}
/**
* Generic setter for the created
* @param created The created to be set on this VersionRest
*/
public void setCreated(Date created) {
this.created = created;
}
/**
* Generic getter for the summary
* @return the summary value of this VersionRest
*/
public String getSummary() {
return summary;
}
/**
* Generic setter for the summary
* @param summary The summary to be set on this VersionRest
*/
public void setSummary(String summary) {
this.summary = summary;
}
/**
* Generic getter for the submitterName
* @return the submitterName value of this VersionRest
*/
public String getSubmitterName() {
return submitterName;
}
/**
* Generic setter for the submitterName
* @param submitterName The submitterName to be set on this VersionRest
*/
public void setSubmitterName(String submitterName) {
this.submitterName = submitterName;
}
@Override
public String getCategory() {
return CATEGORY;
}
@Override
public Class getController() {
return RestResourceController.class;
}
@Override
public String getType() {
return NAME;
}
}

View File

@@ -0,0 +1,23 @@
/**
* 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.model.hateoas;
import org.dspace.app.rest.model.VersionHistoryRest;
import org.dspace.app.rest.model.hateoas.annotations.RelNameDSpaceResource;
import org.dspace.app.rest.utils.Utils;
/**
* The HALResource object for the {@link VersionHistoryRest} object
*/
@RelNameDSpaceResource(VersionHistoryRest.NAME)
public class VersionHistoryResource extends DSpaceResource<VersionHistoryRest> {
public VersionHistoryResource(VersionHistoryRest data, Utils utils) {
super(data, utils);
}
}

View File

@@ -0,0 +1,24 @@
/**
* 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.model.hateoas;
import org.dspace.app.rest.model.VersionRest;
import org.dspace.app.rest.model.hateoas.annotations.RelNameDSpaceResource;
import org.dspace.app.rest.utils.Utils;
/**
* The HALResource object for the {@link VersionRest} object
*/
@RelNameDSpaceResource(VersionRest.NAME)
public class VersionResource extends DSpaceResource<VersionRest> {
public VersionResource(VersionRest data, Utils utils) {
super(data, utils);
}
}

View File

@@ -0,0 +1,68 @@
/**
* 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.ItemRest;
import org.dspace.app.rest.model.VersionRest;
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.dspace.versioning.Version;
import org.dspace.versioning.service.VersioningService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.stereotype.Component;
/**
* This is the Repository that will take care of fetching the Version for a given Item
*/
@Component(ItemRest.CATEGORY + "." + ItemRest.NAME + "." + ItemRest.VERSION)
public class ItemVersionLinkRepository extends AbstractDSpaceRestRepository
implements LinkRestRepository {
@Autowired
private VersioningService versioningService;
@Autowired
private ItemService itemService;
/**
* This method will return the VersionRest object from the Item that is associated with the given itemUuid
* @param request The current request
* @param itemUuid The itemUuid used to find the Item for which we'll return the VersionRest object
* @param optionalPageable Pageable if present
* @param projection Current Projection
* @return The VersionRest object constructed from the Version object for the Item that has the
* itemUuid param as UUID
* @throws SQLException If something goes wrong
*/
public VersionRest getItemVersion(@Nullable HttpServletRequest request,
UUID itemUuid,
@Nullable Pageable optionalPageable,
Projection projection) throws SQLException {
Context context = obtainContext();
Item item = itemService.find(context, itemUuid);
if (item == null) {
throw new ResourceNotFoundException("The Item for uuid: " + itemUuid + " couldn't be found");
}
Version version = versioningService.getVersion(context, item);
if (version == null) {
return null;
}
return converter.toRest(version, projection);
}
}

View File

@@ -0,0 +1,64 @@
/**
* 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.VersionHistoryRest;
import org.dspace.app.rest.model.VersionRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.core.Context;
import org.dspace.versioning.Version;
import org.dspace.versioning.VersionHistory;
import org.dspace.versioning.service.VersioningService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.stereotype.Component;
/**
* This is the Repository that takes care of the retrieval of the {@link VersionHistory} object
* for a given {@link Version}
*/
@Component(VersionRest.CATEGORY + "." + VersionRest.NAME + "." + VersionRest.VERSION_HISTORY)
public class VersionHistoryLinkRepository extends AbstractDSpaceRestRepository
implements LinkRestRepository {
@Autowired
private VersioningService versioningService;
/**
* This method will retrieve the VersionHistoryRest object from the Version that is found by the associated
* versionId parameter
* @param request The current request
* @param versionId The ID for the Version object
* @param optionalPageable The pageable if present
* @param projection The current Projection
* @return The VersionHistoryRest object that is constructed from the VersionHistory object that
* is linked to the Version found by the versionId parameter
* @throws SQLException If something goes wrong
*/
public VersionHistoryRest getVersionHistory(@Nullable HttpServletRequest request,
Integer versionId,
@Nullable Pageable optionalPageable,
Projection projection) throws SQLException {
Context context = obtainContext();
Version version = versioningService.getVersion(context, versionId);
if (version == null) {
throw new ResourceNotFoundException("The version with ID: " + versionId + " couldn't be found");
}
VersionHistory versionHistory = version.getVersionHistory();
if (versionHistory == null) {
return null;
}
return converter.toRest(versionHistory, projection);
}
}

View File

@@ -0,0 +1,64 @@
/**
* 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 org.apache.logging.log4j.Logger;
import org.dspace.app.rest.converter.ConverterService;
import org.dspace.app.rest.exception.RepositoryMethodNotImplementedException;
import org.dspace.app.rest.model.VersionHistoryRest;
import org.dspace.core.Context;
import org.dspace.versioning.VersionHistory;
import org.dspace.versioning.service.VersionHistoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
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;
/**
* Repository for the operations on the {@link VersionHistoryRest} endpoints
*/
@Component(VersionHistoryRest.CATEGORY + "." + VersionHistoryRest.NAME)
public class VersionHistoryRestRepository extends DSpaceRestRepository<VersionHistoryRest, Integer> {
private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(VersionHistoryRestRepository.class);
@Autowired
private VersionHistoryService versionHistoryService;
@Autowired
private ConverterService converterService;
@Override
@PreAuthorize("hasPermission(#id, 'VERSIONHISTORY', 'READ')")
public VersionHistoryRest findOne(Context context, Integer id) {
try {
VersionHistory versionHistory = versionHistoryService.find(context, id);
if (versionHistory == null) {
throw new ResourceNotFoundException("Couldn't find version for id: " + id);
}
return converterService.toRest(versionHistory, utils.obtainProjection());
} catch (SQLException e) {
log.error("Something with wrong getting version with id:" + id, e);
throw new RuntimeException(e.getMessage(), e);
}
}
@Override
public Page<VersionHistoryRest> findAll(Context context, Pageable pageable) {
throw new RepositoryMethodNotImplementedException("No implementation found; Method not allowed!", "");
}
@Override
public Class<VersionHistoryRest> getDomainClass() {
return VersionHistoryRest.class;
}
}

View File

@@ -0,0 +1,64 @@
/**
* 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.ItemRest;
import org.dspace.app.rest.model.VersionRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.content.Item;
import org.dspace.core.Context;
import org.dspace.versioning.Version;
import org.dspace.versioning.service.VersioningService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.stereotype.Component;
/**
* This Repository takes care of the retrieval of the {@link org.dspace.content.Item} objects
* for a given {@link Version}
*/
@Component(VersionRest.CATEGORY + "." + VersionRest.NAME + "." + VersionRest.ITEM)
public class VersionItemLinkRepository extends AbstractDSpaceRestRepository
implements LinkRestRepository {
@Autowired
private VersioningService versioningService;
/**
* This method will return the ItemRest object constructed from the Item object which is found in the Version
* that will be found through the versionId parameter
* @param request The current request
* @param versionId The ID for the Version to be used
* @param optionalPageable The pageable if present
* @param projection The current Projection
* @return The ItemRest object that is relevant for the Version
* @throws SQLException If something goes wrong
*/
public ItemRest getVersionItem(@Nullable HttpServletRequest request,
Integer versionId,
@Nullable Pageable optionalPageable,
Projection projection) throws SQLException {
Context context = obtainContext();
Version version = versioningService.getVersion(context, versionId);
if (version == null) {
throw new ResourceNotFoundException("The version with ID: " + versionId + " couldn't be found");
}
Item item = version.getItem();
if (item == null) {
return null;
}
return converter.toRest(item, projection);
}
}

View File

@@ -0,0 +1,64 @@
/**
* 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 org.apache.logging.log4j.Logger;
import org.dspace.app.rest.converter.ConverterService;
import org.dspace.app.rest.exception.RepositoryMethodNotImplementedException;
import org.dspace.app.rest.model.VersionRest;
import org.dspace.core.Context;
import org.dspace.versioning.Version;
import org.dspace.versioning.service.VersioningService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
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;
/**
* This is the Repository that takes care of the operations on the {@link VersionRest} objects
*/
@Component(VersionRest.CATEGORY + "." + VersionRest.NAME)
public class VersionRestRepository extends DSpaceRestRepository<VersionRest, Integer> {
private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(VersionRestRepository.class);
@Autowired
private VersioningService versioningService;
@Autowired
private ConverterService converterService;
@Override
@PreAuthorize("hasPermission(#id, 'VERSION', 'READ')")
public VersionRest findOne(Context context, Integer id) {
try {
Version version = versioningService.getVersion(context, id);
if (version == null) {
throw new ResourceNotFoundException("Couldn't find version for id: " + id);
}
return converterService.toRest(version, utils.obtainProjection());
} catch (SQLException e) {
log.error("Something with wrong getting version with id:" + id, e);
throw new RuntimeException(e.getMessage(), e);
}
}
@Override
public Page<VersionRest> findAll(Context context, Pageable pageable) {
throw new RepositoryMethodNotImplementedException("No implementation found; Method not allowed!", "");
}
@Override
public Class<VersionRest> getDomainClass() {
return VersionRest.class;
}
}

View File

@@ -0,0 +1,69 @@
/**
* 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.List;
import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import org.dspace.app.rest.model.VersionHistoryRest;
import org.dspace.app.rest.model.VersionRest;
import org.dspace.app.rest.projection.Projection;
import org.dspace.core.Context;
import org.dspace.versioning.Version;
import org.dspace.versioning.VersionHistory;
import org.dspace.versioning.service.VersionHistoryService;
import org.dspace.versioning.service.VersioningService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.stereotype.Component;
/**
* This is the Repository that takes care of the retrieval of the {@link Version} objects for a given
* {@link VersionHistory}
*/
@Component(VersionHistoryRest.CATEGORY + "." + VersionHistoryRest.NAME + "." + VersionHistoryRest.VERSIONS)
public class VersionsLinkRepository extends AbstractDSpaceRestRepository
implements LinkRestRepository {
@Autowired
private VersionHistoryService versionHistoryService;
@Autowired
private VersioningService versioningService;
/**
* This method will return a page of VersionRest objects found through the VersionHistory object that is resolved
* from the versionHistoryId parameter
* @param request The current request
* @param versionHistoryId The ID for the VersionHistory to be used
* @param optionalPageable The pageable if present
* @param projection The current Projection
* @return The page containing relevant VersionRest objects
* @throws SQLException If something goes wrong
*/
public Page<VersionRest> getVersions(@Nullable HttpServletRequest request,
Integer versionHistoryId,
@Nullable Pageable optionalPageable,
Projection projection) throws SQLException {
Context context = obtainContext();
VersionHistory versionHistory = versionHistoryService.find(context, versionHistoryId);
if (versionHistory == null) {
throw new ResourceNotFoundException("The versionHistory with ID: " + versionHistoryId +
" couldn't be found");
}
List<Version> versions = versioningService.getVersionsByHistory(context, versionHistory);
Pageable pageable = optionalPageable != null ? optionalPageable : new PageRequest(0, 20);
return converter.toRestPage(utils.getPage(versions, pageable), projection);
}
}

View File

@@ -34,9 +34,12 @@ import org.dspace.app.util.SubmissionConfigReader;
import org.dspace.app.util.SubmissionConfigReaderException;
import org.dspace.app.util.SubmissionStepConfig;
import org.dspace.authorize.AuthorizeException;
import org.dspace.authorize.service.AuthorizeService;
import org.dspace.content.Item;
import org.dspace.content.service.BitstreamFormatService;
import org.dspace.content.service.BitstreamService;
import org.dspace.content.service.ItemService;
import org.dspace.core.Constants;
import org.dspace.core.Context;
import org.dspace.eperson.EPerson;
import org.dspace.eperson.EPersonServiceImpl;
@@ -56,6 +59,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
@@ -97,6 +101,9 @@ public class WorkflowItemRestRepository extends DSpaceRestRepository<WorkflowIte
@Autowired
WorkflowService<XmlWorkflowItem> wfs;
@Autowired
AuthorizeService authorizeService;
@Autowired
ClaimedTaskService claimedTaskService;
@@ -354,4 +361,33 @@ public class WorkflowItemRestRepository extends DSpaceRestRepository<WorkflowIte
+ "#checkIfEditMetadataAllowedInCurrentStep trying to retrieve workflow configuration from config", e);
}
}
/**
* This is a search method that will return the WorkflowItemRest object found through the UUID of an item. It'll
* find the Item through the given UUID and try to resolve the WorkflowItem relevant for that item and return it.
* It'll return a 401/403 if the current user isn't allowed to view the WorkflowItem.
* It'll return a 204 if nothing was found
* @param itemUuid The UUID for the Item to be used
* @param pageable The pageable if present
* @return The resulting WorkflowItemRest object
*/
@SearchRestMethod(name = "item")
public WorkflowItemRest findByItemUuid(@Parameter(value = "uuid", required = true) UUID itemUuid,
Pageable pageable) {
try {
Context context = obtainContext();
Item item = itemService.find(context, itemUuid);
XmlWorkflowItem xmlWorkflowItem = wis.findByItem(context, item);
if (xmlWorkflowItem == null) {
return null;
}
if (!authorizeService.authorizeActionBoolean(context, xmlWorkflowItem.getItem(), Constants.READ)) {
throw new AccessDeniedException("The current user does not have rights to view the WorkflowItem");
}
return converter.toRest(xmlWorkflowItem, utils.obtainProjection());
} catch (SQLException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
}

View File

@@ -41,7 +41,9 @@ import org.dspace.app.util.SubmissionConfigReader;
import org.dspace.app.util.SubmissionConfigReaderException;
import org.dspace.app.util.SubmissionStepConfig;
import org.dspace.authorize.AuthorizeException;
import org.dspace.authorize.service.AuthorizeService;
import org.dspace.content.Collection;
import org.dspace.content.Item;
import org.dspace.content.WorkspaceItem;
import org.dspace.content.service.BitstreamFormatService;
import org.dspace.content.service.BitstreamService;
@@ -65,6 +67,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.rest.webmvc.json.patch.PatchException;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
@@ -111,6 +114,9 @@ public class WorkspaceItemRestRepository extends DSpaceRestRepository<WorkspaceI
@Autowired
CollectionService collectionService;
@Autowired
AuthorizeService authorizeService;
@Autowired
private UriListHandlerService uriListHandlerService;
@@ -497,5 +503,32 @@ public class WorkspaceItemRestRepository extends DSpaceRestRepository<WorkspaceI
return converter.toRest(workspaceItem, utils.obtainProjection());
}
/**
* This is a search method that will return the WorkspaceItemRest object found through the UUID of an item. It'll
* find the Item through the given UUID and try to resolve the WorkspaceItem relevant for that item and return it.
* It'll return a 401/403 if the current user isn't allowed to view the WorkspaceItem.
* It'll return a 204 if nothing was found
* @param itemUuid The UUID for the Item to be used
* @param pageable The pageable if present
* @return The resulting WorkspaceItem object
*/
@SearchRestMethod(name = "item")
public WorkspaceItemRest findByItemUuid(@Parameter(value = "uuid", required = true) UUID itemUuid,
Pageable pageable) {
try {
Context context = obtainContext();
Item item = itemService.find(context, itemUuid);
WorkspaceItem workspaceItem = wis.findByItem(context, item);
if (workspaceItem == null) {
return null;
}
if (!authorizeService.authorizeActionBoolean(context, workspaceItem.getItem(), Constants.READ)) {
throw new AccessDeniedException("The current user does not have rights to view the WorkflowItem");
}
return converter.toRest(workspaceItem, utils.obtainProjection());
} catch (SQLException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
}

View File

@@ -0,0 +1,69 @@
/**
* 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.security;
import java.io.Serializable;
import java.sql.SQLException;
import org.apache.commons.lang3.StringUtils;
import org.dspace.app.rest.model.VersionHistoryRest;
import org.dspace.app.rest.utils.ContextUtil;
import org.dspace.authorize.service.AuthorizeService;
import org.dspace.core.Context;
import org.dspace.services.ConfigurationService;
import org.dspace.services.RequestService;
import org.dspace.services.model.Request;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
/**
* This class acts as a PermissionEvaluator to decide whether a given request to a Versioning endpoint is allowed to
* pass through or not
*/
@Component
public class VersionHistoryRestPermissionEvaluatorPlugin extends RestObjectPermissionEvaluatorPlugin {
private static final Logger log = LoggerFactory.getLogger(VersionHistoryRestPermissionEvaluatorPlugin.class);
@Autowired
private RequestService requestService;
@Autowired
private AuthorizeService authorizeService;
@Autowired
private ConfigurationService configurationService;
@Override
public boolean hasDSpacePermission(Authentication authentication, Serializable targetId, String targetType,
DSpaceRestPermission restPermission) {
if (!StringUtils.equalsIgnoreCase(targetType, VersionHistoryRest.NAME)) {
return false;
}
Request request = requestService.getCurrentRequest();
Context context = ContextUtil.obtainContext(request.getServletRequest());
try {
if (configurationService.getBooleanProperty("versioning.item.history.view.admin")
&& !authorizeService.isAdmin(context)) {
return false;
}
return true;
} catch (SQLException e) {
log.error(e.getMessage(), e);
}
return false;
}
}

View File

@@ -0,0 +1,83 @@
/**
* 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.security;
import java.io.Serializable;
import java.sql.SQLException;
import org.apache.commons.lang3.StringUtils;
import org.dspace.app.rest.model.VersionRest;
import org.dspace.app.rest.utils.ContextUtil;
import org.dspace.authorize.service.AuthorizeService;
import org.dspace.core.Context;
import org.dspace.services.ConfigurationService;
import org.dspace.services.RequestService;
import org.dspace.services.model.Request;
import org.dspace.versioning.Version;
import org.dspace.versioning.service.VersioningService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
/**
* This class acts as a PermissionEvaluator to decide whether a given request to a Versioning endpoint is allowed to
* pass through or not
*/
@Component
public class VersionRestPermissionEvaluatorPlugin extends RestObjectPermissionEvaluatorPlugin {
private static final Logger log = LoggerFactory.getLogger(VersionRestPermissionEvaluatorPlugin.class);
@Autowired
private RequestService requestService;
@Autowired
private AuthorizeService authorizeService;
@Autowired
private VersioningService versioningService;
@Autowired
private ConfigurationService configurationService;
@Override
public boolean hasDSpacePermission(Authentication authentication, Serializable targetId, String targetType,
DSpaceRestPermission restPermission) {
if (!StringUtils.equalsIgnoreCase(targetType, VersionRest.NAME)) {
return false;
}
Request request = requestService.getCurrentRequest();
Context context = ContextUtil.obtainContext(request.getServletRequest());
try {
int versionId = Integer.parseInt(targetId.toString());
if (configurationService.getBooleanProperty("versioning.item.history.view.admin")
&& !authorizeService.isAdmin(context)) {
return false;
}
Version version = versioningService.getVersion(context, versionId);
if (version == null) {
return true;
}
if (authorizeService.authorizeActionBoolean(context, version.getItem(),
restPermission.getDspaceApiActionId())) {
return true;
}
} catch (SQLException e) {
log.error(e.getMessage(), e);
}
return false;
}
}

View File

@@ -55,6 +55,7 @@ import org.dspace.app.rest.model.ProcessRest;
import org.dspace.app.rest.model.ResourcePolicyRest;
import org.dspace.app.rest.model.RestAddressableModel;
import org.dspace.app.rest.model.RestModel;
import org.dspace.app.rest.model.VersionHistoryRest;
import org.dspace.app.rest.model.hateoas.DSpaceResource;
import org.dspace.app.rest.model.hateoas.EmbeddedPage;
import org.dspace.app.rest.model.hateoas.HALResource;
@@ -196,6 +197,9 @@ public class Utils {
if (StringUtils.equals(modelPlural, "processes")) {
return ProcessRest.NAME;
}
if (StringUtils.equals(modelPlural, "versionhistories")) {
return VersionHistoryRest.NAME;
}
return modelPlural.replaceAll("s$", "");
}

View File

@@ -0,0 +1,162 @@
/**
* 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;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.sql.SQLException;
import java.util.Date;
import org.dspace.app.rest.builder.CollectionBuilder;
import org.dspace.app.rest.builder.CommunityBuilder;
import org.dspace.app.rest.builder.ItemBuilder;
import org.dspace.app.rest.matcher.VersionHistoryMatcher;
import org.dspace.app.rest.matcher.VersionMatcher;
import org.dspace.app.rest.test.AbstractControllerIntegrationTest;
import org.dspace.authorize.AuthorizeException;
import org.dspace.content.Collection;
import org.dspace.content.Community;
import org.dspace.content.Item;
import org.dspace.services.ConfigurationService;
import org.dspace.versioning.Version;
import org.dspace.versioning.VersionHistory;
import org.dspace.versioning.service.VersionHistoryService;
import org.dspace.versioning.service.VersioningService;
import org.hamcrest.Matchers;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
public class VersionHistoryRestRepositoryIT extends AbstractControllerIntegrationTest {
VersionHistory versionHistory;
Item item;
Version version;
@Autowired
private ConfigurationService configurationService;
@Autowired
private VersionHistoryService versionHistoryService;
@Autowired
private VersioningService versioningService;
@Before
public void setup() throws SQLException, AuthorizeException {
context.turnOffAuthorisationSystem();
versionHistory = versionHistoryService.create(context);
//** 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();
Collection col2 = CollectionBuilder.createCollection(context, child1).withName("Collection 2").build();
//2. Three public items that are readable by Anonymous with different subjects
item = ItemBuilder.createItem(context, col1)
.withTitle("Public item 1")
.withIssueDate("2017-10-17")
.withAuthor("Smith, Donald").withAuthor("Doe, John")
.withSubject("ExtraEntry")
.build();
version = versioningService.createNewVersion(context, versionHistory, item, "test", new Date(), 0);
context.restoreAuthSystemState();
}
@Test
public void findOneTest() throws Exception {
getClient().perform(get("/api/versioning/versionhistories/" + versionHistory.getID()))
.andExpect(status().isOk())
.andExpect(jsonPath("$", is(VersionHistoryMatcher.matchEntry(versionHistory))));
}
@Test
public void findOneForbiddenTest() throws Exception {
configurationService.setProperty("versioning.item.history.view.admin", true);
String token = getAuthToken(eperson.getEmail(), password);
getClient(token).perform(get("/api/versioning/versionhistories/" + versionHistory.getID()))
.andExpect(status().isForbidden());
configurationService.setProperty("versioning.item.history.view.admin", false);
}
@Test
public void findOneWrongIDTest() throws Exception {
int wrongVersionHistoryId = (versionHistory.getID() + 5) * 57;
getClient().perform(get("/api/versioning/versionhistories/" + wrongVersionHistoryId))
.andExpect(status().isNotFound());
}
@Test
public void findVersionsOneWrongIDTest() throws Exception {
int wrongVersionHistoryId = (versionHistory.getID() + 5) * 57;
getClient().perform(get("/api/versioning/versionhistories/" + wrongVersionHistoryId + "/versions"))
.andExpect(status().isNotFound());
}
@Test
public void findVersionsOfVersionHistoryTest() throws Exception {
Version version = versionHistoryService.getFirstVersion(context, versionHistory);
getClient().perform(get("/api/versioning/versionhistories/" + versionHistory.getID() + "/versions"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.versions", contains(VersionMatcher.matchEntry(version))));
context.turnOffAuthorisationSystem();
Version secondVersion = versioningService
.createNewVersion(context, versionHistory, item, "test", new Date(), 0);
context.restoreAuthSystemState();
getClient().perform(get("/api/versioning/versionhistories/" + versionHistory.getID() + "/versions"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.versions", containsInAnyOrder(VersionMatcher.matchEntry(version),
VersionMatcher
.matchEntry(secondVersion))));
}
@Test
public void findVersionsOfVersionHistoryPaginationTest() throws Exception {
context.turnOffAuthorisationSystem();
Version version = versionHistoryService.getFirstVersion(context, versionHistory);
Version secondVersion = versioningService
.createNewVersion(context, versionHistory, item, "test", new Date(), 0);
context.restoreAuthSystemState();
getClient().perform(get("/api/versioning/versionhistories/" + versionHistory.getID() + "/versions")
.param("size", "1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.versions", contains(VersionMatcher.matchEntry(secondVersion))))
.andExpect(jsonPath("$._embedded.versions",
Matchers.not(contains(VersionMatcher.matchEntry(version)))));
getClient().perform(get("/api/versioning/versionhistories/" + versionHistory.getID() + "/versions")
.param("size", "1")
.param("page", "1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.versions", contains(VersionMatcher.matchEntry(version))))
.andExpect(jsonPath("$._embedded.versions",
Matchers.not(contains(VersionMatcher.matchEntry(secondVersion)))));
}
}

View File

@@ -0,0 +1,192 @@
/**
* 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;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.dspace.app.rest.builder.CollectionBuilder;
import org.dspace.app.rest.builder.CommunityBuilder;
import org.dspace.app.rest.builder.ItemBuilder;
import org.dspace.app.rest.matcher.ItemMatcher;
import org.dspace.app.rest.matcher.VersionMatcher;
import org.dspace.app.rest.test.AbstractControllerIntegrationTest;
import org.dspace.content.Collection;
import org.dspace.content.Community;
import org.dspace.content.Item;
import org.dspace.content.service.ItemService;
import org.dspace.services.ConfigurationService;
import org.dspace.versioning.Version;
import org.dspace.versioning.service.VersioningService;
import org.hamcrest.Matchers;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
public class VersionRestRepositoryIT extends AbstractControllerIntegrationTest {
Item item;
Version version;
@Autowired
private ItemService itemService;
@Autowired
private VersioningService versioningService;
@Autowired
private ConfigurationService configurationService;
@Before
public void setup() {
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();
Collection col2 = CollectionBuilder.createCollection(context, child1).withName("Collection 2").build();
//2. Three public items that are readable by Anonymous with different subjects
item = ItemBuilder.createItem(context, col1)
.withTitle("Public item 1")
.withIssueDate("2017-10-17")
.withAuthor("Smith, Donald").withAuthor("Doe, John")
.withSubject("ExtraEntry")
.build();
version = versioningService.createNewVersion(context, item);
context.restoreAuthSystemState();
}
@Test
public void findOneTest() throws Exception {
String adminToken = getAuthToken(admin.getEmail(), password);
getClient(adminToken).perform(get("/api/versioning/versions/" + version.getID()))
.andExpect(status().isOk())
.andExpect(jsonPath("$", Matchers.is(VersionMatcher.matchEntry(version))));
}
@Test
public void findOneSubmitterNameVisisbleTest() throws Exception {
String adminToken = getAuthToken(admin.getEmail(), password);
getClient(adminToken).perform(get("/api/versioning/versions/" + version.getID()))
.andExpect(status().isOk())
.andExpect(jsonPath("$", Matchers.is(VersionMatcher.matchEntry(version))))
.andExpect(jsonPath("$.submitterName", Matchers.is(version.getEPerson().getFullName())));
}
@Test
public void findOneSubmitterNameConfigurationPropertyFalseAdminUserLinkVisibleTest() throws Exception {
configurationService.setProperty("versioning.item.history.include.submitter", false);
String adminToken = getAuthToken(admin.getEmail(), password);
getClient(adminToken).perform(get("/api/versioning/versions/" + version.getID()))
.andExpect(status().isOk())
.andExpect(jsonPath("$", Matchers.is(VersionMatcher.matchEntry(version))))
.andExpect(jsonPath("$.submitterName", Matchers.is(version.getEPerson().getFullName())));
configurationService.setProperty("versioning.item.history.include.submitter", true);
}
@Test
public void findOneSubmitterNameConfigurationPropertyTrueNormalUserLinkVisibleTest() throws Exception {
String adminToken = getAuthToken(admin.getEmail(), password);
getClient(adminToken).perform(get("/api/versioning/versions/" + version.getID()))
.andExpect(status().isOk())
.andExpect(jsonPath("$", Matchers.is(VersionMatcher.matchEntry(version))))
.andExpect(jsonPath("$.submitterName", Matchers.is(version.getEPerson().getFullName())));
}
@Test
public void findOneSubmitterNameConfigurationPropertyTrueAnonUserLinkVisibleTest() throws Exception {
String adminToken = getAuthToken(admin.getEmail(), password);
getClient(adminToken).perform(get("/api/versioning/versions/" + version.getID()))
.andExpect(status().isOk())
.andExpect(jsonPath("$", Matchers.is(VersionMatcher.matchEntry(version))))
.andExpect(jsonPath("$.submitterName", Matchers.is(version.getEPerson().getFullName())));
}
@Test
public void findOneSubmitterNameConfigurationPropertyFalseNormalUserLinkInvisibleTest() throws Exception {
configurationService.setProperty("versioning.item.history.include.submitter", false);
String adminToken = getAuthToken(eperson.getEmail(), password);
getClient(adminToken).perform(get("/api/versioning/versions/" + version.getID()))
.andExpect(status().isOk())
.andExpect(jsonPath("$", Matchers.is(VersionMatcher.matchEntry(version))))
.andExpect(jsonPath("$.submitterName").doesNotExist());
configurationService.setProperty("versioning.item.history.include.submitter", true);
}
@Test
public void findOneUnauthorizedTest() throws Exception {
getClient().perform(get("/api/versioning/versions/" + version.getID()))
.andExpect(status().isUnauthorized());
}
@Test
public void findOneForbiddenTest() throws Exception {
configurationService.setProperty("versioning.item.history.view.admin", true);
String token = getAuthToken(eperson.getEmail(), password);
getClient(token).perform(get("/api/versioning/versions/" + version.getID()))
.andExpect(status().isForbidden());
configurationService.setProperty("versioning.item.history.view.admin", false);
}
@Test
public void versionForItemTest() throws Exception {
getClient().perform(get("/api/core/items/" + version.getItem().getID() + "/version"))
.andExpect(status().isOk())
.andExpect(jsonPath("$", Matchers.is(VersionMatcher.matchEntry(version))));
}
@Test
public void versionItemTest() throws Exception {
String adminToken = getAuthToken(admin.getEmail(), password);
getClient(adminToken).perform(get("/api/versioning/versions/" + version.getID() + "/item"))
.andExpect(status().isOk())
.andExpect(jsonPath("$", Matchers.is(ItemMatcher.matchItemProperties(version.getItem()))));
}
@Test
public void versionItemTestWrongId() throws Exception {
String adminToken = getAuthToken(admin.getEmail(), password);
getClient(adminToken).perform(get("/api/versioning/versions/" + ((version.getID() + 5) * 57) + "/item"))
.andExpect(status().isNotFound());
}
}

View File

@@ -33,6 +33,7 @@ import org.dspace.app.rest.builder.ClaimedTaskBuilder;
import org.dspace.app.rest.builder.CollectionBuilder;
import org.dspace.app.rest.builder.CommunityBuilder;
import org.dspace.app.rest.builder.EPersonBuilder;
import org.dspace.app.rest.builder.ItemBuilder;
import org.dspace.app.rest.builder.WorkflowItemBuilder;
import org.dspace.app.rest.builder.WorkspaceItemBuilder;
import org.dspace.app.rest.matcher.CollectionMatcher;
@@ -1563,6 +1564,153 @@ public class WorkflowItemRestRepositoryIT extends AbstractControllerIntegrationT
;
}
@Test
public void findByItemUuidTest() 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")
.withWorkflowGroup(1, admin).build();
//2. a workflow item
XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1)
.withTitle("Workflow Item 1")
.withIssueDate("2017-10-17")
.withAuthor("Smith, Donald").withAuthor("Doe, John")
.withSubject("ExtraEntry")
.build();
String authToken = getAuthToken(admin.getEmail(), password);
getClient(authToken).perform(get("/api/workflow/workflowitems/search/item")
.param("uuid", String.valueOf(witem.getItem().getID())))
.andExpect(status().isOk())
.andExpect(jsonPath("$",
Matchers.is(
WorkflowItemMatcher.matchItemWithTitleAndDateIssuedAndSubject(witem,
"Workflow Item 1", "2017-10-17", "ExtraEntry"))));
}
@Test
public void findByItemUuidMissingParameterTest() 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")
.withWorkflowGroup(1, admin).build();
String token = getAuthToken(admin.getEmail(), password);
getClient(token).perform(get("/api/workflow/workflowitems/search/item"))
.andExpect(status().isBadRequest());
}
@Test
public void findByItemUuidDoesntExistTest() 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")
.withWorkflowGroup(1, admin).build();
Item item = ItemBuilder.createItem(context, col1).build();
//2. a workspace item
XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1)
.withTitle("Workflow Item 1")
.withIssueDate("2017-10-17")
.withAuthor("Smith, Donald").withAuthor("Doe, John")
.withSubject("ExtraEntry")
.build();
String token = getAuthToken(admin.getEmail(), password);
getClient(token).perform(get("/api/workflow/workflowitems/search/item")
.param("uuid", String.valueOf(item.getID())))
.andExpect(status().isNoContent());
}
@Test
public void findByItemUuidForbiddenTest() throws Exception {
context.turnOffAuthorisationSystem();
context.setCurrentUser(admin);
//** 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")
.withWorkflowGroup(1, admin).build();
XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1)
.withTitle("Workflow Item 1")
.withIssueDate("2017-10-17")
.withAuthor("Smith, Donald").withAuthor("Doe, John")
.withSubject("ExtraEntry")
.build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
getClient(token).perform(get("/api/workflow/workflowitems/search/item")
.param("uuid", String.valueOf(witem.getItem().getID())))
.andExpect(status().isForbidden());
}
@Test
public void findByItemUuidUnAuthenticatedTest() 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")
.withWorkflowGroup(1, admin).build();
XmlWorkflowItem witem = WorkflowItemBuilder.createWorkflowItem(context, col1)
.withTitle("Workflow Item 1")
.withIssueDate("2017-10-17")
.withAuthor("Smith, Donald").withAuthor("Doe, John")
.withSubject("ExtraEntry")
.build();
getClient().perform(get("/api/workflow/workflowitems/search/item")
.param("uuid", String.valueOf(witem.getItem().getID())))
.andExpect(status().isUnauthorized());
}
@Test
public void stepEmbedTest() throws Exception {

View File

@@ -38,6 +38,7 @@ import org.dspace.app.rest.builder.CollectionBuilder;
import org.dspace.app.rest.builder.CommunityBuilder;
import org.dspace.app.rest.builder.EPersonBuilder;
import org.dspace.app.rest.builder.GroupBuilder;
import org.dspace.app.rest.builder.ItemBuilder;
import org.dspace.app.rest.builder.WorkspaceItemBuilder;
import org.dspace.app.rest.matcher.CollectionMatcher;
import org.dspace.app.rest.matcher.ItemMatcher;
@@ -3016,4 +3017,147 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration
"mock/entryValues/one"))
.andExpect(status().isUnauthorized());
}
@Test
public void findByItemUuidTest() 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();
//2. a workspace item
WorkspaceItem witem = WorkspaceItemBuilder.createWorkspaceItem(context, col1)
.withTitle("Workspace Item 1")
.withIssueDate("2017-10-17")
.withAuthor("Smith, Donald").withAuthor("Doe, John")
.withSubject("ExtraEntry")
.build();
String token = getAuthToken(admin.getEmail(), password);
getClient(token).perform(get("/api/submission/workspaceitems/search/item")
.param("uuid", String.valueOf(witem.getItem().getID())))
.andExpect(status().isOk())
.andExpect(jsonPath("$",
Matchers.is(WorkspaceItemMatcher.matchItemWithTitleAndDateIssuedAndSubject
(witem, "Workspace Item 1", "2017-10-17",
"ExtraEntry"))));
}
@Test
public void findByItemUuidMissingParameterTest() 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();
//2. a workspace item
WorkspaceItem witem = WorkspaceItemBuilder.createWorkspaceItem(context, col1)
.withTitle("Workspace Item 1")
.withIssueDate("2017-10-17")
.withAuthor("Smith, Donald").withAuthor("Doe, John")
.withSubject("ExtraEntry")
.build();
String token = getAuthToken(admin.getEmail(), password);
getClient(token).perform(get("/api/submission/workspaceitems/search/item"))
.andExpect(status().isBadRequest());
}
@Test
public void findByItemUuidDoesntExistTest() 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();
Item item = ItemBuilder.createItem(context, col1).build();
//2. a workspace item
WorkspaceItem witem = WorkspaceItemBuilder.createWorkspaceItem(context, col1)
.withTitle("Workspace Item 1")
.withIssueDate("2017-10-17")
.withAuthor("Smith, Donald").withAuthor("Doe, John")
.withSubject("ExtraEntry")
.build();
String token = getAuthToken(admin.getEmail(), password);
getClient(token).perform(get("/api/submission/workspaceitems/search/item")
.param("uuid", String.valueOf(item.getID())))
.andExpect(status().isNoContent());
}
@Test
public void findByItemUuidForbiddenTest() throws Exception {
context.turnOffAuthorisationSystem();
context.setCurrentUser(admin);
//** 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();
//2. a workspace item
WorkspaceItem witem = WorkspaceItemBuilder.createWorkspaceItem(context, col1)
.withTitle("Workspace Item 1")
.withIssueDate("2017-10-17")
.withAuthor("Smith, Donald").withAuthor("Doe, John")
.withSubject("ExtraEntry")
.build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
getClient(token).perform(get("/api/submission/workspaceitems/search/item")
.param("uuid", String.valueOf(witem.getItem().getID())))
.andExpect(status().isForbidden());
}
@Test
public void findByItemUuidUnAuthenticatedTest() 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();
//2. a workspace item
WorkspaceItem witem = WorkspaceItemBuilder.createWorkspaceItem(context, col1)
.withTitle("Workspace Item 1")
.withIssueDate("2017-10-17")
.withAuthor("Smith, Donald").withAuthor("Doe, John")
.withSubject("ExtraEntry")
.build();
getClient().perform(get("/api/submission/workspaceitems/search/item")
.param("uuid", String.valueOf(witem.getItem().getID())))
.andExpect(status().isUnauthorized());
}
}

View File

@@ -53,6 +53,7 @@ public class ItemMatcher {
"bundles[]",
"mappedCollections[]",
"owningCollection",
"version",
"relationships[]",
"templateItemOf"
);
@@ -68,6 +69,7 @@ public class ItemMatcher {
"owningCollection",
"relationships",
"self",
"version",
"templateItemOf"
);
}

View File

@@ -0,0 +1,29 @@
/**
* 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.matcher;
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.is;
import org.dspace.versioning.VersionHistory;
import org.hamcrest.Matcher;
public class VersionHistoryMatcher {
private VersionHistoryMatcher() {
}
public static Matcher<? super Object> matchEntry(VersionHistory versionHistory) {
return allOf(
hasJsonPath("$.id", is(versionHistory.getID())),
hasJsonPath("$.type", is("versionhistory"))
);
}
}

View File

@@ -0,0 +1,31 @@
/**
* 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.matcher;
import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.is;
import org.dspace.versioning.Version;
import org.hamcrest.Matcher;
public class VersionMatcher {
private VersionMatcher() {
}
public static Matcher<? super Object> matchEntry(Version version) {
return allOf(
hasJsonPath("$.id", is(version.getID())),
hasJsonPath("$.version", is(version.getVersionNumber())),
hasJsonPath("$.summary", is(version.getSummary())),
hasJsonPath("$.type", is("version"))
);
}
}