diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/XmlWorkflowServiceImpl.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/XmlWorkflowServiceImpl.java index da7910da29f2..51292fd4773a 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/XmlWorkflowServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/XmlWorkflowServiceImpl.java @@ -221,6 +221,8 @@ public XmlWorkflowItem start(Context context, WorkspaceItem wsi) //Get our next step, if none is found, archive our item firstStep = wf.getNextStep(context, wfi, firstStep, ActionResult.OUTCOME_COMPLETE); if (firstStep == null) { + // record the submitted provenance message + recordStart(context, wfi.getItem(),null); archive(context, wfi); } else { activateFirstStep(context, wf, firstStep, wfi); @@ -334,7 +336,7 @@ protected void activateFirstStep(Context context, Workflow wf, Step firstStep, X + "item_id=" + wfi.getItem().getID() + "collection_id=" + wfi.getCollection().getID())); - // record the start of the workflow w/provenance message +// record the start of the workflow w/provenance message recordStart(context, wfi.getItem(), firstActionConfig.getProcessingAction()); //Fire an event ! @@ -1187,25 +1189,30 @@ protected void recordStart(Context context, Item myitem, Action action) DCDate now = DCDate.getCurrent(); // Create provenance description - String provmessage = ""; + StringBuffer provmessage = new StringBuffer(); if (myitem.getSubmitter() != null) { - provmessage = "Submitted by " + myitem.getSubmitter().getFullName() - + " (" + myitem.getSubmitter().getEmail() + ") on " - + now.toString() + " workflow start=" + action.getProvenanceStartId() + "\n"; + provmessage.append("Submitted by ").append(myitem.getSubmitter().getFullName()) + .append(" (").append(myitem.getSubmitter().getEmail()).append(") on ") + .append(now.toString()); } else { // else, null submitter - provmessage = "Submitted by unknown (probably automated) on" - + now.toString() + " workflow start=" + action.getProvenanceStartId() + "\n"; + provmessage.append("Submitted by unknown (probably automated) on") + .append(now.toString()); + } + if (action != null) { + provmessage.append(" workflow start=").append(action.getProvenanceStartId()).append("\n"); + } else { + provmessage.append("\n"); } // add sizes and checksums of bitstreams - provmessage += installItemService.getBitstreamProvenanceMessage(context, myitem); + provmessage.append(installItemService.getBitstreamProvenanceMessage(context, myitem)); // Add message to the DC itemService .addMetadata(context, myitem, MetadataSchemaEnum.DC.getName(), - "description", "provenance", "en", provmessage); + "description", "provenance", "en", provmessage.toString()); itemService.update(context, myitem); } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/ClarinAutoRegistrationController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/ClarinAutoRegistrationController.java index 31e234ec2c0c..de2dccb9e866 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/ClarinAutoRegistrationController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/ClarinAutoRegistrationController.java @@ -84,12 +84,17 @@ public ResponseEntity sendEmail(HttpServletRequest request, HttpServletResponse return null; } + // Fetch DSpace main cfg info and send it in the email String uiUrl = configurationService.getProperty("dspace.ui.url"); + String helpDeskEmail = configurationService.getProperty("lr.help.mail", ""); + String helpDeskPhoneNum = configurationService.getProperty("lr.help.phone", ""); + String dspaceName = configurationService.getProperty("dspace.name", ""); + String dspaceNameShort = configurationService.getProperty("dspace.name.short", ""); + if (StringUtils.isEmpty(uiUrl)) { log.error("Cannot load the `dspace.ui.url` property from the cfg."); throw new RuntimeException("Cannot load the `dspace.ui.url` property from the cfg."); } - // Generate token and create ClarinVerificationToken record with the token and user email. String verificationToken = Utils.generateHexKey(); clarinVerificationToken.setEmail(email); @@ -103,6 +108,11 @@ public ResponseEntity sendEmail(HttpServletRequest request, HttpServletResponse Locale locale = context.getCurrentLocale(); Email bean = Email.getEmail(I18nUtil.getEmailFilename(locale, "clarin_autoregistration")); bean.addArgument(autoregistrationURL); + bean.addArgument(helpDeskEmail); + bean.addArgument(helpDeskPhoneNum); + bean.addArgument(dspaceNameShort); + bean.addArgument(dspaceName); + bean.addArgument(uiUrl); bean.addRecipient(email); bean.send(); } catch (Exception e) { diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/ClarinUserInfoController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/ClarinUserInfoController.java new file mode 100644 index 000000000000..fc4bf5f19310 --- /dev/null +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/ClarinUserInfoController.java @@ -0,0 +1,56 @@ +/** + * 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; + +import java.io.IOException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import org.apache.commons.lang3.StringUtils; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +/** + * This class is a REST controller that returns information about the client user. + * E.g. the client's IP address. + * + * @author Milan Majchrak (milan.majchrak at dataquest.sk) + */ +@RequestMapping(value = "/api/userinfo") +@RestController +public class ClarinUserInfoController { + + private final ObjectMapper objectMapper = new ObjectMapper(); + /** + * This method returns the client's IP address. + * @param request The HttpServletRequest object. + * @return The client's IP address. + */ + @RequestMapping(method = RequestMethod.GET, path = "/ipaddress") + public ResponseEntity getUserIPAddress(HttpServletRequest request, HttpServletResponse response) + throws IOException { + // Get client's IP address + String ipAddress = request.getRemoteAddr(); + if (StringUtils.isBlank(ipAddress)) { + String errorMessage = "Cannot get user's IP address"; + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, errorMessage); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorMessage); + } + + // Create JSON object using Jackson's ObjectNode + ObjectNode jsonObject = objectMapper.createObjectNode(); + jsonObject.put("ipAddress", ipAddress); + + return ResponseEntity.ok().body(jsonObject); + } +} 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 170e85bd6035..e726c600ce80 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 @@ -173,9 +173,18 @@ private void sendEmailWithDownloadLink(Context context, UUID bitstreamUUID, throw new BadRequestException("Cannot find the clarin license for the bitstream with ID: " + bitstreamUUID); } + // Fetch DSpace main cfg info and send it in the email + String uiUrl = configurationService.getProperty("dspace.ui.url", ""); + String helpDeskEmail = configurationService.getProperty("lr.help.mail", ""); + String helpDeskPhoneNum = configurationService.getProperty("lr.help.phone", ""); + String dspaceName = configurationService.getProperty("dspace.name", ""); + String dspaceNameShort = configurationService.getProperty("dspace.name.short", ""); + + if (StringUtils.isEmpty(uiUrl)) { + log.error("Cannot load the `dspace.ui.url` property from the cfg."); + throw new RuntimeException("Cannot load the `dspace.ui.url` property from the cfg."); + } // Compose download link - // Get UI url - String uiUrl = configurationService.getProperty("dspace.ui.url"); String downloadLink = uiUrl + "/" + BitstreamRest.PLURAL_NAME + "/" + bitstream.getID() + "/download?dtoken=" + downloadToken; @@ -185,6 +194,11 @@ private void sendEmailWithDownloadLink(Context context, UUID bitstreamUUID, bean.addArgument(bitstream.getName()); bean.addArgument(downloadLink); bean.addArgument(clarinLicense.getDefinition()); + bean.addArgument(helpDeskEmail); + bean.addArgument(helpDeskPhoneNum); + bean.addArgument(dspaceNameShort); + bean.addArgument(dspaceName); + bean.addArgument(uiUrl); bean.addRecipient(email); bean.send(); } catch (MessagingException e) { diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ClarinDiscoveryRestControllerIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ClarinDiscoveryRestControllerIT.java index 95051697a462..72b12c7962af 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ClarinDiscoveryRestControllerIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ClarinDiscoveryRestControllerIT.java @@ -984,6 +984,7 @@ public void discoverSearchTest() throws Exception { SearchFilterMatcher.authorFilter(), SearchFilterMatcher.subjectFilter(), // SearchFilterMatcher.dateIssuedFilter(), + SearchFilterMatcher.publisherFilter(), SearchFilterMatcher.hasContentInOriginalBundleFilter(), SearchFilterMatcher.hasFileNameInOriginalBundleFilter(), SearchFilterMatcher.hasFileDescriptionInOriginalBundleFilter(), diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ClarinUserInfoControllerIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ClarinUserInfoControllerIT.java new file mode 100644 index 000000000000..be32cc55a656 --- /dev/null +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ClarinUserInfoControllerIT.java @@ -0,0 +1,34 @@ +/** + * 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; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import javax.ws.rs.core.MediaType; + +import org.dspace.app.rest.test.AbstractControllerIntegrationTest; +import org.junit.Test; + +/** + * This class test the REST controller that returns information about the client user. + * E.g. the client's IP address. + * + * @author Milan Majchrak (milan.majchrak at dataquest.sk) + */ +public class ClarinUserInfoControllerIT extends AbstractControllerIntegrationTest { + + @Test + public void getUserIPAddress() throws Exception { + getClient().perform(get("/api/userinfo/ipaddress") + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().json("{\"ipAddress\":\"127.0.0.1\"}")); + } +} diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ClarinWorkflowItemRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ClarinWorkflowItemRestRepositoryIT.java index 2181bedcf08c..20ec8dc38f24 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ClarinWorkflowItemRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ClarinWorkflowItemRestRepositoryIT.java @@ -10,13 +10,16 @@ import static com.jayway.jsonpath.JsonPath.read; import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasJsonPath; import static org.dspace.app.rest.matcher.MetadataMatcher.matchMetadata; +import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; +import static org.junit.Assert.assertFalse; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import java.util.List; import java.util.UUID; import java.util.concurrent.atomic.AtomicReference; @@ -24,17 +27,22 @@ import org.dspace.app.rest.test.AbstractControllerIntegrationTest; import org.dspace.builder.CollectionBuilder; import org.dspace.builder.CommunityBuilder; +import org.dspace.builder.EPersonBuilder; import org.dspace.builder.ItemBuilder; import org.dspace.builder.VersionBuilder; import org.dspace.builder.WorkspaceItemBuilder; import org.dspace.content.Collection; import org.dspace.content.Item; +import org.dspace.content.MetadataValue; +import org.dspace.content.WorkspaceItem; import org.dspace.content.service.ItemService; import org.dspace.content.service.WorkspaceItemService; +import org.dspace.eperson.EPerson; import org.dspace.license.service.CreativeCommonsService; import org.dspace.services.ConfigurationService; import org.dspace.xmlworkflow.factory.XmlWorkflowFactory; import org.dspace.xmlworkflow.storedcomponents.service.CollectionRoleService; +import org.dspace.xmlworkflow.storedcomponents.service.XmlWorkflowItemService; import org.hamcrest.Matchers; import org.junit.Assert; import org.junit.Before; @@ -64,6 +72,8 @@ public class ClarinWorkflowItemRestRepositoryIT extends AbstractControllerIntegr @Autowired private CreativeCommonsService creativeCommonsService; + @Autowired + private XmlWorkflowItemService xmlWorkflowItemService; @Autowired private ItemService itemService; @@ -250,4 +260,64 @@ public void shouldAddNewHandleToItemMetadata() throws Exception { WorkspaceItemBuilder.deleteWorkspaceItem(idWorkspaceItemRef.get()); } } + + + @Test + public void shouldCreateProvenanceMessageOnItemSubmit() throws Exception { + context.turnOffAuthorisationSystem(); + + //** GIVEN ** + //1. A community with one collection. + parentCommunity = CommunityBuilder.createCommunity(context) + .withName("Parent Community") + .build(); + + //2. create a normal user to use as submitter + EPerson submitter = EPersonBuilder.createEPerson(context) + .withEmail("submitter@example.com") + .withPassword("dspace") + .build(); + + // Submitter group - allow deposit a new item without workflow + Collection col1 = CollectionBuilder.createCollection(context, parentCommunity) + .withName("Collection 2") + .withSubmitterGroup(submitter) + .build(); + context.setCurrentUser(submitter); + + //3. a workspace item + WorkspaceItem wsitem = WorkspaceItemBuilder.createWorkspaceItem(context, col1) + .withTitle("Submission Item") + .withIssueDate("2017-10-17") + .grantLicense() + .build(); + + context.restoreAuthSystemState(); + + // get the submitter auth token + String authToken = getAuthToken(submitter.getEmail(), "dspace"); + + // submit the workspaceitem to start the workflow + getClient(authToken) + .perform(post(BASE_REST_SERVER_URL + "/api/workflow/workflowitems") + .content("/api/submission/workspaceitems/" + wsitem.getID()) + .contentType(textUriContentType)) + .andExpect(status().isCreated()); + + // Load deposited item and check the provenance metadata + Item depositedItem = itemService.find(context, wsitem.getItem().getID()); + List mvList = itemService.getMetadata(depositedItem, "dc", "description", + "provenance", Item.ANY); + assertFalse(mvList.isEmpty()); + + // Check if the provenance contains the submitter info + boolean containsSubmitterProvenance = false; + for (MetadataValue mv: mvList) { + if (mv.getValue().contains("Submitted by " + submitter.getEmail())) { + containsSubmitterProvenance = true; + break; + } + } + assertThat(containsSubmitterProvenance, is(true)); + } } diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/SearchFilterMatcher.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/SearchFilterMatcher.java index 2d38aeb12968..7700d5291249 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/SearchFilterMatcher.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/SearchFilterMatcher.java @@ -195,4 +195,15 @@ public static Matcher clarinItemsTypeFilter() { checkOperators() ); } + + public static Matcher publisherFilter() { + return allOf( + hasJsonPath("$.filter", is("publisher")), + hasJsonPath("$.hasFacets", is(false)), + hasJsonPath("$.type", is("text")), + hasJsonPath("$.openByDefault", is(false)), + checkOperators() + + ); + } } diff --git a/dspace/config/clarin-dspace.cfg b/dspace/config/clarin-dspace.cfg index 3d317c77b41a..e51dca06ba8e 100644 --- a/dspace/config/clarin-dspace.cfg +++ b/dspace/config/clarin-dspace.cfg @@ -2,6 +2,12 @@ # one day similar to this # https://github.com/ufal/clarin-dspace/blob/clarin/utilities/project_helpers/config/local.conf.dist +#------------------------------------------------------------------# +#---------------------------DSpace---------------------------------# +#------------------------------------------------------------------# +dspace.name.short = DSpace +dspace.name = CLARIN DSpace + #------------------------------------------------------------------# #---------------------------UPLOAD FILE----------------------------# #------------------------------------------------------------------# diff --git a/dspace/config/emails/clarin_autoregistration b/dspace/config/emails/clarin_autoregistration index f39770cfd258..c05ba67d9e78 100644 --- a/dspace/config/emails/clarin_autoregistration +++ b/dspace/config/emails/clarin_autoregistration @@ -1,14 +1,27 @@ -## E-mail sent to confirm authenticity of the user's e-mail. -## -## Parameters: {0} confirmation e-mail -## -## See org.dspace.core.Email for information on the format of this file. -## +# E-mail sent to confirm authenticity of the user's e-mail. +# +# Parameters: {0} confirmation e-mail +# {1} helpdesk email +# {2} helpdesk phone number +# {3} DSpace name short +# {4} DSpace name +# {5} DSpace UI url +# +# See org.dspace.core.Email for information on the format of this file. +# +Subject: ${params[3]}: Account Registration +To complete registration for a ${params[3]} repository account at {params[5]}, please click the link below: -Confirmation e-mail: ${params[0]} + ${params[0]} + +If you need assistance with your account, please email +${params[1]} or call us at ${params[2]} + + +${params[3]} Team _____________________________________ -${dspace.name}, -WWW: ${dspace.url} -Email: ${lr.help.mail} -Tel.: ${lr.help.phone} +${params[4]}, +WWW: ${params[5]} +Email: ${params[1]} +Tel.: ${params[2]} diff --git a/dspace/config/emails/clarin_download_link b/dspace/config/emails/clarin_download_link index d44e18cca7c0..bf0bb380f3b5 100644 --- a/dspace/config/emails/clarin_download_link +++ b/dspace/config/emails/clarin_download_link @@ -3,24 +3,29 @@ # Parameters: {0} is expanded to filename # {1} to a download URL # {2} to license url +# {3} helpdesk email +# {4} helpdesk phone number +# {5} DSpace name short +# {6} DSpace name +# {7} DSpace UI url # # See org.dspace.core.Email for information on the format of this file. # -Subject: ${lr.dspace.name.short}: Download instructions for {0} +Subject: ${params[5]}: Download instructions for ${params[0]} To download the file you have requested, please click the link below: - {1} + ${params[1]} Remember, the file is distributed under specific license: - {2} + ${params[2]} If you have trouble downloading the file or if you did not request this download please contact -${lr.help.mail} or call us at ${lr.help.phone} +${params[3]} or call us at ${params[4]} -${lr.dspace.name.short} Team +${params[5]} Team _____________________________________ -${dspace.name}, -WWW: ${dspace.url} -Email: ${lr.help.mail} -Tel.: ${lr.help.phone} \ No newline at end of file +${params[6]}, +WWW: ${params[7]} +Email: ${params[3]} +Tel.: ${params[4]} \ No newline at end of file diff --git a/dspace/config/spring/api/discovery.xml b/dspace/config/spring/api/discovery.xml index 9b8b8351fe55..d40242314260 100644 --- a/dspace/config/spring/api/discovery.xml +++ b/dspace/config/spring/api/discovery.xml @@ -200,6 +200,7 @@ + @@ -2488,6 +2489,17 @@ + + + + + dc.publisher + + + + + +