mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-07 01:54:22 +00:00
Merge branch 'main' into DURACOM-127
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* 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.importer.external.crossref;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dspace.importer.external.metadatamapping.contributor.JsonPathMetadataProcessor;
|
||||
import org.joda.time.LocalDate;
|
||||
|
||||
/**
|
||||
* This class is used for CrossRef's Live-Import to extract
|
||||
* issued attribute.
|
||||
* Beans are configured in the crossref-integration.xml file.
|
||||
*
|
||||
* @author Francesco Pio Scognamiglio (francescopio.scognamiglio at 4science.com)
|
||||
*/
|
||||
public class CrossRefDateMetadataProcessor implements JsonPathMetadataProcessor {
|
||||
|
||||
private final static Logger log = LogManager.getLogger();
|
||||
|
||||
private String pathToArray;
|
||||
|
||||
@Override
|
||||
public Collection<String> processMetadata(String json) {
|
||||
JsonNode rootNode = convertStringJsonToJsonNode(json);
|
||||
Iterator<JsonNode> dates = rootNode.at(pathToArray).iterator();
|
||||
Collection<String> values = new ArrayList<>();
|
||||
while (dates.hasNext()) {
|
||||
JsonNode date = dates.next();
|
||||
LocalDate issuedDate = null;
|
||||
SimpleDateFormat issuedDateFormat = null;
|
||||
if (date.has(0) && date.has(1) && date.has(2)) {
|
||||
issuedDate = new LocalDate(
|
||||
date.get(0).numberValue().intValue(),
|
||||
date.get(1).numberValue().intValue(),
|
||||
date.get(2).numberValue().intValue());
|
||||
issuedDateFormat = new SimpleDateFormat("yyyy-MM-dd");
|
||||
} else if (date.has(0) && date.has(1)) {
|
||||
issuedDate = new LocalDate().withYear(date.get(0).numberValue().intValue())
|
||||
.withMonthOfYear(date.get(1).numberValue().intValue());
|
||||
issuedDateFormat = new SimpleDateFormat("yyyy-MM");
|
||||
} else if (date.has(0)) {
|
||||
issuedDate = new LocalDate().withYear(date.get(0).numberValue().intValue());
|
||||
issuedDateFormat = new SimpleDateFormat("yyyy");
|
||||
}
|
||||
values.add(issuedDateFormat.format(issuedDate.toDate()));
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
private JsonNode convertStringJsonToJsonNode(String json) {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
JsonNode body = null;
|
||||
try {
|
||||
body = mapper.readTree(json);
|
||||
} catch (JsonProcessingException e) {
|
||||
log.error("Unable to process json response.", e);
|
||||
}
|
||||
return body;
|
||||
}
|
||||
|
||||
public void setPathToArray(String pathToArray) {
|
||||
this.pathToArray = pathToArray;
|
||||
}
|
||||
|
||||
}
|
@@ -120,7 +120,7 @@ public class ItemTemplateRestController {
|
||||
* @throws SQLException
|
||||
* @throws AuthorizeException
|
||||
*/
|
||||
@PreAuthorize("hasPermission(#uuid, 'ITEM', 'WRITE')")
|
||||
@PreAuthorize("hasPermission(#uuid, 'ITEMTEMPLATE', 'WRITE')")
|
||||
@RequestMapping(method = RequestMethod.PATCH)
|
||||
public ResponseEntity<RepresentationModel<?>> patch(HttpServletRequest request, @PathVariable UUID uuid,
|
||||
@RequestBody(required = true) JsonNode jsonNode)
|
||||
@@ -153,7 +153,7 @@ public class ItemTemplateRestController {
|
||||
* @throws AuthorizeException
|
||||
* @throws IOException
|
||||
*/
|
||||
@PreAuthorize("hasPermission(#uuid, 'ITEM', 'DELETE')")
|
||||
@PreAuthorize("hasPermission(#uuid, 'ITEMTEMPLATE', 'DELETE')")
|
||||
@RequestMapping(method = RequestMethod.DELETE)
|
||||
public ResponseEntity<RepresentationModel<?>> deleteTemplateItem(HttpServletRequest request,
|
||||
@PathVariable UUID uuid)
|
||||
|
@@ -0,0 +1,83 @@
|
||||
/**
|
||||
* 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.apache.commons.lang3.StringUtils;
|
||||
import org.dspace.app.rest.model.TemplateItemRest;
|
||||
import org.dspace.app.rest.utils.ContextUtil;
|
||||
import org.dspace.authorize.service.AuthorizeService;
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.content.service.ItemService;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.eperson.EPerson;
|
||||
import org.dspace.services.RequestService;
|
||||
import org.dspace.services.model.Request;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* {@link RestObjectPermissionEvaluatorPlugin} class that evaluate WRITE and DELETE permission over a TemplateItem
|
||||
*
|
||||
* @author Bui Thai Hai (thaihai.bui@dlcorp.com.vn)
|
||||
*/
|
||||
@Component
|
||||
public class TemplateItemRestPermissionEvaluatorPlugin extends RestObjectPermissionEvaluatorPlugin {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(TemplateItemRestPermissionEvaluatorPlugin.class);
|
||||
|
||||
@Autowired
|
||||
private RequestService requestService;
|
||||
|
||||
@Autowired
|
||||
ItemService its;
|
||||
|
||||
@Autowired
|
||||
private AuthorizeService authorizeService;
|
||||
|
||||
@Override
|
||||
public boolean hasDSpacePermission(Authentication authentication, Serializable targetId, String targetType,
|
||||
DSpaceRestPermission permission) {
|
||||
|
||||
DSpaceRestPermission restPermission = DSpaceRestPermission.convert(permission);
|
||||
if (!DSpaceRestPermission.WRITE.equals(restPermission) &&
|
||||
!DSpaceRestPermission.DELETE.equals(restPermission)) {
|
||||
return false;
|
||||
}
|
||||
if (!StringUtils.equalsIgnoreCase(targetType, TemplateItemRest.NAME)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Request request = requestService.getCurrentRequest();
|
||||
Context context = ContextUtil.obtainContext(request.getHttpServletRequest());
|
||||
|
||||
EPerson ePerson = context.getCurrentUser();
|
||||
if (ePerson == null) {
|
||||
return false;
|
||||
}
|
||||
// Allow collection's admin to edit/delete the template
|
||||
|
||||
UUID dsoId = UUID.fromString(targetId.toString());
|
||||
requestService.getCurrentRequest().getHttpServletRequest().getRequestURL();
|
||||
try {
|
||||
Collection coll = its.find(context, dsoId).getTemplateItemOf();
|
||||
if (authorizeService.isAdmin(context, coll)) {
|
||||
return true;
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@@ -146,7 +146,7 @@ public class CrossRefImportMetadataSourceServiceIT extends AbstractLiveImportInt
|
||||
+ " Medical College of Prevention of Iodine Deficiency Diseases");
|
||||
MetadatumDTO author = createMetadatumDTO("dc", "contributor", "author", "L.V. Senyuk");
|
||||
MetadatumDTO type = createMetadatumDTO("dc", "type", null, "journal-article");
|
||||
MetadatumDTO date = createMetadatumDTO("dc", "date", "issued", "2016");
|
||||
MetadatumDTO date = createMetadatumDTO("dc", "date", "issued", "2016-05-19");
|
||||
MetadatumDTO ispartof = createMetadatumDTO("dc", "relation", "ispartof",
|
||||
"Ukraïnsʹkij žurnal medicini, bìologìï ta sportu");
|
||||
MetadatumDTO doi = createMetadatumDTO("dc", "identifier", "doi", "10.26693/jmbs01.02.184");
|
||||
@@ -172,7 +172,7 @@ public class CrossRefImportMetadataSourceServiceIT extends AbstractLiveImportInt
|
||||
"Ischemic Heart Disease and Role of Nurse of Cardiology Department");
|
||||
MetadatumDTO author2 = createMetadatumDTO("dc", "contributor", "author", "K. І. Kozak");
|
||||
MetadatumDTO type2 = createMetadatumDTO("dc", "type", null, "journal-article");
|
||||
MetadatumDTO date2 = createMetadatumDTO("dc", "date", "issued", "2016");
|
||||
MetadatumDTO date2 = createMetadatumDTO("dc", "date", "issued", "2016-05-19");
|
||||
MetadatumDTO ispartof2 = createMetadatumDTO("dc", "relation", "ispartof",
|
||||
"Ukraïnsʹkij žurnal medicini, bìologìï ta sportu");
|
||||
MetadatumDTO doi2 = createMetadatumDTO("dc", "identifier", "doi", "10.26693/jmbs01.02.105");
|
||||
|
@@ -33,6 +33,7 @@ import org.dspace.app.rest.test.AbstractControllerIntegrationTest;
|
||||
import org.dspace.authorize.service.ResourcePolicyService;
|
||||
import org.dspace.builder.CollectionBuilder;
|
||||
import org.dspace.builder.CommunityBuilder;
|
||||
import org.dspace.builder.ResourcePolicyBuilder;
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.core.Constants;
|
||||
import org.hamcrest.Matchers;
|
||||
@@ -243,6 +244,35 @@ public class ItemTemplateRestControllerIT extends AbstractControllerIntegrationT
|
||||
)))));
|
||||
}
|
||||
|
||||
/* Similar to patchTemplateItem(), except it is for collection admin, not repository admin
|
||||
Test case was simplified, since it does not do anything else.
|
||||
*/
|
||||
@Test
|
||||
public void patchTemplateItemAsCollectionAdmin() throws Exception {
|
||||
setupTestTemplate();
|
||||
|
||||
String itemId = installTestTemplate();
|
||||
|
||||
ResourcePolicyBuilder.createResourcePolicy(context).withUser(eperson)
|
||||
.withAction(Constants.ADMIN)
|
||||
.withDspaceObject(childCollection).build();
|
||||
String collAdminToken = getAuthToken(eperson.getEmail(), password);
|
||||
|
||||
getClient(collAdminToken).perform(patch(getTemplateItemUrlTemplate(itemId))
|
||||
.content(patchBody)
|
||||
.contentType(contentType))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$", Matchers.allOf(
|
||||
hasJsonPath("$.type", is("itemtemplate"))
|
||||
)));
|
||||
|
||||
getClient(collAdminToken).perform(get(getCollectionTemplateItemUrlTemplate(childCollection.getID().toString())))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$", Matchers.allOf(
|
||||
hasJsonPath("$.type", is("itemtemplate"))
|
||||
)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void patchIllegalInArchiveTemplateItem() throws Exception {
|
||||
setupTestTemplate();
|
||||
@@ -337,6 +367,22 @@ public class ItemTemplateRestControllerIT extends AbstractControllerIntegrationT
|
||||
.andExpect(status().isNoContent());
|
||||
}
|
||||
|
||||
/*Similar to deleteTemplateItem(), except it is for collection admin, not repository admin
|
||||
*/
|
||||
@Test
|
||||
public void deleteTemplateItemAsCollectionAdmin() throws Exception {
|
||||
setupTestTemplate();
|
||||
String itemId = installTestTemplate();
|
||||
|
||||
ResourcePolicyBuilder.createResourcePolicy(context).withUser(eperson)
|
||||
.withAction(Constants.ADMIN)
|
||||
.withDspaceObject(childCollection).build();
|
||||
String collAdminToken = getAuthToken(eperson.getEmail(), password);
|
||||
|
||||
getClient(collAdminToken).perform(delete(getTemplateItemUrlTemplate(itemId)))
|
||||
.andExpect(status().isNoContent());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deleteTemplateItemNoRights() throws Exception {
|
||||
setupTestTemplate();
|
||||
|
@@ -69,8 +69,11 @@
|
||||
|
||||
<bean id="crossrefYearContrib" class="org.dspace.importer.external.metadatamapping.contributor.SimpleJsonPathMetadataContributor">
|
||||
<property name="field" ref="crossref.year"/>
|
||||
<property name="query" value="/issued/date-parts/0/0"/>
|
||||
<property name="metadataProcessor" ref="crossrefDateMetadataProcessor"></property>
|
||||
</bean>
|
||||
<bean name="crossrefDateMetadataProcessor" class="org.dspace.importer.external.crossref.CrossRefDateMetadataProcessor">
|
||||
<property name="pathToArray" value="/issued/date-parts"></property>
|
||||
</bean>
|
||||
<bean id="crossref.year" class="org.dspace.importer.external.metadatamapping.MetadataFieldConfig">
|
||||
<constructor-arg value="dc.date.issued"/>
|
||||
</bean>
|
||||
|
4
pom.xml
4
pom.xml
@@ -20,7 +20,7 @@
|
||||
<!--=== GENERAL / DSPACE-API DEPENDENCIES ===-->
|
||||
<java.version>11</java.version>
|
||||
<spring.version>5.3.27</spring.version>
|
||||
<spring-boot.version>2.7.11</spring-boot.version>
|
||||
<spring-boot.version>2.7.12</spring-boot.version>
|
||||
<spring-security.version>5.7.8</spring-security.version> <!-- sync with version used by spring-boot-->
|
||||
<hibernate.version>5.6.15.Final</hibernate.version>
|
||||
<hibernate-validator.version>6.2.5.Final</hibernate-validator.version>
|
||||
@@ -42,7 +42,7 @@
|
||||
<pdfbox-version>2.0.28</pdfbox-version>
|
||||
<rome.version>1.19.0</rome.version>
|
||||
<slf4j.version>1.7.36</slf4j.version>
|
||||
<tika.version>2.3.0</tika.version>
|
||||
<tika.version>2.5.0</tika.version>
|
||||
<!-- Sync with whatever version Tika uses -->
|
||||
<bouncycastle.version>1.70</bouncycastle.version>
|
||||
|
||||
|
Reference in New Issue
Block a user