From 9882b5280b38a8334b552f688ea5179aaba6b181 Mon Sep 17 00:00:00 2001 From: Philip Durbin Date: Mon, 9 May 2022 16:09:35 -0400 Subject: [PATCH 1/5] SWORD: if custom terms disabled, report error #8580 --- doc/sphinx-guides/source/api/sword.rst | 2 +- .../api/datadeposit/SwordServiceBean.java | 10 ++++++++++ .../api/imports/ImportGenericServiceBean.java | 6 +++++- .../edu/harvard/iq/dataverse/api/SwordIT.java | 16 ++++++++++++++++ 4 files changed, 32 insertions(+), 2 deletions(-) diff --git a/doc/sphinx-guides/source/api/sword.rst b/doc/sphinx-guides/source/api/sword.rst index d4f56ddb5b4..e970e0e7212 100755 --- a/doc/sphinx-guides/source/api/sword.rst +++ b/doc/sphinx-guides/source/api/sword.rst @@ -82,7 +82,7 @@ New features as of v1.1 - "Contributor" can now be populated and the "Type" (Editor, Funder, Researcher, etc.) can be specified with an XML attribute. For example: ``CaffeineForAll`` -- "License" can now be set with ``dcterms:license`` and the possible values determined by the installation ("CC0 1.0" and "CC BY 4.0" by default). "License" interacts with "Terms of Use" (``dcterms:rights``) in that if you include ``dcterms:rights`` in the XML and don't include ``dcterms:license``, the license will be "Custom Dataset Terms" and "Terms of Use" will be populated. If you don't include ``dcterms:rights``, the default license will be used. It is invalid to specify a license and also include ``dcterms:rights``; an error will be returned. For backwards compatibility, ``dcterms:rights`` is allowed to be blank (i.e. ````) but blank values will not be persisted to the database and the license will be set to "Custom Dataset Terms". +- "License" can now be set with ``dcterms:license`` and the possible values determined by the installation ("CC0 1.0" and "CC BY 4.0" by default). "License" interacts with "Terms of Use" (``dcterms:rights``) in that if you include ``dcterms:rights`` in the XML and don't include ``dcterms:license``, the license will be "Custom Dataset Terms" and "Terms of Use" will be populated. If you don't include ``dcterms:rights``, the default license will be used. It is invalid to specify a license and also include ``dcterms:rights``; an error will be returned. For backwards compatibility, ``dcterms:rights`` is allowed to be blank (i.e. ````) but blank values will not be persisted to the database and the license will be set to "Custom Dataset Terms". Note that if admins of an installation have disabled "Custom Dataset Terms" you will get an error if you try to pass (``dcterms:rights``). - "Contact E-mail" is automatically populated from dataset owner's email. diff --git a/src/main/java/edu/harvard/iq/dataverse/api/datadeposit/SwordServiceBean.java b/src/main/java/edu/harvard/iq/dataverse/api/datadeposit/SwordServiceBean.java index ad33e635c91..f97a5d2bdb8 100644 --- a/src/main/java/edu/harvard/iq/dataverse/api/datadeposit/SwordServiceBean.java +++ b/src/main/java/edu/harvard/iq/dataverse/api/datadeposit/SwordServiceBean.java @@ -12,6 +12,7 @@ import edu.harvard.iq.dataverse.license.License; import edu.harvard.iq.dataverse.license.LicenseServiceBean; import edu.harvard.iq.dataverse.util.BundleUtil; +import edu.harvard.iq.dataverse.util.SystemConfig; import java.util.ArrayList; import java.util.List; @@ -36,6 +37,8 @@ public class SwordServiceBean { DatasetFieldServiceBean datasetFieldService; @Inject LicenseServiceBean licenseServiceBean; + @EJB + SystemConfig systemConfig; /** * Mutate the dataset version, adding a datasetContact (email address) from @@ -150,6 +153,13 @@ public void addDatasetSubjectIfMissing(DatasetVersion datasetVersion) { public void setDatasetLicenseAndTermsOfUse(DatasetVersion datasetVersionToMutate, SwordEntry swordEntry) throws SwordError { Map> dcterms = swordEntry.getDublinCore(); List listOfLicensesProvided = dcterms.get("license"); + List rights = dcterms.get("rights"); + if (rights != null) { + if (!systemConfig.isAllowCustomTerms()) { + throw new SwordError("Custom Terms (dcterms:rights) are not allowed."); + } + } + TermsOfUseAndAccess terms = new TermsOfUseAndAccess(); datasetVersionToMutate.setTermsOfUseAndAccess(terms); terms.setDatasetVersion(datasetVersionToMutate); diff --git a/src/main/java/edu/harvard/iq/dataverse/api/imports/ImportGenericServiceBean.java b/src/main/java/edu/harvard/iq/dataverse/api/imports/ImportGenericServiceBean.java index bd7975835e3..7b4193cb1ce 100644 --- a/src/main/java/edu/harvard/iq/dataverse/api/imports/ImportGenericServiceBean.java +++ b/src/main/java/edu/harvard/iq/dataverse/api/imports/ImportGenericServiceBean.java @@ -13,6 +13,7 @@ import edu.harvard.iq.dataverse.api.dto.*; import edu.harvard.iq.dataverse.api.dto.FieldDTO; import edu.harvard.iq.dataverse.api.dto.MetadataBlockDTO; +import edu.harvard.iq.dataverse.license.LicenseServiceBean; import edu.harvard.iq.dataverse.settings.SettingsServiceBean; import edu.harvard.iq.dataverse.util.StringUtil; import edu.harvard.iq.dataverse.util.json.JsonParseException; @@ -67,6 +68,9 @@ public class ImportGenericServiceBean { @EJB SettingsServiceBean settingsService; + @EJB + LicenseServiceBean licenseService; + @PersistenceContext(unitName = "VDCNet-ejbPU") private EntityManager em; @@ -103,7 +107,7 @@ public void importXML(String xmlToParse, String foreignFormat, DatasetVersion da logger.fine(json); JsonReader jsonReader = Json.createReader(new StringReader(json)); JsonObject obj = jsonReader.readObject(); - DatasetVersion dv = new JsonParser(datasetFieldSvc, blockService, settingsService).parseDatasetVersion(obj, datasetVersion); + DatasetVersion dv = new JsonParser(datasetFieldSvc, blockService, settingsService, licenseService).parseDatasetVersion(obj, datasetVersion); } catch (XMLStreamException ex) { //Logger.getLogger("global").log(Level.SEVERE, null, ex); throw new EJBException("ERROR occurred while parsing XML fragment ("+xmlToParse.substring(0, 64)+"...); ", ex); diff --git a/src/test/java/edu/harvard/iq/dataverse/api/SwordIT.java b/src/test/java/edu/harvard/iq/dataverse/api/SwordIT.java index 29173d3bd76..6c745790359 100644 --- a/src/test/java/edu/harvard/iq/dataverse/api/SwordIT.java +++ b/src/test/java/edu/harvard/iq/dataverse/api/SwordIT.java @@ -5,6 +5,7 @@ import com.jayway.restassured.response.Response; import edu.harvard.iq.dataverse.GlobalId; import edu.harvard.iq.dataverse.api.datadeposit.SwordConfigurationImpl; +import edu.harvard.iq.dataverse.settings.SettingsServiceBean; import java.io.File; import java.io.IOException; import java.nio.file.Paths; @@ -725,6 +726,19 @@ public void testCustomTerms() { .statusCode(OK.getStatusCode()) .body("data.latestVersion.termsOfUse", equalTo("Call me")) .body("data.latestVersion.license", equalTo(null)); + + UtilIT.setSetting(SettingsServiceBean.Key.AllowCustomTermsOfUse, "false") + .then().assertThat().statusCode(OK.getStatusCode()); + + Response createDatasetCustomTermsDisabled = UtilIT.createDatasetViaSwordApi(dataverseAlias, title, description, license, rights, apiToken); + createDatasetCustomTermsDisabled.prettyPrint(); + createDatasetCustomTermsDisabled.then().assertThat() + // Custom Terms (dcterms:rights) are not allowed. + .statusCode(BAD_REQUEST.getStatusCode()); + + // cleanup, allow custom terms again (delete because it defaults to true) + UtilIT.deleteSetting(SettingsServiceBean.Key.AllowCustomTermsOfUse); + } @Test @@ -958,6 +972,8 @@ public void testDeleteFiles() { @AfterClass public static void tearDownClass() { + // cleanup, allow custom terms again (delete because it defaults to true) + UtilIT.deleteSetting(SettingsServiceBean.Key.AllowCustomTermsOfUse); UtilIT.deleteUser(superuser); } From 74ad9740956679d6372e57b84c27c107a5e5ef4d Mon Sep 17 00:00:00 2001 From: Philip Durbin Date: Mon, 9 May 2022 16:18:48 -0400 Subject: [PATCH 2/5] typo #8580 --- doc/sphinx-guides/source/api/sword.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/sphinx-guides/source/api/sword.rst b/doc/sphinx-guides/source/api/sword.rst index e970e0e7212..11b43e98774 100755 --- a/doc/sphinx-guides/source/api/sword.rst +++ b/doc/sphinx-guides/source/api/sword.rst @@ -82,7 +82,7 @@ New features as of v1.1 - "Contributor" can now be populated and the "Type" (Editor, Funder, Researcher, etc.) can be specified with an XML attribute. For example: ``CaffeineForAll`` -- "License" can now be set with ``dcterms:license`` and the possible values determined by the installation ("CC0 1.0" and "CC BY 4.0" by default). "License" interacts with "Terms of Use" (``dcterms:rights``) in that if you include ``dcterms:rights`` in the XML and don't include ``dcterms:license``, the license will be "Custom Dataset Terms" and "Terms of Use" will be populated. If you don't include ``dcterms:rights``, the default license will be used. It is invalid to specify a license and also include ``dcterms:rights``; an error will be returned. For backwards compatibility, ``dcterms:rights`` is allowed to be blank (i.e. ````) but blank values will not be persisted to the database and the license will be set to "Custom Dataset Terms". Note that if admins of an installation have disabled "Custom Dataset Terms" you will get an error if you try to pass (``dcterms:rights``). +- "License" can now be set with ``dcterms:license`` and the possible values determined by the installation ("CC0 1.0" and "CC BY 4.0" by default). "License" interacts with "Terms of Use" (``dcterms:rights``) in that if you include ``dcterms:rights`` in the XML and don't include ``dcterms:license``, the license will be "Custom Dataset Terms" and "Terms of Use" will be populated. If you don't include ``dcterms:rights``, the default license will be used. It is invalid to specify a license and also include ``dcterms:rights``; an error will be returned. For backwards compatibility, ``dcterms:rights`` is allowed to be blank (i.e. ````) but blank values will not be persisted to the database and the license will be set to "Custom Dataset Terms". Note that if admins of an installation have disabled "Custom Dataset Terms" you will get an error if you try to pass ``dcterms:rights``. - "Contact E-mail" is automatically populated from dataset owner's email. From 3d4f96850bea046087762e9e26ed050495d52bb7 Mon Sep 17 00:00:00 2001 From: Philip Durbin Date: Tue, 10 May 2022 11:51:30 -0400 Subject: [PATCH 3/5] more readable with && #8580 --- .../iq/dataverse/api/datadeposit/SwordServiceBean.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/api/datadeposit/SwordServiceBean.java b/src/main/java/edu/harvard/iq/dataverse/api/datadeposit/SwordServiceBean.java index f97a5d2bdb8..96df3ab400a 100644 --- a/src/main/java/edu/harvard/iq/dataverse/api/datadeposit/SwordServiceBean.java +++ b/src/main/java/edu/harvard/iq/dataverse/api/datadeposit/SwordServiceBean.java @@ -154,10 +154,8 @@ public void setDatasetLicenseAndTermsOfUse(DatasetVersion datasetVersionToMutate Map> dcterms = swordEntry.getDublinCore(); List listOfLicensesProvided = dcterms.get("license"); List rights = dcterms.get("rights"); - if (rights != null) { - if (!systemConfig.isAllowCustomTerms()) { - throw new SwordError("Custom Terms (dcterms:rights) are not allowed."); - } + if (rights != null && !systemConfig.isAllowCustomTerms()) { + throw new SwordError("Custom Terms (dcterms:rights) are not allowed."); } TermsOfUseAndAccess terms = new TermsOfUseAndAccess(); From de9ff67832f86ed9c43d9231ebbdbe87c5df4d63 Mon Sep 17 00:00:00 2001 From: Philip Durbin Date: Tue, 10 May 2022 13:44:34 -0400 Subject: [PATCH 4/5] deprecate constructor without licenseService #8580 --- src/main/java/edu/harvard/iq/dataverse/util/json/JsonParser.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/edu/harvard/iq/dataverse/util/json/JsonParser.java b/src/main/java/edu/harvard/iq/dataverse/util/json/JsonParser.java index 989850f8620..f6dcf3d5821 100644 --- a/src/main/java/edu/harvard/iq/dataverse/util/json/JsonParser.java +++ b/src/main/java/edu/harvard/iq/dataverse/util/json/JsonParser.java @@ -75,6 +75,7 @@ public class JsonParser { */ boolean lenient = false; + @Deprecated public JsonParser(DatasetFieldServiceBean datasetFieldSvc, MetadataBlockServiceBean blockService, SettingsServiceBean settingsService) { this.datasetFieldSvc = datasetFieldSvc; this.blockService = blockService; From 593213ad38484d050b76e4fefe8a43028f1803c9 Mon Sep 17 00:00:00 2001 From: Philip Durbin Date: Wed, 11 May 2022 10:49:27 -0400 Subject: [PATCH 5/5] remove dead code: alt importXML and importDCTerms #8580 These methods were added in 087b017 before we shipped 4.0 and aren't being used. They are using a constructor we are deprecating (JsonParser with no licenseService). The other importXML method is being used and has been switched to the new constructor. --- .../api/imports/ImportGenericServiceBean.java | 72 ------------------- 1 file changed, 72 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/api/imports/ImportGenericServiceBean.java b/src/main/java/edu/harvard/iq/dataverse/api/imports/ImportGenericServiceBean.java index 7b4193cb1ce..610f5ff84d8 100644 --- a/src/main/java/edu/harvard/iq/dataverse/api/imports/ImportGenericServiceBean.java +++ b/src/main/java/edu/harvard/iq/dataverse/api/imports/ImportGenericServiceBean.java @@ -119,50 +119,6 @@ public void importXML(String xmlToParse, String foreignFormat, DatasetVersion da } catch (XMLStreamException ex) {} } } - - public void importXML(File xmlFile, String foreignFormat, DatasetVersion datasetVersion) { - - FileInputStream in = null; - XMLStreamReader xmlr = null; - - // look up the foreign metadata mapping for this format: - - ForeignMetadataFormatMapping mappingSupported = findFormatMappingByName (foreignFormat); - if (mappingSupported == null) { - throw new EJBException("Unknown/unsupported foreign metadata format "+foreignFormat); - } - - try { - in = new FileInputStream(xmlFile); - XMLInputFactory xmlFactory = javax.xml.stream.XMLInputFactory.newInstance(); - xmlr = xmlFactory.createXMLStreamReader(in); - DatasetDTO datasetDTO = processXML(xmlr, mappingSupported); - - Gson gson = new Gson(); - String json = gson.toJson(datasetDTO.getDatasetVersion()); - logger.info("Json:\n"+json); - JsonReader jsonReader = Json.createReader(new StringReader(json)); - JsonObject obj = jsonReader.readObject(); - DatasetVersion dv = new JsonParser(datasetFieldSvc, blockService, settingsService).parseDatasetVersion(obj, datasetVersion); - } catch (FileNotFoundException ex) { - //Logger.getLogger("global").log(Level.SEVERE, null, ex); - throw new EJBException("ERROR occurred in mapDDI: File Not Found!"); - } catch (XMLStreamException ex) { - //Logger.getLogger("global").log(Level.SEVERE, null, ex); - throw new EJBException("ERROR occurred while parsing XML (file "+xmlFile.getAbsolutePath()+"); ", ex); - } catch (JsonParseException ex) { - Logger.getLogger(ImportGenericServiceBean.class.getName()).log(Level.SEVERE, null, ex); - } finally { - try { - if (xmlr != null) { xmlr.close(); } - } catch (XMLStreamException ex) {} - - try { - if (in != null) { in.close();} - } catch (IOException ex) {} - } - - } public DatasetDTO processXML( XMLStreamReader xmlr, ForeignMetadataFormatMapping foreignFormatMapping) throws XMLStreamException { // init - similarly to what I'm doing in the metadata extraction code? @@ -555,34 +511,6 @@ public DatasetDTO doImport(String xmlToParse) throws XMLStreamException { } return datasetDTO; } - - public void importDCTerms(String xmlToParse, DatasetVersion datasetVersion, DatasetFieldServiceBean datasetFieldSvc, MetadataBlockServiceBean blockService, SettingsServiceBean settingsService) { - DatasetDTO datasetDTO = this.initializeDataset(); - try { - // Read docDescr and studyDesc into DTO objects. - Map fileMap = mapDCTerms(xmlToParse, datasetDTO); - // - // convert DTO to Json, - Gson gson = new Gson(); - String json = gson.toJson(datasetDTO.getDatasetVersion()); - JsonReader jsonReader = Json.createReader(new StringReader(json)); - JsonObject obj = jsonReader.readObject(); - //and call parse Json to read it into a datasetVersion - DatasetVersion dv = new JsonParser(datasetFieldSvc, blockService, settingsService).parseDatasetVersion(obj, datasetVersion); - } catch (XMLStreamException | JsonParseException e) { - // EMK TODO: exception handling - e.printStackTrace(); - } - - //EMK TODO: Call methods for reading FileMetadata and related objects from xml, return list of FileMetadata objects. - /*try { - - Map dataTableMap = new DataTableImportDDI().processDataDscr(xmlr); - } catch(Exception e) { - - }*/ - // Save Dataset and DatasetVersion in database - } public Map mapDCTerms(String xmlToParse, DatasetDTO datasetDTO) throws XMLStreamException {