mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-07 10:04:21 +00:00
Merge pull request #1976 from atmire/DS-3542_Spring-permission-evaluator
DS-3542 Spring security authorizations 2
This commit is contained in:
@@ -164,7 +164,7 @@ public class EPersonDAOImpl extends AbstractHibernateDSODAO<EPerson> implements
|
|||||||
addMetadataValueWhereQuery(queryBuilder, queryFields, "like",
|
addMetadataValueWhereQuery(queryBuilder, queryFields, "like",
|
||||||
EPerson.class.getSimpleName().toLowerCase() + ".email like :queryParam");
|
EPerson.class.getSimpleName().toLowerCase() + ".email like :queryParam");
|
||||||
}
|
}
|
||||||
if (!CollectionUtils.isEmpty(sortFields)) {
|
if (!CollectionUtils.isEmpty(sortFields) || StringUtils.isNotBlank(sortField)) {
|
||||||
addMetadataSortQuery(queryBuilder, sortFields, Collections.singletonList(sortField));
|
addMetadataSortQuery(queryBuilder, sortFields, Collections.singletonList(sortField));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -212,6 +212,11 @@
|
|||||||
<artifactId>spring-boot-starter-data-rest</artifactId>
|
<artifactId>spring-boot-starter-data-rest</artifactId>
|
||||||
<version>${spring-boot.version}</version>
|
<version>${spring-boot.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-aop</artifactId>
|
||||||
|
<version>${spring-boot.version}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-test</artifactId>
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
@@ -22,16 +22,15 @@ import org.dspace.app.rest.model.BitstreamRest;
|
|||||||
import org.dspace.app.rest.utils.ContextUtil;
|
import org.dspace.app.rest.utils.ContextUtil;
|
||||||
import org.dspace.app.rest.utils.MultipartFileSender;
|
import org.dspace.app.rest.utils.MultipartFileSender;
|
||||||
import org.dspace.authorize.AuthorizeException;
|
import org.dspace.authorize.AuthorizeException;
|
||||||
import org.dspace.authorize.service.AuthorizeService;
|
|
||||||
import org.dspace.content.Bitstream;
|
import org.dspace.content.Bitstream;
|
||||||
import org.dspace.content.BitstreamFormat;
|
import org.dspace.content.BitstreamFormat;
|
||||||
import org.dspace.content.service.BitstreamService;
|
import org.dspace.content.service.BitstreamService;
|
||||||
import org.dspace.core.Constants;
|
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
import org.dspace.disseminate.service.CitationDocumentService;
|
import org.dspace.disseminate.service.CitationDocumentService;
|
||||||
import org.dspace.services.EventService;
|
import org.dspace.services.EventService;
|
||||||
import org.dspace.usage.UsageEvent;
|
import org.dspace.usage.UsageEvent;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMethod;
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
@@ -68,12 +67,10 @@ public class BitstreamContentRestController {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private EventService eventService;
|
private EventService eventService;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private AuthorizeService authorizeService;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private CitationDocumentService citationDocumentService;
|
private CitationDocumentService citationDocumentService;
|
||||||
|
|
||||||
|
@PreAuthorize("hasPermission(#uuid, 'BITSTREAM', 'READ')")
|
||||||
@RequestMapping(method = {RequestMethod.GET, RequestMethod.HEAD})
|
@RequestMapping(method = {RequestMethod.GET, RequestMethod.HEAD})
|
||||||
public void retrieve(@PathVariable UUID uuid, HttpServletResponse response,
|
public void retrieve(@PathVariable UUID uuid, HttpServletResponse response,
|
||||||
HttpServletRequest request) throws IOException, SQLException, AuthorizeException {
|
HttpServletRequest request) throws IOException, SQLException, AuthorizeException {
|
||||||
@@ -81,9 +78,9 @@ public class BitstreamContentRestController {
|
|||||||
|
|
||||||
Context context = ContextUtil.obtainContext(request);
|
Context context = ContextUtil.obtainContext(request);
|
||||||
|
|
||||||
Bitstream bit = getBitstream(context, uuid, response);
|
Bitstream bit = bitstreamService.find(context, uuid);
|
||||||
if (bit == null) {
|
if (bit == null) {
|
||||||
//The bitstream was not found or we're not authorized to read it.
|
response.sendError(HttpServletResponse.SC_NOT_FOUND);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,18 +166,6 @@ public class BitstreamContentRestController {
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Bitstream getBitstream(Context context, @PathVariable UUID uuid, HttpServletResponse response)
|
|
||||||
throws SQLException, IOException, AuthorizeException {
|
|
||||||
Bitstream bit = bitstreamService.find(context, uuid);
|
|
||||||
if (bit == null) {
|
|
||||||
response.sendError(HttpServletResponse.SC_NOT_FOUND);
|
|
||||||
} else {
|
|
||||||
authorizeService.authorizeAction(context, bit, Constants.READ);
|
|
||||||
}
|
|
||||||
|
|
||||||
return bit;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isNotAnErrorResponse(HttpServletResponse response) {
|
private boolean isNotAnErrorResponse(HttpServletResponse response) {
|
||||||
Response.Status.Family responseCode = Response.Status.Family.familyOf(response.getStatus());
|
Response.Status.Family responseCode = Response.Status.Family.familyOf(response.getStatus());
|
||||||
return responseCode.equals(Response.Status.Family.SUCCESSFUL)
|
return responseCode.equals(Response.Status.Family.SUCCESSFUL)
|
||||||
|
@@ -21,6 +21,7 @@ import org.dspace.app.rest.model.RestModel;
|
|||||||
import org.dspace.app.rest.model.hateoas.DSpaceResource;
|
import org.dspace.app.rest.model.hateoas.DSpaceResource;
|
||||||
import org.dspace.app.rest.utils.Utils;
|
import org.dspace.app.rest.utils.Utils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.core.annotation.AnnotationUtils;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.hateoas.Link;
|
import org.springframework.hateoas.Link;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@@ -45,7 +46,7 @@ public class DSpaceResourceHalLinkFactory extends HalLinkFactory<DSpaceResource,
|
|||||||
Method readMethod = pd.getReadMethod();
|
Method readMethod = pd.getReadMethod();
|
||||||
String name = pd.getName();
|
String name = pd.getName();
|
||||||
if (readMethod != null && !"class".equals(name)) {
|
if (readMethod != null && !"class".equals(name)) {
|
||||||
LinkRest linkAnnotation = readMethod.getAnnotation(LinkRest.class);
|
LinkRest linkAnnotation = AnnotationUtils.findAnnotation(readMethod, LinkRest.class);
|
||||||
|
|
||||||
if (linkAnnotation != null) {
|
if (linkAnnotation != null) {
|
||||||
if (StringUtils.isNotBlank(linkAnnotation.name())) {
|
if (StringUtils.isNotBlank(linkAnnotation.name())) {
|
||||||
@@ -57,10 +58,9 @@ public class DSpaceResourceHalLinkFactory extends HalLinkFactory<DSpaceResource,
|
|||||||
if (StringUtils.isBlank(linkAnnotation.method())) {
|
if (StringUtils.isBlank(linkAnnotation.method())) {
|
||||||
Object linkedObject = readMethod.invoke(data);
|
Object linkedObject = readMethod.invoke(data);
|
||||||
|
|
||||||
if (linkedObject instanceof RestAddressableModel && linkAnnotation.linkClass()
|
if (linkedObject instanceof RestAddressableModel
|
||||||
.isAssignableFrom(
|
&& linkAnnotation.linkClass().isAssignableFrom(linkedObject.getClass())) {
|
||||||
linkedObject
|
|
||||||
.getClass())) {
|
|
||||||
linkToSubResource = utils
|
linkToSubResource = utils
|
||||||
.linkToSingleResource((RestAddressableModel) linkedObject, name);
|
.linkToSingleResource((RestAddressableModel) linkedObject, name);
|
||||||
}
|
}
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
package org.dspace.app.rest.model.hateoas;
|
package org.dspace.app.rest.model.hateoas;
|
||||||
|
|
||||||
import org.dspace.app.rest.model.hateoas.annotations.RelNameDSpaceResource;
|
import org.dspace.app.rest.model.hateoas.annotations.RelNameDSpaceResource;
|
||||||
|
import org.springframework.core.annotation.AnnotationUtils;
|
||||||
import org.springframework.hateoas.core.EvoInflectorRelProvider;
|
import org.springframework.hateoas.core.EvoInflectorRelProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -20,7 +21,7 @@ public class DSpaceRelProvider extends EvoInflectorRelProvider {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getItemResourceRelFor(Class<?> type) {
|
public String getItemResourceRelFor(Class<?> type) {
|
||||||
RelNameDSpaceResource nameAnnotation = type.getAnnotation(RelNameDSpaceResource.class);
|
RelNameDSpaceResource nameAnnotation = AnnotationUtils.findAnnotation(type, RelNameDSpaceResource.class);
|
||||||
if (nameAnnotation != null) {
|
if (nameAnnotation != null) {
|
||||||
return nameAnnotation.value();
|
return nameAnnotation.value();
|
||||||
}
|
}
|
||||||
|
@@ -25,6 +25,7 @@ import org.dspace.app.rest.model.RestAddressableModel;
|
|||||||
import org.dspace.app.rest.repository.DSpaceRestRepository;
|
import org.dspace.app.rest.repository.DSpaceRestRepository;
|
||||||
import org.dspace.app.rest.repository.LinkRestRepository;
|
import org.dspace.app.rest.repository.LinkRestRepository;
|
||||||
import org.dspace.app.rest.utils.Utils;
|
import org.dspace.app.rest.utils.Utils;
|
||||||
|
import org.springframework.core.annotation.AnnotationUtils;
|
||||||
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.hateoas.Link;
|
import org.springframework.hateoas.Link;
|
||||||
@@ -91,7 +92,7 @@ public abstract class DSpaceResource<T extends RestAddressableModel> extends HAL
|
|||||||
Method readMethod = pd.getReadMethod();
|
Method readMethod = pd.getReadMethod();
|
||||||
String name = pd.getName();
|
String name = pd.getName();
|
||||||
if (readMethod != null && !"class".equals(name)) {
|
if (readMethod != null && !"class".equals(name)) {
|
||||||
LinkRest linkAnnotation = readMethod.getAnnotation(LinkRest.class);
|
LinkRest linkAnnotation = AnnotationUtils.findAnnotation(readMethod, LinkRest.class);
|
||||||
|
|
||||||
if (linkAnnotation != null) {
|
if (linkAnnotation != null) {
|
||||||
if (StringUtils.isNotBlank(linkAnnotation.name())) {
|
if (StringUtils.isNotBlank(linkAnnotation.name())) {
|
||||||
|
@@ -29,6 +29,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.PageImpl;
|
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.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -54,6 +55,7 @@ public class AuthorityEntryLinkRepository extends AbstractDSpaceRestRepository
|
|||||||
return new AuthorityEntryResource(model);
|
return new AuthorityEntryResource(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PreAuthorize("hasAuthority('AUTHENTICATED')")
|
||||||
public Page<AuthorityEntryRest> query(HttpServletRequest request, String name,
|
public Page<AuthorityEntryRest> query(HttpServletRequest request, String name,
|
||||||
Pageable pageable, String projection) {
|
Pageable pageable, String projection) {
|
||||||
Context context = obtainContext();
|
Context context = obtainContext();
|
||||||
|
@@ -20,6 +20,7 @@ import org.dspace.content.authority.service.ChoiceAuthorityService;
|
|||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -42,6 +43,7 @@ public class AuthorityEntryValueLinkRepository extends AbstractDSpaceRestReposit
|
|||||||
return new AuthorityEntryResource(model);
|
return new AuthorityEntryResource(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PreAuthorize("hasAuthority('AUTHENTICATED')")
|
||||||
public AuthorityEntryRest getResource(HttpServletRequest request, String name, String relId,
|
public AuthorityEntryRest getResource(HttpServletRequest request, String name, String relId,
|
||||||
Pageable pageable, String projection) {
|
Pageable pageable, String projection) {
|
||||||
Context context = obtainContext();
|
Context context = obtainContext();
|
||||||
|
@@ -21,6 +21,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.PageImpl;
|
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.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -37,6 +38,7 @@ public class AuthorityRestRepository extends DSpaceRestRepository<AuthorityRest,
|
|||||||
@Autowired
|
@Autowired
|
||||||
private AuthorityUtils authorityUtils;
|
private AuthorityUtils authorityUtils;
|
||||||
|
|
||||||
|
@PreAuthorize("hasAuthority('AUTHENTICATED')")
|
||||||
@Override
|
@Override
|
||||||
public AuthorityRest findOne(Context context, String name) {
|
public AuthorityRest findOne(Context context, String name) {
|
||||||
ChoiceAuthority source = cas.getChoiceAuthorityByAuthorityName(name);
|
ChoiceAuthority source = cas.getChoiceAuthorityByAuthorityName(name);
|
||||||
@@ -44,6 +46,7 @@ public class AuthorityRestRepository extends DSpaceRestRepository<AuthorityRest,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PreAuthorize("hasAuthority('AUTHENTICATED')")
|
||||||
@Override
|
@Override
|
||||||
public Page<AuthorityRest> findAll(Context context, Pageable pageable) {
|
public Page<AuthorityRest> findAll(Context context, Pageable pageable) {
|
||||||
Set<String> authoritiesName = cas.getChoiceAuthoritiesNames();
|
Set<String> authoritiesName = cas.getChoiceAuthoritiesNames();
|
||||||
|
@@ -28,6 +28,7 @@ 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.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;
|
||||||
|
|
||||||
|
|
||||||
@@ -51,6 +52,7 @@ public class BitstreamRestRepository extends DSpaceRestRepository<BitstreamRest,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@PreAuthorize("hasPermission(#id, 'BITSTREAM', 'READ')")
|
||||||
public BitstreamRest findOne(Context context, UUID id) {
|
public BitstreamRest findOne(Context context, UUID id) {
|
||||||
Bitstream bit = null;
|
Bitstream bit = null;
|
||||||
try {
|
try {
|
||||||
@@ -72,6 +74,7 @@ public class BitstreamRestRepository extends DSpaceRestRepository<BitstreamRest,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@PreAuthorize("hasAuthority('ADMIN')")
|
||||||
public Page<BitstreamRest> findAll(Context context, Pageable pageable) {
|
public Page<BitstreamRest> findAll(Context context, Pageable pageable) {
|
||||||
List<Bitstream> bit = new ArrayList<Bitstream>();
|
List<Bitstream> bit = new ArrayList<Bitstream>();
|
||||||
Iterator<Bitstream> it = null;
|
Iterator<Bitstream> it = null;
|
||||||
|
@@ -29,6 +29,7 @@ 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.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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -55,6 +56,7 @@ public class CollectionRestRepository extends DSpaceRestRepository<CollectionRes
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@PreAuthorize("hasPermission(#id, 'COLLECTION', 'READ')")
|
||||||
public CollectionRest findOne(Context context, UUID id) {
|
public CollectionRest findOne(Context context, UUID id) {
|
||||||
Collection collection = null;
|
Collection collection = null;
|
||||||
try {
|
try {
|
||||||
|
@@ -25,6 +25,7 @@ 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.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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -47,6 +48,7 @@ public class CommunityRestRepository extends DSpaceRestRepository<CommunityRest,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@PreAuthorize("hasPermission(#id, 'COMMUNITY', 'READ')")
|
||||||
public CommunityRest findOne(Context context, UUID id) {
|
public CommunityRest findOne(Context context, UUID id) {
|
||||||
Community community = null;
|
Community community = null;
|
||||||
try {
|
try {
|
||||||
|
@@ -23,6 +23,7 @@ import org.dspace.app.rest.model.step.UploadStatusResponse;
|
|||||||
import org.dspace.app.util.DCInputsReaderException;
|
import org.dspace.app.util.DCInputsReaderException;
|
||||||
import org.dspace.authorize.AuthorizeException;
|
import org.dspace.authorize.AuthorizeException;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
|
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.domain.Sort;
|
import org.springframework.data.domain.Sort;
|
||||||
@@ -43,6 +44,13 @@ public abstract class DSpaceRestRepository<T extends RestAddressableModel, ID ex
|
|||||||
|
|
||||||
private static final Logger log = Logger.getLogger(DSpaceRestRepository.class);
|
private static final Logger log = Logger.getLogger(DSpaceRestRepository.class);
|
||||||
|
|
||||||
|
//Trick to make inner-calls to ourselves that are checked by Spring security
|
||||||
|
//See:
|
||||||
|
// https://stackoverflow.com/questions/13564627/spring-aop-not-working-for-method-call-inside-another-method
|
||||||
|
// https://docs.spring.io/spring/docs/4.3.18.RELEASE/spring-framework-reference/htmlsingle/#aop-understanding-aop-proxies
|
||||||
|
@Autowired
|
||||||
|
private DSpaceRestRepository<T, ID> thisRepository;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <S extends T> S save(S entity) {
|
public <S extends T> S save(S entity) {
|
||||||
Context context = null;
|
Context context = null;
|
||||||
@@ -72,7 +80,7 @@ public abstract class DSpaceRestRepository<T extends RestAddressableModel, ID ex
|
|||||||
@Override
|
@Override
|
||||||
public T findOne(ID id) {
|
public T findOne(ID id) {
|
||||||
Context context = obtainContext();
|
Context context = obtainContext();
|
||||||
return findOne(context, id);
|
return thisRepository.findOne(context, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract T findOne(Context context, ID id);
|
public abstract T findOne(Context context, ID id);
|
||||||
@@ -103,7 +111,7 @@ public abstract class DSpaceRestRepository<T extends RestAddressableModel, ID ex
|
|||||||
public void delete(ID id) {
|
public void delete(ID id) {
|
||||||
Context context = obtainContext();
|
Context context = obtainContext();
|
||||||
try {
|
try {
|
||||||
delete(context, id);
|
thisRepository.delete(context, id);
|
||||||
context.commit();
|
context.commit();
|
||||||
} catch (AuthorizeException e) {
|
} catch (AuthorizeException e) {
|
||||||
throw new RESTAuthorizationException(e);
|
throw new RESTAuthorizationException(e);
|
||||||
@@ -141,7 +149,7 @@ public abstract class DSpaceRestRepository<T extends RestAddressableModel, ID ex
|
|||||||
@Override
|
@Override
|
||||||
public Page<T> findAll(Pageable pageable) {
|
public Page<T> findAll(Pageable pageable) {
|
||||||
Context context = obtainContext();
|
Context context = obtainContext();
|
||||||
return findAll(context, pageable);
|
return thisRepository.findAll(context, pageable);
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract Page<T> findAll(Context context, Pageable pageable);
|
public abstract Page<T> findAll(Context context, Pageable pageable);
|
||||||
@@ -154,7 +162,7 @@ public abstract class DSpaceRestRepository<T extends RestAddressableModel, ID ex
|
|||||||
Context context = null;
|
Context context = null;
|
||||||
try {
|
try {
|
||||||
context = obtainContext();
|
context = obtainContext();
|
||||||
T entity = createAndReturn(context);
|
T entity = thisRepository.createAndReturn(context);
|
||||||
context.commit();
|
context.commit();
|
||||||
return entity;
|
return entity;
|
||||||
} catch (AuthorizeException e) {
|
} catch (AuthorizeException e) {
|
||||||
@@ -177,7 +185,7 @@ public abstract class DSpaceRestRepository<T extends RestAddressableModel, ID ex
|
|||||||
throws HttpRequestMethodNotSupportedException, UnprocessableEntityException, PatchBadRequestException {
|
throws HttpRequestMethodNotSupportedException, UnprocessableEntityException, PatchBadRequestException {
|
||||||
Context context = obtainContext();
|
Context context = obtainContext();
|
||||||
try {
|
try {
|
||||||
patch(context, request, apiCategory, model, id, patch);
|
thisRepository.patch(context, request, apiCategory, model, id, patch);
|
||||||
context.commit();
|
context.commit();
|
||||||
} catch (AuthorizeException ae) {
|
} catch (AuthorizeException ae) {
|
||||||
throw new RESTAuthorizationException(ae);
|
throw new RESTAuthorizationException(ae);
|
||||||
|
@@ -34,6 +34,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.PageImpl;
|
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.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
|
||||||
@@ -94,6 +95,7 @@ public class EPersonRestRepository extends DSpaceRestRepository<EPersonRest, UUI
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@PreAuthorize("hasPermission(#id, 'EPERSON', 'READ')")
|
||||||
public EPersonRest findOne(Context context, UUID id) {
|
public EPersonRest findOne(Context context, UUID id) {
|
||||||
EPerson eperson = null;
|
EPerson eperson = null;
|
||||||
try {
|
try {
|
||||||
@@ -108,6 +110,7 @@ public class EPersonRestRepository extends DSpaceRestRepository<EPersonRest, UUI
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@PreAuthorize("hasAuthority('ADMIN')")
|
||||||
public Page<EPersonRest> findAll(Context context, Pageable pageable) {
|
public Page<EPersonRest> findAll(Context context, Pageable pageable) {
|
||||||
List<EPerson> epersons = null;
|
List<EPerson> epersons = null;
|
||||||
int total = 0;
|
int total = 0;
|
||||||
@@ -117,7 +120,7 @@ public class EPersonRestRepository extends DSpaceRestRepository<EPersonRest, UUI
|
|||||||
"The EPerson collection endpoint is reserved to system administrators");
|
"The EPerson collection endpoint is reserved to system administrators");
|
||||||
}
|
}
|
||||||
total = es.countTotal(context);
|
total = es.countTotal(context);
|
||||||
epersons = es.findAll(context, EPerson.ID, pageable.getPageSize(), pageable.getOffset());
|
epersons = es.findAll(context, EPerson.EMAIL, pageable.getPageSize(), pageable.getOffset());
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw new RuntimeException(e.getMessage(), e);
|
throw new RuntimeException(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
@@ -22,6 +22,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.PageImpl;
|
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.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -38,6 +39,7 @@ public class GroupRestRepository extends DSpaceRestRepository<GroupRest, UUID> {
|
|||||||
GroupConverter converter;
|
GroupConverter converter;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@PreAuthorize("hasPermission(#id, 'GROUP', 'READ')")
|
||||||
public GroupRest findOne(Context context, UUID id) {
|
public GroupRest findOne(Context context, UUID id) {
|
||||||
Group group = null;
|
Group group = null;
|
||||||
try {
|
try {
|
||||||
@@ -51,6 +53,7 @@ public class GroupRestRepository extends DSpaceRestRepository<GroupRest, UUID> {
|
|||||||
return converter.fromModel(group);
|
return converter.fromModel(group);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PreAuthorize("hasAuthority('ADMIN')")
|
||||||
@Override
|
@Override
|
||||||
public Page<GroupRest> findAll(Context context, Pageable pageable) {
|
public Page<GroupRest> findAll(Context context, Pageable pageable) {
|
||||||
List<Group> groups = null;
|
List<Group> groups = null;
|
||||||
|
@@ -32,6 +32,7 @@ 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.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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -63,6 +64,7 @@ public class ItemRestRepository extends DSpaceRestRepository<ItemRest, UUID> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@PreAuthorize("hasPermission(#id, 'ITEM', 'READ')")
|
||||||
public ItemRest findOne(Context context, UUID id) {
|
public ItemRest findOne(Context context, UUID id) {
|
||||||
Item item = null;
|
Item item = null;
|
||||||
try {
|
try {
|
||||||
@@ -77,6 +79,7 @@ public class ItemRestRepository extends DSpaceRestRepository<ItemRest, UUID> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@PreAuthorize("hasAuthority('ADMIN')")
|
||||||
public Page<ItemRest> findAll(Context context, Pageable pageable) {
|
public Page<ItemRest> findAll(Context context, Pageable pageable) {
|
||||||
Iterator<Item> it = null;
|
Iterator<Item> it = null;
|
||||||
List<Item> items = new ArrayList<Item>();
|
List<Item> items = new ArrayList<Item>();
|
||||||
|
@@ -21,6 +21,7 @@ import org.dspace.core.Context;
|
|||||||
import org.dspace.core.service.LicenseService;
|
import org.dspace.core.service.LicenseService;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -43,6 +44,7 @@ public class LicenseRestLinkRepository extends AbstractDSpaceRestRepository
|
|||||||
return new LicenseResource(model);
|
return new LicenseResource(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PreAuthorize("hasAuthority('AUTHENTICATED')")
|
||||||
public LicenseRest getLicenseCollection(HttpServletRequest request, UUID uuid, Pageable pageable, String projection)
|
public LicenseRest getLicenseCollection(HttpServletRequest request, UUID uuid, Pageable pageable, String projection)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
Context context = obtainContext();
|
Context context = obtainContext();
|
||||||
|
@@ -20,6 +20,7 @@ import org.dspace.core.Context;
|
|||||||
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.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -39,6 +40,7 @@ public class ResourcePolicyRestRepository extends DSpaceRestRepository<ResourceP
|
|||||||
@Autowired
|
@Autowired
|
||||||
Utils utils;
|
Utils utils;
|
||||||
|
|
||||||
|
@PreAuthorize("hasAuthority('AUTHENTICATED')")
|
||||||
@Override
|
@Override
|
||||||
public ResourcePolicyRest findOne(Context context, Integer id) {
|
public ResourcePolicyRest findOne(Context context, Integer id) {
|
||||||
ResourcePolicy source = null;
|
ResourcePolicy source = null;
|
||||||
@@ -53,6 +55,7 @@ public class ResourcePolicyRestRepository extends DSpaceRestRepository<ResourceP
|
|||||||
return resourcePolicyConverter.convert(source);
|
return resourcePolicyConverter.convert(source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PreAuthorize("hasAuthority('AUTHENTICATED')")
|
||||||
@Override
|
@Override
|
||||||
public Page<ResourcePolicyRest> findAll(Context context, Pageable pageable) {
|
public Page<ResourcePolicyRest> findAll(Context context, Pageable pageable) {
|
||||||
throw new RepositoryMethodNotImplementedException(ResourcePolicyRest.NAME, "findAll");
|
throw new RepositoryMethodNotImplementedException(ResourcePolicyRest.NAME, "findAll");
|
||||||
|
@@ -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.PageImpl;
|
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.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -48,6 +49,7 @@ public class SubmissionDefinitionRestRepository extends DSpaceRestRepository<Sub
|
|||||||
submissionConfigReader = new SubmissionConfigReader();
|
submissionConfigReader = new SubmissionConfigReader();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PreAuthorize("hasAuthority('AUTHENTICATED')")
|
||||||
@Override
|
@Override
|
||||||
public SubmissionDefinitionRest findOne(Context context, String submitName) {
|
public SubmissionDefinitionRest findOne(Context context, String submitName) {
|
||||||
SubmissionConfig subConfig = submissionConfigReader.getSubmissionConfigByName(submitName);
|
SubmissionConfig subConfig = submissionConfigReader.getSubmissionConfigByName(submitName);
|
||||||
@@ -57,6 +59,7 @@ public class SubmissionDefinitionRestRepository extends DSpaceRestRepository<Sub
|
|||||||
return converter.convert(subConfig);
|
return converter.convert(subConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PreAuthorize("hasAuthority('AUTHENTICATED')")
|
||||||
@Override
|
@Override
|
||||||
public Page<SubmissionDefinitionRest> findAll(Context context, Pageable pageable) {
|
public Page<SubmissionDefinitionRest> findAll(Context context, Pageable pageable) {
|
||||||
List<SubmissionConfig> subConfs = new ArrayList<SubmissionConfig>();
|
List<SubmissionConfig> subConfs = new ArrayList<SubmissionConfig>();
|
||||||
@@ -66,6 +69,7 @@ public class SubmissionDefinitionRestRepository extends DSpaceRestRepository<Sub
|
|||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PreAuthorize("hasAuthority('AUTHENTICATED')")
|
||||||
@SearchRestMethod(name = "findByCollection")
|
@SearchRestMethod(name = "findByCollection")
|
||||||
public SubmissionDefinitionRest findByCollection(@Parameter(value = "uuid", required = true) UUID collectionUuid)
|
public SubmissionDefinitionRest findByCollection(@Parameter(value = "uuid", required = true) UUID collectionUuid)
|
||||||
throws SQLException {
|
throws SQLException {
|
||||||
|
@@ -21,6 +21,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.PageImpl;
|
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.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -41,6 +42,7 @@ public class SubmissionFormRestRepository extends DSpaceRestRepository<Submissio
|
|||||||
inputReader = new DCInputsReader();
|
inputReader = new DCInputsReader();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PreAuthorize("hasAuthority('AUTHENTICATED')")
|
||||||
@Override
|
@Override
|
||||||
public SubmissionFormRest findOne(Context context, String submitName) {
|
public SubmissionFormRest findOne(Context context, String submitName) {
|
||||||
DCInputSet inputConfig;
|
DCInputSet inputConfig;
|
||||||
@@ -55,6 +57,7 @@ public class SubmissionFormRestRepository extends DSpaceRestRepository<Submissio
|
|||||||
return converter.convert(inputConfig);
|
return converter.convert(inputConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PreAuthorize("hasAuthority('AUTHENTICATED')")
|
||||||
@Override
|
@Override
|
||||||
public Page<SubmissionFormRest> findAll(Context context, Pageable pageable) {
|
public Page<SubmissionFormRest> findAll(Context context, Pageable pageable) {
|
||||||
List<DCInputSet> subConfs = new ArrayList<DCInputSet>();
|
List<DCInputSet> subConfs = new ArrayList<DCInputSet>();
|
||||||
|
@@ -23,6 +23,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.PageImpl;
|
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.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -42,6 +43,7 @@ public class SubmissionPanelRestRepository extends DSpaceRestRepository<Submissi
|
|||||||
submissionConfigReader = new SubmissionConfigReader();
|
submissionConfigReader = new SubmissionConfigReader();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PreAuthorize("hasAuthority('AUTHENTICATED')")
|
||||||
@Override
|
@Override
|
||||||
public SubmissionSectionRest findOne(Context context, String id) {
|
public SubmissionSectionRest findOne(Context context, String id) {
|
||||||
try {
|
try {
|
||||||
@@ -53,6 +55,7 @@ public class SubmissionPanelRestRepository extends DSpaceRestRepository<Submissi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PreAuthorize("hasAuthority('AUTHENTICATED')")
|
||||||
@Override
|
@Override
|
||||||
public Page<SubmissionSectionRest> findAll(Context context, Pageable pageable) {
|
public Page<SubmissionSectionRest> findAll(Context context, Pageable pageable) {
|
||||||
List<SubmissionConfig> subConfs = new ArrayList<SubmissionConfig>();
|
List<SubmissionConfig> subConfs = new ArrayList<SubmissionConfig>();
|
||||||
|
@@ -30,6 +30,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.PageImpl;
|
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.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -61,6 +62,7 @@ public class SubmissionUploadRestRepository extends DSpaceRestRepository<Submiss
|
|||||||
submissionConfigReader = new SubmissionConfigReader();
|
submissionConfigReader = new SubmissionConfigReader();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PreAuthorize("hasAuthority('AUTHENTICATED')")
|
||||||
@Override
|
@Override
|
||||||
public SubmissionUploadRest findOne(Context context, String submitName) {
|
public SubmissionUploadRest findOne(Context context, String submitName) {
|
||||||
UploadConfiguration config = uploadConfigurationService.getMap().get(submitName);
|
UploadConfiguration config = uploadConfigurationService.getMap().get(submitName);
|
||||||
@@ -72,6 +74,7 @@ public class SubmissionUploadRestRepository extends DSpaceRestRepository<Submiss
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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>();
|
List<SubmissionConfig> subConfs = new ArrayList<SubmissionConfig>();
|
||||||
|
@@ -93,6 +93,7 @@ public class WorkspaceItemRestRepository extends DSpaceRestRepository<WorkspaceI
|
|||||||
submissionConfigReader = new SubmissionConfigReader();
|
submissionConfigReader = new SubmissionConfigReader();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO @PreAuthorize("hasPermission(#id, 'WORKSPACEITEM', 'READ')")
|
||||||
@Override
|
@Override
|
||||||
public WorkspaceItemRest findOne(Context context, Integer id) {
|
public WorkspaceItemRest findOne(Context context, Integer id) {
|
||||||
WorkspaceItem witem = null;
|
WorkspaceItem witem = null;
|
||||||
@@ -107,6 +108,7 @@ public class WorkspaceItemRestRepository extends DSpaceRestRepository<WorkspaceI
|
|||||||
return converter.fromModel(witem);
|
return converter.fromModel(witem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO @PreAuthorize("hasAuthority('ADMIN')")
|
||||||
@Override
|
@Override
|
||||||
public Page<WorkspaceItemRest> findAll(Context context, Pageable pageable) {
|
public Page<WorkspaceItemRest> findAll(Context context, Pageable pageable) {
|
||||||
List<WorkspaceItem> witems = null;
|
List<WorkspaceItem> witems = null;
|
||||||
@@ -121,6 +123,7 @@ public class WorkspaceItemRestRepository extends DSpaceRestRepository<WorkspaceI
|
|||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO @PreAuthorize("hasPermission(#submitterID, 'EPERSON', 'READ')")
|
||||||
@SearchRestMethod(name = "findBySubmitter")
|
@SearchRestMethod(name = "findBySubmitter")
|
||||||
public Page<WorkspaceItemRest> findBySubmitter(@Parameter(value = "uuid", required = true) UUID submitterID,
|
public Page<WorkspaceItemRest> findBySubmitter(@Parameter(value = "uuid", required = true) UUID submitterID,
|
||||||
Pageable pageable) {
|
Pageable pageable) {
|
||||||
@@ -194,6 +197,7 @@ public class WorkspaceItemRestRepository extends DSpaceRestRepository<WorkspaceI
|
|||||||
return new WorkspaceItemResource(witem, utils, rels);
|
return new WorkspaceItemResource(witem, utils, rels);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO @PreAuthorize("hasPermission(#id, 'WORKSPACEITEM', 'WRITE')")
|
||||||
@Override
|
@Override
|
||||||
public UploadBitstreamRest upload(HttpServletRequest request, String apiCategory, String model, Integer id,
|
public UploadBitstreamRest upload(HttpServletRequest request, String apiCategory, String model, Integer id,
|
||||||
String extraField, MultipartFile file) throws Exception {
|
String extraField, MultipartFile file) throws Exception {
|
||||||
@@ -243,6 +247,7 @@ public class WorkspaceItemRestRepository extends DSpaceRestRepository<WorkspaceI
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO @PreAuthorize("hasPermission(#id, 'WORKSPACEITEM', 'WRITE')")
|
||||||
@Override
|
@Override
|
||||||
public void patch(Context context, HttpServletRequest request, String apiCategory, String model, Integer id,
|
public void patch(Context context, HttpServletRequest request, String apiCategory, String model, Integer id,
|
||||||
Patch patch) throws SQLException, AuthorizeException {
|
Patch patch) throws SQLException, AuthorizeException {
|
||||||
@@ -304,6 +309,7 @@ public class WorkspaceItemRestRepository extends DSpaceRestRepository<WorkspaceI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO @PreAuthorize("hasPermission(#id, 'WORKSPACEITEM', 'DELETE')")
|
||||||
@Override
|
@Override
|
||||||
protected void delete(Context context, Integer id) throws AuthorizeException {
|
protected void delete(Context context, Integer id) throws AuthorizeException {
|
||||||
WorkspaceItem witem = null;
|
WorkspaceItem witem = null;
|
||||||
|
@@ -0,0 +1,74 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.app.rest.security;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import org.dspace.app.rest.utils.ContextUtil;
|
||||||
|
import org.dspace.authorize.service.AuthorizeService;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.eperson.EPerson;
|
||||||
|
import org.dspace.eperson.service.EPersonService;
|
||||||
|
import org.dspace.services.RequestService;
|
||||||
|
import org.dspace.services.model.Request;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Administrators are always allowed to perform any action on any DSpace object. This plugin will check if
|
||||||
|
* the authenticated EPerson is an administrator of the provided target DSpace Object. If that is the case,
|
||||||
|
* the authenticated EPerson is allowed to perform the requested action.
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class AdminRestPermissionEvaluatorPlugin extends DSpaceObjectPermissionEvaluatorPlugin {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(DSpaceObjectPermissionEvaluatorPlugin.class);
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AuthorizeService authorizeService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RequestService requestService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private EPersonService ePersonService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType,
|
||||||
|
Object permission) {
|
||||||
|
|
||||||
|
//We do not check the "permission" object here because administrators are allowed to do everything
|
||||||
|
|
||||||
|
Request request = requestService.getCurrentRequest();
|
||||||
|
Context context = ContextUtil.obtainContext(request.getServletRequest());
|
||||||
|
EPerson ePerson = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
ePerson = ePersonService.findByEmail(context, (String) authentication.getPrincipal());
|
||||||
|
|
||||||
|
if (ePerson != null) {
|
||||||
|
|
||||||
|
//Check if user is a repository admin
|
||||||
|
if (authorizeService.isAdmin(context, ePerson)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//We don't check the DSO Admin level here as this is action specific.
|
||||||
|
//For example see org.dspace.authorize.AuthorizeConfiguration.canCollectionAdminPerformItemDeletion
|
||||||
|
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,91 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.app.rest.security;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.dspace.app.rest.utils.ContextUtil;
|
||||||
|
import org.dspace.authorize.service.AuthorizeService;
|
||||||
|
import org.dspace.content.DSpaceObject;
|
||||||
|
import org.dspace.content.factory.ContentServiceFactory;
|
||||||
|
import org.dspace.content.service.DSpaceObjectService;
|
||||||
|
import org.dspace.core.Constants;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.eperson.EPerson;
|
||||||
|
import org.dspace.eperson.service.EPersonService;
|
||||||
|
import org.dspace.services.RequestService;
|
||||||
|
import org.dspace.services.model.Request;
|
||||||
|
import org.dspace.util.UUIDUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DSpaceObjectPermissionEvaluatorPlugin will check persmissions based on the DSpace {@link AuthorizeService}.
|
||||||
|
* This service will validate if the authenticated user is allowed to perform an action on the given DSpace Object
|
||||||
|
* based on the resource policies attached to that DSpace object.
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class AuthorizeServicePermissionEvaluatorPlugin extends DSpaceObjectPermissionEvaluatorPlugin {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(AuthorizeServicePermissionEvaluatorPlugin.class);
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AuthorizeService authorizeService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RequestService requestService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private EPersonService ePersonService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ContentServiceFactory contentServiceFactory;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType,
|
||||||
|
Object permission) {
|
||||||
|
|
||||||
|
DSpaceRestPermission restPermission = DSpaceRestPermission.convert(permission);
|
||||||
|
if (restPermission == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Request request = requestService.getCurrentRequest();
|
||||||
|
Context context = ContextUtil.obtainContext(request.getServletRequest());
|
||||||
|
EPerson ePerson = null;
|
||||||
|
try {
|
||||||
|
ePerson = ePersonService.findByEmail(context, (String) authentication.getPrincipal());
|
||||||
|
|
||||||
|
UUID dsoId = UUIDUtils.fromString(targetId.toString());
|
||||||
|
DSpaceObjectService dSpaceObjectService =
|
||||||
|
contentServiceFactory.getDSpaceObjectService(Constants.getTypeID(targetType));
|
||||||
|
|
||||||
|
if (dSpaceObjectService != null && dsoId != null) {
|
||||||
|
DSpaceObject dSpaceObject = dSpaceObjectService.find(context, dsoId);
|
||||||
|
|
||||||
|
//If the dso is null then we give permission so we can throw another status code instead
|
||||||
|
if (dSpaceObject == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return authorizeService.authorizeActionBoolean(context, ePerson, dSpaceObject,
|
||||||
|
restPermission.getDspaceApiActionId(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@@ -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.security;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.springframework.security.core.AuthenticationException;
|
||||||
|
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spring security authentication entry point to return a 401 response for unauthorized requests
|
||||||
|
* This class is used in the {@link WebSecurityConfiguration} class.
|
||||||
|
*/
|
||||||
|
public class DSpace401AuthenticationEntryPoint implements AuthenticationEntryPoint {
|
||||||
|
|
||||||
|
private RestAuthenticationService restAuthenticationService;
|
||||||
|
|
||||||
|
public DSpace401AuthenticationEntryPoint(RestAuthenticationService restAuthenticationService) {
|
||||||
|
this.restAuthenticationService = restAuthenticationService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void commence(HttpServletRequest request,
|
||||||
|
HttpServletResponse response,
|
||||||
|
AuthenticationException authException) throws IOException, ServletException {
|
||||||
|
|
||||||
|
response.setHeader("WWW-Authenticate",
|
||||||
|
restAuthenticationService.getWwwAuthenticateHeaderValue(request, response));
|
||||||
|
|
||||||
|
response.sendError(HttpServletResponse.SC_UNAUTHORIZED,
|
||||||
|
authException.getMessage());
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,38 @@
|
|||||||
|
/**
|
||||||
|
* 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 org.dspace.app.rest.model.DSpaceObjectRest;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract {@link RestPermissionEvaluatorPlugin} class that contains utility methods to
|
||||||
|
* evaluate permissions for a DSpace Object.
|
||||||
|
*/
|
||||||
|
public abstract class DSpaceObjectPermissionEvaluatorPlugin implements RestPermissionEvaluatorPlugin {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility implementation to make the implementation of DSpace Object Permission evaluator plugins more easy.
|
||||||
|
*
|
||||||
|
* @param authentication represents the user in question. Should not be null.
|
||||||
|
* @param targetDomainObject the DSpace object for which permissions should be
|
||||||
|
* checked. May be null in which case implementations should return false, as the null
|
||||||
|
* condition can be checked explicitly in the expression.
|
||||||
|
* @param permission a representation of the DSpace action as supplied by the
|
||||||
|
* expression system. This corresponds to the DSpace action. Not null.
|
||||||
|
* @return true if the permission is granted by one of the plugins, false otherwise
|
||||||
|
*/
|
||||||
|
public boolean hasPermission(Authentication authentication, Object targetDomainObject,
|
||||||
|
Object permission) {
|
||||||
|
|
||||||
|
DSpaceObjectRest dSpaceObject = (DSpaceObjectRest) targetDomainObject;
|
||||||
|
return hasPermission(authentication, dSpaceObject.getId(), dSpaceObject.getType(), permission);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,71 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.app.rest.security;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.security.access.PermissionEvaluator;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DSpace permission evaluator.
|
||||||
|
* To check if a user has permission to a target object, a list of permissionEvaluatorPlugins will be checked.
|
||||||
|
*
|
||||||
|
* The following list of plugins exists: EPersonRestPermissionEvaluatorPlugin, AdminRestPermissionEvaluatorPlugin,
|
||||||
|
* AuthorizeServicePermissionEvaluatorPlugin, GroupRestPermissionEvaluatorPlugin
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class DSpacePermissionEvaluator implements PermissionEvaluator {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private List<RestPermissionEvaluatorPlugin> permissionEvaluatorPluginList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param authentication represents the user in question. Should not be null.
|
||||||
|
* @param targetDomainObject the DSpace object for which permissions should be
|
||||||
|
* checked. May be null in which case implementations should return false, as the null
|
||||||
|
* condition can be checked explicitly in the expression.
|
||||||
|
* @param permission a representation of the DSpace action as supplied by the
|
||||||
|
* expression system. This corresponds to the DSpace action. Not null.
|
||||||
|
* @return true if the permission is granted by one of the plugins, false otherwise
|
||||||
|
*/
|
||||||
|
public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {
|
||||||
|
for (RestPermissionEvaluatorPlugin permissionEvaluatorPlugin : permissionEvaluatorPluginList) {
|
||||||
|
if (permissionEvaluatorPlugin.hasPermission(authentication, targetDomainObject, permission)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Alternative method for evaluating a permission where only the identifier of the
|
||||||
|
* target object is available, rather than the target instance itself.
|
||||||
|
*
|
||||||
|
* @param authentication represents the user in question. Should not be null.
|
||||||
|
* @param targetId the UUID for the DSpace object
|
||||||
|
* @param targetType represents the DSpace object type of the target object. Not null.
|
||||||
|
* @param permission a representation of the permission object as supplied by the
|
||||||
|
* expression system. This corresponds to the DSpace action. Not null.
|
||||||
|
* @return true if the permission is granted by one of the plugins, false otherwise
|
||||||
|
*/
|
||||||
|
public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType,
|
||||||
|
Object permission) {
|
||||||
|
for (RestPermissionEvaluatorPlugin permissionEvaluatorPlugin : permissionEvaluatorPluginList) {
|
||||||
|
if (permissionEvaluatorPlugin.hasPermission(authentication, targetId, targetType, permission)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,52 @@
|
|||||||
|
/**
|
||||||
|
* 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 org.dspace.core.Constants;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enum that lists all available "permissions" an authenticated user can have on a specific REST endpoint.
|
||||||
|
*/
|
||||||
|
public enum DSpaceRestPermission {
|
||||||
|
|
||||||
|
READ(Constants.READ),
|
||||||
|
WRITE(Constants.WRITE),
|
||||||
|
DELETE(Constants.DELETE);
|
||||||
|
|
||||||
|
private int dspaceApiActionId;
|
||||||
|
|
||||||
|
DSpaceRestPermission(int dspaceApiActionId) {
|
||||||
|
this.dspaceApiActionId = dspaceApiActionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDspaceApiActionId() {
|
||||||
|
return dspaceApiActionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a given object to a {@link DSpaceRestPermission} if possible.
|
||||||
|
* @param object The object to convert
|
||||||
|
* @return A DSpaceRestPersmission value if the conversion succeeded, null otherwise
|
||||||
|
*/
|
||||||
|
public static DSpaceRestPermission convert(Object object) {
|
||||||
|
if (object == null) {
|
||||||
|
return null;
|
||||||
|
} else if (object instanceof DSpaceRestPermission) {
|
||||||
|
return (DSpaceRestPermission) object;
|
||||||
|
} else if (object instanceof String) {
|
||||||
|
try {
|
||||||
|
return DSpaceRestPermission.valueOf((String) object);
|
||||||
|
} catch (IllegalArgumentException ex) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -8,7 +8,7 @@
|
|||||||
package org.dspace.app.rest.security;
|
package org.dspace.app.rest.security;
|
||||||
|
|
||||||
import static org.dspace.app.rest.security.WebSecurityConfiguration.ADMIN_GRANT;
|
import static org.dspace.app.rest.security.WebSecurityConfiguration.ADMIN_GRANT;
|
||||||
import static org.dspace.app.rest.security.WebSecurityConfiguration.EPERSON_GRANT;
|
import static org.dspace.app.rest.security.WebSecurityConfiguration.AUTHENTICATED_GRANT;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
@@ -150,7 +150,7 @@ public class EPersonRestAuthenticationProvider implements AuthenticationProvider
|
|||||||
authorities.add(new SimpleGrantedAuthority(ADMIN_GRANT));
|
authorities.add(new SimpleGrantedAuthority(ADMIN_GRANT));
|
||||||
}
|
}
|
||||||
|
|
||||||
authorities.add(new SimpleGrantedAuthority(EPERSON_GRANT));
|
authorities.add(new SimpleGrantedAuthority(AUTHENTICATED_GRANT));
|
||||||
}
|
}
|
||||||
|
|
||||||
return authorities;
|
return authorities;
|
||||||
|
@@ -0,0 +1,73 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.app.rest.security;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.dspace.app.rest.utils.ContextUtil;
|
||||||
|
import org.dspace.core.Constants;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.eperson.EPerson;
|
||||||
|
import org.dspace.eperson.service.EPersonService;
|
||||||
|
import org.dspace.services.RequestService;
|
||||||
|
import org.dspace.services.model.Request;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An authenicated user is allowed to view, update or delete his or her own data. This {@link RestPermissionEvaluatorPlugin}
|
||||||
|
* implemenents that requirement.
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class EPersonRestPermissionEvaluatorPlugin extends DSpaceObjectPermissionEvaluatorPlugin {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(EPersonRestPermissionEvaluatorPlugin.class);
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RequestService requestService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private EPersonService ePersonService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasPermission(Authentication authentication, Serializable targetId,
|
||||||
|
String targetType, Object permission) {
|
||||||
|
//For now this plugin only evaluates READ access
|
||||||
|
DSpaceRestPermission restPermission = DSpaceRestPermission.convert(permission);
|
||||||
|
if (!DSpaceRestPermission.READ.equals(restPermission)
|
||||||
|
&& !DSpaceRestPermission.WRITE.equals(restPermission)
|
||||||
|
&& !DSpaceRestPermission.DELETE.equals(restPermission)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (Constants.getTypeID(targetType) != Constants.EPERSON) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Request request = requestService.getCurrentRequest();
|
||||||
|
Context context = ContextUtil.obtainContext(request.getServletRequest());
|
||||||
|
EPerson ePerson = null;
|
||||||
|
try {
|
||||||
|
ePerson = ePersonService.findByEmail(context, (String) authentication.getPrincipal());
|
||||||
|
UUID dsoId = UUID.fromString(targetId.toString());
|
||||||
|
|
||||||
|
if (dsoId.equals(ePerson.getID())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,76 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.app.rest.security;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.dspace.app.rest.utils.ContextUtil;
|
||||||
|
import org.dspace.core.Constants;
|
||||||
|
import org.dspace.core.Context;
|
||||||
|
import org.dspace.eperson.EPerson;
|
||||||
|
import org.dspace.eperson.Group;
|
||||||
|
import org.dspace.eperson.service.EPersonService;
|
||||||
|
import org.dspace.eperson.service.GroupService;
|
||||||
|
import org.dspace.services.RequestService;
|
||||||
|
import org.dspace.services.model.Request;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An authenticated user is allowed to view information on all the groups he or she is a member of (READ permission).
|
||||||
|
* This {@link RestPermissionEvaluatorPlugin} implements that requirement by validating the group membership.
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class GroupRestPermissionEvaluatorPlugin extends DSpaceObjectPermissionEvaluatorPlugin {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(GroupRestPermissionEvaluatorPlugin.class);
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RequestService requestService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private GroupService groupService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private EPersonService ePersonService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasPermission(Authentication authentication, Serializable targetId,
|
||||||
|
String targetType, Object permission) {
|
||||||
|
|
||||||
|
//This plugin only evaluates READ access
|
||||||
|
DSpaceRestPermission restPermission = DSpaceRestPermission.convert(permission);
|
||||||
|
if (!DSpaceRestPermission.READ.equals(restPermission)
|
||||||
|
|| Constants.getTypeID(targetType) != Constants.GROUP) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Request request = requestService.getCurrentRequest();
|
||||||
|
Context context = ContextUtil.obtainContext(request.getServletRequest());
|
||||||
|
EPerson ePerson = null;
|
||||||
|
try {
|
||||||
|
ePerson = ePersonService.findByEmail(context, (String) authentication.getPrincipal());
|
||||||
|
UUID dsoId = UUID.fromString(targetId.toString());
|
||||||
|
|
||||||
|
Group group = groupService.find(context, dsoId);
|
||||||
|
|
||||||
|
if (groupService.isMember(context, ePerson, group)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,32 @@
|
|||||||
|
/**
|
||||||
|
* The contents of this file are subject to the license and copyright
|
||||||
|
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||||
|
* tree and available online at
|
||||||
|
*
|
||||||
|
* http://www.dspace.org/license/
|
||||||
|
*/
|
||||||
|
package org.dspace.app.rest.security;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.security.access.PermissionEvaluator;
|
||||||
|
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
|
||||||
|
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
|
||||||
|
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
|
||||||
|
import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
||||||
|
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private PermissionEvaluator dSpacePermissionEvaluator;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected MethodSecurityExpressionHandler createExpressionHandler() {
|
||||||
|
DefaultMethodSecurityExpressionHandler expressionHandler =
|
||||||
|
new DefaultMethodSecurityExpressionHandler();
|
||||||
|
expressionHandler.setPermissionEvaluator(dSpacePermissionEvaluator);
|
||||||
|
return expressionHandler;
|
||||||
|
}
|
||||||
|
}
|
@@ -35,4 +35,13 @@ public interface RestAuthenticationService {
|
|||||||
void invalidateAuthenticationData(HttpServletRequest request, Context context) throws Exception;
|
void invalidateAuthenticationData(HttpServletRequest request, Context context) throws Exception;
|
||||||
|
|
||||||
AuthenticationService getAuthenticationService();
|
AuthenticationService getAuthenticationService();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the value that should be passed in the WWWW-Authenticate header for 4xx responses to the client
|
||||||
|
* @param request The current client request
|
||||||
|
* @param response The response being build for the client
|
||||||
|
* @return A string value that should be set in the WWWW-Authenticate header
|
||||||
|
*/
|
||||||
|
String getWwwAuthenticateHeaderValue(HttpServletRequest request, HttpServletResponse response);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,47 @@
|
|||||||
|
/**
|
||||||
|
* 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.springframework.security.access.PermissionEvaluator;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface to define a permission evaluator plugin. These plugins are used in the DSpace {@link PermissionEvaluator}
|
||||||
|
* implementation {@link DSpacePermissionEvaluator} to check if an authenticated user has permission to perform a
|
||||||
|
* certain action on a certain object.
|
||||||
|
*
|
||||||
|
* If you implement a this interface in a Spring bean, it will be automatically taken into account when evaluating
|
||||||
|
* permissions.
|
||||||
|
*/
|
||||||
|
public interface RestPermissionEvaluatorPlugin {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check in the authenticated user (provided by the {@link Authentication} object) has the specified permission on
|
||||||
|
* the provided target object.
|
||||||
|
* @param authentication Authentication object providing user details of the authenticated user
|
||||||
|
* @param targetDomainObject The target object that the authenticated user wants to see or manipulate
|
||||||
|
* @param permission Permission object that describes the action the user wants to perform on the target object
|
||||||
|
* @return true if the user is allowed to perform the action described by the permission. False otherwise.
|
||||||
|
*/
|
||||||
|
boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check in the authenticated user (provided by the {@link Authentication} object) has the specified permission on
|
||||||
|
* the target object with the provided identifier.
|
||||||
|
* @param authentication Authentication object providing user details of the authenticated user
|
||||||
|
* @param targetId Unique identifier of the target object the user wants to view or manipulate
|
||||||
|
* @param targetType Type of the target object the users wants to view or manipulate
|
||||||
|
* @param permission Permission object that describes the action the user wants to perform on the target object
|
||||||
|
* @return true if the user is allowed to perform the action described by the permission. False otherwise.
|
||||||
|
*/
|
||||||
|
boolean hasPermission(Authentication authentication, Serializable targetId, String targetType,
|
||||||
|
Object permission);
|
||||||
|
|
||||||
|
}
|
@@ -9,17 +9,11 @@ package org.dspace.app.rest.security;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
|
||||||
import javax.servlet.FilterChain;
|
import javax.servlet.FilterChain;
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.dspace.app.rest.utils.ContextUtil;
|
|
||||||
import org.dspace.authenticate.AuthenticationMethod;
|
|
||||||
import org.dspace.authenticate.service.AuthenticationService;
|
|
||||||
import org.dspace.core.Context;
|
|
||||||
import org.springframework.security.authentication.AuthenticationManager;
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.core.AuthenticationException;
|
import org.springframework.security.core.AuthenticationException;
|
||||||
@@ -77,31 +71,10 @@ public class StatelessLoginFilter extends AbstractAuthenticationProcessingFilter
|
|||||||
HttpServletResponse response, AuthenticationException failed)
|
HttpServletResponse response, AuthenticationException failed)
|
||||||
throws IOException, ServletException {
|
throws IOException, ServletException {
|
||||||
|
|
||||||
AuthenticationService authenticationService = restAuthenticationService.getAuthenticationService();
|
String authenticateHeaderValue = restAuthenticationService.getWwwAuthenticateHeaderValue(request, response);
|
||||||
|
|
||||||
Iterator<AuthenticationMethod> authenticationMethodIterator
|
response.setHeader("WWW-Authenticate", authenticateHeaderValue);
|
||||||
= authenticationService.authenticationMethodIterator();
|
|
||||||
Context context = ContextUtil.obtainContext(request);
|
|
||||||
|
|
||||||
StringBuilder wwwAuthenticate = new StringBuilder();
|
|
||||||
while (authenticationMethodIterator.hasNext()) {
|
|
||||||
AuthenticationMethod authenticationMethod = authenticationMethodIterator.next();
|
|
||||||
|
|
||||||
if (wwwAuthenticate.length() > 0) {
|
|
||||||
wwwAuthenticate.append(", ");
|
|
||||||
}
|
|
||||||
|
|
||||||
wwwAuthenticate.append(authenticationMethod.getName()).append(" realm=\"DSpace REST API\"");
|
|
||||||
|
|
||||||
String loginPageURL = authenticationMethod.loginPageURL(context, request, response);
|
|
||||||
if (StringUtils.isNotBlank(loginPageURL)) {
|
|
||||||
// We cannot reply with a 303 code because may browsers handle 3xx response codes transparently. This
|
|
||||||
// means that the JavaScript client code is not aware of the 303 status and fails to react accordingly.
|
|
||||||
wwwAuthenticate.append(", location=\"").append(loginPageURL).append("\"");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
response.setHeader("WWW-Authenticate", wwwAuthenticate.toString());
|
|
||||||
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, failed.getMessage());
|
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, failed.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -15,12 +15,12 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
import org.springframework.http.HttpMethod;
|
import org.springframework.http.HttpMethod;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||||
|
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
import org.springframework.security.config.annotation.web.builders.WebSecurity;
|
import org.springframework.security.config.annotation.web.builders.WebSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||||
import org.springframework.security.config.http.SessionCreationPolicy;
|
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||||
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
|
|
||||||
import org.springframework.security.web.authentication.logout.HttpStatusReturningLogoutSuccessHandler;
|
import org.springframework.security.web.authentication.logout.HttpStatusReturningLogoutSuccessHandler;
|
||||||
import org.springframework.security.web.authentication.logout.LogoutFilter;
|
import org.springframework.security.web.authentication.logout.LogoutFilter;
|
||||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
||||||
@@ -34,10 +34,11 @@ import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
|||||||
@EnableWebSecurity
|
@EnableWebSecurity
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableConfigurationProperties(SecurityProperties.class)
|
@EnableConfigurationProperties(SecurityProperties.class)
|
||||||
|
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
||||||
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
|
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
|
||||||
|
|
||||||
public static final String ADMIN_GRANT = "ADMIN";
|
public static final String ADMIN_GRANT = "ADMIN";
|
||||||
public static final String EPERSON_GRANT = "EPERSON";
|
public static final String AUTHENTICATED_GRANT = "AUTHENTICATED";
|
||||||
public static final String ANONYMOUS_GRANT = "ANONYMOUS";
|
public static final String ANONYMOUS_GRANT = "ANONYMOUS";
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@@ -69,9 +70,6 @@ public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
|
|||||||
http
|
http
|
||||||
//Tell Spring to not create Sessions
|
//Tell Spring to not create Sessions
|
||||||
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
|
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
|
||||||
//Return the login URL when having an access denied error
|
|
||||||
.exceptionHandling().authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/api/authn/login"))
|
|
||||||
.and()
|
|
||||||
//Anonymous requests should have the "ANONYMOUS" security grant
|
//Anonymous requests should have the "ANONYMOUS" security grant
|
||||||
.anonymous().authorities(ANONYMOUS_GRANT).and()
|
.anonymous().authorities(ANONYMOUS_GRANT).and()
|
||||||
//Wire up the HttpServletRequest with the current SecurityContext values
|
//Wire up the HttpServletRequest with the current SecurityContext values
|
||||||
@@ -79,6 +77,10 @@ public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
|
|||||||
//Disable CSRF as our API can be used by clients on an other domain, we are also protected against this,
|
//Disable CSRF as our API can be used by clients on an other domain, we are also protected against this,
|
||||||
// since we pass the token in a header
|
// since we pass the token in a header
|
||||||
.csrf().disable()
|
.csrf().disable()
|
||||||
|
//Return 401 on authorization failures with a correct WWWW-Authenticate header
|
||||||
|
.exceptionHandling().authenticationEntryPoint(
|
||||||
|
new DSpace401AuthenticationEntryPoint(restAuthenticationService))
|
||||||
|
.and()
|
||||||
|
|
||||||
//Logout configuration
|
//Logout configuration
|
||||||
.logout()
|
.logout()
|
||||||
|
@@ -10,6 +10,7 @@ package org.dspace.app.rest.security.jwt;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
@@ -19,6 +20,7 @@ import org.apache.commons.lang.StringUtils;
|
|||||||
import org.dspace.app.rest.security.DSpaceAuthentication;
|
import org.dspace.app.rest.security.DSpaceAuthentication;
|
||||||
import org.dspace.app.rest.security.RestAuthenticationService;
|
import org.dspace.app.rest.security.RestAuthenticationService;
|
||||||
import org.dspace.app.rest.utils.ContextUtil;
|
import org.dspace.app.rest.utils.ContextUtil;
|
||||||
|
import org.dspace.authenticate.AuthenticationMethod;
|
||||||
import org.dspace.authenticate.service.AuthenticationService;
|
import org.dspace.authenticate.service.AuthenticationService;
|
||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
import org.dspace.eperson.EPerson;
|
import org.dspace.eperson.EPerson;
|
||||||
@@ -111,6 +113,33 @@ public class JWTTokenRestAuthenticationServiceImpl implements RestAuthentication
|
|||||||
return authenticationService;
|
return authenticationService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getWwwAuthenticateHeaderValue(final HttpServletRequest request, final HttpServletResponse response) {
|
||||||
|
Iterator<AuthenticationMethod> authenticationMethodIterator
|
||||||
|
= authenticationService.authenticationMethodIterator();
|
||||||
|
Context context = ContextUtil.obtainContext(request);
|
||||||
|
|
||||||
|
StringBuilder wwwAuthenticate = new StringBuilder();
|
||||||
|
while (authenticationMethodIterator.hasNext()) {
|
||||||
|
AuthenticationMethod authenticationMethod = authenticationMethodIterator.next();
|
||||||
|
|
||||||
|
if (wwwAuthenticate.length() > 0) {
|
||||||
|
wwwAuthenticate.append(", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
wwwAuthenticate.append(authenticationMethod.getName()).append(" realm=\"DSpace REST API\"");
|
||||||
|
|
||||||
|
String loginPageURL = authenticationMethod.loginPageURL(context, request, response);
|
||||||
|
if (org.apache.commons.lang3.StringUtils.isNotBlank(loginPageURL)) {
|
||||||
|
// We cannot reply with a 303 code because may browsers handle 3xx response codes transparently. This
|
||||||
|
// means that the JavaScript client code is not aware of the 303 status and fails to react accordingly.
|
||||||
|
wwwAuthenticate.append(", location=\"").append(loginPageURL).append("\"");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return wwwAuthenticate.toString();
|
||||||
|
}
|
||||||
|
|
||||||
private void addTokenToResponse(final HttpServletResponse response, final String token) throws IOException {
|
private void addTokenToResponse(final HttpServletResponse response, final String token) throws IOException {
|
||||||
response.setHeader(AUTHORIZATION_HEADER, String.format("%s %s", AUTHORIZATION_TYPE, token));
|
response.setHeader(AUTHORIZATION_HEADER, String.format("%s %s", AUTHORIZATION_TYPE, token));
|
||||||
}
|
}
|
||||||
|
@@ -21,6 +21,7 @@ import org.dspace.app.rest.repository.LinkRestRepository;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.core.MethodParameter;
|
import org.springframework.core.MethodParameter;
|
||||||
|
import org.springframework.core.annotation.AnnotationUtils;
|
||||||
import org.springframework.core.convert.ConversionException;
|
import org.springframework.core.convert.ConversionException;
|
||||||
import org.springframework.core.convert.ConversionService;
|
import org.springframework.core.convert.ConversionService;
|
||||||
import org.springframework.core.convert.TypeDescriptor;
|
import org.springframework.core.convert.TypeDescriptor;
|
||||||
@@ -60,7 +61,11 @@ public class RestRepositoryUtils {
|
|||||||
*/
|
*/
|
||||||
public boolean haveSearchMethods(DSpaceRestRepository repository) {
|
public boolean haveSearchMethods(DSpaceRestRepository repository) {
|
||||||
for (Method method : repository.getClass().getMethods()) {
|
for (Method method : repository.getClass().getMethods()) {
|
||||||
SearchRestMethod ann = method.getAnnotation(SearchRestMethod.class);
|
// We need to use AnnotationUtils because the DSpaceRestRepository is possibly enhanced by a Spring AOP
|
||||||
|
// proxy. The regular "method.getAnnotation()" method would then search the proxy instead of the
|
||||||
|
// underlying actual class. The proxy does not inherit the annotations.
|
||||||
|
SearchRestMethod ann =
|
||||||
|
AnnotationUtils.findAnnotation(method, SearchRestMethod.class);
|
||||||
if (ann != null) {
|
if (ann != null) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -75,7 +80,10 @@ public class RestRepositoryUtils {
|
|||||||
public List<String> listSearchMethods(DSpaceRestRepository repository) {
|
public List<String> listSearchMethods(DSpaceRestRepository repository) {
|
||||||
List<String> searchMethods = new LinkedList<String>();
|
List<String> searchMethods = new LinkedList<String>();
|
||||||
for (Method method : repository.getClass().getMethods()) {
|
for (Method method : repository.getClass().getMethods()) {
|
||||||
SearchRestMethod ann = method.getAnnotation(SearchRestMethod.class);
|
// We need to use AnnotationUtils because the DSpaceRestRepository is possibly enhanced by a Spring AOP
|
||||||
|
// proxy. The regular "method.getAnnotation()" method would then search the proxy instead of the
|
||||||
|
// underlying actual class. The proxy does not inherit the annotations.
|
||||||
|
SearchRestMethod ann = AnnotationUtils.findAnnotation(method, SearchRestMethod.class);
|
||||||
if (ann != null) {
|
if (ann != null) {
|
||||||
String name = ann.name();
|
String name = ann.name();
|
||||||
if (name.isEmpty()) {
|
if (name.isEmpty()) {
|
||||||
@@ -96,8 +104,15 @@ public class RestRepositoryUtils {
|
|||||||
*/
|
*/
|
||||||
public Method getSearchMethod(String searchMethodName, DSpaceRestRepository repository) {
|
public Method getSearchMethod(String searchMethodName, DSpaceRestRepository repository) {
|
||||||
Method searchMethod = null;
|
Method searchMethod = null;
|
||||||
for (Method method : repository.getClass().getMethods()) {
|
// DSpaceRestRepository is possibly enhanced with a Spring AOP proxy. Therefor use ClassUtils to determine
|
||||||
SearchRestMethod ann = method.getAnnotation(SearchRestMethod.class);
|
// the underlying implementation class.
|
||||||
|
Method[] methods = ClassUtils.getUserClass(repository.getClass()).getMethods();
|
||||||
|
for (Method method : methods) {
|
||||||
|
// We need to use AnnotationUtils because the DSpaceRestRepository is possibly enhanced by a Spring AOP
|
||||||
|
// proxy. The regular "method.getAnnotation()" method would then search the proxy instead of the
|
||||||
|
// underlying actual class. The proxy does not inherit the annotations.
|
||||||
|
SearchRestMethod ann =
|
||||||
|
AnnotationUtils.findAnnotation(method, SearchRestMethod.class);
|
||||||
if (ann != null) {
|
if (ann != null) {
|
||||||
String name = ann.name();
|
String name = ann.name();
|
||||||
if (name.isEmpty()) {
|
if (name.isEmpty()) {
|
||||||
|
@@ -88,15 +88,15 @@ public class BitstreamRestRepositoryIT extends AbstractControllerIntegrationTest
|
|||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
getClient().perform(get("/api/core/bitstreams/"))
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
|
getClient(token).perform(get("/api/core/bitstreams/"))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().contentType(contentType))
|
.andExpect(content().contentType(contentType))
|
||||||
.andExpect(jsonPath("$._embedded.bitstreams", Matchers.containsInAnyOrder(
|
.andExpect(jsonPath("$._embedded.bitstreams", Matchers.containsInAnyOrder(
|
||||||
BitstreamMatcher.matchBitstreamEntry(bitstream),
|
BitstreamMatcher.matchBitstreamEntry(bitstream),
|
||||||
BitstreamMatcher.matchBitstreamEntry(bitstream1)
|
BitstreamMatcher.matchBitstreamEntry(bitstream1)
|
||||||
)))
|
)));
|
||||||
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -145,7 +145,9 @@ public class BitstreamRestRepositoryIT extends AbstractControllerIntegrationTest
|
|||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
getClient().perform(get("/api/core/bitstreams/")
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
|
getClient(token).perform(get("/api/core/bitstreams/")
|
||||||
.param("size", "1"))
|
.param("size", "1"))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().contentType(contentType))
|
.andExpect(content().contentType(contentType))
|
||||||
@@ -160,7 +162,7 @@ public class BitstreamRestRepositoryIT extends AbstractControllerIntegrationTest
|
|||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
getClient().perform(get("/api/core/bitstreams/")
|
getClient(token).perform(get("/api/core/bitstreams/")
|
||||||
.param("size", "1")
|
.param("size", "1")
|
||||||
.param("page", "1"))
|
.param("page", "1"))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
@@ -172,9 +174,10 @@ public class BitstreamRestRepositoryIT extends AbstractControllerIntegrationTest
|
|||||||
Matchers.contains(
|
Matchers.contains(
|
||||||
BitstreamMatcher.matchBitstreamEntry(bitstream)
|
BitstreamMatcher.matchBitstreamEntry(bitstream)
|
||||||
)
|
)
|
||||||
)))
|
)));
|
||||||
|
|
||||||
;
|
getClient().perform(get("/api/core/bitstreams/"))
|
||||||
|
.andExpect(status().isUnauthorized());
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO Re-enable test after https://jira.duraspace.org/browse/DS-3774 is fixed
|
//TODO Re-enable test after https://jira.duraspace.org/browse/DS-3774 is fixed
|
||||||
@@ -413,7 +416,9 @@ public class BitstreamRestRepositoryIT extends AbstractControllerIntegrationTest
|
|||||||
.build();
|
.build();
|
||||||
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
||||||
|
|
||||||
getClient().perform(get("/api/core/bitstreams/" + UUID.randomUUID()))
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
|
getClient(token).perform(get("/api/core/bitstreams/" + UUID.randomUUID()))
|
||||||
.andExpect(status().isNotFound())
|
.andExpect(status().isNotFound())
|
||||||
;
|
;
|
||||||
|
|
||||||
@@ -462,7 +467,7 @@ public class BitstreamRestRepositoryIT extends AbstractControllerIntegrationTest
|
|||||||
.andExpect(status().is(204));
|
.andExpect(status().is(204));
|
||||||
|
|
||||||
// Verify 404 after delete
|
// Verify 404 after delete
|
||||||
getClient().perform(get("/api/core/bitstreams/" + bitstream.getID()))
|
getClient(token).perform(get("/api/core/bitstreams/" + bitstream.getID()))
|
||||||
.andExpect(status().isNotFound());
|
.andExpect(status().isNotFound());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -322,7 +322,7 @@ public class BrowsesResourceControllerIT extends AbstractControllerIntegrationTe
|
|||||||
.withIssueDate("2015-03-12")
|
.withIssueDate("2015-03-12")
|
||||||
.withAuthor("Duck, Donald")
|
.withAuthor("Duck, Donald")
|
||||||
.withSubject("Cartoons").withSubject("Ducks")
|
.withSubject("Cartoons").withSubject("Ducks")
|
||||||
.makePrivate()
|
.makeUnDiscoverable()
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
//4. An item with an item-level embargo
|
//4. An item with an item-level embargo
|
||||||
|
@@ -1735,7 +1735,7 @@ public class DiscoveryRestControllerIT extends AbstractControllerIntegrationTest
|
|||||||
.withIssueDate("1990-02-13")
|
.withIssueDate("1990-02-13")
|
||||||
.withAuthor("Smith, Maria").withAuthor("Doe, Jane").withAuthor("Testing, Works")
|
.withAuthor("Smith, Maria").withAuthor("Doe, Jane").withAuthor("Testing, Works")
|
||||||
.withSubject("TestingForMore").withSubject("ExtraEntry")
|
.withSubject("TestingForMore").withSubject("ExtraEntry")
|
||||||
.makePrivate()
|
.makeUnDiscoverable()
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
Item publicItem3 = ItemBuilder.createItem(context, col2)
|
Item publicItem3 = ItemBuilder.createItem(context, col2)
|
||||||
@@ -1987,7 +1987,7 @@ public class DiscoveryRestControllerIT extends AbstractControllerIntegrationTest
|
|||||||
.withAuthor("test2, test2").withAuthor("Maybe, Maybe")
|
.withAuthor("test2, test2").withAuthor("Maybe, Maybe")
|
||||||
.withSubject("AnotherTest").withSubject("TestingForMore")
|
.withSubject("AnotherTest").withSubject("TestingForMore")
|
||||||
.withSubject("ExtraEntry")
|
.withSubject("ExtraEntry")
|
||||||
.makePrivate()
|
.makeUnDiscoverable()
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
UUID scope = col2.getID();
|
UUID scope = col2.getID();
|
||||||
@@ -2142,7 +2142,7 @@ public class DiscoveryRestControllerIT extends AbstractControllerIntegrationTest
|
|||||||
.withIssueDate("2010-02-13")
|
.withIssueDate("2010-02-13")
|
||||||
.withAuthor("Smith, Maria").withAuthor("Doe, Jane")
|
.withAuthor("Smith, Maria").withAuthor("Doe, Jane")
|
||||||
.withSubject("AnotherTest").withSubject("ExtraEntry")
|
.withSubject("AnotherTest").withSubject("ExtraEntry")
|
||||||
.makePrivate()
|
.makeUnDiscoverable()
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
|
||||||
|
@@ -95,12 +95,16 @@ public class EPersonRestRepositoryIT extends AbstractControllerIntegrationTest {
|
|||||||
.andExpect(content().contentType(contentType))
|
.andExpect(content().contentType(contentType))
|
||||||
.andExpect(jsonPath("$._embedded.epersons", Matchers.containsInAnyOrder(
|
.andExpect(jsonPath("$._embedded.epersons", Matchers.containsInAnyOrder(
|
||||||
EPersonMatcher.matchEPersonEntry(newUser),
|
EPersonMatcher.matchEPersonEntry(newUser),
|
||||||
EPersonMatcher.matchDefaultTestEPerson(),
|
EPersonMatcher.matchEPersonOnEmail(admin.getEmail()),
|
||||||
EPersonMatcher.matchDefaultTestEPerson()
|
EPersonMatcher.matchEPersonOnEmail(eperson.getEmail())
|
||||||
)))
|
)))
|
||||||
.andExpect(jsonPath("$.page.size", is(20)))
|
.andExpect(jsonPath("$.page.size", is(20)))
|
||||||
.andExpect(jsonPath("$.page.totalElements", is(3)))
|
.andExpect(jsonPath("$.page.totalElements", is(3)))
|
||||||
;
|
;
|
||||||
|
|
||||||
|
getClient().perform(get("/api/eperson/epersons"))
|
||||||
|
.andExpect(status().isUnauthorized())
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -134,24 +138,24 @@ public class EPersonRestRepositoryIT extends AbstractControllerIntegrationTest {
|
|||||||
public void findAllPaginationTest() throws Exception {
|
public void findAllPaginationTest() throws Exception {
|
||||||
context.turnOffAuthorisationSystem();
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
EPerson ePerson = EPersonBuilder.createEPerson(context)
|
EPerson testEPerson = EPersonBuilder.createEPerson(context)
|
||||||
.withNameInMetadata("John", "Doe")
|
.withNameInMetadata("John", "Doe")
|
||||||
.withEmail("Johndoe@fake-email.com")
|
.withEmail("Johndoe@fake-email.com")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
String authToken = getAuthToken(admin.getEmail(), password);
|
String authToken = getAuthToken(admin.getEmail(), password);
|
||||||
// using size = 2 the first page will contains our test user and admin
|
// using size = 2 the first page will contains our test user and admin
|
||||||
getClient(authToken).perform(get("/api/eperson/eperson")
|
getClient(authToken).perform(get("/api/eperson/epersons")
|
||||||
.param("size", "2"))
|
.param("size", "2"))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().contentType(contentType))
|
.andExpect(content().contentType(contentType))
|
||||||
.andExpect(jsonPath("$._embedded.epersons", Matchers.containsInAnyOrder(
|
.andExpect(jsonPath("$._embedded.epersons", Matchers.containsInAnyOrder(
|
||||||
EPersonMatcher.matchDefaultTestEPerson(),
|
EPersonMatcher.matchEPersonEntry(admin),
|
||||||
EPersonMatcher.matchDefaultTestEPerson()
|
EPersonMatcher.matchEPersonEntry(testEPerson)
|
||||||
)))
|
)))
|
||||||
.andExpect(jsonPath("$._embedded.epersons", Matchers.not(
|
.andExpect(jsonPath("$._embedded.epersons", Matchers.not(
|
||||||
Matchers.contains(
|
Matchers.contains(
|
||||||
EPersonMatcher.matchEPersonEntry(ePerson)
|
EPersonMatcher.matchEPersonEntry(admin)
|
||||||
)
|
)
|
||||||
)))
|
)))
|
||||||
.andExpect(jsonPath("$.page.size", is(2)))
|
.andExpect(jsonPath("$.page.size", is(2)))
|
||||||
@@ -159,17 +163,22 @@ public class EPersonRestRepositoryIT extends AbstractControllerIntegrationTest {
|
|||||||
;
|
;
|
||||||
|
|
||||||
// using size = 2 the first page will contains our test user and admin
|
// using size = 2 the first page will contains our test user and admin
|
||||||
getClient(authToken).perform(get("/api/eperson/eperson")
|
getClient(authToken).perform(get("/api/eperson/epersons")
|
||||||
.param("size", "2")
|
.param("size", "2")
|
||||||
.param("page", "1"))
|
.param("page", "1"))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().contentType(contentType))
|
.andExpect(content().contentType(contentType))
|
||||||
.andExpect(jsonPath("$._embedded.epersons", Matchers.contains(
|
.andExpect(jsonPath("$._embedded.epersons", Matchers.contains(
|
||||||
EPersonMatcher.matchEPersonEntry(ePerson)
|
EPersonMatcher.matchEPersonEntry(eperson)
|
||||||
)))
|
)))
|
||||||
|
.andExpect(jsonPath("$._embedded.epersons", Matchers.hasSize(1)))
|
||||||
.andExpect(jsonPath("$.page.size", is(2)))
|
.andExpect(jsonPath("$.page.size", is(2)))
|
||||||
.andExpect(jsonPath("$.page.totalElements", is(3)))
|
.andExpect(jsonPath("$.page.totalElements", is(3)))
|
||||||
;
|
;
|
||||||
|
|
||||||
|
getClient().perform(get("/api/eperson/epersons"))
|
||||||
|
.andExpect(status().isUnauthorized())
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -203,7 +212,7 @@ public class EPersonRestRepositoryIT extends AbstractControllerIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findOneRelsTest() throws Exception {
|
public void readEpersonAuthorizationTest() throws Exception {
|
||||||
context.turnOffAuthorisationSystem();
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
EPerson ePerson = EPersonBuilder.createEPerson(context)
|
EPerson ePerson = EPersonBuilder.createEPerson(context)
|
||||||
@@ -225,24 +234,41 @@ public class EPersonRestRepositoryIT extends AbstractControllerIntegrationTest {
|
|||||||
)))
|
)))
|
||||||
.andExpect(jsonPath("$", Matchers.not(
|
.andExpect(jsonPath("$", Matchers.not(
|
||||||
is(
|
is(
|
||||||
EPersonMatcher.matchEPersonEntry(ePerson)
|
EPersonMatcher.matchEPersonEntry(eperson)
|
||||||
)
|
)
|
||||||
)))
|
)))
|
||||||
.andExpect(jsonPath("$._links.self.href",
|
.andExpect(jsonPath("$._links.self.href",
|
||||||
Matchers.containsString("/api/eperson/epersons/" + ePerson2.getID())));
|
Matchers.containsString("/api/eperson/epersons/" + ePerson2.getID())));
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
//EPerson can only access himself
|
||||||
|
String epersonToken = getAuthToken(eperson.getEmail(), password);
|
||||||
|
|
||||||
|
getClient(epersonToken).perform(get("/api/eperson/epersons/" + ePerson2.getID()))
|
||||||
|
.andExpect(status().isForbidden());
|
||||||
|
|
||||||
|
|
||||||
|
getClient(epersonToken).perform(get("/api/eperson/epersons/" + eperson.getID()))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(content().contentType(contentType))
|
||||||
|
.andExpect(jsonPath("$", is(
|
||||||
|
EPersonMatcher.matchEPersonOnEmail(eperson.getEmail())
|
||||||
|
)))
|
||||||
|
.andExpect(jsonPath("$._links.self.href",
|
||||||
|
Matchers.containsString("/api/eperson/epersons/" + eperson.getID())));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findOneTestWrongUUID() throws Exception {
|
public void findOneTestWrongUUID() throws Exception {
|
||||||
context.turnOffAuthorisationSystem();
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
EPerson ePerson = EPersonBuilder.createEPerson(context)
|
EPerson testEPerson1 = EPersonBuilder.createEPerson(context)
|
||||||
.withNameInMetadata("John", "Doe")
|
.withNameInMetadata("John", "Doe")
|
||||||
.withEmail("Johndoe@fake-email.com")
|
.withEmail("Johndoe@fake-email.com")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
EPerson ePerson2 = EPersonBuilder.createEPerson(context)
|
EPerson testEPerson2 = EPersonBuilder.createEPerson(context)
|
||||||
.withNameInMetadata("Jane", "Smith")
|
.withNameInMetadata("Jane", "Smith")
|
||||||
.withEmail("janesmith@fake-email.com")
|
.withEmail("janesmith@fake-email.com")
|
||||||
.build();
|
.build();
|
||||||
|
@@ -19,23 +19,25 @@ public class EmptyRestRepositoryIT extends AbstractControllerIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findAllTest() throws Exception {
|
public void findAllTest() throws Exception {
|
||||||
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
//Test retrieval of all communities while none exist
|
//Test retrieval of all communities while none exist
|
||||||
getClient().perform(get("/api/core/communities"))
|
getClient(token).perform(get("/api/core/communities"))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("$.page.totalElements", is(0)));
|
.andExpect(jsonPath("$.page.totalElements", is(0)));
|
||||||
|
|
||||||
//Test retrieval of all collections while none exist
|
//Test retrieval of all collections while none exist
|
||||||
getClient().perform(get("/api/core/collections"))
|
getClient(token).perform(get("/api/core/collections"))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("$.page.totalElements", is(0)));
|
.andExpect(jsonPath("$.page.totalElements", is(0)));
|
||||||
|
|
||||||
//Test retrieval of all items while none exist
|
//Test retrieval of all items while none exist
|
||||||
getClient().perform(get("/api/core/items"))
|
getClient(token).perform(get("/api/core/items"))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("$.page.totalElements", is(0)));
|
.andExpect(jsonPath("$.page.totalElements", is(0)));
|
||||||
|
|
||||||
//Test retrieval of all bitstreams while none exist
|
//Test retrieval of all bitstreams while none exist
|
||||||
getClient().perform(get("/api/core/bitstreams"))
|
getClient(token).perform(get("/api/core/bitstreams"))
|
||||||
. andExpect(status().isOk())
|
. andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("$.page.totalElements", is(0)));
|
.andExpect(jsonPath("$.page.totalElements", is(0)));
|
||||||
}
|
}
|
||||||
|
@@ -31,8 +31,16 @@ public class GroupRestRepositoryIT extends AbstractControllerIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findAllTest() throws Exception {
|
public void findAllTest() throws Exception {
|
||||||
//When we call the root endpoint
|
|
||||||
getClient().perform(get("/api/eperson/groups"))
|
getClient().perform(get("/api/eperson/groups"))
|
||||||
|
//The status has to be 403 Not Authorized
|
||||||
|
.andExpect(status().isUnauthorized());
|
||||||
|
|
||||||
|
|
||||||
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
|
//When we call the root endpoint
|
||||||
|
getClient(token).perform(get("/api/eperson/groups"))
|
||||||
//The status has to be 200 OK
|
//The status has to be 200 OK
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().contentType(contentType))
|
.andExpect(content().contentType(contentType))
|
||||||
@@ -48,8 +56,16 @@ public class GroupRestRepositoryIT extends AbstractControllerIntegrationTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findAllPaginationTest() throws Exception {
|
public void findAllPaginationTest() throws Exception {
|
||||||
context.turnOffAuthorisationSystem();
|
|
||||||
getClient().perform(get("/api/eperson/groups"))
|
getClient().perform(get("/api/eperson/groups"))
|
||||||
|
//The status has to be 403 Not Authorized
|
||||||
|
.andExpect(status().isUnauthorized());
|
||||||
|
|
||||||
|
|
||||||
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
|
//When we call the root endpoint
|
||||||
|
getClient(token).perform(get("/api/eperson/groups"))
|
||||||
//The status has to be 200 OK
|
//The status has to be 200 OK
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().contentType(contentType))
|
.andExpect(content().contentType(contentType))
|
||||||
@@ -69,9 +85,11 @@ public class GroupRestRepositoryIT extends AbstractControllerIntegrationTest {
|
|||||||
.withName(testGroupName)
|
.withName(testGroupName)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
String generatedGroupId = group.getID().toString();
|
String generatedGroupId = group.getID().toString();
|
||||||
String groupIdCall = "/api/eperson/groups/" + generatedGroupId;
|
String groupIdCall = "/api/eperson/groups/" + generatedGroupId;
|
||||||
getClient().perform(get(groupIdCall))
|
getClient(token).perform(get(groupIdCall))
|
||||||
//The status has to be 200 OK
|
//The status has to be 200 OK
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().contentType(contentType))
|
.andExpect(content().contentType(contentType))
|
||||||
@@ -79,7 +97,7 @@ public class GroupRestRepositoryIT extends AbstractControllerIntegrationTest {
|
|||||||
GroupMatcher.matchGroupEntry(group.getID(), group.getName())
|
GroupMatcher.matchGroupEntry(group.getID(), group.getName())
|
||||||
)))
|
)))
|
||||||
;
|
;
|
||||||
getClient().perform(get("/api/eperson/groups"))
|
getClient(token).perform(get("/api/eperson/groups"))
|
||||||
//The status has to be 200 OK
|
//The status has to be 200 OK
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().contentType(contentType))
|
.andExpect(content().contentType(contentType))
|
||||||
@@ -89,7 +107,7 @@ public class GroupRestRepositoryIT extends AbstractControllerIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findOneRelsTest() throws Exception {
|
public void readGroupAuthorizationTest() throws Exception {
|
||||||
context.turnOffAuthorisationSystem();
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
Group group = GroupBuilder.createGroup(context)
|
Group group = GroupBuilder.createGroup(context)
|
||||||
@@ -98,21 +116,42 @@ public class GroupRestRepositoryIT extends AbstractControllerIntegrationTest {
|
|||||||
|
|
||||||
Group group2 = GroupBuilder.createGroup(context)
|
Group group2 = GroupBuilder.createGroup(context)
|
||||||
.withName("Group2")
|
.withName("Group2")
|
||||||
|
.addMember(eperson)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
getClient().perform(get("/api/eperson/groups/" + group2.getID()))
|
//Admin can access
|
||||||
.andExpect(status().isOk())
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
.andExpect(content().contentType(contentType))
|
getClient(token).perform(get("/api/eperson/groups/" + group2.getID()))
|
||||||
.andExpect(jsonPath("$", Matchers.is(
|
.andExpect(status().isOk())
|
||||||
GroupMatcher.matchGroupEntry(group2.getID(), group2.getName())
|
.andExpect(content().contentType(contentType))
|
||||||
)))
|
.andExpect(jsonPath("$", Matchers.is(
|
||||||
.andExpect(jsonPath("$", Matchers.not(
|
GroupMatcher.matchGroupEntry(group2.getID(), group2.getName())
|
||||||
Matchers.is(
|
)))
|
||||||
GroupMatcher.matchGroupEntry(group.getID(), group.getName())
|
.andExpect(jsonPath("$", Matchers.not(
|
||||||
)
|
Matchers.is(
|
||||||
)))
|
GroupMatcher.matchGroupEntry(group.getID(), group.getName())
|
||||||
.andExpect(jsonPath("$._links.self.href",
|
)
|
||||||
Matchers.containsString("/api/eperson/groups/" + group2.getID())));
|
)))
|
||||||
|
.andExpect(jsonPath("$._links.self.href",
|
||||||
|
Matchers.containsString("/api/eperson/groups/" + group2.getID())));
|
||||||
|
|
||||||
|
|
||||||
|
//People in group should be able to access token
|
||||||
|
token = getAuthToken(eperson.getEmail(), password);
|
||||||
|
|
||||||
|
getClient(token).perform(get("/api/eperson/groups/" + group2.getID()))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(content().contentType(contentType))
|
||||||
|
.andExpect(jsonPath("$", Matchers.is(
|
||||||
|
GroupMatcher.matchGroupEntry(group2.getID(), group2.getName())
|
||||||
|
)))
|
||||||
|
.andExpect(jsonPath("$", Matchers.not(
|
||||||
|
Matchers.is(
|
||||||
|
GroupMatcher.matchGroupEntry(group.getID(), group.getName())
|
||||||
|
)
|
||||||
|
)))
|
||||||
|
.andExpect(jsonPath("$._links.self.href",
|
||||||
|
Matchers.containsString("/api/eperson/groups/" + group2.getID())));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@@ -26,6 +26,8 @@ import org.apache.commons.lang3.CharEncoding;
|
|||||||
import org.dspace.app.rest.builder.BitstreamBuilder;
|
import org.dspace.app.rest.builder.BitstreamBuilder;
|
||||||
import org.dspace.app.rest.builder.CollectionBuilder;
|
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.builder.ItemBuilder;
|
import org.dspace.app.rest.builder.ItemBuilder;
|
||||||
import org.dspace.app.rest.builder.WorkspaceItemBuilder;
|
import org.dspace.app.rest.builder.WorkspaceItemBuilder;
|
||||||
import org.dspace.app.rest.matcher.ItemMatcher;
|
import org.dspace.app.rest.matcher.ItemMatcher;
|
||||||
@@ -37,6 +39,8 @@ import org.dspace.content.Collection;
|
|||||||
import org.dspace.content.Community;
|
import org.dspace.content.Community;
|
||||||
import org.dspace.content.Item;
|
import org.dspace.content.Item;
|
||||||
import org.dspace.content.WorkspaceItem;
|
import org.dspace.content.WorkspaceItem;
|
||||||
|
import org.dspace.eperson.EPerson;
|
||||||
|
import org.dspace.eperson.Group;
|
||||||
import org.hamcrest.Matchers;
|
import org.hamcrest.Matchers;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
@@ -80,7 +84,9 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest {
|
|||||||
.withSubject("ExtraEntry")
|
.withSubject("ExtraEntry")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
getClient().perform(get("/api/core/items"))
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
|
getClient(token).perform(get("/api/core/items"))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("$._embedded.items", Matchers.containsInAnyOrder(
|
.andExpect(jsonPath("$._embedded.items", Matchers.containsInAnyOrder(
|
||||||
ItemMatcher.matchItemWithTitleAndDateIssued(publicItem1, "Public item 1", "2017-10-17"),
|
ItemMatcher.matchItemWithTitleAndDateIssued(publicItem1, "Public item 1", "2017-10-17"),
|
||||||
@@ -131,7 +137,9 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest {
|
|||||||
.withSubject("ExtraEntry")
|
.withSubject("ExtraEntry")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
getClient().perform(get("/api/core/items")
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
|
getClient(token).perform(get("/api/core/items")
|
||||||
.param("size", "2"))
|
.param("size", "2"))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(jsonPath("$._embedded.items", Matchers.containsInAnyOrder(
|
.andExpect(jsonPath("$._embedded.items", Matchers.containsInAnyOrder(
|
||||||
@@ -146,7 +154,7 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest {
|
|||||||
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/items")))
|
.andExpect(jsonPath("$._links.self.href", Matchers.containsString("/api/core/items")))
|
||||||
;
|
;
|
||||||
|
|
||||||
getClient().perform(get("/api/core/items")
|
getClient(token).perform(get("/api/core/items")
|
||||||
.param("size", "2")
|
.param("size", "2")
|
||||||
.param("page", "1"))
|
.param("page", "1"))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
@@ -312,7 +320,9 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest {
|
|||||||
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
||||||
Collection col2 = CollectionBuilder.createCollection(context, child1).withName("Collection 2").build();
|
Collection col2 = CollectionBuilder.createCollection(context, child1).withName("Collection 2").build();
|
||||||
|
|
||||||
getClient().perform(get("/api/core/items/" + UUID.randomUUID()))
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
|
getClient(token).perform(get("/api/core/items/" + UUID.randomUUID()))
|
||||||
.andExpect(status().isNotFound())
|
.andExpect(status().isNotFound())
|
||||||
;
|
;
|
||||||
|
|
||||||
@@ -714,7 +724,7 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest {
|
|||||||
.withIssueDate("2017-10-17")
|
.withIssueDate("2017-10-17")
|
||||||
.withAuthor("Smith, Donald").withAuthor("Doe, John")
|
.withAuthor("Smith, Donald").withAuthor("Doe, John")
|
||||||
.withSubject("ExtraEntry")
|
.withSubject("ExtraEntry")
|
||||||
.makePrivate()
|
.makeUnDiscoverable()
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
String token = getAuthToken(admin.getEmail(), password);
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
@@ -767,7 +777,7 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest {
|
|||||||
.withIssueDate("2017-10-17")
|
.withIssueDate("2017-10-17")
|
||||||
.withAuthor("Smith, Donald").withAuthor("Doe, John")
|
.withAuthor("Smith, Donald").withAuthor("Doe, John")
|
||||||
.withSubject("ExtraEntry")
|
.withSubject("ExtraEntry")
|
||||||
.makePrivate()
|
.makeUnDiscoverable()
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
String token = getAuthToken(admin.getEmail(), password);
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
@@ -810,7 +820,7 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest {
|
|||||||
.withIssueDate("2017-10-17")
|
.withIssueDate("2017-10-17")
|
||||||
.withAuthor("Smith, Donald").withAuthor("Doe, John")
|
.withAuthor("Smith, Donald").withAuthor("Doe, John")
|
||||||
.withSubject("ExtraEntry")
|
.withSubject("ExtraEntry")
|
||||||
.makePrivate()
|
.makeUnDiscoverable()
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
String token = getAuthToken(eperson.getEmail(), password);
|
String token = getAuthToken(eperson.getEmail(), password);
|
||||||
@@ -835,7 +845,7 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void makePrivatePatchTest() throws Exception {
|
public void makeUnDiscoverablePatchTest() throws Exception {
|
||||||
context.turnOffAuthorisationSystem();
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
//** GIVEN **
|
//** GIVEN **
|
||||||
@@ -880,7 +890,7 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void makePrivatePatchUnauthorizedTest() throws Exception {
|
public void makeUnDiscoverablePatchUnauthorizedTest() throws Exception {
|
||||||
context.turnOffAuthorisationSystem();
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
//** GIVEN **
|
//** GIVEN **
|
||||||
@@ -922,7 +932,8 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void makePrivatePatchForbiddenTest() throws Exception {
|
@Test
|
||||||
|
public void makeUnDiscoverablePatchForbiddenTest() throws Exception {
|
||||||
context.turnOffAuthorisationSystem();
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
//** GIVEN **
|
//** GIVEN **
|
||||||
@@ -994,7 +1005,7 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest {
|
|||||||
.withIssueDate("2017-10-17")
|
.withIssueDate("2017-10-17")
|
||||||
.withAuthor("Smith, Donald").withAuthor("Doe, John")
|
.withAuthor("Smith, Donald").withAuthor("Doe, John")
|
||||||
.withSubject("ExtraEntry")
|
.withSubject("ExtraEntry")
|
||||||
.makePrivate()
|
.makeUnDiscoverable()
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
String token = getAuthToken(admin.getEmail(), password);
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
@@ -1089,6 +1100,7 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest {
|
|||||||
.andExpect(status().is(404));
|
.andExpect(status().is(404));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void deleteOneTemplateTest() throws Exception {
|
public void deleteOneTemplateTest() throws Exception {
|
||||||
context.turnOffAuthorisationSystem();
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
@@ -1113,10 +1125,11 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest {
|
|||||||
.andExpect(status().is(422));
|
.andExpect(status().is(422));
|
||||||
|
|
||||||
//Check templateItem is available after failed deletion
|
//Check templateItem is available after failed deletion
|
||||||
getClient().perform(get("/api/core/items/" + templateItem.getID()))
|
getClient(token).perform(get("/api/core/items/" + templateItem.getID()))
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void deleteOneWorkspaceTest() throws Exception {
|
public void deleteOneWorkspaceTest() throws Exception {
|
||||||
context.turnOffAuthorisationSystem();
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
@@ -1138,8 +1151,198 @@ public class ItemRestRepositoryIT extends AbstractControllerIntegrationTest {
|
|||||||
getClient(token).perform(delete("/api/core/items/" + workspaceItem.getItem().getID()))
|
getClient(token).perform(delete("/api/core/items/" + workspaceItem.getItem().getID()))
|
||||||
.andExpect(status().is(422));
|
.andExpect(status().is(422));
|
||||||
|
|
||||||
//Check templateItem is available after failed deletion
|
//Check workspaceItem is available after failed deletion
|
||||||
getClient().perform(get("/api/core/items/" + workspaceItem.getID()))
|
getClient(token).perform(get("/api/core/items/" + workspaceItem.getItem().getID()))
|
||||||
.andExpect(status().isOk());
|
.andExpect(status().isOk());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void embargoAccessTest() throws Exception {
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
//** GIVEN **
|
||||||
|
//1. A community-collection structure with one parent community with sub-community and two collections.
|
||||||
|
parentCommunity = CommunityBuilder.createCommunity(context)
|
||||||
|
.withName("Parent Community")
|
||||||
|
.build();
|
||||||
|
Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity)
|
||||||
|
.withName("Sub Community")
|
||||||
|
.build();
|
||||||
|
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
||||||
|
|
||||||
|
//2. An embargoed item
|
||||||
|
Item embargoedItem1 = ItemBuilder.createItem(context, col1)
|
||||||
|
.withTitle("embargoed item 1")
|
||||||
|
.withIssueDate("2017-12-18")
|
||||||
|
.withAuthor("Smith, Donald").withAuthor("Doe, John")
|
||||||
|
.withSubject("ExtraEntry")
|
||||||
|
.withEmbargoPeriod("6 months")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
//3. a public item
|
||||||
|
Item publicItem1 = ItemBuilder.createItem(context, col1)
|
||||||
|
.withTitle("Public item 1")
|
||||||
|
.withIssueDate("2017-10-17")
|
||||||
|
.withAuthor("Smith, Donald").withAuthor("Doe, John")
|
||||||
|
.withSubject("ExtraEntry")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
//** THEN **
|
||||||
|
//An anonymous user can view public items
|
||||||
|
getClient().perform(get("/api/core/items/" + publicItem1.getID()))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$", Matchers.is(
|
||||||
|
ItemMatcher.matchItemWithTitleAndDateIssued(
|
||||||
|
publicItem1, "Public item 1", "2017-10-17")
|
||||||
|
)))
|
||||||
|
.andExpect(jsonPath("$._links.self.href",
|
||||||
|
Matchers.containsString("/api/core/items")));
|
||||||
|
|
||||||
|
//An anonymous user is not allowed to view embargoed items
|
||||||
|
getClient().perform(get("/api/core/items/" + embargoedItem1.getID()))
|
||||||
|
.andExpect(status().isUnauthorized());
|
||||||
|
|
||||||
|
//An admin user is allowed to access the embargoed item
|
||||||
|
String token1 = getAuthToken(admin.getEmail(), password);
|
||||||
|
getClient(token1).perform(get("/api/core/items/" + embargoedItem1.getID()))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$", Matchers.is(
|
||||||
|
ItemMatcher.matchItemWithTitleAndDateIssued(
|
||||||
|
embargoedItem1, "embargoed item 1", "2017-12-18")
|
||||||
|
)))
|
||||||
|
.andExpect(jsonPath("$._links.self.href",
|
||||||
|
Matchers.containsString("/api/core/items")));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void undiscoverableAccessTest() throws Exception {
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
//** GIVEN **
|
||||||
|
//1. A community-collection structure with one parent community with sub-community and two collections.
|
||||||
|
parentCommunity = CommunityBuilder.createCommunity(context)
|
||||||
|
.withName("Parent Community")
|
||||||
|
.build();
|
||||||
|
Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity)
|
||||||
|
.withName("Sub Community")
|
||||||
|
.build();
|
||||||
|
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
||||||
|
|
||||||
|
//2. An undiscoverable item
|
||||||
|
Item unDiscoverableYetAccessibleItem1 = ItemBuilder.createItem(context, col1)
|
||||||
|
.withTitle("Undiscoverable item 1")
|
||||||
|
.withIssueDate("2017-10-17")
|
||||||
|
.withAuthor("Smith, Donald").withAuthor("Doe, John")
|
||||||
|
.withSubject("ExtraEntry")
|
||||||
|
.makeUnDiscoverable()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
|
||||||
|
//Anonymous users are allowed to access undiscoverable items
|
||||||
|
getClient().perform(get("/api/core/items/" + unDiscoverableYetAccessibleItem1.getID()))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$", Matchers.is(
|
||||||
|
ItemMatcher.matchItemWithTitleAndDateIssued(unDiscoverableYetAccessibleItem1,
|
||||||
|
"Undiscoverable item 1", "2017-10-17")
|
||||||
|
)));
|
||||||
|
|
||||||
|
|
||||||
|
//Admin users are allowed to acceess undiscoverable items
|
||||||
|
String token1 = getAuthToken(admin.getEmail(), password);
|
||||||
|
getClient(token1).perform(get("/api/core/items/" + unDiscoverableYetAccessibleItem1.getID()))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$", Matchers.is(
|
||||||
|
ItemMatcher.matchItemWithTitleAndDateIssued(unDiscoverableYetAccessibleItem1,
|
||||||
|
"Undiscoverable item 1", "2017-10-17")
|
||||||
|
)));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void privateGroupAccessTest() throws Exception {
|
||||||
|
context.turnOffAuthorisationSystem();
|
||||||
|
|
||||||
|
//** GIVEN **
|
||||||
|
//1. A community-collection structure with one parent community with sub-community and two collections.
|
||||||
|
parentCommunity = CommunityBuilder.createCommunity(context)
|
||||||
|
.withName("Parent Community")
|
||||||
|
.build();
|
||||||
|
Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity)
|
||||||
|
.withName("Sub Community")
|
||||||
|
.build();
|
||||||
|
Collection col1 = CollectionBuilder.createCollection(context, child1).withName("Collection 1").build();
|
||||||
|
|
||||||
|
//2. An item restricted to a specific internal group
|
||||||
|
Group staffGroup = GroupBuilder.createGroup(context)
|
||||||
|
.withName("Staff")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Item restrictedItem1 = ItemBuilder.createItem(context, col1)
|
||||||
|
.withTitle("Restricted item 1")
|
||||||
|
.withIssueDate("2017-12-18")
|
||||||
|
.withReaderGroup(staffGroup)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
//3. A public item
|
||||||
|
Item publicItem1 = ItemBuilder.createItem(context, col1)
|
||||||
|
.withTitle("Public item 1")
|
||||||
|
.withIssueDate("2017-10-17")
|
||||||
|
.withAuthor("Smith, Donald").withAuthor("Doe, John")
|
||||||
|
.withSubject("ExtraEntry")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
//4. A member of the internal group
|
||||||
|
EPerson staffEPerson = EPersonBuilder.createEPerson(context)
|
||||||
|
.withEmail("professor@myuni.edu")
|
||||||
|
.withPassword("s3cr3t")
|
||||||
|
.withNameInMetadata("Doctor", "Professor")
|
||||||
|
.withGroupMembership(staffGroup)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
|
||||||
|
context.restoreAuthSystemState();
|
||||||
|
|
||||||
|
//** THEN **
|
||||||
|
//An anonymous user can view the public item
|
||||||
|
getClient().perform(get("/api/core/items/" + publicItem1.getID()))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$", Matchers.is(
|
||||||
|
ItemMatcher.matchItemWithTitleAndDateIssued(
|
||||||
|
publicItem1, "Public item 1", "2017-10-17")
|
||||||
|
)))
|
||||||
|
.andExpect(jsonPath("$._links.self.href",
|
||||||
|
Matchers.containsString("/api/core/items")));
|
||||||
|
|
||||||
|
//An anonymous user is not allowed to the restricted item
|
||||||
|
getClient().perform(get("/api/core/items/" + restrictedItem1.getID()))
|
||||||
|
.andExpect(status().isUnauthorized());
|
||||||
|
|
||||||
|
//An admin user is allowed to access the restricted item
|
||||||
|
String token1 = getAuthToken(admin.getEmail(), password);
|
||||||
|
getClient(token1).perform(get("/api/core/items/" + restrictedItem1.getID()))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$", Matchers.is(
|
||||||
|
ItemMatcher.matchItemWithTitleAndDateIssued(
|
||||||
|
restrictedItem1, "Restricted item 1", "2017-12-18")
|
||||||
|
)))
|
||||||
|
.andExpect(jsonPath("$._links.self.href",
|
||||||
|
Matchers.containsString("/api/core/items")));
|
||||||
|
|
||||||
|
//A member of the internal group is also allowed to access the restricted item
|
||||||
|
String token2 = getAuthToken("professor@myuni.edu", "s3cr3t");
|
||||||
|
getClient(token2).perform(get("/api/core/items/" + restrictedItem1.getID()))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$", Matchers.is(
|
||||||
|
ItemMatcher.matchItemWithTitleAndDateIssued(
|
||||||
|
restrictedItem1, "Restricted item 1", "2017-12-18")
|
||||||
|
)))
|
||||||
|
.andExpect(jsonPath("$._links.self.href",
|
||||||
|
Matchers.containsString("/api/core/items")));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -34,8 +34,16 @@ public class SubmissionDefinitionsControllerIT extends AbstractControllerIntegra
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findAll() throws Exception {
|
public void findAll() throws Exception {
|
||||||
//When we call the root endpoint
|
//When we call the root endpoint as anonymous user
|
||||||
getClient().perform(get("/api/config/submissiondefinitions"))
|
getClient().perform(get("/api/config/submissiondefinitions"))
|
||||||
|
//The status has to be 403 Not Authorized
|
||||||
|
.andExpect(status().isUnauthorized());
|
||||||
|
|
||||||
|
|
||||||
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
|
|
||||||
|
getClient(token).perform(get("/api/config/submissiondefinitions"))
|
||||||
//The status has to be 200 OK
|
//The status has to be 200 OK
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
//We expect the content type to be "application/hal+json;charset=UTF-8"
|
//We expect the content type to be "application/hal+json;charset=UTF-8"
|
||||||
@@ -56,7 +64,14 @@ public class SubmissionDefinitionsControllerIT extends AbstractControllerIntegra
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findDefault() throws Exception {
|
public void findDefault() throws Exception {
|
||||||
|
|
||||||
getClient().perform(get("/api/config/submissiondefinitions/traditional"))
|
getClient().perform(get("/api/config/submissiondefinitions/traditional"))
|
||||||
|
//The status has to be 403 Not Authorized
|
||||||
|
.andExpect(status().isUnauthorized());
|
||||||
|
|
||||||
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
|
getClient(token).perform(get("/api/config/submissiondefinitions/traditional"))
|
||||||
//The status has to be 200 OK
|
//The status has to be 200 OK
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
//We expect the content type to be "application/hal+json;charset=UTF-8"
|
//We expect the content type to be "application/hal+json;charset=UTF-8"
|
||||||
@@ -80,6 +95,16 @@ public class SubmissionDefinitionsControllerIT extends AbstractControllerIntegra
|
|||||||
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build();
|
Collection col1 = CollectionBuilder.createCollection(context, parentCommunity).withName("Collection 1").build();
|
||||||
|
|
||||||
getClient().perform(get("/api/config/submissiondefinitions/search/findByCollection")
|
getClient().perform(get("/api/config/submissiondefinitions/search/findByCollection")
|
||||||
|
.param("uuid", col1.getID().toString()))
|
||||||
|
//** THEN **
|
||||||
|
//The status has to be 200
|
||||||
|
.andExpect(status().isUnauthorized());
|
||||||
|
|
||||||
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
getClient(token).perform(get("/api/config/submissiondefinitions/search/findByCollection")
|
||||||
.param("uuid", col1.getID().toString()))
|
.param("uuid", col1.getID().toString()))
|
||||||
//** THEN **
|
//** THEN **
|
||||||
//The status has to be 200
|
//The status has to be 200
|
||||||
@@ -93,8 +118,17 @@ public class SubmissionDefinitionsControllerIT extends AbstractControllerIntegra
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findCollections() throws Exception {
|
public void findCollections() throws Exception {
|
||||||
|
|
||||||
//Match only that a section exists with a submission configuration behind
|
//Match only that a section exists with a submission configuration behind
|
||||||
getClient().perform(get("/api/config/submissiondefinitions/traditional/collections"))
|
getClient().perform(get("/api/config/submissiondefinitions/traditional/collections"))
|
||||||
|
//The status has to be 403 Not Authorized
|
||||||
|
.andExpect(status().isUnauthorized());
|
||||||
|
|
||||||
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
|
|
||||||
|
//Match only that a section exists with a submission configuration behind
|
||||||
|
getClient(token).perform(get("/api/config/submissiondefinitions/traditional/collections"))
|
||||||
//TODO - this method should return an empty page
|
//TODO - this method should return an empty page
|
||||||
.andExpect(status().isNoContent());
|
.andExpect(status().isNoContent());
|
||||||
//this is the expected result
|
//this is the expected result
|
||||||
@@ -104,7 +138,14 @@ public class SubmissionDefinitionsControllerIT extends AbstractControllerIntegra
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findSections() throws Exception {
|
public void findSections() throws Exception {
|
||||||
|
|
||||||
getClient().perform(get("/api/config/submissiondefinitions/traditional/sections"))
|
getClient().perform(get("/api/config/submissiondefinitions/traditional/sections"))
|
||||||
|
//The status has to be 403 Not Authorized
|
||||||
|
.andExpect(status().isUnauthorized());
|
||||||
|
|
||||||
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
|
getClient(token).perform(get("/api/config/submissiondefinitions/traditional/sections"))
|
||||||
// The status has to be 200 OK
|
// The status has to be 200 OK
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
// We expect the content type to be "application/hal+json;charset=UTF-8"
|
// We expect the content type to be "application/hal+json;charset=UTF-8"
|
||||||
|
@@ -28,8 +28,16 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findAll() throws Exception {
|
public void findAll() throws Exception {
|
||||||
//When we call the root endpoint
|
//When we call the root endpoint as anonymous user
|
||||||
getClient().perform(get("/api/config/submissionforms"))
|
getClient().perform(get("/api/config/submissionforms"))
|
||||||
|
//The status has to be 403 Not Authorized
|
||||||
|
.andExpect(status().isUnauthorized());
|
||||||
|
|
||||||
|
|
||||||
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
|
//When we call the root endpoint
|
||||||
|
getClient(token).perform(get("/api/config/submissionforms"))
|
||||||
//The status has to be 200 OK
|
//The status has to be 200 OK
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
//We expect the content type to be "application/hal+json;charset=UTF-8"
|
//We expect the content type to be "application/hal+json;charset=UTF-8"
|
||||||
@@ -51,7 +59,15 @@ public class SubmissionFormsControllerIT extends AbstractControllerIntegrationTe
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findTraditionalPageOne() throws Exception {
|
public void findTraditionalPageOne() throws Exception {
|
||||||
|
//When we call the root endpoint as anonymous user
|
||||||
getClient().perform(get("/api/config/submissionforms/traditionalpageone"))
|
getClient().perform(get("/api/config/submissionforms/traditionalpageone"))
|
||||||
|
//The status has to be 403 Not Authorized
|
||||||
|
.andExpect(status().isUnauthorized());
|
||||||
|
|
||||||
|
|
||||||
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
|
getClient(token).perform(get("/api/config/submissionforms/traditionalpageone"))
|
||||||
//The status has to be 200 OK
|
//The status has to be 200 OK
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
//We expect the content type to be "application/hal+json;charset=UTF-8"
|
//We expect the content type to be "application/hal+json;charset=UTF-8"
|
||||||
|
@@ -27,8 +27,16 @@ public class SubmissionSectionsControllerIT extends AbstractControllerIntegratio
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findAll() throws Exception {
|
public void findAll() throws Exception {
|
||||||
//When we call the root endpoint
|
//When we call the root endpoint as anonymous user
|
||||||
getClient().perform(get("/api/config/submissionsections"))
|
getClient().perform(get("/api/config/submissionsections"))
|
||||||
|
//The status has to be 403 Not Authorized
|
||||||
|
.andExpect(status().isUnauthorized());
|
||||||
|
|
||||||
|
|
||||||
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
|
//When we call the root endpoint
|
||||||
|
getClient(token).perform(get("/api/config/submissionsections"))
|
||||||
//The status has to be 200 OK
|
//The status has to be 200 OK
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
//We expect the content type to be "application/hal+json;charset=UTF-8"
|
//We expect the content type to be "application/hal+json;charset=UTF-8"
|
||||||
|
@@ -27,8 +27,16 @@ public class SubmissionUploadsControllerIT extends AbstractControllerIntegration
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findAll() throws Exception {
|
public void findAll() throws Exception {
|
||||||
//When we call the root endpoint
|
//When we call the root endpoint as anonymous user
|
||||||
getClient().perform(get("/api/config/submissionuploads"))
|
getClient().perform(get("/api/config/submissionuploads"))
|
||||||
|
//The status has to be 403 Not Authorized
|
||||||
|
.andExpect(status().isUnauthorized());
|
||||||
|
|
||||||
|
|
||||||
|
String token = getAuthToken(admin.getEmail(), password);
|
||||||
|
|
||||||
|
//When we call the root endpoint
|
||||||
|
getClient(token).perform(get("/api/config/submissionuploads"))
|
||||||
//The status has to be 200 OK
|
//The status has to be 200 OK
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
//We expect the content type to be "application/hal+json;charset=UTF-8"
|
//We expect the content type to be "application/hal+json;charset=UTF-8"
|
||||||
|
@@ -14,6 +14,7 @@ import org.dspace.content.service.DSpaceObjectService;
|
|||||||
import org.dspace.core.Context;
|
import org.dspace.core.Context;
|
||||||
import org.dspace.discovery.SearchServiceException;
|
import org.dspace.discovery.SearchServiceException;
|
||||||
import org.dspace.eperson.EPerson;
|
import org.dspace.eperson.EPerson;
|
||||||
|
import org.dspace.eperson.Group;
|
||||||
|
|
||||||
public class EPersonBuilder extends AbstractDSpaceObjectBuilder<EPerson> {
|
public class EPersonBuilder extends AbstractDSpaceObjectBuilder<EPerson> {
|
||||||
|
|
||||||
@@ -71,4 +72,15 @@ public class EPersonBuilder extends AbstractDSpaceObjectBuilder<EPerson> {
|
|||||||
ePerson.setEmail(name);
|
ePerson.setEmail(name);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public EPersonBuilder withGroupMembership(Group group) {
|
||||||
|
groupService.addMember(context, group, ePerson);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EPersonBuilder withPassword(final String password) {
|
||||||
|
ePerson.setCanLogIn(true);
|
||||||
|
ePersonService.setPassword(ePerson, password);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -67,7 +67,7 @@ public class ItemBuilder extends AbstractDSpaceObjectBuilder<Item> {
|
|||||||
return addMetadataValue(item, MetadataSchema.DC_SCHEMA, "subject", null, subject);
|
return addMetadataValue(item, MetadataSchema.DC_SCHEMA, "subject", null, subject);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemBuilder makePrivate() {
|
public ItemBuilder makeUnDiscoverable() {
|
||||||
item.setDiscoverable(false);
|
item.setDiscoverable(false);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@@ -29,7 +29,7 @@ public class EPersonMatcher {
|
|||||||
hasJsonPath("$.type", is("eperson")),
|
hasJsonPath("$.type", is("eperson")),
|
||||||
hasJsonPath("$.canLogIn", not(empty())),
|
hasJsonPath("$.canLogIn", not(empty())),
|
||||||
hasJsonPath("$._links.self.href", containsString("/api/eperson/epersons/" + ePerson.getID().toString())),
|
hasJsonPath("$._links.self.href", containsString("/api/eperson/epersons/" + ePerson.getID().toString())),
|
||||||
hasJsonPath("$.metadata", Matchers.containsInAnyOrder(
|
hasJsonPath("$.metadata", Matchers.hasItems(
|
||||||
EPersonMetadataMatcher.matchFirstName(ePerson.getFirstName()),
|
EPersonMetadataMatcher.matchFirstName(ePerson.getFirstName()),
|
||||||
EPersonMetadataMatcher.matchLastName(ePerson.getLastName())
|
EPersonMetadataMatcher.matchLastName(ePerson.getLastName())
|
||||||
))
|
))
|
||||||
@@ -37,9 +37,16 @@ public class EPersonMatcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static Matcher<? super Object> matchEPersonOnEmail(String email) {
|
||||||
|
return allOf(
|
||||||
|
hasJsonPath("$.type", is("eperson")),
|
||||||
|
hasJsonPath("$.email", is(email))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public static Matcher<? super Object> matchDefaultTestEPerson() {
|
public static Matcher<? super Object> matchDefaultTestEPerson() {
|
||||||
return allOf(
|
return allOf(
|
||||||
hasJsonPath("$.type", is("eperson"))
|
hasJsonPath("$.type", is("eperson"))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -31,4 +31,10 @@ public class EPersonMetadataMatcher {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Matcher<? super Object> matchLanguage(String language) {
|
||||||
|
return allOf(
|
||||||
|
hasJsonPath("$.key", is("eperson.language")),
|
||||||
|
hasJsonPath("$.value", is(language))
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -47,8 +47,7 @@ public class ItemMatcher {
|
|||||||
hasJsonPath("$._links.self.href", startsWith(REST_SERVER_URL)),
|
hasJsonPath("$._links.self.href", startsWith(REST_SERVER_URL)),
|
||||||
hasJsonPath("$._links.bitstreams.href", startsWith(REST_SERVER_URL)),
|
hasJsonPath("$._links.bitstreams.href", startsWith(REST_SERVER_URL)),
|
||||||
hasJsonPath("$._links.owningCollection.href", startsWith(REST_SERVER_URL)),
|
hasJsonPath("$._links.owningCollection.href", startsWith(REST_SERVER_URL)),
|
||||||
hasJsonPath("$._links.templateItemOf.href", startsWith(REST_SERVER_URL)),
|
hasJsonPath("$._links.templateItemOf.href", startsWith(REST_SERVER_URL))
|
||||||
hasJsonPath("$._links.self.href", startsWith(REST_SERVER_URL))
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -50,7 +50,7 @@ public class EPersonRestAuthenticationProviderTest {
|
|||||||
List<GrantedAuthority> authorities = ePersonRestAuthenticationProvider.getGrantedAuthorities(context, ePerson);
|
List<GrantedAuthority> authorities = ePersonRestAuthenticationProvider.getGrantedAuthorities(context, ePerson);
|
||||||
|
|
||||||
assertThat(authorities.stream().map(a -> a.getAuthority()).collect(Collectors.toList()), containsInAnyOrder(
|
assertThat(authorities.stream().map(a -> a.getAuthority()).collect(Collectors.toList()), containsInAnyOrder(
|
||||||
WebSecurityConfiguration.ADMIN_GRANT, WebSecurityConfiguration.EPERSON_GRANT));
|
WebSecurityConfiguration.ADMIN_GRANT, WebSecurityConfiguration.AUTHENTICATED_GRANT));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ public class EPersonRestAuthenticationProviderTest {
|
|||||||
List<GrantedAuthority> authorities = ePersonRestAuthenticationProvider.getGrantedAuthorities(context, ePerson);
|
List<GrantedAuthority> authorities = ePersonRestAuthenticationProvider.getGrantedAuthorities(context, ePerson);
|
||||||
|
|
||||||
assertThat(authorities.stream().map(a -> a.getAuthority()).collect(Collectors.toList()), containsInAnyOrder(
|
assertThat(authorities.stream().map(a -> a.getAuthority()).collect(Collectors.toList()), containsInAnyOrder(
|
||||||
WebSecurityConfiguration.EPERSON_GRANT));
|
WebSecurityConfiguration.AUTHENTICATED_GRANT));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -22,6 +22,7 @@ import org.apache.commons.io.Charsets;
|
|||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.dspace.app.rest.Application;
|
import org.dspace.app.rest.Application;
|
||||||
import org.dspace.app.rest.model.patch.Operation;
|
import org.dspace.app.rest.model.patch.Operation;
|
||||||
|
import org.dspace.app.rest.security.MethodSecurityConfig;
|
||||||
import org.dspace.app.rest.security.WebSecurityConfiguration;
|
import org.dspace.app.rest.security.WebSecurityConfiguration;
|
||||||
import org.dspace.app.rest.utils.ApplicationConfig;
|
import org.dspace.app.rest.utils.ApplicationConfig;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
@@ -54,7 +55,8 @@ import org.springframework.web.context.WebApplicationContext;
|
|||||||
* @author Tom Desair (tom dot desair at atmire dot com)
|
* @author Tom Desair (tom dot desair at atmire dot com)
|
||||||
*/
|
*/
|
||||||
@RunWith(SpringJUnit4ClassRunner.class)
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
@SpringBootTest(classes = {Application.class, ApplicationConfig.class, WebSecurityConfiguration.class})
|
@SpringBootTest(classes = {Application.class, ApplicationConfig.class, WebSecurityConfiguration.class,
|
||||||
|
MethodSecurityConfig.class})
|
||||||
@TestExecutionListeners( {DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class,
|
@TestExecutionListeners( {DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class,
|
||||||
TransactionalTestExecutionListener.class})
|
TransactionalTestExecutionListener.class})
|
||||||
@DirtiesContext
|
@DirtiesContext
|
||||||
@@ -62,7 +64,10 @@ import org.springframework.web.context.WebApplicationContext;
|
|||||||
public class AbstractControllerIntegrationTest extends AbstractIntegrationTestWithDatabase {
|
public class AbstractControllerIntegrationTest extends AbstractIntegrationTestWithDatabase {
|
||||||
|
|
||||||
protected static final String AUTHORIZATION_HEADER = "Authorization";
|
protected static final String AUTHORIZATION_HEADER = "Authorization";
|
||||||
protected static final String AUTHORIZATION_TYPE = "Bearer";
|
|
||||||
|
//The Authorization header contains a value like "Bearer TOKENVALUE". This constant string represents the part that
|
||||||
|
//sits before the actual authentication token and can be used to easily compose or parse the Authorization header.
|
||||||
|
protected static final String AUTHORIZATION_TYPE = "Bearer ";
|
||||||
|
|
||||||
public static final String REST_SERVER_URL = "http://localhost/api/";
|
public static final String REST_SERVER_URL = "http://localhost/api/";
|
||||||
|
|
||||||
@@ -105,7 +110,8 @@ public class AbstractControllerIntegrationTest extends AbstractIntegrationTestWi
|
|||||||
.addFilters(requestFilters.toArray(new Filter[requestFilters.size()]));
|
.addFilters(requestFilters.toArray(new Filter[requestFilters.size()]));
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(authToken)) {
|
if (StringUtils.isNotBlank(authToken)) {
|
||||||
mockMvcBuilder.defaultRequest(get("").header(AUTHORIZATION_HEADER, AUTHORIZATION_TYPE + " " + authToken));
|
mockMvcBuilder.defaultRequest(
|
||||||
|
get("").header(AUTHORIZATION_HEADER, AUTHORIZATION_TYPE + authToken));
|
||||||
}
|
}
|
||||||
|
|
||||||
return mockMvcBuilder
|
return mockMvcBuilder
|
||||||
@@ -120,7 +126,9 @@ public class AbstractControllerIntegrationTest extends AbstractIntegrationTestWi
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String getAuthToken(String user, String password) throws Exception {
|
public String getAuthToken(String user, String password) throws Exception {
|
||||||
return getAuthResponse(user, password).getHeader(AUTHORIZATION_HEADER);
|
return StringUtils.substringAfter(
|
||||||
|
getAuthResponse(user, password).getHeader(AUTHORIZATION_HEADER),
|
||||||
|
AUTHORIZATION_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPatchContent(List<Operation> ops) {
|
public String getPatchContent(List<Operation> ops) {
|
||||||
|
Reference in New Issue
Block a user