Merge branch 'DS-4466_new' of https://github.com/4science/DSpace into DS-4466_new

This commit is contained in:
Danilo Di Nuzzo
2020-06-22 18:29:49 +02:00
60 changed files with 1960 additions and 1157 deletions

View File

@@ -590,8 +590,11 @@ public class AuthorizeUtil {
authorizeManageAdminGroup(context, collection); authorizeManageAdminGroup(context, collection);
return; return;
} }
// if we reach this point, it means that the group is related
// to a collection but as it is not the submitters, nor the administrators,
// nor a workflow groups it must be a default item/bitstream groups
authorizeManageDefaultReadGroup(context, collection);
return;
} }
if (parentObject.getType() == Constants.COMMUNITY) { if (parentObject.getType() == Constants.COMMUNITY) {
Community community = (Community) parentObject; Community community = (Community) parentObject;
@@ -601,4 +604,38 @@ public class AuthorizeUtil {
throw new AuthorizeException("not authorized to manage this group"); throw new AuthorizeException("not authorized to manage this group");
} }
/**
* This method checks if the community Admin can manage accounts
*
* @return true if is able
*/
public static boolean canCommunityAdminManageAccounts() {
boolean isAble = false;
if (AuthorizeConfiguration.canCommunityAdminManagePolicies()
|| AuthorizeConfiguration.canCommunityAdminManageAdminGroup()
|| AuthorizeConfiguration.canCommunityAdminManageCollectionPolicies()
|| AuthorizeConfiguration.canCommunityAdminManageCollectionSubmitters()
|| AuthorizeConfiguration.canCommunityAdminManageCollectionWorkflows()
|| AuthorizeConfiguration.canCommunityAdminManageCollectionAdminGroup()) {
isAble = true;
}
return isAble;
}
/**
* This method checks if the Collection Admin can manage accounts
*
* @return true if is able
*/
public static boolean canCollectionAdminManageAccounts() {
boolean isAble = false;
if (AuthorizeConfiguration.canCollectionAdminManagePolicies()
|| AuthorizeConfiguration.canCollectionAdminManageSubmitters()
|| AuthorizeConfiguration.canCollectionAdminManageWorkflows()
|| AuthorizeConfiguration.canCollectionAdminManageAdminGroup()) {
isAble = true;
}
return isAble;
}
} }

View File

@@ -430,7 +430,11 @@ public class AuthorizeServiceImpl implements AuthorizeService {
public boolean isCommunityAdmin(Context c) throws SQLException { public boolean isCommunityAdmin(Context c) throws SQLException {
EPerson e = c.getCurrentUser(); EPerson e = c.getCurrentUser();
return isCommunityAdmin(c, e);
}
@Override
public boolean isCommunityAdmin(Context c, EPerson e) throws SQLException {
if (e != null) { if (e != null) {
List<ResourcePolicy> policies = resourcePolicyService.find(c, e, List<ResourcePolicy> policies = resourcePolicyService.find(c, e,
groupService.allMemberGroups(c, e), groupService.allMemberGroups(c, e),
@@ -446,7 +450,11 @@ public class AuthorizeServiceImpl implements AuthorizeService {
public boolean isCollectionAdmin(Context c) throws SQLException { public boolean isCollectionAdmin(Context c) throws SQLException {
EPerson e = c.getCurrentUser(); EPerson e = c.getCurrentUser();
return isCollectionAdmin(c, e);
}
@Override
public boolean isCollectionAdmin(Context c, EPerson e) throws SQLException {
if (e != null) { if (e != null) {
List<ResourcePolicy> policies = resourcePolicyService.find(c, e, List<ResourcePolicy> policies = resourcePolicyService.find(c, e,
groupService.allMemberGroups(c, e), groupService.allMemberGroups(c, e),

View File

@@ -213,6 +213,26 @@ public interface AuthorizeService {
public boolean isCollectionAdmin(Context c) throws SQLException; public boolean isCollectionAdmin(Context c) throws SQLException;
/**
* Check to see if a specific user is Community admin
*
* @param c current context
* @param e the user to check
* @return true if user is an admin of some community
* @throws SQLException
*/
public boolean isCommunityAdmin(Context c, EPerson e) throws SQLException;
/**
* Check to see if a specific user is Collection admin
*
* @param c current context
* @param e the user to check
* @return true if user is an admin of some collection
* @throws SQLException if database error
*/
public boolean isCollectionAdmin(Context c, EPerson e) throws SQLException;
/////////////////////////////////////////////// ///////////////////////////////////////////////
// policy manipulation methods // policy manipulation methods
/////////////////////////////////////////////// ///////////////////////////////////////////////

View File

@@ -23,7 +23,9 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import org.dspace.authorize.AuthorizeConfiguration; import org.dspace.authorize.AuthorizeConfiguration;
import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.AuthorizeException;
import org.dspace.authorize.ResourcePolicy;
import org.dspace.authorize.service.AuthorizeService; import org.dspace.authorize.service.AuthorizeService;
import org.dspace.authorize.service.ResourcePolicyService;
import org.dspace.content.Collection; import org.dspace.content.Collection;
import org.dspace.content.DSpaceObject; import org.dspace.content.DSpaceObject;
import org.dspace.content.DSpaceObjectServiceImpl; import org.dspace.content.DSpaceObjectServiceImpl;
@@ -76,6 +78,8 @@ public class GroupServiceImpl extends DSpaceObjectServiceImpl<Group> implements
@Autowired(required = true) @Autowired(required = true)
protected AuthorizeService authorizeService; protected AuthorizeService authorizeService;
@Autowired(required = true)
protected ResourcePolicyService resourcePolicyService;
protected GroupServiceImpl() { protected GroupServiceImpl() {
super(); super();
@@ -654,6 +658,23 @@ public class GroupServiceImpl extends DSpaceObjectServiceImpl<Group> implements
return collectionService.getParentObject(context, collection); return collectionService.getParentObject(context, collection);
} }
} }
} else {
if (AuthorizeConfiguration.canCollectionAdminManagePolicies()
|| AuthorizeConfiguration.canCommunityAdminManagePolicies()
|| AuthorizeConfiguration.canCommunityAdminManageCollectionWorkflows()) {
List<Group> groups = new ArrayList<Group>();
groups.add(group);
List<ResourcePolicy> policies = resourcePolicyService.find(context, null, groups,
Constants.DEFAULT_ITEM_READ, Constants.COLLECTION);
if (policies.size() > 0) {
return policies.get(0).getdSpaceObject();
}
policies = resourcePolicyService.find(context, null, groups,
Constants.DEFAULT_BITSTREAM_READ, Constants.COLLECTION);
if (policies.size() > 0) {
return policies.get(0).getdSpaceObject();
}
}
} }
} }
if (AuthorizeConfiguration.canCommunityAdminManageAdminGroup()) { if (AuthorizeConfiguration.canCommunityAdminManageAdminGroup()) {

View File

@@ -7,8 +7,10 @@
*/ */
package org.dspace.app.rest.converter; package org.dspace.app.rest.converter;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
@@ -17,6 +19,7 @@ import java.util.Set;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.dspace.app.rest.link.HalLinkFactory; import org.dspace.app.rest.link.HalLinkFactory;
import org.dspace.app.rest.link.HalLinkService; import org.dspace.app.rest.link.HalLinkService;
@@ -26,18 +29,22 @@ import org.dspace.app.rest.model.RestModel;
import org.dspace.app.rest.model.hateoas.HALResource; import org.dspace.app.rest.model.hateoas.HALResource;
import org.dspace.app.rest.projection.DefaultProjection; import org.dspace.app.rest.projection.DefaultProjection;
import org.dspace.app.rest.projection.Projection; import org.dspace.app.rest.projection.Projection;
import org.dspace.app.rest.repository.DSpaceRestRepository;
import org.dspace.app.rest.security.DSpacePermissionEvaluator; import org.dspace.app.rest.security.DSpacePermissionEvaluator;
import org.dspace.app.rest.security.WebSecurityExpressionEvaluator;
import org.dspace.app.rest.utils.Utils; import org.dspace.app.rest.utils.Utils;
import org.dspace.services.RequestService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider; import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.type.filter.AssignableTypeFilter; import org.springframework.core.type.filter.AssignableTypeFilter;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.hateoas.EntityModel; import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.Link; import org.springframework.hateoas.Link;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -71,6 +78,12 @@ public class ConverterService {
@Autowired @Autowired
private DSpacePermissionEvaluator dSpacePermissionEvaluator; private DSpacePermissionEvaluator dSpacePermissionEvaluator;
@Autowired
private WebSecurityExpressionEvaluator webSecurityExpressionEvaluator;
@Autowired
private RequestService requestService;
/** /**
* Converts the given model object to a rest object, using the appropriate {@link DSpaceConverter} and * Converts the given model object to a rest object, using the appropriate {@link DSpaceConverter} and
* the given projection. * the given projection.
@@ -94,8 +107,15 @@ public class ConverterService {
DSpaceConverter<M, R> converter = requireConverter(modelObject.getClass()); DSpaceConverter<M, R> converter = requireConverter(modelObject.getClass());
R restObject = converter.convert(transformedModel, projection); R restObject = converter.convert(transformedModel, projection);
if (restObject instanceof BaseObjectRest) { if (restObject instanceof BaseObjectRest) {
if (!dSpacePermissionEvaluator.hasPermission(SecurityContextHolder.getContext().getAuthentication(), BaseObjectRest baseObjectRest = (BaseObjectRest) restObject;
restObject, "READ")) { // This section will verify whether the current user has permissions to retrieve the
// rest object. It'll only return the REST object if the permission is granted.
// If permission isn't granted, it'll return null
String preAuthorizeValue = getPreAuthorizeAnnotationForBaseObject(baseObjectRest);
if (!webSecurityExpressionEvaluator
.evaluate(preAuthorizeValue, requestService.getCurrentRequest().getHttpServletRequest(),
requestService.getCurrentRequest().getHttpServletResponse(),
String.valueOf(baseObjectRest.getId()))) {
log.debug("Access denied on " + restObject.getClass() + " with id: " + log.debug("Access denied on " + restObject.getClass() + " with id: " +
((BaseObjectRest) restObject).getId()); ((BaseObjectRest) restObject).getId());
return null; return null;
@@ -107,6 +127,48 @@ public class ConverterService {
return restObject; return restObject;
} }
private String getPreAuthorizeAnnotationForBaseObject(BaseObjectRest restObject) {
Annotation preAuthorize = getAnnotationForRestObject(restObject);
if (preAuthorize == null) {
preAuthorize = getDefaultFindOnePreAuthorize();
}
return parseAnnotation(preAuthorize);
}
private String parseAnnotation(Annotation preAuthorize) {
if (preAuthorize != null) {
return (String) AnnotationUtils.getValue(preAuthorize);
}
return null;
}
private Annotation getAnnotationForRestObject(BaseObjectRest restObject) {
BaseObjectRest baseObjectRest = restObject;
DSpaceRestRepository repositoryToUse = utils
.getResourceRepositoryByCategoryAndModel(baseObjectRest.getCategory(), baseObjectRest.getType());
Annotation preAuthorize = null;
for (Method m : repositoryToUse.getClass().getMethods()) {
if (StringUtils.equalsIgnoreCase(m.getName(), "findOne")) {
preAuthorize = AnnotationUtils.findAnnotation(m, PreAuthorize.class);
}
}
return preAuthorize;
}
private Annotation getDefaultFindOnePreAuthorize() {
for (Method m : DSpaceRestRepository.class.getMethods()) {
if (StringUtils.equalsIgnoreCase(m.getName(), "findOne")) {
Annotation annotation = AnnotationUtils.findAnnotation(m, PreAuthorize.class);
if (annotation != null) {
return annotation;
}
}
}
return null;
}
/** /**
* Converts a list of model objects to a page of rest objects using the given {@link Projection}. * Converts a list of model objects to a page of rest objects using the given {@link Projection}.
* *
@@ -328,19 +390,19 @@ public class ConverterService {
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false); ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
provider.addIncludeFilter(new AssignableTypeFilter(EntityModel.class)); provider.addIncludeFilter(new AssignableTypeFilter(EntityModel.class));
Set<BeanDefinition> beanDefinitions = provider.findCandidateComponents( Set<BeanDefinition> beanDefinitions = provider.findCandidateComponents(
HALResource.class.getPackage().getName().replaceAll("\\.", "/")); HALResource.class.getPackage().getName().replaceAll("\\.", "/"));
for (BeanDefinition beanDefinition : beanDefinitions) { for (BeanDefinition beanDefinition : beanDefinitions) {
String resourceClassName = beanDefinition.getBeanClassName(); String resourceClassName = beanDefinition.getBeanClassName();
String resourceClassSimpleName = resourceClassName.substring(resourceClassName.lastIndexOf(".") + 1); String resourceClassSimpleName = resourceClassName.substring(resourceClassName.lastIndexOf(".") + 1);
String restClassSimpleName = resourceClassSimpleName String restClassSimpleName = resourceClassSimpleName
.replaceAll("ResourceWrapper$", "RestWrapper") .replaceAll("ResourceWrapper$", "RestWrapper")
.replaceAll("Resource$", "Rest"); .replaceAll("Resource$", "Rest");
String restClassName = RestModel.class.getPackage().getName() + "." + restClassSimpleName; String restClassName = RestModel.class.getPackage().getName() + "." + restClassSimpleName;
try { try {
Class<? extends RestModel> restClass = Class<? extends RestModel> restClass =
(Class<? extends RestModel>) Class.forName(restClassName); (Class<? extends RestModel>) Class.forName(restClassName);
Class<HALResource<? extends RestModel>> resourceClass = Class<HALResource<? extends RestModel>> resourceClass =
(Class<HALResource<? extends RestModel>>) Class.forName(resourceClassName); (Class<HALResource<? extends RestModel>>) Class.forName(resourceClassName);
Constructor compatibleConstructor = null; Constructor compatibleConstructor = null;
for (Constructor constructor : resourceClass.getDeclaredConstructors()) { for (Constructor constructor : resourceClass.getDeclaredConstructors()) {
if (constructor.getParameterCount() == 2 && constructor.getParameterTypes()[1] == Utils.class) { if (constructor.getParameterCount() == 2 && constructor.getParameterTypes()[1] == Utils.class) {
@@ -354,11 +416,11 @@ public class ConverterService {
resourceConstructors.put(restClass, compatibleConstructor); resourceConstructors.put(restClass, compatibleConstructor);
} else { } else {
log.warn("Skipping registration of resource class " + resourceClassName log.warn("Skipping registration of resource class " + resourceClassName
+ "; compatible constructor not found"); + "; compatible constructor not found");
} }
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
log.warn("Skipping registration of resource class " + resourceClassName log.warn("Skipping registration of resource class " + resourceClassName
+ "; rest class not found: " + restClassName); + "; rest class not found: " + restClassName);
} }
} }
} }

View File

@@ -22,7 +22,9 @@ import org.springframework.stereotype.Component;
/** /**
* This filter assures that when the dspace instance supports multiple languages * This filter assures that when the dspace instance supports multiple languages
* they are noted in the Content-Language Header of the response * they are noted in the Content-Language Header of the response. Where
* appropriate the single endpoint can set the Content-Language header directly
* to note that the response is specific for a language
* *
* @author Mykhaylo Boychuk (at 4science.it) * @author Mykhaylo Boychuk (at 4science.it)
*/ */
@@ -36,20 +38,17 @@ public class ContentLanguageHeaderResponseFilter implements Filter {
@Override @Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException { throws IOException, ServletException {
chain.doFilter(request, response);
HttpServletResponse httpServletResponse = (HttpServletResponse) response; HttpServletResponse httpServletResponse = (HttpServletResponse) response;
if (!httpServletResponse.containsHeader("Content-Language")) { Locale[] locales = I18nUtil.getSupportedLocales();
Locale[] locales = I18nUtil.getSupportedLocales(); StringBuilder locsStr = new StringBuilder();
StringBuilder locsStr = new StringBuilder(); for (Locale locale : locales) {
for (Locale locale : locales) { if (locsStr.length() > 0) {
if (locsStr.length() > 0) { locsStr.append(",");
locsStr.append(",");
}
locsStr.append(locale.getLanguage());
} }
httpServletResponse.setHeader("Content-Language", locsStr.toString()); locsStr.append(locale.getLanguage());
} }
httpServletResponse.setHeader("Content-Language", locsStr.toString());
chain.doFilter(request, response);
} }
@Override @Override

View File

@@ -12,7 +12,7 @@ import org.dspace.app.rest.ExternalSourcesRestController;
/** /**
* This class serves as a REST representation for an entry of external data * This class serves as a REST representation for an entry of external data
*/ */
public class ExternalSourceEntryRest extends BaseObjectRest<String> { public class ExternalSourceEntryRest extends RestAddressableModel {
public static final String NAME = "externalSourceEntry"; public static final String NAME = "externalSourceEntry";
public static final String PLURAL_NAME = "externalSourceEntries"; public static final String PLURAL_NAME = "externalSourceEntries";

View File

@@ -48,7 +48,7 @@ public class AuthorizationFeatureRestRepository extends DSpaceRestRepository<Aut
return converter.toRestPage(authorizationFeatureService.findAll(), pageable, utils.obtainProjection()); return converter.toRestPage(authorizationFeatureService.findAll(), pageable, utils.obtainProjection());
} }
@PreAuthorize("hasAuthority('ADMIN')") @PreAuthorize("permitAll()")
@Override @Override
public AuthorizationFeatureRest findOne(Context context, String id) { public AuthorizationFeatureRest findOne(Context context, String id) {
AuthorizationFeature authzFeature = authorizationFeatureService.find(id); AuthorizationFeature authzFeature = authorizationFeatureService.find(id);

View File

@@ -74,11 +74,11 @@ public class BundleRestRepository extends DSpaceObjectRestRepository<Bundle, Bun
this.bundleService = dsoService; this.bundleService = dsoService;
} }
@PreAuthorize("hasPermission(#uuid, 'BUNDLE', 'READ')") @PreAuthorize("hasPermission(#id, 'BUNDLE', 'READ')")
public BundleRest findOne(Context context, UUID uuid) { public BundleRest findOne(Context context, UUID id) {
Bundle bundle = null; Bundle bundle = null;
try { try {
bundle = bundleService.find(context, uuid); bundle = bundleService.find(context, id);
} catch (SQLException e) { } catch (SQLException e) {
throw new RuntimeException(e.getMessage(), e); throw new RuntimeException(e.getMessage(), e);
} }

View File

@@ -155,7 +155,7 @@ public class EPersonRestRepository extends DSpaceObjectRestRepository<EPerson, E
* contains the pagination information * contains the pagination information
* @return a Page of EPersonRest instances matching the user query * @return a Page of EPersonRest instances matching the user query
*/ */
@PreAuthorize("hasAuthority('ADMIN')") @PreAuthorize("hasAuthority('ADMIN') || hasAuthority('MANAGE_ACCESS_GROUP')")
@SearchRestMethod(name = "byMetadata") @SearchRestMethod(name = "byMetadata")
public Page<EPersonRest> findByMetadata(@Parameter(value = "query", required = true) String query, public Page<EPersonRest> findByMetadata(@Parameter(value = "query", required = true) String query,
Pageable pageable) { Pageable pageable) {

View File

@@ -30,6 +30,7 @@ public class EntityTypeRestRepository extends DSpaceRestRepository<EntityTypeRes
@Autowired @Autowired
private EntityTypeService entityTypeService; private EntityTypeService entityTypeService;
@Override
@PreAuthorize("permitAll()") @PreAuthorize("permitAll()")
public EntityTypeRest findOne(Context context, Integer integer) { public EntityTypeRest findOne(Context context, Integer integer) {
try { try {
@@ -43,6 +44,7 @@ public class EntityTypeRestRepository extends DSpaceRestRepository<EntityTypeRes
} }
} }
@Override
public Page<EntityTypeRest> findAll(Context context, Pageable pageable) { public Page<EntityTypeRest> findAll(Context context, Pageable pageable) {
try { try {
List<EntityType> entityTypes = entityTypeService.findAll(context); List<EntityType> entityTypes = entityTypeService.findAll(context);
@@ -52,6 +54,7 @@ public class EntityTypeRestRepository extends DSpaceRestRepository<EntityTypeRes
} }
} }
@Override
public Class<EntityTypeRest> getDomainClass() { public Class<EntityTypeRest> getDomainClass() {
return EntityTypeRest.class; return EntityTypeRest.class;
} }

View File

@@ -131,7 +131,7 @@ public class GroupRestRepository extends DSpaceObjectRestRepository<Group, Group
* @param pageable contains the pagination information * @param pageable contains the pagination information
* @return a Page of GroupRest instances matching the user query * @return a Page of GroupRest instances matching the user query
*/ */
@PreAuthorize("hasAuthority('ADMIN')") @PreAuthorize("hasAuthority('ADMIN') || hasAuthority('MANAGE_ACCESS_GROUP')")
@SearchRestMethod(name = "byMetadata") @SearchRestMethod(name = "byMetadata")
public Page<GroupRest> findByMetadata(@Parameter(value = "query", required = true) String query, public Page<GroupRest> findByMetadata(@Parameter(value = "query", required = true) String query,
Pageable pageable) { Pageable pageable) {

View File

@@ -7,7 +7,10 @@
*/ */
package org.dspace.app.rest.repository; package org.dspace.app.rest.repository;
import java.sql.SQLException;
import java.text.ParseException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.List; import java.util.List;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@@ -16,10 +19,6 @@ import org.dspace.app.rest.model.AccessConditionOptionRest;
import org.dspace.app.rest.model.SubmissionUploadRest; import org.dspace.app.rest.model.SubmissionUploadRest;
import org.dspace.app.rest.projection.Projection; import org.dspace.app.rest.projection.Projection;
import org.dspace.app.rest.utils.DateMathParser; import org.dspace.app.rest.utils.DateMathParser;
import org.dspace.app.util.SubmissionConfig;
import org.dspace.app.util.SubmissionConfigReader;
import org.dspace.app.util.SubmissionConfigReaderException;
import org.dspace.app.util.SubmissionStepConfig;
import org.dspace.core.Context; import org.dspace.core.Context;
import org.dspace.eperson.Group; import org.dspace.eperson.Group;
import org.dspace.eperson.service.GroupService; import org.dspace.eperson.service.GroupService;
@@ -28,7 +27,6 @@ import org.dspace.submit.model.UploadConfiguration;
import org.dspace.submit.model.UploadConfigurationService; import org.dspace.submit.model.UploadConfigurationService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -45,8 +43,6 @@ public class SubmissionUploadRestRepository extends DSpaceRestRepository<Submiss
private static final Logger log = org.apache.logging.log4j.LogManager private static final Logger log = org.apache.logging.log4j.LogManager
.getLogger(SubmissionUploadRestRepository.class); .getLogger(SubmissionUploadRestRepository.class);
private SubmissionConfigReader submissionConfigReader;
@Autowired @Autowired
private SubmissionFormRestRepository submissionFormRestRepository; private SubmissionFormRestRepository submissionFormRestRepository;
@@ -58,10 +54,6 @@ public class SubmissionUploadRestRepository extends DSpaceRestRepository<Submiss
DateMathParser dateMathParser = new DateMathParser(); DateMathParser dateMathParser = new DateMathParser();
public SubmissionUploadRestRepository() throws SubmissionConfigReaderException {
submissionConfigReader = new SubmissionConfigReader();
}
@PreAuthorize("hasAuthority('AUTHENTICATED')") @PreAuthorize("hasAuthority('AUTHENTICATED')")
@Override @Override
public SubmissionUploadRest findOne(Context context, String submitName) { public SubmissionUploadRest findOne(Context context, String submitName) {
@@ -77,27 +69,21 @@ public class SubmissionUploadRestRepository extends DSpaceRestRepository<Submiss
@PreAuthorize("hasAuthority('AUTHENTICATED')") @PreAuthorize("hasAuthority('AUTHENTICATED')")
@Override @Override
public Page<SubmissionUploadRest> findAll(Context context, Pageable pageable) { public Page<SubmissionUploadRest> findAll(Context context, Pageable pageable) {
List<SubmissionConfig> subConfs = new ArrayList<SubmissionConfig>(); Collection<UploadConfiguration> uploadConfigs = uploadConfigurationService.getMap().values();
subConfs = submissionConfigReader.getAllSubmissionConfigs(pageable.getPageSize(),
Math.toIntExact(pageable.getOffset()));
Projection projection = utils.obtainProjection(); Projection projection = utils.obtainProjection();
List<SubmissionUploadRest> results = new ArrayList<>(); List<SubmissionUploadRest> results = new ArrayList<>();
for (SubmissionConfig config : subConfs) { List<String> configNames = new ArrayList<String>();
for (int i = 0; i < config.getNumberOfSteps(); i++) { for (UploadConfiguration uploadConfig : uploadConfigs) {
SubmissionStepConfig step = config.getStep(i); if (!configNames.contains(uploadConfig.getName())) {
if (SubmissionStepConfig.UPLOAD_STEP_NAME.equals(step.getType())) { configNames.add(uploadConfig.getName());
UploadConfiguration uploadConfig = uploadConfigurationService.getMap().get(step.getId()); try {
if (uploadConfig != null) { results.add(convert(context, uploadConfig, projection));
try { } catch (Exception e) {
results.add(convert(context, uploadConfig, projection)); log.error(e.getMessage(), e);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
} }
} }
} }
return new PageImpl<SubmissionUploadRest>(results, pageable, results.size()); return utils.getPage(results, pageable);
} }
@Override @Override
@@ -105,20 +91,31 @@ public class SubmissionUploadRestRepository extends DSpaceRestRepository<Submiss
return SubmissionUploadRest.class; return SubmissionUploadRest.class;
} }
private SubmissionUploadRest convert(Context context, UploadConfiguration config, Projection projection) private SubmissionUploadRest convert(Context context, UploadConfiguration config, Projection projection) {
throws Exception {
SubmissionUploadRest result = new SubmissionUploadRest(); SubmissionUploadRest result = new SubmissionUploadRest();
result.setProjection(projection); result.setProjection(projection);
for (AccessConditionOption option : config.getOptions()) { for (AccessConditionOption option : config.getOptions()) {
AccessConditionOptionRest optionRest = new AccessConditionOptionRest(); AccessConditionOptionRest optionRest = new AccessConditionOptionRest();
if (option.getGroupName() != null) { if (option.getGroupName() != null) {
Group group = groupService.findByName(context, option.getGroupName()); Group group;
try {
group = groupService.findByName(context, option.getGroupName());
} catch (SQLException e) {
throw new IllegalStateException("Wrong group name configuration for the access condition "
+ "option named " + option.getName());
}
if (group != null) { if (group != null) {
optionRest.setGroupUUID(group.getID()); optionRest.setGroupUUID(group.getID());
} }
} }
if (option.getSelectGroupName() != null) { if (option.getSelectGroupName() != null) {
Group group = groupService.findByName(context, option.getSelectGroupName()); Group group;
try {
group = groupService.findByName(context, option.getSelectGroupName());
} catch (SQLException e) {
throw new IllegalStateException("Wrong select group name configuration for the access condition "
+ "option named " + option.getName());
}
if (group != null) { if (group != null) {
optionRest.setSelectGroupUUID(group.getID()); optionRest.setSelectGroupUUID(group.getID());
} }
@@ -126,10 +123,20 @@ public class SubmissionUploadRestRepository extends DSpaceRestRepository<Submiss
optionRest.setHasStartDate(option.getHasStartDate()); optionRest.setHasStartDate(option.getHasStartDate());
optionRest.setHasEndDate(option.getHasEndDate()); optionRest.setHasEndDate(option.getHasEndDate());
if (StringUtils.isNotBlank(option.getStartDateLimit())) { if (StringUtils.isNotBlank(option.getStartDateLimit())) {
optionRest.setMaxStartDate(dateMathParser.parseMath(option.getStartDateLimit())); try {
optionRest.setMaxStartDate(dateMathParser.parseMath(option.getStartDateLimit()));
} catch (ParseException e) {
throw new IllegalStateException("Wrong start date limit configuration for the access condition "
+ "option named " + option.getName());
}
} }
if (StringUtils.isNotBlank(option.getEndDateLimit())) { if (StringUtils.isNotBlank(option.getEndDateLimit())) {
optionRest.setMaxEndDate(dateMathParser.parseMath(option.getEndDateLimit())); try {
optionRest.setMaxEndDate(dateMathParser.parseMath(option.getEndDateLimit()));
} catch (ParseException e) {
throw new IllegalStateException("Wrong end date limit configuration for the access condition "
+ "option named " + option.getName());
}
} }
optionRest.setName(option.getName()); optionRest.setName(option.getName());
result.getAccessConditionOptions().add(optionRest); result.getAccessConditionOptions().add(optionRest);

View File

@@ -28,6 +28,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.rest.webmvc.ResourceNotFoundException; import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
/** /**
@@ -49,6 +50,7 @@ public class TemplateItemRestRepository extends DSpaceRestRepository<TemplateIte
ResourcePatch<Item> resourcePatch; ResourcePatch<Item> resourcePatch;
@Override @Override
@PreAuthorize("permitAll()")
public TemplateItemRest findOne(Context context, UUID uuid) { public TemplateItemRest findOne(Context context, UUID uuid) {
Item item = null; Item item = null;
try { try {

View File

@@ -1,31 +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.security;
import java.io.Serializable;
import org.apache.commons.lang3.StringUtils;
import org.dspace.app.rest.model.AuthenticationStatusRest;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
/**
* This class will handle calls made to AuthenticationStatusRest endpoints.
* It will return true because access can be granted anytime it's linked from another resource
*/
@Component
public class AuthenticationStatusRestPermissionEvaluatorPlugin extends RestObjectPermissionEvaluatorPlugin {
@Override
public boolean hasDSpacePermission(Authentication authentication, Serializable targetId, String targetType,
DSpaceRestPermission restPermission) {
if (!StringUtils.equalsIgnoreCase(AuthenticationStatusRest.NAME, targetType)) {
return false;
}
return true;
}
}

View File

@@ -1,31 +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.security;
import java.io.Serializable;
import org.apache.commons.lang3.StringUtils;
import org.dspace.app.rest.model.AuthnRest;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
/**
* This class will handle calls made to AuthnRest endpoints.
* It will return true because access can be granted anytime it's linked from another resource
*/
@Component
public class AuthnRestPermissionEvaluatorPlugin extends RestObjectPermissionEvaluatorPlugin {
@Override
public boolean hasDSpacePermission(Authentication authentication, Serializable targetId, String targetType,
DSpaceRestPermission restPermission) {
if (!StringUtils.equalsIgnoreCase(AuthnRest.NAME, targetType)) {
return false;
}
return true;
}
}

View File

@@ -1,31 +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.security;
import java.io.Serializable;
import org.apache.commons.lang3.StringUtils;
import org.dspace.app.rest.model.AuthorizationFeatureRest;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
/**
* This class will handle calls made to AuthorizationRest endpoints. It will return true because access can be granted
* anytime it's linked from another resource.
*/
@Component
public class AuthorizationFeatureRestPermissionEvaluatorPlugin extends RestObjectPermissionEvaluatorPlugin {
@Override
public boolean hasDSpacePermission(Authentication authentication, Serializable targetId, String targetType,
DSpaceRestPermission restPermission) {
if (!StringUtils.equalsIgnoreCase(AuthorizationFeatureRest.NAME, targetType)) {
return false;
}
return true;
}
}

View File

@@ -1,31 +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.security;
import java.io.Serializable;
import org.apache.commons.lang3.StringUtils;
import org.dspace.app.rest.model.BitstreamFormatRest;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
/**
* This class will handle calls made to BitstreamFormatRest endpoints.
* It will return true because access can be granted anytime it's linked from another resource
*/
@Component
public class BitstreamFormatRestPermissionEvaluatorPlugin extends RestObjectPermissionEvaluatorPlugin {
@Override
public boolean hasDSpacePermission(Authentication authentication, Serializable targetId, String targetType,
DSpaceRestPermission restPermission) {
if (!StringUtils.equalsIgnoreCase(BitstreamFormatRest.NAME, targetType)) {
return false;
}
return true;
}
}

View File

@@ -1,31 +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.security;
import java.io.Serializable;
import org.apache.commons.lang3.StringUtils;
import org.dspace.app.rest.model.BrowseIndexRest;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
/**
* This class will handle calls made to BrowseIndexRest endpoints.
* It will return true because access can be granted anytime it's linked from another resource
*/
@Component
public class BrowseIndexRestPermissionEvaluatorPlugin extends RestObjectPermissionEvaluatorPlugin {
@Override
public boolean hasDSpacePermission(Authentication authentication, Serializable targetId, String targetType,
DSpaceRestPermission restPermission) {
if (!StringUtils.equalsIgnoreCase(BrowseIndexRest.NAME, targetType)) {
return false;
}
return true;
}
}

View File

@@ -1,31 +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.security;
import java.io.Serializable;
import org.apache.commons.lang3.StringUtils;
import org.dspace.app.rest.model.DiscoveryResultsRest;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
/**
* This class will handle calls made to DiscoveryResultsRest endpoints.
* It will return true because access can be granted anytime it's linked from another resource
*/
@Component
public class DiscoveryResultRestPermissionEvaluatorPlugin extends RestObjectPermissionEvaluatorPlugin {
@Override
public boolean hasDSpacePermission(Authentication authentication, Serializable targetId, String targetType,
DSpaceRestPermission restPermission) {
if (!StringUtils.equalsIgnoreCase(DiscoveryResultsRest.NAME, targetType)) {
return false;
}
return true;
}
}

View File

@@ -18,6 +18,7 @@ import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.dspace.app.rest.utils.ContextUtil; import org.dspace.app.rest.utils.ContextUtil;
import org.dspace.app.util.AuthorizeUtil;
import org.dspace.authenticate.AuthenticationMethod; import org.dspace.authenticate.AuthenticationMethod;
import org.dspace.authenticate.service.AuthenticationService; import org.dspace.authenticate.service.AuthenticationService;
import org.dspace.authorize.service.AuthorizeService; import org.dspace.authorize.service.AuthorizeService;
@@ -47,6 +48,8 @@ public class EPersonRestAuthenticationProvider implements AuthenticationProvider
private static final Logger log = LoggerFactory.getLogger(EPersonRestAuthenticationProvider.class); private static final Logger log = LoggerFactory.getLogger(EPersonRestAuthenticationProvider.class);
public static final String MANAGE_ACCESS_GROUP = "MANAGE_ACCESS_GROUP";
@Autowired @Autowired
private AuthenticationService authenticationService; private AuthenticationService authenticationService;
@@ -140,14 +143,21 @@ public class EPersonRestAuthenticationProvider implements AuthenticationProvider
if (eperson != null) { if (eperson != null) {
boolean isAdmin = false; boolean isAdmin = false;
boolean isCommunityAdmin = false;
boolean isCollectionAdmin = false;
try { try {
isAdmin = authorizeService.isAdmin(context, eperson); isAdmin = authorizeService.isAdmin(context, eperson);
isCommunityAdmin = authorizeService.isCommunityAdmin(context, eperson);
isCollectionAdmin = authorizeService.isCollectionAdmin(context, eperson);
} catch (SQLException e) { } catch (SQLException e) {
log.error("SQL error while checking for admin rights", e); log.error("SQL error while checking for admin rights", e);
} }
if (isAdmin) { if (isAdmin) {
authorities.add(new SimpleGrantedAuthority(ADMIN_GRANT)); authorities.add(new SimpleGrantedAuthority(ADMIN_GRANT));
} else if ((isCommunityAdmin && AuthorizeUtil.canCommunityAdminManageAccounts())
|| (isCollectionAdmin && AuthorizeUtil.canCollectionAdminManageAccounts())) {
authorities.add(new SimpleGrantedAuthority(MANAGE_ACCESS_GROUP));
} }
authorities.add(new SimpleGrantedAuthority(AUTHENTICATED_GRANT)); authorities.add(new SimpleGrantedAuthority(AUTHENTICATED_GRANT));

View File

@@ -17,6 +17,7 @@ import org.dspace.app.rest.model.patch.Patch;
import org.dspace.app.rest.repository.patch.operation.DSpaceObjectMetadataPatchUtils; import org.dspace.app.rest.repository.patch.operation.DSpaceObjectMetadataPatchUtils;
import org.dspace.app.rest.repository.patch.operation.EPersonPasswordReplaceOperation; import org.dspace.app.rest.repository.patch.operation.EPersonPasswordReplaceOperation;
import org.dspace.app.rest.utils.ContextUtil; import org.dspace.app.rest.utils.ContextUtil;
import org.dspace.app.util.AuthorizeUtil;
import org.dspace.authorize.service.AuthorizeService; import org.dspace.authorize.service.AuthorizeService;
import org.dspace.core.Constants; import org.dspace.core.Constants;
import org.dspace.core.Context; import org.dspace.core.Context;
@@ -74,9 +75,13 @@ public class EPersonRestPermissionEvaluatorPlugin extends RestObjectPermissionEv
// anonymous user // anonymous user
if (ePerson == null) { if (ePerson == null) {
return false; return false;
} } else if (dsoId.equals(ePerson.getID())) {
return true;
if (dsoId.equals(ePerson.getID())) { } else if (authorizeService.isCommunityAdmin(context, ePerson)
&& AuthorizeUtil.canCommunityAdminManageAccounts()) {
return true;
} else if (authorizeService.isCollectionAdmin(context, ePerson)
&& AuthorizeUtil.canCollectionAdminManageAccounts()) {
return true; return true;
} }

View File

@@ -1,31 +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.security;
import java.io.Serializable;
import org.apache.commons.lang3.StringUtils;
import org.dspace.app.rest.model.EntityTypeRest;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
/**
* This class will handle calls made to EntityTypeRest endpoints.
* It will return true because access can be granted anytime it's linked from another resource
*/
@Component
public class EntityTypeRestPermissionEvaluatorPlugin extends RestObjectPermissionEvaluatorPlugin {
@Override
public boolean hasDSpacePermission(Authentication authentication, Serializable targetId, String targetType,
DSpaceRestPermission restPermission) {
if (!StringUtils.equalsIgnoreCase(EntityTypeRest.NAME, targetType)) {
return false;
}
return true;
}
}

View File

@@ -1,31 +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.security;
import java.io.Serializable;
import org.apache.commons.lang3.StringUtils;
import org.dspace.app.rest.model.ExternalSourceEntryRest;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
/**
* This class will handle calls made to ExternalSourceEntryRest endpoints.
* It will return true because access can be granted anytime it's linked from another resource
*/
@Component
public class ExternalSourceEntryRestPermissionEvaluatorPlugin extends RestObjectPermissionEvaluatorPlugin {
@Override
public boolean hasDSpacePermission(Authentication authentication, Serializable targetId, String targetType,
DSpaceRestPermission restPermission) {
if (!StringUtils.equalsIgnoreCase(ExternalSourceEntryRest.NAME, targetType)) {
return false;
}
return true;
}
}

View File

@@ -1,31 +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.security;
import java.io.Serializable;
import org.apache.commons.lang3.StringUtils;
import org.dspace.app.rest.model.ExternalSourceRest;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
/**
* This class will handle calls made to ExternalSourceRest endpoints.
* It will return true because access can be granted anytime it's linked from another resource
*/
@Component
public class ExternalSourceRestPermissionEvaluatorPlugin extends RestObjectPermissionEvaluatorPlugin {
@Override
public boolean hasDSpacePermission(Authentication authentication, Serializable targetId, String targetType,
DSpaceRestPermission restPermission) {
if (!StringUtils.equalsIgnoreCase(ExternalSourceRest.NAME, targetType)) {
return false;
}
return true;
}
}

View File

@@ -1,31 +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.security;
import java.io.Serializable;
import org.apache.commons.lang3.StringUtils;
import org.dspace.app.rest.model.FacetConfigurationRest;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
/**
* This class will handle calls made to FacetConfigurationRest endpoints.
* It will return true because access can be granted anytime it's linked from another resource
*/
@Component
public class FacetConfigurationRestPermissionEvaluatorPlugin extends RestObjectPermissionEvaluatorPlugin {
@Override
public boolean hasDSpacePermission(Authentication authentication, Serializable targetId, String targetType,
DSpaceRestPermission restPermission) {
if (!StringUtils.equalsIgnoreCase(FacetConfigurationRest.NAME, targetType)) {
return false;
}
return true;
}
}

View File

@@ -12,6 +12,8 @@ import java.sql.SQLException;
import java.util.UUID; import java.util.UUID;
import org.dspace.app.rest.utils.ContextUtil; import org.dspace.app.rest.utils.ContextUtil;
import org.dspace.app.util.AuthorizeUtil;
import org.dspace.authorize.service.AuthorizeService;
import org.dspace.core.Constants; import org.dspace.core.Constants;
import org.dspace.core.Context; import org.dspace.core.Context;
import org.dspace.eperson.EPerson; import org.dspace.eperson.EPerson;
@@ -44,6 +46,9 @@ public class GroupRestPermissionEvaluatorPlugin extends RestObjectPermissionEval
@Autowired @Autowired
private EPersonService ePersonService; private EPersonService ePersonService;
@Autowired
AuthorizeService authorizeService;
@Override @Override
public boolean hasDSpacePermission(Authentication authentication, Serializable targetId, public boolean hasDSpacePermission(Authentication authentication, Serializable targetId,
String targetType, DSpaceRestPermission permission) { String targetType, DSpaceRestPermission permission) {
@@ -64,7 +69,16 @@ public class GroupRestPermissionEvaluatorPlugin extends RestObjectPermissionEval
Group group = groupService.find(context, dsoId); Group group = groupService.find(context, dsoId);
if (groupService.isMember(context, ePerson, group)) { // anonymous user
if (ePerson == null) {
return false;
} else if (groupService.isMember(context, ePerson, group)) {
return true;
} else if (authorizeService.isCommunityAdmin(context, ePerson)
&& AuthorizeUtil.canCommunityAdminManageAccounts()) {
return true;
} else if (authorizeService.isCollectionAdmin(context, ePerson)
&& AuthorizeUtil.canCollectionAdminManageAccounts()) {
return true; return true;
} }

View File

@@ -1,31 +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.security;
import java.io.Serializable;
import org.apache.commons.lang3.StringUtils;
import org.dspace.app.rest.model.HarvestedCollectionRest;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
/**
* This class will handle calls made to HarvestedCollectionRest endpoints.
* It will return true because access can be granted anytime it's linked from another resource
*/
@Component
public class HarvestedCollectionRestPermissionEvaluatorPlugin extends RestObjectPermissionEvaluatorPlugin {
@Override
public boolean hasDSpacePermission(Authentication authentication, Serializable targetId, String targetType,
DSpaceRestPermission restPermission) {
if (!StringUtils.equalsIgnoreCase(HarvestedCollectionRest.NAME, targetType)) {
return false;
}
return true;
}
}

View File

@@ -1,31 +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.security;
import java.io.Serializable;
import org.apache.commons.lang3.StringUtils;
import org.dspace.app.rest.model.HarvesterMetadataRest;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
/**
* This class will handle calls made to HarvesterMetadataRest endpoints.
* It will return true because access can be granted anytime it's linked from another resource
*/
@Component
public class HarvesterMetadataRestPermissionEvaluatorPlugin extends RestObjectPermissionEvaluatorPlugin {
@Override
public boolean hasDSpacePermission(Authentication authentication, Serializable targetId, String targetType,
DSpaceRestPermission restPermission) {
if (!StringUtils.equalsIgnoreCase(HarvesterMetadataRest.NAME, targetType)) {
return false;
}
return true;
}
}

View File

@@ -1,31 +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.security;
import java.io.Serializable;
import org.apache.commons.lang3.StringUtils;
import org.dspace.app.rest.model.MetadataFieldRest;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
/**
* This class will handle calls made to MetadataFieldRest endpoints.
* It will return true because access can be granted anytime it's linked from another resource
*/
@Component
public class MetadataFieldRestPermissionEvaluatorPlugin extends RestObjectPermissionEvaluatorPlugin {
@Override
public boolean hasDSpacePermission(Authentication authentication, Serializable targetId, String targetType,
DSpaceRestPermission restPermission) {
if (!StringUtils.equalsIgnoreCase(MetadataFieldRest.NAME, targetType)) {
return false;
}
return true;
}
}

View File

@@ -1,31 +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.security;
import java.io.Serializable;
import org.apache.commons.lang3.StringUtils;
import org.dspace.app.rest.model.MetadataSchemaRest;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
/**
* This class will handle calls made to MetadataSchemaRest endpoints.
* It will return true because access can be granted anytime it's linked from another resource
*/
@Component
public class MetadataSchemaRestPermissionEvaluatorPlugin extends RestObjectPermissionEvaluatorPlugin {
@Override
public boolean hasDSpacePermission(Authentication authentication, Serializable targetId, String targetType,
DSpaceRestPermission restPermission) {
if (!StringUtils.equalsIgnoreCase(MetadataSchemaRest.NAME, targetType)) {
return false;
}
return true;
}
}

View File

@@ -1,31 +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.security;
import java.io.Serializable;
import org.apache.commons.lang3.StringUtils;
import org.dspace.app.rest.model.RelationshipRest;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
/**
* This class will handle calls made to RelationshipRest endpoints.
* It will return true because access can be granted anytime it's linked from another resource
*/
@Component
public class RelationshipRestPermissionEvaluatorPlugin extends RestObjectPermissionEvaluatorPlugin {
@Override
public boolean hasDSpacePermission(Authentication authentication, Serializable targetId, String targetType,
DSpaceRestPermission restPermission) {
if (!StringUtils.equalsIgnoreCase(RelationshipRest.NAME, targetType)) {
return false;
}
return true;
}
}

View File

@@ -1,31 +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.security;
import java.io.Serializable;
import org.apache.commons.lang3.StringUtils;
import org.dspace.app.rest.model.RelationshipTypeRest;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
/**
* This class will handle calls made to RelationshipTypeRest endpoints.
* It will return true because access can be granted anytime it's linked from another resource
*/
@Component
public class RelationshipTypeRestPermissionEvaluatorPlugin extends RestObjectPermissionEvaluatorPlugin {
@Override
public boolean hasDSpacePermission(Authentication authentication, Serializable targetId, String targetType,
DSpaceRestPermission restPermission) {
if (!StringUtils.equalsIgnoreCase(RelationshipTypeRest.NAME, targetType)) {
return false;
}
return true;
}
}

View File

@@ -1,30 +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.security;
import java.io.Serializable;
import org.apache.commons.lang3.StringUtils;
import org.dspace.app.rest.model.ScriptRest;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
/**
* This class will handle Permissions for the {@link ScriptRest} object and its calls
*/
@Component
public class ScriptRestPermissionEvaluatorPlugin extends RestObjectPermissionEvaluatorPlugin {
@Override
public boolean hasDSpacePermission(Authentication authentication, Serializable targetId, String targetType,
DSpaceRestPermission restPermission) {
if (!StringUtils.equalsIgnoreCase(ScriptRest.NAME, targetType)) {
return false;
}
return true;
}
}

View File

@@ -1,31 +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.security;
import java.io.Serializable;
import org.apache.commons.lang3.StringUtils;
import org.dspace.app.rest.model.SearchConfigurationRest;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
/**
* This class will handle calls made to SearchConfigurationRest endpoints.
* It will return true because access can be granted anytime it's linked from another resource
*/
@Component
public class SearchConfigurationRestPermissionEvaluatorPlugin extends RestObjectPermissionEvaluatorPlugin {
@Override
public boolean hasDSpacePermission(Authentication authentication, Serializable targetId, String targetType,
DSpaceRestPermission restPermission) {
if (!StringUtils.equalsIgnoreCase(SearchConfigurationRest.NAME, targetType)) {
return false;
}
return true;
}
}

View File

@@ -1,31 +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.security;
import java.io.Serializable;
import org.apache.commons.lang3.StringUtils;
import org.dspace.app.rest.model.SearchEventRest;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
/**
* This class will handle calls made to SearchEventRest endpoints.
* It will return true because access can be granted anytime it's linked from another resource
*/
@Component
public class SearchEventRestPermissionEvaluatorPlugin extends RestObjectPermissionEvaluatorPlugin {
@Override
public boolean hasDSpacePermission(Authentication authentication, Serializable targetId, String targetType,
DSpaceRestPermission restPermission) {
if (!StringUtils.equalsIgnoreCase(SearchEventRest.NAME, targetType)) {
return false;
}
return true;
}
}

View File

@@ -1,31 +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.security;
import java.io.Serializable;
import org.apache.commons.lang3.StringUtils;
import org.dspace.app.rest.model.SearchResultsRest;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
/**
* This class will handle calls made to SearchResultsRest endpoints.
* It will return true because access can be granted anytime it's linked from another resource
*/
@Component
public class SearchResultsRestPermissionEvaluatorPlugin extends RestObjectPermissionEvaluatorPlugin {
@Override
public boolean hasDSpacePermission(Authentication authentication, Serializable targetId, String targetType,
DSpaceRestPermission restPermission) {
if (!StringUtils.equalsIgnoreCase(SearchResultsRest.NAME, targetType)) {
return false;
}
return true;
}
}

View File

@@ -1,31 +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.security;
import java.io.Serializable;
import org.apache.commons.lang3.StringUtils;
import org.dspace.app.rest.model.SearchSupportRest;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
/**
* This class will handle calls made to SearchSupportRest endpoints.
* It will return true because access can be granted anytime it's linked from another resource
*/
@Component
public class SearchSupportRestPermissionEvaluatorPlugin extends RestObjectPermissionEvaluatorPlugin {
@Override
public boolean hasDSpacePermission(Authentication authentication, Serializable targetId, String targetType,
DSpaceRestPermission restPermission) {
if (!StringUtils.equalsIgnoreCase(SearchSupportRest.NAME, targetType)) {
return false;
}
return true;
}
}

View File

@@ -1,31 +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.security;
import java.io.Serializable;
import org.apache.commons.lang3.StringUtils;
import org.dspace.app.rest.model.SiteRest;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
/**
* This class will handle calls made to SiteRest endpoints.
* It will return true because access can be granted anytime it's linked from another resource
*/
@Component
public class SiteRestPermissionEvaluatorPlugin extends RestObjectPermissionEvaluatorPlugin {
@Override
public boolean hasDSpacePermission(Authentication authentication, Serializable targetId, String targetType,
DSpaceRestPermission restPermission) {
if (!StringUtils.equalsIgnoreCase(SiteRest.NAME, targetType)) {
return false;
}
return true;
}
}

View File

@@ -1,31 +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.security;
import java.io.Serializable;
import org.apache.commons.lang3.StringUtils;
import org.dspace.app.rest.model.StatisticsSupportRest;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
/**
* This class will handle calls made to StatisticsSupportRest endpoints.
* It will return true because access can be granted anytime it's linked from another resource
*/
@Component
public class StatisticsSupportRestPermissionEvaluatorPlugin extends RestObjectPermissionEvaluatorPlugin {
@Override
public boolean hasDSpacePermission(Authentication authentication, Serializable targetId, String targetType,
DSpaceRestPermission restPermission) {
if (!StringUtils.equalsIgnoreCase(StatisticsSupportRest.NAME, targetType)) {
return false;
}
return true;
}
}

View File

@@ -1,31 +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.security;
import java.io.Serializable;
import org.apache.commons.lang3.StringUtils;
import org.dspace.app.rest.model.SubmissionDefinitionRest;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
/**
* This class will handle calls made to SubmissionDefinitionRest endpoints.
* It will return true because access can be granted anytime it's linked from another resource
*/
@Component
public class SubmissionDefinitionRestPermissionEvaluatorPlugin extends RestObjectPermissionEvaluatorPlugin {
@Override
public boolean hasDSpacePermission(Authentication authentication, Serializable targetId, String targetType,
DSpaceRestPermission restPermission) {
if (!StringUtils.equalsIgnoreCase(SubmissionDefinitionRest.NAME, targetType)) {
return false;
}
return true;
}
}

View File

@@ -1,31 +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.security;
import java.io.Serializable;
import org.apache.commons.lang3.StringUtils;
import org.dspace.app.rest.model.SubmissionFormRest;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
/**
* This class will handle calls made to SubmissionFormRest endpoints.
* It will return true because access can be granted anytime it's linked from another resource
*/
@Component
public class SubmissionFormRestPermissionEvaluatorPlugin extends RestObjectPermissionEvaluatorPlugin {
@Override
public boolean hasDSpacePermission(Authentication authentication, Serializable targetId, String targetType,
DSpaceRestPermission restPermission) {
if (!StringUtils.equalsIgnoreCase(SubmissionFormRest.NAME, targetType)) {
return false;
}
return true;
}
}

View File

@@ -1,31 +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.security;
import java.io.Serializable;
import org.apache.commons.lang3.StringUtils;
import org.dspace.app.rest.model.SubmissionUploadRest;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
/**
* This class will handle calls made to SubmissionUploadRest endpoints.
* It will return true because access can be granted anytime it's linked from another resource
*/
@Component
public class SubmissionUploadRestPermissionEvaluatorPlugin extends RestObjectPermissionEvaluatorPlugin {
@Override
public boolean hasDSpacePermission(Authentication authentication, Serializable targetId, String targetType,
DSpaceRestPermission restPermission) {
if (!StringUtils.equalsIgnoreCase(SubmissionUploadRest.NAME, targetType)) {
return false;
}
return true;
}
}

View File

@@ -1,31 +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.security;
import java.io.Serializable;
import org.apache.commons.lang3.StringUtils;
import org.dspace.app.rest.model.SubmissionSectionRest;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
/**
* This class will handle calls made to SubmissionSectionRest endpoints.
* It will return true because access can be granted anytime it's linked from another resource
*/
@Component
public class SubmissonSectionRestPermissionEvaluatorPlugin extends RestObjectPermissionEvaluatorPlugin {
@Override
public boolean hasDSpacePermission(Authentication authentication, Serializable targetId, String targetType,
DSpaceRestPermission restPermission) {
if (!StringUtils.equalsIgnoreCase(SubmissionSectionRest.NAME, targetType)) {
return false;
}
return true;
}
}

View File

@@ -1,31 +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.security;
import java.io.Serializable;
import org.apache.commons.lang3.StringUtils;
import org.dspace.app.rest.model.TemplateItemRest;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
/**
* This class will handle calls made to TemplateItemRest endpoints.
* It will return true because access can be granted anytime it's linked from another resource
*/
@Component
public class TemplateItemRestPermissionEvaluatorPlugin extends RestObjectPermissionEvaluatorPlugin {
@Override
public boolean hasDSpacePermission(Authentication authentication, Serializable targetId, String targetType,
DSpaceRestPermission restPermission) {
if (!StringUtils.equalsIgnoreCase(TemplateItemRest.NAME, targetType)) {
return false;
}
return true;
}
}

View File

@@ -1,31 +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.security;
import java.io.Serializable;
import org.apache.commons.lang3.StringUtils;
import org.dspace.app.rest.model.ViewEventRest;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
/**
* This class will handle calls made to ViewEventRest endpoints.
* It will return true because access can be granted anytime it's linked from another resource
*/
@Component
public class ViewEventRestPermissionEvaluatorPlugin extends RestObjectPermissionEvaluatorPlugin {
@Override
public boolean hasDSpacePermission(Authentication authentication, Serializable targetId, String targetType,
DSpaceRestPermission restPermission) {
if (!StringUtils.equalsIgnoreCase(ViewEventRest.NAME, targetType)) {
return false;
}
return true;
}
}

View File

@@ -0,0 +1,95 @@
/**
* 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.util.List;
import javax.servlet.FilterChain;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.core.GenericTypeResolver;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.security.access.expression.ExpressionUtils;
import org.springframework.security.access.expression.SecurityExpressionHandler;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.FilterInvocation;
import org.springframework.stereotype.Component;
/**
* This class will contain the logic to allow us to evaluate an expression given through a String.
* This will be used by the {@link org.dspace.app.rest.converter.ConverterService} for parsing
* the {@link org.springframework.security.access.prepost.PreAuthorize} annotations used on the findOne
* methods of RestRepositories. A String will be given to the evaluate method and that String will then
* be parsed and a boolean will be returned based on the condition in the String.
* For example: "hasPermission(#id, 'ITEM', 'READ')" is such a String
* This will be evaluated and if the current user has the permission to read an item with the given id,
* a true will be returned, if not it'll be false.
* This works on all the methods in {@link org.springframework.security.access.expression.SecurityExpressionRoot}
*/
@Component
public class WebSecurityExpressionEvaluator {
private static final FilterChain EMPTY_CHAIN = (request, response) -> {
throw new UnsupportedOperationException();
};
private final List<SecurityExpressionHandler> securityExpressionHandlers;
/**
* Constructor for this class that sets all the {@link SecurityExpressionHandler} objects in a list
* @param securityExpressionHandlers The {@link SecurityExpressionHandler} for this class
*/
public WebSecurityExpressionEvaluator(List<SecurityExpressionHandler> securityExpressionHandlers) {
this.securityExpressionHandlers = securityExpressionHandlers;
}
/**
* This method will have to be used to evaluate the String given. It'll parse the String and resolve
* it to a method in {@link org.springframework.security.access.expression.SecurityExpressionRoot}
* and evaluate it to then return a boolean
* @param securityExpression The String that resembles the expression that has to be parsed
* @param request The current request
* @param response The current response
* @param id The id for the Object that is the subject of the permission
* @return A boolean indicating whether the currentUser adheres to the
* permissions in the securityExpression String or not
*/
public boolean evaluate(String securityExpression, HttpServletRequest request, HttpServletResponse response,
String id) {
SecurityExpressionHandler handler = getFilterSecurityHandler();
Expression expression = handler.getExpressionParser().parseExpression(securityExpression);
EvaluationContext evaluationContext = createEvaluationContext(handler, request, response);
evaluationContext.setVariable("id", id);
return ExpressionUtils.evaluateAsBoolean(expression, evaluationContext);
}
@SuppressWarnings("unchecked")
private EvaluationContext createEvaluationContext(SecurityExpressionHandler handler, HttpServletRequest request,
HttpServletResponse response) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
FilterInvocation filterInvocation = new FilterInvocation(request, response, EMPTY_CHAIN);
return handler.createEvaluationContext(authentication, filterInvocation);
}
private SecurityExpressionHandler getFilterSecurityHandler() {
return securityExpressionHandlers.stream()
.filter(handler ->
FilterInvocation.class.equals(
GenericTypeResolver.resolveTypeArgument(handler.getClass(),
SecurityExpressionHandler.class)))
.findAny()
.orElseThrow(() -> new IllegalStateException("No filter invocation security" +
" expression handler has been found! Handlers: " +
securityExpressionHandlers.size()));
}
}

View File

@@ -1,31 +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.security;
import java.io.Serializable;
import org.apache.commons.lang3.StringUtils;
import org.dspace.app.rest.model.WorkflowActionRest;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
/**
* This class will handle calls made to WorkflowActionRest endpoints.
* It will return true because access can be granted anytime it's linked from another resource
*/
@Component
public class WorkflowActionRestPermissionEvaluatorPlugin extends RestObjectPermissionEvaluatorPlugin {
@Override
public boolean hasDSpacePermission(Authentication authentication, Serializable targetId, String targetType,
DSpaceRestPermission restPermission) {
if (!StringUtils.equalsIgnoreCase(WorkflowActionRest.NAME, targetType)) {
return false;
}
return true;
}
}

View File

@@ -1,31 +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.security;
import java.io.Serializable;
import org.apache.commons.lang3.StringUtils;
import org.dspace.app.rest.model.WorkflowDefinitionRest;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
/**
* This class will handle calls made to WorkflowDefinitionRest endpoints.
* It will return true because access can be granted anytime it's linked from another resource
*/
@Component
public class WorkflowDefinitionRestPermissionEvaluatorPlugin extends RestObjectPermissionEvaluatorPlugin {
@Override
public boolean hasDSpacePermission(Authentication authentication, Serializable targetId, String targetType,
DSpaceRestPermission restPermission) {
if (!StringUtils.equalsIgnoreCase(WorkflowDefinitionRest.NAME, targetType)) {
return false;
}
return true;
}
}

View File

@@ -1,31 +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.security;
import java.io.Serializable;
import org.apache.commons.lang3.StringUtils;
import org.dspace.app.rest.model.WorkflowStepRest;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
/**
* This class will handle calls made to WorkflowStepRest endpoints.
* It will return true because access can be granted anytime it's linked from another resource
*/
@Component
public class WorkflowStepRestPermissionEvaluatorPlugin extends RestObjectPermissionEvaluatorPlugin {
@Override
public boolean hasDSpacePermission(Authentication authentication, Serializable targetId, String targetType,
DSpaceRestPermission restPermission) {
if (!StringUtils.equalsIgnoreCase(WorkflowStepRest.NAME, targetType)) {
return false;
}
return true;
}
}

View File

@@ -29,7 +29,7 @@ import org.springframework.beans.factory.annotation.Autowired;
/** /**
* Test suite for the Authorization Feature endpoint * Test suite for the Authorization Feature endpoint
* *
* @author Andrea Bollini (andrea.bollini at 4science.it) * @author Andrea Bollini (andrea.bollini at 4science.it)
* *
*/ */
@@ -50,10 +50,10 @@ public class AuthorizationFeatureRestRepositoryIT extends AbstractControllerInte
// verify that only the admin can access the endpoint (see subsequent call in the method) // verify that only the admin can access the endpoint (see subsequent call in the method)
getClient(adminToken).perform(get("/api/authz/features")).andExpect(status().isOk()) getClient(adminToken).perform(get("/api/authz/features")).andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.features", Matchers.hasSize(is(expReturn)))) .andExpect(jsonPath("$._embedded.features", Matchers.hasSize(is(expReturn))))
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/authz/features"))) .andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/authz/features")))
.andExpect(jsonPath("$.page.size", is(20))) .andExpect(jsonPath("$.page.size", is(20)))
.andExpect(jsonPath("$.page.totalElements", is(featuresNum))); .andExpect(jsonPath("$.page.totalElements", is(featuresNum)));
// verify that anonymous user cannot access // verify that anonymous user cannot access
getClient().perform(get("/api/authz/features")).andExpect(status().isUnauthorized()); getClient().perform(get("/api/authz/features")).andExpect(status().isUnauthorized());
// verify that normal user cannot access // verify that normal user cannot access
@@ -78,21 +78,21 @@ public class AuthorizationFeatureRestRepositoryIT extends AbstractControllerInte
AtomicReference<String> idRef = new AtomicReference<String>(); AtomicReference<String> idRef = new AtomicReference<String>();
getClient(adminToken) getClient(adminToken)
.perform(get("/api/authz/features").param("page", String.valueOf(page)).param("size", "1")) .perform(get("/api/authz/features").param("page", String.valueOf(page)).param("size", "1"))
.andExpect(status().isOk()).andExpect(jsonPath("$._embedded.features", Matchers.hasSize(is(1)))) .andExpect(status().isOk()).andExpect(jsonPath("$._embedded.features", Matchers.hasSize(is(1))))
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/authz/features"))) .andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/authz/features")))
.andExpect( .andExpect(
(page == 0) ? jsonPath("$._links.prev.href").doesNotExist() (page == 0) ? jsonPath("$._links.prev.href").doesNotExist()
: jsonPath("$._links.prev.href", Matchers.containsString("/api/authz/features"))) : jsonPath("$._links.prev.href", Matchers.containsString("/api/authz/features")))
.andExpect((page == featuresNum - 1) .andExpect((page == featuresNum - 1)
? jsonPath("$._links.next.href").doesNotExist() ? jsonPath("$._links.next.href").doesNotExist()
: jsonPath("$._links.next.href", Matchers.containsString("/api/authz/features"))) : jsonPath("$._links.next.href", Matchers.containsString("/api/authz/features")))
.andExpect(jsonPath("$._links.first.href", Matchers.containsString("/api/authz/features"))) .andExpect(jsonPath("$._links.first.href", Matchers.containsString("/api/authz/features")))
.andExpect(jsonPath("$._links.last.href", Matchers.containsString("/api/authz/features"))) .andExpect(jsonPath("$._links.last.href", Matchers.containsString("/api/authz/features")))
.andExpect(jsonPath("$.page.size", is(1))) .andExpect(jsonPath("$.page.size", is(1)))
.andExpect(jsonPath("$.page.totalElements", is(Integer.valueOf(featuresNum)))) .andExpect(jsonPath("$.page.totalElements", is(Integer.valueOf(featuresNum))))
.andDo(result -> idRef .andDo(result -> idRef
.set(read(result.getResponse().getContentAsString(), "$._embedded.features[0].id"))); .set(read(result.getResponse().getContentAsString(), "$._embedded.features[0].id")));
if (idRef.get() == null || featureIDs.contains(idRef.get())) { if (idRef.get() == null || featureIDs.contains(idRef.get())) {
fail("Duplicate feature " + idRef.get() + " returned at page " + page); fail("Duplicate feature " + idRef.get() + " returned at page " + page);
@@ -108,30 +108,17 @@ public class AuthorizationFeatureRestRepositoryIT extends AbstractControllerInte
* @throws Exception * @throws Exception
*/ */
public void findOneTest() throws Exception { public void findOneTest() throws Exception {
String adminToken = getAuthToken(admin.getEmail(), password); getClient().perform(get("/api/authz/features/withdrawItem")).andExpect(status().isOk())
// verify that only the admin can access the endpoint (see subsequent call in the method) .andExpect(jsonPath("$.id", is("withdrawItem")))
getClient(adminToken).perform(get("/api/authz/features/withdrawItem")).andExpect(status().isOk()) .andExpect(jsonPath("$.description", Matchers.any(String.class)))
.andExpect(jsonPath("$.id", is("withdrawItem"))) .andExpect(jsonPath("$.resourcetypes", Matchers.contains("core.item")))
.andExpect(jsonPath("$.description", Matchers.any(String.class))) .andExpect(jsonPath("$.type", is("feature")));
.andExpect(jsonPath("$.resourcetypes", Matchers.contains("core.item")))
.andExpect(jsonPath("$.type", is("feature")));
// verify that anonymous user cannot access
getClient().perform(get("/api/authz/features/withdrawItem")).andExpect(status().isUnauthorized());
// verify that normal user cannot access
String epersonAuthToken = getAuthToken(eperson.getEmail(), password);
getClient(epersonAuthToken).perform(get("/api/authz/features/withdrawItem")).andExpect(status().isForbidden());
} }
@Test @Test
public void findOneNotFoundTest() throws Exception { public void findOneNotFoundTest() throws Exception {
String adminToken = getAuthToken(admin.getEmail(), password); getClient().perform(get("/api/authz/features/not-existing-feature")).andExpect(status().isNotFound());
// verify that only the admin can access the endpoint and get the not found response code
// (see subsequent calls in the method for unauthorized and forbidden attempts)
getClient(adminToken).perform(get("/api/authz/features/not-existing-feature")).andExpect(status().isNotFound());
// verify that anonymous user cannot access, without information disclosure
getClient().perform(get("/api/authz/features/not-existing-feature")).andExpect(status().isUnauthorized());
// verify that normal user cannot access, without information disclosure
getClient(adminToken).perform(get("/api/authz/features/1")).andExpect(status().isNotFound());
} }
@Test @Test
@@ -146,27 +133,28 @@ public class AuthorizationFeatureRestRepositoryIT extends AbstractControllerInte
for (String type : alwaysTrueFeature.getSupportedTypes()) { for (String type : alwaysTrueFeature.getSupportedTypes()) {
// verify that only the admin can access the endpoint (see subsequent call in the method) // verify that only the admin can access the endpoint (see subsequent call in the method)
getClient(adminToken).perform(get("/api/authz/features/search/resourcetype").param("type", type)) getClient(adminToken).perform(get("/api/authz/features/search/resourcetype").param("type", type))
.andExpect(status().isOk()) .andExpect(status().isOk())
.andExpect(jsonPath("$", .andExpect(jsonPath("$",
JsonPathMatchers.hasJsonPath("$._embedded.features", JsonPathMatchers.hasJsonPath("$._embedded.features",
Matchers.everyItem( Matchers.everyItem(
JsonPathMatchers.hasJsonPath("$.resourcetypes", JsonPathMatchers.hasJsonPath(
Matchers.hasItem(is(type)))) "$.resourcetypes",
))) Matchers.hasItem(is(type))))
.andExpect( )))
jsonPath("$._links.self.href", .andExpect(
Matchers.containsString("/api/authz/features/search/resourcetype"))); jsonPath("$._links.self.href",
Matchers.containsString("/api/authz/features/search/resourcetype")));
} }
// verify that the right response code is returned also for not existing types // verify that the right response code is returned also for not existing types
getClient(adminToken).perform(get("/api/authz/features/search/resourcetype").param("type", "NOT-EXISTING")) getClient(adminToken).perform(get("/api/authz/features/search/resourcetype").param("type", "NOT-EXISTING"))
.andExpect(status().isOk()).andExpect(jsonPath("$.page.totalElements", is(0))); .andExpect(status().isOk()).andExpect(jsonPath("$.page.totalElements", is(0)));
// verify that anonymous user cannot access, without information disclosure // verify that anonymous user cannot access, without information disclosure
getClient().perform(get("/api/authz/features/search/resourcetype").param("type", "core.item")) getClient().perform(get("/api/authz/features/search/resourcetype").param("type", "core.item"))
.andExpect(status().isUnauthorized()); .andExpect(status().isUnauthorized());
// verify that normal user cannot access, without information disclosure // verify that normal user cannot access, without information disclosure
String epersonAuthToken = getAuthToken(eperson.getEmail(), password); String epersonAuthToken = getAuthToken(eperson.getEmail(), password);
getClient(epersonAuthToken).perform(get("/api/authz/features/search/resourcetype").param("type", "core.item")) getClient(epersonAuthToken).perform(get("/api/authz/features/search/resourcetype").param("type", "core.item"))
.andExpect(status().isForbidden()); .andExpect(status().isForbidden());
} }

View File

@@ -35,7 +35,6 @@ import org.dspace.eperson.Group;
import org.dspace.eperson.service.GroupService; import org.dspace.eperson.service.GroupService;
import org.dspace.workflow.WorkflowService; import org.dspace.workflow.WorkflowService;
import org.junit.Before; import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -971,11 +970,7 @@ public class CollectionGroupRestControllerIT extends AbstractControllerIntegrati
jsonPath("$", GroupMatcher.matchGroupEntry(role.getID(), role.getName()))); jsonPath("$", GroupMatcher.matchGroupEntry(role.getID(), role.getName())));
} }
// Put on ignore because there's no support to identify read rights on a group for a user in a special
// com/coll admin group
// Please refer to: https://jira.lyrasis.org/browse/DS-4505
@Test @Test
@Ignore
public void getCollectionDefaultItemReadGroupTestParentCommunityAdmin() throws Exception { public void getCollectionDefaultItemReadGroupTestParentCommunityAdmin() throws Exception {
context.turnOffAuthorisationSystem(); context.turnOffAuthorisationSystem();
String itemGroupString = "ITEM"; String itemGroupString = "ITEM";
@@ -993,11 +988,7 @@ public class CollectionGroupRestControllerIT extends AbstractControllerIntegrati
jsonPath("$", GroupMatcher.matchGroupEntry(role.getID(), role.getName()))); jsonPath("$", GroupMatcher.matchGroupEntry(role.getID(), role.getName())));
} }
// Put on ignore because there's no support to identify read rights on a group for a user in a special
// com/coll admin group
// Please refer to: https://jira.lyrasis.org/browse/DS-4505
@Test @Test
@Ignore
public void getCollectionDefaultItemReadGroupTestCollectionAdmin() throws Exception { public void getCollectionDefaultItemReadGroupTestCollectionAdmin() throws Exception {
context.turnOffAuthorisationSystem(); context.turnOffAuthorisationSystem();
String itemGroupString = "ITEM"; String itemGroupString = "ITEM";
@@ -1120,13 +1111,7 @@ public class CollectionGroupRestControllerIT extends AbstractControllerIntegrati
} }
// Put on ignore because there's no support to identify read rights on a group for a user in a special
// com/coll admin group
// Please refer to: https://jira.lyrasis.org/browse/DS-4505
@Test @Test
@Ignore
public void postCollectionDefaultItemReadGroupCreateDefaultItemReadGroupSuccessParentCommunityAdmin() public void postCollectionDefaultItemReadGroupCreateDefaultItemReadGroupSuccessParentCommunityAdmin()
throws Exception { throws Exception {
@@ -1161,12 +1146,7 @@ public class CollectionGroupRestControllerIT extends AbstractControllerIntegrati
} }
// Put on ignore because there's no support to identify read rights on a group for a user in a special
// com/coll admin group
// Please refer to: https://jira.lyrasis.org/browse/DS-4505
@Test @Test
@Ignore
public void postCollectionDefaultItemReadGroupCreateDefaultItemReadGroupSuccessCollectionAdmin() throws Exception { public void postCollectionDefaultItemReadGroupCreateDefaultItemReadGroupSuccessCollectionAdmin() throws Exception {
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper();
@@ -1475,11 +1455,7 @@ public class CollectionGroupRestControllerIT extends AbstractControllerIntegrati
jsonPath("$", GroupMatcher.matchGroupEntry(role.getID(), role.getName()))); jsonPath("$", GroupMatcher.matchGroupEntry(role.getID(), role.getName())));
} }
// Put on ignore because there's no support to identify read rights on a group for a user in a special
// com/coll admin group
// Please refer to: https://jira.lyrasis.org/browse/DS-4505
@Test @Test
@Ignore
public void getCollectionDefaultBitstreamReadGroupTestParentCommunityAdmin() throws Exception { public void getCollectionDefaultBitstreamReadGroupTestParentCommunityAdmin() throws Exception {
context.turnOffAuthorisationSystem(); context.turnOffAuthorisationSystem();
String bitstreamGroupString = "BITSTREAM"; String bitstreamGroupString = "BITSTREAM";
@@ -1497,11 +1473,7 @@ public class CollectionGroupRestControllerIT extends AbstractControllerIntegrati
jsonPath("$", GroupMatcher.matchGroupEntry(role.getID(), role.getName()))); jsonPath("$", GroupMatcher.matchGroupEntry(role.getID(), role.getName())));
} }
// Put on ignore because there's no support to identify read rights on a group for a user in a special
// com/coll admin group
// Please refer to: https://jira.lyrasis.org/browse/DS-4505
@Test @Test
@Ignore
public void getCollectionDefaultBitstreamReadGroupTestCollectionAdmin() throws Exception { public void getCollectionDefaultBitstreamReadGroupTestCollectionAdmin() throws Exception {
context.turnOffAuthorisationSystem(); context.turnOffAuthorisationSystem();
String bitstreamGroupString = "BITSTREAM"; String bitstreamGroupString = "BITSTREAM";
@@ -1627,13 +1599,7 @@ public class CollectionGroupRestControllerIT extends AbstractControllerIntegrati
} }
// Put on ignore because there's no support to identify read rights on a group for a user in a special
// com/coll admin group
// Please refer to: https://jira.lyrasis.org/browse/DS-4505
@Test @Test
@Ignore
public void postCollectionDefaultBitstreamReadGroupCreateDefaultBitstreamReadGroupSuccessParentCommunityAdmin() public void postCollectionDefaultBitstreamReadGroupCreateDefaultBitstreamReadGroupSuccessParentCommunityAdmin()
throws Exception { throws Exception {
@@ -1668,12 +1634,7 @@ public class CollectionGroupRestControllerIT extends AbstractControllerIntegrati
} }
// Put on ignore because there's no support to identify read rights on a group for a user in a special
// com/coll admin group
// Please refer to: https://jira.lyrasis.org/browse/DS-4505
@Test @Test
@Ignore
public void postCollectionDefaultBitstreamReadGroupCreateDefaultBitstreamReadGroupSuccessCollectionAdmin() public void postCollectionDefaultBitstreamReadGroupCreateDefaultBitstreamReadGroupSuccessCollectionAdmin()
throws Exception { throws Exception {

View File

@@ -10,6 +10,7 @@ package org.dspace.app.rest;
import static com.jayway.jsonpath.JsonPath.read; import static com.jayway.jsonpath.JsonPath.read;
import static org.dspace.app.rest.matcher.MetadataMatcher.matchMetadata; import static org.dspace.app.rest.matcher.MetadataMatcher.matchMetadata;
import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.allOf;
import static org.springframework.http.MediaType.parseMediaType;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
@@ -20,21 +21,31 @@ import java.util.UUID;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import org.dspace.app.rest.builder.CollectionBuilder;
import org.dspace.app.rest.builder.CommunityBuilder; import org.dspace.app.rest.builder.CommunityBuilder;
import org.dspace.app.rest.builder.EPersonBuilder;
import org.dspace.app.rest.builder.GroupBuilder;
import org.dspace.app.rest.matcher.EPersonMatcher;
import org.dspace.app.rest.matcher.GroupMatcher; import org.dspace.app.rest.matcher.GroupMatcher;
import org.dspace.app.rest.model.GroupRest; import org.dspace.app.rest.model.GroupRest;
import org.dspace.app.rest.model.MetadataRest; import org.dspace.app.rest.model.MetadataRest;
import org.dspace.app.rest.model.MetadataValueRest; import org.dspace.app.rest.model.MetadataValueRest;
import org.dspace.app.rest.test.AbstractControllerIntegrationTest; import org.dspace.app.rest.test.AbstractControllerIntegrationTest;
import org.dspace.authorize.service.AuthorizeService; import org.dspace.authorize.service.AuthorizeService;
import org.dspace.content.Collection;
import org.dspace.content.Community; import org.dspace.content.Community;
import org.dspace.content.service.CollectionService;
import org.dspace.content.service.CommunityService; import org.dspace.content.service.CommunityService;
import org.dspace.core.Constants; import org.dspace.core.Constants;
import org.dspace.eperson.EPerson;
import org.dspace.eperson.Group; import org.dspace.eperson.Group;
import org.dspace.eperson.service.GroupService; import org.dspace.eperson.service.GroupService;
import org.dspace.services.ConfigurationService;
import org.hamcrest.Matchers;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
public class CommunityAdminGroupRestControllerIT extends AbstractControllerIntegrationTest { public class CommunityAdminGroupRestControllerIT extends AbstractControllerIntegrationTest {
@@ -48,10 +59,19 @@ public class CommunityAdminGroupRestControllerIT extends AbstractControllerInteg
@Autowired @Autowired
private AuthorizeService authorizeService; private AuthorizeService authorizeService;
@Autowired
private CollectionService collectionService;
@Autowired
private ConfigurationService configurationService;
Collection collection;
@Before @Before
public void setup() { public void setup() {
context.turnOffAuthorisationSystem(); context.turnOffAuthorisationSystem();
parentCommunity = CommunityBuilder.createCommunity(context).withName("test").build(); parentCommunity = CommunityBuilder.createCommunity(context).withName("test").build();
collection = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build();
context.restoreAuthSystemState(); context.restoreAuthSystemState();
} }
@@ -437,4 +457,328 @@ public class CommunityAdminGroupRestControllerIT extends AbstractControllerInteg
getClient(token).perform(delete("/api/core/communities/" + UUID.randomUUID() + "/adminGroup")) getClient(token).perform(delete("/api/core/communities/" + UUID.randomUUID() + "/adminGroup"))
.andExpect(status().isNotFound()); .andExpect(status().isNotFound());
} }
@Test
public void communityAdminAddMembersToCommunityAdminGroupPropertySetToFalse() throws Exception {
context.turnOffAuthorisationSystem();
Group adminGroup = communityService.createAdministrators(context, parentCommunity);
authorizeService.addPolicy(context, parentCommunity, Constants.ADMIN, eperson);
EPerson ePerson = EPersonBuilder.createEPerson(context).withEmail("testToAdd@test.com").build();
configurationService.setProperty("core.authorization.community-admin.admin-group", false);
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
getClient(token).perform(
post("/api/eperson/groups/" + adminGroup.getID() + "/epersons")
.contentType(parseMediaType
(org.springframework.data.rest.webmvc.RestMediaTypes.TEXT_URI_LIST_VALUE))
.content("https://localhost:8080/server/api/eperson/epersons/" + ePerson.getID()))
.andExpect(status().isForbidden());
token = getAuthToken(admin.getEmail(), password);
getClient(token).perform(get("/api/eperson/groups/" + adminGroup.getID() + "/epersons"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.epersons", Matchers.not(Matchers.hasItem(
EPersonMatcher.matchEPersonOnEmail(ePerson.getEmail())
))));
}
@Test
public void communityAdminRemoveMembersFromCommunityAdminGroupPropertySetToFalse() throws Exception {
context.turnOffAuthorisationSystem();
Group adminGroup = communityService.createAdministrators(context, parentCommunity);
authorizeService.addPolicy(context, parentCommunity, Constants.ADMIN, eperson);
EPerson ePerson = EPersonBuilder.createEPerson(context).withEmail("testToAdd@test.com").build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
getClient(token).perform(
post("/api/eperson/groups/" + adminGroup.getID() + "/epersons")
.contentType(parseMediaType
(org.springframework.data.rest.webmvc.RestMediaTypes
.TEXT_URI_LIST_VALUE))
.content("https://localhost:8080/server/api/eperson/epersons/" + ePerson.getID()));
getClient(token).perform(get("/api/eperson/groups/" + adminGroup.getID() + "/epersons"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.epersons", Matchers.hasItem(
EPersonMatcher.matchEPersonOnEmail(ePerson.getEmail())
)));
configurationService.setProperty("core.authorization.community-admin.admin-group", false);
getClient(token).perform(delete("/api/eperson/groups/" + adminGroup.getID() + "/epersons/" + ePerson.getID()))
.andExpect(status().isForbidden());
token = getAuthToken(admin.getEmail(), password);
getClient(token).perform(get("/api/eperson/groups/" + adminGroup.getID() + "/epersons"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.epersons", Matchers.hasItem(
EPersonMatcher.matchEPersonOnEmail(ePerson.getEmail())
)));
}
@Test
public void communityAdminAddChildGroupToCommunityAdminGroupPropertySetToFalse() throws Exception {
context.turnOffAuthorisationSystem();
Group adminGroup = communityService.createAdministrators(context, parentCommunity);
authorizeService.addPolicy(context, parentCommunity, Constants.ADMIN, eperson);
Group group = GroupBuilder.createGroup(context).withName("testGroup").build();
configurationService.setProperty("core.authorization.community-admin.admin-group", false);
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
getClient(token).perform(
post("/api/eperson/groups/" + adminGroup.getID() + "/subgroups")
.contentType(parseMediaType
(org.springframework.data.rest.webmvc.RestMediaTypes
.TEXT_URI_LIST_VALUE))
.content("https://localhost:8080/server/api/eperson/groups/" + group.getID()))
.andExpect(status().isForbidden());
token = getAuthToken(admin.getEmail(), password);
getClient(token).perform(get("/api/eperson/groups/" + adminGroup.getID() + "/subgroups"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.subgroups", Matchers.not(Matchers.hasItem(
GroupMatcher.matchGroupWithName(group.getName())
))));
}
@Test
public void communityAdminRemoveChildGroupFromCommunityAdminGroupPropertySetToFalse() throws Exception {
context.turnOffAuthorisationSystem();
Group adminGroup = communityService.createAdministrators(context, parentCommunity);
authorizeService.addPolicy(context, parentCommunity, Constants.ADMIN, eperson);
Group group = GroupBuilder.createGroup(context).withName("testGroup").build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
getClient(token).perform(
post("/api/eperson/groups/" + adminGroup.getID() + "/subgroups")
.contentType(parseMediaType
(org.springframework.data.rest.webmvc.RestMediaTypes
.TEXT_URI_LIST_VALUE))
.content("https://localhost:8080/server/api/eperson/groups/" + group.getID()));
getClient(token).perform(get("/api/eperson/groups/" + adminGroup.getID() + "/subgroups"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.subgroups", Matchers.hasItem(
GroupMatcher.matchGroupWithName(group.getName())
)));
configurationService.setProperty("core.authorization.community-admin.admin-group", false);
getClient(token).perform(delete("/api/eperson/groups/" + adminGroup.getID() + "/subgroups/" + group.getID()))
.andExpect(status().isForbidden());
token = getAuthToken(admin.getEmail(), password);
getClient(token).perform(get("/api/eperson/groups/" + adminGroup.getID() + "/subgroups"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.subgroups", Matchers.hasItem(
GroupMatcher.matchGroupWithName(group.getName())
)));
}
@Test
public void communityAdminAddChildGroupToCollectionAdminGroupSuccess() throws Exception {
context.turnOffAuthorisationSystem();
Group adminGroup = collectionService.createAdministrators(context, collection);
authorizeService.addPolicy(context, parentCommunity, Constants.ADMIN, eperson);
Group group = GroupBuilder.createGroup(context).withName("testGroup").build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
getClient(token).perform(
post("/api/eperson/groups/" + adminGroup.getID() + "/subgroups")
.contentType(MediaType.parseMediaType
(org.springframework.data.rest.webmvc.RestMediaTypes
.TEXT_URI_LIST_VALUE))
.content("https://localhost:8080/server/api/eperson/groups/" + group.getID()));
getClient(token).perform(get("/api/eperson/groups/" + adminGroup.getID() + "/subgroups"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.subgroups", Matchers.hasItem(
GroupMatcher.matchGroupWithName(group.getName())
)));
}
@Test
public void communityAdminRemoveChildGroupFromCollectionAdminGroupSuccess() throws Exception {
context.turnOffAuthorisationSystem();
Group adminGroup = collectionService.createAdministrators(context, collection);
authorizeService.addPolicy(context, parentCommunity, Constants.ADMIN, eperson);
Group group = GroupBuilder.createGroup(context).withName("testGroup").build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
getClient(token).perform(
post("/api/eperson/groups/" + adminGroup.getID() + "/subgroups")
.contentType(MediaType.parseMediaType
(org.springframework.data.rest.webmvc.RestMediaTypes
.TEXT_URI_LIST_VALUE))
.content("https://localhost:8080/server/api/eperson/groups/" + group.getID()));
getClient(token).perform(get("/api/eperson/groups/" + adminGroup.getID() + "/subgroups"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.subgroups", Matchers.hasItem(
GroupMatcher.matchGroupWithName(group.getName())
)));
getClient(token).perform(delete("/api/eperson/groups/" + adminGroup.getID() + "/subgroups/" + group.getID()))
.andExpect(status().isNoContent());
getClient(token).perform(get("/api/eperson/groups/" + adminGroup.getID() + "/subgroups"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.subgroups", Matchers.not(Matchers.hasItem(
GroupMatcher.matchGroupWithName(group.getName())
))));
}
@Test
public void communityAdminAddMembersToCollectionAdminGroupPropertySetToFalse() throws Exception {
context.turnOffAuthorisationSystem();
Group adminGroup = collectionService.createAdministrators(context, collection);
authorizeService.addPolicy(context, parentCommunity, Constants.ADMIN, eperson);
EPerson ePerson = EPersonBuilder.createEPerson(context).withEmail("testToAdd@test.com").build();
configurationService.setProperty("core.authorization.community-admin.collection.admin-group", false);
configurationService.setProperty("core.authorization.collection-admin.admin-group", false);
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
getClient(token).perform(
post("/api/eperson/groups/" + adminGroup.getID() + "/epersons")
.contentType(MediaType.parseMediaType
(org.springframework.data.rest.webmvc.RestMediaTypes.TEXT_URI_LIST_VALUE))
.content("https://localhost:8080/server/api/eperson/epersons/" + ePerson.getID()))
.andExpect(status().isForbidden());
token = getAuthToken(admin.getEmail(), password);
getClient(token).perform(get("/api/eperson/groups/" + adminGroup.getID() + "/epersons"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.epersons", Matchers.not(Matchers.hasItem(
EPersonMatcher.matchEPersonOnEmail(ePerson.getEmail())
))));
}
@Test
public void communityAdminRemoveMembersFromCollectionAdminGroupPropertySetToFalse() throws Exception {
context.turnOffAuthorisationSystem();
Group adminGroup = collectionService.createAdministrators(context, collection);
authorizeService.addPolicy(context, parentCommunity, Constants.ADMIN, eperson);
EPerson ePerson = EPersonBuilder.createEPerson(context).withEmail("testToAdd@test.com").build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
getClient(token).perform(
post("/api/eperson/groups/" + adminGroup.getID() + "/epersons")
.contentType(MediaType.parseMediaType
(org.springframework.data.rest.webmvc.RestMediaTypes
.TEXT_URI_LIST_VALUE))
.content("https://localhost:8080/server/api/eperson/epersons/" + ePerson.getID()));
getClient(token).perform(get("/api/eperson/groups/" + adminGroup.getID() + "/epersons"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.epersons", Matchers.hasItem(
EPersonMatcher.matchEPersonOnEmail(ePerson.getEmail())
)));
configurationService.setProperty("core.authorization.community-admin.collection.admin-group", false);
configurationService.setProperty("core.authorization.collection-admin.admin-group", false);
getClient(token).perform(delete("/api/eperson/groups/" + adminGroup.getID() + "/epersons/" + ePerson.getID()))
.andExpect(status().isForbidden());
token = getAuthToken(admin.getEmail(), password);
getClient(token).perform(get("/api/eperson/groups/" + adminGroup.getID() + "/epersons"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.epersons", Matchers.hasItem(
EPersonMatcher.matchEPersonOnEmail(ePerson.getEmail())
)));
}
@Test
public void communityAdminAddChildGroupToCollectionAdminGroupPropertySetToFalse() throws Exception {
context.turnOffAuthorisationSystem();
Group adminGroup = collectionService.createAdministrators(context, collection);
authorizeService.addPolicy(context, parentCommunity, Constants.ADMIN, eperson);
Group group = GroupBuilder.createGroup(context).withName("testGroup").build();
configurationService.setProperty("core.authorization.community-admin.collection.admin-group", false);
configurationService.setProperty("core.authorization.collection-admin.admin-group", false);
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
getClient(token).perform(
post("/api/eperson/groups/" + adminGroup.getID() + "/subgroups")
.contentType(MediaType.parseMediaType
(org.springframework.data.rest.webmvc.RestMediaTypes
.TEXT_URI_LIST_VALUE))
.content("https://localhost:8080/server/api/eperson/groups/" + group.getID()))
.andExpect(status().isForbidden());
token = getAuthToken(admin.getEmail(), password);
getClient(token).perform(get("/api/eperson/groups/" + adminGroup.getID() + "/subgroups"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.subgroups", Matchers.not(Matchers.hasItem(
GroupMatcher.matchGroupWithName(group.getName())
))));
}
@Test
public void communityAdminRemoveChildGroupFromCollectionAdminGroupPropertySetToFalse() throws Exception {
context.turnOffAuthorisationSystem();
Group adminGroup = collectionService.createAdministrators(context, collection);
authorizeService.addPolicy(context, parentCommunity, Constants.ADMIN, eperson);
Group group = GroupBuilder.createGroup(context).withName("testGroup").build();
context.restoreAuthSystemState();
String token = getAuthToken(eperson.getEmail(), password);
getClient(token).perform(
post("/api/eperson/groups/" + adminGroup.getID() + "/subgroups")
.contentType(MediaType.parseMediaType
(org.springframework.data.rest.webmvc.RestMediaTypes
.TEXT_URI_LIST_VALUE))
.content("https://localhost:8080/server/api/eperson/groups/" + group.getID()));
getClient(token).perform(get("/api/eperson/groups/" + adminGroup.getID() + "/subgroups"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.subgroups", Matchers.hasItem(
GroupMatcher.matchGroupWithName(group.getName())
)));
configurationService.setProperty("core.authorization.community-admin.collection.admin-group", false);
configurationService.setProperty("core.authorization.collection-admin.admin-group", false);
getClient(token).perform(delete("/api/eperson/groups/" + adminGroup.getID() + "/subgroups/" + group.getID()))
.andExpect(status().isForbidden());
token = getAuthToken(admin.getEmail(), password);
getClient(token).perform(get("/api/eperson/groups/" + adminGroup.getID() + "/subgroups"))
.andExpect(status().isOk())
.andExpect(jsonPath("$._embedded.subgroups", Matchers.hasItem(
GroupMatcher.matchGroupWithName(group.getName())
)));
}
} }

View File

@@ -25,6 +25,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
@@ -48,15 +49,20 @@ import org.dspace.app.rest.model.patch.ReplaceOperation;
import org.dspace.app.rest.test.AbstractControllerIntegrationTest; import org.dspace.app.rest.test.AbstractControllerIntegrationTest;
import org.dspace.app.rest.test.MetadataPatchSuite; import org.dspace.app.rest.test.MetadataPatchSuite;
import org.dspace.content.Collection; import org.dspace.content.Collection;
import org.dspace.content.Community;
import org.dspace.content.Item; import org.dspace.content.Item;
import org.dspace.eperson.EPerson; import org.dspace.eperson.EPerson;
import org.dspace.eperson.Group; import org.dspace.eperson.Group;
import org.dspace.services.ConfigurationService;
import org.hamcrest.Matchers; import org.hamcrest.Matchers;
import org.junit.Test; import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
public class EPersonRestRepositoryIT extends AbstractControllerIntegrationTest { public class EPersonRestRepositoryIT extends AbstractControllerIntegrationTest {
@Autowired
private ConfigurationService configurationService;
@Test @Test
public void createTest() throws Exception { public void createTest() throws Exception {
@@ -1787,6 +1793,167 @@ public class EPersonRestRepositoryIT extends AbstractControllerIntegrationTest {
} }
@Test
public void findByMetadataByCommAdminAndByColAdminTest() throws Exception {
context.turnOffAuthorisationSystem();
EPerson adminChild1 = EPersonBuilder.createEPerson(context)
.withNameInMetadata("Oliver", "Rossi")
.withEmail("adminChild1@example.com")
.withPassword(password)
.build();
EPerson adminCol1 = EPersonBuilder.createEPerson(context)
.withNameInMetadata("James", "Rossi")
.withEmail("adminCol1@example.com")
.withPassword(password)
.build();
EPerson colSubmitter = EPersonBuilder.createEPerson(context)
.withNameInMetadata("Carl", "Rossi")
.withEmail("colSubmitter@example.com")
.withPassword(password)
.build();
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community")
.withAdminGroup(eperson)
.build();
Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity)
.withName("Sub Community")
.withAdminGroup(adminChild1)
.build();
Collection col1 = CollectionBuilder.createCollection(context, child1)
.withName("Collection 1")
.withAdminGroup(adminCol1)
.withSubmitterGroup(colSubmitter)
.build();
context.restoreAuthSystemState();
String tokenAdminComm = getAuthToken(adminChild1.getEmail(), password);
String tokenAdminCol = getAuthToken(adminCol1.getEmail(), password);
String tokencolSubmitter = getAuthToken(colSubmitter.getEmail(), password);
getClient(tokenAdminComm).perform(get("/api/eperson/epersons/search/byMetadata")
.param("query", "Rossi"))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.epersons", Matchers.containsInAnyOrder(
EPersonMatcher.matchEPersonEntry(adminChild1),
EPersonMatcher.matchEPersonEntry(adminCol1),
EPersonMatcher.matchEPersonEntry(colSubmitter)
)))
.andExpect(jsonPath("$.page.totalElements", is(3)));
getClient(tokenAdminCol).perform(get("/api/eperson/epersons/search/byMetadata")
.param("query", "Rossi"))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.epersons", Matchers.containsInAnyOrder(
EPersonMatcher.matchEPersonEntry(adminChild1),
EPersonMatcher.matchEPersonEntry(adminCol1),
EPersonMatcher.matchEPersonEntry(colSubmitter)
)))
.andExpect(jsonPath("$.page.totalElements", is(3)));
getClient(tokencolSubmitter).perform(get("/api/eperson/epersons/search/byMetadata")
.param("query", "Rossi"))
.andExpect(status().isForbidden());
}
@Test
public void findByMetadataByCommAdminAndByColAdminWithoutAuthorizationsTest() throws Exception {
context.turnOffAuthorisationSystem();
List<String> confPropsCollectionAdmins = new LinkedList<>();
confPropsCollectionAdmins.add("core.authorization.collection-admin.policies");
confPropsCollectionAdmins.add("core.authorization.collection-admin.workflows");
confPropsCollectionAdmins.add("core.authorization.collection-admin.submitters");
confPropsCollectionAdmins.add("core.authorization.collection-admin.admin-group");
List<String> confPropsCommunityAdmins = new LinkedList<>();
confPropsCommunityAdmins.add("core.authorization.community-admin.policies");
confPropsCommunityAdmins.add("core.authorization.community-admin.admin-group");
confPropsCommunityAdmins.add("core.authorization.community-admin.collection.policies");
confPropsCommunityAdmins.add("core.authorization.community-admin.collection.workflows");
confPropsCommunityAdmins.add("core.authorization.community-admin.collection.submitters");
confPropsCommunityAdmins.add("core.authorization.community-admin.collection.admin-group");
EPerson adminChild1 = EPersonBuilder.createEPerson(context)
.withNameInMetadata("Oliver", "Rossi")
.withEmail("adminChild1@example.com")
.withPassword(password)
.build();
EPerson adminCol = EPersonBuilder.createEPerson(context)
.withNameInMetadata("James", "Rossi")
.withEmail("adminCol1@example.com")
.withPassword(password)
.build();
EPerson col1Submitter = EPersonBuilder.createEPerson(context)
.withNameInMetadata("Carl", "Rossi")
.withEmail("col1Submitter@example.com")
.withPassword(password)
.build();
parentCommunity = CommunityBuilder.createCommunity(context)
.withName("Parent Community")
.withAdminGroup(eperson)
.build();
Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity)
.withName("Sub Community")
.withAdminGroup(adminChild1)
.build();
Collection col1 = CollectionBuilder.createCollection(context, child1)
.withName("Collection 1")
.withAdminGroup(adminCol)
.withSubmitterGroup(col1Submitter)
.build();
context.restoreAuthSystemState();
String tokenAdminCol = getAuthToken(adminCol.getEmail(), password);
String tokenAdminComm = getAuthToken(adminChild1.getEmail(), password);
for (String prop : confPropsCollectionAdmins) {
getClient(tokenAdminCol).perform(get("/api/eperson/epersons/search/byMetadata")
.param("query", "Rossi"))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.epersons", Matchers.containsInAnyOrder(
EPersonMatcher.matchEPersonEntry(adminChild1),
EPersonMatcher.matchEPersonEntry(adminCol),
EPersonMatcher.matchEPersonEntry(col1Submitter)
)))
.andExpect(jsonPath("$.page.totalElements", is(3)));
configurationService.setProperty(prop, false);
}
getClient(tokenAdminCol).perform(get("/api/eperson/epersons/search/byMetadata")
.param("query", "Rossi"))
.andExpect(status().isForbidden());
for (String prop : confPropsCommunityAdmins) {
getClient(tokenAdminComm).perform(get("/api/eperson/epersons/search/byMetadata")
.param("query", "Rossi"))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$._embedded.epersons", Matchers.containsInAnyOrder(
EPersonMatcher.matchEPersonEntry(adminChild1),
EPersonMatcher.matchEPersonEntry(adminCol),
EPersonMatcher.matchEPersonEntry(col1Submitter)
)))
.andExpect(jsonPath("$.page.totalElements", is(3)));
configurationService.setProperty(prop, false);
}
getClient(tokenAdminComm).perform(get("/api/eperson/epersons/search/byMetadata")
.param("query", "Rossi"))
.andExpect(status().isForbidden());
}
@Test @Test
public void discoverableNestedLinkTest() throws Exception { public void discoverableNestedLinkTest() throws Exception {
String token = getAuthToken(eperson.getEmail(), password); String token = getAuthToken(eperson.getEmail(), password);

View File

@@ -18,6 +18,7 @@ import org.dspace.content.authority.ChoiceAuthorityServiceImpl;
import org.dspace.core.LegacyPluginServiceImpl; import org.dspace.core.LegacyPluginServiceImpl;
import org.dspace.eperson.EPerson; import org.dspace.eperson.EPerson;
import org.dspace.services.ConfigurationService; import org.dspace.services.ConfigurationService;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -42,6 +43,8 @@ public class LanguageSupportIT extends AbstractControllerIntegrationTest {
} }
@Test @Test
@Ignore("This test fails due to a bug in the MockHttpResponseServlet,"
+ " see https://github.com/spring-projects/spring-framework/issues/25281")
public void checkEnabledMultipleLanguageSupportTest() throws Exception { public void checkEnabledMultipleLanguageSupportTest() throws Exception {
context.turnOffAuthorisationSystem(); context.turnOffAuthorisationSystem();
String[] supportedLanguage = {"uk","it"}; String[] supportedLanguage = {"uk","it"};
@@ -75,7 +78,7 @@ public class LanguageSupportIT extends AbstractControllerIntegrationTest {
.andExpect(header().stringValues("Content-Language","uk, it")); .andExpect(header().stringValues("Content-Language","uk, it"));
getClient(tokenEPersonFR).perform(get("/api").locale(it)) getClient(tokenEPersonFR).perform(get("/api").locale(it))
.andExpect(header().stringValues("Content-Language","en")); .andExpect(header().stringValues("Content-Language","uk, it"));
configurationService.setProperty("webui.supported.locales",null); configurationService.setProperty("webui.supported.locales",null);
legacyPluginService.clearNamedPluginClasses(); legacyPluginService.clearNamedPluginClasses();

View File

@@ -43,6 +43,13 @@ public class ProcessRestRepositoryIT extends AbstractControllerIntegrationTest {
@Before @Before
public void setup() throws SQLException { public void setup() throws SQLException {
CollectionUtils.emptyIfNull(processService.findAll(context)).stream().forEach(process -> {
try {
processService.delete(context, process);
} catch (SQLException e) {
throw new RuntimeException(e);
}
});
parameters.add(new DSpaceCommandLineParameter("-r", "test")); parameters.add(new DSpaceCommandLineParameter("-r", "test"));
parameters.add(new DSpaceCommandLineParameter("-i", null)); parameters.add(new DSpaceCommandLineParameter("-i", null));

View File

@@ -258,7 +258,7 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
+ " Як що вмiст вайлу не є текстовим, наприклад є фотографiєю, тодi вибрати (N/A)", + " Як що вмiст вайлу не є текстовим, наприклад є фотографiєю, тодi вибрати (N/A)",
"dc.language.iso")))); "dc.language.iso"))));
resetPropertyFile(); resetLocalesConfiguration();
} }
@Test @Test
@@ -331,7 +331,7 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
+ " Як що вмiст вайлу не є текстовим, наприклад є фотографiєю, тодi вибрати (N/A)", + " Як що вмiст вайлу не є текстовим, наприклад є фотографiєю, тодi вибрати (N/A)",
"dc.language.iso")))); "dc.language.iso"))));
resetPropertyFile(); resetLocalesConfiguration();
} }
@Test @Test
@@ -377,7 +377,7 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
+ " Se il contenuto non ha davvero una lingua" + " Se il contenuto non ha davvero una lingua"
+ " (ad esempio, se è un set di dati o un'immagine) selezionare (N/A)", "dc.language.iso")))); + " (ad esempio, se è un set di dati o un'immagine) selezionare (N/A)", "dc.language.iso"))));
resetPropertyFile(); resetLocalesConfiguration();
} }
@Test @Test
@@ -408,10 +408,11 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
"\u00C8 necessario inserire un titolo principale per questo item", false, "\u00C8 necessario inserire un titolo principale per questo item", false,
"Inserisci titolo principale di questo item", "dc.title")))); "Inserisci titolo principale di questo item", "dc.title"))));
resetPropertyFile(); resetLocalesConfiguration();
} }
private void resetPropertyFile() throws DCInputsReaderException { private void resetLocalesConfiguration() throws DCInputsReaderException {
configurationService.setProperty("default.locale","en");
configurationService.setProperty("webui.supported.locales",null); configurationService.setProperty("webui.supported.locales",null);
submissionFormRestRepository.reload(); submissionFormRestRepository.reload();
} }

View File

@@ -13,6 +13,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import java.util.HashMap; import java.util.HashMap;
@@ -41,6 +42,9 @@ import org.springframework.hateoas.EntityModel;
import org.springframework.hateoas.Link; import org.springframework.hateoas.Link;
import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
/** /**
* Tests functionality of {@link ConverterService}. * Tests functionality of {@link ConverterService}.
@@ -76,6 +80,11 @@ public class ConverterServiceIT extends AbstractControllerIntegrationTest {
mockHttpServletRequest.setAttribute("dspace.context", new Context()); mockHttpServletRequest.setAttribute("dspace.context", new Context());
MockHttpServletResponse mockHttpServletResponse = new MockHttpServletResponse(); MockHttpServletResponse mockHttpServletResponse = new MockHttpServletResponse();
requestService.startRequest(mockHttpServletRequest, mockHttpServletResponse); requestService.startRequest(mockHttpServletRequest, mockHttpServletResponse);
Authentication authentication = mock(Authentication.class);
SecurityContext securityContext = mock(SecurityContext.class);
when(securityContext.getAuthentication()).thenReturn(authentication);
SecurityContextHolder.setContext(securityContext);
when(SecurityContextHolder.getContext().getAuthentication().getPrincipal()).thenReturn(eperson);
} }
/** /**
* When calling {@code toRest} with an object for which an appropriate {@link DSpaceConverter} can't be found, * When calling {@code toRest} with an object for which an appropriate {@link DSpaceConverter} can't be found,
@@ -103,6 +112,10 @@ public class ConverterServiceIT extends AbstractControllerIntegrationTest {
/** /**
* When calling {@code toRest} with the default projection, the converter should run and no changes should be made. * When calling {@code toRest} with the default projection, the converter should run and no changes should be made.
* This converter.toRest will now also check permissions through the PreAuthorize annotation on the
* Repository's findOne method. Therefor a repository has been added for this MockObjectRest namely
* {@link org.dspace.app.rest.repository.MockObjectRestRepository} and added PreAuthorize annotations
* on the methods of this Repository
*/ */
@Test @Test
public void toRestWithDefaultProjection() { public void toRestWithDefaultProjection() {

View File

@@ -0,0 +1,41 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.app.rest.repository;
import org.dspace.app.rest.model.MockObjectRest;
import org.dspace.core.Context;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
/**
* This class has been added to allow the MockObjectRest to act as an actual BaseObjectRest since they're
* expected to have a RestRepository
*/
@Component(MockObjectRest.CATEGORY + "." + MockObjectRest.NAME)
public class MockObjectRestRepository extends DSpaceRestRepository<MockObjectRest, Long> {
// Added a permitAll preAuthorize annotation to allow the object to be used in tests by every user
@Override
@PreAuthorize("permitAll()")
public MockObjectRest findOne(Context context, Long aLong) {
return null;
}
@Override
@PreAuthorize("permitAll()")
public Page<MockObjectRest> findAll(Context context, Pageable pageable) {
return null;
}
@Override
public Class<MockObjectRest> getDomainClass() {
return MockObjectRest.class;
}
}