Merge branch 'main' into iiif-endpoint

This commit is contained in:
Michael Spalti
2021-04-02 10:12:59 -07:00
69 changed files with 6350 additions and 520 deletions

View File

@@ -890,10 +890,10 @@ public class MetadataImport extends DSpaceRunnable<MetadataImportScriptConfigura
Entity relationEntity = getEntity(c, value);
// Get relationship type of entity and item
String relationEntityRelationshipType = itemService.getMetadata(relationEntity.getItem(),
"relationship", "type",
null, Item.ANY).get(0).getValue();
String itemRelationshipType = itemService.getMetadata(item, "relationship", "type",
null, Item.ANY).get(0).getValue();
"dspace", "entity",
"type", Item.ANY).get(0).getValue();
String itemRelationshipType = itemService.getMetadata(item, "dspace", "entity",
"type", Item.ANY).get(0).getValue();
// Get the correct RelationshipType based on typeName
List<RelationshipType> relType = relationshipTypeService.findByLeftwardOrRightwardTypeName(c, typeName);
@@ -1487,7 +1487,7 @@ public class MetadataImport extends DSpaceRunnable<MetadataImportScriptConfigura
}
}
//Populate entityTypeMap
if (key.equalsIgnoreCase("relationship.type") && line.get(key).size() > 0) {
if (key.equalsIgnoreCase("dspace.entity.type") && line.get(key).size() > 0) {
if (uuid == null) {
entityTypeMap.put(new UUID(0, rowCount), line.get(key).get(0));
} else {
@@ -1651,8 +1651,8 @@ public class MetadataImport extends DSpaceRunnable<MetadataImportScriptConfigura
if (itemService.find(c, UUID.fromString(targetUUID)) != null) {
targetItem = itemService.find(c, UUID.fromString(targetUUID));
List<MetadataValue> relTypes = itemService.
getMetadata(targetItem, "relationship", "type",
null, Item.ANY);
getMetadata(targetItem, "dspace", "entity",
"type", Item.ANY);
String relTypeValue = null;
if (relTypes.size() > 0) {
relTypeValue = relTypes.get(0).getValue();
@@ -1696,9 +1696,9 @@ public class MetadataImport extends DSpaceRunnable<MetadataImportScriptConfigura
if (itemService.find(c, UUID.fromString(targetUUID)) != null) {
DSpaceCSVLine dSpaceCSVLine = this.csv.getCSVLines()
.get(Integer.valueOf(originRow) - 1);
List<String> relTypes = dSpaceCSVLine.get("relationship.type");
List<String> relTypes = dSpaceCSVLine.get("dspace.entity.type");
if (relTypes == null || relTypes.isEmpty()) {
dSpaceCSVLine.get("relationship.type[]");
dSpaceCSVLine.get("dspace.entity.type[]");
}
if (relTypes != null && relTypes.size() > 0) {
@@ -1710,8 +1710,8 @@ public class MetadataImport extends DSpaceRunnable<MetadataImportScriptConfigura
originItem = itemService.find(c, UUID.fromString(originRefererUUID));
if (originItem != null) {
List<MetadataValue> mdv = itemService.getMetadata(originItem,
"relationship",
"type", null,
"dspace",
"entity", "type",
Item.ANY);
if (!mdv.isEmpty()) {
String relTypeValue = mdv.get(0).getValue();
@@ -1825,4 +1825,4 @@ public class MetadataImport extends DSpaceRunnable<MetadataImportScriptConfigura
return foundRelationshipType;
}
}
}

View File

@@ -17,6 +17,8 @@ import java.util.UUID;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.dspace.authorize.service.AuthorizeService;
import org.dspace.authorize.service.ResourcePolicyService;
import org.dspace.content.Bitstream;
@@ -30,6 +32,13 @@ import org.dspace.content.service.BitstreamService;
import org.dspace.content.service.WorkspaceItemService;
import org.dspace.core.Constants;
import org.dspace.core.Context;
import org.dspace.discovery.DiscoverQuery;
import org.dspace.discovery.DiscoverResult;
import org.dspace.discovery.IndexableObject;
import org.dspace.discovery.SearchService;
import org.dspace.discovery.SearchServiceException;
import org.dspace.discovery.indexobject.IndexableCollection;
import org.dspace.discovery.indexobject.IndexableCommunity;
import org.dspace.eperson.EPerson;
import org.dspace.eperson.Group;
import org.dspace.eperson.service.GroupService;
@@ -52,6 +61,9 @@ import org.springframework.beans.factory.annotation.Autowired;
* group 0, which is anonymous - all EPeople are members of group 0.
*/
public class AuthorizeServiceImpl implements AuthorizeService {
private static Logger log = LogManager.getLogger(AuthorizeServiceImpl.class);
@Autowired(required = true)
protected BitstreamService bitstreamService;
@Autowired(required = true)
@@ -64,6 +76,9 @@ public class AuthorizeServiceImpl implements AuthorizeService {
protected WorkspaceItemService workspaceItemService;
@Autowired(required = true)
protected WorkflowItemService workflowItemService;
@Autowired(required = true)
private SearchService searchService;
protected AuthorizeServiceImpl() {
@@ -428,46 +443,6 @@ public class AuthorizeServiceImpl implements AuthorizeService {
}
}
public boolean isCommunityAdmin(Context c) throws SQLException {
EPerson e = c.getCurrentUser();
return isCommunityAdmin(c, e);
}
@Override
public boolean isCommunityAdmin(Context c, EPerson e) throws SQLException {
if (e != null) {
List<ResourcePolicy> policies = resourcePolicyService.find(c, e,
groupService.allMemberGroups(c, e),
Constants.ADMIN, Constants.COMMUNITY);
if (CollectionUtils.isNotEmpty(policies)) {
return true;
}
}
return false;
}
public boolean isCollectionAdmin(Context c) throws SQLException {
EPerson e = c.getCurrentUser();
return isCollectionAdmin(c, e);
}
@Override
public boolean isCollectionAdmin(Context c, EPerson e) throws SQLException {
if (e != null) {
List<ResourcePolicy> policies = resourcePolicyService.find(c, e,
groupService.allMemberGroups(c, e),
Constants.ADMIN, Constants.COLLECTION);
if (CollectionUtils.isNotEmpty(policies) || isCommunityAdmin(c, e)) {
return true;
}
}
return false;
}
///////////////////////////////////////////////
// policy manipulation methods
///////////////////////////////////////////////
@@ -787,4 +762,191 @@ public class AuthorizeServiceImpl implements AuthorizeService {
return resourcePolicyService.findExceptRpType(c, o, actionID, rpType);
}
/**
* Checks that the context's current user is a community admin in the site by querying the solr database.
*
* @param context context with the current user
* @return true if the current user is a community admin in the site
* false when this is not the case, or an exception occurred
*/
@Override
public boolean isCommunityAdmin(Context context) throws SQLException {
return performCheck(context, "search.resourcetype:" + IndexableCommunity.TYPE);
}
/**
* Checks that the context's current user is a collection admin in the site by querying the solr database.
*
* @param context context with the current user
* @return true if the current user is a collection admin in the site
* false when this is not the case, or an exception occurred
*/
@Override
public boolean isCollectionAdmin(Context context) throws SQLException {
return performCheck(context, "search.resourcetype:" + IndexableCollection.TYPE);
}
/**
* Checks that the context's current user is a community or collection admin in the site.
*
* @param context context with the current user
* @return true if the current user is a community or collection admin in the site
* false when this is not the case, or an exception occurred
*/
@Override
public boolean isComColAdmin(Context context) throws SQLException {
return performCheck(context,
"(search.resourcetype:" + IndexableCommunity.TYPE + " OR search.resourcetype:" +
IndexableCollection.TYPE + ")");
}
/**
* Finds communities for which the logged in user has ADMIN rights.
*
* @param context the context whose user is checked against
* @param query the optional extra query
* @param offset the offset for pagination
* @param limit the amount of dso's to return
* @return a list of communities for which the logged in user has ADMIN rights.
* @throws SearchServiceException
*/
@Override
public List<Community> findAdminAuthorizedCommunity(Context context, String query, int offset, int limit)
throws SearchServiceException, SQLException {
List<Community> communities = new ArrayList<>();
query = formatCustomQuery(query);
DiscoverResult discoverResult = getDiscoverResult(context, query + "search.resourcetype:" +
IndexableCommunity.TYPE,
offset, limit);
for (IndexableObject solrCollections : discoverResult.getIndexableObjects()) {
Community community = ((IndexableCommunity) solrCollections).getIndexedObject();
communities.add(community);
}
return communities;
}
/**
* Finds the amount of communities for which the logged in user has ADMIN rights.
*
* @param context the context whose user is checked against
* @param query the optional extra query
* @return the number of communities for which the logged in user has ADMIN rights.
* @throws SearchServiceException
*/
@Override
public long countAdminAuthorizedCommunity(Context context, String query)
throws SearchServiceException, SQLException {
query = formatCustomQuery(query);
DiscoverResult discoverResult = getDiscoverResult(context, query + "search.resourcetype:" +
IndexableCommunity.TYPE,
null, null);
return discoverResult.getTotalSearchResults();
}
/**
* Finds collections for which the logged in user has ADMIN rights.
*
* @param context the context whose user is checked against
* @param query the optional extra query
* @param offset the offset for pagination
* @param limit the amount of dso's to return
* @return a list of collections for which the logged in user has ADMIN rights.
* @throws SearchServiceException
*/
@Override
public List<Collection> findAdminAuthorizedCollection(Context context, String query, int offset, int limit)
throws SearchServiceException, SQLException {
List<Collection> collections = new ArrayList<>();
if (context.getCurrentUser() == null) {
return collections;
}
query = formatCustomQuery(query);
DiscoverResult discoverResult = getDiscoverResult(context, query + "search.resourcetype:" +
IndexableCollection.TYPE,
offset, limit);
for (IndexableObject solrCollections : discoverResult.getIndexableObjects()) {
Collection collection = ((IndexableCollection) solrCollections).getIndexedObject();
collections.add(collection);
}
return collections;
}
/**
* Finds the amount of collections for which the logged in user has ADMIN rights.
*
* @param context the context whose user is checked against
* @param query the optional extra query
* @return the number of collections for which the logged in user has ADMIN rights.
* @throws SearchServiceException
*/
@Override
public long countAdminAuthorizedCollection(Context context, String query)
throws SearchServiceException, SQLException {
query = formatCustomQuery(query);
DiscoverResult discoverResult = getDiscoverResult(context, query + "search.resourcetype:" +
IndexableCollection.TYPE,
null, null);
return discoverResult.getTotalSearchResults();
}
private boolean performCheck(Context context, String query) throws SQLException {
if (context.getCurrentUser() == null) {
return false;
}
try {
DiscoverResult discoverResult = getDiscoverResult(context, query, null, null);
if (discoverResult.getTotalSearchResults() > 0) {
return true;
}
} catch (SearchServiceException e) {
log.error("Failed getting getting community/collection admin status for "
+ context.getCurrentUser().getEmail() + " The search error is: " + e.getMessage()
+ " The search resourceType filter was: " + query);
}
return false;
}
private DiscoverResult getDiscoverResult(Context context, String query, Integer offset, Integer limit)
throws SearchServiceException, SQLException {
String groupQuery = getGroupToQuery(groupService.allMemberGroups(context, context.getCurrentUser()));
DiscoverQuery discoverQuery = new DiscoverQuery();
if (!this.isAdmin(context)) {
query = query + " AND (" +
"admin:e" + context.getCurrentUser().getID() + groupQuery + ")";
}
discoverQuery.setQuery(query);
if (offset != null) {
discoverQuery.setStart(offset);
}
if (limit != null) {
discoverQuery.setMaxResults(limit);
}
return searchService.search(context, discoverQuery);
}
private String getGroupToQuery(List<Group> groups) {
StringBuilder groupQuery = new StringBuilder();
if (groups != null) {
for (Group group: groups) {
groupQuery.append(" OR admin:g");
groupQuery.append(group.getID());
}
}
return groupQuery.toString();
}
private String formatCustomQuery(String query) {
if (StringUtils.isBlank(query)) {
return "";
} else {
return query + " AND ";
}
}
}

View File

@@ -14,8 +14,10 @@ import java.util.List;
import org.dspace.authorize.AuthorizeException;
import org.dspace.authorize.ResourcePolicy;
import org.dspace.content.Collection;
import org.dspace.content.Community;
import org.dspace.content.DSpaceObject;
import org.dspace.core.Context;
import org.dspace.discovery.SearchServiceException;
import org.dspace.eperson.EPerson;
import org.dspace.eperson.Group;
@@ -209,30 +211,6 @@ public interface AuthorizeService {
*/
public boolean isAdmin(Context c, EPerson e) throws SQLException;
public boolean isCommunityAdmin(Context c) throws SQLException;
public boolean isCollectionAdmin(Context c) throws SQLException;
/**
* Check to see if a specific user is Community admin
*
* @param c current context
* @param e the user to check
* @return true if user is an admin of some community
* @throws SQLException
*/
public boolean isCommunityAdmin(Context c, EPerson e) throws SQLException;
/**
* Check to see if a specific user is Collection admin
*
* @param c current context
* @param e the user to check
* @return true if user is an admin of some collection
* @throws SQLException if database error
*/
public boolean isCollectionAdmin(Context c, EPerson e) throws SQLException;
///////////////////////////////////////////////
// policy manipulation methods
///////////////////////////////////////////////
@@ -536,4 +514,82 @@ public interface AuthorizeService {
void switchPoliciesAction(Context context, DSpaceObject dso, int fromAction, int toAction)
throws SQLException, AuthorizeException;
/**
* Checks that the context's current user is a community admin in the site by querying the solr database.
*
* @param context context with the current user
* @return true if the current user is a community admin in the site
* false when this is not the case, or an exception occurred
*/
boolean isCommunityAdmin(Context context) throws SQLException;
/**
* Checks that the context's current user is a collection admin in the site by querying the solr database.
*
* @param context context with the current user
* @return true if the current user is a collection admin in the site
* false when this is not the case, or an exception occurred
*/
boolean isCollectionAdmin(Context context) throws SQLException;
/**
* Checks that the context's current user is a community or collection admin in the site.
*
* @param context context with the current user
* @return true if the current user is a community or collection admin in the site
* false when this is not the case, or an exception occurred
*/
boolean isComColAdmin(Context context) throws SQLException;
/**
* Finds communities for which the current user is admin, AND which match the query.
*
* @param context context with the current user
* @param query the query for which to filter the results more
* @param offset used for pagination of the results
* @param limit used for pagination of the results
* @return the number of matching communities
* @throws SearchServiceException
* @throws SQLException
*/
List<Community> findAdminAuthorizedCommunity(Context context, String query, int offset, int limit)
throws SearchServiceException, SQLException;
/**
* Counts communities for which the current user is admin, AND which match the query.
*
* @param context context with the current user
* @param query the query for which to filter the results more
* @return the matching communities
* @throws SearchServiceException
* @throws SQLException
*/
long countAdminAuthorizedCommunity(Context context, String query)
throws SearchServiceException, SQLException;
/**
* Finds collections for which the current user is admin, AND which match the query.
*
* @param context context with the current user
* @param query the query for which to filter the results more
* @param offset used for pagination of the results
* @param limit used for pagination of the results
* @return the matching collections
* @throws SearchServiceException
* @throws SQLException
*/
List<Collection> findAdminAuthorizedCollection(Context context, String query, int offset, int limit)
throws SearchServiceException, SQLException;
/**
* Counts collections for which the current user is admin, AND which match the query.
*
* @param context context with the current user
* @param query the query for which to filter the results more
* @return the number of matching collections
* @throws SearchServiceException
* @throws SQLException
*/
long countAdminAuthorizedCollection(Context context, String query)
throws SearchServiceException, SQLException;
}

View File

@@ -305,6 +305,7 @@ public abstract class DSpaceObjectServiceImpl<T extends DSpaceObject> implements
// metadataValueService.update(context, metadataValue);
dso.addDetails(metadataField.toString());
}
setMetadataModified(dso);
return newMetadata;
}

View File

@@ -51,7 +51,7 @@ public class EntityServiceImpl implements EntityService {
@Override
public EntityType getType(Context context, Entity entity) throws SQLException {
Item item = entity.getItem();
List<MetadataValue> list = itemService.getMetadata(item, "relationship", "type", null, Item.ANY, false);
List<MetadataValue> list = itemService.getMetadata(item, "dspace", "entity", "type", Item.ANY, false);
if (!list.isEmpty()) {
return entityTypeService.findByEntityType(context, list.get(0).getValue());
} else {

View File

@@ -112,6 +112,16 @@ public class Item extends DSpaceObject implements DSpaceObjectLegacySupport {
@Transient
private transient ItemService itemService;
/**
* True if anything else was changed since last metadata retrieval()
* (to drive metadata cache)
*/
@Transient
private boolean modifiedMetadataCache = true;
@Transient
private List<MetadataValue> cachedMetadata = new ArrayList<>();
/**
* Protected constructor, create object using:
* {@link org.dspace.content.service.ItemService#create(Context, WorkspaceItem)}
@@ -373,4 +383,23 @@ public class Item extends DSpaceObject implements DSpaceObjectLegacySupport {
}
return itemService;
}
@Override
protected void setMetadataModified() {
super.setMetadataModified();
modifiedMetadataCache = true;
}
public boolean isModifiedMetadataCache() {
return modifiedMetadataCache;
}
protected List<MetadataValue> getCachedMetadata() {
return cachedMetadata;
}
protected void setCachedMetadata(List<MetadataValue> cachedMetadata) {
this.cachedMetadata = cachedMetadata;
modifiedMetadataCache = false;
}
}

View File

@@ -1328,42 +1328,33 @@ prevent the generation of resource policy entry values with null dspace_object a
@Override
public List<MetadataValue> getMetadata(Item item, String schema, String element, String qualifier, String lang,
boolean enableVirtualMetadata) {
//Fields of the relation schema are virtual metadata
//except for relation.type which is the type of item in the model
if (StringUtils.equals(schema, MetadataSchemaEnum.RELATION.getName()) && !StringUtils.equals(element, "type")) {
List<RelationshipMetadataValue> relationMetadata = relationshipMetadataService
.getRelationshipMetadata(item, enableVirtualMetadata);
List<MetadataValue> listToReturn = new LinkedList<>();
for (MetadataValue metadataValue : relationMetadata) {
if (StringUtils.equals(metadataValue.getMetadataField().getElement(), element)) {
listToReturn.add(metadataValue);
}
}
listToReturn = sortMetadataValueList(listToReturn);
return listToReturn;
} else {
List<MetadataValue> dbMetadataValues = super.getMetadata(item, schema, element, qualifier, lang);
if (!enableVirtualMetadata) {
log.debug("Called getMetadata for " + item.getID() + " without enableVirtualMetadata");
return super.getMetadata(item, schema, element, qualifier, lang);
}
if (item.isModifiedMetadataCache()) {
log.debug("Called getMetadata for " + item.getID() + " with invalid cache");
//rebuild cache
List<MetadataValue> dbMetadataValues = item.getMetadata();
List<MetadataValue> fullMetadataValueList = new LinkedList<>();
if (enableVirtualMetadata) {
fullMetadataValueList.addAll(relationshipMetadataService.getRelationshipMetadata(item, true));
}
fullMetadataValueList.addAll(relationshipMetadataService.getRelationshipMetadata(item, true));
fullMetadataValueList.addAll(dbMetadataValues);
List<MetadataValue> finalList = new LinkedList<>();
for (MetadataValue metadataValue : fullMetadataValueList) {
if (match(schema, element, qualifier, lang, metadataValue)) {
finalList.add(metadataValue);
}
}
finalList = sortMetadataValueList(finalList);
return finalList;
item.setCachedMetadata(sortMetadataValueList(fullMetadataValueList));
}
log.debug("Called getMetadata for " + item.getID() + " based on cache");
// Build up list of matching values based on the cache
List<MetadataValue> values = new ArrayList<>();
for (MetadataValue dcv : item.getCachedMetadata()) {
if (match(schema, element, qualifier, lang, dcv)) {
values.add(dcv);
}
}
// Create an array of matching values
return values;
}
/**

View File

@@ -164,6 +164,7 @@ public class Relationship implements ReloadableEntity<Integer> {
*/
public void setLeftPlace(int leftPlace) {
this.leftPlace = leftPlace;
leftItem.setMetadataModified();
}
/**
@@ -180,6 +181,7 @@ public class Relationship implements ReloadableEntity<Integer> {
*/
public void setRightPlace(int rightPlace) {
this.rightPlace = rightPlace;
rightItem.setMetadataModified();
}
/**

View File

@@ -63,11 +63,9 @@ public class RelationshipMetadataServiceImpl implements RelationshipMetadataServ
public String getEntityTypeStringFromMetadata(Item item) {
List<MetadataValue> list = item.getMetadata();
for (MetadataValue mdv : list) {
if (StringUtils.equals(mdv.getMetadataField().getMetadataSchema().getName(),
"relationship")
&& StringUtils.equals(mdv.getMetadataField().getElement(),
"type")) {
if (StringUtils.equals(mdv.getMetadataField().getMetadataSchema().getName(), "dspace")
&& StringUtils.equals(mdv.getMetadataField().getElement(), "entity")
&& StringUtils.equals(mdv.getMetadataField().getQualifier(), "type")) {
return mdv.getValue();
}
}

View File

@@ -257,8 +257,8 @@ public class RelationshipServiceImpl implements RelationshipService {
}
private boolean verifyEntityTypes(Item itemToProcess, EntityType entityTypeToProcess) {
List<MetadataValue> list = itemService.getMetadata(itemToProcess, "relationship", "type",
null, Item.ANY, false);
List<MetadataValue> list = itemService.getMetadata(itemToProcess, "dspace", "entity",
"type", Item.ANY, false);
if (list.isEmpty()) {
return false;
}

View File

@@ -13,6 +13,7 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
@@ -315,6 +316,9 @@ public class DSpaceControlledVocabulary extends SelfNamedPlugin implements Hiera
private String getNodeLabel(String key, boolean useHierarchy) {
try {
Node node = getNode(key);
if (Objects.isNull(node)) {
return null;
}
if (useHierarchy) {
return this.buildString(node);
} else {

View File

@@ -8,8 +8,10 @@
package org.dspace.content.dao.impl;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.persistence.Query;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
@@ -17,6 +19,7 @@ import javax.persistence.criteria.Join;
import javax.persistence.criteria.Root;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.Logger;
import org.dspace.content.MetadataField;
import org.dspace.content.MetadataField_;
import org.dspace.content.MetadataSchema;
@@ -24,6 +27,7 @@ import org.dspace.content.MetadataSchema_;
import org.dspace.content.dao.MetadataFieldDAO;
import org.dspace.core.AbstractHibernateDAO;
import org.dspace.core.Context;
import org.hibernate.Session;
/**
* Hibernate implementation of the Database Access Object interface class for the MetadataField object.
@@ -33,6 +37,17 @@ import org.dspace.core.Context;
* @author kevinvandevelde at atmire.com
*/
public class MetadataFieldDAOImpl extends AbstractHibernateDAO<MetadataField> implements MetadataFieldDAO {
/**
* log4j logger
*/
private static Logger log = org.apache.logging.log4j.LogManager.getLogger(MetadataFieldDAOImpl.class);
/**
* Cache for improvement the performance of searching metadata fields
* This cache only stores IDs, the actual MetadataField is retrieved from hibernate
*/
private static Map<String, Integer> cachedFields = new HashMap();
protected MetadataFieldDAOImpl() {
super();
}
@@ -79,6 +94,30 @@ public class MetadataFieldDAOImpl extends AbstractHibernateDAO<MetadataField> im
@Override
public MetadataField findByElement(Context context, String metadataSchema, String element, String qualifier)
throws SQLException {
String key = metadataSchema + "." + element + "." + qualifier;
if (cachedFields.containsKey(key)) {
Session session = getHibernateSession(context);
MetadataField metadataField = null;
try {
metadataField = session.load(MetadataField.class, cachedFields.get(key));
} catch (Throwable e) {
log.error("Failed to load metadata field " + key + " using ID " + cachedFields.get(key));
}
try {
if (metadataField != null &&
(metadataField.getMetadataSchema().getName() + "." + metadataField.getElement() +
"." + metadataField.getQualifier()).equals(key)) {
return metadataField;
} else {
cachedFields.remove(key);
}
} catch (Throwable e) {
log.error("Failed to verify consistence of metadata field " + key +
" using ID " + cachedFields.get(key));
cachedFields.clear();
}
}
Query query;
if (StringUtils.isNotBlank(qualifier)) {
@@ -103,7 +142,11 @@ public class MetadataFieldDAOImpl extends AbstractHibernateDAO<MetadataField> im
}
query.setHint("org.hibernate.cacheable", Boolean.TRUE);
return singleResult(query);
MetadataField metadataField = singleResult(query);
if (metadataField != null) {
cachedFields.put(key, metadataField.getID());
}
return metadataField;
}
@Override

View File

@@ -157,6 +157,13 @@ public class IndexEventConsumer implements Consumer {
} else {
log.debug("consume() adding event to update queue: " + event.toString());
objectsToUpdate.addAll(indexObjectServiceFactory.getIndexableObjects(ctx, subject));
// If the event subject is a Collection and the event object is an Item,
// also update the object in order to index mapped/unmapped Items
if (subject != null &&
subject.getType() == Constants.COLLECTION && object.getType() == Constants.ITEM) {
objectsToUpdate.addAll(indexObjectServiceFactory.getIndexableObjects(ctx, object));
}
}
break;

View File

@@ -11,6 +11,7 @@ import static org.apache.logging.log4j.LogManager.getLogger;
import java.sql.SQLException;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.Logger;
import org.apache.solr.client.solrj.SolrQuery;
import org.dspace.authorize.service.AuthorizeService;
@@ -37,9 +38,16 @@ public class SolrServicePrivateItemPlugin implements SolrServiceSearchPlugin {
try {
// Prevents access if user has no administrative rights on the community or collection.
// NOTE: the resource restriction plugin adds location filters for community and collection admins.
if ( !authorizeService.isAdmin(context) && !authorizeService.isCommunityAdmin(context)
&& !authorizeService.isCollectionAdmin(context)) {
if (authorizeService.isAdmin(context)) {
return;
}
if (!StringUtils.equalsIgnoreCase(discoveryQuery.getDiscoveryConfigurationName(), "administrativeView")) {
solrQuery.addFilterQuery("NOT(discoverable:false)");
return;
}
if (!authorizeService.isCommunityAdmin(context) && !authorizeService.isCollectionAdmin(context)) {
solrQuery.addFilterQuery("NOT(discoverable:false)");
}
} catch (SQLException ex) {
log.error(LogManager.getHeader(context, "Error looking up authorization rights of current user",

View File

@@ -11,6 +11,7 @@ import java.sql.SQLException;
import java.util.List;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.Logger;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.common.SolrInputDocument;
@@ -118,6 +119,7 @@ public class SolrServiceResourceRestrictionPlugin implements SolrServiceIndexPlu
fieldValue = "e" + resourcePolicy.getEPerson().getID();
}
document.addField("read", fieldValue);
document.addField("admin", fieldValue);
}
// remove the policy from the cache to save memory
@@ -159,14 +161,15 @@ public class SolrServiceResourceRestrictionPlugin implements SolrServiceIndexPlu
resourceQuery.append(")");
if (authorizeService.isCommunityAdmin(context)
|| authorizeService.isCollectionAdmin(context)) {
String locations = DSpaceServicesFactory.getInstance()
.getServiceManager()
.getServiceByName(SearchService.class.getName(),
SearchService.class)
.createLocationQueryForAdministrableItems(context);
if (StringUtils.isNotBlank(locations)) {
resourceQuery.append(" OR ");
resourceQuery.append(DSpaceServicesFactory.getInstance()
.getServiceManager()
.getServiceByName(SearchService.class.getName(),
SearchService.class)
.createLocationQueryForAdministrableItems(context));
resourceQuery.append(locations);
}
solrQuery.addFilterQuery(resourceQuery.toString());

View File

@@ -0,0 +1,56 @@
--
-- The contents of this file are subject to the license and copyright
-- detailed in the LICENSE and NOTICE files at the root of the source
-- tree and available online at
--
-- http://www.dspace.org/license/
--
-- ===============================================================
-- WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
--
-- DO NOT MANUALLY RUN THIS DATABASE MIGRATION. IT WILL BE EXECUTED
-- AUTOMATICALLY (IF NEEDED) BY "FLYWAY" WHEN YOU STARTUP DSPACE.
-- http://flywaydb.org/
-- ===============================================================
-------------------------------------------------------------------------------------------------------
-- Move all 'relationship.type' metadata fields to 'dspace.entity.type'. Remove 'relationship' schema.
-------------------------------------------------------------------------------------------------------
-- Special case: we need to the 'dspace' schema to already exist. If users don't already have it we must create it
-- manually via SQL, as by default it won't be created until database updates are finished.
INSERT INTO metadataschemaregistry (metadata_schema_id, namespace, short_id)
SELECT metadataschemaregistry_seq.nextval, 'http://dspace.org/dspace' as namespace, 'dspace' as short_id FROM dual
WHERE NOT EXISTS
(SELECT metadata_schema_id,namespace,short_id FROM metadataschemaregistry
WHERE namespace = 'http://dspace.org/dspace' AND short_id = 'dspace');
-- Add 'dspace.entity.type' field to registry (if missing)
INSERT INTO metadatafieldregistry (metadata_field_id, metadata_schema_id, element, qualifier)
SELECT metadatafieldregistry_seq.nextval,
(SELECT metadata_schema_id FROM metadataschemaregistry WHERE short_id='dspace'), 'entity', 'type' FROM dual
WHERE NOT EXISTS
(SELECT metadata_field_id,element,qualifier FROM metadatafieldregistry
WHERE metadata_schema_id = (SELECT metadata_schema_id FROM metadataschemaregistry WHERE short_id='dspace')
AND element = 'entitye' AND qualifier='type');
-- Moves all 'relationship.type' field values to a new 'dspace.entity.type' field
UPDATE metadatavalue
SET metadata_field_id =
(SELECT metadata_field_id FROM metadatafieldregistry
WHERE metadata_schema_id = (SELECT metadata_schema_id FROM metadataschemaregistry WHERE short_id='dspace')
AND element = 'entity' AND qualifier='type')
WHERE metadata_field_id =
(SELECT metadata_field_id FROM metadatafieldregistry
WHERE metadata_schema_id = (SELECT metadata_schema_id FROM metadataschemaregistry WHERE short_id='relationship')
AND element = 'type' AND qualifier is NULL);
-- Delete 'relationship.type' field from registry
DELETE FROM metadatafieldregistry
WHERE metadata_schema_id = (SELECT metadata_schema_id FROM metadataschemaregistry WHERE short_id = 'relationship')
AND element = 'type' AND qualifier is NULL;
-- Delete 'relationship' schema (which is now empty)
DELETE FROM metadataschemaregistry WHERE short_id = 'relationship' AND namespace = 'http://dspace.org/relationship';

View File

@@ -0,0 +1,56 @@
--
-- The contents of this file are subject to the license and copyright
-- detailed in the LICENSE and NOTICE files at the root of the source
-- tree and available online at
--
-- http://www.dspace.org/license/
--
-- ===============================================================
-- WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
--
-- DO NOT MANUALLY RUN THIS DATABASE MIGRATION. IT WILL BE EXECUTED
-- AUTOMATICALLY (IF NEEDED) BY "FLYWAY" WHEN YOU STARTUP DSPACE.
-- http://flywaydb.org/
-- ===============================================================
-------------------------------------------------------------------------------------------------------
-- Move all 'relationship.type' metadata fields to 'dspace.entity.type'. Remove 'relationship' schema.
-------------------------------------------------------------------------------------------------------
-- Special case: we need to the 'dspace' schema to already exist. If users don't already have it we must create it
-- manually via SQL, as by default it won't be created until database updates are finished.
INSERT INTO metadataschemaregistry (namespace, short_id)
SELECT 'http://dspace.org/dspace', 'dspace'
WHERE NOT EXISTS
(SELECT metadata_schema_id,namespace,short_id FROM metadataschemaregistry
WHERE namespace = 'http://dspace.org/dspace' AND short_id = 'dspace');
-- Add 'dspace.entity.type' field to registry (if missing)
INSERT INTO metadatafieldregistry (metadata_schema_id, element, qualifier)
SELECT (SELECT metadata_schema_id FROM metadataschemaregistry WHERE short_id='dspace'), 'entity', 'type'
WHERE NOT EXISTS
(SELECT metadata_field_id,element,qualifier FROM metadatafieldregistry
WHERE metadata_schema_id = (SELECT metadata_schema_id FROM metadataschemaregistry WHERE short_id='dspace')
AND element = 'entity' AND qualifier='type');
-- Moves all 'relationship.type' field values to new 'dspace.entity.type' field
UPDATE metadatavalue
SET metadata_field_id =
(SELECT metadata_field_id FROM metadatafieldregistry
WHERE metadata_schema_id = (SELECT metadata_schema_id FROM metadataschemaregistry WHERE short_id='dspace')
AND element = 'entity' AND qualifier='type')
WHERE metadata_field_id =
(SELECT metadata_field_id FROM metadatafieldregistry
WHERE metadata_schema_id = (SELECT metadata_schema_id FROM metadataschemaregistry WHERE short_id='relationship')
AND element = 'type' AND qualifier is NULL);
-- Delete 'relationship.type' field from registry
DELETE FROM metadatafieldregistry
WHERE metadata_schema_id = (SELECT metadata_schema_id FROM metadataschemaregistry WHERE short_id = 'relationship')
AND element = 'type' AND qualifier is NULL;
-- Delete 'relationship' schema (which is now empty)
DELETE FROM metadataschemaregistry WHERE short_id = 'relationship' AND namespace = 'http://dspace.org/relationship';

View File

@@ -105,7 +105,7 @@ public class MetadataImportIT extends AbstractIntegrationTestWithDatabase {
@Test
public void relationshipMetadataImportTest() throws Exception {
context.turnOffAuthorisationSystem();
Item item = ItemBuilder.createItem(context, collection).withRelationshipType("Publication")
Item item = ItemBuilder.createItem(context, collection).withEntityType("Publication")
.withTitle("Publication1").build();
EntityType publication = EntityTypeBuilder.createEntityTypeBuilder(context, "Publication").build();
EntityType person = EntityTypeBuilder.createEntityTypeBuilder(context, "Person").build();
@@ -113,7 +113,7 @@ public class MetadataImportIT extends AbstractIntegrationTestWithDatabase {
"isPublicationOfAuthor", 0, 10, 0, 10);
context.restoreAuthSystemState();
String[] csv = {"id,collection,dc.title,relation.isPublicationOfAuthor,relationship.type",
String[] csv = {"id,collection,dc.title,relation.isPublicationOfAuthor,dspace.entity.type",
"+," + collection.getHandle() + ",\"Test Import 1\"," + item.getID() + ",Person"};
performImportScript(csv);
Item importedItem = findItemByName("Test Import 1");
@@ -128,11 +128,11 @@ public class MetadataImportIT extends AbstractIntegrationTestWithDatabase {
@Test
public void relationshipMetadataImporAlreadyExistingItemTest() throws Exception {
context.turnOffAuthorisationSystem();
Item personItem = ItemBuilder.createItem(context, collection).withRelationshipType("Person")
Item personItem = ItemBuilder.createItem(context, collection).withEntityType("Person")
.withTitle("Person1").build();
List<Relationship> relationshipList = relationshipService.findByItem(context, personItem);
assertEquals(0, relationshipList.size());
Item publicationItem = ItemBuilder.createItem(context, collection).withRelationshipType("Publication")
Item publicationItem = ItemBuilder.createItem(context, collection).withEntityType("Publication")
.withTitle("Publication1").build();
EntityType publication = EntityTypeBuilder.createEntityTypeBuilder(context, "Publication").build();

View File

@@ -128,7 +128,7 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat
*/
@Test
public void testSingleMdRef() throws Exception {
String[] csv = {"id,relationship.type,relation.isAuthorOfPublication,collection,dc.identifier.other",
String[] csv = {"id,dspace.entity.type,relation.isAuthorOfPublication,collection,dc.identifier.other",
"+,Person,," + col1.getHandle() + ",0",
"+,Publication,dc.identifier.other:0," + col1.getHandle() + ",1"};
Item[] items = runImport(csv);
@@ -157,7 +157,7 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat
*/
@Test
public void testSingleRowNameRef() throws Exception {
String[] csv = {"id,dc.title,relationship.type,relation.isAuthorOfPublication,collection,rowName," +
String[] csv = {"id,dc.title,dspace.entity.type,relation.isAuthorOfPublication,collection,rowName," +
"dc.identifier.other",
"+,Test Item 1,Person,," + col1.getHandle() + ",idVal,0",
"+,Test Item 2,Publication,rowName:idVal," + col1.getHandle() + ",anything,1"};
@@ -171,7 +171,7 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat
*/
@Test
public void testMultiMdRef() throws Exception {
String[] csv = {"id,relationship.type,relation.isAuthorOfPublication,collection,dc.identifier.other",
String[] csv = {"id,dspace.entity.type,relation.isAuthorOfPublication,collection,dc.identifier.other",
"+,Person,," + col1.getHandle() + ",0",
"+,Person,," + col1.getHandle() + ",1",
"+,Publication,dc.identifier.other:0||dc.identifier.other:1," + col1.getHandle() + ",2"};
@@ -186,7 +186,7 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat
*/
@Test
public void testMultiRowNameRef() throws Exception {
String[] csv = {"id,relationship.type,relation.isAuthorOfPublication,collection,dc.identifier.other,rowName",
String[] csv = {"id,dspace.entity.type,relation.isAuthorOfPublication,collection,dc.identifier.other,rowName",
"+,Person,," + col1.getHandle() + ",0,val1",
"+,Person,," + col1.getHandle() + ",1,val2",
"+,Publication,rowName:val1||rowName:val2," + col1.getHandle() + ",2,val3"};
@@ -208,10 +208,10 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat
.withAuthor("Smith, Donald")
.withPersonIdentifierLastName("Smith")
.withPersonIdentifierFirstName("Donald")
.withRelationshipType("Person")
.withEntityType("Person")
.build();
context.restoreAuthSystemState();
String[] csv = {"id,relationship.type,relation.isAuthorOfPublication,collection,rowName,dc.identifier.other",
String[] csv = {"id,dspace.entity.type,relation.isAuthorOfPublication,collection,rowName,dc.identifier.other",
"+,Publication," + person.getID().toString() + "," + col1.getHandle() + ",anything,0"};
Item[] items = runImport(csv);
assertRelationship(items[0], person, 1, "left", 0);
@@ -230,7 +230,7 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat
.withAuthor("Smith, Donald")
.withPersonIdentifierLastName("Smith")
.withPersonIdentifierFirstName("Donald")
.withRelationshipType("Person")
.withEntityType("Person")
.build();
Item person2 = ItemBuilder.createItem(context, col1)
.withTitle("Author2")
@@ -238,9 +238,9 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat
.withAuthor("Smith, John")
.withPersonIdentifierLastName("Smith")
.withPersonIdentifierFirstName("John")
.withRelationshipType("Person")
.withEntityType("Person")
.build();
String[] csv = {"id,relationship.type,relation.isAuthorOfPublication,collection,rowName,dc.identifier.other",
String[] csv = {"id,dspace.entity.type,relation.isAuthorOfPublication,collection,rowName,dc.identifier.other",
"+,Publication," + person.getID().toString() + "||" + person2.getID().toString() + "," +
col1.getHandle() + ",anything,0"};
Item[] items = runImport(csv);
@@ -261,9 +261,9 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat
.withAuthor("Smith, Donald")
.withPersonIdentifierLastName("Smith")
.withPersonIdentifierFirstName("Donald")
.withRelationshipType("Person")
.withEntityType("Person")
.build();
String[] csv = {"id,dc.title,relationship.type,relation.isAuthorOfPublication,collection,rowName," +
String[] csv = {"id,dc.title,dspace.entity.type,relation.isAuthorOfPublication,collection,rowName," +
"dc.identifier.other",
"+,Person2,Person,," + col1.getHandle() + ",idVal,0",
"+,Pub1,Publication,dc.title:Person||dc.title:Person2," + col1.getHandle() + ",anything,1"};
@@ -287,7 +287,7 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat
.withAuthor("Smith, Donald")
.withPersonIdentifierLastName("Smith")
.withPersonIdentifierFirstName("Donald")
.withRelationshipType("Person")
.withEntityType("Person")
.build();
Item person2 = ItemBuilder.createItem(context, col1)
.withTitle("Person2")
@@ -295,11 +295,11 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat
.withAuthor("Smith, John")
.withPersonIdentifierLastName("Smith")
.withPersonIdentifierFirstName("John")
.withRelationshipType("Person")
.withEntityType("Person")
.build();
context.restoreAuthSystemState();
String[] csv = {"id,dc.title,relationship.type,relation.isAuthorOfPublication,collection,rowName," +
String[] csv = {"id,dc.title,dspace.entity.type,relation.isAuthorOfPublication,collection,rowName," +
"dc.identifier.other",
"+,Person3,Person,," + col1.getHandle() + ",idVal,0",
"+,Pub1,Publication," + person.getID() + "||dc.title:Person2||rowName:idVal," +
@@ -316,7 +316,7 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat
*/
@Test
public void testRefWithSpecialChar() throws Exception {
String[] csv = {"id,dc.title,relationship.type,relation.isAuthorOfPublication,collection,rowName," +
String[] csv = {"id,dc.title,dspace.entity.type,relation.isAuthorOfPublication,collection,rowName," +
"dc.identifier.other",
"+,Person:,Person,," + col1.getHandle() + ",idVal,0",
"+,Pub1,Publication,dc.title:Person:," + col1.getHandle() + ",anything,1"};
@@ -329,7 +329,7 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat
*/
@Test(expected = MetadataImportException.class)
public void testNonUniqueMDRefInCsv() throws Exception {
String[] csv = {"id,relationship.type,relation.isAuthorOfPublication,collection,dc.identifier.other",
String[] csv = {"id,dspace.entity.type,relation.isAuthorOfPublication,collection,dc.identifier.other",
"+,Person,," + col1.getHandle() + ",1",
"+,Person,," + col1.getHandle() + ",1",
"+,Publication,dc.identifier.other:1," + col1.getHandle() + ",2"};
@@ -341,7 +341,7 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat
*/
@Test(expected = MetadataImportException.class)
public void testNonUniqueRowName() throws Exception {
String[] csv = {"id,relationship.type,relation.isAuthorOfPublication,collection,dc.identifier.other,rowName",
String[] csv = {"id,dspace.entity.type,relation.isAuthorOfPublication,collection,dc.identifier.other,rowName",
"+,Person,," + col1.getHandle() + ",1,value",
"+,Person,," + col1.getHandle() + ",1,value",
"+,Publication,rowName:value," + col1.getHandle() + ",2"};
@@ -360,7 +360,7 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat
.withAuthor("Smith, Donald")
.withPersonIdentifierLastName("Smith")
.withPersonIdentifierFirstName("Donald")
.withRelationshipType("Person")
.withEntityType("Person")
.withIdentifierOther("1")
.build();
Item person2 = ItemBuilder.createItem(context, col1)
@@ -369,12 +369,12 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat
.withAuthor("Smith, John")
.withPersonIdentifierLastName("Smith")
.withPersonIdentifierFirstName("John")
.withRelationshipType("Person")
.withEntityType("Person")
.withIdentifierOther("1")
.build();
context.restoreAuthSystemState();
String[] csv = {"id,relationship.type,relation.isAuthorOfPublication,collection,dc.identifier.other",
String[] csv = {"id,dspace.entity.type,relation.isAuthorOfPublication,collection,dc.identifier.other",
"+,Publication,dc.identifier.other:1," + col1.getHandle() + ",2"};
performImportScript(csv, true);
}
@@ -391,11 +391,11 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat
.withAuthor("Smith, Donald")
.withPersonIdentifierLastName("Smith")
.withPersonIdentifierFirstName("Donald")
.withRelationshipType("Person")
.withEntityType("Person")
.withIdentifierOther("1")
.build();
context.restoreAuthSystemState();
String[] csv = {"id,relationship.type,relation.isAuthorOfPublication,collection,dc.identifier.other",
String[] csv = {"id,dspace.entity.type,relation.isAuthorOfPublication,collection,dc.identifier.other",
"+,Person,," + col1.getHandle() + ",1",
"+,Publication,dc.identifier.other:1," + col1.getHandle() + ",2"};
performImportScript(csv, true);
@@ -406,7 +406,7 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat
*/
@Test(expected = Exception.class)
public void testNonExistMdRef() throws Exception {
String[] csv = {"id,relationship.type,relation.isAuthorOfPublication,collection,dc.identifier.other",
String[] csv = {"id,dspace.entity.type,relation.isAuthorOfPublication,collection,dc.identifier.other",
"+,Person,," + col1.getHandle() + ",1",
"+,Publication,dc.identifier.other:8675309," + col1.getHandle() + ",2"};
performImportScript(csv, false);
@@ -417,7 +417,7 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat
*/
@Test(expected = Exception.class)
public void testCSVImportWrongOrder() throws Exception {
String[] csv = {"id,relationship.type,relation.isAuthorOfPublication,collection,dc.identifier.other",
String[] csv = {"id,dspace.entity.type,relation.isAuthorOfPublication,collection,dc.identifier.other",
"+,Publication,dc.identifier.other:8675309," + col1.getHandle() + ",2",
"+,Person,," + col1.getHandle() + ",8675309",};
performImportScript(csv, false);
@@ -428,7 +428,7 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat
*/
@Test(expected = Exception.class)
public void testCSVImportWrongOrderRowName() throws Exception {
String[] csv = {"id,relationship.type,relation.isAuthorOfPublication,collection,dc.identifier.other,rowName",
String[] csv = {"id,dspace.entity.type,relation.isAuthorOfPublication,collection,dc.identifier.other,rowName",
"+,Publication,rowName:row2," + col1.getHandle() + ",2,row1",
"+,Person,," + col1.getHandle() + ",8675309,row2",};
performImportScript(csv, false);
@@ -439,7 +439,7 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat
*/
@Test(expected = MetadataImportException.class)
public void testCSVImportInvalidRelationship() throws Exception {
String[] csv = {"id,relationship.type,relation.isAuthorOfPublication,collection,rowName",
String[] csv = {"id,dspace.entity.type,relation.isAuthorOfPublication,collection,rowName",
"+,Publication,," + col1.getHandle() + ",row1",
"+,Unit,rowName:row1," + col1.getHandle() + ",row2",};
performImportScript(csv, true);
@@ -454,10 +454,10 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat
Item testItem = ItemBuilder.createItem(context, col1)
.withTitle("OrgUnit")
.withIssueDate("2017-10-17")
.withRelationshipType("OrgUnit")
.withEntityType("OrgUnit")
.build();
context.restoreAuthSystemState();
String[] csv = {"id,relationship.type,relation.isAuthorOfPublication,collection,rowName",
String[] csv = {"id,dspace.entity.type,relation.isAuthorOfPublication,collection,rowName",
"+,Person,," + col1.getHandle() + ",1" +
testItem.getID().toString() + ",,rowName:1," + col1.getHandle() + ",2"};
performImportScript(csv, false);
@@ -472,10 +472,10 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat
Item testItem = ItemBuilder.createItem(context, col1)
.withTitle("OrgUnit")
.withIssueDate("2017-10-17")
.withRelationshipType("OrgUnit")
.withEntityType("OrgUnit")
.build();
context.restoreAuthSystemState();
String[] csv = {"id,relationship.type,relation.isAuthorOfPublication,collection,rowName",
String[] csv = {"id,dspace.entity.type,relation.isAuthorOfPublication,collection,rowName",
testItem.getID().toString() + ",Person,," + col1.getHandle() + ",1" +
"+,OrgUnit,rowName:1," + col1.getHandle() + ",2"};
performImportScript(csv, false);
@@ -494,7 +494,7 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat
.withAuthor("Smith, Donald")
.withPersonIdentifierLastName("Smith")
.withPersonIdentifierFirstName("Donald")
.withRelationshipType("Person")
.withEntityType("Person")
.withIdentifierOther("testItemOne")
.build();
@@ -502,7 +502,7 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat
Item testItem2 = ItemBuilder.createItem(context, col1)
.withTitle("Publication")
.withIssueDate("2017-10-17")
.withRelationshipType("Publication")
.withEntityType("Publication")
.withIdentifierOther("testItemTwo")
.build();
@@ -510,7 +510,7 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat
Item testItem3 = ItemBuilder.createItem(context, col1)
.withTitle("Project")
.withIssueDate("2017-10-17")
.withRelationshipType("Project")
.withEntityType("Project")
.withIdentifierOther("testItemThree")
.build();
@@ -530,7 +530,7 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat
*/
@Test
public void testDuplicateRowNameReferences() throws Exception {
String[] csv = {"id,relationship.type,relation.isAuthorOfPublication,collection,dc.identifier.other,rowName",
String[] csv = {"id,dspace.entity.type,relation.isAuthorOfPublication,collection,dc.identifier.other,rowName",
"+,Person,," + col1.getHandle() + ",0,value",
"+,Publication,rowName:value," + col1.getHandle() + ",1,1",
"+,Publication,rowName:value," + col1.getHandle() + ",2,2"};
@@ -548,12 +548,12 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat
.withAuthor("Smith, Donald")
.withPersonIdentifierLastName("Smith")
.withPersonIdentifierFirstName("Donald")
.withRelationshipType("Person")
.withEntityType("Person")
.withIdentifierOther("testItemOne")
.build();
String[] csv = {"id,relationship.type,relation.isAuthorOfPublication,collection,dc.identifier.other,rowName",
String[] csv = {"id,dspace.entity.type,relation.isAuthorOfPublication,collection,dc.identifier.other,rowName",
"+,Publication," + testItem.getID() + "::virtual::4::600," + col1.getHandle() + ",0,1"};
Item[] items = runImport(csv);
assertRelationship(items[0], testItem, 1, "left", 0);
@@ -569,10 +569,10 @@ public class CSVMetadataImportReferenceIT extends AbstractIntegrationTestWithDat
Item testItem = ItemBuilder.createItem(context, col1)
.withTitle("Publication")
.withIssueDate("2017-10-17")
.withRelationshipType("Publication")
.withEntityType("Publication")
.build();
context.restoreAuthSystemState();
String[] csv = {"id,collection,relationship.type,dc.title," +
String[] csv = {"id,collection,dspace.entity.type,dc.title," +
"relation.isProjectOfPublication,relation.isPublicationOfProject",
"+," + col1.getHandle() + ",Project,Title," +
testItem.getID().toString() + "," + testItem.getID().toString()};

View File

@@ -8,13 +8,11 @@
package org.dspace.authorize;
import java.io.IOException;
import java.sql.SQLException;
import org.dspace.AbstractUnitTest;
import org.dspace.authorize.factory.AuthorizeServiceFactory;
import org.dspace.authorize.service.ResourcePolicyService;
import org.dspace.content.Collection;
import org.dspace.content.Community;
import org.dspace.content.factory.ContentServiceFactory;
import org.dspace.content.service.CollectionService;
@@ -129,70 +127,72 @@ public class AuthorizeServiceTest extends AbstractUnitTest {
throw new AssertionError(ex);
}
}
@Test
public void testIsCollectionAdmin() throws SQLException, AuthorizeException, IOException {
Community community = null;
EPerson eperson = null;
try {
context.turnOffAuthorisationSystem();
community = communityService.create(null, context);
Collection collection = collectionService.create(context, community);
eperson = ePersonService.create(context);
Group administrators = collectionService.createAdministrators(context, collection);
groupService.addMember(context, administrators, eperson);
context.commit();
Assert.assertTrue(authorizeService.isCollectionAdmin(context, eperson));
} finally {
if (community != null) {
communityService.delete(context, context.reloadEntity(community));
}
if (eperson != null) {
ePersonService.delete(context, context.reloadEntity(eperson));
}
context.restoreAuthSystemState();
}
}
@Test
public void testIsCollectionAdminReturnsTrueIfTheUserIsCommunityAdmin()
throws SQLException, AuthorizeException, IOException {
Community community = null;
EPerson eperson = null;
try {
context.turnOffAuthorisationSystem();
community = communityService.create(null, context);
eperson = ePersonService.create(context);
Group administrators = communityService.createAdministrators(context, community);
groupService.addMember(context, administrators, eperson);
context.commit();
Assert.assertTrue(authorizeService.isCollectionAdmin(context, eperson));
} finally {
if (community != null) {
communityService.delete(context, context.reloadEntity(community));
}
if (eperson != null) {
ePersonService.delete(context, context.reloadEntity(eperson));
}
context.restoreAuthSystemState();
}
}
//
// @Test
// public void testIsCollectionAdmin() throws SQLException, AuthorizeException, IOException {
//
// Community community = null;
// EPerson eperson = null;
//
// try {
//
// context.turnOffAuthorisationSystem();
//
// community = communityService.create(null, context);
// Collection collection = collectionService.create(context, community);
// eperson = ePersonService.create(context);
//
// Group administrators = collectionService.createAdministrators(context, collection);
// groupService.addMember(context, administrators, eperson);
// context.commit();
// context.setCurrentUser(eperson);
//
// Assert.assertTrue(authorizeService.isCollectionAdmin(context));
//
// } finally {
//
// if (community != null) {
// communityService.delete(context, context.reloadEntity(community));
// }
// if (eperson != null) {
// ePersonService.delete(context, context.reloadEntity(eperson));
// }
//
// context.restoreAuthSystemState();
// }
// }
//
// @Test
// public void testIsCollectionAdminReturnsTrueIfTheUserIsCommunityAdmin()
// throws SQLException, AuthorizeException, IOException {
//
// Community community = null;
// EPerson eperson = null;
//
// try {
//
// context.turnOffAuthorisationSystem();
//
// community = communityService.create(null, context);
// eperson = ePersonService.create(context);
//
// Group administrators = communityService.createAdministrators(context, community);
// groupService.addMember(context, administrators, eperson);
// context.setCurrentUser(eperson);
// context.commit();
//
// Assert.assertTrue(authorizeService.isCollectionAdmin(context));
//
// } finally {
//
// if (community != null) {
// communityService.delete(context, context.reloadEntity(community));
// }
// if (eperson != null) {
// ePersonService.delete(context, context.reloadEntity(eperson));
// }
//
// context.restoreAuthSystemState();
// }
// }
}

View File

@@ -95,8 +95,8 @@ public class ItemBuilder extends AbstractDSpaceObjectBuilder<Item> {
subject, authority, confidence);
}
public ItemBuilder withRelationshipType(final String relationshipType) {
return addMetadataValue(item, "relationship", "type", null, relationshipType);
public ItemBuilder withEntityType(final String entityType) {
return addMetadataValue(item, "dspace", "entity", "type", entityType);
}
public ItemBuilder withType(final String type) {

View File

@@ -180,8 +180,8 @@ public class WorkspaceItemBuilder extends AbstractBuilder<WorkspaceItem, Workspa
return addMetadataValue(MetadataSchemaEnum.DC.getName(),"description", "abstract", subject);
}
public WorkspaceItemBuilder withRelationshipType(final String relationshipType) {
return addMetadataValue("relationship", "type", null, relationshipType);
public WorkspaceItemBuilder withEntityType(final String entityType) {
return addMetadataValue("dspace", "entity", "type", entityType);
}
public WorkspaceItemBuilder grantLicense() {

View File

@@ -181,7 +181,7 @@ public class EntityServiceImplTest {
// Mock the state of objects utilized in getLeftRelationshipTypes()
// to meet the success criteria of the invocation
when(itemService.getMetadata(item, "relationship", "type", null, Item.ANY, false)).thenReturn(metsList);
when(itemService.getMetadata(item, "dspace", "entity", "type", Item.ANY, false)).thenReturn(metsList);
when(entity.getItem()).thenReturn(item);
when(entityService.getType(context, entity)).thenReturn(entityType);
when(relationshipTypeService.findByEntityType(context, entityService.getType(context, entity), true, -1, -1))
@@ -209,7 +209,7 @@ public class EntityServiceImplTest {
// Mock the state of objects utilized in getRightRelationshipTypes()
// to meet the success criteria of the invocation
when(itemService.getMetadata(item, "relationship", "type", null, Item.ANY, false)).thenReturn(metsList);
when(itemService.getMetadata(item, "dspace", "entity", "type", Item.ANY, false)).thenReturn(metsList);
when(entity.getItem()).thenReturn(item);
when(entityService.getType(context, entity)).thenReturn(entityType);
when(relationshipTypeService.findByEntityType(context, entityService.getType(context, entity), false, -1, -1))

View File

@@ -0,0 +1,100 @@
/**
* 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.content;
import java.sql.SQLException;
import org.dspace.AbstractUnitTest;
import org.dspace.authorize.AuthorizeException;
import org.dspace.content.factory.ContentServiceFactory;
import org.dspace.content.service.CollectionService;
import org.dspace.content.service.CommunityService;
import org.dspace.content.service.MetadataFieldService;
import org.junit.Assert;
import org.junit.Test;
/**
* Unit Tests for Performance of class MetadataField
*
* @author ben @ atmire . com
*/
public class MetadataFieldPerformanceTest extends AbstractUnitTest {
private final MetadataFieldService metadataFieldService =
ContentServiceFactory.getInstance().getMetadataFieldService();
private final CommunityService communityService = ContentServiceFactory.getInstance().getCommunityService();
private final CollectionService collectionService = ContentServiceFactory.getInstance().getCollectionService();
@Test
public void testManyQueries() throws SQLException {
long startTime = System.currentTimeMillis();
int amount = 50000;
for (int i = 0; i < amount; i++) {
metadataFieldService.findByElement(context, "dc", "description", null);
}
long endTime = System.currentTimeMillis();
long duration = (endTime - startTime);
double maxDurationPerCall = 0.01;
double maxDuration = maxDurationPerCall * amount;
//Duration is 0.05798 without performance improvements
//Duration is 0.0022 with performance improvements
Assert.assertTrue("Duration (" + duration + ") should be smaller than " + maxDuration +
" for " + amount + " tests." +
" Max of " + maxDurationPerCall + " ms per operation exceeded: " +
(((double) (duration)) / amount) + " ms.", duration < maxDuration);
}
@Test
public void testManyMetadataAdds() throws SQLException, AuthorizeException {
context.turnOffAuthorisationSystem();
Community owningCommunity = communityService.create(null, context);
Collection collection = collectionService.create(context, owningCommunity);
//we need to commit the changes so we don't block the table for testing
context.restoreAuthSystemState();
long startTime = System.currentTimeMillis();
int amount = 5000;
for (int i = 0; i < amount; i++) {
collectionService.addMetadata(context, collection,
"dc", "description", null, null, "Test " + i);
collectionService.clearMetadata(context, collection,
"dc", "description", null, null);
}
long endTime = System.currentTimeMillis();
long duration = (endTime - startTime);
double maxDurationPerCall = .3;
double maxDuration = maxDurationPerCall * amount;
//Duration is 1.542 without performance improvements
//Duration is 0.0538 with performance improvements
Assert.assertTrue("Duration (" + duration + ") should be smaller than " + maxDuration +
" for " + amount + " tests." +
" Max of " + maxDurationPerCall + " ms per operation exceeded: " +
(((double) (duration)) / amount) + " ms.", duration < maxDuration);
context.turnOffAuthorisationSystem();
// Delete community & collection created in init()
try {
collectionService.delete(context, collection);
} catch (Exception e) {
// ignore
}
try {
communityService.delete(context, owningCommunity);
} catch (Exception e) {
// ignore
}
context.restoreAuthSystemState();
}
}

View File

@@ -9,11 +9,13 @@ package org.dspace.content;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.sql.SQLException;
import java.util.List;
import java.util.stream.Collectors;
import org.dspace.AbstractIntegrationTestWithDatabase;
import org.dspace.authorize.AuthorizeException;
@@ -88,8 +90,8 @@ public class RelationshipMetadataServiceIT extends AbstractIntegrationTestWithDa
context.turnOffAuthorisationSystem();
EntityType publicationEntityType = EntityTypeBuilder.createEntityTypeBuilder(context, "Publication").build();
EntityType authorEntityType = EntityTypeBuilder.createEntityTypeBuilder(context, "Author").build();
leftItem = ItemBuilder.createItem(context, col).withRelationshipType("Publication").build();
rightItem = ItemBuilder.createItem(context, col).withRelationshipType("Author")
leftItem = ItemBuilder.createItem(context, col).withEntityType("Publication").build();
rightItem = ItemBuilder.createItem(context, col).withEntityType("Author")
.withPersonIdentifierLastName("familyName")
.withPersonIdentifierFirstName("firstName").build();
isAuthorOfPublicationRelationshipType =
@@ -112,8 +114,8 @@ public class RelationshipMetadataServiceIT extends AbstractIntegrationTestWithDa
context.turnOffAuthorisationSystem();
EntityType publicationEntityType = EntityTypeBuilder.createEntityTypeBuilder(context, "Publication").build();
EntityType authorEntityType = EntityTypeBuilder.createEntityTypeBuilder(context, "Author").build();
leftItem = ItemBuilder.createItem(context, col).withRelationshipType("Publication").build();
rightItem = ItemBuilder.createItem(context, col).withRelationshipType("Author")
leftItem = ItemBuilder.createItem(context, col).withEntityType("Publication").build();
rightItem = ItemBuilder.createItem(context, col).withEntityType("Author")
.withPersonIdentifierLastName("familyName")
.withPersonIdentifierFirstName("firstName").build();
RelationshipType isAuthorOfPublication =
@@ -136,9 +138,9 @@ public class RelationshipMetadataServiceIT extends AbstractIntegrationTestWithDa
EntityType journalIssueEntityType = EntityTypeBuilder.createEntityTypeBuilder(context, "JournalIssue").build();
EntityType publicationVolumeEntityType =
EntityTypeBuilder.createEntityTypeBuilder(context, "JournalVolume").build();
leftItem = ItemBuilder.createItem(context, col).withRelationshipType("JournalIssue")
leftItem = ItemBuilder.createItem(context, col).withEntityType("JournalIssue")
.withPublicationIssueNumber("2").build();
rightItem = ItemBuilder.createItem(context, col).withRelationshipType("JournalVolume")
rightItem = ItemBuilder.createItem(context, col).withEntityType("JournalVolume")
.withPublicationVolumeNumber("30").build();
RelationshipType isIssueOfVolume =
RelationshipTypeBuilder
@@ -186,13 +188,38 @@ public class RelationshipMetadataServiceIT extends AbstractIntegrationTestWithDa
public void testDeleteAuthorRelationshipCopyToLeftItem() throws Exception {
initPublicationAuthor();
context.turnOffAuthorisationSystem();
//verify the dc.contributor.author virtual metadata
List<MetadataValue> authorList = itemService.getMetadata(leftItem, "dc", "contributor", "author", Item.ANY);
assertThat(authorList.size(), equalTo(1));
//verify the dc.contributor.author actual metadata
List<MetadataValue> plainMetadataAuthorList = leftItem.getMetadata().stream()
.filter(metadataValue -> metadataValue.getMetadataField().getQualifier() != null &&
metadataValue.getMetadataField().getQualifier().equals("author"))
.collect(Collectors.toList());
assertThat(plainMetadataAuthorList.size(), equalTo(0));
//verify there's no relation.isAuthorOfPublication actual metadata
List<MetadataValue> plainRelationshipMetadataList = leftItem.getMetadata().stream()
.filter(metadataValue -> metadataValue.getMetadataField().getElement().equals("isAuthorOfPublication"))
.collect(Collectors.toList());
assertThat(plainRelationshipMetadataList.size(), equalTo(0));
//delete the relationship, copying the virtual metadata to actual metadata on the leftItem
//leftItem is the publication
relationshipService.delete(context, relationship, true, false);
context.restoreAuthSystemState();
//verify the dc.contributor.author actual metadata
List<MetadataValue> authorList = itemService.getMetadata(leftItem, "dc", "contributor", "author", Item.ANY);
plainMetadataAuthorList = leftItem.getMetadata().stream()
.filter(metadataValue -> metadataValue.getMetadataField().getQualifier() != null &&
metadataValue.getMetadataField().getQualifier().equals("author"))
.collect(Collectors.toList());
assertThat(plainMetadataAuthorList.size(), equalTo(1));
//verify the dc.contributor.author actual metadata
authorList = itemService.getMetadata(leftItem, "dc", "contributor", "author", Item.ANY);
assertThat(authorList.size(), equalTo(1));
assertThat(authorList.get(0).getValue(), equalTo("familyName, firstName"));
assertThat(authorList.get(0).getMetadataField().getMetadataSchema().getName(), equalTo("dc"));
@@ -200,10 +227,15 @@ public class RelationshipMetadataServiceIT extends AbstractIntegrationTestWithDa
assertThat(authorList.get(0).getMetadataField().getQualifier(), equalTo("author"));
assertNull(authorList.get(0).getAuthority());
//verify there's no relation.isAuthorOfPublication actual metadata
//verify there's relation.isAuthorOfPublication actual metadata
plainRelationshipMetadataList = leftItem.getMetadata().stream()
.filter(metadataValue -> metadataValue.getMetadataField().getElement().equals("isAuthorOfPublication"))
.collect(Collectors.toList());
assertThat(plainRelationshipMetadataList.size(), equalTo(1));
//verify there's relation.isAuthorOfPublication actual metadata
List<MetadataValue> relationshipMetadataList = itemService
.getMetadata(leftItem, MetadataSchemaEnum.RELATION.getName(), "isAuthorOfPublication", null, Item.ANY);
assertThat(relationshipMetadataList.size(), equalTo(0));
assertThat(relationshipMetadataList.size(), equalTo(1));
//request the virtual metadata of the publication only
List<RelationshipMetadataValue> list = relationshipMetadataService.getRelationshipMetadata(leftItem, true);
@@ -227,18 +259,50 @@ public class RelationshipMetadataServiceIT extends AbstractIntegrationTestWithDa
List<MetadataValue> relationshipMetadataList = itemService
.getMetadata(leftItem, MetadataSchemaEnum.RELATION.getName(), "isAuthorOfPublication", null, Item.ANY);
assertThat(relationshipMetadataList.size(), equalTo(0));
//verify there's relation.isPublicationOfAuthor actual metadata on the author
assertThat(rightItem.getMetadata().stream()
.filter(metadataValue -> metadataValue.getMetadataField().getElement().equals("isPublicationOfAuthor"))
.collect(Collectors.toList()).size(), equalTo(1));
assertThat(itemService
.getMetadata(rightItem, MetadataSchemaEnum.RELATION.getName(), "isPublicationOfAuthor", null, Item.ANY)
.size(), equalTo(1));
}
@Test
public void testDeleteAuthorRelationshipCopyToBothItems() throws Exception {
initPublicationAuthor();
context.turnOffAuthorisationSystem();
//verify the dc.contributor.author virtual metadata
List<MetadataValue> authorList = itemService.getMetadata(leftItem, "dc", "contributor", "author", Item.ANY);
assertThat(authorList.size(), equalTo(1));
//verify the dc.contributor.author actual metadata
List<MetadataValue> plainMetadataAuthorList = leftItem.getMetadata().stream()
.filter(metadataValue -> metadataValue.getMetadataField().getQualifier() != null &&
metadataValue.getMetadataField().getQualifier().equals("author"))
.collect(Collectors.toList());
assertThat(plainMetadataAuthorList.size(), equalTo(0));
//verify there's no relation.isAuthorOfPublication actual metadata
List<MetadataValue> plainRelationshipMetadataList = leftItem.getMetadata().stream()
.filter(metadataValue -> metadataValue.getMetadataField().getElement().equals("isAuthorOfPublication"))
.collect(Collectors.toList());
assertThat(plainRelationshipMetadataList.size(), equalTo(0));
//delete the relationship, copying the virtual metadata to actual metadata on the both items
relationshipService.delete(context, relationship, true, true);
context.restoreAuthSystemState();
//verify the dc.contributor.author actual metadata
List<MetadataValue> authorList = itemService.getMetadata(leftItem, "dc", "contributor", "author", Item.ANY);
plainMetadataAuthorList = leftItem.getMetadata().stream()
.filter(metadataValue -> metadataValue.getMetadataField().getQualifier() != null &&
metadataValue.getMetadataField().getQualifier().equals("author"))
.collect(Collectors.toList());
assertThat(plainMetadataAuthorList.size(), equalTo(1));
//verify the dc.contributor.author actual metadata
authorList = itemService.getMetadata(leftItem, "dc", "contributor", "author", Item.ANY);
assertThat(authorList.size(), equalTo(1));
assertThat(authorList.get(0).getValue(), equalTo("familyName, firstName"));
assertThat(authorList.get(0).getMetadataField().getMetadataSchema().getName(), equalTo("dc"));
@@ -246,10 +310,21 @@ public class RelationshipMetadataServiceIT extends AbstractIntegrationTestWithDa
assertThat(authorList.get(0).getMetadataField().getQualifier(), equalTo("author"));
assertNull(authorList.get(0).getAuthority());
//verify there's no relation.isAuthorOfPublication actual metadata
List<MetadataValue> relationshipMetadataList = itemService
.getMetadata(leftItem, MetadataSchemaEnum.RELATION.getName(), "isAuthorOfPublication", null, Item.ANY);
assertThat(relationshipMetadataList.size(), equalTo(0));
//verify there's relation.isPublicationOfAuthor actual metadata
assertEquals(1, rightItem.getMetadata().stream()
.filter(metadataValue -> metadataValue.getMetadataField().getElement().equals("isPublicationOfAuthor"))
.collect(Collectors.toList()).size());
assertEquals(1, itemService
.getMetadata(rightItem, MetadataSchemaEnum.RELATION.getName(), "isPublicationOfAuthor", null, Item.ANY)
.size());
//verify there's relation.isAuthorOfPublication actual metadata
assertEquals(1, leftItem.getMetadata().stream()
.filter(metadataValue -> metadataValue.getMetadataField().getElement().equals("isAuthorOfPublication"))
.collect(Collectors.toList()).size());
assertEquals(1, itemService
.getMetadata(leftItem, MetadataSchemaEnum.RELATION.getName(), "isAuthorOfPublication", null, Item.ANY)
.size());
}
@Test
@@ -369,13 +444,38 @@ public class RelationshipMetadataServiceIT extends AbstractIntegrationTestWithDa
public void testDeleteAuthorRelationshipCopyToLeftItemFromDefaultInDb() throws Exception {
initPublicationAuthorWithCopyParams(true, false);
context.turnOffAuthorisationSystem();
//verify the dc.contributor.author virtual metadata
List<MetadataValue> authorList = itemService.getMetadata(leftItem, "dc", "contributor", "author", Item.ANY);
assertThat(authorList.size(), equalTo(1));
//verify the dc.contributor.author actual metadata
List<MetadataValue> plainMetadataAuthorList = leftItem.getMetadata().stream()
.filter(metadataValue -> metadataValue.getMetadataField().getQualifier() != null &&
metadataValue.getMetadataField().getQualifier().equals("author"))
.collect(Collectors.toList());
assertThat(plainMetadataAuthorList.size(), equalTo(0));
//verify there's no relation.isAuthorOfPublication actual metadata
List<MetadataValue> plainRelationshipMetadataList = leftItem.getMetadata().stream()
.filter(metadataValue -> metadataValue.getMetadataField().getElement().equals("isAuthorOfPublication"))
.collect(Collectors.toList());
assertThat(plainRelationshipMetadataList.size(), equalTo(0));
//delete the relationship, copying the virtual metadata to actual metadata on the leftItem
//leftItem is the publication
relationshipService.delete(context, relationship);
context.restoreAuthSystemState();
//verify the dc.contributor.author actual metadata
List<MetadataValue> authorList = itemService.getMetadata(leftItem, "dc", "contributor", "author", Item.ANY);
plainMetadataAuthorList = leftItem.getMetadata().stream()
.filter(metadataValue -> metadataValue.getMetadataField().getQualifier() != null &&
metadataValue.getMetadataField().getQualifier().equals("author"))
.collect(Collectors.toList());
assertThat(plainMetadataAuthorList.size(), equalTo(1));
//verify the dc.contributor.author actual metadata
authorList = itemService.getMetadata(leftItem, "dc", "contributor", "author", Item.ANY);
assertThat(authorList.size(), equalTo(1));
assertThat(authorList.get(0).getValue(), equalTo("familyName, firstName"));
assertThat(authorList.get(0).getMetadataField().getMetadataSchema().getName(), equalTo("dc"));
@@ -383,10 +483,15 @@ public class RelationshipMetadataServiceIT extends AbstractIntegrationTestWithDa
assertThat(authorList.get(0).getMetadataField().getQualifier(), equalTo("author"));
assertNull(authorList.get(0).getAuthority());
//verify there's no relation.isAuthorOfPublication actual metadata
//verify there's relation.isAuthorOfPublication actual metadata
plainRelationshipMetadataList = leftItem.getMetadata().stream()
.filter(metadataValue -> metadataValue.getMetadataField().getElement().equals("isAuthorOfPublication"))
.collect(Collectors.toList());
assertThat(plainRelationshipMetadataList.size(), equalTo(1));
//verify there's relation.isAuthorOfPublication actual metadata
List<MetadataValue> relationshipMetadataList = itemService
.getMetadata(leftItem, MetadataSchemaEnum.RELATION.getName(), "isAuthorOfPublication", null, Item.ANY);
assertThat(relationshipMetadataList.size(), equalTo(0));
assertThat(relationshipMetadataList.size(), equalTo(1));
//request the virtual metadata of the publication only
List<RelationshipMetadataValue> list = relationshipMetadataService.getRelationshipMetadata(leftItem, true);
@@ -410,18 +515,50 @@ public class RelationshipMetadataServiceIT extends AbstractIntegrationTestWithDa
List<MetadataValue> relationshipMetadataList = itemService
.getMetadata(leftItem, MetadataSchemaEnum.RELATION.getName(), "isAuthorOfPublication", null, Item.ANY);
assertThat(relationshipMetadataList.size(), equalTo(0));
//verify there's relation.isPublicationOfAuthor actual metadata on the author
assertThat(rightItem.getMetadata().stream()
.filter(metadataValue -> metadataValue.getMetadataField().getElement().equals("isPublicationOfAuthor"))
.collect(Collectors.toList()).size(), equalTo(1));
assertThat(itemService
.getMetadata(rightItem, MetadataSchemaEnum.RELATION.getName(), "isPublicationOfAuthor", null, Item.ANY)
.size(), equalTo(1));
}
@Test
public void testDeleteAuthorRelationshipCopyToBothItemsFromDefaultsInDb() throws Exception {
initPublicationAuthorWithCopyParams(true, true);
context.turnOffAuthorisationSystem();
//verify the dc.contributor.author virtual metadata
List<MetadataValue> authorList = itemService.getMetadata(leftItem, "dc", "contributor", "author", Item.ANY);
assertThat(authorList.size(), equalTo(1));
//verify the dc.contributor.author actual metadata
List<MetadataValue> plainMetadataAuthorList = leftItem.getMetadata().stream()
.filter(metadataValue -> metadataValue.getMetadataField().getQualifier() != null &&
metadataValue.getMetadataField().getQualifier().equals("author"))
.collect(Collectors.toList());
assertThat(plainMetadataAuthorList.size(), equalTo(0));
//verify there's no relation.isAuthorOfPublication actual metadata
List<MetadataValue> plainRelationshipMetadataList = leftItem.getMetadata().stream()
.filter(metadataValue -> metadataValue.getMetadataField().getElement().equals("isAuthorOfPublication"))
.collect(Collectors.toList());
assertThat(plainRelationshipMetadataList.size(), equalTo(0));
//delete the relationship, copying the virtual metadata to actual metadata on the both items
relationshipService.delete(context, relationship);
context.restoreAuthSystemState();
//verify the dc.contributor.author actual metadata
List<MetadataValue> authorList = itemService.getMetadata(leftItem, "dc", "contributor", "author", Item.ANY);
plainMetadataAuthorList = leftItem.getMetadata().stream()
.filter(metadataValue -> metadataValue.getMetadataField().getQualifier() != null &&
metadataValue.getMetadataField().getQualifier().equals("author"))
.collect(Collectors.toList());
assertThat(plainMetadataAuthorList.size(), equalTo(1));
//verify the dc.contributor.author actual metadata
authorList = itemService.getMetadata(leftItem, "dc", "contributor", "author", Item.ANY);
assertThat(authorList.size(), equalTo(1));
assertThat(authorList.get(0).getValue(), equalTo("familyName, firstName"));
assertThat(authorList.get(0).getMetadataField().getMetadataSchema().getName(), equalTo("dc"));
@@ -429,10 +566,20 @@ public class RelationshipMetadataServiceIT extends AbstractIntegrationTestWithDa
assertThat(authorList.get(0).getMetadataField().getQualifier(), equalTo("author"));
assertNull(authorList.get(0).getAuthority());
//verify there's no relation.isAuthorOfPublication actual metadata
List<MetadataValue> relationshipMetadataList = itemService
.getMetadata(leftItem, MetadataSchemaEnum.RELATION.getName(), "isAuthorOfPublication", null, Item.ANY);
assertThat(relationshipMetadataList.size(), equalTo(0));
//verify there's relation.isAuthorOfPublication actual metadata on the publication
assertThat(leftItem.getMetadata().stream()
.filter(metadataValue -> metadataValue.getMetadataField().getElement().equals("isAuthorOfPublication"))
.collect(Collectors.toList()).size(), equalTo(1));
assertThat(itemService
.getMetadata(leftItem, MetadataSchemaEnum.RELATION.getName(), "isAuthorOfPublication", null, Item.ANY)
.size(), equalTo(1));
//verify there's relation.isPublicationOfAuthor actual metadata on the author
assertThat(rightItem.getMetadata().stream()
.filter(metadataValue -> metadataValue.getMetadataField().getElement().equals("isPublicationOfAuthor"))
.collect(Collectors.toList()).size(), equalTo(1));
assertThat(itemService
.getMetadata(rightItem, MetadataSchemaEnum.RELATION.getName(), "isPublicationOfAuthor", null, Item.ANY)
.size(), equalTo(1));
}
@Test
@@ -446,7 +593,7 @@ public class RelationshipMetadataServiceIT extends AbstractIntegrationTestWithDa
Community community = CommunityBuilder.createCommunity(context).build();
Collection col = CollectionBuilder.createCollection(context, community).build();
Item secondItem = ItemBuilder.createItem(context, col).withRelationshipType("Publication").build();
Item secondItem = ItemBuilder.createItem(context, col).withEntityType("Publication").build();
RelationshipBuilder.createRelationshipBuilder(context, secondItem, rightItem,
isAuthorOfPublicationRelationshipType).build();
context.restoreAuthSystemState();
@@ -465,7 +612,7 @@ public class RelationshipMetadataServiceIT extends AbstractIntegrationTestWithDa
Community community = CommunityBuilder.createCommunity(context).build();
Collection col = CollectionBuilder.createCollection(context, community).build();
Item secondAuthor = ItemBuilder.createItem(context, col).withRelationshipType("Author")
Item secondAuthor = ItemBuilder.createItem(context, col).withEntityType("Author")
.withPersonIdentifierFirstName("firstName")
.withPersonIdentifierLastName("familyName").build();
@@ -505,13 +652,13 @@ public class RelationshipMetadataServiceIT extends AbstractIntegrationTestWithDa
Community community = CommunityBuilder.createCommunity(context).build();
Collection collection = CollectionBuilder.createCollection(context, community).build();
Item journalIssue = ItemBuilder.createItem(context, collection).withRelationshipType("JournalIssue").build();
Item journalIssue = ItemBuilder.createItem(context, collection).withEntityType("JournalIssue").build();
Item journalVolume = ItemBuilder.createItem(context, collection)
.withPublicationVolumeNumber("30")
.withRelationshipType("JournalVolume").build();
.withEntityType("JournalVolume").build();
Item journal = ItemBuilder.createItem(context, collection)
.withMetadata("creativeworkseries", "issn", null, "issn journal")
.withRelationshipType("Journal").build();
.withEntityType("Journal").build();
RelationshipBuilder.createRelationshipBuilder(context, journalIssue, journalVolume,
isJournalVolumeOfIssueRelationshipType).build();
RelationshipBuilder.createRelationshipBuilder(context, journalVolume, journal,
@@ -519,7 +666,7 @@ public class RelationshipMetadataServiceIT extends AbstractIntegrationTestWithDa
Item publication = ItemBuilder.createItem(context, collection)
.withTitle("Pub 1")
.withRelationshipType("Publication").build();
.withEntityType("Publication").build();
RelationshipBuilder.createRelationshipBuilder(context, publication, journalIssue,
isJournalIssueOfPublicationRelationshipType).build();

View File

@@ -77,10 +77,10 @@ public class RelationshipServiceImplPlaceTest extends AbstractUnitTest {
WorkspaceItem authorIs = workspaceItemService.create(context, col, false);
item = installItemService.installItem(context, is);
itemService.addMetadata(context, item, "relationship", "type", null, null, "Publication");
itemService.addMetadata(context, item, "dspace", "entity", "type", null, "Publication");
authorItem = installItemService.installItem(context, authorIs);
itemService.addMetadata(context, authorItem, "relationship", "type", null, null, "Person");
itemService.addMetadata(context, authorItem, "dspace", "entity", "type", null, "Person");
itemService.addMetadata(context, authorItem, "person", "familyName", null, null, "familyName");
itemService.addMetadata(context, authorItem, "person", "givenName", null, null, "firstName");
@@ -156,7 +156,7 @@ public class RelationshipServiceImplPlaceTest extends AbstractUnitTest {
// Here we create an Item so that we can create another relationship with this item
WorkspaceItem authorIs = workspaceItemService.create(context, col, false);
Item secondAuthorItem = installItemService.installItem(context, authorIs);
itemService.addMetadata(context, secondAuthorItem, "relationship", "type", null, null, "Person");
itemService.addMetadata(context, secondAuthorItem, "dspace", "entity", "type", null, "Person");
itemService.addMetadata(context, secondAuthorItem, "person", "familyName", null, null, "familyNameTwo");
itemService.addMetadata(context, secondAuthorItem, "person", "givenName", null, null, "firstNameTwo");
Relationship relationshipTwo = relationshipService
@@ -222,7 +222,7 @@ public class RelationshipServiceImplPlaceTest extends AbstractUnitTest {
// Relationship a specific place as well
WorkspaceItem authorIs = workspaceItemService.create(context, col, false);
Item secondAuthorItem = installItemService.installItem(context, authorIs);
itemService.addMetadata(context, secondAuthorItem, "relationship", "type", null, null, "Person");
itemService.addMetadata(context, secondAuthorItem, "dspace", "entity", "type", null, "Person");
itemService.addMetadata(context, secondAuthorItem, "person", "familyName", null, null, "familyNameTwo");
itemService.addMetadata(context, secondAuthorItem, "person", "givenName", null, null, "firstNameTwo");
Relationship relationshipTwo = relationshipService
@@ -334,7 +334,7 @@ public class RelationshipServiceImplPlaceTest extends AbstractUnitTest {
// Create an additional item for another relationship
WorkspaceItem authorIs = workspaceItemService.create(context, col, false);
Item secondAuthorItem = installItemService.installItem(context, authorIs);
itemService.addMetadata(context, secondAuthorItem, "relationship", "type", null, null, "Person");
itemService.addMetadata(context, secondAuthorItem, "dspace", "entity", "type", null, "Person");
itemService.addMetadata(context, secondAuthorItem, "person", "familyName", null, null, "familyNameTwo");
itemService.addMetadata(context, secondAuthorItem, "person", "givenName", null, null, "firstNameTwo");
Relationship relationshipTwo = relationshipService

View File

@@ -227,8 +227,8 @@ public class RelationshipServiceImplTest {
when(metsList.get(0).getValue()).thenReturn("Entitylabel");
when(relationshipService
.findByItemAndRelationshipType(context, leftItem, testRel, true)).thenReturn(leftTypelist);
when(itemService.getMetadata(leftItem, "relationship", "type", null, Item.ANY, false)).thenReturn(metsList);
when(itemService.getMetadata(rightItem, "relationship", "type", null, Item.ANY, false)).thenReturn(metsList);
when(itemService.getMetadata(leftItem, "dspace", "entity", "type", Item.ANY, false)).thenReturn(metsList);
when(itemService.getMetadata(rightItem, "dspace", "entity", "type", Item.ANY, false)).thenReturn(metsList);
when(relationshipDAO.create(any(), any())).thenReturn(relationship);
// The reported Relationship should match our defined relationship
@@ -305,8 +305,8 @@ public class RelationshipServiceImplTest {
relationship = getRelationship(leftItem, rightItem, testRel, 0,0);
// Mock the state of objects utilized in update() to meet the success criteria of the invocation
when(itemService.getMetadata(leftItem, "relationship", "type", null, Item.ANY, false)).thenReturn(metsList);
when(itemService.getMetadata(rightItem, "relationship", "type", null, Item.ANY, false)).thenReturn(metsList);
when(itemService.getMetadata(leftItem, "dspace", "entity", "type", Item.ANY, false)).thenReturn(metsList);
when(itemService.getMetadata(rightItem, "dspace", "entity", "type", Item.ANY, false)).thenReturn(metsList);
when(authorizeService.authorizeActionBoolean(context, relationship.getLeftItem(),
Constants.WRITE)).thenReturn(true);

View File

@@ -87,8 +87,8 @@ public class RelationshipDAOImplTest extends AbstractIntegrationTest {
WorkspaceItem workspaceItemTwo = workspaceItemService.create(context, collection, false);
itemOne = installItemService.installItem(context, workspaceItem);
itemTwo = installItemService.installItem(context, workspaceItemTwo);
itemService.addMetadata(context, itemOne, "relationship", "type", null, Item.ANY, "Publication");
itemService.addMetadata(context, itemTwo, "relationship", "type", null, Item.ANY, "Person");
itemService.addMetadata(context, itemOne, "dspace", "entity", "type", Item.ANY, "Publication");
itemService.addMetadata(context, itemTwo, "dspace", "entity", "type", Item.ANY, "Person");
itemService.update(context, itemOne);
itemService.update(context, itemTwo);
entityTypeOne = entityTypeService.create(context, "Person");

View File

@@ -82,8 +82,8 @@ public class RelationshipTypeDAOImplTest extends AbstractIntegrationTest {
WorkspaceItem workspaceItemTwo = workspaceItemService.create(context, collection, false);
itemOne = installItemService.installItem(context, workspaceItem);
itemTwo = installItemService.installItem(context, workspaceItemTwo);
itemService.addMetadata(context, itemOne, "relationship", "type", null, Item.ANY, "Publication");
itemService.addMetadata(context, itemTwo, "relationship", "type", null, Item.ANY, "Person");
itemService.addMetadata(context, itemOne, "dspace", "entity", "type", Item.ANY, "Publication");
itemService.addMetadata(context, itemTwo, "dspace", "entity", "type", Item.ANY, "Person");
itemService.update(context, itemOne);
itemService.update(context, itemTwo);
entityTypeOne = entityTypeService.create(context, "Person");

View File

@@ -0,0 +1,106 @@
/**
* 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.content.service;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import org.dspace.AbstractUnitTest;
import org.dspace.content.MetadataField;
import org.dspace.content.MetadataSchema;
import org.dspace.content.factory.ContentServiceFactory;
import org.dspace.core.Context;
import org.junit.Test;
public class MetadataFieldServiceTest extends AbstractUnitTest {
private MetadataFieldService metadataFieldService =
ContentServiceFactory.getInstance().getMetadataFieldService();
private MetadataSchemaService metadataSchemaService =
ContentServiceFactory.getInstance().getMetadataSchemaService();
@Test
public void testMetadataFieldCaching() throws Exception {
MetadataField subjectField = metadataFieldService.findByElement(context, "dc", "subject", null);
MetadataField issnField = metadataFieldService.findByElement(context, "dc", "identifier", "issn");
MetadataSchema dspaceSchema = metadataSchemaService.find(context, "dspace");
subjectField.setMetadataSchema(dspaceSchema);
issnField.setMetadataSchema(dspaceSchema);
// Searching for dspace.subject and dspace.identifier.issn should return the already stored metadatafields
assertEquals(
subjectField,
metadataFieldService.findByElement(context, "dspace", "subject", null)
);
assertEquals(
issnField,
metadataFieldService.findByElement(context, "dspace", "identifier", "issn")
);
// The dspace.subject and dspace.identifier.issn metadatafields should now reference the 'dspace' metadataschema
assertEquals(
"dspace",
metadataFieldService
.findByElement(context, "dspace", "subject", null)
.getMetadataSchema()
.getName()
);
assertEquals(
"dspace",
metadataFieldService
.findByElement(context, "dspace", "identifier", "issn")
.getMetadataSchema()
.getName()
);
// Metadatafields dc.subject and dc.identifier.issn should no longer be found
assertNull(
metadataFieldService.findByElement(context, "dc", "subject", null)
);
assertNull(
metadataFieldService.findByElement(context, "dc", "identifier", "issn")
);
// Same tests, new context
context.complete();
context = new Context();
assertEquals(
subjectField,
metadataFieldService.findByElement(context, "dspace", "subject", null)
);
assertEquals(
issnField,
metadataFieldService.findByElement(context, "dspace", "identifier", "issn")
);
assertEquals(
"dspace",
metadataFieldService
.findByElement(context, "dspace", "subject", null)
.getMetadataSchema()
.getName()
);
assertEquals(
"dspace",
metadataFieldService
.findByElement(context, "dspace", "identifier", "issn")
.getMetadataSchema()
.getName()
);
assertNull(
metadataFieldService.findByElement(context, "dc", "subject", null)
);
assertNull(
metadataFieldService.findByElement(context, "dc", "identifier", "issn")
);
}
}

View File

@@ -27,6 +27,9 @@ import org.dspace.content.Collection;
import org.dspace.content.Community;
import org.dspace.content.Item;
import org.dspace.content.WorkspaceItem;
import org.dspace.content.authority.Choices;
import org.dspace.content.authority.factory.ContentAuthorityServiceFactory;
import org.dspace.content.authority.service.MetadataAuthorityService;
import org.dspace.content.factory.ContentServiceFactory;
import org.dspace.content.service.ItemService;
import org.dspace.content.service.WorkspaceItemService;
@@ -36,6 +39,7 @@ import org.dspace.discovery.indexobject.IndexablePoolTask;
import org.dspace.discovery.indexobject.IndexableWorkflowItem;
import org.dspace.discovery.indexobject.IndexableWorkspaceItem;
import org.dspace.eperson.EPerson;
import org.dspace.services.ConfigurationService;
import org.dspace.services.factory.DSpaceServicesFactory;
import org.dspace.workflow.WorkflowException;
import org.dspace.xmlworkflow.WorkflowConfigurationException;
@@ -73,6 +77,10 @@ public class DiscoveryIT extends AbstractIntegrationTestWithDatabase {
.getServiceByName(IndexingService.class.getName(),
IndexingService.class);
ConfigurationService configurationService = DSpaceServicesFactory.getInstance().getConfigurationService();
MetadataAuthorityService metadataAuthorityService = ContentAuthorityServiceFactory.getInstance()
.getMetadataAuthorityService();
@Test
public void solrRecordsAfterDepositOrDeletionOfWorkspaceItemTest() throws Exception {
@@ -273,6 +281,41 @@ public class DiscoveryIT extends AbstractIntegrationTestWithDatabase {
}
@Test
public void solrRecordFromMessyItemTest() throws Exception {
configurationService.setProperty("authority.controlled.dc.subject", "true");
metadataAuthorityService.clearCache();
try {
context.turnOffAuthorisationSystem();
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community").build();
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity)
.withName("Collection 1").build();
context.restoreAuthSystemState();
assertSearchQuery(IndexableItem.TYPE, 0);
context.turnOffAuthorisationSystem();
ItemBuilder.createItem(context, col1)
.withTitle("Public item 1")
.withIssueDate("2021-01-21")
.withAuthor("Smith, Donald")
.withSubject("Test Value", "NOT-EXISTING", Choices.CF_ACCEPTED)
.build();
context.restoreAuthSystemState();
assertSearchQuery(IndexableItem.TYPE, 1);
} finally {
configurationService.setProperty("authority.controlled.dc.subject", "false");
metadataAuthorityService.clearCache();
}
}
private void assertSearchQuery(String resourceType, int size) throws SearchServiceException {
DiscoverQuery discoverQuery = new DiscoverQuery();
discoverQuery.setQuery("*:*");

View File

@@ -123,14 +123,14 @@ public class ITIrusExportUsageEventListener extends AbstractIntegrationTestWithD
community = CommunityBuilder.createCommunity(context).build();
collection = CollectionBuilder.createCollection(context, community).build();
item = ItemBuilder.createItem(context, collection)
.withRelationshipType(entityType.getLabel())
.withEntityType(entityType.getLabel())
.build();
File f = new File(testProps.get("test.bitstream").toString());
bitstream = BitstreamBuilder.createBitstream(context, item, new FileInputStream(f)).build();
itemNotToBeProcessed = ItemBuilder.createItem(context, collection)
.withRelationshipType(entityType.getLabel())
.withEntityType(entityType.getLabel())
.withType("Excluded type")
.build();
File itemNotToBeProcessedFile = new File(testProps.get("test.bitstream").toString());
@@ -263,8 +263,8 @@ public class ITIrusExportUsageEventListener extends AbstractIntegrationTestWithD
when(usageEvent.getRequest()).thenReturn(request);
when(usageEvent.getContext()).thenReturn(new Context());
itemService.clearMetadata(context, item, "relationship", "type", null, Item.ANY);
itemService.addMetadata(context, item, "relationship", "type", null, null, "OrgUnit");
itemService.clearMetadata(context, item, "dspace", "entity", "type", Item.ANY);
itemService.addMetadata(context, item, "dspace", "entity", "type", null, "OrgUnit");
itemService.update(context, item);
context.restoreAuthSystemState();
@@ -359,8 +359,8 @@ public class ITIrusExportUsageEventListener extends AbstractIntegrationTestWithD
when(usageEvent.getRequest()).thenReturn(request);
when(usageEvent.getContext()).thenReturn(new Context());
itemService.clearMetadata(context, item, "relationship", "type", null, Item.ANY);
itemService.addMetadata(context, item, "relationship", "type", null, null, "OrgUnit");
itemService.clearMetadata(context, item, "dspace", "entity", "type", Item.ANY);
itemService.addMetadata(context, item, "dspace", "entity", "type", null, "OrgUnit");
itemService.update(context, item);
context.restoreAuthSystemState();

View File

@@ -135,7 +135,7 @@ public class ExportEventProcessorIT extends AbstractIntegrationTestWithDatabase
context.turnOffAuthorisationSystem();
Community community = CommunityBuilder.createCommunity(context).build();
Collection collection = CollectionBuilder.createCollection(context, community).build();
Item item = ItemBuilder.createItem(context, collection).withRelationshipType(otherEntity.getLabel()).build();
Item item = ItemBuilder.createItem(context, collection).withEntityType(otherEntity.getLabel()).build();
context.restoreAuthSystemState();
context.setCurrentUser(admin);
@@ -157,7 +157,7 @@ public class ExportEventProcessorIT extends AbstractIntegrationTestWithDatabase
Collection collection = CollectionBuilder.createCollection(context, community).build();
Item item = ItemBuilder.createItem(context, collection)
.withType("Excluded type")
.withRelationshipType(publication.getLabel())
.withEntityType(publication.getLabel())
.build();
context.restoreAuthSystemState();
@@ -177,7 +177,7 @@ public class ExportEventProcessorIT extends AbstractIntegrationTestWithDatabase
context.turnOffAuthorisationSystem();
Community community = CommunityBuilder.createCommunity(context).build();
Collection collection = CollectionBuilder.createCollection(context, community).build();
Item item = ItemBuilder.createItem(context, collection).withRelationshipType(otherEntity.getLabel()).build();
Item item = ItemBuilder.createItem(context, collection).withEntityType(otherEntity.getLabel()).build();
context.restoreAuthSystemState();
ExportEventProcessor exportEventProcessor = new ItemEventProcessor(context, request, item);
@@ -195,7 +195,7 @@ public class ExportEventProcessorIT extends AbstractIntegrationTestWithDatabase
context.turnOffAuthorisationSystem();
Community community = CommunityBuilder.createCommunity(context).build();
Collection collection = CollectionBuilder.createCollection(context, community).build();
Item item = ItemBuilder.createItem(context, collection).withRelationshipType(publication.getLabel()).build();
Item item = ItemBuilder.createItem(context, collection).withEntityType(publication.getLabel()).build();
context.restoreAuthSystemState();
ExportEventProcessor exportEventProcessor = new ItemEventProcessor(context, request, item);
@@ -214,7 +214,7 @@ public class ExportEventProcessorIT extends AbstractIntegrationTestWithDatabase
context.turnOffAuthorisationSystem();
Community community = CommunityBuilder.createCommunity(context).build();
Collection collection = CollectionBuilder.createCollection(context, community).build();
Item item = ItemBuilder.createItem(context, collection).withRelationshipType(publication.getLabel()).build();
Item item = ItemBuilder.createItem(context, collection).withEntityType(publication.getLabel()).build();
context.restoreAuthSystemState();
ExportEventProcessor exportEventProcessor = new ItemEventProcessor(context, request, item);
@@ -232,7 +232,7 @@ public class ExportEventProcessorIT extends AbstractIntegrationTestWithDatabase
context.turnOffAuthorisationSystem();
Community community = CommunityBuilder.createCommunity(context).build();
Collection collection = CollectionBuilder.createCollection(context, community).build();
Item item = ItemBuilder.createItem(context, collection).withRelationshipType(otherEntity.getLabel()).build();
Item item = ItemBuilder.createItem(context, collection).withEntityType(otherEntity.getLabel()).build();
context.restoreAuthSystemState();
ExportEventProcessor exportEventProcessor = new ItemEventProcessor(context, request, item);

View File

@@ -0,0 +1,55 @@
/**
* 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.authorization.impl;
import java.sql.SQLException;
import org.dspace.app.rest.authorization.AuthorizationFeature;
import org.dspace.app.rest.authorization.AuthorizationFeatureDocumentation;
import org.dspace.app.rest.model.BaseObjectRest;
import org.dspace.app.rest.model.SiteRest;
import org.dspace.authorize.service.AuthorizeService;
import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* The Collection Admin feature. It can be used to verify if the current user is admin of any collection in the site.
*
* Authorization is granted if the current user has ADMIN permissions for any Collection anywhere in the site, or if the
* current user is a site admin.
*/
@Component
@AuthorizationFeatureDocumentation(name = CollectionAdminFeature.NAME,
description = "It can be used to verify if the current user is admin of any collection in the site")
public class CollectionAdminFeature implements AuthorizationFeature {
public final static String NAME = "isCollectionAdmin";
@Autowired
private AuthorizeService authorizeService;
@Override
public boolean isAuthorized(Context context, BaseObjectRest object) throws SQLException {
if (object instanceof SiteRest) {
if (authorizeService.isAdmin(context)) {
return true;
}
return authorizeService.isCollectionAdmin(context);
}
return false;
}
@Override
public String[] getSupportedTypes() {
return new String[]{
SiteRest.CATEGORY + "." + SiteRest.NAME
};
}
}

View File

@@ -0,0 +1,56 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest.authorization.impl;
import java.sql.SQLException;
import org.dspace.app.rest.authorization.AuthorizationFeature;
import org.dspace.app.rest.authorization.AuthorizationFeatureDocumentation;
import org.dspace.app.rest.model.BaseObjectRest;
import org.dspace.app.rest.model.SiteRest;
import org.dspace.authorize.service.AuthorizeService;
import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* The ComCol Admin feature. It can be used to verify if the current user is admin of any community or collection in the
* site.
*
* Authorization is granted if the current user has ADMIN permissions for any Community or Collection anywhere in the
* site, or if the current user is a site admin.
*/
@Component
@AuthorizationFeatureDocumentation(name = ComColAdminFeature.NAME,
description = "It can be used to verify if the current user is admin of any community or collection in the site")
public class ComColAdminFeature implements AuthorizationFeature {
public final static String NAME = "isComColAdmin";
@Autowired
private AuthorizeService authorizeService;
@Override
public boolean isAuthorized(Context context, BaseObjectRest object) throws SQLException {
if (object instanceof SiteRest) {
if (authorizeService.isAdmin(context)) {
return true;
}
return authorizeService.isComColAdmin(context);
}
return false;
}
@Override
public String[] getSupportedTypes() {
return new String[]{
SiteRest.CATEGORY + "." + SiteRest.NAME
};
}
}

View File

@@ -0,0 +1,55 @@
/**
* 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.authorization.impl;
import java.sql.SQLException;
import org.dspace.app.rest.authorization.AuthorizationFeature;
import org.dspace.app.rest.authorization.AuthorizationFeatureDocumentation;
import org.dspace.app.rest.model.BaseObjectRest;
import org.dspace.app.rest.model.SiteRest;
import org.dspace.authorize.service.AuthorizeService;
import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* The Community Admin feature. It can be used to verify if the current user is admin of any community in the site.
*
* Authorization is granted if the current user has ADMIN permissions for any Community anywhere in the site, or if the
* current user is a site admin.
*/
@Component
@AuthorizationFeatureDocumentation(name = CommunityAdminFeature.NAME,
description = "It can be used to verify if the current user is admin of any community in the site")
public class CommunityAdminFeature implements AuthorizationFeature {
public final static String NAME = "isCommunityAdmin";
@Autowired
private AuthorizeService authorizeService;
@Override
public boolean isAuthorized(Context context, BaseObjectRest object) throws SQLException {
if (object instanceof SiteRest) {
if (authorizeService.isAdmin(context)) {
return true;
}
return authorizeService.isCommunityAdmin(context);
}
return false;
}
@Override
public String[] getSupportedTypes() {
return new String[]{
SiteRest.CATEGORY + "." + SiteRest.NAME
};
}
}

View File

@@ -0,0 +1,70 @@
/**
* 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.authorization.impl;
import java.sql.SQLException;
import org.dspace.app.rest.authorization.AuthorizationFeature;
import org.dspace.app.rest.authorization.AuthorizationFeatureDocumentation;
import org.dspace.app.rest.model.BaseObjectRest;
import org.dspace.app.rest.model.SiteRest;
import org.dspace.authorize.AuthorizeConfiguration;
import org.dspace.authorize.service.AuthorizeService;
import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* The Manage Groups Feature. It can be used to verify if the current user can manage groups in any community or
* collection in the site.
*
* Authorization is granted if the current user has ADMIN permissions for any Community or Collection anywhere in the
* site AND the corresponding core.authorization.* properties are set to true.
*/
@Component
@AuthorizationFeatureDocumentation(name = ManageGroupsFeature.NAME, description =
"It can be used to verify if the current user can manage groups in any community or collection in the site")
public class ManageGroupsFeature implements AuthorizationFeature {
public final static String NAME = "canManageGroups";
@Autowired
private AuthorizeService authorizeService;
@Override
public boolean isAuthorized(Context context, BaseObjectRest object) throws SQLException {
if (object instanceof SiteRest) {
if (authorizeService.isAdmin(context)) {
return true;
}
if ((AuthorizeConfiguration.canCommunityAdminManagePolicies() ||
AuthorizeConfiguration.canCommunityAdminManageAdminGroup()) &&
authorizeService.isCommunityAdmin(context)) {
return true;
}
if (
(AuthorizeConfiguration.canCommunityAdminManageCollectionPolicies() ||
AuthorizeConfiguration.canCommunityAdminManageCollectionSubmitters() ||
AuthorizeConfiguration.canCommunityAdminManageCollectionWorkflows() ||
AuthorizeConfiguration.canCommunityAdminManageCollectionAdminGroup())
&& authorizeService.isCollectionAdmin(context)) {
return true;
}
}
return false;
}
@Override
public String[] getSupportedTypes() {
return new String[]{
SiteRest.CATEGORY + "." + SiteRest.NAME
};
}
}

View File

@@ -41,6 +41,7 @@ public class DiscoverFacetResultsConverter {
Projection projection) {
FacetResultsRest facetResultsRest = new FacetResultsRest();
facetResultsRest.setProjection(projection);
facetResultsRest.setConfiguration(configuration.getId());
setRequestInformation(context, facetName, prefix, query, dsoTypes, dsoScope, searchFilters, searchResult,
configuration, facetResultsRest, page, projection);

View File

@@ -51,7 +51,7 @@ public class ItemConverter
item.setLastModified(obj.getLastModified());
List<MetadataValue> entityTypes =
itemService.getMetadata(obj, "relationship", "type", null, Item.ANY, false);
itemService.getMetadata(obj, "dspace", "entity", "type", Item.ANY, false);
if (CollectionUtils.isNotEmpty(entityTypes) && StringUtils.isNotBlank(entityTypes.get(0).getValue())) {
item.setEntityType(entityTypes.get(0).getValue());
}

View File

@@ -200,6 +200,22 @@ public class CollectionRestRepository extends DSpaceObjectRestRepository<Collect
}
}
@PreAuthorize("hasAuthority('AUTHENTICATED')")
@SearchRestMethod(name = "findAdminAuthorized")
public Page<CollectionRest> findAdminAuthorized (
Pageable pageable, @Parameter(value = "query") String query) {
try {
Context context = obtainContext();
List<Collection> collections = authorizeService.findAdminAuthorizedCollection(context, query,
Math.toIntExact(pageable.getOffset()),
Math.toIntExact(pageable.getPageSize()));
long tot = authorizeService.countAdminAuthorizedCollection(context, query);
return converter.toRestPage(collections, pageable, tot , utils.obtainProjection());
} catch (SearchServiceException | SQLException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
@Override
@PreAuthorize("hasPermission(#id, 'COLLECTION', 'WRITE')")
protected void patch(Context context, HttpServletRequest request, String apiCategory, String model, UUID id,

View File

@@ -20,6 +20,7 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.Logger;
import org.dspace.app.rest.Parameter;
import org.dspace.app.rest.SearchRestMethod;
import org.dspace.app.rest.exception.DSpaceBadRequestException;
import org.dspace.app.rest.exception.RepositoryMethodNotImplementedException;
@@ -203,6 +204,22 @@ public class CommunityRestRepository extends DSpaceObjectRestRepository<Communit
}
}
@PreAuthorize("hasAuthority('AUTHENTICATED')")
@SearchRestMethod(name = "findAdminAuthorized")
public Page<CommunityRest> findAdminAuthorized (
Pageable pageable, @Parameter(value = "query") String query) {
try {
Context context = obtainContext();
List<Community> communities = authorizeService.findAdminAuthorizedCommunity(context, query,
Math.toIntExact(pageable.getOffset()),
Math.toIntExact(pageable.getPageSize()));
long tot = authorizeService.countAdminAuthorizedCommunity(context, query);
return converter.toRestPage(communities, pageable, tot , utils.obtainProjection());
} catch (SearchServiceException | SQLException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
@Override
@PreAuthorize("hasPermission(#id, 'COMMUNITY', 'WRITE')")
protected void patch(Context context, HttpServletRequest request, String apiCategory, String model, UUID id,

View File

@@ -129,7 +129,7 @@ public class EPersonRestAuthenticationProvider implements AuthenticationProvider
//Pass the eperson ID to the request service
requestService.setCurrentUserId(ePerson.getID());
return new DSpaceAuthentication(ePerson, getGrantedAuthorities(context, ePerson));
return new DSpaceAuthentication(ePerson, getGrantedAuthorities(context));
} else {
log.info(
@@ -138,17 +138,17 @@ public class EPersonRestAuthenticationProvider implements AuthenticationProvider
}
}
public List<GrantedAuthority> getGrantedAuthorities(Context context, EPerson eperson) {
public List<GrantedAuthority> getGrantedAuthorities(Context context) {
List<GrantedAuthority> authorities = new LinkedList<>();
EPerson eperson = context.getCurrentUser();
if (eperson != null) {
boolean isAdmin = false;
boolean isCommunityAdmin = false;
boolean isCollectionAdmin = false;
try {
isAdmin = authorizeService.isAdmin(context, eperson);
isCommunityAdmin = authorizeService.isCommunityAdmin(context, eperson);
isCollectionAdmin = authorizeService.isCollectionAdmin(context, eperson);
isCommunityAdmin = authorizeService.isCommunityAdmin(context);
isCollectionAdmin = authorizeService.isCollectionAdmin(context);
} catch (SQLException e) {
log.error("SQL error while checking for admin rights", e);
}

View File

@@ -76,10 +76,10 @@ public class EPersonRestPermissionEvaluatorPlugin extends RestObjectPermissionEv
return false;
} else if (dsoId.equals(ePerson.getID())) {
return true;
} else if (authorizeService.isCommunityAdmin(context, ePerson)
} else if (authorizeService.isCommunityAdmin(context)
&& AuthorizeUtil.canCommunityAdminManageAccounts()) {
return true;
} else if (authorizeService.isCollectionAdmin(context, ePerson)
} else if (authorizeService.isCollectionAdmin(context)
&& AuthorizeUtil.canCollectionAdminManageAccounts()) {
return true;
}

View File

@@ -62,9 +62,8 @@ public class GroupRestPermissionEvaluatorPlugin extends RestObjectPermissionEval
Request request = requestService.getCurrentRequest();
Context context = ContextUtil.obtainContext(request.getServletRequest());
EPerson ePerson = null;
EPerson ePerson = context.getCurrentUser();
try {
ePerson = ePersonService.findByEmail(context, (String) authentication.getPrincipal());
UUID dsoId = UUID.fromString(targetId.toString());
Group group = groupService.find(context, dsoId);
@@ -74,10 +73,10 @@ public class GroupRestPermissionEvaluatorPlugin extends RestObjectPermissionEval
return false;
} else if (groupService.isMember(context, ePerson, group)) {
return true;
} else if (authorizeService.isCommunityAdmin(context, ePerson)
} else if (authorizeService.isCommunityAdmin(context)
&& AuthorizeUtil.canCommunityAdminManageAccounts()) {
return true;
} else if (authorizeService.isCollectionAdmin(context, ePerson)
} else if (authorizeService.isCollectionAdmin(context)
&& AuthorizeUtil.canCollectionAdminManageAccounts()) {
return true;
}

View File

@@ -129,7 +129,7 @@ public class StatelessAuthenticationFilter extends BasicAuthenticationFilter {
requestService.setCurrentUserId(eperson.getID());
//Get the Spring authorities for this eperson
List<GrantedAuthority> authorities = authenticationProvider.getGrantedAuthorities(context, eperson);
List<GrantedAuthority> authorities = authenticationProvider.getGrantedAuthorities(context);
String onBehalfOfParameterValue = request.getHeader(ON_BEHALF_OF_REQUEST_PARAM);
if (onBehalfOfParameterValue != null) {
if (configurationService.getBooleanProperty("webui.user.assumelogin")) {
@@ -174,7 +174,7 @@ public class StatelessAuthenticationFilter extends BasicAuthenticationFilter {
requestService.setCurrentUserId(epersonUuid);
context.switchContextUser(onBehalfOfEPerson);
return new DSpaceAuthentication(onBehalfOfEPerson.getEmail(),
authenticationProvider.getGrantedAuthorities(context, onBehalfOfEPerson));
authenticationProvider.getGrantedAuthorities(context));
} else {
throw new IllegalArgumentException("You're unable to use the login as feature to log " +
"in as another admin");

View File

@@ -58,6 +58,7 @@ import org.dspace.core.Constants;
import org.dspace.eperson.EPerson;
import org.dspace.eperson.Group;
import org.dspace.eperson.service.GroupService;
import org.dspace.services.ConfigurationService;
import org.hamcrest.Matchers;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
@@ -77,9 +78,26 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
@Autowired
GroupService groupService;
@Autowired
private ConfigurationService configurationService;
@Autowired
CollectionService collectionService;
private Community topLevelCommunityA;
private Community subCommunityA;
private Community communityB;
private Community communityC;
private Collection collectionA;
private Collection collectionB;
private Collection collectionC;
private EPerson topLevelCommunityAAdmin;
private EPerson subCommunityAAdmin;
private EPerson collectionAAdmin;
private EPerson submitter;
@Test
public void findAllTest() throws Exception {
@@ -2497,4 +2515,552 @@ public class CollectionRestRepositoryIT extends AbstractControllerIntegrationTes
}
private void setUpAuthorizedSearch() throws Exception {
super.setUp();
/**
* The common Community/Collection structure for the AuthorizedSearch tests:
*
* topLevelCommunityA
* └── subCommunityA
* └── collectionA
*/
context.turnOffAuthorisationSystem();
topLevelCommunityAAdmin = EPersonBuilder.createEPerson(context)
.withNameInMetadata("Jhon", "Brown")
.withEmail("topLevelCommunityAAdmin@my.edu")
.withPassword(password)
.build();
topLevelCommunityA = CommunityBuilder.createCommunity(context)
.withName("The name of this community is topLevelCommunityA")
.withAdminGroup(topLevelCommunityAAdmin)
.build();
subCommunityAAdmin = EPersonBuilder.createEPerson(context)
.withNameInMetadata("Jhon", "Brown")
.withEmail("subCommunityAAdmin@my.edu")
.withPassword(password)
.build();
subCommunityA = CommunityBuilder.createCommunity(context)
.withName("The name of this sub-community is subCommunityA")
.withAdminGroup(subCommunityAAdmin)
.addParentCommunity(context, topLevelCommunityA)
.build();
submitter = EPersonBuilder.createEPerson(context)
.withNameInMetadata("Jhon", "Brown")
.withEmail("submitter@my.edu")
.withPassword(password)
.build();
collectionAAdmin = EPersonBuilder.createEPerson(context)
.withNameInMetadata("Jhon", "Brown")
.withEmail("collectionAAdmin@my.edu")
.withPassword(password)
.build();
collectionA = CollectionBuilder.createCollection(context, subCommunityA)
.withName("The name of this collection is collectionA")
.withAdminGroup(collectionAAdmin)
.withSubmitterGroup(submitter)
.build();
context.restoreAuthSystemState();
configurationService.setProperty(
"org.dspace.app.rest.authorization.AlwaysThrowExceptionFeature.turnoff", "true");
}
@Test
public void testAdminAuthorizedSearch() throws Exception {
setUpAuthorizedSearch();
context.turnOffAuthorisationSystem();
communityB = CommunityBuilder.createCommunity(context)
.withName("topLevelCommunityB is a very original name")
.withAdminGroup(admin)
.build();
communityC = CommunityBuilder.createCommunity(context)
.withName("the last community is named topLevelCommunityC")
.build();
collectionB = CollectionBuilder.createCollection(context, subCommunityA)
.withName("collectionB is a very original name")
.build();
collectionC = CollectionBuilder.createCollection(context, communityC)
.withName("the last collection is collectionC")
.build();
context.restoreAuthSystemState();
String token = getAuthToken(admin.getEmail(), password);
// Verify the site admin gets all collections
getClient(token).perform(get("/api/core/collections/search/findAdminAuthorized"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.collections", Matchers.containsInAnyOrder(
CollectionMatcher.matchProperties(collectionA.getName(), collectionA.getID(), collectionA.getHandle()),
CollectionMatcher.matchProperties(collectionB.getName(), collectionB.getID(), collectionB.getHandle()),
CollectionMatcher.matchProperties(collectionC.getName(), collectionC.getID(), collectionC.getHandle())
)));
// Verify the search only shows dso's which according to the query
getClient(token).perform(get("/api/core/collections/search/findAdminAuthorized")
.param("query", collectionB.getName()))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.collections", Matchers.containsInAnyOrder(
CollectionMatcher.matchProperties(collectionB.getName(), collectionB.getID(), collectionB.getHandle())
)));
}
@Test
public void testCommunityAdminAuthorizedSearch() throws Exception {
setUpAuthorizedSearch();
/**
* The Community/Collection structure for this test:
*
* topLevelCommunityA
* ├── subCommunityA
* | └── collectionA
* └── collectionB
* communityB
* communityC
* └── collectionC
*/
context.turnOffAuthorisationSystem();
communityB = CommunityBuilder.createCommunity(context)
.withName("topLevelCommunityB is a very original name")
.withAdminGroup(topLevelCommunityAAdmin)
.build();
communityC = CommunityBuilder.createCommunity(context)
.withName("the last community is named topLevelCommunityC")
.build();
collectionB = CollectionBuilder.createCollection(context, topLevelCommunityA)
.withName("collectionB is a very original name")
.build();
collectionC = CollectionBuilder.createCollection(context, communityC)
.withName("the last collection is collectionC")
.build();
context.restoreAuthSystemState();
String token = getAuthToken(topLevelCommunityAAdmin.getEmail(), password);
// Verify the community admin gets all the communities he's admin for
getClient(token).perform(get("/api/core/collections/search/findAdminAuthorized"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.collections", Matchers.containsInAnyOrder(
CollectionMatcher.matchProperties(collectionA.getName(), collectionA.getID(), collectionA.getHandle()),
CollectionMatcher.matchProperties(collectionB.getName(), collectionB.getID(), collectionB.getHandle())
)));
// Verify the search only shows dso's which according to the query
getClient(token).perform(get("/api/core/collections/search/findAdminAuthorized")
.param("query", collectionB.getName()))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.collections", Matchers.containsInAnyOrder(
CollectionMatcher.matchProperties(collectionB.getName(), collectionB.getID(), collectionB.getHandle())
)));
// Verify that a query doesn't show dso's which the user doesn't have rights for
getClient(token).perform(get("/api/core/collections/search/findAdminAuthorized")
.param("query", collectionC.getName()))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.collections").doesNotExist());
}
@Test
public void testSubCommunityAdminAuthorizedSearch() throws Exception {
setUpAuthorizedSearch();
context.turnOffAuthorisationSystem();
communityB = CommunityBuilder.createCommunity(context)
.withName("topLevelCommunityB is a very original name")
.addParentCommunity(context, subCommunityA)
.build();
communityC = CommunityBuilder.createCommunity(context)
.withName("the last community is topLevelCommunityC")
.build();
collectionB = CollectionBuilder.createCollection(context, communityB)
.withName("collectionB is a very original name")
.build();
collectionC = CollectionBuilder.createCollection(context, communityC)
.withName("the last collection is collectionC")
.build();
context.restoreAuthSystemState();
String token = getAuthToken(subCommunityAAdmin.getEmail(), password);
// Verify the subcommunity admin gets all the communities he's admin for
getClient(token).perform(get("/api/core/collections/search/findAdminAuthorized"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.collections", Matchers.containsInAnyOrder(
CollectionMatcher.matchProperties(collectionA.getName(), collectionA.getID(), collectionA.getHandle()),
CollectionMatcher.matchProperties(collectionB.getName(), collectionB.getID(), collectionB.getHandle())
)));
// Verify the search only shows dso's which according to the query
getClient(token).perform(get("/api/core/collections/search/findAdminAuthorized")
.param("query", collectionB.getName()))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.collections", Matchers.containsInAnyOrder(
CollectionMatcher.matchProperties(collectionB.getName(), collectionB.getID(), collectionB.getHandle())
)));
// Verify that a query doesn't show dso's which the user doesn't have rights for
getClient(token).perform(get("/api/core/collections/search/findAdminAuthorized")
.param("query", collectionC.getName()))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.collections").doesNotExist());
}
@Test
public void testCollectionAdminAuthorizedSearch() throws Exception {
setUpAuthorizedSearch();
context.turnOffAuthorisationSystem();
communityB = CommunityBuilder.createCommunity(context)
.withName("topLevelCommunityB is a very original name")
.addParentCommunity(context, subCommunityA)
.build();
communityC = CommunityBuilder.createCommunity(context)
.withName("the last community is topLevelCommunityC")
.build();
collectionB = CollectionBuilder.createCollection(context, communityB)
.withName("collectionB is a very original name")
.withAdminGroup(collectionAAdmin)
.build();
collectionC = CollectionBuilder.createCollection(context, communityC)
.withName("the last collection is collectionC")
.build();
context.restoreAuthSystemState();
String token = getAuthToken(collectionAAdmin.getEmail(), password);
// Verify the collection admin gets all the communities he's admin for
getClient(token).perform(get("/api/core/collections/search/findAdminAuthorized"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.collections", Matchers.containsInAnyOrder(
CollectionMatcher.matchProperties(collectionA.getName(), collectionA.getID(), collectionA.getHandle()),
CollectionMatcher.matchProperties(collectionB.getName(), collectionB.getID(), collectionB.getHandle())
)));
// Verify the search only shows dso's which according to the query
getClient(token).perform(get("/api/core/collections/search/findAdminAuthorized")
.param("query", collectionB.getName()))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.collections", Matchers.containsInAnyOrder(
CollectionMatcher.matchProperties(collectionB.getName(), collectionB.getID(), collectionB.getHandle())
)));
// Verify that a query doesn't show dso's which the user doesn't have rights for
getClient(token).perform(get("/api/core/collections/search/findAdminAuthorized")
.param("query", collectionC.getName()))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.collections").doesNotExist());
}
@Test
public void testSubmitterAuthorizedSearch() throws Exception {
setUpAuthorizedSearch();
context.turnOffAuthorisationSystem();
communityB = CommunityBuilder.createCommunity(context)
.withName("topLevelCommunityB is a very original name")
.addParentCommunity(context, subCommunityA)
.build();
communityC = CommunityBuilder.createCommunity(context)
.withName("the last community is topLevelCommunityC")
.build();
collectionB = CollectionBuilder.createCollection(context, communityB)
.withName("collectionB is a very original name")
.withSubmitterGroup(submitter)
.withAdminGroup(collectionAAdmin)
.build();
collectionC = CollectionBuilder.createCollection(context, communityC)
.withName("the last collection is collectionC")
.build();
context.restoreAuthSystemState();
String token = getAuthToken(submitter.getEmail(), password);
// Verify the submitter doesn't have any matches for collections
getClient(token).perform(get("/api/core/collections/search/findAdminAuthorized"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.collections").doesNotExist());
// Verify the search only shows dso's which according to the query
getClient(token).perform(get("/api/core/collections/search/findAdminAuthorized")
.param("query", collectionB.getName()))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.collections").doesNotExist());
// Verify that a query doesn't show dso's which the user doesn't have rights for
getClient(token).perform(get("/api/core/collections/search/findAdminAuthorized")
.param("query", collectionC.getName()))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.collections").doesNotExist());
}
@Test
public void testSubGroupOfAdminGroupAuthorizedSearch() throws Exception {
setUpAuthorizedSearch();
context.turnOffAuthorisationSystem();
GroupBuilder.createGroup(context)
.withName("adminSubGroup")
.withParent(groupService.findByName(context, Group.ADMIN))
.addMember(eperson)
.build();
communityB = CommunityBuilder.createCommunity(context)
.withName("topLevelCommunityB is a very original name")
.build();
communityC = CommunityBuilder.createCommunity(context)
.withName("the last community is topLevelCommunityC")
.build();
collectionB = CollectionBuilder.createCollection(context, subCommunityA)
.withName("collectionB is a very original name")
.build();
collectionC = CollectionBuilder.createCollection(context, communityC)
.withName("the last collection is collectionC")
.build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
// Verify the site admins' subgroups members get all collections
getClient(token).perform(get("/api/core/collections/search/findAdminAuthorized"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.collections", Matchers.containsInAnyOrder(
CollectionMatcher.matchProperties(collectionA.getName(), collectionA.getID(), collectionA.getHandle()),
CollectionMatcher.matchProperties(collectionB.getName(), collectionB.getID(), collectionB.getHandle()),
CollectionMatcher.matchProperties(collectionC.getName(), collectionC.getID(), collectionC.getHandle())
)));
// Verify the search only shows dso's which according to the query
getClient(token).perform(get("/api/core/collections/search/findAdminAuthorized")
.param("query", collectionB.getName()))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.collections", Matchers.containsInAnyOrder(
CollectionMatcher.matchProperties(collectionB.getName(), collectionB.getID(), collectionB.getHandle())
)));
}
@Test
public void testSubGroupOfCommunityAdminGroupAuthorizedSearch() throws Exception {
setUpAuthorizedSearch();
context.turnOffAuthorisationSystem();
GroupBuilder.createGroup(context)
.withName("communityAdminSubGroup")
.withParent(groupService.findByName(context, "COMMUNITY_" + topLevelCommunityA.getID() + "_ADMIN"))
.addMember(eperson)
.build();
communityB = CommunityBuilder.createCommunity(context)
.withName("topLevelCommunityB is a very original name")
.build();
communityC = CommunityBuilder.createCommunity(context)
.withName("the last community is topLevelCommunityC")
.build();
ResourcePolicyBuilder.createResourcePolicy(context)
.withDspaceObject(communityB)
.withAction(Constants.ADMIN)
.withGroup(groupService.findByName(context, "COMMUNITY_" + topLevelCommunityA.getID() + "_ADMIN"))
.build();
collectionB = CollectionBuilder.createCollection(context, subCommunityA)
.withName("collectionB is a very original name")
.build();
collectionC = CollectionBuilder.createCollection(context, communityC)
.withName("the last collection is collectionC")
.build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
// Verify an ePerson in a subgroup of a community admin group gets all the collections he's admin for
getClient(token).perform(get("/api/core/collections/search/findAdminAuthorized"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.collections", Matchers.containsInAnyOrder(
CollectionMatcher.matchProperties(collectionA.getName(), collectionA.getID(), collectionA.getHandle()),
CollectionMatcher.matchProperties(collectionB.getName(), collectionB.getID(), collectionB.getHandle())
)));
// Verify the search only shows dso's which according to the query
getClient(token).perform(get("/api/core/collections/search/findAdminAuthorized")
.param("query", collectionB.getName()))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.collections", Matchers.containsInAnyOrder(
CollectionMatcher.matchProperties(collectionB.getName(), collectionB.getID(), collectionB.getHandle())
)));
// Verify that a query doesn't show dso's which the user doesn't have rights for
getClient(token).perform(get("/api/core/collections/search/findAdminAuthorized")
.param("query", collectionC.getName()))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.collections").doesNotExist());
}
@Test
public void testSubGroupOfSubCommunityAdminGroupAuthorizedSearch() throws Exception {
setUpAuthorizedSearch();
context.turnOffAuthorisationSystem();
GroupBuilder.createGroup(context)
.withName("communityAdminSubGroup")
.withParent(groupService.findByName(context, "COMMUNITY_" + subCommunityA.getID() + "_ADMIN"))
.addMember(eperson)
.build();
communityB = CommunityBuilder.createCommunity(context)
.withName("topLevelCommunityB is a very original name")
.addParentCommunity(context, topLevelCommunityA)
.build();
communityC = CommunityBuilder.createCommunity(context)
.withName("the last community is topLevelCommunityC")
.addParentCommunity(context, topLevelCommunityA)
.build();
ResourcePolicyBuilder.createResourcePolicy(context)
.withDspaceObject(communityB)
.withAction(Constants.ADMIN)
.withGroup(groupService.findByName(context, "COMMUNITY_" + subCommunityA.getID() + "_ADMIN"))
.build();
collectionB = CollectionBuilder.createCollection(context, subCommunityA)
.withName("collectionB is a very original name")
.build();
collectionC = CollectionBuilder.createCollection(context, communityC)
.withName("the last collection is collectionC")
.build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
// Verify an ePerson in a subgroup of a subcommunity admin group gets all the collections he's admin for
getClient(token).perform(get("/api/core/collections/search/findAdminAuthorized"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.collections", Matchers.containsInAnyOrder(
CollectionMatcher.matchProperties(collectionA.getName(), collectionA.getID(), collectionA.getHandle()),
CollectionMatcher.matchProperties(collectionB.getName(), collectionB.getID(), collectionB.getHandle())
)));
// Verify the search only shows dso's which according to the query
getClient(token).perform(get("/api/core/collections/search/findAdminAuthorized")
.param("query", collectionB.getName()))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.collections", Matchers.containsInAnyOrder(
CollectionMatcher.matchProperties(collectionB.getName(), collectionB.getID(), collectionB.getHandle())
)));
// Verify that a query doesn't show dso's which the user doesn't have rights for
getClient(token).perform(get("/api/core/collections/search/findAdminAuthorized")
.param("query", collectionC.getName()))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.collections").doesNotExist());
}
@Test
public void testSubGroupOfCollectionAdminGroupAuthorizedSearch() throws Exception {
setUpAuthorizedSearch();
context.turnOffAuthorisationSystem();
GroupBuilder.createGroup(context)
.withName("collectionAdminSubGroup")
.withParent(groupService.findByName(context, "COLLECTION_" + collectionA.getID() + "_ADMIN"))
.addMember(eperson)
.build();
communityB = CommunityBuilder.createCommunity(context)
.withName("topLevelCommunityB is a very original name")
.addParentCommunity(context, topLevelCommunityA)
.build();
communityC = CommunityBuilder.createCommunity(context)
.withName("the last community is topLevelCommunityC")
.addParentCommunity(context, topLevelCommunityA)
.build();
collectionB = CollectionBuilder.createCollection(context, communityB)
.withName("collectionB is a very original name")
.build();
collectionC = CollectionBuilder.createCollection(context, communityC)
.withName("the last collection is collectionC")
.build();
ResourcePolicyBuilder.createResourcePolicy(context)
.withDspaceObject(collectionB)
.withAction(Constants.ADMIN)
.withGroup(groupService.findByName(context, "COLLECTION_" + collectionA.getID() + "_ADMIN"))
.build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
// Verify an ePerson in a subgroup of a collection admin group gets all the collections he's admin for
getClient(token).perform(get("/api/core/collections/search/findAdminAuthorized"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.collections", Matchers.containsInAnyOrder(
CollectionMatcher.matchProperties(collectionA.getName(), collectionA.getID(), collectionA.getHandle()),
CollectionMatcher.matchProperties(collectionB.getName(), collectionB.getID(), collectionB.getHandle())
)));
// Verify the search only shows dso's which according to the query
getClient(token).perform(get("/api/core/collections/search/findAdminAuthorized")
.param("query", collectionB.getName()))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.collections", Matchers.containsInAnyOrder(
CollectionMatcher.matchProperties(collectionB.getName(), collectionB.getID(), collectionB.getHandle())
)));
// Verify that a query doesn't show dso's which the user doesn't have rights for
getClient(token).perform(get("/api/core/collections/search/findAdminAuthorized")
.param("query", collectionC.getName()))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.collections").doesNotExist());
}
@Test
public void testSubGroupOfSubmitterGroupAuthorizedSearch() throws Exception {
setUpAuthorizedSearch();
context.turnOffAuthorisationSystem();
GroupBuilder.createGroup(context)
.withName("collectionAdminSubGroup")
.withParent(groupService.findByName(context, "COLLECTION_" + collectionA.getID() + "_SUBMIT"))
.addMember(eperson)
.build();
communityB = CommunityBuilder.createCommunity(context)
.withName("topLevelCommunityB is a very original name")
.addParentCommunity(context, topLevelCommunityA)
.build();
communityC = CommunityBuilder.createCommunity(context)
.withName("the last community is topLevelCommunityC")
.addParentCommunity(context, topLevelCommunityA)
.build();
collectionB = CollectionBuilder.createCollection(context, communityB)
.withName("collectionB is a very original name")
.build();
ResourcePolicyBuilder.createResourcePolicy(context)
.withDspaceObject(collectionB)
.withAction(Constants.ADD)
.withGroup(groupService.findByName(context, "COLLECTION_" + collectionA.getID() + "_SUBMIT"))
.build();
collectionC = CollectionBuilder.createCollection(context, communityC)
.withName("the last collection is collectionC")
.build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
// Verify an ePerson in a subgroup of submitter group doesn't have any matches for collections
getClient(token).perform(get("/api/core/collections/search/findAdminAuthorized"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.collections").doesNotExist());
// Verify the search only shows dso's which according to the query
getClient(token).perform(get("/api/core/collections/search/findAdminAuthorized")
.param("query", collectionB.getName()))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.collections").doesNotExist());
// Verify that a query doesn't show dso's which the user doesn't have rights for
getClient(token).perform(get("/api/core/collections/search/findAdminAuthorized")
.param("query", collectionC.getName()))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.collections").doesNotExist());
}
@Test
public void testAdminAuthorizedSearchUnauthenticated() throws Exception {
// Verify a non-authenticated user can't use this function
getClient().perform(get("/api/core/collections/search/findAdminAuthorized"))
.andExpect(status().isUnauthorized());
}
}

View File

@@ -49,11 +49,16 @@ import org.dspace.authorize.service.ResourcePolicyService;
import org.dspace.builder.CollectionBuilder;
import org.dspace.builder.CommunityBuilder;
import org.dspace.builder.EPersonBuilder;
import org.dspace.builder.GroupBuilder;
import org.dspace.builder.ResourcePolicyBuilder;
import org.dspace.content.Collection;
import org.dspace.content.Community;
import org.dspace.content.service.CommunityService;
import org.dspace.core.Constants;
import org.dspace.eperson.EPerson;
import org.dspace.eperson.Group;
import org.dspace.eperson.service.GroupService;
import org.dspace.services.ConfigurationService;
import org.hamcrest.Matchers;
import org.json.JSONArray;
import org.json.JSONObject;
@@ -79,6 +84,23 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
@Autowired
ResourcePolicyService resoucePolicyService;
@Autowired
private ConfigurationService configurationService;
@Autowired
private GroupService groupService;
private Community topLevelCommunityA;
private Community subCommunityA;
private Community communityB;
private Community communityC;
private Collection collectionA;
private EPerson topLevelCommunityAAdmin;
private EPerson subCommunityAAdmin;
private EPerson collectionAdmin;
private EPerson submitter;
@Test
public void createTest() throws Exception {
ObjectMapper mapper = new ObjectMapper();
@@ -1962,4 +1984,498 @@ public class CommunityRestRepositoryIT extends AbstractControllerIntegrationTest
.contentType(contentType))
.andExpect(status().isBadRequest());
}
public void setUpAuthorizedSearch() throws Exception {
super.setUp();
context.turnOffAuthorisationSystem();
topLevelCommunityAAdmin = EPersonBuilder.createEPerson(context)
.withNameInMetadata("Jhon", "Brown")
.withEmail("topLevelCommunityAAdmin@my.edu")
.withPassword(password)
.build();
topLevelCommunityA = CommunityBuilder.createCommunity(context)
.withName("The name of this community is topLevelCommunityA")
.withAdminGroup(topLevelCommunityAAdmin)
.build();
subCommunityAAdmin = EPersonBuilder.createEPerson(context)
.withNameInMetadata("Jhon", "Brown")
.withEmail("subCommunityAAdmin@my.edu")
.withPassword(password)
.build();
subCommunityA = CommunityBuilder.createCommunity(context)
.withName("The name of this sub-community is subCommunityA")
.withAdminGroup(subCommunityAAdmin)
.addParentCommunity(context, topLevelCommunityA)
.build();
submitter = EPersonBuilder.createEPerson(context)
.withNameInMetadata("Jhon", "Brown")
.withEmail("submitter@my.edu")
.withPassword(password)
.build();
collectionAdmin = EPersonBuilder.createEPerson(context)
.withNameInMetadata("Jhon", "Brown")
.withEmail("collectionAdmin@my.edu")
.withPassword(password)
.build();
collectionA = CollectionBuilder.createCollection(context, subCommunityA)
.withName("The name of this collection is collectionA")
.withAdminGroup(collectionAdmin)
.withSubmitterGroup(submitter)
.build();
context.restoreAuthSystemState();
configurationService.setProperty(
"org.dspace.app.rest.authorization.AlwaysThrowExceptionFeature.turnoff", "true");
}
@Test
public void testAdminAuthorizedSearch() throws Exception {
setUpAuthorizedSearch();
context.turnOffAuthorisationSystem();
communityB = CommunityBuilder.createCommunity(context)
.withName("topLevelCommunityB is a very original name")
.withAdminGroup(admin)
.build();
communityC = CommunityBuilder.createCommunity(context)
.withName("the last community is topLevelCommunityC")
.build();
context.restoreAuthSystemState();
String token = getAuthToken(admin.getEmail(), password);
// Verify the site admin gets all communities
getClient(token).perform(get("/api/core/communities/search/findAdminAuthorized"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.communities", Matchers.containsInAnyOrder(
CommunityMatcher.matchProperties(topLevelCommunityA.getName(), topLevelCommunityA.getID(),
topLevelCommunityA.getHandle()),
CommunityMatcher.matchProperties(subCommunityA.getName(), subCommunityA.getID(),
subCommunityA.getHandle()),
CommunityMatcher.matchProperties(communityB.getName(), communityB.getID(), communityB.getHandle()),
CommunityMatcher.matchProperties(communityC.getName(), communityC.getID(), communityC.getHandle())
)));
// Verify the search only shows dso's which according to the query
getClient(token).perform(get("/api/core/communities/search/findAdminAuthorized")
.param("query", communityB.getName()))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.communities", Matchers.containsInAnyOrder(
CommunityMatcher.matchProperties(communityB.getName(), communityB.getID(), communityB.getHandle())
)));
}
@Test
public void testCommunityAdminAuthorizedSearch() throws Exception {
setUpAuthorizedSearch();
context.turnOffAuthorisationSystem();
communityB = CommunityBuilder.createCommunity(context)
.withName("topLevelCommunityB is a very original name")
.withAdminGroup(topLevelCommunityAAdmin)
.build();
communityC = CommunityBuilder.createCommunity(context)
.withName("the last community is named topLevelCommunityC")
.build();
context.restoreAuthSystemState();
String token = getAuthToken(topLevelCommunityAAdmin.getEmail(), password);
// Verify the community admin gets all the communities he's admin for
getClient(token).perform(get("/api/core/communities/search/findAdminAuthorized"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.communities", Matchers.containsInAnyOrder(
CommunityMatcher.matchProperties(topLevelCommunityA.getName(), topLevelCommunityA.getID(),
topLevelCommunityA.getHandle()),
CommunityMatcher.matchProperties(subCommunityA.getName(), subCommunityA.getID(),
subCommunityA.getHandle()),
CommunityMatcher.matchProperties(communityB.getName(), communityB.getID(), communityB.getHandle())
)));
// Verify the search only shows dso's which according to the query
getClient(token).perform(get("/api/core/communities/search/findAdminAuthorized")
.param("query", communityB.getName()))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.communities", Matchers.containsInAnyOrder(
CommunityMatcher.matchProperties(communityB.getName(), communityB.getID(), communityB.getHandle())
)));
// Verify that a query doesn't show dso's which the user doesn't have rights for
getClient(token).perform(get("/api/core/communities/search/findAdminAuthorized")
.param("query", communityC.getName()))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.communities").doesNotExist());
}
@Test
public void testSubCommunityAdminAuthorizedSearch() throws Exception {
setUpAuthorizedSearch();
/**
* The Community/Collection structure for this test:
*
* topLevelCommunityA
* ├── subCommunityA
* | └── collectionA
* ├── communityB
* └── communityC
*/
context.turnOffAuthorisationSystem();
communityB = CommunityBuilder.createCommunity(context)
.withName("topLevelCommunityB is a very original name")
.addParentCommunity(context, topLevelCommunityA)
.withAdminGroup(subCommunityAAdmin)
.build();
communityC = CommunityBuilder.createCommunity(context)
.withName("the last community is topLevelCommunityC")
.addParentCommunity(context, topLevelCommunityA)
.build();
context.restoreAuthSystemState();
String token = getAuthToken(subCommunityAAdmin.getEmail(), password);
// Verify the community admin gets all the communities he's admin for
getClient(token).perform(get("/api/core/communities/search/findAdminAuthorized"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.communities", Matchers.containsInAnyOrder(
CommunityMatcher.matchProperties(subCommunityA.getName(), subCommunityA.getID(),
subCommunityA.getHandle()),
CommunityMatcher.matchProperties(communityB.getName(), communityB.getID(), communityB.getHandle())
)));
// Verify the search only shows dso's which according to the query
getClient(token).perform(get("/api/core/communities/search/findAdminAuthorized")
.param("query", communityB.getName()))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.communities", Matchers.containsInAnyOrder(
CommunityMatcher.matchProperties(communityB.getName(), communityB.getID(), communityB.getHandle())
)));
// Verify that a query doesn't show dso's which the user doesn't have rights for
getClient(token).perform(get("/api/core/communities/search/findAdminAuthorized")
.param("query", communityC.getName()))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.communities").doesNotExist());
}
@Test
public void testCollectionAdminAuthorizedSearch() throws Exception {
setUpAuthorizedSearch();
context.turnOffAuthorisationSystem();
communityB = CommunityBuilder.createCommunity(context)
.withName("topLevelCommunityB is a very original name")
.addParentCommunity(context, topLevelCommunityA)
.build();
communityC = CommunityBuilder.createCommunity(context)
.withName("the last community is topLevelCommunityC")
.addParentCommunity(context, topLevelCommunityA)
.build();
context.restoreAuthSystemState();
String token = getAuthToken(collectionAdmin.getEmail(), password);
// Verify the collection admin doesn't have any matches for communities
getClient(token).perform(get("/api/core/communities/search/findAdminAuthorized"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.communities").doesNotExist());
// Verify the search only shows dso's which according to the query
getClient(token).perform(get("/api/core/communities/search/findAdminAuthorized")
.param("query", communityB.getName()))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.communities").doesNotExist());
// Verify that a query doesn't show dso's which the user doesn't have rights for
getClient(token).perform(get("/api/core/communities/search/findAdminAuthorized")
.param("query", communityC.getName()))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.communities").doesNotExist());
}
@Test
public void testSubmitterAuthorizedSearch() throws Exception {
setUpAuthorizedSearch();
context.turnOffAuthorisationSystem();
communityB = CommunityBuilder.createCommunity(context)
.withName("topLevelCommunityB is a very original name")
.addParentCommunity(context, topLevelCommunityA)
.build();
communityC = CommunityBuilder.createCommunity(context)
.withName("the last community is topLevelCommunityC")
.addParentCommunity(context, topLevelCommunityA)
.build();
context.restoreAuthSystemState();
String token = getAuthToken(submitter.getEmail(), password);
// Verify the submitter doesn't have any matches for communities
getClient(token).perform(get("/api/core/communities/search/findAdminAuthorized"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.communities").doesNotExist());
// Verify the search only shows dso's which according to the query
getClient(token).perform(get("/api/core/communities/search/findAdminAuthorized")
.param("query", communityB.getName()))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.communities").doesNotExist());
// Verify that a query doesn't show dso's which the user doesn't have rights for
getClient(token).perform(get("/api/core/communities/search/findAdminAuthorized")
.param("query", communityC.getName()))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.communities").doesNotExist());
}
@Test
public void testSubGroupOfAdminGroupAuthorizedSearch() throws Exception {
setUpAuthorizedSearch();
context.turnOffAuthorisationSystem();
GroupBuilder.createGroup(context)
.withName("adminSubGroup")
.withParent(groupService.findByName(context, Group.ADMIN))
.addMember(eperson)
.build();
communityB = CommunityBuilder.createCommunity(context)
.withName("topLevelCommunityB is a very original name")
.build();
communityC = CommunityBuilder.createCommunity(context)
.withName("the last community is topLevelCommunityC")
.build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
// Verify the site admins' subgroups members get all communities
getClient(token).perform(get("/api/core/communities/search/findAdminAuthorized"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.communities", Matchers.containsInAnyOrder(
CommunityMatcher.matchProperties(topLevelCommunityA.getName(), topLevelCommunityA.getID(),
topLevelCommunityA.getHandle()),
CommunityMatcher.matchProperties(subCommunityA.getName(), subCommunityA.getID(),
subCommunityA.getHandle()),
CommunityMatcher.matchProperties(communityB.getName(), communityB.getID(), communityB.getHandle()),
CommunityMatcher.matchProperties(communityC.getName(), communityC.getID(), communityC.getHandle())
)));
// Verify the search only shows dso's which according to the query
getClient(token).perform(get("/api/core/communities/search/findAdminAuthorized")
.param("query", communityB.getName()))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.communities", Matchers.containsInAnyOrder(
CommunityMatcher.matchProperties(communityB.getName(), communityB.getID(), communityB.getHandle())
)));
}
@Test
public void testSubGroupOfCommunityAdminGroupAuthorizedSearch() throws Exception {
setUpAuthorizedSearch();
context.turnOffAuthorisationSystem();
GroupBuilder.createGroup(context)
.withName("communityAdminSubGroup")
.withParent(groupService.findByName(context, "COMMUNITY_" + topLevelCommunityA.getID() + "_ADMIN"))
.addMember(eperson)
.build();
communityB = CommunityBuilder.createCommunity(context)
.withName("topLevelCommunityB is a very original name")
.build();
communityC = CommunityBuilder.createCommunity(context)
.withName("the last community is topLevelCommunityC")
.build();
ResourcePolicyBuilder.createResourcePolicy(context)
.withDspaceObject(communityB)
.withAction(Constants.ADMIN)
.withGroup(groupService.findByName(context, "COMMUNITY_" + topLevelCommunityA.getID() + "_ADMIN"))
.build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
// Verify the community admins' subgroup users get all the communities he's admin for
getClient(token).perform(get("/api/core/communities/search/findAdminAuthorized"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.communities", Matchers.containsInAnyOrder(
CommunityMatcher.matchProperties(topLevelCommunityA.getName(), topLevelCommunityA.getID(),
topLevelCommunityA.getHandle()),
CommunityMatcher.matchProperties(subCommunityA.getName(), subCommunityA.getID(),
subCommunityA.getHandle()),
CommunityMatcher.matchProperties(communityB.getName(), communityB.getID(), communityB.getHandle())
)));
// Verify the search only shows dso's which according to the query
getClient(token).perform(get("/api/core/communities/search/findAdminAuthorized")
.param("query", communityB.getName()))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.communities", Matchers.containsInAnyOrder(
CommunityMatcher.matchProperties(communityB.getName(), communityB.getID(), communityB.getHandle())
)));
// Verify that a query doesn't show dso's which the user doesn't have rights for
getClient(token).perform(get("/api/core/communities/search/findAdminAuthorized")
.param("query", communityC.getName()))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.communities").doesNotExist());
}
@Test
public void testSubGroupOfSubCommunityAdminGroupAuthorizedSearch() throws Exception {
setUpAuthorizedSearch();
context.turnOffAuthorisationSystem();
GroupBuilder.createGroup(context)
.withName("communityAdminSubGroup")
.withParent(groupService.findByName(context, "COMMUNITY_" + subCommunityA.getID() + "_ADMIN"))
.addMember(eperson)
.build();
communityB = CommunityBuilder.createCommunity(context)
.withName("topLevelCommunityB is a very original name")
.addParentCommunity(context, topLevelCommunityA)
.build();
communityC = CommunityBuilder.createCommunity(context)
.withName("the last community is topLevelCommunityC")
.addParentCommunity(context, topLevelCommunityA)
.build();
ResourcePolicyBuilder.createResourcePolicy(context)
.withDspaceObject(communityB)
.withAction(Constants.ADMIN)
.withGroup(groupService.findByName(context, "COMMUNITY_" + subCommunityA.getID() + "_ADMIN"))
.build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
// Verify the sub-community admins' subgroup users get all the communities he's admin for
getClient(token).perform(get("/api/core/communities/search/findAdminAuthorized"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.communities", Matchers.containsInAnyOrder(
CommunityMatcher.matchProperties(subCommunityA.getName(), subCommunityA.getID(),
subCommunityA.getHandle()),
CommunityMatcher.matchProperties(communityB.getName(), communityB.getID(), communityB.getHandle())
)));
// Verify the search only shows dso's which according to the query
getClient(token).perform(get("/api/core/communities/search/findAdminAuthorized")
.param("query", communityB.getName()))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.communities", Matchers.containsInAnyOrder(
CommunityMatcher.matchProperties(communityB.getName(), communityB.getID(), communityB.getHandle())
)));
// Verify that a query doesn't show dso's which the user doesn't have rights for
getClient(token).perform(get("/api/core/communities/search/findAdminAuthorized")
.param("query", communityC.getName()))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.communities").doesNotExist());
}
@Test
public void testSubGroupOfCollectionAdminGroupAuthorizedSearch() throws Exception {
setUpAuthorizedSearch();
context.turnOffAuthorisationSystem();
GroupBuilder.createGroup(context)
.withName("collectionAdminSubGroup")
.withParent(groupService.findByName(context, "COLLECTION_" + collectionA.getID() + "_ADMIN"))
.addMember(eperson)
.build();
communityB = CommunityBuilder.createCommunity(context)
.withName("topLevelCommunityB is a very original name")
.addParentCommunity(context, topLevelCommunityA)
.build();
Collection collectionB = CollectionBuilder.createCollection(context, communityB)
.withName("collectionB")
.build();
ResourcePolicyBuilder.createResourcePolicy(context)
.withDspaceObject(collectionB)
.withAction(Constants.ADMIN)
.withGroup(groupService.findByName(context, "COLLECTION_" + collectionA.getID() + "_ADMIN"))
.build();
communityC = CommunityBuilder.createCommunity(context)
.withName("the last community is topLevelCommunityC")
.addParentCommunity(context, topLevelCommunityA)
.build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
// Verify the collection admins' subgroup members don't have any matches for communities
getClient(token).perform(get("/api/core/communities/search/findAdminAuthorized"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.communities").doesNotExist());
// Verify the search only shows dso's which according to the query
getClient(token).perform(get("/api/core/communities/search/findAdminAuthorized")
.param("query", communityB.getName()))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.communities").doesNotExist());
// Verify that a query doesn't show dso's which the user doesn't have rights for
getClient(token).perform(get("/api/core/communities/search/findAdminAuthorized")
.param("query", communityC.getName()))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.communities").doesNotExist());
}
@Test
public void testSubGroupOfSubmitterGroupAuthorizedSearch() throws Exception {
setUpAuthorizedSearch();
context.turnOffAuthorisationSystem();
GroupBuilder.createGroup(context)
.withName("collectionAdminSubGroup")
.withParent(groupService.findByName(context, "COLLECTION_" + collectionA.getID() + "_SUBMIT"))
.addMember(eperson)
.build();
communityB = CommunityBuilder.createCommunity(context)
.withName("topLevelCommunityB is a very original name")
.addParentCommunity(context, topLevelCommunityA)
.build();
Collection collectionB = CollectionBuilder.createCollection(context, communityB)
.withName("collectionB")
.build();
ResourcePolicyBuilder.createResourcePolicy(context)
.withDspaceObject(collectionB)
.withAction(Constants.ADD)
.withGroup(groupService.findByName(context, "COLLECTION_" + collectionA.getID() + "_SUBMIT"))
.build();
communityC = CommunityBuilder.createCommunity(context)
.withName("the last community is topLevelCommunityC")
.addParentCommunity(context, topLevelCommunityA)
.build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
// Verify an ePerson in a subgroup of submitter group doesn't have any matches for communities
getClient(token).perform(get("/api/core/communities/search/findAdminAuthorized"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.communities").doesNotExist());
// Verify the search only shows dso's which according to the query
getClient(token).perform(get("/api/core/communities/search/findAdminAuthorized")
.param("query", communityB.getName()))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.communities").doesNotExist());
// Verify that a query doesn't show dso's which the user doesn't have rights for
getClient(token).perform(get("/api/core/communities/search/findAdminAuthorized")
.param("query", communityC.getName()))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.communities").doesNotExist());
}
@Test
public void testAdminAuthorizedSearchUnauthenticated() throws Exception {
// Verify a non-authenticated user can't use this function
getClient().perform(get("/api/core/communities/search/findAdminAuthorized"))
.andExpect(status().isUnauthorized());
}
}

View File

@@ -12,6 +12,7 @@ import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.emptyOrNullString;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
@@ -720,7 +721,7 @@ public class DiscoveryRestControllerIT extends AbstractControllerIntegrationTest
//The scope has to be the same as the one that we've given in the parameters
.andExpect(jsonPath("$.scope", is("testScope")))
//There always needs to be a self link available
.andExpect(jsonPath("$._links.self.href", containsString("api/discover/facets/author")))
.andExpect(jsonPath("$._links.self.href", containsString("api/discover/facets/author?scope=testScope")))
//These are all the authors for the items that were created and thus they have to be present in
// the embedded values section
.andExpect(jsonPath("$._embedded.values", containsInAnyOrder(
@@ -748,7 +749,9 @@ public class DiscoveryRestControllerIT extends AbstractControllerIntegrationTest
//The scope has to be same as the param that we've entered
.andExpect(jsonPath("$.scope", is("testScope")))
//There always needs to be a self link available
.andExpect(jsonPath("$._links.self.href", containsString("api/discover/facets/author")))
.andExpect(jsonPath("$._links.self.href", containsString("api/discover/facets/author?scope=testScope")))
.andExpect(jsonPath("$._links.next.href",
containsString("api/discover/facets/author?scope=testScope&page=1&size=2")))
//These are the values that need to be present as it's ordered by count and these authors are the
// most common ones in the items that we've created
.andExpect(jsonPath("$._embedded.values", containsInAnyOrder(
@@ -5227,4 +5230,245 @@ public class DiscoveryRestControllerIT extends AbstractControllerIntegrationTest
.andExpect(jsonPath("$._embedded.searchResult.page.totalElements", is(3)));
}
@Test
public void discoverSearchFacetValuesTest() throws Exception {
context.turnOffAuthorisationSystem();
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();
ItemBuilder.createItem(context, col1)
.withTitle("Public Test Item")
.withIssueDate("2010-10-17")
.withAuthor("Smith, Donald")
.withSubject("ExtraEntry").build();
ItemBuilder.createItem(context, col2)
.withTitle("Withdrawn Test Item")
.withIssueDate("1990-02-13")
.withAuthor("Smith, Maria")
.withAuthor("Doe, Jane")
.withSubject("ExtraEntry")
.withdrawn().build();
ItemBuilder.createItem(context, col2)
.withTitle("Private Test Item")
.withIssueDate("2010-02-13")
.withAuthor("Smith, Maria")
.withAuthor("Doe, Jane")
.withSubject("AnotherTest")
.withSubject("ExtraEntry")
.makeUnDiscoverable().build();
context.restoreAuthSystemState();
String adminToken = getAuthToken(admin.getEmail(), password);
getClient(adminToken).perform(get("/api/discover/facets/discoverable")
.param("configuration", "administrativeView")
.param("sort", "score,DESC")
.param("page", "0")
.param("size", "10"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._links.self.href",containsString(
"/api/discover/facets/discoverable?configuration=administrativeView&sort=score,DESC")))
.andExpect(jsonPath("$._embedded.values", Matchers.containsInAnyOrder(
SearchResultMatcher.matchEmbeddedFacetValues("true", 2, "discover",
"/api/discover/search/objects?configuration=administrativeView&f.discoverable=true,equals"),
SearchResultMatcher.matchEmbeddedFacetValues("false", 1, "discover",
"/api/discover/search/objects?configuration=administrativeView&f.discoverable=false,equals")
)));
}
@Test
public void discoverSearchFacetValuesPaginationTest() throws Exception {
context.turnOffAuthorisationSystem();
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();
ItemBuilder.createItem(context, col1)
.withTitle("Public Test Item")
.withIssueDate("2010-10-17")
.withAuthor("Smith, Donald")
.withSubject("ExtraEntry").build();
ItemBuilder.createItem(context, col2)
.withTitle("Withdrawn Test Item")
.withIssueDate("1990-02-13")
.withAuthor("Smith, Maria")
.withAuthor("Doe, Jane")
.withSubject("ExtraEntry")
.withdrawn().build();
ItemBuilder.createItem(context, col2)
.withTitle("Private Test Item")
.withIssueDate("2010-02-13")
.withAuthor("Smith, Maria")
.withAuthor("Doe, Jane")
.withSubject("AnotherTest")
.withSubject("ExtraEntry")
.makeUnDiscoverable().build();
context.restoreAuthSystemState();
String adminToken = getAuthToken(admin.getEmail(), password);
getClient(adminToken).perform(get("/api/discover/facets/discoverable")
.param("configuration", "administrativeView")
.param("sort", "score,DESC")
.param("page", "0")
.param("size", "1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._links.self.href",containsString(
"/api/discover/facets/discoverable?configuration=administrativeView&sort=score,DESC")))
.andExpect(jsonPath("$._links.next.href",containsString(
"/api/discover/facets/discoverable?configuration=administrativeView&sort=score,DESC&page=1&size=1")))
.andExpect(jsonPath("$._embedded.values", Matchers.contains(
SearchResultMatcher.matchEmbeddedFacetValues("true", 2, "discover",
"/api/discover/search/objects?configuration=administrativeView&f.discoverable=true,equals")
)));
getClient(adminToken).perform(get("/api/discover/facets/discoverable")
.param("configuration", "administrativeView")
.param("sort", "score,DESC")
.param("page", "1")
.param("size", "1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._links.first.href",containsString(
"/api/discover/facets/discoverable?configuration=administrativeView&sort=score,DESC&page=0&size=1")))
.andExpect(jsonPath("$._links.prev.href",containsString(
"/api/discover/facets/discoverable?configuration=administrativeView&sort=score,DESC&page=0&size=1")))
.andExpect(jsonPath("$._links.self.href",containsString(
"/api/discover/facets/discoverable?configuration=administrativeView&sort=score,DESC&page=1&size=1")))
.andExpect(jsonPath("$._embedded.values", Matchers.contains(
SearchResultMatcher.matchEmbeddedFacetValues("false", 1, "discover",
"/api/discover/search/objects?configuration=administrativeView&f.discoverable=false,equals")
)));
}
@Test
public void discoverFacetsTestWithQueryTest() throws Exception {
context.turnOffAuthorisationSystem();
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community").build();
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity)
.withName("Collection 1").build();
Collection col2 = CollectionBuilder.createCollection(context, parentCommunity)
.withName("Collection 2").build();
Item publicItem1 = ItemBuilder.createItem(context, col1)
.withTitle("Public item 1")
.withIssueDate("2019-10-17")
.withAuthor("Smith, Donald")
.withSubject("ExtraEntry")
.build();
Item publicItem2 = ItemBuilder.createItem(context, col2)
.withTitle("Public item 2")
.withIssueDate("2020-02-13")
.withAuthor("Doe, Jane")
.withSubject("TestingForMore").withSubject("ExtraEntry")
.build();
Item publicItem3 = ItemBuilder.createItem(context, col2)
.withTitle("Public item 2")
.withIssueDate("2020-02-13")
.withAuthor("Anton, Senek")
.withSubject("AnotherTest").withSubject("TestingForMore")
.withSubject("ExtraEntry")
.build();
context.restoreAuthSystemState();
getClient().perform(get("/api/discover/facets/author")
.param("query", "Donald"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.type", is("discover")))
.andExpect(jsonPath("$.name", is("author")))
.andExpect(jsonPath("$.facetType", is("text")))
.andExpect(jsonPath("$.scope", is(emptyOrNullString())))
.andExpect(jsonPath("$._links.self.href", containsString("api/discover/facets/author?query=Donald")))
.andExpect(jsonPath("$._embedded.values[0].label", is("Smith, Donald")))
.andExpect(jsonPath("$._embedded.values[0].count", is(1)))
.andExpect(jsonPath("$._embedded.values[0]._links.search.href",
containsString("api/discover/search/objects?query=Donald&f.author=Smith, Donald,equals")))
.andExpect(jsonPath("$._embedded.values").value(Matchers.hasSize(1)));
}
@Test
public void discoverFacetsTestWithDsoTypeTest() throws Exception {
context.turnOffAuthorisationSystem();
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community").build();
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity)
.withName("Collection 1").build();
Collection col2 = CollectionBuilder.createCollection(context, parentCommunity)
.withName("Collection 2").build();
Item publicItem1 = ItemBuilder.createItem(context, col1)
.withTitle("Public item 1")
.withIssueDate("2017-10-17")
.withAuthor("Smith, Donald")
.withSubject("ExtraEntry")
.build();
Item publicItem2 = ItemBuilder.createItem(context, col2)
.withTitle("Public item 2")
.withIssueDate("2020-02-13")
.withAuthor("Doe, Jane")
.withSubject("ExtraEntry")
.build();
Item publicItem3 = ItemBuilder.createItem(context, col2)
.withTitle("Public item 2")
.withIssueDate("2020-02-13")
.withAuthor("Anton, Senek")
.withSubject("TestingForMore")
.withSubject("ExtraEntry")
.build();
context.restoreAuthSystemState();
getClient().perform(get("/api/discover/facets/dateIssued")
.param("dsoType", "Item"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.type", is("discover")))
.andExpect(jsonPath("$.name", is("dateIssued")))
.andExpect(jsonPath("$.facetType", is("date")))
.andExpect(jsonPath("$.scope", is(emptyOrNullString())))
.andExpect(jsonPath("$._links.self.href",
containsString("api/discover/facets/dateIssued?dsoType=Item")))
.andExpect(jsonPath("$._embedded.values[0].label", is("2017 - 2020")))
.andExpect(jsonPath("$._embedded.values[0].count", is(3)))
.andExpect(jsonPath("$._embedded.values[0]._links.search.href",
containsString("api/discover/search/objects?dsoType=Item&f.dateIssued=[2017 TO 2020],equals")))
.andExpect(jsonPath("$._embedded.values").value(Matchers.hasSize(1)));
}
}

View File

@@ -2800,7 +2800,7 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest {
.withAuthor("Smith, Donald")
.withPersonIdentifierLastName("Smith")
.withPersonIdentifierFirstName("Donald")
.withRelationshipType("Person")
.withEntityType("Person")
.build();
context.restoreAuthSystemState();
@@ -2834,7 +2834,7 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest {
.withTitle("Publication1")
.withAuthor("Testy, TEst")
.withIssueDate("2015-01-01")
.withRelationshipType("Publication")
.withEntityType("Publication")
.build();
context.restoreAuthSystemState();
@@ -2916,7 +2916,7 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest {
Map<String, String> value = new HashMap<>();
value.put("value", "Publication");
values.add(value);
AddOperation addOperation = new AddOperation("/metadata/relationship.type", values);
AddOperation addOperation = new AddOperation("/metadata/dspace.entity.type", values);
ops.add(addOperation);
String patchBody = getPatchContent(ops);
getClient(token).perform(patch("/api/core/items/" + item.getID())
@@ -3477,21 +3477,21 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest {
.withAuthor("Smith, Donald")
.withPersonIdentifierLastName("Smith")
.withPersonIdentifierFirstName("Donald")
.withRelationshipType("Person")
.withEntityType("Person")
.build();
author2 = ItemBuilder.createItem(context, col1)
.withTitle("Author2")
.withIssueDate("2016-02-13")
.withAuthor("Smith, Maria")
.withRelationshipType("Person")
.withEntityType("Person")
.build();
publication1 = ItemBuilder.createItem(context, col1)
.withTitle("Publication1")
.withAuthor("Testy, TEst")
.withIssueDate("2015-01-01")
.withRelationshipType("Publication")
.withEntityType("Publication")
.build();
EntityType publication = EntityTypeBuilder.createEntityTypeBuilder(context, "Publication").build();
@@ -3541,21 +3541,21 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest {
.withAuthor("Smith, Donald")
.withPersonIdentifierLastName("Smith")
.withPersonIdentifierFirstName("Donald")
.withRelationshipType("Person")
.withEntityType("Person")
.build();
author2 = ItemBuilder.createItem(context, col1)
.withTitle("Author2")
.withIssueDate("2016-02-13")
.withAuthor("Smith, Maria")
.withRelationshipType("Person")
.withEntityType("Person")
.build();
publication1 = ItemBuilder.createItem(context, col1)
.withTitle("Publication1")
.withAuthor("Testy, TEst")
.withIssueDate("2015-01-01")
.withRelationshipType("Publication")
.withEntityType("Publication")
.build();
EntityType publication = EntityTypeBuilder.createEntityTypeBuilder(context, "Publication").build();

View File

@@ -7,6 +7,7 @@
*/
package org.dspace.app.rest;
import static org.hamcrest.Matchers.is;
import static org.springframework.data.rest.webmvc.RestMediaTypes.TEXT_URI_LIST_VALUE;
import static org.springframework.http.MediaType.parseMediaType;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
@@ -17,6 +18,8 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
import org.dspace.app.rest.matcher.CollectionMatcher;
import org.dspace.app.rest.matcher.ItemMatcher;
import org.dspace.app.rest.matcher.PageMatcher;
import org.dspace.app.rest.matcher.SearchResultMatcher;
import org.dspace.app.rest.test.AbstractControllerIntegrationTest;
import org.dspace.builder.CollectionBuilder;
import org.dspace.builder.CommunityBuilder;
@@ -442,7 +445,7 @@ public class MappedCollectionRestRepositoryIT extends AbstractControllerIntegrat
getClient(adminToken)
.perform(post("/api/core/items/" + publicItem1.getID() + "/mappedCollections/")
.contentType(parseMediaType(TEXT_URI_LIST_VALUE))
.content("https://localhost:8080/spring-rest/api/core/collections/" + col1.getID() )
.content("https://localhost:8080/spring-rest/api/core/collections/" + col1.getID())
)
.andExpect(status().isUnprocessableEntity());
}
@@ -502,7 +505,7 @@ public class MappedCollectionRestRepositoryIT extends AbstractControllerIntegrat
getClient(adminToken)
.perform(post("/api/core/items/" + templateItem.getID() + "/mappedCollections/")
.contentType(parseMediaType(TEXT_URI_LIST_VALUE))
.content("https://localhost:8080/spring-rest/api/core/collections/" + col2.getID() )
.content("https://localhost:8080/spring-rest/api/core/collections/" + col2.getID())
)
.andExpect(status().is(405));
}
@@ -697,4 +700,125 @@ public class MappedCollectionRestRepositoryIT extends AbstractControllerIntegrat
}
@Test
public void mappedItemAppearsInCollectionBrowseTest() throws Exception {
context.turnOffAuthorisationSystem();
//** GIVEN **
//1. A community-collection structure with one parent community with two collections.
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community")
.build();
Collection source = CollectionBuilder.createCollection(context, parentCommunity).withName("Source").build();
Collection sink = CollectionBuilder.createCollection(context, parentCommunity).withName("Sink").build();
//2. An item in the source collection
Item item = ItemBuilder.createItem(context, source)
.withTitle("Mapped item")
.withIssueDate("2020")
.build();
context.restoreAuthSystemState();
String adminToken = getAuthToken(admin.getEmail(), password);
// Source collection browse is empty
getClient().perform(
get("/api/discover/search/objects")
.param("dsoType", "ITEM")
.param("scope", sink.getID().toString()))
// should return with 200 OK
.andExpect(status().isOk())
// should contain no search results
.andExpect(jsonPath("$._embedded.searchResult.page", is(
PageMatcher.pageEntryWithTotalPagesAndElements(0, 20, 0, 0)
)));
// Map the item to the sink collection
getClient(adminToken).perform(
post("/api/core/items/" + item.getID() + "/mappedCollections/")
.contentType(parseMediaType(TEXT_URI_LIST_VALUE))
.content(
"https://localhost:8080/spring-rest/api/core/collections/" + sink.getID() + "\n"
)
);
// Source collection browse contains mapped item
getClient().perform(
get("/api/discover/search/objects")
.param("dsoType", "ITEM")
.param("scope", sink.getID().toString()))
// should return with 200 OK
.andExpect(status().isOk())
// should contain no search results
.andExpect(jsonPath("$._embedded.searchResult.page", is(
PageMatcher.pageEntryWithTotalPagesAndElements(0, 20, 1, 1)
)))
// should match mapped item title
.andExpect(jsonPath("$._embedded.searchResult._embedded.objects", Matchers.containsInAnyOrder(
SearchResultMatcher.matchOnItemName("item", "items", "Mapped item")
)));
}
@Test
public void unmappedItemIsRemovedFromCollectionBrowseTest() throws Exception {
context.turnOffAuthorisationSystem();
//** GIVEN **
//1. A community-collection structure with one parent community with two collections.
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community")
.build();
Collection source = CollectionBuilder.createCollection(context, parentCommunity).withName("Source").build();
Collection sink = CollectionBuilder.createCollection(context, parentCommunity).withName("Sink").build();
//2. An item in the source collection
Item item = ItemBuilder.createItem(context, source)
.withTitle("Mapped item")
.withIssueDate("2020")
.build();
context.restoreAuthSystemState();
String adminToken = getAuthToken(admin.getEmail(), password);
//3. The item mapped to the sink collection
getClient(adminToken).perform(
post("/api/core/items/" + item.getID() + "/mappedCollections/")
.contentType(parseMediaType(TEXT_URI_LIST_VALUE))
.content(
"https://localhost:8080/spring-rest/api/core/collections/" + sink.getID() + "\n"
)
);
// Source collection browse contains mapped item
getClient().perform(
get("/api/discover/search/objects")
.param("dsoType", "ITEM")
.param("scope", sink.getID().toString()))
// should return with 200 OK
.andExpect(status().isOk())
// should contain no search results
.andExpect(jsonPath("$._embedded.searchResult.page", is(
PageMatcher.pageEntryWithTotalPagesAndElements(0, 20, 1, 1)
)))
// should match mapped item title
.andExpect(jsonPath("$._embedded.searchResult._embedded.objects", Matchers.containsInAnyOrder(
SearchResultMatcher.matchOnItemName("item", "items", "Mapped item")
)));
// Unmap item from sink collection
getClient(adminToken).perform(
delete("/api/core/items/" + item.getID() + "/mappedCollections/" + sink.getID()));
// Source collection browse is empty
getClient().perform(
get("/api/discover/search/objects")
.param("dsoType", "ITEM")
.param("scope", sink.getID().toString()))
// should return with 200 OK
.andExpect(status().isOk())
// should contain no search results
.andExpect(jsonPath("$._embedded.searchResult.page", is(
PageMatcher.pageEntryWithTotalPagesAndElements(0, 20, 0, 0)
)));
}
}

View File

@@ -29,6 +29,7 @@ import org.dspace.app.rest.projection.Projection;
import org.dspace.app.rest.test.AbstractControllerIntegrationTest;
import org.dspace.builder.MetadataSchemaBuilder;
import org.dspace.content.MetadataSchema;
import org.dspace.content.factory.ContentServiceFactory;
import org.hamcrest.Matchers;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
@@ -271,74 +272,85 @@ public class MetadataSchemaRestRepositoryIT extends AbstractControllerIntegratio
@Test
public void findAllPaginationTest() throws Exception {
// Determine number of schemas from database
int numberOfSchema = ContentServiceFactory.getInstance()
.getMetadataSchemaService().findAll(context).size();
// If we return 6 schema per page, determine number of pages we expect
int pageSize = 6;
int numberOfPages = (int) Math.ceil((double) numberOfSchema / pageSize);
// In these tests we just validate the first 3 pages, as we currently have at least that many schema
getClient().perform(get("/api/core/metadataschemas")
.param("size", "6")
.param("size", String.valueOf(pageSize))
.param("page", "0"))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.metadataschemas", Matchers.hasItem(matchEntry())))
.andExpect(jsonPath("$._links.first.href", Matchers.allOf(
Matchers.containsString("/api/core/metadataschemas?"),
Matchers.containsString("page=0"), Matchers.containsString("size=6"))))
Matchers.containsString("page=0"), Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$._links.self.href", Matchers.allOf(
Matchers.containsString("/api/core/metadataschemas?"),
Matchers.containsString("page=0"), Matchers.containsString("size=6"))))
Matchers.containsString("page=0"), Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$._links.next.href", Matchers.allOf(
Matchers.containsString("/api/core/metadataschemas?"),
Matchers.containsString("page=1"), Matchers.containsString("size=6"))))
Matchers.containsString("page=1"), Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$._links.last.href", Matchers.allOf(
Matchers.containsString("/api/core/metadataschemas?"),
Matchers.containsString("page=2"), Matchers.containsString("size=6"))))
.andExpect(jsonPath("$.page.totalElements", is(16)))
.andExpect(jsonPath("$.page.totalPages", is(3)))
.andExpect(jsonPath("$.page.size", is(6)));
Matchers.containsString("page=" + (numberOfPages - 1)),
Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$.page.totalElements", is(numberOfSchema)))
.andExpect(jsonPath("$.page.totalPages", is(numberOfPages)))
.andExpect(jsonPath("$.page.size", is(pageSize)));
getClient().perform(get("/api/core/metadataschemas")
.param("size", "6")
.param("size", String.valueOf(pageSize))
.param("page", "1"))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.metadataschemas", Matchers.hasItem(matchEntry())))
.andExpect(jsonPath("$._links.first.href", Matchers.allOf(
Matchers.containsString("/api/core/metadataschemas?"),
Matchers.containsString("page=0"), Matchers.containsString("size=6"))))
Matchers.containsString("page=0"), Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$._links.prev.href", Matchers.allOf(
Matchers.containsString("/api/core/metadataschemas?"),
Matchers.containsString("page=0"), Matchers.containsString("size=6"))))
Matchers.containsString("page=0"), Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$._links.self.href", Matchers.allOf(
Matchers.containsString("/api/core/metadataschemas?"),
Matchers.containsString("page=1"), Matchers.containsString("size=6"))))
Matchers.containsString("page=1"), Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$._links.next.href", Matchers.allOf(
Matchers.containsString("/api/core/metadataschemas?"),
Matchers.containsString("page=2"), Matchers.containsString("size=6"))))
Matchers.containsString("page=2"), Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$._links.last.href", Matchers.allOf(
Matchers.containsString("/api/core/metadataschemas?"),
Matchers.containsString("page=2"), Matchers.containsString("size=6"))))
.andExpect(jsonPath("$.page.totalElements", is(16)))
.andExpect(jsonPath("$.page.totalPages", is(3)))
.andExpect(jsonPath("$.page.size", is(6)));
Matchers.containsString("page=" + (numberOfPages - 1)),
Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$.page.totalElements", is(numberOfSchema)))
.andExpect(jsonPath("$.page.totalPages", is(numberOfPages)))
.andExpect(jsonPath("$.page.size", is(pageSize)));
getClient().perform(get("/api/core/metadataschemas")
.param("size", "6")
.param("size", String.valueOf(pageSize))
.param("page", "2"))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.metadataschemas", Matchers.hasItem(matchEntry())))
.andExpect(jsonPath("$._links.first.href", Matchers.allOf(
Matchers.containsString("/api/core/metadataschemas?"),
Matchers.containsString("page=0"), Matchers.containsString("size=6"))))
Matchers.containsString("page=0"), Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$._links.prev.href", Matchers.allOf(
Matchers.containsString("/api/core/metadataschemas?"),
Matchers.containsString("page=1"), Matchers.containsString("size=6"))))
Matchers.containsString("page=1"), Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$._links.self.href", Matchers.allOf(
Matchers.containsString("/api/core/metadataschemas?"),
Matchers.containsString("page=2"), Matchers.containsString("size=6"))))
Matchers.containsString("page=2"), Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$._links.last.href", Matchers.allOf(
Matchers.containsString("/api/core/metadataschemas?"),
Matchers.containsString("page=2"), Matchers.containsString("size=6"))))
.andExpect(jsonPath("$.page.totalElements", is(16)))
.andExpect(jsonPath("$.page.totalPages", is(3)))
.andExpect(jsonPath("$.page.size", is(6)));
Matchers.containsString("page=" + (numberOfPages - 1)),
Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$.page.totalElements", is(numberOfSchema)))
.andExpect(jsonPath("$.page.totalPages", is(numberOfPages)))
.andExpect(jsonPath("$.page.size", is(pageSize)));
}

View File

@@ -32,6 +32,7 @@ import org.dspace.builder.MetadataSchemaBuilder;
import org.dspace.content.MetadataField;
import org.dspace.content.MetadataFieldServiceImpl;
import org.dspace.content.MetadataSchema;
import org.dspace.content.factory.ContentServiceFactory;
import org.dspace.content.service.MetadataSchemaService;
import org.hamcrest.Matchers;
import org.junit.Before;
@@ -966,11 +967,21 @@ public class MetadatafieldRestRepositoryIT extends AbstractControllerIntegration
@Test
public void findAllPaginationTest() throws Exception {
// Determine number of metadata fields from database
int numberOfMdFields = ContentServiceFactory.getInstance().getMetadataFieldService().findAll(context).size();
// If we return 3 fields per page, determine number of pages we expect
int pageSize = 3;
int numberOfPages = (int) Math.ceil((double) numberOfMdFields / pageSize);
// Check first page
getClient().perform(get("/api/core/metadatafields")
.param("size", "3")
.param("size", String.valueOf(pageSize))
.param("page", "0"))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
// Metadata fields are returned alphabetically. So, look for the first 3 alphabetically
.andExpect(jsonPath("$._embedded.metadatafields", Matchers.hasItems(
MetadataFieldMatcher.matchMetadataFieldByKeys("creativework","datePublished", null),
MetadataFieldMatcher.matchMetadataFieldByKeys("creativework", "editor", null),
@@ -978,25 +989,28 @@ public class MetadatafieldRestRepositoryIT extends AbstractControllerIntegration
)))
.andExpect(jsonPath("$._links.first.href", Matchers.allOf(
Matchers.containsString("/api/core/metadatafields?"),
Matchers.containsString("page=0"), Matchers.containsString("size=3"))))
Matchers.containsString("page=0"), Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$._links.self.href", Matchers.allOf(
Matchers.containsString("/api/core/metadatafields?"),
Matchers.containsString("page=0"), Matchers.containsString("size=3"))))
Matchers.containsString("page=0"), Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$._links.next.href", Matchers.allOf(
Matchers.containsString("/api/core/metadatafields?"),
Matchers.containsString("page=1"), Matchers.containsString("size=3"))))
Matchers.containsString("page=1"), Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$._links.last.href", Matchers.allOf(
Matchers.containsString("/api/core/metadatafields?"),
Matchers.containsString("page=63"), Matchers.containsString("size=3"))))
.andExpect(jsonPath("$.page.totalElements", is(192)))
.andExpect(jsonPath("$.page.totalPages", is(64)))
.andExpect(jsonPath("$.page.size", is(3)));
Matchers.containsString("page=" + (numberOfPages - 1)),
Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$.page.totalElements", is(numberOfMdFields)))
.andExpect(jsonPath("$.page.totalPages", is(numberOfPages)))
.andExpect(jsonPath("$.page.size", is(pageSize)));
// Check second page
getClient().perform(get("/api/core/metadatafields")
.param("size", "3")
.param("size", String.valueOf(pageSize))
.param("page", "1"))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
// Metadata fields are returned alphabetically. So, look for the next 3 alphabetically
.andExpect(jsonPath("$._embedded.metadatafields", Matchers.hasItems(
MetadataFieldMatcher.matchMetadataFieldByKeys("creativework","publisher", null),
MetadataFieldMatcher.matchMetadataFieldByKeys("creativeworkseries", "issn", null),
@@ -1004,48 +1018,53 @@ public class MetadatafieldRestRepositoryIT extends AbstractControllerIntegration
)))
.andExpect(jsonPath("$._links.first.href", Matchers.allOf(
Matchers.containsString("/api/core/metadatafields?"),
Matchers.containsString("page=0"), Matchers.containsString("size=3"))))
Matchers.containsString("page=0"), Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$._links.prev.href", Matchers.allOf(
Matchers.containsString("/api/core/metadatafields?"),
Matchers.containsString("page=0"), Matchers.containsString("size=3"))))
Matchers.containsString("page=0"), Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$._links.self.href", Matchers.allOf(
Matchers.containsString("/api/core/metadatafields?"),
Matchers.containsString("page=1"), Matchers.containsString("size=3"))))
Matchers.containsString("page=1"), Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$._links.next.href", Matchers.allOf(
Matchers.containsString("/api/core/metadatafields?"),
Matchers.containsString("page=2"), Matchers.containsString("size=3"))))
Matchers.containsString("page=2"), Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$._links.last.href", Matchers.allOf(
Matchers.containsString("/api/core/metadatafields?"),
Matchers.containsString("page=63"), Matchers.containsString("size=3"))))
.andExpect(jsonPath("$.page.totalElements", is(192)))
.andExpect(jsonPath("$.page.totalPages", is(64)))
.andExpect(jsonPath("$.page.size", is(3)));
Matchers.containsString("page=" + (numberOfPages - 1)),
Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$.page.totalElements", is(numberOfMdFields)))
.andExpect(jsonPath("$.page.totalPages", is(numberOfPages)))
.andExpect(jsonPath("$.page.size", is(pageSize)));
// Check last page
getClient().perform(get("/api/core/metadatafields")
.param("size", "3")
.param("page", "63"))
.param("size", String.valueOf(pageSize))
.param("page", String.valueOf(numberOfPages - 1)))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
// Metadata fields are returned alphabetically.
// So, on the last page we'll just ensure it *at least* includes the last field alphabetically
.andExpect(jsonPath("$._embedded.metadatafields", Matchers.hasItems(
MetadataFieldMatcher.matchMetadataFieldByKeys("relation","isVolumeOfJournal", null),
MetadataFieldMatcher.matchMetadataFieldByKeys("relationship", "type", null),
MetadataFieldMatcher.matchMetadataFieldByKeys("workflow", "score", null)
)))
.andExpect(jsonPath("$._links.first.href", Matchers.allOf(
Matchers.containsString("/api/core/metadatafields?"),
Matchers.containsString("page=0"), Matchers.containsString("size=3"))))
Matchers.containsString("page=0"), Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$._links.prev.href", Matchers.allOf(
Matchers.containsString("/api/core/metadatafields?"),
Matchers.containsString("page=62"), Matchers.containsString("size=3"))))
Matchers.containsString("page=" + (numberOfPages - 2)),
Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$._links.self.href", Matchers.allOf(
Matchers.containsString("/api/core/metadatafields?"),
Matchers.containsString("page=63"), Matchers.containsString("size=3"))))
Matchers.containsString("page=" + (numberOfPages - 1)),
Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$._links.last.href", Matchers.allOf(
Matchers.containsString("/api/core/metadatafields?"),
Matchers.containsString("page=63"), Matchers.containsString("size=3"))))
.andExpect(jsonPath("$.page.totalElements", is(192)))
.andExpect(jsonPath("$.page.totalPages", is(64)))
.andExpect(jsonPath("$.page.size", is(3)));
Matchers.containsString("page=" + (numberOfPages - 1)),
Matchers.containsString("size=" + pageSize))))
.andExpect(jsonPath("$.page.totalElements", is(numberOfMdFields)))
.andExpect(jsonPath("$.page.totalPages", is(numberOfPages)))
.andExpect(jsonPath("$.page.size", is(pageSize)));
}
}

View File

@@ -139,17 +139,17 @@ public class PatchMetadataIT extends AbstractEntityIntegrationTest {
.withTitle("Person 1")
.withPersonIdentifierFirstName("Sarah")
.withPersonIdentifierLastName("Dahlen")
.withRelationshipType("Person")
.withEntityType("Person")
.build();
personItem2 = ItemBuilder.createItem(context, collection)
.withTitle("Person 2")
.withPersonIdentifierFirstName("Oliver")
.withPersonIdentifierLastName("Linton")
.withRelationshipType("Person")
.withEntityType("Person")
.build();
publicationItem = WorkspaceItemBuilder.createWorkspaceItem(context, collection)
.withTitle("Publication 1")
.withRelationshipType("Publication")
.withEntityType("Publication")
.build();
publicationPersonRelationshipType = relationshipTypeService.findbyTypesAndTypeName(context,
entityTypeService.findByEntityType(context, "Publication"),
@@ -257,7 +257,7 @@ public class PatchMetadataIT extends AbstractEntityIntegrationTest {
publicationItem = WorkspaceItemBuilder.createWorkspaceItem(context, collection)
.withTitle("Publication 1")
.withRelationshipType("Publication")
.withEntityType("Publication")
.build();
String adminToken = getAuthToken(admin.getEmail(), password);

View File

@@ -7,8 +7,12 @@
*/
package org.dspace.app.rest;
import static java.util.Arrays.asList;
import static java.util.stream.Collectors.toList;
import static org.dspace.content.Item.ANY;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.startsWith;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
@@ -117,11 +121,11 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio
leftItem = ItemBuilder.createItem(context, collection)
.withTitle("Left item")
.withRelationshipType("Publication")
.withEntityType("Publication")
.build();
rightItem = ItemBuilder.createItem(context, collection)
.withTitle("Right item")
.withRelationshipType("Person")
.withEntityType("Person")
.withPersonIdentifierFirstName("firstName")
.withPersonIdentifierLastName("familyName")
.build();
@@ -141,12 +145,12 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio
leftItem = ItemBuilder.createItem(context, collection)
.withTitle("Left item")
.withRelationshipType("JournalIssue")
.withEntityType("JournalIssue")
.withPublicationIssueNumber("2")
.build();
rightItem = ItemBuilder.createItem(context, collection)
.withTitle("Right item")
.withRelationshipType("JournalVolume")
.withEntityType("JournalVolume")
.withPublicationVolumeNumber("30")
.build();
relationshipType = relationshipTypeService
@@ -166,15 +170,15 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio
.withTitle("Person 1")
.withPersonIdentifierFirstName("Donald")
.withPersonIdentifierLastName("Smith")
.withRelationshipType("Person")
.withEntityType("Person")
.build();
projectItem = ItemBuilder.createItem(context, collection)
.withTitle("Project 1")
.withRelationshipType("Project")
.withEntityType("Project")
.build();
publicationItem = ItemBuilder.createItem(context, collection)
.withTitle("Publication 1")
.withRelationshipType("Publication")
.withEntityType("Publication")
.build();
personProjectRelationshipType = relationshipTypeService.findbyTypesAndTypeName(context,
entityTypeService.findByEntityType(context, "Person"),
@@ -221,6 +225,35 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio
public void testDeleteAuthorRelationshipCopyToLeftItem() throws Exception {
initPublicationAuthor();
// Verify the dc.contributor.author virtual metadata of the left item
assertEquals(
1,
itemService
.getMetadata(leftItem, "dc", "contributor", "author", Item.ANY)
.size()
);
// Verify there's no dc.contributor.author actual metadata on the left item
assertEquals(
0,
leftItem.getMetadata()
.stream()
.filter(metadataValue -> "author".equals(metadataValue.getMetadataField().getQualifier()))
.collect(toList())
.size()
);
// Verify there's no relation.isAuthorOfPublication actual metadata on the left item
assertEquals(
0,
leftItem.getMetadata()
.stream()
.filter(metadataValue -> "isAuthorOfPublication"
.equals(metadataValue.getMetadataField().getElement()))
.collect(toList())
.size()
);
getClient(adminAuthToken).perform(
delete("/api/core/relationships/" + relationship.getID() + "?copyVirtualMetadata=left"))
.andExpect(status().isNoContent());
@@ -235,12 +268,35 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio
assertThat(authorList.get(0).getMetadataField().getQualifier(), equalTo("author"));
assertNull(authorList.get(0).getAuthority());
// Check that the relation metadata values are gone because the relationship is gone
List<MetadataValue> relationshipMetadataList = itemService
.getMetadata(leftItem, "relation", "isAuthorOfPublication", null, Item.ANY);
assertThat(relationshipMetadataList.size(), equalTo(0));
assertThat(relationshipMetadataList.size(), equalTo(1));
// Verify there's dc.contributor.author actual metadata on the left item
assertEquals(
1,
leftItem.getMetadata()
.stream()
.filter(metadataValue -> metadataValue.getMetadataField().getQualifier() != null &&
metadataValue.getMetadataField().getQualifier().equals("author"))
.collect(toList())
.size()
);
// Verify there's relation.isAuthorOfPublication actual metadata on the left item
assertEquals(
1,
leftItem.getMetadata()
.stream()
.filter(metadataValue -> "isAuthorOfPublication"
.equals(metadataValue.getMetadataField().getElement()))
.collect(toList())
.size()
);
// Check right item to ensure that no metadata is copied
rightItem = context.reloadEntity(rightItem);
relationshipMetadataList = itemService
.getMetadata(rightItem, "relation", "isPublicationOfAuthor", null, Item.ANY);
assertThat(relationshipMetadataList.size(), equalTo(0));
@@ -250,6 +306,27 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio
public void testAuthorDeleteRelationshipCopyToRightItem() throws Exception {
initPublicationAuthor();
// Verify there's no dc.contributor.author actual metadata on the right item
assertEquals(
0,
rightItem.getMetadata()
.stream()
.filter(metadataValue -> "author".equals(metadataValue.getMetadataField().getQualifier()))
.collect(toList())
.size()
);
// Verify there's no relation.isPublicationOfAuthor actual metadata on the right item
assertEquals(
0,
rightItem.getMetadata()
.stream()
.filter(metadataValue -> "isPublicationOfAuthor"
.equals(metadataValue.getMetadataField().getElement()))
.collect(toList())
.size()
);
getClient(adminAuthToken).perform(
delete("/api/core/relationships/" + relationship.getID() + "?copyVirtualMetadata=right"))
.andExpect(status().isNoContent());
@@ -259,14 +336,27 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio
List<MetadataValue> authorList = itemService.getMetadata(leftItem, "dc", "contributor", "author", Item.ANY);
assertThat(authorList.size(), equalTo(0));
// Check that the relation metadata values are gone because the relationship is gone
List<MetadataValue> relationshipMetadataList = itemService
.getMetadata(leftItem, "relation", "isAuthorOfPublication", null, Item.ANY);
assertThat(relationshipMetadataList.size(), equalTo(0));
// Check right item to ensure that the metadata is copied
rightItem = itemService.find(context, rightItem.getID());
relationshipMetadataList = itemService
.getMetadata(rightItem, "relation", "isPublicationOfAuthor", null, Item.ANY);
assertThat(relationshipMetadataList.size(), equalTo(0));
assertThat(relationshipMetadataList.size(), equalTo(1));
// Verify there's relation.isPublicationOfAuthor actual metadata on the right item
assertEquals(
1,
rightItem.getMetadata()
.stream()
.filter(metadataValue -> "isPublicationOfAuthor"
.equals(metadataValue.getMetadataField().getElement()))
.collect(toList())
.size()
);
// There is no additional Metadata to check on the rightItem because the configuration of the virtual
// metadata holds no config to display virtual metadata on the author of the publication
@@ -291,11 +381,44 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio
List<MetadataValue> relationshipMetadataList = itemService
.getMetadata(leftItem, "relation", "isAuthorOfPublication", null, Item.ANY);
assertThat(relationshipMetadataList.size(), equalTo(0));
assertThat(relationshipMetadataList.size(), equalTo(1));
// Verify there's dc.contributor.author actual metadata on the left item
assertEquals(
1,
leftItem.getMetadata()
.stream()
.filter(metadataValue -> "author".equals(metadataValue.getMetadataField().getQualifier()))
.collect(toList())
.size()
);
// Verify there's relation.isAuthorOfPublication actual metadata on the left item
assertEquals(
1,
leftItem.getMetadata()
.stream()
.filter(metadataValue -> "isAuthorOfPublication"
.equals(metadataValue.getMetadataField().getElement()))
.collect(toList())
.size()
);
rightItem = itemService.find(context, rightItem.getID());
relationshipMetadataList = itemService
.getMetadata(rightItem, "relation", "isPublicationOfAuthor", null, Item.ANY);
assertThat(relationshipMetadataList.size(), equalTo(0));
assertThat(relationshipMetadataList.size(), equalTo(1));
// Verify there's relation.isPublicationOfAuthor actual metadata on the right item
assertEquals(
1,
rightItem.getMetadata()
.stream()
.filter(metadataValue -> "isPublicationOfAuthor"
.equals(metadataValue.getMetadataField().getElement()))
.collect(toList())
.size()
);
// There is no additional Metadata to check on the rightItem because the configuration of the virtual
// metadata holds no config to display virtual metadata on the author of the publication
@@ -375,6 +498,32 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio
public void deleteItemCopyVirtualMetadataAll() throws Exception {
initPersonProjectPublication();
for (Item item : asList(publicationItem, projectItem)) {
// Verify the dc.contributor.author virtual metadata
assertEquals(
1,
itemService.getMetadata(item, "dc", "contributor", "author", ANY).size()
);
// Verify there's no dc.contributor.author actual metadata on the item
assertEquals(
0,
item.getMetadata().stream()
.filter(metadataValue -> "author".equals(metadataValue.getMetadataField().getQualifier()))
.collect(toList()).size()
);
// Verify there's no relation.isAuthorOfPublication actual metadata on the item
assertEquals(
0,
item.getMetadata().stream()
.filter(metadataValue -> "isAuthorOfPublication"
.equals(metadataValue.getMetadataField().getElement()))
.collect(toList()).size()
);
}
getClient(adminAuthToken).perform(
delete("/api/core/items/" + personItem.getID() + "?copyVirtualMetadata=all"))
.andExpect(status().isNoContent());
@@ -387,7 +536,26 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio
assertNull(publicationAuthorList.get(0).getAuthority());
List<MetadataValue> publicationRelationships = itemService.getMetadata(publicationItem,
"relation", "isAuthorOfPublication", Item.ANY, Item.ANY);
assertThat(publicationRelationships.size(), equalTo(0));
assertThat(publicationRelationships.size(), equalTo(1));
// Verify there's dc.contributor.author actual metadata on the publication item
assertEquals(
1,
publicationItem.getMetadata().stream()
.filter(metadataValue -> "author".equals(metadataValue.getMetadataField().getQualifier()))
.collect(toList())
.size()
);
// Verify there's relation.isAuthorOfPublication actual metadata on the publication item
assertEquals(
1,
publicationItem.getMetadata().stream()
.filter(metadataValue -> "isAuthorOfPublication"
.equals(metadataValue.getMetadataField().getElement()))
.collect(toList())
.size()
);
projectItem = itemService.find(context, projectItem.getID());
List<MetadataValue> projectAuthorList = itemService.getMetadata(projectItem,
@@ -397,13 +565,58 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio
assertNull(projectAuthorList.get(0).getAuthority());
List<MetadataValue> projectRelationships = itemService.getMetadata(projectItem,
"relation", "isPersonOfProject", Item.ANY, Item.ANY);
assertThat(projectRelationships.size(), equalTo(0));
assertThat(projectRelationships.size(), equalTo(1));
// Verify there's dc.contributor.author actual metadata on the project item
assertEquals(
1,
projectItem.getMetadata().stream()
.filter(metadataValue -> "author".equals(metadataValue.getMetadataField().getQualifier()))
.collect(toList())
.size()
);
// Verify there's relation.isPersonOfProject actual metadata on the project item
assertEquals(
1,
projectItem.getMetadata().stream()
.filter(metadataValue -> "isPersonOfProject"
.equals(metadataValue.getMetadataField().getElement()))
.collect(toList())
.size()
);
}
@Test
public void deleteItemCopyVirtualMetadataOneType() throws Exception {
initPersonProjectPublication();
for (Item item : asList(publicationItem, projectItem)) {
// Verify the dc.contributor.author virtual metadata
assertEquals(
1,
itemService.getMetadata(item, "dc", "contributor", "author", ANY).size()
);
// Verify there's no dc.contributor.author actual metadata on the item
assertEquals(
0,
item.getMetadata().stream()
.filter(metadataValue -> "author".equals(metadataValue.getMetadataField().getQualifier()))
.collect(toList()).size()
);
// Verify there's no relation.isAuthorOfPublication actual metadata on the item
assertEquals(
0,
item.getMetadata().stream()
.filter(metadataValue -> "isAuthorOfPublication"
.equals(metadataValue.getMetadataField().getElement()))
.collect(toList()).size()
);
}
getClient(adminAuthToken).perform(
delete("/api/core/items/" + personItem.getID() + "?copyVirtualMetadata="
+ publicationPersonRelationshipType.getID()))
@@ -417,7 +630,26 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio
assertNull(publicationAuthorList.get(0).getAuthority());
List<MetadataValue> publicationRelationships = itemService.getMetadata(publicationItem,
"relation", "isAuthorOfPublication", Item.ANY, Item.ANY);
assertThat(publicationRelationships.size(), equalTo(0));
assertThat(publicationRelationships.size(), equalTo(1));
// Verify there's dc.contributor.author actual metadata on the publication item
assertEquals(
1,
publicationItem.getMetadata().stream()
.filter(metadataValue -> "author".equals(metadataValue.getMetadataField().getQualifier()))
.collect(toList())
.size()
);
// Verify there's relation.isAuthorOfPublication actual metadata on the publication item
assertEquals(
1,
publicationItem.getMetadata().stream()
.filter(metadataValue -> "isAuthorOfPublication"
.equals(metadataValue.getMetadataField().getElement()))
.collect(toList())
.size()
);
projectItem = itemService.find(context, projectItem.getID());
List<MetadataValue> projectAuthorList = itemService.getMetadata(projectItem,
@@ -432,6 +664,32 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio
public void deleteItemCopyVirtualMetadataTwoTypes() throws Exception {
initPersonProjectPublication();
for (Item item : asList(publicationItem, projectItem)) {
// Verify the dc.contributor.author virtual metadata
assertEquals(
1,
itemService.getMetadata(item, "dc", "contributor", "author", ANY).size()
);
// Verify there's no dc.contributor.author actual metadata on the item
assertEquals(
0,
item.getMetadata().stream()
.filter(metadataValue -> "author".equals(metadataValue.getMetadataField().getQualifier()))
.collect(toList()).size()
);
// Verify there's no relation.isAuthorOfPublication actual metadata on the item
assertEquals(
0,
item.getMetadata().stream()
.filter(metadataValue -> "isAuthorOfPublication"
.equals(metadataValue.getMetadataField().getElement()))
.collect(toList()).size()
);
}
getClient(adminAuthToken).perform(
delete("/api/core/items/" + personItem.getID()
+ "?copyVirtualMetadata=" + publicationPersonRelationshipType.getID()
@@ -446,7 +704,26 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio
assertNull(publicationAuthorList.get(0).getAuthority());
List<MetadataValue> publicationRelationships = itemService.getMetadata(publicationItem,
"relation", "isAuthorOfPublication", Item.ANY, Item.ANY);
assertThat(publicationRelationships.size(), equalTo(0));
assertThat(publicationRelationships.size(), equalTo(1));
// Verify there's dc.contributor.author actual metadata on the publication item
assertEquals(
1,
publicationItem.getMetadata().stream()
.filter(metadataValue -> "author".equals(metadataValue.getMetadataField().getQualifier()))
.collect(toList())
.size()
);
// Verify there's relation.isAuthorOfPublication actual metadata on the publication item
assertEquals(
1,
publicationItem.getMetadata().stream()
.filter(metadataValue -> "isAuthorOfPublication"
.equals(metadataValue.getMetadataField().getElement()))
.collect(toList())
.size()
);
projectItem = itemService.find(context, projectItem.getID());
List<MetadataValue> projectAuthorList = itemService.getMetadata(projectItem,
@@ -456,7 +733,26 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio
assertNull(projectAuthorList.get(0).getAuthority());
List<MetadataValue> projectRelationships = itemService.getMetadata(projectItem,
"relation", "isPersonOfProject", Item.ANY, Item.ANY);
assertThat(projectRelationships.size(), equalTo(0));
assertThat(projectRelationships.size(), equalTo(1));
// Verify there's dc.contributor.author actual metadata on the project item
assertEquals(
1,
projectItem.getMetadata().stream()
.filter(metadataValue -> "author".equals(metadataValue.getMetadataField().getQualifier()))
.collect(toList())
.size()
);
// Verify there's relation.isPersonOfProject actual metadata on the project item
assertEquals(
1,
projectItem.getMetadata().stream()
.filter(metadataValue -> "isPersonOfProject"
.equals(metadataValue.getMetadataField().getElement()))
.collect(toList())
.size()
);
}
@Test
@@ -520,6 +816,32 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio
public void deleteItemCopyVirtualMetadataAllNoPermissions() throws Exception {
initPersonProjectPublication();
for (Item item : asList(publicationItem, projectItem)) {
// Verify the dc.contributor.author virtual metadata
assertEquals(
1,
itemService.getMetadata(item, "dc", "contributor", "author", ANY).size()
);
// Verify there's no dc.contributor.author actual metadata on the item
assertEquals(
0,
item.getMetadata().stream()
.filter(metadataValue -> "author".equals(metadataValue.getMetadataField().getQualifier()))
.collect(toList()).size()
);
// Verify there's no relation.isAuthorOfPublication actual metadata on the item
assertEquals(
0,
item.getMetadata().stream()
.filter(metadataValue -> "isAuthorOfPublication"
.equals(metadataValue.getMetadataField().getElement()))
.collect(toList()).size()
);
}
getClient(getAuthToken(eperson.getEmail(), password)).perform(
delete("/api/core/items/" + personItem.getID()))
.andExpect(status().isForbidden());
@@ -608,6 +930,32 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio
public void deleteItemCopyVirtualMetadataConfigured() throws Exception {
initPersonProjectPublication();
for (Item item : asList(publicationItem, projectItem)) {
// Verify the dc.contributor.author virtual metadata
assertEquals(
1,
itemService.getMetadata(item, "dc", "contributor", "author", ANY).size()
);
// Verify there's no dc.contributor.author actual metadata on the item
assertEquals(
0,
item.getMetadata().stream()
.filter(metadataValue -> "author".equals(metadataValue.getMetadataField().getQualifier()))
.collect(toList()).size()
);
// Verify there's no relation.isAuthorOfPublication actual metadata on the item
assertEquals(
0,
item.getMetadata().stream()
.filter(metadataValue -> "isAuthorOfPublication"
.equals(metadataValue.getMetadataField().getElement()))
.collect(toList()).size()
);
}
getClient(adminAuthToken).perform(
delete("/api/core/items/" + personItem.getID() + "?copyVirtualMetadata=configured"))
.andExpect(status().isNoContent());
@@ -629,7 +977,26 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio
assertNull(projectAuthorList.get(0).getAuthority());
List<MetadataValue> projectRelationships = itemService.getMetadata(projectItem,
"relation", "isPersonOfProject", Item.ANY, Item.ANY);
assertThat(projectRelationships.size(), equalTo(0));
assertThat(projectRelationships.size(), equalTo(1));
// Verify there's dc.contributor.author actual metadata on the project item
assertEquals(
1,
projectItem.getMetadata().stream()
.filter(metadataValue -> "author".equals(metadataValue.getMetadataField().getQualifier()))
.collect(toList())
.size()
);
// Verify there's relation.isPersonOfProject actual metadata on the project item
assertEquals(
1,
projectItem.getMetadata().stream()
.filter(metadataValue -> "isPersonOfProject"
.equals(metadataValue.getMetadataField().getElement()))
.collect(toList())
.size()
);
}
@Test
@@ -653,7 +1020,7 @@ public class RelationshipDeleteRestRepositoryIT extends AbstractEntityIntegratio
assertNull(publicationAuthorList.get(0).getAuthority());
List<MetadataValue> publicationRelationships = itemService.getMetadata(publicationItem,
"relation", "isAuthorOfPublication", Item.ANY, Item.ANY);
assertThat(publicationRelationships.size(), equalTo(0));
assertThat(publicationRelationships.size(), equalTo(1));
projectItem = itemService.find(context, projectItem.getID());
List<MetadataValue> projectAuthorList = itemService.getMetadata(projectItem,

View File

@@ -143,14 +143,14 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
.withAuthor("Smith, Donald")
.withPersonIdentifierLastName("Smith")
.withPersonIdentifierFirstName("Donald")
.withRelationshipType("Person")
.withEntityType("Person")
.build();
author2 = ItemBuilder.createItem(context, col2)
.withTitle("Author2")
.withIssueDate("2016-02-13")
.withAuthor("Smith, Maria")
.withRelationshipType("Person")
.withEntityType("Person")
.build();
author3 = ItemBuilder.createItem(context, col2)
@@ -158,49 +158,49 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
.withIssueDate("2016-02-13")
.withPersonIdentifierFirstName("Maybe")
.withPersonIdentifierLastName("Maybe")
.withRelationshipType("Person")
.withEntityType("Person")
.build();
publication1 = ItemBuilder.createItem(context, col3)
.withTitle("Publication1")
.withAuthor("Testy, TEst")
.withIssueDate("2015-01-01")
.withRelationshipType("Publication")
.withEntityType("Publication")
.build();
publication2 = ItemBuilder.createItem(context, col3)
.withTitle("Publication2")
.withAuthor("Testy, TEst")
.withIssueDate("2015-01-01")
.withRelationshipType("Publication")
.withEntityType("Publication")
.build();
orgUnit1 = ItemBuilder.createItem(context, col3)
.withTitle("OrgUnit1")
.withAuthor("Testy, TEst")
.withIssueDate("2015-01-01")
.withRelationshipType("OrgUnit")
.withEntityType("OrgUnit")
.build();
orgUnit2 = ItemBuilder.createItem(context, col3)
.withTitle("OrgUnit2")
.withAuthor("Testy, TEst")
.withIssueDate("2015-01-01")
.withRelationshipType("OrgUnit")
.withEntityType("OrgUnit")
.build();
orgUnit3 = ItemBuilder.createItem(context, col3)
.withTitle("OrgUnit3")
.withAuthor("Test, Testy")
.withIssueDate("2015-02-01")
.withRelationshipType("OrgUnit")
.withEntityType("OrgUnit")
.build();
project1 = ItemBuilder.createItem(context, col3)
.withTitle("Project1")
.withAuthor("Testy, TEst")
.withIssueDate("2015-01-01")
.withRelationshipType("Project")
.withEntityType("Project")
.build();
isAuthorOfPublicationRelationshipType = relationshipTypeService
@@ -665,7 +665,7 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
.withIssueDate("2017-10-17")
.withPersonIdentifierFirstName("Donald")
.withPersonIdentifierLastName("Smith")
.withRelationshipType("Person")
.withEntityType("Person")
.build();
Item author2 = ItemBuilder.createItem(context, col2)
@@ -673,7 +673,7 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
.withIssueDate("2016-02-13")
.withPersonIdentifierFirstName("Maria")
.withPersonIdentifierLastName("Smith")
.withRelationshipType("Person")
.withEntityType("Person")
.build();
Item author3 = ItemBuilder.createItem(context, col2)
@@ -681,13 +681,13 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
.withIssueDate("2016-02-13")
.withPersonIdentifierFirstName("Maybe")
.withPersonIdentifierLastName("Maybe")
.withRelationshipType("Person")
.withEntityType("Person")
.build();
Item publication1 = ItemBuilder.createItem(context, col3)
.withTitle("Publication1")
.withIssueDate("2015-01-01")
.withRelationshipType("Publication")
.withEntityType("Publication")
.build();
RelationshipType isAuthorOfPublicationRelationshipType = relationshipTypeService
@@ -775,6 +775,7 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
.andExpect(status().isCreated())
.andDo(result -> idRef2.set(read(result.getResponse().getContentAsString(), "$.id")));
publication1 = itemService.find(context, publication1.getID());
list = itemService.getMetadata(publication1, "dc", "contributor", "author", Item.ANY);
// Ensure that we now have three dc.contributor.author mdv ("Smith, Donald", "plain text", "Smith, Maria"
// In that order which will be checked below the rest call
@@ -801,6 +802,7 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
itemService.update(context, publication1);
context.restoreAuthSystemState();
publication1 = itemService.find(context, publication1.getID());
list = itemService.getMetadata(publication1, "dc", "contributor", "author", Item.ANY);
// Assert that the list of dc.contributor.author mdv is now of size 4 in the following order:
@@ -838,6 +840,7 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
.andExpect(status().isCreated())
.andDo(result -> idRef3.set(read(result.getResponse().getContentAsString(), "$.id")));
publication1 = itemService.find(context, publication1.getID());
list = itemService.getMetadata(publication1, "dc", "contributor", "author", Item.ANY);
// Assert that our dc.contributor.author mdv list is now of size 5
assertEquals(5, list.size());
@@ -901,6 +904,7 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
itemService.update(context, publication1);
context.restoreAuthSystemState();
publication1 = itemService.find(context, publication1.getID());
list = itemService.getMetadata(publication1, "dc", "contributor", "author", Item.ANY);
assertEquals(10, list.size());
@@ -968,7 +972,7 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
Item publication1 = ItemBuilder.createItem(context, col3)
.withTitle("Publication1")
.withIssueDate("2015-01-01")
.withRelationshipType("Publication")
.withEntityType("Publication")
.build();
Item author2 = ItemBuilder.createItem(context, col2)
@@ -976,7 +980,7 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
.withIssueDate("2016-02-13")
.withPersonIdentifierFirstName("Maria")
.withPersonIdentifierLastName("Smith")
.withRelationshipType("Person")
.withEntityType("Person")
.build();
Item author3 = ItemBuilder.createItem(context, col2)
@@ -984,7 +988,7 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
.withIssueDate("2016-02-13")
.withPersonIdentifierFirstName("Maybe")
.withPersonIdentifierLastName("Maybe")
.withRelationshipType("Person")
.withEntityType("Person")
.build();
String adminToken = getAuthToken(admin.getEmail(), password);
@@ -1181,7 +1185,7 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
Item publication1 = ItemBuilder.createItem(context, col3)
.withTitle("Publication1")
.withIssueDate("2015-01-01")
.withRelationshipType("Publication")
.withEntityType("Publication")
.build();
Item author2 = ItemBuilder.createItem(context, col2)
@@ -1189,7 +1193,7 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
.withIssueDate("2016-02-13")
.withPersonIdentifierFirstName("Maria")
.withPersonIdentifierLastName("Smith")
.withRelationshipType("Person")
.withEntityType("Person")
.build();
Item author3 = ItemBuilder.createItem(context, col2)
@@ -1197,7 +1201,7 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
.withIssueDate("2016-02-13")
.withPersonIdentifierFirstName("Maybe")
.withPersonIdentifierLastName("Maybe")
.withRelationshipType("Person")
.withEntityType("Person")
.build();
String adminToken = getAuthToken(admin.getEmail(), password);
@@ -1395,7 +1399,7 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
.withIssueDate("2016-02-13")
.withPersonIdentifierFirstName("Maria")
.withPersonIdentifierLastName("Smith")
.withRelationshipType("Person")
.withEntityType("Person")
.build();
String adminToken = getAuthToken(admin.getEmail(), password);
@@ -2385,7 +2389,7 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
.withAuthor("Smith, Donald")
.withPersonIdentifierFirstName("testingFirstName")
.withPersonIdentifierLastName("testingLastName")
.withRelationshipType("Person")
.withEntityType("Person")
.build();
Relationship relationship3 = RelationshipBuilder
@@ -2755,15 +2759,15 @@ public class RelationshipRestRepositoryIT extends AbstractEntityIntegrationTest
// Create entity items
Item journal =
ItemBuilder.createItem(context, col1).withRelationshipType("Journal").withTitle(journalTitle).build();
ItemBuilder.createItem(context, col1).withEntityType("Journal").withTitle(journalTitle).build();
Item journalVolume =
ItemBuilder.createItem(context, col1).withRelationshipType("JournalVolume").withTitle("JournalVolume")
ItemBuilder.createItem(context, col1).withEntityType("JournalVolume").withTitle("JournalVolume")
.build();
Item journalIssue =
ItemBuilder.createItem(context, col1).withRelationshipType("JournalIssue").withTitle("JournalIssue")
ItemBuilder.createItem(context, col1).withEntityType("JournalIssue").withTitle("JournalIssue")
.build();
Item publication =
ItemBuilder.createItem(context, col1).withRelationshipType("Publication").withTitle("Publication").build();
ItemBuilder.createItem(context, col1).withEntityType("Publication").withTitle("Publication").build();
// Link Publication-Journal Issue
RelationshipBuilder.createRelationshipBuilder(context, journalIssue, publication, isPublicationOfJournalIssue)

View File

@@ -118,48 +118,48 @@ public class RelationshipTypeRestControllerIT extends AbstractEntityIntegrationT
.withTitle("Author1")
.withIssueDate("2017-10-17")
.withAuthor("Smith, Donald")
.withRelationshipType("Person")
.withEntityType("Person")
.build();
Item author2 = ItemBuilder.createItem(context, col2)
.withTitle("Author2")
.withIssueDate("2016-02-13")
.withAuthor("Smith, Maria")
.withRelationshipType("Person")
.withEntityType("Person")
.build();
Item author3 = ItemBuilder.createItem(context, col2)
.withTitle("Author3")
.withIssueDate("2016-02-13")
.withAuthor("Maybe, Maybe")
.withRelationshipType("Person")
.withEntityType("Person")
.build();
Item orgUnit1 = ItemBuilder.createItem(context, col3)
.withTitle("OrgUnit1")
.withAuthor("Testy, TEst")
.withIssueDate("2015-01-01")
.withRelationshipType("OrgUnit")
.withEntityType("OrgUnit")
.build();
Item project1 = ItemBuilder.createItem(context, col3)
.withTitle("Project1")
.withAuthor("Testy, TEst")
.withIssueDate("2015-01-01")
.withRelationshipType("Project")
.withEntityType("Project")
.build();
Item publication = ItemBuilder.createItem(context, col3)
.withTitle("Publication1")
.withAuthor("Testy, TEst")
.withIssueDate("2015-01-01")
.withRelationshipType("Publication")
.withEntityType("Publication")
.build();
Item publication2 = ItemBuilder.createItem(context, col3)
.withTitle("Publication2")
.withIssueDate("2015-01-01")
.withRelationshipType("Publication")
.withEntityType("Publication")
.build();
RelationshipType isOrgUnitOfPersonRelationshipType = relationshipTypeService

View File

@@ -4972,19 +4972,19 @@ public class WorkspaceItemRestRepositoryIT extends AbstractControllerIntegration
.withAuthor("Smith, Donald")
.withPersonIdentifierLastName("Smith")
.withPersonIdentifierFirstName("Donald")
.withRelationshipType("Person")
.withEntityType("Person")
.build();
Item author2 = ItemBuilder.createItem(context, col1)
.withTitle("Author2")
.withIssueDate("2016-02-13")
.withAuthor("Smith, Maria")
.withRelationshipType("Person")
.withEntityType("Person")
.build();
//2. One workspace item.
WorkspaceItem workspaceItem = WorkspaceItemBuilder.createWorkspaceItem(context, col1)
.withRelationshipType("Publication")
.withEntityType("Publication")
.build();
EntityType publication = EntityTypeBuilder.createEntityTypeBuilder(context, "Publication").build();

View File

@@ -0,0 +1,394 @@
/**
* 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.authorization;
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.test.AbstractControllerIntegrationTest;
import org.dspace.builder.CollectionBuilder;
import org.dspace.builder.CommunityBuilder;
import org.dspace.builder.EPersonBuilder;
import org.dspace.builder.GroupBuilder;
import org.dspace.content.Collection;
import org.dspace.content.Community;
import org.dspace.content.service.SiteService;
import org.dspace.eperson.EPerson;
import org.dspace.eperson.Group;
import org.dspace.eperson.service.GroupService;
import org.dspace.services.ConfigurationService;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
public class CollectionAdminFeatureIT extends AbstractControllerIntegrationTest {
@Autowired
private SiteService siteService;
@Autowired
private ConfigurationService configurationService;
@Autowired
private GroupService groupService;
private Community topLevelCommunityA;
private Community subCommunityA;
private Collection collectionA;
private EPerson topLevelCommunityAAdmin;
private EPerson subCommunityAAdmin;
private EPerson collectionAAdmin;
private EPerson submitter;
@Override
@Before
public void setUp() throws Exception {
super.setUp();
context.turnOffAuthorisationSystem();
topLevelCommunityAAdmin = EPersonBuilder.createEPerson(context)
.withNameInMetadata("Jhon", "Brown")
.withEmail("topLevelCommunityAAdmin@my.edu")
.withPassword(password)
.build();
topLevelCommunityA = CommunityBuilder.createCommunity(context)
.withName("The name of this community is topLevelCommunityA")
.withAdminGroup(topLevelCommunityAAdmin)
.build();
subCommunityAAdmin = EPersonBuilder.createEPerson(context)
.withNameInMetadata("Jhon", "Brown")
.withEmail("subCommunityAAdmin@my.edu")
.withPassword(password)
.build();
subCommunityA = CommunityBuilder.createCommunity(context)
.withName("The name of this sub-community is subCommunityA")
.withAdminGroup(subCommunityAAdmin)
.addParentCommunity(context, topLevelCommunityA)
.build();
submitter = EPersonBuilder.createEPerson(context)
.withNameInMetadata("Jhon", "Brown")
.withEmail("submitter@my.edu")
.withPassword(password)
.build();
collectionAAdmin = EPersonBuilder.createEPerson(context)
.withNameInMetadata("Jhon", "Brown")
.withEmail("collectionAAdmin@my.edu")
.withPassword(password)
.build();
collectionA = CollectionBuilder.createCollection(context, subCommunityA)
.withName("The name of this collection is collectionA")
.withAdminGroup(collectionAAdmin)
.withSubmitterGroup(submitter)
.build();
context.restoreAuthSystemState();
configurationService.setProperty(
"org.dspace.app.rest.authorization.AlwaysThrowExceptionFeature.turnoff", "true");
}
@Test
public void testAdmin() throws Exception {
String token = getAuthToken(admin.getEmail(), password);
// Verify the general admin has this feature
getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri="
+ "http://localhost/api/core/site/" + siteService.findSite(context).getID()))
.andExpect(status().isOk())
.andExpect(
jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='isCollectionAdmin')]")
.exists());
}
@Test
public void testCommunityAdmin() throws Exception {
String token = getAuthToken(topLevelCommunityAAdmin.getEmail(), password);
// Verify the community admin has this feature
getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri="
+ "http://localhost/api/core/site/" + siteService.findSite(context).getID()))
.andExpect(status().isOk())
.andExpect(
jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='isCollectionAdmin')]")
.exists());
}
@Test
public void testSubCommunityAdmin() throws Exception {
String token = getAuthToken(subCommunityAAdmin.getEmail(), password);
// Verify the subcommunity admin has this feature
getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri="
+ "http://localhost/api/core/site/" + siteService.findSite(context).getID()))
.andExpect(status().isOk())
.andExpect(
jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='isCollectionAdmin')]")
.exists());
}
@Test
public void testCollectionAdmin() throws Exception {
String token = getAuthToken(collectionAAdmin.getEmail(), password);
// Verify the collection admin has this feature
getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri="
+ "http://localhost/api/core/site/" + siteService.findSite(context).getID()))
.andExpect(status().isOk())
.andExpect(
jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='isCollectionAdmin')]")
.exists());
}
@Test
public void testSubmitter() throws Exception {
String token = getAuthToken(submitter.getEmail(), password);
// Verify a submitter doesn't have this feature
getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri="
+ "http://localhost/api/core/site/" + siteService.findSite(context).getID()))
.andExpect(status().isOk())
.andExpect(
jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='isCollectionAdmin')]")
.doesNotExist());
}
@Test
public void testSubGroupOfAdminGroup() throws Exception {
context.turnOffAuthorisationSystem();
GroupBuilder.createGroup(context)
.withName("userGroup")
.withParent(groupService.findByName(context, Group.ADMIN))
.addMember(eperson)
.build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
// Verify an ePerson in a subgroup of the site administrators has this feature
getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri="
+ "http://localhost/api/core/site/" + siteService.findSite(context).getID()))
.andExpect(status().isOk())
.andExpect(
jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='isCollectionAdmin')]")
.exists());
}
@Test
public void testSubGroupOfCommunityAdminGroup() throws Exception {
context.turnOffAuthorisationSystem();
GroupBuilder.createGroup(context)
.withName("userGroup")
.withParent(groupService.findByName(context, "COMMUNITY_" + topLevelCommunityA.getID() + "_ADMIN"))
.addMember(eperson)
.build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
// Verify an ePerson in a subgroup of a community admin group has this feature
getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri="
+ "http://localhost/api/core/site/" + siteService.findSite(context).getID()))
.andExpect(status().isOk())
.andExpect(
jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='isCollectionAdmin')]")
.exists());
}
@Test
public void testSubGroupOfSubCommunityAdminGroup() throws Exception {
context.turnOffAuthorisationSystem();
GroupBuilder.createGroup(context)
.withName("userGroup")
.withParent(groupService.findByName(context, "COMMUNITY_" + subCommunityA.getID() + "_ADMIN"))
.addMember(eperson)
.build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
// Verify an ePerson in a subgroup of a subcommunity admin group has this feature
getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri="
+ "http://localhost/api/core/site/" + siteService.findSite(context).getID()))
.andExpect(status().isOk())
.andExpect(
jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='isCollectionAdmin')]")
.exists());
}
@Test
public void testSubGroupOfCollectionAdminGroup() throws Exception {
context.turnOffAuthorisationSystem();
GroupBuilder.createGroup(context)
.withName("userGroup")
.withParent(groupService.findByName(context, "COLLECTION_" + collectionA.getID() + "_ADMIN"))
.addMember(eperson)
.build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
// Verify an ePerson in a subgroup of a collection admin group has this feature
getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri="
+ "http://localhost/api/core/site/" + siteService.findSite(context).getID()))
.andExpect(status().isOk())
.andExpect(
jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='isCollectionAdmin')]")
.exists());
}
@Test
public void testSubGroupOfSubmitterGroup() throws Exception {
context.turnOffAuthorisationSystem();
GroupBuilder.createGroup(context)
.withName("userGroup")
.withParent(groupService.findByName(context, "COLLECTION_" + collectionA.getID() + "_SUBMIT"))
.addMember(eperson)
.build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
// Verify an ePerson in a subgroup of submitter group doesn't have this feature
getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri="
+ "http://localhost/api/core/site/" + siteService.findSite(context).getID()))
.andExpect(status().isOk())
.andExpect(
jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='isCollectionAdmin')]")
.doesNotExist());
}
@Test
public void testSubSubGroupOfAdminGroup() throws Exception {
context.turnOffAuthorisationSystem();
Group groupB = GroupBuilder.createGroup(context)
.withName("GroupB")
.withParent(groupService.findByName(context, Group.ADMIN))
.build();
GroupBuilder.createGroup(context)
.withName("GroupA")
.withParent(groupB)
.addMember(eperson)
.build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
// Verify an ePerson in a sub-subgroup of the site administrators has this feature
getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri="
+ "http://localhost/api/core/site/" + siteService.findSite(context).getID()))
.andExpect(status().isOk())
.andExpect(
jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='isCollectionAdmin')]")
.exists());
}
@Test
public void testSubSubGroupOfCommunityAdminGroup() throws Exception {
context.turnOffAuthorisationSystem();
Group groupB = GroupBuilder.createGroup(context)
.withName("GroupB")
.withParent(groupService.findByName(context, "COMMUNITY_" + topLevelCommunityA.getID() + "_ADMIN"))
.build();
GroupBuilder.createGroup(context)
.withName("GroupA")
.withParent(groupB)
.addMember(eperson)
.build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
// Verify an ePerson in a sub-subgroup of a community admin group has this feature
getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri="
+ "http://localhost/api/core/site/" + siteService.findSite(context).getID()))
.andExpect(status().isOk())
.andExpect(
jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='isCollectionAdmin')]")
.exists());
}
@Test
public void testSubSubGroupOfSubCommunityAdminGroup() throws Exception {
context.turnOffAuthorisationSystem();
Group groupB = GroupBuilder.createGroup(context)
.withName("GroupB")
.withParent(groupService.findByName(context, "COMMUNITY_" + subCommunityA.getID() + "_ADMIN"))
.build();
GroupBuilder.createGroup(context)
.withName("GroupA")
.withParent(groupB)
.addMember(eperson)
.build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
// Verify an ePerson in a sub-subgroup of a subcommunity admin group has this feature
getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri="
+ "http://localhost/api/core/site/" + siteService.findSite(context).getID()))
.andExpect(status().isOk())
.andExpect(
jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='isCollectionAdmin')]")
.exists());
}
@Test
public void testSubSubGroupOfCollectionAdminGroup() throws Exception {
context.turnOffAuthorisationSystem();
Group groupB = GroupBuilder.createGroup(context)
.withName("GroupB")
.withParent(groupService.findByName(context, "COLLECTION_" + collectionA.getID() + "_ADMIN"))
.build();
GroupBuilder.createGroup(context)
.withName("GroupA")
.withParent(groupB)
.addMember(eperson)
.build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
// Verify an ePerson in a sub-subgroup of a collection admin group has this feature
getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri="
+ "http://localhost/api/core/site/" + siteService.findSite(context).getID()))
.andExpect(status().isOk())
.andExpect(
jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='isCollectionAdmin')]")
.exists());
}
@Test
public void testSubSubGroupOfSubmitterGroup() throws Exception {
context.turnOffAuthorisationSystem();
Group groupB = GroupBuilder.createGroup(context)
.withName("GroupB")
.withParent(groupService.findByName(context, "COLLECTION_" + collectionA.getID() + "_SUBMIT"))
.build();
GroupBuilder.createGroup(context)
.withName("GroupA")
.withParent(groupB)
.addMember(eperson)
.build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
// Verify an ePerson in a sub-subgroup of submitter group doesn't have this feature
getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri="
+ "http://localhost/api/core/site/" + siteService.findSite(context).getID()))
.andExpect(status().isOk())
.andExpect(
jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='isCollectionAdmin')]")
.doesNotExist());
}
}

View File

@@ -0,0 +1,394 @@
/**
* 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.authorization;
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.test.AbstractControllerIntegrationTest;
import org.dspace.builder.CollectionBuilder;
import org.dspace.builder.CommunityBuilder;
import org.dspace.builder.EPersonBuilder;
import org.dspace.builder.GroupBuilder;
import org.dspace.content.Collection;
import org.dspace.content.Community;
import org.dspace.content.service.SiteService;
import org.dspace.eperson.EPerson;
import org.dspace.eperson.Group;
import org.dspace.eperson.service.GroupService;
import org.dspace.services.ConfigurationService;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
public class ComColAdminFeatureIT extends AbstractControllerIntegrationTest {
@Autowired
private SiteService siteService;
@Autowired
private ConfigurationService configurationService;
@Autowired
private GroupService groupService;
private Community topLevelCommunity;
private Community subCommunity;
private Collection collection;
private EPerson communityAdmin;
private EPerson subCommunityAdmin;
private EPerson collectionAdmin;
private EPerson submitter;
@Override
@Before
public void setUp() throws Exception {
super.setUp();
context.turnOffAuthorisationSystem();
communityAdmin = EPersonBuilder.createEPerson(context)
.withNameInMetadata("Jhon", "Brown")
.withEmail("communityAdmin@my.edu")
.withPassword(password)
.build();
topLevelCommunity = CommunityBuilder.createCommunity(context)
.withName("topLevelCommunity")
.withAdminGroup(communityAdmin)
.build();
subCommunityAdmin = EPersonBuilder.createEPerson(context)
.withNameInMetadata("Jhon", "Brown")
.withEmail("subCommunityAdmin@my.edu")
.withPassword(password)
.build();
subCommunity = CommunityBuilder.createCommunity(context)
.withName("subCommunity")
.withAdminGroup(subCommunityAdmin)
.addParentCommunity(context, topLevelCommunity)
.build();
submitter = EPersonBuilder.createEPerson(context)
.withNameInMetadata("Jhon", "Brown")
.withEmail("submitter@my.edu")
.withPassword(password)
.build();
collectionAdmin = EPersonBuilder.createEPerson(context)
.withNameInMetadata("Jhon", "Brown")
.withEmail("collectionAdmin@my.edu")
.withPassword(password)
.build();
collection = CollectionBuilder.createCollection(context, subCommunity)
.withName("collection")
.withAdminGroup(collectionAdmin)
.withSubmitterGroup(submitter)
.build();
context.restoreAuthSystemState();
configurationService.setProperty(
"org.dspace.app.rest.authorization.AlwaysThrowExceptionFeature.turnoff", "true");
}
@Test
public void testAdmin() throws Exception {
String token = getAuthToken(admin.getEmail(), password);
// Verify the general admin has this feature
getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri="
+ "http://localhost/api/core/site/" + siteService.findSite(context).getID()))
.andExpect(status().isOk())
.andExpect(
jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='isComColAdmin')]")
.exists());
}
@Test
public void testCommunityAdmin() throws Exception {
String token = getAuthToken(communityAdmin.getEmail(), password);
// Verify the community admin has this feature
getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri="
+ "http://localhost/api/core/site/" + siteService.findSite(context).getID()))
.andExpect(status().isOk())
.andExpect(
jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='isComColAdmin')]")
.exists());
}
@Test
public void testSubCommunityAdmin() throws Exception {
String token = getAuthToken(subCommunityAdmin.getEmail(), password);
// Verify the subcommunity admin has this feature
getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri="
+ "http://localhost/api/core/site/" + siteService.findSite(context).getID()))
.andExpect(status().isOk())
.andExpect(
jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='isComColAdmin')]")
.exists());
}
@Test
public void testCollectionAdmin() throws Exception {
String token = getAuthToken(collectionAdmin.getEmail(), password);
// Verify the collection admin has this feature
getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri="
+ "http://localhost/api/core/site/" + siteService.findSite(context).getID()))
.andExpect(status().isOk())
.andExpect(
jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='isComColAdmin')]")
.exists());
}
@Test
public void testSubmitter() throws Exception {
String token = getAuthToken(submitter.getEmail(), password);
// Verify a submitter doesn't have this feature
getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri="
+ "http://localhost/api/core/site/" + siteService.findSite(context).getID()))
.andExpect(status().isOk())
.andExpect(
jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='isComColAdmin')]")
.doesNotExist());
}
@Test
public void testSubGroupOfAdminGroup() throws Exception {
context.turnOffAuthorisationSystem();
GroupBuilder.createGroup(context)
.withName("userGroup")
.withParent(groupService.findByName(context, Group.ADMIN))
.addMember(eperson)
.build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
// Verify an ePerson in a subgroup of the site administrators has this feature
getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri="
+ "http://localhost/api/core/site/" + siteService.findSite(context).getID()))
.andExpect(status().isOk())
.andExpect(
jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='isComColAdmin')]")
.exists());
}
@Test
public void testSubGroupOfCommunityAdminGroup() throws Exception {
context.turnOffAuthorisationSystem();
GroupBuilder.createGroup(context)
.withName("userGroup")
.withParent(groupService.findByName(context, "COMMUNITY_" + topLevelCommunity.getID() + "_ADMIN"))
.addMember(eperson)
.build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
// Verify an ePerson in a subgroup of a community admin group has this feature
getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri="
+ "http://localhost/api/core/site/" + siteService.findSite(context).getID()))
.andExpect(status().isOk())
.andExpect(
jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='isComColAdmin')]")
.exists());
}
@Test
public void testSubGroupOfSubCommunityAdminGroup() throws Exception {
context.turnOffAuthorisationSystem();
GroupBuilder.createGroup(context)
.withName("userGroup")
.withParent(groupService.findByName(context, "COMMUNITY_" + subCommunity.getID() + "_ADMIN"))
.addMember(eperson)
.build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
// Verify an ePerson in a subgroup of a subcommunity admin group has this feature
getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri="
+ "http://localhost/api/core/site/" + siteService.findSite(context).getID()))
.andExpect(status().isOk())
.andExpect(
jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='isComColAdmin')]")
.exists());
}
@Test
public void testSubGroupOfCollectionAdminGroup() throws Exception {
context.turnOffAuthorisationSystem();
GroupBuilder.createGroup(context)
.withName("userGroup")
.withParent(groupService.findByName(context, "COLLECTION_" + collection.getID() + "_ADMIN"))
.addMember(eperson)
.build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
// Verify an ePerson in a subgroup of a collection admin group has this feature
getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri="
+ "http://localhost/api/core/site/" + siteService.findSite(context).getID()))
.andExpect(status().isOk())
.andExpect(
jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='isComColAdmin')]")
.exists());
}
@Test
public void testSubGroupOfSubmitterGroup() throws Exception {
context.turnOffAuthorisationSystem();
GroupBuilder.createGroup(context)
.withName("userGroup")
.withParent(groupService.findByName(context, "COLLECTION_" + collection.getID() + "_SUBMIT"))
.addMember(eperson)
.build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
// Verify an ePerson in a subgroup of submitter group doesn't have this feature
getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri="
+ "http://localhost/api/core/site/" + siteService.findSite(context).getID()))
.andExpect(status().isOk())
.andExpect(
jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='isComColAdmin')]")
.doesNotExist());
}
@Test
public void testSubSubGroupOfAdminGroup() throws Exception {
context.turnOffAuthorisationSystem();
Group groupB = GroupBuilder.createGroup(context)
.withName("GroupB")
.withParent(groupService.findByName(context, Group.ADMIN))
.build();
GroupBuilder.createGroup(context)
.withName("GroupA")
.withParent(groupB)
.addMember(eperson)
.build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
// Verify an ePerson in a sub-subgroup of the site administrators has this feature
getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri="
+ "http://localhost/api/core/site/" + siteService.findSite(context).getID()))
.andExpect(status().isOk())
.andExpect(
jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='isComColAdmin')]")
.exists());
}
@Test
public void testSubSubGroupOfCommunityAdminGroup() throws Exception {
context.turnOffAuthorisationSystem();
Group groupB = GroupBuilder.createGroup(context)
.withName("GroupB")
.withParent(groupService.findByName(context, "COMMUNITY_" + topLevelCommunity.getID() + "_ADMIN"))
.build();
GroupBuilder.createGroup(context)
.withName("GroupA")
.withParent(groupB)
.addMember(eperson)
.build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
// Verify an ePerson in a sub-subgroup of a community admin group has this feature
getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri="
+ "http://localhost/api/core/site/" + siteService.findSite(context).getID()))
.andExpect(status().isOk())
.andExpect(
jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='isComColAdmin')]")
.exists());
}
@Test
public void testSubSubGroupOfSubCommunityAdminGroup() throws Exception {
context.turnOffAuthorisationSystem();
Group groupB = GroupBuilder.createGroup(context)
.withName("GroupB")
.withParent(groupService.findByName(context, "COMMUNITY_" + subCommunity.getID() + "_ADMIN"))
.build();
GroupBuilder.createGroup(context)
.withName("GroupA")
.withParent(groupB)
.addMember(eperson)
.build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
// Verify an ePerson in a sub-subgroup of a subcommunity admin group has this feature
getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri="
+ "http://localhost/api/core/site/" + siteService.findSite(context).getID()))
.andExpect(status().isOk())
.andExpect(
jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='isComColAdmin')]")
.exists());
}
@Test
public void testSubSubGroupOfCollectionAdminGroup() throws Exception {
context.turnOffAuthorisationSystem();
Group groupB = GroupBuilder.createGroup(context)
.withName("GroupB")
.withParent(groupService.findByName(context, "COLLECTION_" + collection.getID() + "_ADMIN"))
.build();
GroupBuilder.createGroup(context)
.withName("GroupA")
.withParent(groupB)
.addMember(eperson)
.build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
// Verify an ePerson in a sub-subgroup of a collection admin group has this feature
getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri="
+ "http://localhost/api/core/site/" + siteService.findSite(context).getID()))
.andExpect(status().isOk())
.andExpect(
jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='isComColAdmin')]")
.exists());
}
@Test
public void testSubSubGroupOfSubmitterGroup() throws Exception {
context.turnOffAuthorisationSystem();
Group groupB = GroupBuilder.createGroup(context)
.withName("GroupB")
.withParent(groupService.findByName(context, "COLLECTION_" + collection.getID() + "_SUBMIT"))
.build();
GroupBuilder.createGroup(context)
.withName("GroupA")
.withParent(groupB)
.addMember(eperson)
.build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
// Verify an ePerson in a sub-subgroup of submitter group doesn't have this feature
getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri="
+ "http://localhost/api/core/site/" + siteService.findSite(context).getID()))
.andExpect(status().isOk())
.andExpect(
jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='isComColAdmin')]")
.doesNotExist());
}
}

View File

@@ -0,0 +1,394 @@
/**
* 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.authorization;
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.test.AbstractControllerIntegrationTest;
import org.dspace.builder.CollectionBuilder;
import org.dspace.builder.CommunityBuilder;
import org.dspace.builder.EPersonBuilder;
import org.dspace.builder.GroupBuilder;
import org.dspace.content.Collection;
import org.dspace.content.Community;
import org.dspace.content.service.SiteService;
import org.dspace.eperson.EPerson;
import org.dspace.eperson.Group;
import org.dspace.eperson.service.GroupService;
import org.dspace.services.ConfigurationService;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
public class CommunityAdminFeatureIT extends AbstractControllerIntegrationTest {
@Autowired
private SiteService siteService;
@Autowired
private ConfigurationService configurationService;
@Autowired
private GroupService groupService;
private Community topLevelCommunityA;
private Community subCommunityA;
private Collection collectionA;
private EPerson topLevelCommunityAAdmin;
private EPerson subCommunityAAdmin;
private EPerson collectionAdmin;
private EPerson submitter;
@Override
@Before
public void setUp() throws Exception {
super.setUp();
context.turnOffAuthorisationSystem();
topLevelCommunityAAdmin = EPersonBuilder.createEPerson(context)
.withNameInMetadata("Jhon", "Brown")
.withEmail("topLevelCommunityAAdmin@my.edu")
.withPassword(password)
.build();
topLevelCommunityA = CommunityBuilder.createCommunity(context)
.withName("The name of this community is topLevelCommunityA")
.withAdminGroup(topLevelCommunityAAdmin)
.build();
subCommunityAAdmin = EPersonBuilder.createEPerson(context)
.withNameInMetadata("Jhon", "Brown")
.withEmail("subCommunityAAdmin@my.edu")
.withPassword(password)
.build();
subCommunityA = CommunityBuilder.createCommunity(context)
.withName("The name of this sub-community is subCommunityA")
.withAdminGroup(subCommunityAAdmin)
.addParentCommunity(context, topLevelCommunityA)
.build();
submitter = EPersonBuilder.createEPerson(context)
.withNameInMetadata("Jhon", "Brown")
.withEmail("submitter@my.edu")
.withPassword(password)
.build();
collectionAdmin = EPersonBuilder.createEPerson(context)
.withNameInMetadata("Jhon", "Brown")
.withEmail("collectionAdmin@my.edu")
.withPassword(password)
.build();
collectionA = CollectionBuilder.createCollection(context, subCommunityA)
.withName("The name of this collection is collectionA")
.withAdminGroup(collectionAdmin)
.withSubmitterGroup(submitter)
.build();
context.restoreAuthSystemState();
configurationService.setProperty(
"org.dspace.app.rest.authorization.AlwaysThrowExceptionFeature.turnoff", "true");
}
@Test
public void testAdmin() throws Exception {
String token = getAuthToken(admin.getEmail(), password);
// Verify the general admin has this feature
getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri="
+ "http://localhost/api/core/site/" + siteService.findSite(context).getID()))
.andExpect(status().isOk())
.andExpect(
jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='isCommunityAdmin')]")
.exists());
}
@Test
public void testCommunityAdmin() throws Exception {
String token = getAuthToken(topLevelCommunityAAdmin.getEmail(), password);
// Verify the community admin has this feature
getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri="
+ "http://localhost/api/core/site/" + siteService.findSite(context).getID()))
.andExpect(status().isOk())
.andExpect(
jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='isCommunityAdmin')]")
.exists());
}
@Test
public void testSubCommunityAdmin() throws Exception {
String token = getAuthToken(subCommunityAAdmin.getEmail(), password);
// Verify the subcommunity admin has this feature
getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri="
+ "http://localhost/api/core/site/" + siteService.findSite(context).getID()))
.andExpect(status().isOk())
.andExpect(
jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='isCommunityAdmin')]")
.exists());
}
@Test
public void testCollectionAdmin() throws Exception {
String token = getAuthToken(collectionAdmin.getEmail(), password);
// Verify the collection admin doesn't have this feature
getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri="
+ "http://localhost/api/core/site/" + siteService.findSite(context).getID()))
.andExpect(status().isOk())
.andExpect(
jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='isCommunityAdmin')]")
.doesNotExist());
}
@Test
public void testSubmitter() throws Exception {
String token = getAuthToken(submitter.getEmail(), password);
// Verify a submitter doesn't have this feature
getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri="
+ "http://localhost/api/core/site/" + siteService.findSite(context).getID()))
.andExpect(status().isOk())
.andExpect(
jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='isCommunityAdmin')]")
.doesNotExist());
}
@Test
public void testSubGroupOfAdminGroup() throws Exception {
context.turnOffAuthorisationSystem();
GroupBuilder.createGroup(context)
.withName("userGroup")
.withParent(groupService.findByName(context, Group.ADMIN))
.addMember(eperson)
.build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
// Verify an ePerson in a subgroup of the site administrators has this feature
getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri="
+ "http://localhost/api/core/site/" + siteService.findSite(context).getID()))
.andExpect(status().isOk())
.andExpect(
jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='isCommunityAdmin')]")
.exists());
}
@Test
public void testSubGroupOfCommunityAdminGroup() throws Exception {
context.turnOffAuthorisationSystem();
GroupBuilder.createGroup(context)
.withName("userGroup")
.withParent(groupService.findByName(context, "COMMUNITY_" + topLevelCommunityA.getID() + "_ADMIN"))
.addMember(eperson)
.build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
// Verify an ePerson in a subgroup of a community admin group has this feature
getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri="
+ "http://localhost/api/core/site/" + siteService.findSite(context).getID()))
.andExpect(status().isOk())
.andExpect(
jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='isCommunityAdmin')]")
.exists());
}
@Test
public void testSubGroupOfSubCommunityAdminGroup() throws Exception {
context.turnOffAuthorisationSystem();
GroupBuilder.createGroup(context)
.withName("userGroup")
.withParent(groupService.findByName(context, "COMMUNITY_" + subCommunityA.getID() + "_ADMIN"))
.addMember(eperson)
.build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
// Verify an ePerson in a subgroup of a subcommunity admin group has this feature
getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri="
+ "http://localhost/api/core/site/" + siteService.findSite(context).getID()))
.andExpect(status().isOk())
.andExpect(
jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='isCommunityAdmin')]")
.exists());
}
@Test
public void testSubGroupOfCollectionAdminGroup() throws Exception {
context.turnOffAuthorisationSystem();
GroupBuilder.createGroup(context)
.withName("userGroup")
.withParent(groupService.findByName(context, "COLLECTION_" + collectionA.getID() + "_ADMIN"))
.addMember(eperson)
.build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
// Verify an ePerson in a subgroup of a collection admin group doesn't have this feature
getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri="
+ "http://localhost/api/core/site/" + siteService.findSite(context).getID()))
.andExpect(status().isOk())
.andExpect(
jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='isCommunityAdmin')]")
.doesNotExist());
}
@Test
public void testSubGroupOfSubmitterGroup() throws Exception {
context.turnOffAuthorisationSystem();
GroupBuilder.createGroup(context)
.withName("userGroup")
.withParent(groupService.findByName(context, "COLLECTION_" + collectionA.getID() + "_SUBMIT"))
.addMember(eperson)
.build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
// Verify an ePerson in a subgroup of submitter group doesn't have this feature
getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri="
+ "http://localhost/api/core/site/" + siteService.findSite(context).getID()))
.andExpect(status().isOk())
.andExpect(
jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='isCommunityAdmin')]")
.doesNotExist());
}
@Test
public void testSubSubGroupOfAdminGroup() throws Exception {
context.turnOffAuthorisationSystem();
Group groupB = GroupBuilder.createGroup(context)
.withName("GroupB")
.withParent(groupService.findByName(context, Group.ADMIN))
.build();
GroupBuilder.createGroup(context)
.withName("GroupA")
.withParent(groupB)
.addMember(eperson)
.build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
// Verify an ePerson in a sub-subgroup of the site administrators has this feature
getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri="
+ "http://localhost/api/core/site/" + siteService.findSite(context).getID()))
.andExpect(status().isOk())
.andExpect(
jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='isCommunityAdmin')]")
.exists());
}
@Test
public void testSubSubGroupOfCommunityAdminGroup() throws Exception {
context.turnOffAuthorisationSystem();
Group groupB = GroupBuilder.createGroup(context)
.withName("GroupB")
.withParent(groupService.findByName(context, "COMMUNITY_" + topLevelCommunityA.getID() + "_ADMIN"))
.build();
GroupBuilder.createGroup(context)
.withName("GroupA")
.withParent(groupB)
.addMember(eperson)
.build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
// Verify an ePerson in a sub-subgroup of a community admin group has this feature
getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri="
+ "http://localhost/api/core/site/" + siteService.findSite(context).getID()))
.andExpect(status().isOk())
.andExpect(
jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='isCommunityAdmin')]")
.exists());
}
@Test
public void testSubSubGroupOfSubCommunityAdminGroup() throws Exception {
context.turnOffAuthorisationSystem();
Group groupB = GroupBuilder.createGroup(context)
.withName("GroupB")
.withParent(groupService.findByName(context, "COMMUNITY_" + subCommunityA.getID() + "_ADMIN"))
.build();
GroupBuilder.createGroup(context)
.withName("GroupA")
.withParent(groupB)
.addMember(eperson)
.build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
// Verify an ePerson in a sub-subgroup of a subcommunity admin group has this feature
getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri="
+ "http://localhost/api/core/site/" + siteService.findSite(context).getID()))
.andExpect(status().isOk())
.andExpect(
jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='isCommunityAdmin')]")
.exists());
}
@Test
public void testSubSubGroupOfCollectionAdminGroup() throws Exception {
context.turnOffAuthorisationSystem();
Group groupB = GroupBuilder.createGroup(context)
.withName("GroupB")
.withParent(groupService.findByName(context, "COLLECTION_" + collectionA.getID() + "_ADMIN"))
.build();
GroupBuilder.createGroup(context)
.withName("GroupA")
.withParent(groupB)
.addMember(eperson)
.build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
// Verify an ePerson in a sub-subgroup of a collection admin group doesn't have this feature
getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri="
+ "http://localhost/api/core/site/" + siteService.findSite(context).getID()))
.andExpect(status().isOk())
.andExpect(
jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='isCommunityAdmin')]")
.doesNotExist());
}
@Test
public void testSubSubGroupOfSubmitterGroup() throws Exception {
context.turnOffAuthorisationSystem();
Group groupB = GroupBuilder.createGroup(context)
.withName("GroupB")
.withParent(groupService.findByName(context, "COLLECTION_" + collectionA.getID() + "_SUBMIT"))
.build();
GroupBuilder.createGroup(context)
.withName("GroupA")
.withParent(groupB)
.addMember(eperson)
.build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
// Verify an ePerson in a sub-subgroup of submitter group doesn't have this feature
getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri="
+ "http://localhost/api/core/site/" + siteService.findSite(context).getID()))
.andExpect(status().isOk())
.andExpect(
jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='isCommunityAdmin')]")
.doesNotExist());
}
}

View File

@@ -60,7 +60,7 @@ public class CsvExportIT extends AbstractControllerIntegrationTest {
Item article = ItemBuilder.createItem(context, col1)
.withTitle("Article")
.withIssueDate("2017-10-17")
.withRelationshipType("Publication")
.withEntityType("Publication")
.build();
AtomicReference<Integer> idRef = new AtomicReference<>();
@@ -111,7 +111,7 @@ public class CsvExportIT extends AbstractControllerIntegrationTest {
Item article = ItemBuilder.createItem(context, col1)
.withTitle("Article")
.withIssueDate("2017-10-17")
.withRelationshipType("Publication")
.withEntityType("Publication")
.build();
AtomicReference<Integer> idRef = new AtomicReference<>();

View File

@@ -9,10 +9,10 @@ package org.dspace.app.rest.csv;
import static com.jayway.jsonpath.JsonPath.read;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.fileUpload;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
@@ -88,77 +88,93 @@ public class CsvImportIT extends AbstractEntityIntegrationTest {
Collection col2 = CollectionBuilder.createCollection(context, child1).withName("Collection 2").build();
Collection col3 = CollectionBuilder.createCollection(context, child1).withName("OrgUnits").build();
// Create a new Publication (which is an Article)
Item article = ItemBuilder.createItem(context, col1)
.withTitle("Article")
.withIssueDate("2017-10-17")
.withRelationshipType("Publication")
.withEntityType("Publication")
.build();
Item itemB = validateSpecificItemRelationCreationCsvImport(col1, article, "TestItemB", "Person",
// Via CSV import, add two Authors to that Publication
Item author1 = validateSpecificItemRelationCreationCsvImport(col1, article, "TestAuthor1", "Person",
"isPublicationOfAuthor",
"Relationship list size is 1", 1, 0, 0);
Item itemC = validateSpecificItemRelationCreationCsvImport(col1, article, "TestItemC", "Person",
Item author2 = validateSpecificItemRelationCreationCsvImport(col1, article, "TestAuthor2", "Person",
"isPublicationOfAuthor",
"Relationship list size is 1", 1, 1, 0);
Item itemD = validateSpecificItemRelationCreationCsvImport(col1, article, "TestItemD", "Project",
// Via CSV import, add a Project related to that Publication
Item project = validateSpecificItemRelationCreationCsvImport(col1, article, "TestProject", "Project",
"isPublicationOfProject",
"Relationship list size is 1", 1, 0, 0);
Item itemE = validateSpecificItemRelationCreationCsvImportMultiple(col1, "TestItemE", "Publication",
// Via CSV import, add a new Publication related to both author1 & author2
Item article2 = validateSpecificItemRelationCreationCsvImportMultiple(col1, "TestArticle2", "Publication",
"isAuthorOfPublication",
"Relationship list size is 2", 2, 0, 1,
itemC, itemB);
author2, author1);
List<Relationship> relationships = relationshipService.findByItem(context, itemE);
// Verify that the new Publication is related to both author2 and author1 (in that exact order)
List<Relationship> relationships = relationshipService.findByItem(context, article2);
assertEquals(2, relationships.size());
getClient().perform(get("/api/core/relationships/" + relationships.get(0).getID()).param("projection", "full"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.leftPlace", is(0)))
.andExpect(jsonPath("$._links.rightItem.href", containsString(itemC.getID().toString())))
.andExpect(jsonPath("$._links.rightItem.href", containsString(author2.getID().toString())))
.andExpect(jsonPath("$.rightPlace", is(1)))
.andExpect(jsonPath("$", Matchers.is(RelationshipMatcher.matchRelationship(relationships.get(0)))));
getClient().perform(get("/api/core/relationships/" + relationships.get(1).getID()).param("projection", "full"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.leftPlace", is(1)))
.andExpect(jsonPath("$._links.rightItem.href", containsString(itemB.getID().toString())))
.andExpect(jsonPath("$._links.rightItem.href", containsString(author1.getID().toString())))
.andExpect(jsonPath("$.rightPlace", is(1)))
.andExpect(jsonPath("$", Matchers.is(RelationshipMatcher.matchRelationship(relationships.get(1)))));
Item itemF = validateSpecificItemRelationCreationCsvImport(col1, itemE, "TestItemF", "Person",
// Via CSV import add a new Author to the new Publication, as the *third* author.
// At this point the new Publication has three authors in this order: author2, author1, author3
Item author3 = validateSpecificItemRelationCreationCsvImport(col1, article2, "TestAuthor3", "Person",
"isPublicationOfAuthor",
"Relationship list size is 1", 1, 2, 0);
UpdateItemEToDeleteRelationshipToC(itemE, itemB, itemF, col1, "TestItemE");
// Verify the new Publication now has 3 relationships (3 authors)
relationships = relationshipService.findByItem(context, article2);
assertEquals(3,relationships.size());
getClient().perform(get("/api/core/items/" + itemE.getID())).andExpect(status().isOk());
// Now, *remove* the first listed author (author2) from this new Publication
updateArticle2ToDeleteRelationshipToAuthor2(article2, author1, author3, col1, "TestArticle2");
assertItemERelationships(itemB, itemE, itemF);
// Verify new Publication still exists after author removal
getClient().perform(get("/api/core/items/" + article2.getID())).andExpect(status().isOk());
updateArticleItemToAddAnotherRelationship(col1, article, itemB, itemC, itemF);
// Check relationships to new Publication. Verify it's only related to author1 and author3
assertArticle2Relationships(article2, author1, author3);
// Update original Article to now be related to all three authors
updateArticleItemToAddAnotherRelationship(col1, article, author1, author2, author3);
getClient().perform(get("/api/core/items/" + article.getID())).andExpect(status().isOk());
assertArticleRelationships(article, itemB, itemC, itemF);
// Verify original article is now related to all three authors
assertArticleRelationships(article, author1, author2, author3);
}
private void assertItemERelationships(Item itemB, Item itemE, Item itemF) throws SQLException {
List<Relationship> relationshipsForItemE = relationshipService.findByItem(context, itemE);
assertThat(relationshipsForItemE.size(), is(2));
assertThat(relationshipsForItemE.get(0).getRightItem(), is(itemF));
assertThat(relationshipsForItemE.get(1).getRightItem(), is(itemB));
private void assertArticle2Relationships(Item article2, Item author1, Item author3) throws SQLException {
List<Relationship> relationshipsForArticle2 = relationshipService.findByItem(context, article2);
assertEquals(2, relationshipsForArticle2.size());
assertEquals(author3, relationshipsForArticle2.get(0).getRightItem());
assertEquals(author1, relationshipsForArticle2.get(1).getRightItem());
}
private void assertArticleRelationships(Item article, Item itemB, Item itemC, Item itemF) throws SQLException {
private void assertArticleRelationships(Item article, Item author1, Item author2, Item author3)
throws SQLException {
List<Relationship> relationshipsForArticle = relationshipService
.findByItemAndRelationshipType(context, article, relationshipTypeService
.findbyTypesAndTypeName(context, entityTypeService.findByEntityType(context, "Publication"),
entityTypeService.findByEntityType(context, "Person"), "isAuthorOfPublication",
"isPublicationOfAuthor"));
assertThat(relationshipsForArticle.size(), is(3));
entityTypeService.findByEntityType(context, "Person"),
"isAuthorOfPublication", "isPublicationOfAuthor"));
assertEquals(3, relationshipsForArticle.size());
List<Item> expectedRelationshipsItemsForArticle = new ArrayList<>();
expectedRelationshipsItemsForArticle.add(itemC);
expectedRelationshipsItemsForArticle.add(itemF);
expectedRelationshipsItemsForArticle.add(itemB);
expectedRelationshipsItemsForArticle.add(author2);
expectedRelationshipsItemsForArticle.add(author3);
expectedRelationshipsItemsForArticle.add(author1);
List<Item> actualRelationshipsItemsForArticle = new ArrayList<>();
for (Relationship relationship : relationshipsForArticle) {
@@ -168,45 +184,46 @@ public class CsvImportIT extends AbstractEntityIntegrationTest {
actualRelationshipsItemsForArticle.add(relationship.getRightItem());
}
}
assertThat(true, Matchers.is(actualRelationshipsItemsForArticle
.containsAll(expectedRelationshipsItemsForArticle)));
assertTrue(actualRelationshipsItemsForArticle.containsAll(expectedRelationshipsItemsForArticle));
}
private void updateArticleItemToAddAnotherRelationship(Collection col1, Item article, Item itemB, Item itemC,
Item itemF) throws Exception {
private void updateArticleItemToAddAnotherRelationship(Collection col1, Item article, Item author1, Item author2,
Item author3) throws Exception {
String csvLineString = article.getID().toString() + "," + col1
.getHandle() + "," + "Article" + "," + "Publication" + "," +
itemB.getID().toString() + "||" + itemC.getID().toString() + "||" + itemF
author1.getID().toString() + "||" + author2.getID().toString() + "||" + author3
.getID().toString();
String[] csv = {"id,collection,dc.title,relationship.type,relation." + "isAuthorOfPublication", csvLineString};
String[] csv = {"id,collection,dc.title,dspace.entity.type,relation." + "isAuthorOfPublication", csvLineString};
performImportScript(csv);
}
private void UpdateItemEToDeleteRelationshipToC(Item itemE, Item itemB, Item itemF, Collection owningCollection,
String title) throws Exception {
String csvLineString = itemE.getID().toString() + "," + owningCollection
.getHandle() + "," + title + "," + "Person" + "," + itemB.getID().toString() + "||" + itemF.getID()
private void updateArticle2ToDeleteRelationshipToAuthor2(Item article2, Item author1, Item author3,
Collection owningCollection, String title)
throws Exception {
String csvLineString = article2.getID().toString() + "," + owningCollection
.getHandle() + "," + title + "," + "Publication" + "," + author1.getID().toString() + "||" + author3.getID()
.toString();
String[] csv = {"id,collection,dc.title,relationship.type,relation." + "isAuthorOfPublication", csvLineString};
String[] csv = {"id,collection,dc.title,dspace.entity.type,relation." + "isAuthorOfPublication", csvLineString};
performImportScript(csv);
}
private Item validateSpecificItemRelationCreationCsvImport(Collection col1, Item relatedItem, String itemTitle,
String relationshipType,
String entityType,
String relationshipTypeLabel,
String reasonAssertCheck, Integer sizeToCheck,
Integer leftPlaceToCheck,
Integer rightPlaceToCheck) throws Exception {
String csvLineString = "+," + col1.getHandle() + "," + itemTitle + "," + relationshipType + "," + relatedItem
String reasonAssertCheck, int sizeToCheck,
int leftPlaceToCheck,
int rightPlaceToCheck) throws Exception {
String csvLineString = "+," + col1.getHandle() + "," + itemTitle + "," + entityType + "," + relatedItem
.getID().toString();
String[] csv = {"id,collection,dc.title,relationship.type,relation." + relationshipTypeLabel, csvLineString};
String[] csv = {"id,collection,dc.title,dspace.entity.type,relation." + relationshipTypeLabel, csvLineString};
performImportScript(csv);
Iterator<Item> itemIteratorItem = itemService.findByMetadataField(context, "dc", "title", null, itemTitle);
Item item = itemIteratorItem.next();
List<Relationship> relationships = relationshipService.findByItem(context, item);
assertThat(reasonAssertCheck, relationships.size(), equalTo(sizeToCheck));
assertEquals(reasonAssertCheck, sizeToCheck, relationships.size());
getClient().perform(get("/api/core/items/" + item.getID())).andExpect(status().isOk());
getClient().perform(get("/api/core/relationships/" + relationships.get(0).getID()).param("projection", "full"))
.andExpect(status().isOk())
@@ -218,7 +235,7 @@ public class CsvImportIT extends AbstractEntityIntegrationTest {
}
private Item validateSpecificItemRelationCreationCsvImportMultiple(Collection col1, String itemTitle,
String relationshipType,
String entityType,
String relationshipTypeLabel,
String reasonAssertCheck, Integer sizeToCheck,
Integer leftPlaceToCheck,
@@ -231,8 +248,8 @@ public class CsvImportIT extends AbstractEntityIntegrationTest {
}
idStringRelatedItems = idStringRelatedItems.substring(0, idStringRelatedItems.length() - 2);
String csvLineString = "+," + col1
.getHandle() + "," + itemTitle + "," + relationshipType + "," + idStringRelatedItems;
String[] csv = {"id,collection,dc.title,relationship.type,relation." + relationshipTypeLabel, csvLineString};
.getHandle() + "," + itemTitle + "," + entityType + "," + idStringRelatedItems;
String[] csv = {"id,collection,dc.title,dspace.entity.type,relation." + relationshipTypeLabel, csvLineString};
performImportScript(csv);
Iterator<Item> itemIteratorItem = itemService.findByMetadataField(context, "dc", "title", null, itemTitle);
Item item = itemIteratorItem.next();
@@ -294,12 +311,12 @@ public class CsvImportIT extends AbstractEntityIntegrationTest {
Item article = ItemBuilder.createItem(context, col1)
.withTitle("Article")
.withIssueDate("2017-10-17")
.withRelationshipType("Publication")
.withEntityType("Publication")
.build();
String csvLineString = "+," + col1.getHandle() + ",TestItemB,Person," + article
.getID().toString();
String[] csv = {"id,collection,dc.title,relationship.type,relation.isPublicationOfAuthor", csvLineString};
String[] csv = {"id,collection,dc.title,dspace.entity.type,relation.isPublicationOfAuthor", csvLineString};
InputStream inputStream = new ByteArrayInputStream(String.join(System.lineSeparator(),
Arrays.asList(csv))

View File

@@ -83,4 +83,16 @@ public class SearchResultMatcher {
))
);
}
public static Matcher<? super Object> matchEmbeddedFacetValues(String label, int count,
String type,
String search_href) {
return allOf(
hasJsonPath("$.label", is(label)),
hasJsonPath("$.count", is(count)),
hasJsonPath("$.type", is(type)),
hasJsonPath("$._links.search.href", containsString(search_href))
);
}
}

View File

@@ -47,7 +47,8 @@ public class EPersonRestAuthenticationProviderTest {
public void testGetGrantedAuthoritiesAdmin() throws Exception {
when(authorizeService.isAdmin(context, ePerson)).thenReturn(true);
List<GrantedAuthority> authorities = ePersonRestAuthenticationProvider.getGrantedAuthorities(context, ePerson);
when(context.getCurrentUser()).thenReturn(ePerson);
List<GrantedAuthority> authorities = ePersonRestAuthenticationProvider.getGrantedAuthorities(context);
assertThat(authorities.stream().map(a -> a.getAuthority()).collect(Collectors.toList()), containsInAnyOrder(
WebSecurityConfiguration.ADMIN_GRANT, WebSecurityConfiguration.AUTHENTICATED_GRANT));
@@ -57,8 +58,9 @@ public class EPersonRestAuthenticationProviderTest {
@Test
public void testGetGrantedAuthoritiesEPerson() throws Exception {
when(authorizeService.isAdmin(context, ePerson)).thenReturn(false);
when(context.getCurrentUser()).thenReturn(ePerson);
List<GrantedAuthority> authorities = ePersonRestAuthenticationProvider.getGrantedAuthorities(context, ePerson);
List<GrantedAuthority> authorities = ePersonRestAuthenticationProvider.getGrantedAuthorities(context);
assertThat(authorities.stream().map(a -> a.getAuthority()).collect(Collectors.toList()), containsInAnyOrder(
WebSecurityConfiguration.AUTHENTICATED_GRANT));

View File

@@ -177,7 +177,7 @@
<SchemaLocation>http://irdb.nii.ac.jp/oai/junii2-3-1.xsd</SchemaLocation>
</Format>
<!-- Metadata format based on the OpenAIRE 4.0 guidelines
https://openaire-guidelines-for-literature-repository-managers.readthedocs.io/en/v4.0.0/use_of_oai_pmh.html
https://openaire-guidelines-for-literature-repository-managers.readthedocs.io/en/v4.0.0/use_of_oai_pmh.html
-->
<Format id="oaiopenaire">
<Prefix>oai_openaire</Prefix>
@@ -323,8 +323,8 @@
By default, return an Item record:
* If it is publicly accessible
* * OR it has been withdrawn (in order to display a tombstone record).
* AND doesn't have a relationship.type field
* * OR the relationship.type is a Publication
* AND doesn't have a dspace.entity.type field
* * OR the dspace.entity.type is a Publication
* limiting the results only to Publications as expected
This filter is used by the default context ([oai]/request).
-->
@@ -363,8 +363,8 @@
By default, return an Item record:
* If it is publicly accessible
* * OR it has been withdrawn (in order to display a tombstone record).
* AND doesn't have a relationship.type field
* * OR the relationship.type is a Publication
* AND doesn't have a dspace.entity.type field
* * OR the dspace.entity.type is a Publication
* limiting the results only to Publications as expected
This filter is used by the default context ([oai]/request).
-->
@@ -493,20 +493,20 @@
</Configuration>
</CustomCondition>
<!-- This condition determines if an Item has a "relationship.type" -->
<!-- This condition determines if an Item has a "dspace.entity.type" -->
<CustomCondition id="relationshipTypeExistsCondition">
<Class>org.dspace.xoai.filter.DSpaceMetadataExistsFilter</Class>
<Configuration>
<string name="field">relationship.type</string>
<string name="field">dspace.entity.type</string>
</Configuration>
</CustomCondition>
<!-- This condition determines if an Item has a "relationship.type" field
<!-- This condition determines if an Item has a "dspace.entity.type" field
specifying one of the valid DRIVER document types. -->
<CustomCondition id="isPublicationEntityCondition">
<Class>org.dspace.xoai.filter.DSpaceAtLeastOneMetadataFilter</Class>
<Configuration>
<string name="field">relationship.type</string>
<string name="field">dspace.entity.type</string>
<string name="operator">equal</string>
<list name="values">
<string>Publication</string>

View File

@@ -30,4 +30,11 @@
<scope_note>Stores the cookie preferences of an EPerson, as selected in last session. Value will be an array of cookieName/boolean pairs, specifying which cookies are allowed or not allowed.</scope_note>
</dc-type>
<dc-type>
<schema>dspace</schema>
<element>entity</element>
<qualifier>type</qualifier>
<scope_note>Stores the type of Entity that a specific Item represents</scope_note>
</dc-type>
</dspace-dc-types>

View File

@@ -1,25 +1,14 @@
<dspace-dc-types>
<dspace-header>
<title>DSpace Relationship</title>
<title>DSpace Entity Relationships</title>
</dspace-header>
<dc-schema>
<name>relationship</name>
<namespace>http://dspace.org/relationship</namespace>
</dc-schema>
<dc-schema>
<name>relation</name>
<namespace>http://dspace.org/relation</namespace>
</dc-schema>
<dc-type>
<schema>relationship</schema>
<element>type</element>
<scope_note>Metadata field used for the type of entity, stored in the item</scope_note>
</dc-type>
<dc-type>
<schema>relation</schema>
<element>isAuthorOfPublication</element>
@@ -124,7 +113,7 @@
<!--
OpenAIRE4 Guidelines
required relationships -->
required relationships -->
<dc-type>
<schema>relation</schema>
<element>isContributorOfPublication</element>

View File

@@ -195,7 +195,7 @@
<property name="snippets" value="5"/>
</bean>
<bean class="org.dspace.discovery.configuration.DiscoveryHitHighlightFieldConfiguration">
<property name="field" value="relationship.type"/>
<property name="field" value="dspace.entity.type"/>
<property name="snippets" value="5"/>
</bean>
<bean class="org.dspace.discovery.configuration.DiscoveryHitHighlightFieldConfiguration">
@@ -261,6 +261,7 @@
<!--The configuration settings for discovery of withdrawn and indiscoverable items (admin only)-->
<bean id="unDiscoverableItems" class="org.dspace.discovery.configuration.DiscoveryConfiguration" scope="prototype">
<property name="id" value="undiscoverable"/>
<!--Which sidebar facets are to be displayed-->
<property name="sidebarFacets">
<list>
@@ -337,7 +338,7 @@
<property name="snippets" value="5"/>
</bean>
<bean class="org.dspace.discovery.configuration.DiscoveryHitHighlightFieldConfiguration">
<property name="field" value="relationship.type"/>
<property name="field" value="dspace.entity.type"/>
<property name="snippets" value="5"/>
</bean>
<bean class="org.dspace.discovery.configuration.DiscoveryHitHighlightFieldConfiguration">
@@ -403,7 +404,7 @@
<!--The configuration settings for discovery of withdrawn and undiscoverable items (admin only) and regular items-->
<bean id="administrativeView" class="org.dspace.discovery.configuration.DiscoveryConfiguration" scope="prototype">
<!--Which sidebar facets are to be displayed-->
<property name="id" value="administrativeView"/>
<property name="sidebarFacets">
<list>
<ref bean="searchFilterDiscoverable" />
@@ -481,7 +482,7 @@
<property name="snippets" value="5"/>
</bean>
<bean class="org.dspace.discovery.configuration.DiscoveryHitHighlightFieldConfiguration">
<property name="field" value="relationship.type"/>
<property name="field" value="dspace.entity.type"/>
<property name="snippets" value="5"/>
</bean>
<bean class="org.dspace.discovery.configuration.DiscoveryHitHighlightFieldConfiguration">
@@ -618,7 +619,7 @@
<property name="snippets" value="5"/>
</bean>
<bean class="org.dspace.discovery.configuration.DiscoveryHitHighlightFieldConfiguration">
<property name="field" value="relationship.type"/>
<property name="field" value="dspace.entity.type"/>
<property name="snippets" value="5"/>
</bean>
<bean class="org.dspace.discovery.configuration.DiscoveryHitHighlightFieldConfiguration">
@@ -1652,7 +1653,7 @@
<property name="indexFieldName" value="entityType"/>
<property name="metadataFields">
<list>
<value>relationship.type</value>
<value>dspace.entity.type</value>
</list>
</property>
<property name="facetLimit" value="5"/>
@@ -2231,7 +2232,7 @@
</bean>
<bean id="sortEntityType" class="org.dspace.discovery.configuration.DiscoverySortFieldConfiguration">
<property name="metadataField" value="relationship.type"/>
<property name="metadataField" value="dspace.entity.type"/>
</bean>
</beans>