diff --git a/dspace-api/pom.xml b/dspace-api/pom.xml
index 6ac36d129ade..9cba7263632d 100644
--- a/dspace-api/pom.xml
+++ b/dspace-api/pom.xml
@@ -859,23 +859,6 @@
-
- io.findify
- s3mock_2.13
- 0.2.6
- test
-
-
- com.amazonawsl
- aws-java-sdk-s3
-
-
- com.amazonaws
- aws-java-sdk-s3
-
-
-
-
diff --git a/dspace-api/src/main/java/org/dspace/authorize/AuthorizationBitstreamUtils.java b/dspace-api/src/main/java/org/dspace/authorize/AuthorizationBitstreamUtils.java
index 1b98556ecad0..0f7dc8eaa285 100644
--- a/dspace-api/src/main/java/org/dspace/authorize/AuthorizationBitstreamUtils.java
+++ b/dspace-api/src/main/java/org/dspace/authorize/AuthorizationBitstreamUtils.java
@@ -7,6 +7,8 @@
*/
package org.dspace.authorize;
+import static org.dspace.content.clarin.ClarinLicense.Confirmation;
+
import java.sql.SQLException;
import java.util.List;
import java.util.Objects;
@@ -117,10 +119,10 @@ public boolean authorizeLicenseWithUser(Context context, UUID bitstreamID) throw
// Bitstream should have only one type of the Clarin license, so we could get first record
ClarinLicense clarinLicense = Objects.requireNonNull(clarinLicenseResourceMappings.get(0)).getLicense();
- // 3 - Allow download for anonymous users, but with license confirmation
- // 0 - License confirmation is not required
- if (Objects.equals(clarinLicense.getConfirmation(), 3) ||
- Objects.equals(clarinLicense.getConfirmation(), 0)) {
+ // ALLOW_ANONYMOUS - Allow download for anonymous users, but with license confirmation
+ // NOT_REQUIRED - License confirmation is not required
+ if ((clarinLicense.getConfirmation() == Confirmation.ALLOW_ANONYMOUS) ||
+ (clarinLicense.getConfirmation() == Confirmation.NOT_REQUIRED)) {
return true;
}
return false;
diff --git a/dspace-api/src/main/java/org/dspace/content/clarin/ClarinLicense.java b/dspace-api/src/main/java/org/dspace/content/clarin/ClarinLicense.java
index 71500d00ecad..bc592507d538 100644
--- a/dspace-api/src/main/java/org/dspace/content/clarin/ClarinLicense.java
+++ b/dspace-api/src/main/java/org/dspace/content/clarin/ClarinLicense.java
@@ -16,6 +16,8 @@
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
@@ -83,7 +85,8 @@ public class ClarinLicense implements ReloadableEntity {
private String definition = null;
@Column(name = "confirmation")
- private Integer confirmation = 0;
+ @Enumerated(EnumType.ORDINAL)
+ private Confirmation confirmation = Confirmation.NOT_REQUIRED;
@Column(name = "required_info")
private String requiredInfo = null;
@@ -111,11 +114,11 @@ public void setDefinition(String definition) {
this.definition = definition;
}
- public Integer getConfirmation() {
- return confirmation;
+ public Confirmation getConfirmation() {
+ return confirmation == null ? Confirmation.NOT_REQUIRED : confirmation;
}
- public void setConfirmation(Integer confirmation) {
+ public void setConfirmation(Confirmation confirmation) {
this.confirmation = confirmation;
}
@@ -191,4 +194,29 @@ public ClarinUserRegistration getEperson() {
public void setEperson(ClarinUserRegistration eperson) {
this.eperson = eperson;
}
+
+ public enum Confirmation {
+
+ // if new Confirmation value is needed, add it to the end of this list, to not break the backward compatibility
+ NOT_REQUIRED(0), ASK_ONLY_ONCE(1), ASK_ALWAYS(2), ALLOW_ANONYMOUS(3);
+
+ private final int value;
+
+ Confirmation(int value) {
+ this.value = value;
+ }
+
+ public int getValue() {
+ return value;
+ }
+
+ public static Confirmation getConfirmation(int value) {
+ return Arrays.stream(values())
+ .filter(v -> (v.getValue() == value))
+ .findFirst()
+ .orElseThrow(() ->
+ new IllegalArgumentException("No license confirmation found for value: " + value));
+ }
+
+ }
}
diff --git a/dspace-api/src/main/java/org/dspace/content/clarin/ClarinLicenseResourceMappingServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/clarin/ClarinLicenseResourceMappingServiceImpl.java
index 82c8b2839bd5..bc5d1884564e 100644
--- a/dspace-api/src/main/java/org/dspace/content/clarin/ClarinLicenseResourceMappingServiceImpl.java
+++ b/dspace-api/src/main/java/org/dspace/content/clarin/ClarinLicenseResourceMappingServiceImpl.java
@@ -7,6 +7,8 @@
*/
package org.dspace.content.clarin;
+import static org.dspace.content.clarin.ClarinLicense.Confirmation;
+
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
@@ -203,23 +205,23 @@ public ClarinLicense getLicenseToAgree(Context context, UUID userId, UUID resour
}
// Confirmation states:
- // 0 - Not required
- // 1 - Ask only once
- // 2 - Ask always
- // 3 - Allow anonymous
- if (Objects.equals(clarinLicenseToAgree.getConfirmation(), 0)) {
+ // NOT_REQUIRED
+ // ASK_ONLY_ONCE
+ // ASK_ALWAYS
+ // ALLOW_ANONYMOUS
+ if (clarinLicenseToAgree.getConfirmation() == Confirmation.NOT_REQUIRED) {
return null;
}
switch (clarinLicenseToAgree.getConfirmation()) {
- case 1:
+ case ASK_ONLY_ONCE:
// Ask only once - check if the clarin license required info is filled in by the user
if (userFilledInRequiredInfo(context, clarinLicenseResourceMapping, userId)) {
return null;
}
return clarinLicenseToAgree;
- case 2:
- case 3:
+ case ASK_ALWAYS:
+ case ALLOW_ANONYMOUS:
return clarinLicenseToAgree;
default:
return null;
diff --git a/dspace-api/src/main/java/org/dspace/handle/HandleClarinServiceImpl.java b/dspace-api/src/main/java/org/dspace/handle/HandleClarinServiceImpl.java
index 8aaae6d8bd5d..126e7e6e7bf0 100644
--- a/dspace-api/src/main/java/org/dspace/handle/HandleClarinServiceImpl.java
+++ b/dspace-api/src/main/java/org/dspace/handle/HandleClarinServiceImpl.java
@@ -337,6 +337,11 @@ public DSpaceObject resolveToObject(Context context, String handle) throws Illeg
+ Constants.typeText[handleTypeId]);
}
+ @Override
+ public int count(Context context) throws SQLException {
+ return handleDAO.countRows(context);
+ }
+
/**
* Create id for handle object.
*
@@ -457,6 +462,21 @@ public Handle createHandle(Context context, String handleStr) throws SQLExceptio
return handle;
}
+ @Override
+ public Handle findByHandleAndMagicToken(Context context, String handle, String token) throws SQLException {
+ Handle h = findByHandle(context, handle);
+ if (Objects.isNull(h) || Objects.isNull(h.getUrl()) || !h.getUrl().contains(MAGIC_BEAN)) {
+ return null;
+ }
+ org.dspace.handle.external.Handle magicHandle =
+ new org.dspace.handle.external.Handle(h.getHandle(), h.getUrl());
+ if (magicHandle.token.equals(token)) {
+ return h;
+ } else {
+ return null;
+ }
+ }
+
/**
* Strips the part identifier from the handle
*
diff --git a/dspace-api/src/main/java/org/dspace/handle/external/Handle.java b/dspace-api/src/main/java/org/dspace/handle/external/Handle.java
index 5f34012b7173..e4ff31cdcc71 100644
--- a/dspace-api/src/main/java/org/dspace/handle/external/Handle.java
+++ b/dspace-api/src/main/java/org/dspace/handle/external/Handle.java
@@ -87,20 +87,20 @@ public Handle(String handle, String magicURL) {
}
/**
- * From the attributes generate the url with `@magicLindat` string
+ * Generate new token and combine the properties into the url with `@magicLindat` string
* @return url with the `@magicLindat` string
*/
- public String getMagicUrl() {
- return this.getMagicUrl(this.title, this.submitdate, this.reportemail, this.datasetName, this.datasetVersion,
+ public String generateMagicUrl() {
+ return generateMagicUrl(this.title, this.submitdate, this.reportemail, this.datasetName, this.datasetVersion,
this.query, this.url);
}
/**
- * From the attributes generate the url with `@magicLindat` string
+ * Generate new token and combine the params into the url with `@magicLindat` string
* @return url with the `@magicLindat` string
*/
- public String getMagicUrl(String title, String submitdate, String reportemail, String datasetName,
- String datasetVersion, String query, String url) {
+ private static String generateMagicUrl(String title, String submitdate, String reportemail, String datasetName,
+ String datasetVersion, String query, String url) {
String magicURL = "";
String token = UUID.randomUUID().toString();
String[] magicURLProps = new String[] {title, HandlePlugin.getRepositoryName(), submitdate, reportemail,
diff --git a/dspace-api/src/main/java/org/dspace/handle/service/HandleClarinService.java b/dspace-api/src/main/java/org/dspace/handle/service/HandleClarinService.java
index 3cc4fb60f46e..ab0ffac99b34 100644
--- a/dspace-api/src/main/java/org/dspace/handle/service/HandleClarinService.java
+++ b/dspace-api/src/main/java/org/dspace/handle/service/HandleClarinService.java
@@ -156,6 +156,14 @@ public void update(Context context, Handle handleObject, String newHandle,
*/
public DSpaceObject resolveToObject(Context context, String handle) throws IllegalStateException, SQLException;
+ /**
+ * Return the number of entries in the handle table.
+ * @param context
+ * @return number of rows in the handle table
+ * @throws SQLException
+ */
+ int count(Context context) throws SQLException;
+
/**
* Create the external handles from the list of handles with magic URL
*
@@ -226,4 +234,15 @@ public void update(Context context, Handle handleObject, String newHandle,
* @throws AuthorizeException if authorization error
*/
public Handle createHandle(Context context, String handle) throws SQLException, AuthorizeException;
+
+ /**
+ * Returns a handle entity matching the provided `prefix/suffix` but only when the "magic url"
+ * contains the provided token.
+ * @param context
+ * @param handle prefix/suffix
+ * @param token the automatically generated part of the magic URL
+ * @return Handle entity or null (if the handle is not found or the "magic url" does not contain the provided token)
+ * @throws SQLException
+ */
+ Handle findByHandleAndMagicToken(Context context, String handle, String token) throws SQLException;
}
diff --git a/dspace-api/src/test/java/org/dspace/content/BundleClarinTest.java b/dspace-api/src/test/java/org/dspace/content/BundleClarinTest.java
index eedbd2db715e..36ddfafa1679 100644
--- a/dspace-api/src/test/java/org/dspace/content/BundleClarinTest.java
+++ b/dspace-api/src/test/java/org/dspace/content/BundleClarinTest.java
@@ -7,6 +7,7 @@
*/
package org.dspace.content;
+import static org.dspace.content.clarin.ClarinLicense.Confirmation;
import static org.dspace.core.Constants.CONTENT_BUNDLE_NAME;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.instanceOf;
@@ -119,7 +120,7 @@ public void init() {
this.clarinLicense.setLicenseLabels(cllSet);
this.clarinLicense.setName(LICENSE_NAME);
this.clarinLicense.setDefinition(LICENSE_URI);
- this.clarinLicense.setConfirmation(0);
+ this.clarinLicense.setConfirmation(Confirmation.NOT_REQUIRED);
this.clarinLicenseService.update(context, this.clarinLicense);
// initialize second clarin license and clarin license label
@@ -139,7 +140,7 @@ public void init() {
this.secondClarinLicense.setLicenseLabels(secondCllSet);
this.secondClarinLicense.setName("wrong name");
this.secondClarinLicense.setDefinition("wrong uri");
- this.secondClarinLicense.setConfirmation(0);
+ this.secondClarinLicense.setConfirmation(Confirmation.NOT_REQUIRED);
this.clarinLicenseService.update(context, this.secondClarinLicense);
//we need to commit the changes, so we don't block the table for testing
diff --git a/dspace-server-webapp/pom.xml b/dspace-server-webapp/pom.xml
index d6442a57174a..d55c28030ca6 100644
--- a/dspace-server-webapp/pom.xml
+++ b/dspace-server-webapp/pom.xml
@@ -290,12 +290,6 @@
${spring-boot.version}
-
- org.springframework.boot
- spring-boot-starter-actuator
- ${spring-boot.version}
-
-
com.flipkart.zjsonpatch
zjsonpatch
diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/ItemAddBundleController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/ItemAddBundleController.java
index 74f28bbfd19c..5b1a2fdaa520 100644
--- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/ItemAddBundleController.java
+++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/ItemAddBundleController.java
@@ -16,11 +16,11 @@
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import javax.ws.rs.BadRequestException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.dspace.app.rest.converter.ConverterService;
import org.dspace.app.rest.converter.MetadataConverter;
+import org.dspace.app.rest.exception.DSpaceBadRequestException;
import org.dspace.app.rest.exception.UnprocessableEntityException;
import org.dspace.app.rest.model.BundleRest;
import org.dspace.app.rest.model.ItemRest;
@@ -156,7 +156,7 @@ public ItemRest updateLicenseForBundle(@PathVariable UUID uuid,
throws SQLException, AuthorizeException {
Context context = ContextUtil.obtainContext(request);
if (Objects.isNull(context)) {
- throw new BadRequestException("No context found for current user");
+ throw new DSpaceBadRequestException("No context found for current user");
}
Item item = itemService.find(context, uuid);
diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ClarinLicenseConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ClarinLicenseConverter.java
index 87abebaa2b15..77325827bb1f 100644
--- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ClarinLicenseConverter.java
+++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/ClarinLicenseConverter.java
@@ -41,7 +41,7 @@ public ClarinLicenseRest convert(ClarinLicense modelObject, Projection projectio
license.setProjection(projection);
license.setId(modelObject.getID());
license.setName(modelObject.getName());
- license.setConfirmation(modelObject.getConfirmation());
+ license.setConfirmation(modelObject.getConfirmation().getValue());
license.setDefinition(modelObject.getDefinition());
license.setRequiredInfo(modelObject.getRequiredInfo());
setExtendedClarinLicenseLabels(license, modelObject.getLicenseLabels(), projection);
diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/exception/DSpaceApiExceptionControllerAdvice.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/exception/DSpaceApiExceptionControllerAdvice.java
index 8640f64a7f8d..4833cb938317 100644
--- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/exception/DSpaceApiExceptionControllerAdvice.java
+++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/exception/DSpaceApiExceptionControllerAdvice.java
@@ -246,24 +246,67 @@ protected void handleGenericException(HttpServletRequest request, HttpServletRes
} else {
returnCode = HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
}
- sendErrorResponse(request, response, ex, "An exception has occurred", returnCode);
+ if ((HttpStatus.valueOf(returnCode).is4xxClientError())) {
+ sendErrorResponseFromException(request, response, ex, returnCode);
+ } else {
+ sendErrorResponse(request, response, ex, "An exception has occurred", returnCode);
+ }
}
+ /**
+ * Send the error to the response. The error message is taken from exception message.
+ * This method is mainly appropriate for 4xx errors,
+ * where the exception message should be exposed to REST API clients in response body.
+ * This method also logs the ERROR log, containing the first line from the exception stack trace.
+ * Specific errors where an ERROR log with full stack trace is more appropriate are configured
+ * using property {@code logging.server.include-stacktrace-for-httpcode}
+ * (see {@link DSpaceApiExceptionControllerAdvice#P_LOG_AS_ERROR}
+ * and {@link DSpaceApiExceptionControllerAdvice#LOG_AS_ERROR_DEFAULT}).
+ *
+ * @param request current request
+ * @param response current response
+ * @param ex Exception causing the error response
+ * @param statusCode status code to send in response
+ */
+ private void sendErrorResponseFromException(final HttpServletRequest request,
+ final HttpServletResponse response,
+ final Exception ex,
+ final int statusCode)
+ throws IOException {
+ //Make sure Spring picks up this exception
+ request.setAttribute(EXCEPTION_ATTRIBUTE, ex);
+
+ final Set statusCodesLoggedAsErrors = getStatusCodesLoggedAsErrors();
+
+ String message = ex.getMessage();
+ if (statusCodesLoggedAsErrors.contains(statusCode)) {
+ log.error("{} (status:{})", message, statusCode, ex);
+ } else {
+ // Log the error as a single-line WARN
+ StackTraceElement[] trace = ex.getStackTrace();
+ String location = trace.length <= 0 ? "unknown" : trace[0].toString();
+ log.warn("{} (status:{} exception: {} at: {})",
+ message, statusCode, ex.getClass().getName(), location);
+ }
+
+ response.sendError(statusCode, message);
+ }
+
/**
* Send the error to the response.
* 5xx errors will be logged as ERROR with a full stack trace. 4xx errors
* will be logged as WARN without a stack trace. Specific 4xx errors where
* an ERROR log with full stack trace is more appropriate are configured
* using property {@code logging.server.include-stacktrace-for-httpcode}
- * (see {@link P_LOG_AS_ERROR} and {@link LOG_AS_ERROR_DEFAULT}).
+ * (see {@link DSpaceApiExceptionControllerAdvice#P_LOG_AS_ERROR}
+ * and {@link DSpaceApiExceptionControllerAdvice#LOG_AS_ERROR_DEFAULT}).
*
* @param request current request
* @param response current response
* @param ex Exception thrown
* @param message message to log or send in response
* @param statusCode status code to send in response
- * @throws IOException
*/
private void sendErrorResponse(final HttpServletRequest request,
final HttpServletResponse response,
@@ -272,18 +315,7 @@ private void sendErrorResponse(final HttpServletRequest request,
//Make sure Spring picks up this exception
request.setAttribute(EXCEPTION_ATTRIBUTE, ex);
- // Which status codes should be treated as ERROR?
- final Set LOG_AS_ERROR = new HashSet<>();
- String[] error_codes = configurationService.getArrayProperty(
- P_LOG_AS_ERROR, LOG_AS_ERROR_DEFAULT);
- for (String code : error_codes) {
- try {
- LOG_AS_ERROR.add(Integer.valueOf(code));
- } catch (NumberFormatException e) {
- log.warn("Non-integer HTTP status code {} in {}", code, P_LOG_AS_ERROR);
- // And continue
- }
- }
+ final Set LOG_AS_ERROR = getStatusCodesLoggedAsErrors();
// We don't want to fill logs with bad/invalid REST API requests.
if (HttpStatus.valueOf(statusCode).is5xxServerError() || LOG_AS_ERROR.contains(statusCode)) {
@@ -309,4 +341,24 @@ private void sendErrorResponse(final HttpServletRequest request,
response.sendError(statusCode, message);
}
+ /**
+ * Get set of status codes that should be treated as errors.
+ *
+ * @return set of status codes that should be treated as errors
+ */
+ private Set getStatusCodesLoggedAsErrors() {
+ final Set statusCodesLoggedAsErrors = new HashSet<>();
+ String[] error_codes = configurationService.getArrayProperty(
+ P_LOG_AS_ERROR, LOG_AS_ERROR_DEFAULT);
+ for (String code : error_codes) {
+ try {
+ statusCodesLoggedAsErrors.add(Integer.valueOf(code));
+ } catch (NumberFormatException e) {
+ log.warn("Non-integer HTTP status code {} in {}", code, P_LOG_AS_ERROR);
+ // And continue
+ }
+ }
+ return statusCodesLoggedAsErrors;
+ }
+
}
diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClarinLicenseRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClarinLicenseRestRepository.java
index 2ef00709a512..0ad207114168 100644
--- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClarinLicenseRestRepository.java
+++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClarinLicenseRestRepository.java
@@ -8,6 +8,7 @@
package org.dspace.app.rest.repository;
import static org.apache.commons.lang3.StringUtils.isBlank;
+import static org.dspace.content.clarin.ClarinLicense.Confirmation;
import java.io.IOException;
import java.sql.SQLException;
@@ -25,6 +26,7 @@
import org.dspace.app.rest.Parameter;
import org.dspace.app.rest.SearchRestMethod;
import org.dspace.app.rest.exception.DSpaceBadRequestException;
+import org.dspace.app.rest.exception.PaginationException;
import org.dspace.app.rest.exception.UnprocessableEntityException;
import org.dspace.app.rest.model.ClarinLicenseLabelRest;
import org.dspace.app.rest.model.ClarinLicenseRest;
@@ -43,6 +45,7 @@
import org.dspace.core.Context;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.rest.webmvc.ResourceNotFoundException;
import org.springframework.security.access.prepost.PreAuthorize;
@@ -103,33 +106,44 @@ public Page findByName(@Parameter(value = "name", required =
throw new RuntimeException(e.getMessage(), e);
}
clarinLicenseList.add(clarinLicense);
- return converter.toRestPage(clarinLicenseList, pageable, utils.obtainProjection());
+ try {
+ return converter.toRestPage(clarinLicenseList, pageable, utils.obtainProjection());
+ } catch (PaginationException pe) {
+ return getEmptyPageForIncorrectPageable(pageable, clarinLicenseList.size());
+ }
}
@SearchRestMethod(name = "byNameLike")
public Page findByNameLike(@Parameter(value = "name", required = true) String name,
- Pageable pageable) {
- List clarinLicenseList;
+ Pageable pageable) {
+ List clarinLicenseList = new ArrayList<>();
try {
Context context = obtainContext();
- clarinLicenseList = clarinLicenseService.findByNameLike(context, name);
- if (CollectionUtils.isEmpty(clarinLicenseList)) {
+ clarinLicenseList.addAll(clarinLicenseService.findByNameLike(context, name));
+ if (clarinLicenseList.isEmpty()) {
return null;
}
} catch (SQLException e) {
throw new RuntimeException(e.getMessage(), e);
}
- return converter.toRestPage(clarinLicenseList, pageable, utils.obtainProjection());
+ try {
+ return converter.toRestPage(clarinLicenseList, pageable, utils.obtainProjection());
+ } catch (PaginationException pe) {
+ return getEmptyPageForIncorrectPageable(pageable, clarinLicenseList.size());
+ }
}
@Override
@PreAuthorize("permitAll()")
public Page findAll(Context context, Pageable pageable) {
+ List clarinLicenseList = new ArrayList<>();
try {
- List clarinLicenseList = clarinLicenseService.findAll(context);
+ clarinLicenseList.addAll(clarinLicenseService.findAll(context));
return converter.toRestPage(clarinLicenseList, pageable, utils.obtainProjection());
} catch (SQLException | AuthorizeException e) {
throw new RuntimeException(e.getMessage(), e);
+ } catch (PaginationException pe) {
+ return getEmptyPageForIncorrectPageable(pageable, clarinLicenseList.size());
}
}
@@ -172,7 +186,7 @@ protected ClarinLicenseRest createAndReturn(Context context)
clarinLicense.setLicenseLabels(this.getClarinLicenseLabels(clarinLicenseRest.getClarinLicenseLabel(),
clarinLicenseRest.getExtendedClarinLicenseLabels()));
clarinLicense.setDefinition(clarinLicenseRest.getDefinition());
- clarinLicense.setConfirmation(clarinLicenseRest.getConfirmation());
+ clarinLicense.setConfirmation(Confirmation.getConfirmation(clarinLicenseRest.getConfirmation()));
clarinLicense.setRequiredInfo(clarinLicenseRest.getRequiredInfo());
clarinLicense.setEperson(userRegistration);
@@ -220,7 +234,7 @@ protected ClarinLicenseRest put(Context context, HttpServletRequest request, Str
clarinLicense.setName(clarinLicenseRest.getName());
clarinLicense.setRequiredInfo(clarinLicenseRest.getRequiredInfo());
clarinLicense.setDefinition(clarinLicenseRest.getDefinition());
- clarinLicense.setConfirmation(clarinLicenseRest.getConfirmation());
+ clarinLicense.setConfirmation(Confirmation.getConfirmation(clarinLicenseRest.getConfirmation()));
clarinLicense.setLicenseLabels(this.getClarinLicenseLabels(clarinLicenseRest.getClarinLicenseLabel(),
clarinLicenseRest.getExtendedClarinLicenseLabels()));
@@ -273,4 +287,8 @@ private ClarinLicenseLabel getClarinLicenseLabelFromRest(ClarinLicenseLabelRest
return clarinLicenseLabel;
}
+ private Page getEmptyPageForIncorrectPageable(Pageable pageable, int totalElements) {
+ return new PageImpl<>(List.of(), pageable, totalElements);
+ }
+
}
diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClarinUserMetadataRestController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClarinUserMetadataRestController.java
index 3f217345cdb0..e6657769bde8 100644
--- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClarinUserMetadataRestController.java
+++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ClarinUserMetadataRestController.java
@@ -9,6 +9,7 @@
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import static org.dspace.app.rest.utils.ContextUtil.obtainContext;
+import static org.dspace.content.clarin.ClarinLicense.Confirmation;
import static org.dspace.content.clarin.ClarinLicense.EXTRA_EMAIL;
import static org.dspace.content.clarin.ClarinLicense.SEND_TOKEN;
import static org.dspace.content.clarin.ClarinUserRegistration.ANONYMOUS_USER_REGISTRATION;
@@ -25,12 +26,12 @@
import java.util.UUID;
import javax.mail.MessagingException;
import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.BadRequestException;
import javax.ws.rs.NotFoundException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
+import org.dspace.app.rest.exception.DSpaceBadRequestException;
import org.dspace.app.rest.model.BitstreamRest;
import org.dspace.app.rest.model.ClarinUserMetadataRest;
import org.dspace.app.rest.model.ItemRest;
@@ -219,6 +220,11 @@ public ResponseEntity manageUserMetadata(@RequestParam("bitstreamUUID") UUID bit
" and the bitstream");
}
+ ClarinLicense clarinLicense = this.getClarinLicense(clarinLicenseResourceMapping);
+ if (Objects.isNull(currentUser) && (clarinLicense.getConfirmation() != Confirmation.ALLOW_ANONYMOUS)) {
+ throw new AuthorizeException("Anonymous user is not allowed to get access token");
+ }
+
// Get ClarinUserMetadataRest Array from the request body
ClarinUserMetadataRest[] clarinUserMetadataRestArray =
new ObjectMapper().readValue(request.getInputStream(), ClarinUserMetadataRest[].class);
@@ -246,7 +252,6 @@ public ResponseEntity manageUserMetadata(@RequestParam("bitstreamUUID") UUID bit
// If yes - send token to e-mail
try {
String email = getEmailFromUserMetadata(clarinUserMetadataRestList);
- ClarinLicense clarinLicense = this.getClarinLicense(clarinLicenseResourceMapping);
this.sendEmailWithDownloadLink(context, bitstream, clarinLicense,
email, downloadToken, MailType.BITSTREAM, clarinUserMetadataRestList);
} catch (MessagingException e) {
@@ -270,12 +275,13 @@ private void sendEmailWithDownloadLink(Context context, DSpaceObject dso,
throws IOException, SQLException, MessagingException {
if (StringUtils.isBlank(email)) {
log.error("Cannot send email with download link because the email is empty.");
- throw new BadRequestException("Cannot send email with download link because the email is empty.");
+ throw new DSpaceBadRequestException("Cannot send email with download link because the email is empty.");
}
if (Objects.isNull(dso)) {
log.error("Cannot send email with download link because the DSpaceObject is null.");
- throw new BadRequestException("Cannot send email with download link because the DSpaceObject is null.");
+ throw new DSpaceBadRequestException(
+ "Cannot send email with download link because the DSpaceObject is null.");
}
// Fetch DSpace main cfg info and send it in the email
@@ -547,10 +553,6 @@ public ClarinLicenseResourceMapping getLicenseResourceMapping(Context context, U
}
private ClarinLicense getClarinLicense(ClarinLicenseResourceMapping clarinLicenseResourceMapping) {
- if (Objects.isNull(clarinLicenseResourceMapping)) {
- throw new NullPointerException("The clarinLicenseResourceMapping object is null.");
- }
-
// Get ClarinLicense from the ClarinLicenseResourceMapping
ClarinLicense clarinLicense = clarinLicenseResourceMapping.getLicense();
if (Objects.isNull(clarinLicense)) {
@@ -562,9 +564,6 @@ private ClarinLicense getClarinLicense(ClarinLicenseResourceMapping clarinLicens
private boolean shouldEmailToken(ClarinLicenseResourceMapping clarinLicenseResourceMapping) {
ClarinLicense clarinLicense = this.getClarinLicense(clarinLicenseResourceMapping);
- if (Objects.isNull(clarinLicense)) {
- throw new NullPointerException("The ClarinLicense is null.");
- }
// If the required info contains the key work `SEND_TOKEN` it should generate the token.
if (StringUtils.isBlank(clarinLicense.getRequiredInfo())) {
diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ExternalHandleRestRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ExternalHandleRestRepository.java
index df89e4214bb6..5330f49e43bc 100644
--- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ExternalHandleRestRepository.java
+++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/ExternalHandleRestRepository.java
@@ -18,12 +18,10 @@
import java.util.Date;
import java.util.List;
import java.util.Objects;
-import javax.persistence.PersistenceException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.core.MediaType;
-import org.apache.commons.lang.RandomStringUtils;
import org.dspace.app.rest.utils.ContextUtil;
import org.dspace.authorize.AuthorizeException;
import org.dspace.content.DCDate;
@@ -34,7 +32,8 @@
import org.dspace.handle.service.HandleClarinService;
import org.dspace.handle.service.HandleService;
import org.dspace.services.ConfigurationService;
-import org.postgresql.util.PSQLException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
@@ -50,6 +49,8 @@
@RequestMapping("/api/services")
public class ExternalHandleRestRepository {
+ private static final Logger log = LoggerFactory.getLogger(ExternalHandleRestRepository.class);
+
private final String EXTERNAL_HANDLE_ENDPOINT_FIND_ALL = "handles/magic";
private final String EXTERNAL_HANDLE_ENDPOINT_SHORTEN = "handles";
private final String EXTERNAL_HANDLE_ENDPOINT_UPDATE = "handles";
@@ -65,6 +66,9 @@ public class ExternalHandleRestRepository {
@Autowired
private ConfigurationService configurationService;
+ @Autowired
+ private RandomStringGenerator randomStringGenerator;
+
/**
* Get all Handles with url which contains the `@magicLindat` string then convert them to the `external/Handle`
* and return in the List.
@@ -108,11 +112,11 @@ public ResponseEntity