diff --git a/dspace-api/src/main/java/org/dspace/content/factory/ContentServiceFactory.java b/dspace-api/src/main/java/org/dspace/content/factory/ContentServiceFactory.java index 2335af007f..8a83976b66 100644 --- a/dspace-api/src/main/java/org/dspace/content/factory/ContentServiceFactory.java +++ b/dspace-api/src/main/java/org/dspace/content/factory/ContentServiceFactory.java @@ -119,7 +119,6 @@ public abstract class ContentServiceFactory { public DSpaceObjectService getDSpaceObjectService(T dso) { // No need to worry when supressing, as long as our "getDSpaceObjectManager" method is properly implemented // no casting issues should occur - @SuppressWarnings("unchecked") DSpaceObjectService manager = getDSpaceObjectService(dso.getType()); return manager; } diff --git a/dspace-api/src/main/java/org/dspace/eperson/SubscribeParameterServiceImpl.java b/dspace-api/src/main/java/org/dspace/eperson/SubscribeParameterServiceImpl.java index 870a95b7f7..81c867f921 100644 --- a/dspace-api/src/main/java/org/dspace/eperson/SubscribeParameterServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/eperson/SubscribeParameterServiceImpl.java @@ -9,8 +9,8 @@ package org.dspace.eperson; import java.sql.SQLException; import java.util.List; +import java.util.Objects; -import org.dspace.authorize.AuthorizeException; import org.dspace.core.Context; import org.dspace.eperson.dao.SubscriptionParameterDAO; import org.dspace.eperson.service.SubscriptionParameterService; @@ -34,8 +34,8 @@ public class SubscribeParameterServiceImpl implements SubscriptionParameterServi } @Override - public SubscriptionParameter add(Context context, String name, String value, - Subscription subscription) throws SQLException, AuthorizeException { + public SubscriptionParameter add(Context context, String name, String value, Subscription subscription) + throws SQLException { SubscriptionParameter subscriptionParameter = subscriptionParameterDAO.create(context, new SubscriptionParameter()); subscriptionParameter.setName(name); @@ -43,12 +43,12 @@ public class SubscribeParameterServiceImpl implements SubscriptionParameterServi subscriptionParameter.setValue(value); return subscriptionParameter; } + @Override - public SubscriptionParameter edit(Context context,Integer id,String value, - String name, Subscription subscription) throws SQLException, AuthorizeException { + public SubscriptionParameter edit(Context context, Integer id, String value, String name, Subscription subscription) + throws SQLException { SubscriptionParameter subscriptionParameter = - subscriptionParameterDAO.findByID(context, SubscriptionParameter.class, id); - subscriptionParameter.setId(id); + subscriptionParameterDAO.findByID(context, SubscriptionParameter.class, id); subscriptionParameter.setName(name); subscriptionParameter.setSubscription(subscription); subscriptionParameter.setValue(value); @@ -62,16 +62,15 @@ public class SubscribeParameterServiceImpl implements SubscriptionParameterServi } @Override - public void deleteSubscriptionParameter(Context context, Integer id) throws SQLException, AuthorizeException { + public void delete(Context context, Integer id) throws SQLException { SubscriptionParameter subscriptionParameter = subscriptionParameterDAO.findByID(context, SubscriptionParameter.class, id); - if (subscriptionParameter != null) { + if (Objects.nonNull(subscriptionParameter)) { subscriptionParameter.setSubscription(null); subscriptionParameterDAO.delete(context, subscriptionParameter); } else { throw new SQLException("Subscription parameter with id" + id + "do not exists"); } - } } diff --git a/dspace-api/src/main/java/org/dspace/eperson/SubscribeServiceImpl.java b/dspace-api/src/main/java/org/dspace/eperson/SubscribeServiceImpl.java index 817085cdda..6ed9ca2d5a 100644 --- a/dspace-api/src/main/java/org/dspace/eperson/SubscribeServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/eperson/SubscribeServiceImpl.java @@ -11,6 +11,7 @@ import java.sql.SQLException; import java.util.List; import java.util.Objects; +import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.dspace.authorize.AuthorizeException; @@ -43,9 +44,9 @@ public class SubscribeServiceImpl implements SubscribeService { private CollectionService collectionService; @Override - public List findAll(Context context, String resourceType, - Integer limit, Integer offset) throws Exception { - if (resourceType == null) { + public List findAll(Context context, String resourceType, Integer limit, Integer offset) + throws Exception { + if (StringUtils.isBlank(resourceType)) { return subscriptionDAO.findAllOrderedByDSO(context, limit, offset); } else { if (resourceType.equals("Item") || resourceType.equals("Collection") || resourceType.equals("Community")) { @@ -101,24 +102,25 @@ public class SubscribeServiceImpl implements SubscribeService { } @Override - public List getSubscriptionsByEPerson(Context context, EPerson eperson, Integer limit, Integer offset) + public List findSubscriptionsByEPerson(Context context, EPerson eperson, Integer limit,Integer offset) throws SQLException { return subscriptionDAO.findByEPerson(context, eperson, limit, offset); } @Override - public List getSubscriptionsByEPersonAndDso(Context context,EPerson eperson,DSpaceObject dSpaceObject, - Integer limit, Integer offset) throws SQLException { + public List findSubscriptionsByEPersonAndDso(Context context, EPerson eperson, + DSpaceObject dSpaceObject, + Integer limit, Integer offset) throws SQLException { return subscriptionDAO.findByEPersonAndDso(context, eperson, dSpaceObject, limit, offset); } @Override - public List getAvailableSubscriptions(Context context) throws SQLException { - return getAvailableSubscriptions(context, null); + public List findAvailableSubscriptions(Context context) throws SQLException { + return findAvailableSubscriptions(context, null); } @Override - public List getAvailableSubscriptions(Context context, EPerson eperson) throws SQLException { + public List findAvailableSubscriptions(Context context, EPerson eperson) throws SQLException { if (Objects.nonNull(eperson)) { context.setCurrentUser(eperson); } @@ -141,91 +143,50 @@ public class SubscribeServiceImpl implements SubscribeService { } @Override - public Subscription findById(Context context, int id) throws SQLException, AuthorizeException { - Subscription subscription = subscriptionDAO.findByID(context, Subscription.class, id); - if (context.getCurrentUser().equals(subscription.getePerson()) || - authorizeService.isAdmin(context, context.getCurrentUser())) { - return subscription; - } - throw new AuthorizeException("Only admin or e-person themselves can edit the subscription"); + public Subscription findById(Context context, int id) throws SQLException { + return subscriptionDAO.findByID(context, Subscription.class, id); } @Override - public Subscription updateSubscription(Context context, Integer id, - EPerson eperson, - DSpaceObject dSpaceObject, - List subscriptionParameterList, - String type) throws SQLException, AuthorizeException { - // must be admin or the subscriber of the subscription - if (authorizeService.isAdmin(context, context.getCurrentUser()) || eperson.equals(context.getCurrentUser())) { - Subscription subscriptionDB = subscriptionDAO.findByID(context, Subscription.class, id); - subscriptionDB.removeParameterList(); - subscriptionDB.setType(type); - subscriptionDB.setdSpaceObject(dSpaceObject); - subscriptionParameterList.forEach(subscriptionParameter -> - subscriptionDB.addParameter(subscriptionParameter)); - subscriptionDB.setePerson(eperson); - subscriptionDAO.save(context, subscriptionDB); - return subscriptionDB; - } else { - throw new AuthorizeException("Only admin or e-person themselves can edit the subscription"); - } - } - - @Override - public Subscription addSubscriptionParameter(Context context, Integer id, - SubscriptionParameter subscriptionParameter) throws SQLException, AuthorizeException { - // must be admin or the subscriber of the subscription + public Subscription updateSubscription(Context context, Integer id, EPerson eperson, DSpaceObject dSpaceObject, + List subscriptionParameterList, String type) + throws SQLException { Subscription subscriptionDB = subscriptionDAO.findByID(context, Subscription.class, id); - if (authorizeService.isAdmin(context, context.getCurrentUser()) - || subscriptionDB.getePerson().equals(context.getCurrentUser())) { - subscriptionDB.addParameter(subscriptionParameter); - subscriptionDAO.save(context, subscriptionDB); - return subscriptionDB; - } else { - throw new AuthorizeException("Only admin or e-person themselves can edit the subscription"); - } + subscriptionDB.removeParameterList(); + subscriptionDB.setType(type); + subscriptionDB.setdSpaceObject(dSpaceObject); + subscriptionParameterList.forEach(x -> subscriptionDB.addParameter(x)); + subscriptionDB.setePerson(eperson); + subscriptionDAO.save(context, subscriptionDB); + return subscriptionDB; } @Override - public Subscription removeSubscriptionParameter(Context context, Integer id, - SubscriptionParameter subscriptionParameter) throws SQLException, AuthorizeException { - // must be admin or the subscriber of the subscription + public Subscription addSubscriptionParameter(Context context, Integer id, SubscriptionParameter subscriptionParam) + throws SQLException { Subscription subscriptionDB = subscriptionDAO.findByID(context, Subscription.class, id); - if (authorizeService.isAdmin(context, context.getCurrentUser()) - || subscriptionDB.getePerson().equals(context.getCurrentUser())) { - subscriptionDB.removeParameter(subscriptionParameter); - subscriptionDAO.save(context, subscriptionDB); - return subscriptionDB; - } else { - throw new AuthorizeException("Only admin or e-person themselves can edit the subscription"); - } + subscriptionDB.addParameter(subscriptionParam); + subscriptionDAO.save(context, subscriptionDB); + return subscriptionDB; } @Override - public void deleteSubscription(Context context, Integer id) throws SQLException, AuthorizeException { - // initially find the eperson associated with the subscription - Subscription subscription = subscriptionDAO.findByID(context, Subscription.class, id); - if (subscription != null) { - // must be admin or the subscriber of the subscription - if (authorizeService.isAdmin(context, context.getCurrentUser()) - || subscription.getePerson().equals(context.getCurrentUser())) { - try { - subscriptionDAO.delete(context, subscription); - } catch (SQLException sqlException) { - throw new SQLException(sqlException); - } - } else { - throw new AuthorizeException("Only admin or e-person themselves can delete the subscription"); - } - } else { - throw new IllegalArgumentException("Subscription with id " + id + " is not found"); - } + public Subscription removeSubscriptionParameter(Context context,Integer id, SubscriptionParameter subscriptionParam) + throws SQLException { + Subscription subscriptionDB = subscriptionDAO.findByID(context, Subscription.class, id); + subscriptionDB.removeParameter(subscriptionParam); + subscriptionDAO.save(context, subscriptionDB); + return subscriptionDB; } @Override - public List findAllSubscriptionsByTypeAndFrequency(Context context, - String type, String frequencyValue) throws SQLException { + public void deleteSubscription(Context context, Subscription subscription) throws SQLException { + subscriptionDAO.delete(context, subscription); + } + + @Override + public List findAllSubscriptionsByTypeAndFrequency(Context context,String type, String frequencyValue) + throws SQLException { return subscriptionDAO.findAllSubscriptionsByTypeAndFrequency(context, type, frequencyValue); } @@ -235,12 +196,12 @@ public class SubscribeServiceImpl implements SubscribeService { } @Override - public Long countAllByEPerson(Context context, EPerson ePerson) throws SQLException { + public Long countSubscriptionsByEPerson(Context context, EPerson ePerson) throws SQLException { return subscriptionDAO.countAllByEPerson(context, ePerson); } @Override - public Long countAllByEPersonAndDSO(Context context, EPerson ePerson, DSpaceObject dSpaceObject) + public Long countByEPersonAndDSO(Context context, EPerson ePerson, DSpaceObject dSpaceObject) throws SQLException { return subscriptionDAO.countAllByEPersonAndDso(context, ePerson, dSpaceObject); } diff --git a/dspace-api/src/main/java/org/dspace/eperson/SubscriptionParameter.java b/dspace-api/src/main/java/org/dspace/eperson/SubscriptionParameter.java index 002b517032..590374802c 100644 --- a/dspace-api/src/main/java/org/dspace/eperson/SubscriptionParameter.java +++ b/dspace-api/src/main/java/org/dspace/eperson/SubscriptionParameter.java @@ -17,6 +17,8 @@ import javax.persistence.ManyToOne; import javax.persistence.SequenceGenerator; import javax.persistence.Table; +import org.dspace.core.ReloadableEntity; + /** * Database entity representation of the subscription_parameter table * @@ -24,7 +26,7 @@ import javax.persistence.Table; */ @Entity @Table(name = "subscription_parameter") -public class SubscriptionParameter { +public class SubscriptionParameter implements ReloadableEntity { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "subscription_parameter_seq") @@ -76,7 +78,8 @@ public class SubscriptionParameter { this.value = value; } - public Integer getId() { + @Override + public Integer getID() { return id; } diff --git a/dspace-api/src/main/java/org/dspace/eperson/dao/impl/SubscriptionDAOImpl.java b/dspace-api/src/main/java/org/dspace/eperson/dao/impl/SubscriptionDAOImpl.java index 71518c1fcf..4133b09f47 100644 --- a/dspace-api/src/main/java/org/dspace/eperson/dao/impl/SubscriptionDAOImpl.java +++ b/dspace-api/src/main/java/org/dspace/eperson/dao/impl/SubscriptionDAOImpl.java @@ -41,8 +41,8 @@ public class SubscriptionDAOImpl extends AbstractHibernateDAO impl } @Override - public List findByEPerson(Context context, EPerson eperson, - Integer limit, Integer offset) throws SQLException { + public List findByEPerson(Context context, EPerson eperson, Integer limit, Integer offset) + throws SQLException { CriteriaBuilder criteriaBuilder = getCriteriaBuilder(context); javax.persistence.criteria.CriteriaQuery criteriaQuery = getCriteriaQuery(criteriaBuilder, Subscription.class); Root subscriptionRoot = criteriaQuery.from(Subscription.class); diff --git a/dspace-api/src/main/java/org/dspace/eperson/service/SubscribeService.java b/dspace-api/src/main/java/org/dspace/eperson/service/SubscribeService.java index d06c23f1f0..98b810ac49 100644 --- a/dspace-api/src/main/java/org/dspace/eperson/service/SubscribeService.java +++ b/dspace-api/src/main/java/org/dspace/eperson/service/SubscribeService.java @@ -50,8 +50,7 @@ public interface SubscribeService { * @throws AuthorizeException Exception indicating the current user of the context does not have permission * to perform a particular action. */ - public Subscription subscribe(Context context, EPerson eperson, - DSpaceObject dSpaceObject, + public Subscription subscribe(Context context, EPerson eperson, DSpaceObject dSpaceObject, List subscriptionParameterList, String type) throws SQLException, AuthorizeException; @@ -80,7 +79,7 @@ public interface SubscribeService { * @return array of collections e-person is subscribed to * @throws SQLException An exception that provides information on a database access error or other errors. */ - public List getSubscriptionsByEPerson(Context context, EPerson eperson, Integer limit, Integer offset) + public List findSubscriptionsByEPerson(Context context, EPerson eperson, Integer limit,Integer offset) throws SQLException; /** @@ -94,11 +93,9 @@ public interface SubscribeService { * @return array of collections e-person is subscribed to and related with dso * @throws SQLException An exception that provides information on a database access error or other errors. */ - public List getSubscriptionsByEPersonAndDso(Context context, - EPerson eperson, + public List findSubscriptionsByEPersonAndDso(Context context, EPerson eperson, DSpaceObject dSpaceObject, - Integer limit, - Integer offset) throws SQLException; + Integer limit, Integer offset) throws SQLException; /** * Find out which collections the currently logged in e-person can subscribe to @@ -107,7 +104,7 @@ public interface SubscribeService { * @return array of collections the currently logged in e-person can subscribe to * @throws SQLException An exception that provides information on a database access error or other errors. */ - public List getAvailableSubscriptions(Context context) throws SQLException; + public List findAvailableSubscriptions(Context context) throws SQLException; /** * Find out which collections an e-person can subscribe to @@ -117,7 +114,7 @@ public interface SubscribeService { * @return array of collections e-person can subscribe to * @throws SQLException An exception that provides information on a database access error or other errors. */ - public List getAvailableSubscriptions(Context context, EPerson eperson) throws SQLException; + public List findAvailableSubscriptions(Context context, EPerson eperson) throws SQLException; /** * Is that e-person subscribed to that collection? @@ -155,7 +152,7 @@ public interface SubscribeService { * @param id the id of subscription to be searched * @throws SQLException An exception that provides information on a database access error or other errors. */ - public Subscription findById(Context context, int id) throws SQLException, AuthorizeException; + public Subscription findById(Context context, int id) throws SQLException; /** * Updates a subscription by id @@ -168,10 +165,8 @@ public interface SubscribeService { * @param type String type * @throws SQLException An exception that provides information on a database access error or other errors. */ - public Subscription updateSubscription(Context context, Integer id, EPerson eperson, - DSpaceObject dSpaceObject, - List subscriptionParameterList, - String type) throws SQLException, AuthorizeException; + public Subscription updateSubscription(Context context, Integer id, EPerson eperson, DSpaceObject dSpaceObject, + List subscriptionParameterList, String type) throws SQLException; /** * Adds a parameter to a subscription @@ -182,18 +177,18 @@ public interface SubscribeService { * @throws SQLException An exception that provides information on a database access error or other errors. */ public Subscription addSubscriptionParameter(Context context,Integer id,SubscriptionParameter subscriptionParameter) - throws SQLException, AuthorizeException; + throws SQLException; /** * Deletes a parameter from subscription * * @param context DSpace context * @param id Integer id - * @param subscriptionParameter SubscriptionParameter subscriptionParameter - * @throws SQLException An exception that provides information on a database access error or other errors. + * @param subscriptionParam SubscriptionParameter subscriptionParameter + * @throws SQLException An exception that provides information on a database access error or other errors. */ - public Subscription removeSubscriptionParameter(Context context, Integer id, - SubscriptionParameter subscriptionParameter) throws SQLException, AuthorizeException; + public Subscription removeSubscriptionParameter(Context context, Integer id,SubscriptionParameter subscriptionParam) + throws SQLException; /** * Deletes a subscription @@ -202,7 +197,7 @@ public interface SubscribeService { * @param id Integer id of subscription * @throws SQLException An exception that provides information on a database access error or other errors. */ - public void deleteSubscription(Context context, Integer id) throws SQLException, AuthorizeException; + public void deleteSubscription(Context context, Subscription subscription) throws SQLException; /** * Finds all subscriptions having given type and frequency @@ -220,7 +215,7 @@ public interface SubscribeService { * * @param context DSpace context */ - public Long countAll(Context context) throws SQLException, AuthorizeException; + public Long countAll(Context context) throws SQLException; /** * Counts all subscriptions by ePerson @@ -228,7 +223,7 @@ public interface SubscribeService { * @param context DSpace context * @param ePerson EPerson ePerson */ - public Long countAllByEPerson(Context context, EPerson ePerson) throws SQLException, AuthorizeException; + public Long countSubscriptionsByEPerson(Context context, EPerson ePerson) throws SQLException; /** * Counts all subscriptions by ePerson and DSO @@ -237,7 +232,6 @@ public interface SubscribeService { * @param ePerson EPerson ePerson * @param dSpaceObject DSpaceObject dSpaceObject */ - public Long countAllByEPersonAndDSO(Context context, EPerson ePerson, DSpaceObject dSpaceObject) - throws SQLException, AuthorizeException; + public Long countByEPersonAndDSO(Context context, EPerson ePerson, DSpaceObject dSpaceObject) throws SQLException; } \ No newline at end of file diff --git a/dspace-api/src/main/java/org/dspace/eperson/service/SubscriptionParameterService.java b/dspace-api/src/main/java/org/dspace/eperson/service/SubscriptionParameterService.java index 88052ac20a..ff6f2b447d 100644 --- a/dspace-api/src/main/java/org/dspace/eperson/service/SubscriptionParameterService.java +++ b/dspace-api/src/main/java/org/dspace/eperson/service/SubscriptionParameterService.java @@ -44,9 +44,8 @@ public interface SubscriptionParameterService { * @throws AuthorizeException Exception indicating the current user of the context does not have permission * to perform a particular action. */ - public SubscriptionParameter add(Context context, String value, - String name, - Subscription subscription) throws SQLException, AuthorizeException; + public SubscriptionParameter add(Context context, String value, String name, Subscription subscription) + throws SQLException; /** * Updates a subscription parameter with id @@ -60,9 +59,8 @@ public interface SubscriptionParameterService { * @throws AuthorizeException Exception indicating the current user of the context does not have permission * to perform a particular action. */ - public SubscriptionParameter edit(Context context, Integer id, String value, - String name, - Subscription subscription) throws SQLException, AuthorizeException; + public SubscriptionParameter edit(Context context, Integer id, String value, String name, Subscription subscription) + throws SQLException; /** * Finds a subscriptionParameter by id @@ -73,14 +71,12 @@ public interface SubscriptionParameterService { */ public SubscriptionParameter findById(Context context, int id) throws SQLException; - /** * Deletes a subscriptionParameter with id * * @param context DSpace context * @throws SQLException An exception that provides information on a database access error or other errors. */ - public void deleteSubscriptionParameter(Context context, Integer id) throws SQLException, AuthorizeException; - + public void delete(Context context, Integer id) throws SQLException; } diff --git a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/h2/V7.0_2021.07.30__add_table_subscriptionparamter_change_columns_subscription_table.sql b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/h2/V7.0_2021.07.30__add_table_subscriptionparamter_change_columns_subscription_table.sql index ab20e35257..e94ec3c504 100644 --- a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/h2/V7.0_2021.07.30__add_table_subscriptionparamter_change_columns_subscription_table.sql +++ b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/h2/V7.0_2021.07.30__add_table_subscriptionparamter_change_columns_subscription_table.sql @@ -20,7 +20,7 @@ CREATE TABLE subscription_parameter ( subscription_parameter_id INTEGER NOT NULL, name CHARACTER VARYING(255), - `value` CHARACTER VARYING(255), + value CHARACTER VARYING(255), subscription_id INTEGER NOT NULL, CONSTRAINT subscription_parameter_pkey PRIMARY KEY (subscription_parameter_id), CONSTRAINT subscription_parameter_subscription_fkey FOREIGN KEY (subscription_id) REFERENCES subscription (subscription_id) ON DELETE CASCADE diff --git a/dspace-api/src/test/data/dspaceFolder/config/local.cfg b/dspace-api/src/test/data/dspaceFolder/config/local.cfg index 9cc6b7ebea..89bd528ed4 100644 --- a/dspace-api/src/test/data/dspaceFolder/config/local.cfg +++ b/dspace-api/src/test/data/dspaceFolder/config/local.cfg @@ -43,7 +43,7 @@ dspace.server.url = http://localhost db.driver = org.h2.Driver db.dialect=org.hibernate.dialect.H2Dialect # Use a 10 second database lock timeout to avoid occasional JDBC lock timeout errors -db.url = jdbc:h2:mem:test;LOCK_TIMEOUT=10000; +db.url = jdbc:h2:mem:test;LOCK_TIMEOUT=10000;NON_KEYWORDS=VALUE db.username = sa db.password = # H2's default schema is PUBLIC diff --git a/dspace-api/src/test/java/org/dspace/builder/SubscribeBuilder.java b/dspace-api/src/test/java/org/dspace/builder/SubscribeBuilder.java index 9c1c778d56..40e890a8c9 100644 --- a/dspace-api/src/test/java/org/dspace/builder/SubscribeBuilder.java +++ b/dspace-api/src/test/java/org/dspace/builder/SubscribeBuilder.java @@ -9,6 +9,7 @@ package org.dspace.builder; import java.sql.SQLException; import java.util.List; +import java.util.Objects; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -44,18 +45,27 @@ public class SubscribeBuilder extends AbstractBuilder subscriptionParameterList) { SubscribeBuilder builder = new SubscribeBuilder(context); @@ -103,4 +101,11 @@ public class SubscribeBuilder extends AbstractBuilder - implements LinkRestRepository { +public class SubscriptionRestRepository extends DSpaceRestRepository { @Autowired private ConverterService converter; @Autowired - private EPersonService personService; + private EPersonService ePersonService; @Autowired private AuthorizeService authorizeService; @Autowired private SubscribeService subscribeService; @Autowired private DSpaceObjectUtils dspaceObjectUtil; - @Autowired - private ResourcePatch resourcePatch; @Override - @PreAuthorize("isAuthenticated()") + @PreAuthorize("hasPermission(#id, 'subscription', 'READ')") public SubscriptionRest findOne(Context context, Integer id) { + Subscription subscription = null; try { - Subscription subscription = subscribeService.findById(context, id); - if (Objects.isNull(subscription)) { - throw new ResourceNotFoundException("The subscription for ID: " + id + " could not be found"); - } - return converter.toRest(subscription, utils.obtainProjection()); - } catch (SQLException sqlException) { - throw new RuntimeException(sqlException.getMessage(), sqlException); - } catch (AuthorizeException authorizeException) { - throw new RuntimeException(authorizeException.getMessage()); + subscription = subscribeService.findById(context, id); + } catch (SQLException e) { + throw new RuntimeException(e.getMessage(), e); } + return Objects.isNull(subscription) ? null : converter.toRest(subscription, utils.obtainProjection()); } @Override @@ -90,91 +86,77 @@ public class SubscriptionRestRepository extends DSpaceRestRepository subscriptionList = subscribeService.findAll(context, resourceType, - pageable.getPageSize(), Math.toIntExact(pageable.getOffset())); + Math.toIntExact(pageable.getPageSize()), + Math.toIntExact(pageable.getOffset())); Long total = subscribeService.countAll(context); return converter.toRestPage(subscriptionList, pageable, total, utils.obtainProjection()); } catch (Exception e) { - throw new RuntimeException(e.getMessage()); + throw new RuntimeException(e.getMessage(), e); } } - @PreAuthorize("isAuthenticated()") @SearchRestMethod(name = "findByEPerson") - public Page findAllSubscriptionsByEPerson(String id, Pageable pageable) throws Exception { + @PreAuthorize("hasPermission(#epersonId, 'AdminOrOwner', 'READ')") + public Page findSubscriptionsByEPerson(@Parameter(value = "uuid", required = true) UUID epersonId, + Pageable pageable)throws Exception { + Long total = null; + List subscriptions = null; try { Context context = obtainContext(); - EPerson ePerson = personService.findByIdOrLegacyId(context, id); - if (context.getCurrentUser().equals(ePerson) - || authorizeService.isAdmin(context, context.getCurrentUser())) { - List subscriptionList = subscribeService.getSubscriptionsByEPerson(context, - ePerson, pageable.getPageSize(), Math.toIntExact(pageable.getOffset())); - Long total = subscribeService.countAllByEPerson(context, ePerson); - return converter.toRestPage(subscriptionList, pageable, total, utils.obtainProjection()); - } else { - throw new AuthorizeException("Only admin or e-person themselves can search for it's subscription"); - } - } catch (SQLException sqlException) { - throw new SQLException(sqlException.getMessage(), sqlException); - - } catch (AuthorizeException authorizeException) { - throw new AuthorizeException(authorizeException.getMessage()); + EPerson ePerson = ePersonService.find(context, epersonId); + subscriptions = subscribeService.findSubscriptionsByEPerson(context, ePerson, + Math.toIntExact(pageable.getPageSize()), + Math.toIntExact(pageable.getOffset())); + total = subscribeService.countSubscriptionsByEPerson(context, ePerson); + } catch (SQLException e) { + throw new SQLException(e.getMessage(), e); } + return converter.toRestPage(subscriptions, pageable, total, utils.obtainProjection()); } - @PreAuthorize("isAuthenticated()") @SearchRestMethod(name = "findByEPersonAndDso") - public Page findByEPersonAndDso(Pageable pageable) throws Exception { + @PreAuthorize("hasPermission(#epersonId, 'AdminOrOwner', 'READ')") + public Page findByEPersonAndDso(@Parameter(value = "eperson_id", required = true) UUID epersonId, + @Parameter(value = "dspace_object_id",required = true) UUID dsoId, + Pageable pageable) throws Exception { + Long total = null; + List subscriptions = null; try { Context context = obtainContext(); - HttpServletRequest req = getRequestService().getCurrentRequest().getHttpServletRequest(); - String epersonId = req.getParameter("eperson_id"); - String dsoId = req.getParameter("dspace_object_id"); - DSpaceObject dSpaceObject = dspaceObjectUtil.findDSpaceObject(context, UUID.fromString(dsoId)); - EPerson ePerson = personService.findByIdOrLegacyId(context, epersonId); - // dso must always be set - if (dsoId == null || epersonId == null) { - throw new UnprocessableEntityException("error parsing the body"); - } - if (context.getCurrentUser().equals(ePerson) - || authorizeService.isAdmin(context, context.getCurrentUser())) { - List subscriptionList = - subscribeService.getSubscriptionsByEPersonAndDso(context, ePerson, dSpaceObject, - pageable.getPageSize(), Math.toIntExact(pageable.getOffset())); - Long total = subscribeService.countAllByEPersonAndDSO(context, ePerson, dSpaceObject); - return converter.toRestPage(subscriptionList, pageable, total, - utils.obtainProjection()); - } else { - throw new AuthorizeException("Only admin or e-person themselves can search for it's subscription"); - } - } catch (SQLException sqlException) { - throw new SQLException(sqlException.getMessage(), sqlException); - - } catch (AuthorizeException authorizeException) { - throw new AuthorizeException(authorizeException.getMessage()); + DSpaceObject dSpaceObject = dspaceObjectUtil.findDSpaceObject(context, dsoId); + EPerson ePerson = ePersonService.find(context, epersonId); + subscriptions = subscribeService.findSubscriptionsByEPersonAndDso(context, ePerson, dSpaceObject, + Math.toIntExact(pageable.getPageSize()), + Math.toIntExact(pageable.getOffset())); + total = subscribeService.countByEPersonAndDSO(context, ePerson, dSpaceObject); + } catch (SQLException e) { + throw new SQLException(e.getMessage(), e); } + return converter.toRestPage(subscriptions, pageable, total, utils.obtainProjection()); } @Override - @PreAuthorize("isAuthenticated()") protected SubscriptionRest createAndReturn(Context context) throws SQLException, AuthorizeException { HttpServletRequest req = getRequestService().getCurrentRequest().getHttpServletRequest(); String epersonId = req.getParameter("eperson_id"); String dsoId = req.getParameter("dspace_object_id"); - // dso must always be set - if (dsoId == null || epersonId == null) { - throw new UnprocessableEntityException("error parsing the body"); + + if (Objects.isNull(dsoId) || Objects.isNull(epersonId)) { + throw new UnprocessableEntityException("Both eperson than DSpaceObject uuids must be provieded!"); } - ObjectMapper mapper = new ObjectMapper(); + try { DSpaceObject dSpaceObject = dspaceObjectUtil.findDSpaceObject(context, UUID.fromString(dsoId)); - EPerson ePerson = personService.findByIdOrLegacyId(context, epersonId); - if (ePerson == null || dSpaceObject == null) { + EPerson ePerson = ePersonService.findByIdOrLegacyId(context, epersonId); + if (Objects.isNull(ePerson) || Objects.isNull(dSpaceObject)) { throw new BadRequestException("Id of person or dspace object must represents reals ids"); } + // user must have read permissions to dataspace object if (!authorizeService.authorizeActionBoolean(context, ePerson, dSpaceObject, Constants.READ, true)) { throw new AuthorizeException("The user has not READ rights on this DSO"); } + // if user is admin do not make this control, // otherwise make this control because normal user can only subscribe with their own ID of user. if (!authorizeService.isAdmin(context)) { @@ -183,7 +165,7 @@ public class SubscriptionRestRepository extends DSpaceRestRepository subscriptionParameterList = subscriptionRest.getSubscriptionParameterList(); if (subscriptionParameterList != null) { @@ -212,91 +194,71 @@ public class SubscriptionRestRepository extends DSpaceRestRepository subscriptionParameterList = new ArrayList<>(); - for (SubscriptionParameterRest subscriptionParameterRest : - subscriptionRest.getSubscriptionParameterList()) { + for (SubscriptionParameterRest subscriptionParamRest : subscriptionRest.getSubscriptionParameterList()) { SubscriptionParameter subscriptionParameter = new SubscriptionParameter(); subscriptionParameter.setSubscription(subscription); - subscriptionParameter.setValue(subscriptionParameterRest.getValue()); - subscriptionParameter.setName(subscriptionParameterRest.getName()); + subscriptionParameter.setValue(subscriptionParamRest.getValue()); + subscriptionParameter.setName(subscriptionParamRest.getName()); subscriptionParameterList.add(subscriptionParameter); } - subscription = subscribeService.updateSubscription(context, id, ePerson, - dSpaceObject, subscriptionParameterList, subscriptionRest.getSubscriptionType()); + subscription = subscribeService.updateSubscription(context, id, ePerson, dSpaceObject, + subscriptionParameterList, subscriptionRest.getSubscriptionType()); context.commit(); return converter.toRest(subscription, utils.obtainProjection()); } else { - throw new IllegalArgumentException("The id in the Json and the id in the url do not match: " - + id + ", " - + subscription.getID()); + throw new IllegalArgumentException("The id in the Json and the id in the url do not match: " + id + ", " + + subscription.getID()); } } @Override - @PreAuthorize("isAuthenticated()") - public void patch(Context context,HttpServletRequest request,String category, String model, Integer id, Patch patch) - throws UnprocessableEntityException, DSpaceBadRequestException, AuthorizeException { + @PreAuthorize("hasPermission(#id, 'subscription', 'DELETE')") + protected void delete(Context context, Integer id) throws AuthorizeException { try { Subscription subscription = subscribeService.findById(context, id); - if (subscription == null) { - throw new ResourceNotFoundException(category + "." + model + " with id: " + id + " not found"); + if (Objects.isNull(subscription)) { + throw new ResourceNotFoundException(CATEGORY + "." + NAME + " with id: " + id + " not found"); } - if (!authorizeService.isAdmin(context) || subscription.getePerson().equals(context.getCurrentUser())) { - throw new AuthorizeException("Only admin or e-person themselves can edit the subscription"); - } - resourcePatch.patch(context, subscription, patch.getOperations()); + subscribeService.deleteSubscription(context, subscription); } catch (SQLException e) { - throw new RuntimeException(e.getMessage(), e); - } catch (AuthorizeException authorizeException) { - throw new AuthorizeException(authorizeException.getMessage()); - } catch (RuntimeException runtimeException) { - throw new RuntimeException(runtimeException.getMessage()); + throw new RuntimeException("Unable to delete Subscription with id = " + id, e); } } @Override - @PreAuthorize("isAuthenticated()") - public void delete(Context context, Integer id) throws AuthorizeException { - try { - subscribeService.deleteSubscription(context, id); - } catch (SQLException sqlException) { - throw new RuntimeException(sqlException.getMessage(), sqlException); - } catch (AuthorizeException authorizeException) { - throw new AuthorizeException(authorizeException.getMessage()); - } + protected void patch(Context c, HttpServletRequest req, String category, String model, Integer id, Patch patch) { + throw new RepositoryMethodNotImplementedException(SubscriptionRest.NAME, "patch"); } @Override diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/patch/operation/SubscriptionParameterAddOperation.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/patch/operation/SubscriptionParameterAddOperation.java deleted file mode 100644 index 2393d49f23..0000000000 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/patch/operation/SubscriptionParameterAddOperation.java +++ /dev/null @@ -1,79 +0,0 @@ -/** - * The contents of this file are subject to the license and copyright - * detailed in the LICENSE and NOTICE files at the root of the source - * tree and available online at - * - * http://www.dspace.org/license/ - */ -package org.dspace.app.rest.repository.patch.operation; - -import java.sql.SQLException; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.dspace.app.rest.exception.DSpaceBadRequestException; -import org.dspace.app.rest.exception.UnprocessableEntityException; -import org.dspace.app.rest.model.SubscriptionParameterRest; -import org.dspace.app.rest.model.patch.JsonValueEvaluator; -import org.dspace.app.rest.model.patch.Operation; -import org.dspace.core.Context; -import org.dspace.eperson.Subscription; -import org.dspace.eperson.SubscriptionParameter; -import org.dspace.eperson.service.SubscribeService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - - - -/** - * Implementation for SubscriptionParameterAddOperation patches. - *

- * Example: - * curl -X PATCH http://${dspace.server.url}api/core/subscriptions/<:id-subscription> -H " - * Content-Type: application/json" -d '[{ "op": "replace", "path": " - * - */ -@Component -public class SubscriptionParameterAddOperation extends PatchOperation { - - @Autowired - private SubscribeService subscribeService; - - - @Override - public Subscription perform(Context context, Subscription subscription, Operation operation) - throws SQLException { - if (supports(subscription, operation)) { - JsonNode value = null; - ObjectMapper objectMapper = new ObjectMapper(); - try { - if (operation.getValue() instanceof JsonValueEvaluator) { - value = ((JsonValueEvaluator) operation.getValue()).getValueNode(); - } else { - value = objectMapper.readTree((String) operation.getValue()); - } - SubscriptionParameterRest subscriptionParameterRest = - objectMapper.readValue(value.toString(), SubscriptionParameterRest.class); - SubscriptionParameter subscriptionParameter = new SubscriptionParameter(); - subscriptionParameter.setSubscription(subscription); - subscriptionParameter.setValue(subscriptionParameterRest.getValue()); - subscriptionParameter.setName(subscriptionParameterRest.getName()); - subscribeService.addSubscriptionParameter(context, subscription.getID(), subscriptionParameter); - } catch (UnprocessableEntityException e) { - throw new UnprocessableEntityException(e.getMessage(), e); - } catch (Exception e) { - throw new RuntimeException(e.getMessage(), e); - } - } else { - throw new DSpaceBadRequestException("Subscription does not support this operation"); - } - return subscription; - } - - @Override - public boolean supports(Object objectToMatch, Operation operation) { - return (objectToMatch instanceof Subscription - && operation.getOp().trim().equalsIgnoreCase(OPERATION_ADD)); - } - -} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/patch/operation/SubscriptionParameterRemoveOperation.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/patch/operation/SubscriptionParameterRemoveOperation.java deleted file mode 100644 index 660ed7f8d4..0000000000 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/patch/operation/SubscriptionParameterRemoveOperation.java +++ /dev/null @@ -1,65 +0,0 @@ -/** - * The contents of this file are subject to the license and copyright - * detailed in the LICENSE and NOTICE files at the root of the source - * tree and available online at - * - * http://www.dspace.org/license/ - */ -package org.dspace.app.rest.repository.patch.operation; - -import java.sql.SQLException; - -import org.dspace.app.rest.exception.DSpaceBadRequestException; -import org.dspace.app.rest.exception.RESTAuthorizationException; -import org.dspace.app.rest.model.patch.Operation; -import org.dspace.authorize.AuthorizeException; -import org.dspace.core.Context; -import org.dspace.eperson.Subscription; -import org.dspace.eperson.SubscriptionParameter; -import org.dspace.eperson.service.SubscribeService; -import org.dspace.eperson.service.SubscriptionParameterService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -/** - * Implementation for SubscriptionParameterRemoveOperation patches. - *

- * Example: - * curl -X PATCH http://${dspace.server.url}api/core/subscriptions/<:id-subscription> -H " - * Content-Type: application/json" -d '[{ "op": "replace", "path": " - * - */ -@Component -public class SubscriptionParameterRemoveOperation extends PatchOperation { - - @Autowired - private SubscriptionParameterService subscriptionParameterService; - @Autowired - private SubscribeService subscribeService; - - - @Override - public Subscription perform(Context context, Subscription subscription, Operation operation) - throws SQLException { - if (supports(subscription, operation)) { - Integer path = Integer.parseInt(operation.getPath().split("/")[2]); - try { - SubscriptionParameter subscriptionParameter = subscriptionParameterService.findById(context, path); - subscribeService.removeSubscriptionParameter(context, subscription.getID(), subscriptionParameter); - } catch (AuthorizeException e) { - throw new RESTAuthorizationException("Unauthorized user for removing subscription parameter"); - } - } else { - throw new DSpaceBadRequestException("Subscription does not support this operation"); - - } - return subscription; - } - - @Override - public boolean supports(Object objectToMatch, Operation operation) { - return (objectToMatch instanceof Subscription - && operation.getOp().trim().equalsIgnoreCase(OPERATION_REMOVE)); - } - -} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/patch/operation/SubscriptionParameterReplaceOperation.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/patch/operation/SubscriptionParameterReplaceOperation.java deleted file mode 100644 index c9149aa115..0000000000 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/patch/operation/SubscriptionParameterReplaceOperation.java +++ /dev/null @@ -1,83 +0,0 @@ -/** - * The contents of this file are subject to the license and copyright - * detailed in the LICENSE and NOTICE files at the root of the source - * tree and available online at - * - * http://www.dspace.org/license/ - */ -package org.dspace.app.rest.repository.patch.operation; - -import java.sql.SQLException; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.dspace.app.rest.exception.DSpaceBadRequestException; -import org.dspace.app.rest.exception.UnprocessableEntityException; -import org.dspace.app.rest.model.SubscriptionParameterRest; -import org.dspace.app.rest.model.patch.JsonValueEvaluator; -import org.dspace.app.rest.model.patch.Operation; -import org.dspace.core.Context; -import org.dspace.eperson.Subscription; -import org.dspace.eperson.service.SubscriptionParameterService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -/** - * Implementation for SubscriptionParameterReplaceOperation patches. - *

- * Example: - * curl -X PATCH http://${dspace.server.url}api/core/subscriptions/<:id-subscription> -H " - * Content-Type: application/json" -d '[{ "op": "replace", "path": " - * - */ -@Component -public class SubscriptionParameterReplaceOperation extends PatchOperation { - - @Autowired - private SubscriptionParameterService subscriptionParameterService; - - @Override - public Subscription perform(Context context, Subscription subscription, Operation operation) - throws SQLException { - if (supports(subscription, operation)) { - Integer subscriptionParameterId = Integer.parseInt(operation.getPath().split("/", 3)[2]); - checkModelForExistingValue(subscription, subscriptionParameterId); - JsonNode value = null; - ObjectMapper objectMapper = new ObjectMapper(); - try { - if (operation.getValue() instanceof JsonValueEvaluator) { - value = ((JsonValueEvaluator) operation.getValue()).getValueNode(); - } else { - value = objectMapper.readTree((String) operation.getValue()); - } - SubscriptionParameterRest subscriptionParameterRest = objectMapper.readValue( - value.toString(), SubscriptionParameterRest.class); - subscriptionParameterService.edit(context, subscriptionParameterId,subscriptionParameterRest.getValue(), - subscriptionParameterRest.getName(), subscription); - } catch (UnprocessableEntityException e) { - throw new UnprocessableEntityException(e.getMessage(), e); - } catch (Exception e) { - throw new RuntimeException(e.getMessage(), e); - } - return subscription; - } else { - throw new DSpaceBadRequestException("Subscription does not support this operation"); - } - } - - @Override - public boolean supports(Object objectToMatch, Operation operation) { - return (objectToMatch instanceof Subscription && operation.getOp().trim().equalsIgnoreCase(OPERATION_REPLACE)); - } - - /** - * Checks whether the subscription - */ - @SuppressWarnings("ReturnValueIgnored") - private void checkModelForExistingValue(Subscription subscription, Integer id) { - subscription.getSubscriptionParameterList().stream().filter(subscriptionParameter -> { - return subscriptionParameter.getId().equals(id); - }).findFirst().orElseThrow(); - } - -} \ No newline at end of file diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/SubscriptionAdminAndOwnerPermissionEvaluatorPlugin.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/SubscriptionAdminAndOwnerPermissionEvaluatorPlugin.java new file mode 100644 index 0000000000..7e58afd601 --- /dev/null +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/SubscriptionAdminAndOwnerPermissionEvaluatorPlugin.java @@ -0,0 +1,73 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +package org.dspace.app.rest.security; + +import java.io.Serializable; +import java.sql.SQLException; +import java.util.Objects; +import java.util.UUID; + +import org.apache.commons.lang3.StringUtils; +import org.dspace.app.rest.utils.ContextUtil; +import org.dspace.authorize.service.AuthorizeService; +import org.dspace.core.Context; +import org.dspace.eperson.EPerson; +import org.dspace.services.RequestService; +import org.dspace.services.model.Request; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.Authentication; +import org.springframework.stereotype.Component; + +/** + * @author Mykhaylo Boychuk (mykhaylo.boychuk@4science.com) + */ +@Component +public class SubscriptionAdminAndOwnerPermissionEvaluatorPlugin extends RestObjectPermissionEvaluatorPlugin { + + private static final Logger log = LoggerFactory.getLogger(SubscriptionAdminAndOwnerPermissionEvaluatorPlugin.class); + + @Autowired + private RequestService requestService; + @Autowired + private AuthorizeService authorizeService; + + @Override + public boolean hasDSpacePermission(Authentication authentication, Serializable targetId, + String targetType, DSpaceRestPermission permission) { + + DSpaceRestPermission restPermission = DSpaceRestPermission.convert(permission); + + if (!DSpaceRestPermission.READ.equals(restPermission) && + !DSpaceRestPermission.WRITE.equals(restPermission) && + !DSpaceRestPermission.DELETE.equals(restPermission) || + !StringUtils.equals(targetType, "AdminOrOwner")) { + return false; + } + + Request request = requestService.getCurrentRequest(); + Context context = ContextUtil.obtainContext(request.getHttpServletRequest()); + + UUID dsoId = UUID.fromString(targetId.toString()); + EPerson currentUser = context.getCurrentUser(); + + // anonymous user + if (Objects.isNull(currentUser)) { + return false; + } + + try { + return dsoId.equals(currentUser.getID()) || authorizeService.isAdmin(context, currentUser); + } catch (SQLException e) { + log.error(e.getMessage(), e); + } + return false; + } + +} diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/SubscriptionRestPermissionEvaluatorPlugin.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/SubscriptionRestPermissionEvaluatorPlugin.java new file mode 100644 index 0000000000..b92fed9435 --- /dev/null +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/SubscriptionRestPermissionEvaluatorPlugin.java @@ -0,0 +1,84 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +package org.dspace.app.rest.security; + +import static org.dspace.app.rest.model.SubscriptionRest.NAME; +import static org.dspace.app.rest.security.DSpaceRestPermission.DELETE; +import static org.dspace.app.rest.security.DSpaceRestPermission.READ; +import static org.dspace.app.rest.security.DSpaceRestPermission.WRITE; + +import java.io.Serializable; +import java.sql.SQLException; +import java.util.Objects; + +import org.apache.commons.lang3.StringUtils; +import org.dspace.app.rest.utils.ContextUtil; +import org.dspace.authorize.service.AuthorizeService; +import org.dspace.core.Context; +import org.dspace.eperson.EPerson; +import org.dspace.eperson.Subscription; +import org.dspace.eperson.service.SubscribeService; +import org.dspace.services.RequestService; +import org.dspace.services.model.Request; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.Authentication; +import org.springframework.stereotype.Component; + +/** + * {@link RestPermissionEvaluatorPlugin} + * + * @author Mykhaylo Boychuk (mykhaylo.boychuk at 4science.com) + */ +@Component +public class SubscriptionRestPermissionEvaluatorPlugin extends RestObjectPermissionEvaluatorPlugin { + + private static final Logger log = LoggerFactory.getLogger(SubscriptionRestPermissionEvaluatorPlugin.class); + + @Autowired + private RequestService requestService; + @Autowired + private SubscribeService subscribeService; + @Autowired + private AuthorizeService authorizeService; + + @Override + public boolean hasDSpacePermission(Authentication authentication, Serializable targetId, String targetType, + DSpaceRestPermission permission) { + + DSpaceRestPermission restPermission = DSpaceRestPermission.convert(permission); + + if (!READ.equals(restPermission) && !WRITE.equals(restPermission) && !DELETE.equals(restPermission) + || !StringUtils.equalsIgnoreCase(targetType, NAME)) { + return false; + } + + Request request = requestService.getCurrentRequest(); + Context context = ContextUtil.obtainContext(request.getHttpServletRequest()); + + try { + EPerson currentUser = context.getCurrentUser(); + // anonymous user + if (Objects.isNull(currentUser)) { + return false; + } + // Admin user + if (authorizeService.isAdmin(context, currentUser)) { + return true; + } + + Subscription subscription = subscribeService.findById(context, Integer.parseInt(targetId.toString())); + return Objects.nonNull(subscription) ? currentUser.equals(subscription.getePerson()) : true; + } catch (SQLException e) { + log.error(e.getMessage(), e); + } + return false; + } + +} diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/SubscriptionRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/SubscriptionRestRepositoryIT.java index dc3519fe07..15d57b3376 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/SubscriptionRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/SubscriptionRestRepositoryIT.java @@ -7,10 +7,11 @@ */ package org.dspace.app.rest; +import static com.jayway.jsonpath.JsonPath.read; import static org.hamcrest.Matchers.greaterThanOrEqualTo; import static org.hamcrest.Matchers.is; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; @@ -21,14 +22,12 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.atomic.AtomicReference; import com.fasterxml.jackson.databind.ObjectMapper; +import org.dspace.app.rest.matcher.SubscriptionMatcher; import org.dspace.app.rest.model.SubscriptionParameterRest; import org.dspace.app.rest.model.SubscriptionRest; -import org.dspace.app.rest.model.patch.AddOperation; -import org.dspace.app.rest.model.patch.Operation; -import org.dspace.app.rest.model.patch.RemoveOperation; -import org.dspace.app.rest.model.patch.ReplaceOperation; import org.dspace.app.rest.test.AbstractControllerIntegrationTest; import org.dspace.builder.CollectionBuilder; import org.dspace.builder.CommunityBuilder; @@ -84,39 +83,34 @@ public class SubscriptionRestRepositoryIT extends AbstractControllerIntegrationT @Test public void findAll() throws Exception { context.turnOffAuthorisationSystem(); - List subscriptionParameterList = new ArrayList<>(); SubscriptionParameter subscriptionParameter = new SubscriptionParameter(); subscriptionParameter.setName("Frequency"); subscriptionParameter.setValue("Daily"); subscriptionParameterList.add(subscriptionParameter); - Subscription subscription = SubscribeBuilder.subscribeBuilder(context, - "TypeTest", publicItem, admin, subscriptionParameterList).build(); - subscriptionParameter.setSubscription(subscription); + Subscription subscription1 = SubscribeBuilder.subscribeBuilder(context, + "TestType", publicItem, eperson, subscriptionParameterList).build(); + List subscriptionParameterList2 = new ArrayList<>(); + SubscriptionParameter subscriptionParameter2 = new SubscriptionParameter(); + subscriptionParameter2.setName("Frequency"); + subscriptionParameter2.setValue("WEEKLY"); + subscriptionParameterList2.add(subscriptionParameter2); + Subscription subscription2 = SubscribeBuilder.subscribeBuilder(context, + "TestType 2", collection, admin, subscriptionParameterList2).build(); context.restoreAuthSystemState(); String tokenAdmin = getAuthToken(admin.getEmail(), password); getClient(tokenAdmin).perform(get("/api/core/subscriptions")) - .andExpect(status().isOk()) - //We expect the content type to be "application/hal+json;charset=UTF-8" - .andExpect(content().contentType(contentType)) - //By default we expect at least 1 submission forms so this to be reflected in the page object - .andExpect(jsonPath("$.page.size", is(20))) - .andExpect(jsonPath("$.page.totalElements", greaterThanOrEqualTo(1))) - .andExpect(jsonPath("$.page.totalPages", greaterThanOrEqualTo(1))) - .andExpect(jsonPath("$.page.number", is(0))) - .andExpect(jsonPath("$._embedded.subscriptions[0].subscriptionType", is("TypeTest"))) - .andExpect(jsonPath("$._embedded.subscriptions[0]._links.dSpaceObject.href", - Matchers.startsWith(REST_SERVER_URL + "core/subscriptions"))) - .andExpect(jsonPath("$._embedded.subscriptions[0]._links.dSpaceObject.href", - Matchers.endsWith("dSpaceObject"))) - .andExpect(jsonPath("$._embedded.subscriptions[0]._links.ePerson.href", - Matchers.startsWith(REST_SERVER_URL + "core/subscriptions"))) - .andExpect(jsonPath("$._embedded.subscriptions[0]._links.ePerson.href", Matchers.endsWith("ePerson"))) - .andExpect(jsonPath("$._embedded.subscriptions[0].subscriptionParameterList[0].name", is("Frequency"))) - .andExpect(jsonPath("$._embedded.subscriptions[0].subscriptionParameterList[0].value", is("Daily"))) - .andExpect(jsonPath("$._links.self.href", Matchers.is(REST_SERVER_URL + "core/subscriptions"))); + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.subscriptions", Matchers.containsInAnyOrder( + SubscriptionMatcher.matchSubscription(subscription1), + SubscriptionMatcher.matchSubscription(subscription2) + ))) + .andExpect(jsonPath("$.page.size", is(20))) + .andExpect(jsonPath("$.page.totalElements", greaterThanOrEqualTo(2))) + .andExpect(jsonPath("$.page.totalPages", greaterThanOrEqualTo(1))) + .andExpect(jsonPath("$.page.number", is(0))); } @Test @@ -141,39 +135,26 @@ public class SubscriptionRestRepositoryIT extends AbstractControllerIntegrationT subscriptionParameter.setName("Frequency"); subscriptionParameter.setValue("Daily"); subscriptionParameterList.add(subscriptionParameter); + Subscription subscription = SubscribeBuilder.subscribeBuilder(context, - "TypeTest", publicItem, admin, subscriptionParameterList).build(); - subscriptionParameter.setSubscription(subscription); + "TypeTest", publicItem, admin, subscriptionParameterList).build(); context.restoreAuthSystemState(); String tokenAdmin = getAuthToken(admin.getEmail(), password); getClient(tokenAdmin).perform(get("/api/core/subscriptions?resourceType=Item")) .andExpect(status().isOk()) - //We expect the content type to be "application/hal+json;charset=UTF-8" - .andExpect(content().contentType(contentType)) - //By default we expect at least 1 submission forms so this to be reflected in the page object + .andExpect(jsonPath("$._embedded.subscriptions", Matchers.contains( + SubscriptionMatcher.matchSubscription(subscription) + ))) .andExpect(jsonPath("$.page.size", is(20))) .andExpect(jsonPath("$.page.totalElements", greaterThanOrEqualTo(1))) .andExpect(jsonPath("$.page.totalPages", greaterThanOrEqualTo(1))) - .andExpect(jsonPath("$.page.number", is(0))) - .andExpect(jsonPath("$._embedded.subscriptions[0].subscriptionType", is("TypeTest"))) - .andExpect(jsonPath("$._embedded.subscriptions[0]._links.dSpaceObject.href", - Matchers.startsWith(REST_SERVER_URL + "core/subscriptions"))) - .andExpect(jsonPath("$._embedded.subscriptions[0]._links.dSpaceObject.href", - Matchers.endsWith("dSpaceObject"))) - .andExpect(jsonPath("$._embedded.subscriptions[0]._links.ePerson.href", - Matchers.startsWith(REST_SERVER_URL + "core/subscriptions"))) - .andExpect(jsonPath("$._embedded.subscriptions[0]._links.ePerson.href", Matchers.endsWith("ePerson"))) - .andExpect(jsonPath("$._embedded.subscriptions[0].subscriptionParameterList[0].name", is("Frequency"))) - .andExpect(jsonPath("$._embedded.subscriptions[0].subscriptionParameterList[0].value", is("Daily"))) - .andExpect(jsonPath("$._links.self.href", - Matchers.is(REST_SERVER_URL + "core/subscriptions?resourceType=Item"))); + .andExpect(jsonPath("$.page.number", is(0))); // search for subscriptions related with collections getClient(tokenAdmin).perform(get("/api/core/subscriptions?resourceType=Collection")) .andExpect(status().isOk()) - //We expect the content type to be "application/hal+json;charset=UTF-8" .andExpect(content().contentType(contentType)) //By default we expect at least 1 submission forms so this to be reflected in the page object .andExpect(jsonPath("$.page.size", is(20))) @@ -185,7 +166,7 @@ public class SubscriptionRestRepositoryIT extends AbstractControllerIntegrationT } @Test - public void findByIdAsAdministrator() throws Exception { + public void findOneWithOwnerTest() throws Exception { context.turnOffAuthorisationSystem(); List subscriptionParameterList = new ArrayList<>(); SubscriptionParameter subscriptionParameter = new SubscriptionParameter(); @@ -193,7 +174,39 @@ public class SubscriptionRestRepositoryIT extends AbstractControllerIntegrationT subscriptionParameter.setValue("ValueParameter"); subscriptionParameterList.add(subscriptionParameter); Subscription subscription = SubscribeBuilder.subscribeBuilder(context, - "TestType", publicItem, admin, subscriptionParameterList).build(); + "TestType", publicItem, eperson, subscriptionParameterList).build(); + context.restoreAuthSystemState(); + + String tokenEPerson = getAuthToken(eperson.getEmail(), password); + getClient(tokenEPerson).perform(get("/api/core/subscriptions/" + subscription.getID())) + .andExpect(status().isOk()) + //We expect the content type to be "application/hal+json;charset=UTF-8" + .andExpect(content().contentType(contentType)) + //By default we expect at least 1 submission forms so this to be reflected in the page object + .andExpect(jsonPath("$.subscriptionType", is("TestType"))) + .andExpect(jsonPath("$.subscriptionParameterList[0].name", is("Parameter"))) + .andExpect(jsonPath("$.subscriptionParameterList[0].value", is("ValueParameter"))) + .andExpect(jsonPath("$._links.ePerson.href", Matchers.endsWith("/ePerson"))) + .andExpect(jsonPath("$._links.dSpaceObject.href", Matchers.endsWith("/dSpaceObject"))) + .andExpect(jsonPath("$._links.self.href", + Matchers.startsWith(REST_SERVER_URL + "core/subscriptions/" + subscription.getID()))) + .andExpect(jsonPath("$._links.dSpaceObject.href", + Matchers.startsWith(REST_SERVER_URL + "core/subscriptions"))) + .andExpect(jsonPath("$._links.ePerson.href", + Matchers.startsWith(REST_SERVER_URL + "core/subscriptions"))); + } + + @Test + public void findOneAdminTest() throws Exception { + context.turnOffAuthorisationSystem(); + + List subscriptionParameterList = new ArrayList<>(); + SubscriptionParameter subscriptionParameter = new SubscriptionParameter(); + subscriptionParameter.setName("Parameter"); + subscriptionParameter.setValue("ValueParameter"); + subscriptionParameterList.add(subscriptionParameter); + Subscription subscription = SubscribeBuilder.subscribeBuilder(context, + "TestType", publicItem, admin, subscriptionParameterList).build(); context.restoreAuthSystemState(); String tokenAdmin = getAuthToken(admin.getEmail(), password); @@ -216,7 +229,7 @@ public class SubscriptionRestRepositoryIT extends AbstractControllerIntegrationT } @Test - public void findByIdAsAnonymous() throws Exception { + public void findOneAnonymousTest() throws Exception { context.turnOffAuthorisationSystem(); List subscriptionParameterList = new ArrayList<>(); SubscriptionParameter subscriptionParameter = new SubscriptionParameter(); @@ -224,7 +237,7 @@ public class SubscriptionRestRepositoryIT extends AbstractControllerIntegrationT subscriptionParameter.setValue("ValueParameter"); subscriptionParameterList.add(subscriptionParameter); Subscription subscription = SubscribeBuilder.subscribeBuilder(context, - "TestType", publicItem, admin, subscriptionParameterList).build(); + "TestType", publicItem, admin, subscriptionParameterList).build(); context.restoreAuthSystemState(); getClient().perform(get("/api/core/subscriptions/" + subscription.getID())) @@ -232,8 +245,7 @@ public class SubscriptionRestRepositoryIT extends AbstractControllerIntegrationT } @Test - //TODO - public void findByIdNotAsSubscriberNotAsAdmin() throws Exception { + public void findOneForbiddenTest() throws Exception { context.turnOffAuthorisationSystem(); List subscriptionParameterList = new ArrayList<>(); SubscriptionParameter subscriptionParameter = new SubscriptionParameter(); @@ -241,90 +253,148 @@ public class SubscriptionRestRepositoryIT extends AbstractControllerIntegrationT subscriptionParameter.setValue("ValueParameter"); subscriptionParameterList.add(subscriptionParameter); Subscription subscription = SubscribeBuilder.subscribeBuilder(context, - "TestType", publicItem, admin, subscriptionParameterList).build(); + "TestType", publicItem, admin, subscriptionParameterList).build(); context.restoreAuthSystemState(); String tokenEPerson = getAuthToken(eperson.getEmail(), password); getClient(tokenEPerson).perform(get("/api/core/subscriptions/" + subscription.getID())) - .andExpect(status().isInternalServerError()); + .andExpect(status().isForbidden()); } @Test - public void findAllSubscriptionsByEPerson() throws Exception { + public void findOneNotFoundTest() throws Exception { + String tokenAdmin = getAuthToken(admin.getEmail(), password); + getClient(tokenAdmin).perform(get("/api/core/subscriptions/" + Integer.MAX_VALUE)) + .andExpect(status().isNotFound()); + } + + @Test + public void findSubscriptionsByEPersonAdminTest() throws Exception { context.turnOffAuthorisationSystem(); - EPerson user = EPersonBuilder.createEPerson(context) - .withEmail("user@test.it") - .withPassword(password) - .build(); List subscriptionParameterList = new ArrayList<>(); SubscriptionParameter subscriptionParameter = new SubscriptionParameter(); - subscriptionParameter.setName("Parameter1"); - subscriptionParameter.setValue("ValueParameter1"); + subscriptionParameter.setName("Parameter 1"); + subscriptionParameter.setValue("ValueParameter 1"); + subscriptionParameterList.add(subscriptionParameter); + Subscription subscription1 = SubscribeBuilder.subscribeBuilder(context, + "TestType", publicItem, eperson, subscriptionParameterList).build(); + List subscriptionParameterList2 = new ArrayList<>(); + SubscriptionParameter subscriptionParameter2 = new SubscriptionParameter(); + subscriptionParameter2.setName("Parameter 2"); + subscriptionParameter2.setValue("ValueParameter 2"); + subscriptionParameterList2.add(subscriptionParameter2); + Subscription subscription2 = SubscribeBuilder.subscribeBuilder(context, + "TestType 2", collection, eperson, subscriptionParameterList2).build(); + + context.restoreAuthSystemState(); + + String tokenAdmin = getAuthToken(admin.getEmail(), password); + getClient(tokenAdmin).perform(get("/api/core/subscriptions/search/findByEPerson") + .param("uuid", eperson.getID().toString())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.subscriptions", Matchers.containsInAnyOrder( + SubscriptionMatcher.matchSubscription(subscription1), + SubscriptionMatcher.matchSubscription(subscription2) + ))) + .andExpect(jsonPath("$.page.size", is(20))) + .andExpect(jsonPath("$.page.totalElements", greaterThanOrEqualTo(2))) + .andExpect(jsonPath("$.page.totalPages", greaterThanOrEqualTo(1))) + .andExpect(jsonPath("$.page.number", is(0))); + } + + @Test + public void findSubscriptionsByEPersonOwnerTest() throws Exception { + context.turnOffAuthorisationSystem(); + List subscriptionParameterList = new ArrayList<>(); + SubscriptionParameter subscriptionParameter = new SubscriptionParameter(); + subscriptionParameter.setName("Parameter 1"); + subscriptionParameter.setValue("ValueParameter 1"); + subscriptionParameterList.add(subscriptionParameter); + Subscription subscription1 = SubscribeBuilder.subscribeBuilder(context, + "TestType", publicItem, eperson, subscriptionParameterList).build(); + List subscriptionParameterList2 = new ArrayList<>(); + SubscriptionParameter subscriptionParameter2 = new SubscriptionParameter(); + subscriptionParameter2.setName("Parameter 2"); + subscriptionParameter2.setValue("ValueParameter 2"); + subscriptionParameterList2.add(subscriptionParameter2); + Subscription subscription2 = SubscribeBuilder.subscribeBuilder(context, + "TestType 2", collection, eperson, subscriptionParameterList2).build(); + + context.restoreAuthSystemState(); + + String tokenAdmin = getAuthToken(eperson.getEmail(), password); + getClient(tokenAdmin).perform(get("/api/core/subscriptions/search/findByEPerson") + .param("uuid", eperson.getID().toString())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$._embedded.subscriptions", Matchers.containsInAnyOrder( + SubscriptionMatcher.matchSubscription(subscription1), + SubscriptionMatcher.matchSubscription(subscription2) + ))) + .andExpect(jsonPath("$.page.size", is(20))) + .andExpect(jsonPath("$.page.totalElements", greaterThanOrEqualTo(2))) + .andExpect(jsonPath("$.page.totalPages", greaterThanOrEqualTo(1))) + .andExpect(jsonPath("$.page.number", is(0))); + } + + @Test + public void findSubscriptionsByEPersonUnauthorizedTest() throws Exception { + context.turnOffAuthorisationSystem(); + List subscriptionParameterList = new ArrayList<>(); + SubscriptionParameter subscriptionParameter = new SubscriptionParameter(); + subscriptionParameter.setName("Parameter 1"); + subscriptionParameter.setValue("ValueParameter 1"); + subscriptionParameterList.add(subscriptionParameter); + SubscribeBuilder.subscribeBuilder(context, "TestType", publicItem, eperson, subscriptionParameterList).build(); + context.restoreAuthSystemState(); + + getClient().perform(get("/api/core/subscriptions/search/findByEPerson") + .param("uuid", eperson.getID().toString())) + .andExpect(status().isUnauthorized()); + } + + @Test + public void findSubscriptionsByEPersonForbiddenTest() throws Exception { + context.turnOffAuthorisationSystem(); + EPerson user = EPersonBuilder.createEPerson(context) + .withEmail("user1@mail.com") + .withPassword(password) + .build(); + + List subscriptionParameterList = new ArrayList<>(); + SubscriptionParameter subscriptionParameter = new SubscriptionParameter(); + subscriptionParameter.setName("Parameter 1"); + subscriptionParameter.setValue("ValueParameter 1"); subscriptionParameterList.add(subscriptionParameter); SubscribeBuilder.subscribeBuilder(context, "TestType", publicItem, user, subscriptionParameterList).build(); context.restoreAuthSystemState(); String tokenEPerson = getAuthToken(eperson.getEmail(), password); - getClient(tokenEPerson).perform(get("/api/core/subscriptions/search/findByEPerson?id=" + eperson.getID())) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.page.size", is(20))) - .andExpect(jsonPath("$.page.totalElements", greaterThanOrEqualTo(1))) - .andExpect(jsonPath("$.page.totalPages", greaterThanOrEqualTo(1))) - .andExpect(jsonPath("$.page.number", is(0))) - .andExpect(jsonPath("$._embedded.subscriptions[0].subscriptionType", is("TestType"))) - .andExpect(jsonPath("$._embedded.subscriptions[0]._links.dSpaceObject.href", - Matchers.startsWith(REST_SERVER_URL + "core/subscriptions"))) - .andExpect(jsonPath("$._embedded.subscriptions[0]._links.dSpaceObject.href", - Matchers.endsWith("dSpaceObject"))) - .andExpect(jsonPath("$._embedded.subscriptions[0]._links.ePerson.href", - Matchers.startsWith(REST_SERVER_URL + "core/subscriptions"))) - .andExpect(jsonPath("$._embedded.subscriptions[0]._links.ePerson.href", Matchers.endsWith("ePerson"))) - .andExpect(jsonPath("$._embedded.subscriptions[0].subscriptionParameterList[0].name", is("Parameter1"))) - .andExpect(jsonPath("$._embedded.subscriptions[0].subscriptionParameterList[0].value", - is("ValueParameter1"))); - - context.turnOffAuthorisationSystem(); - EPersonBuilder.createEPerson(context) - .withEmail("epersonIT@example.com") - .withPassword(password) - .withLanguage("al") - .build(); - - subscriptionParameter.setName("Parameter1"); - subscriptionParameter.setValue("ValueParameter1"); - subscriptionParameterList.add(subscriptionParameter); - List subscriptionParameterList1 = new ArrayList<>(); - SubscriptionParameter subscriptionParameter1 = new SubscriptionParameter(); - subscriptionParameter1.setName("Parameter1"); - subscriptionParameter1.setValue("ValueParameter1"); - subscriptionParameterList1.add(subscriptionParameter1); - SubscribeBuilder.subscribeBuilder(context, "TestType", collection, user, subscriptionParameterList).build(); - SubscribeBuilder.subscribeBuilder(context, "Test", collection, user, subscriptionParameterList1).build(); - context.restoreAuthSystemState(); - - String tokenAdmin = getAuthToken(admin.getEmail(), password); - getClient(tokenAdmin).perform(get("/api/core/subscriptions/search/findByEPersonAndDso") - .param("dspace_object_id", collection.getID().toString()) - .param("eperson_id", user.getID().toString())) - .andExpect(status().isUnauthorized()); + getClient(tokenEPerson).perform(get("/api/core/subscriptions/search/findByEPerson") + .param("uuid", user.getID().toString())) + .andExpect(status().isForbidden()); } @Test - public void addSubscriptionNotLoggedIn() throws Exception { + public void createSubscriptionUnauthorizedTest() throws Exception { context.turnOffAuthorisationSystem(); + SubscriptionParameterRest subscriptionParameterRest = new SubscriptionParameterRest(); - subscriptionParameterRest.setValue("nameTest"); - subscriptionParameterRest.setName("valueTest"); + subscriptionParameterRest.setValue("Frequency"); + subscriptionParameterRest.setName("Daily"); List subscriptionParameterRestList = new ArrayList<>(); subscriptionParameterRestList.add(subscriptionParameterRest); + SubscriptionRest subscriptionRest = new SubscriptionRest(); subscriptionRest.setType("testType"); + MultiValueMap params = new LinkedMultiValueMap(); params.add("dspace_object_id", publicItem.getID().toString()); params.add("eperson_id", eperson.getID().toString()); + context.restoreAuthSystemState(); ObjectMapper objectMapper = new ObjectMapper(); + getClient().perform(post("/api/core/subscriptions") .param("dspace_object_id", publicItem.getID().toString()) .param("eperson_id", eperson.getID().toString()) @@ -334,48 +404,165 @@ public class SubscriptionRestRepositoryIT extends AbstractControllerIntegrationT } @Test - public void addSubscriptionAsAdmin() throws Exception { - SubscriptionParameterRest subscriptionParameterRest = new SubscriptionParameterRest(); - subscriptionParameterRest.setValue("nameTest"); - subscriptionParameterRest.setName("valueTest"); - List subscriptionParameterRestList = new ArrayList<>(); - subscriptionParameterRestList.add(subscriptionParameterRest); - SubscriptionRest subscriptionRest = new SubscriptionRest(); - subscriptionRest.setType("testType"); - ObjectMapper objectMapper = new ObjectMapper(); + public void createSubscriptionAdminForOtherPersonTest() throws Exception { + context.turnOffAuthorisationSystem(); + Map map = new HashMap<>(); - map.put("type", "test"); + map.put("type", "testType"); List> list = new ArrayList<>(); Map sub_list = new HashMap<>(); - sub_list.put("name", "frequency"); + sub_list.put("name", "Frequency"); sub_list.put("value", "daily"); list.add(sub_list); map.put("subscriptionParameterList", list); - String tokenAdmin = getAuthToken(admin.getEmail(), password); - getClient(tokenAdmin).perform(post("/api/core/subscriptions") - .param("dspace_object_id", publicItem.getID().toString()) - .param("eperson_id", admin.getID().toString()) - .content(objectMapper.writeValueAsString(map)) - .contentType(MediaType.APPLICATION_JSON_VALUE)) - .andExpect(status().isOk()) - //We expect the content type to be "application/hal+json;charset=UTF-8" - //By default we expect at least 1 submission forms so this to be reflected in the page object - .andExpect(jsonPath("$.subscriptionType", is("testType"))) - .andExpect(jsonPath("$.id", Matchers.endsWith(REST_SERVER_URL + "core/dSpaceObject"))) - .andExpect(jsonPath("$.subscriptionParameterList[0].name", is("nameTest"))) - .andExpect(jsonPath("$.subscriptionParameterList[0].value", is("valueTest"))) - .andExpect(jsonPath("$._links.self.href", Matchers.startsWith(REST_SERVER_URL + "core/subscriptions"))) - .andExpect(jsonPath("$._links.dSpaceObject.href", - Matchers.startsWith(REST_SERVER_URL + "core/subscriptions"))) - .andExpect(jsonPath("$._links.dSpaceObject.href", Matchers.endsWith("dSpaceObject"))) - .andExpect(jsonPath("$._links.ePerson.href", - Matchers.startsWith(REST_SERVER_URL + "core/subscriptions"))) - .andExpect(jsonPath("$._links.ePerson.href", Matchers.endsWith("ePerson"))); + context.restoreAuthSystemState(); + + AtomicReference idRef = new AtomicReference(); + + try { + String tokenAdmin = getAuthToken(admin.getEmail(), password); + getClient(tokenAdmin).perform(post("/api/core/subscriptions") + .param("dspace_object_id", publicItem.getID().toString()) + .param("eperson_id", eperson.getID().toString()) + .content(new ObjectMapper().writeValueAsString(map)) + .contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(status().isCreated()) + .andExpect(jsonPath("$.subscriptionType", is("testType"))) + .andExpect(jsonPath("$.subscriptionParameterList[0].name", is("Frequency"))) + .andExpect(jsonPath("$.subscriptionParameterList[0].value", is("daily"))) + .andExpect(jsonPath("$._links.ePerson.href", Matchers.endsWith("ePerson"))) + .andExpect(jsonPath("$._links.dSpaceObject.href", Matchers.endsWith("dSpaceObject"))) + .andDo(result -> idRef.set(read(result.getResponse().getContentAsString(), "$.id"))); + } finally { + SubscribeBuilder.deleteSubscription(idRef.get()); + } } @Test - public void editSubscriptionAnonymous() throws Exception { + public void createSubscriptionByEPersonTest() throws Exception { + context.turnOffAuthorisationSystem(); + + Map map = new HashMap<>(); + map.put("type", "testType"); + List> list = new ArrayList<>(); + Map sub_list = new HashMap<>(); + sub_list.put("name", "Frequency"); + sub_list.put("value", "daily"); + list.add(sub_list); + map.put("subscriptionParameterList", list); + + context.restoreAuthSystemState(); + + AtomicReference idRef = new AtomicReference(); + + try { + String tokenEPerson = getAuthToken(eperson.getEmail(), password); + getClient(tokenEPerson).perform(post("/api/core/subscriptions") + .param("dspace_object_id", publicItem.getID().toString()) + .param("eperson_id", eperson.getID().toString()) + .content(new ObjectMapper().writeValueAsString(map)) + .contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(status().isCreated()) + .andExpect(jsonPath("$.subscriptionType", is("testType"))) + .andExpect(jsonPath("$.subscriptionParameterList[0].name", is("Frequency"))) + .andExpect(jsonPath("$.subscriptionParameterList[0].value", is("daily"))) + .andExpect(jsonPath("$._links.ePerson.href", Matchers.endsWith("ePerson"))) + .andExpect(jsonPath("$._links.dSpaceObject.href", Matchers.endsWith("dSpaceObject"))) + .andDo(result -> idRef.set(read(result.getResponse().getContentAsString(), "$.id"))); + } finally { + SubscribeBuilder.deleteSubscription(idRef.get()); + } + } + + @Test + public void createSubscriptionPersonForAnotherPersonTest() throws Exception { + context.turnOffAuthorisationSystem(); + + EPerson user = EPersonBuilder.createEPerson(context) + .withEmail("user1@mail.com") + .withPassword(password) + .build(); + + Map map = new HashMap<>(); + map.put("type", "testType"); + List> list = new ArrayList<>(); + Map sub_list = new HashMap<>(); + sub_list.put("name", "Frequency"); + sub_list.put("value", "Daily"); + list.add(sub_list); + map.put("subscriptionParameterList", list); + + context.restoreAuthSystemState(); + + String tokenEPerson = getAuthToken(eperson.getEmail(), password); + getClient(tokenEPerson).perform(post("/api/core/subscriptions") + .param("dspace_object_id", publicItem.getID().toString()) + .param("eperson_id", user.getID().toString()) + .content(new ObjectMapper().writeValueAsString(map)) + .contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(status().isForbidden()); + } + + @Test + public void deleteSubscriptionUnauthorizedTest() throws Exception { + context.turnOffAuthorisationSystem(); + List subscriptionParameterList = new ArrayList<>(); + SubscriptionParameter subscriptionParameter = new SubscriptionParameter(); + subscriptionParameter.setName("Frequency"); + subscriptionParameter.setValue("Daily"); + subscriptionParameterList.add(subscriptionParameter); + Subscription subscription = SubscribeBuilder.subscribeBuilder(context, + "Test", publicItem, eperson, subscriptionParameterList).build(); + context.restoreAuthSystemState(); + + getClient().perform(delete("/api/core/subscriptions/" + subscription.getID())) + .andExpect(status().isUnauthorized()); + } + + @Test + public void deleteSubscriptionAdminTest() throws Exception { + context.turnOffAuthorisationSystem(); + List subscriptionParameterList = new ArrayList<>(); + SubscriptionParameter subscriptionParameter = new SubscriptionParameter(); + subscriptionParameter.setName("Frequency"); + subscriptionParameter.setValue("Daily"); + subscriptionParameterList.add(subscriptionParameter); + Subscription subscription = SubscribeBuilder.subscribeBuilder(context, + "Test", publicItem, eperson, subscriptionParameterList).build(); + context.restoreAuthSystemState(); + + String tokenAdmin = getAuthToken(admin.getEmail(), password); + getClient(tokenAdmin).perform(delete("/api/core/subscriptions/" + subscription.getID())) + .andExpect(status().isNoContent()); + } + + @Test + public void deleteSubscriptionForbiddenTest() throws Exception { + context.turnOffAuthorisationSystem(); + List subscriptionParameterList = new ArrayList<>(); + SubscriptionParameter subscriptionParameter = new SubscriptionParameter(); + subscriptionParameter.setName("Frequency"); + subscriptionParameter.setValue("Daily"); + subscriptionParameterList.add(subscriptionParameter); + Subscription subscription = SubscribeBuilder.subscribeBuilder(context, + "Test", publicItem, admin, subscriptionParameterList).build(); + context.restoreAuthSystemState(); + + String tokenEPerson = getAuthToken(eperson.getEmail(), password); + getClient(tokenEPerson).perform(delete("/api/core/subscriptions/" + subscription.getID())) + .andExpect(status().isForbidden()); + } + + @Test + public void deleteSubscriptionNotFoundTest() throws Exception { + String tokenAdmin = getAuthToken(admin.getEmail(), password); + getClient(tokenAdmin).perform(delete("/api/core/subscriptions/" + Integer.MAX_VALUE)) + .andExpect(status().isNotFound()); + } + + @Test + public void putSubscriptionUnauthorizedTest() throws Exception { context.turnOffAuthorisationSystem(); List subscriptionParameterList = new ArrayList<>(); SubscriptionParameter subscriptionParameter = new SubscriptionParameter(); @@ -384,6 +571,8 @@ public class SubscriptionRestRepositoryIT extends AbstractControllerIntegrationT subscriptionParameterList.add(subscriptionParameter); Subscription subscription = SubscribeBuilder.subscribeBuilder(context, "TestType", publicItem, admin, subscriptionParameterList).build(); + context.restoreAuthSystemState(); + ObjectMapper objectMapper = new ObjectMapper(); Map newSubscription = new HashMap<>(); newSubscription.put("type", "test"); @@ -393,7 +582,6 @@ public class SubscriptionRestRepositoryIT extends AbstractControllerIntegrationT sub_list.put("value", "daily"); list.add(sub_list); newSubscription.put("subscriptionParameterList", list); - context.restoreAuthSystemState(); getClient().perform(put("/api/core/subscriptions/" + subscription.getID()) .param("dspace_object_id", publicItem.getID().toString()) @@ -404,44 +592,38 @@ public class SubscriptionRestRepositoryIT extends AbstractControllerIntegrationT } @Test - //TODO - public void editSubscriptionNotAsSubscriberNotAsAdmin() throws Exception { + public void putSubscriptionForbiddenTest() throws Exception { context.turnOffAuthorisationSystem(); - EPerson epersonIT = EPersonBuilder.createEPerson(context) - .withEmail("epersonIT@example.com") - .withPassword(password) - .withLanguage("al") - .build(); List subscriptionParameterList = new ArrayList<>(); SubscriptionParameter subscriptionParameter = new SubscriptionParameter(); subscriptionParameter.setName("Parameter1"); subscriptionParameter.setValue("ValueParameter1"); subscriptionParameterList.add(subscriptionParameter); Subscription subscription = SubscribeBuilder.subscribeBuilder(context, - "TestType", publicItem, eperson, subscriptionParameterList).build(); + "TestType", publicItem, admin, subscriptionParameterList).build(); context.restoreAuthSystemState(); + ObjectMapper objectMapper = new ObjectMapper(); Map newSubscription = new HashMap<>(); newSubscription.put("type", "test"); List> list = new ArrayList<>(); Map sub_list = new HashMap<>(); - sub_list.put("name", "frequency"); - sub_list.put("value", "daily"); + sub_list.put("name", "Frequency"); + sub_list.put("value", "Daily"); list.add(sub_list); newSubscription.put("subscriptionParameterList", list); - String token = getAuthToken(epersonIT.getEmail(), password); + String token = getAuthToken(eperson.getEmail(), password); getClient(token).perform(put("/api/core/subscriptions/" + subscription.getID()) - .param("dspace_object_id", publicItem.getID().toString()) .param("eperson_id", admin.getID().toString()) + .param("dspace_object_id", publicItem.getID().toString()) .content(objectMapper.writeValueAsString(newSubscription)) .contentType(MediaType.APPLICATION_JSON_VALUE)) - //The status has to be 500 Error - .andExpect(status().isInternalServerError()); + .andExpect(status().isForbidden()); } @Test - public void editSubscriptionAsAdministratorOrSubscriber() throws Exception { + public void putSubscriptionTest() throws Exception { context.turnOffAuthorisationSystem(); List subscriptionParameterList = new ArrayList<>(); SubscriptionParameter subscriptionParameter = new SubscriptionParameter(); @@ -449,15 +631,16 @@ public class SubscriptionRestRepositoryIT extends AbstractControllerIntegrationT subscriptionParameter.setValue("Daily"); subscriptionParameterList.add(subscriptionParameter); Subscription subscription = SubscribeBuilder.subscribeBuilder(context, - "TestType", publicItem, eperson, subscriptionParameterList).build(); + "TestType", publicItem, eperson, subscriptionParameterList).build(); context.restoreAuthSystemState(); + ObjectMapper objectMapper = new ObjectMapper(); Map newSubscription = new HashMap<>(); newSubscription.put("type", "test"); List> list = new ArrayList<>(); Map sub_list = new HashMap<>(); - sub_list.put("name", "frequency"); - sub_list.put("value", "daily"); + sub_list.put("name", "Frequency"); + sub_list.put("value", "WEEKLY"); list.add(sub_list); newSubscription.put("subscriptionParameterList", list); @@ -467,206 +650,50 @@ public class SubscriptionRestRepositoryIT extends AbstractControllerIntegrationT .param("eperson_id", eperson.getID().toString()) .content(objectMapper.writeValueAsString(newSubscription)) .contentType(MediaType.APPLICATION_JSON_VALUE)) - .andExpect(status().isOk()) - //We expect the content type to be "application/hal+json;charset=UTF-8" - .andExpect(content().contentType(contentType)) - //By default we expect at least 1 submission forms so this to be reflected in the page object - .andExpect(jsonPath("$.subscriptionType", is("test"))) - .andExpect(jsonPath("$.subscriptionParameterList[0].name", is("frequency"))) - .andExpect(jsonPath("$.subscriptionParameterList[0].value", is("daily"))) - .andExpect(jsonPath("$._links.self.href", Matchers.startsWith(REST_SERVER_URL + "core/subscriptions"))) - .andExpect(jsonPath("$._links.dSpaceObject.href", - Matchers.startsWith(REST_SERVER_URL + "core/subscriptions"))) - .andExpect(jsonPath("$._links.dSpaceObject.href", Matchers.endsWith("/dSpaceObject"))) - .andExpect(jsonPath("$._links.ePerson.href", - Matchers.startsWith(REST_SERVER_URL + "core/subscriptions"))) - .andExpect(jsonPath("$._links.ePerson.href", Matchers.endsWith("/ePerson"))); + .andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$.subscriptionType", is("test"))) + .andExpect(jsonPath("$.subscriptionParameterList[0].name", is("Frequency"))) + .andExpect(jsonPath("$.subscriptionParameterList[0].value", is("WEEKLY"))) + .andExpect(jsonPath("$._links.ePerson.href", Matchers.endsWith("/ePerson"))) + .andExpect(jsonPath("$._links.dSpaceObject.href",Matchers.endsWith("/dSpaceObject"))); } @Test - public void deleteSubscriptionNotAsSubscriberNotAsAdmin() throws Exception { - context.turnOffAuthorisationSystem(); - EPerson epersonIT = EPersonBuilder.createEPerson(context) - .withEmail("epersonIT@example.com") - .withPassword(password) - .withLanguage("al") - .build(); - List subscriptionParameterList = new ArrayList<>(); - SubscriptionParameter subscriptionParameter = new SubscriptionParameter(); - subscriptionParameter.setName("Frequency"); - subscriptionParameter.setValue("Daily"); - subscriptionParameterList.add(subscriptionParameter); - SubscribeBuilder.subscribeBuilder(context, "Test", publicItem, eperson, subscriptionParameterList).build(); - context.restoreAuthSystemState(); - - String epersonITtoken = getAuthToken(epersonIT.getEmail(), password); - getClient(epersonITtoken).perform(put("/api/core/subscriptions")) - .andExpect(status().isUnauthorized()); - } - - @Test - public void deleteSubscriptionAsAdmin() throws Exception { + public void putSubscriptionAdminTest() throws Exception { context.turnOffAuthorisationSystem(); List subscriptionParameterList = new ArrayList<>(); SubscriptionParameter subscriptionParameter = new SubscriptionParameter(); subscriptionParameter.setName("Frequency"); subscriptionParameter.setValue("Daily"); subscriptionParameterList.add(subscriptionParameter); - SubscribeBuilder.subscribeBuilder(context, "Test", publicItem, eperson, subscriptionParameterList).build(); + Subscription subscription = SubscribeBuilder.subscribeBuilder(context, + "TestType", publicItem, eperson, subscriptionParameterList).build(); context.restoreAuthSystemState(); + ObjectMapper objectMapper = new ObjectMapper(); + Map newSubscription = new HashMap<>(); + newSubscription.put("type", "test"); + List> list = new ArrayList<>(); + Map sub_list = new HashMap<>(); + sub_list.put("name", "Frequency"); + sub_list.put("value", "WEEKLY"); + list.add(sub_list); + newSubscription.put("subscriptionParameterList", list); + String tokenAdmin = getAuthToken(admin.getEmail(), password); - getClient(tokenAdmin).perform(put("/api/core/subscriptions")) - .andExpect(status().isOk()); + getClient(tokenAdmin).perform(put("/api/core/subscriptions/" + subscription.getID()) + .param("dspace_object_id", publicItem.getID().toString()) + .param("eperson_id", eperson.getID().toString()) + .content(objectMapper.writeValueAsString(newSubscription)) + .contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(status().isOk()) + .andExpect(content().contentType(contentType)) + .andExpect(jsonPath("$.subscriptionType", is("test"))) + .andExpect(jsonPath("$.subscriptionParameterList[0].name", is("Frequency"))) + .andExpect(jsonPath("$.subscriptionParameterList[0].value", is("WEEKLY"))) + .andExpect(jsonPath("$._links.ePerson.href", Matchers.endsWith("/ePerson"))) + .andExpect(jsonPath("$._links.dSpaceObject.href", Matchers.endsWith("/dSpaceObject"))); } - @Test - public void patchReplaceSubscriptionParameterAsAdmin() throws Exception { - context.turnOffAuthorisationSystem(); - List subscriptionParameterList = new ArrayList<>(); - SubscriptionParameter subscriptionParameter = new SubscriptionParameter(); - subscriptionParameter.setName("TestName"); - subscriptionParameter.setValue("TestValue"); - subscriptionParameterList.add(subscriptionParameter); - Subscription subscription = SubscribeBuilder.subscribeBuilder(context, - "Test", publicItem, eperson, subscriptionParameterList).build(); - List ops = new ArrayList(); - Map value = new HashMap<>(); - value.put("name", "frequency"); - value.put("value", "monthly"); - ReplaceOperation replaceOperation = new ReplaceOperation("/subscriptionsParameter/" - + subscription.getSubscriptionParameterList().get(0).getId(), value); - ops.add(replaceOperation); - String patchBody = getPatchContent(ops); - context.restoreAuthSystemState(); - - String tokenAdmin = getAuthToken(admin.getEmail(), password); - getClient(tokenAdmin).perform(patch("/api/core/subscriptions/" + subscription.getID()) - .content(patchBody)) - .andExpect(status().isOk()) - //We expect the content type to be "application/hal+json;charset=UTF-8" - .andExpect(content().contentType(contentType)) - //By default we expect at least 1 submission forms so this to be reflected in the page object - .andExpect(jsonPath("$.type", is("Test"))) - .andExpect(jsonPath("$.id", Matchers.endsWith(REST_SERVER_URL + "/api/core/dSpaceObject"))) - .andExpect(jsonPath("$.subscriptionParameterList[0].name", is("frequency"))) - .andExpect(jsonPath("$.subscriptionParameterList[0].value", is("monthly"))) - .andExpect(jsonPath("$._links.self.href", - Matchers.startsWith(REST_SERVER_URL + "/api/core/subscriptions"))) - .andExpect(jsonPath("$._links.dSpaceObject.href", - Matchers.startsWith(REST_SERVER_URL + "/api/core/subscriptions"))) - .andExpect(jsonPath("$._links.dSpaceObject.href", - Matchers.endsWith(REST_SERVER_URL + "/api/core/dSpaceObject"))) - .andExpect(jsonPath("$._links.ePerson.href", - Matchers.startsWith(REST_SERVER_URL + "/api/core/subscriptions"))) - .andExpect(jsonPath("$._links.ePerson.href", Matchers.endsWith(REST_SERVER_URL + "/api/core/ePerson"))); - } - - @Test - public void patchSubscriptionParameterNotAsAdminNotAsSubscriber() throws Exception { - context.turnOffAuthorisationSystem(); - List subscriptionParameterList = new ArrayList<>(); - SubscriptionParameter subscriptionParameter = new SubscriptionParameter(); - subscriptionParameter.setName("TestName"); - subscriptionParameter.setValue("TestValue"); - subscriptionParameterList.add(subscriptionParameter); - Subscription subscription = SubscribeBuilder.subscribeBuilder(context, - "Test", publicItem, eperson, subscriptionParameterList).build(); - List ops = new ArrayList(); - Map value = new HashMap<>(); - value.put("name", "frequency"); - value.put("value", "monthly"); - ReplaceOperation replaceOperation = new ReplaceOperation("/subscriptionsParameter/" - + subscription.getSubscriptionParameterList().get(0).getId(), value); - ops.add(replaceOperation); - String patchBody = getPatchContent(ops); - EPerson epersonIT = EPersonBuilder.createEPerson(context) - .withEmail("epersonIT@example.com") - .withPassword(password) - .withLanguage("al") - .build(); - context.restoreAuthSystemState(); - - String epersonITtoken = getAuthToken(epersonIT.getEmail(), password); - getClient(epersonITtoken).perform(patch("/api/core/subscriptions/" + subscription.getID()) - .content(patchBody)) - .andExpect(status().isForbidden()); - } - - @Test - public void patchAddSubscriptionParameter() throws Exception { - context.turnOffAuthorisationSystem(); - List subscriptionParameterList = new ArrayList<>(); - SubscriptionParameter subscriptionParameter = new SubscriptionParameter(); - subscriptionParameter.setName("TestName"); - subscriptionParameter.setValue("TestValue"); - subscriptionParameterList.add(subscriptionParameter); - Subscription subscription = SubscribeBuilder.subscribeBuilder(context, - "Test", publicItem, eperson, subscriptionParameterList).build(); - String token = getAuthToken(admin.getEmail(), password); - List ops = new ArrayList(); - Map value = new HashMap<>(); - value.put("name", "frequency"); - value.put("value", "monthly"); - AddOperation addOperation = new AddOperation("/subscriptionsParameter/" - + subscription.getSubscriptionParameterList().get(0).getId(), value); - ops.add(addOperation); - String patchBody = getPatchContent(ops); - getClient(token).perform(patch("/api/core/subscriptions/" + subscription.getID()) - .content(patchBody)) - .andExpect(status().isOk()) - //We expect the content type to be "application/hal+json;charset=UTF-8" - .andExpect(content().contentType(contentType)) - //By default we expect at least 1 submission forms so this to be reflected in the page object - .andExpect(jsonPath("$.type", is("Test"))) - .andExpect(jsonPath("$.id", Matchers.endsWith(REST_SERVER_URL + "/api/core/dSpaceObject"))) - .andExpect(jsonPath("$.subscriptionParameterList[0].name", is("TestName"))) - .andExpect(jsonPath("$.subscriptionParameterList[0].value", is("TestValue"))) - .andExpect(jsonPath("$.subscriptionParameterList[1].name", is("frequency"))) - .andExpect(jsonPath("$.subscriptionParameterList[1].value", is("monthly"))) - .andExpect(jsonPath("$._links.self.href", - Matchers.startsWith(REST_SERVER_URL + "/api/core/subscriptions"))) - .andExpect(jsonPath("$._links.dSpaceObject.href", - Matchers.startsWith(REST_SERVER_URL + "/api/core/subscriptions"))) - .andExpect(jsonPath("$._links.dSpaceObject.href", - Matchers.endsWith(REST_SERVER_URL + "/api/core/dSpaceObject"))) - .andExpect(jsonPath("$._links.ePerson.href", - Matchers.startsWith(REST_SERVER_URL + "/api/core/subscriptions"))) - .andExpect(jsonPath("$._links.ePerson.href", Matchers.endsWith(REST_SERVER_URL + "/api/core/ePerson"))); - } - - @Test - public void patchRemoveSubscriptionParameter() throws Exception { - context.turnOffAuthorisationSystem(); - List subscriptionParameterList = new ArrayList<>(); - SubscriptionParameter subscriptionParameter = new SubscriptionParameter(); - subscriptionParameter.setName("TestName"); - subscriptionParameter.setValue("TestValue"); - subscriptionParameterList.add(subscriptionParameter); - Subscription subscription = SubscribeBuilder.subscribeBuilder(context, - "Test", publicItem, eperson, subscriptionParameterList).build(); - List ops = new ArrayList(); - Map value = new HashMap<>(); - value.put("name", "frequency"); - value.put("value", "monthly"); - RemoveOperation removeOperation = new RemoveOperation("/subscriptionsParameter/" - + subscription.getSubscriptionParameterList().get(0).getId()); - ops.add(removeOperation); - String patchBody = getPatchContent(ops); - context.restoreAuthSystemState(); - - String token = getAuthToken(admin.getEmail(), password); - getClient(token).perform(patch("/api/core/subscriptions/" + subscription.getID()) - .content(patchBody)) - .andExpect(status().isOk()) - //We expect the content type to be "application/hal+json;charset=UTF-8" - .andExpect(content().contentType(contentType)) - //By default we expect at least 1 submission forms so this to be reflected in the page object - .andExpect(jsonPath("$.type", is("Test"))) - .andExpect(jsonPath("$.id", Matchers.endsWith(REST_SERVER_URL + "/api/core/dSpaceObject"))) - .andExpect(jsonPath("$.subscriptionParameterList", Matchers.arrayWithSize(0))) - .andExpect(jsonPath("$._links.self.href", - Matchers.startsWith(REST_SERVER_URL + "/api/core/subscriptions"))); - } - -} +} \ No newline at end of file diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/SubscriptionMatcher.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/SubscriptionMatcher.java new file mode 100644 index 0000000000..e5b49c2d2e --- /dev/null +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/SubscriptionMatcher.java @@ -0,0 +1,57 @@ +package org.dspace.app.rest.matcher; + +import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath; +import static org.dspace.app.rest.test.AbstractControllerIntegrationTest.REST_SERVER_URL; +import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.Matchers.is; + +import java.util.stream.Collectors; + +import org.dspace.eperson.Subscription; +import org.hamcrest.Matcher; +import org.hamcrest.Matchers; + +/** + * Provide convenient org.hamcrest.Matcher to verify a SubscriptionRest json response + * + * @author Mykhaylo Boychuk (mykhaylo.boychuk at 4science.it) + */ +public class SubscriptionMatcher { + + private SubscriptionMatcher() {} + + public static Matcher matchSubscription(Subscription subscription) { + return allOf( + hasJsonPath("$.id", is(subscription.getID())), + hasJsonPath("$.type", is("subscription")), + hasJsonPath("$.subscriptionType", is(subscription.getType())), + hasJsonPath("$.subscriptionParameterList", Matchers.containsInAnyOrder( + subscription.getSubscriptionParameterList().stream() + .map(x -> SubscriptionMatcher.matchSubscriptionParameter(x.getID(), x.getName(), x.getValue())) + .collect(Collectors.toList()) + )), + //Check links + matchLinks(subscription.getID()) + ); + } + + public static Matcher matchSubscriptionParameter(int id, String name, String value) { + return allOf( + hasJsonPath("$.id", is(id)), + hasJsonPath("$.name", is(name)), + hasJsonPath("$.value", is(value)) + ); + } + + /** + * Gets a matcher for all expected links. + */ + public static Matcher matchLinks(Integer id) { + return HalMatcher.matchLinks(REST_SERVER_URL + "core/subscriptions/" + id, + "dSpaceObject", + "ePerson", + "self" + ); + } + +} \ No newline at end of file