From a849d6cb4a037f971075ff6838bbe3023ed4d953 Mon Sep 17 00:00:00 2001 From: Stephen Kraffmiller Date: Tue, 30 Nov 2021 09:44:41 -0500 Subject: [PATCH 01/49] #8191 update ui and bundle, etc. --- .../edu/harvard/iq/dataverse/Dataset.java | 1 + .../edu/harvard/iq/dataverse/DatasetPage.java | 15 +++++- .../harvard/iq/dataverse/DatasetVersion.java | 28 +++++++++++ .../edu/harvard/iq/dataverse/Template.java | 1 + .../iq/dataverse/TermsOfUseAndAccess.java | 13 ++++++ .../TermsOfUseAndAccessValidator.java | 46 ++++++++++++++++--- src/main/java/propertyFiles/Bundle.properties | 4 +- src/main/webapp/dataset-license-terms.xhtml | 36 ++++++++++----- src/main/webapp/editFilesFragment.xhtml | 45 +++++++++++------- .../webapp/file-edit-popup-fragment.xhtml | 19 ++++++-- 10 files changed, 166 insertions(+), 42 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/Dataset.java b/src/main/java/edu/harvard/iq/dataverse/Dataset.java index 60466f96362..f1fe7b2b09d 100644 --- a/src/main/java/edu/harvard/iq/dataverse/Dataset.java +++ b/src/main/java/edu/harvard/iq/dataverse/Dataset.java @@ -319,6 +319,7 @@ private DatasetVersion createNewDatasetVersion(Template template, FileMetadata f TermsOfUseAndAccess terms = new TermsOfUseAndAccess(); terms.setDatasetVersion(dsv); terms.setLicense(TermsOfUseAndAccess.License.CC0); + terms.setFileAccessRequest(true); dsv.setTermsOfUseAndAccess(terms); } diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java index 90ca5ecb027..0367fca8591 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java @@ -394,6 +394,18 @@ public void setRsyncScript(String rsyncScript) { public String getRsyncScriptFilename() { return rsyncScriptFilename; } + + private Boolean hasRestrictedFiles = null; + + public Boolean isHasRestrictedFiles(){ + //cache in page to limit processing + if (hasRestrictedFiles != null){ + return hasRestrictedFiles; + } else { + hasRestrictedFiles = workingVersion.isHasRestrictedFile(); + return hasRestrictedFiles; + } + } private String thumbnailString = null; @@ -2054,7 +2066,8 @@ private String init(boolean initFull) { previewTools = externalToolService.findFileToolsByType(ExternalTool.Type.PREVIEW); datasetExploreTools = externalToolService.findDatasetToolsByType(ExternalTool.Type.EXPLORE); rowsPerPage = 10; - + hasRestrictedFiles = workingVersion.isHasRestrictedFile(); + return null; } diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java b/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java index d53cf20491c..2a235e5fefb 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java @@ -560,6 +560,13 @@ public boolean isHasNonPackageFile(){ // The presence of any non-package file means that HTTP Upload was used (no mixing allowed) so we just check the first file. return !this.fileMetadatas.get(0).getDataFile().getContentType().equals(DataFileServiceBean.MIME_TYPE_PACKAGE_FILE); } + + public boolean isHasRestrictedFile(){ + if (this.fileMetadatas.isEmpty()){; + return false; + } + return this.fileMetadatas.stream().anyMatch(fm -> (fm.isRestricted())); + } public void updateDefaultValuesFromTemplate(Template template) { if (!template.getDatasetFields().isEmpty()) { @@ -636,6 +643,11 @@ public void initDefaultValues() { TermsOfUseAndAccess terms = new TermsOfUseAndAccess(); terms.setDatasetVersion(this); terms.setLicense(TermsOfUseAndAccess.License.CC0); + /* + Added for https://github.com/IQSS/dataverse/issues/8191 + set File Access Request to true + */ + terms.setFileAccessRequest(true); this.setTermsOfUseAndAccess(terms); } @@ -1665,7 +1677,23 @@ public Set validate() { } } } + + + TermsOfUseAndAccess toua = this.termsOfUseAndAccess; + //Only need to test Terms of Use and Access if there are restricted files + if (toua != null && this.isHasRestrictedFile()) { + Set> constraintViolations = validator.validate(toua); + if (constraintViolations.size() > 0) { + ConstraintViolation violation = constraintViolations.iterator().next(); + String message = "Constraint violation found in Terms of Use and Access. " + + "If Request Access to restricted files is disabled then Terms of Access must be provided."; + logger.info(message); + this.termsOfUseAndAccess.setValidationMessage(message); + returnSet.add(violation); + } + } + return returnSet; } diff --git a/src/main/java/edu/harvard/iq/dataverse/Template.java b/src/main/java/edu/harvard/iq/dataverse/Template.java index b01b0a2b792..5b9d7c82fe8 100644 --- a/src/main/java/edu/harvard/iq/dataverse/Template.java +++ b/src/main/java/edu/harvard/iq/dataverse/Template.java @@ -326,6 +326,7 @@ public Template cloneNewTemplate(Template source) { } else { terms = new TermsOfUseAndAccess(); terms.setLicense(TermsOfUseAndAccess.defaultLicense); + terms.setFileAccessRequest(true); } newTemplate.setTermsOfUseAndAccess(terms); return newTemplate; diff --git a/src/main/java/edu/harvard/iq/dataverse/TermsOfUseAndAccess.java b/src/main/java/edu/harvard/iq/dataverse/TermsOfUseAndAccess.java index 72f4ab54ee8..04dd48ea473 100644 --- a/src/main/java/edu/harvard/iq/dataverse/TermsOfUseAndAccess.java +++ b/src/main/java/edu/harvard/iq/dataverse/TermsOfUseAndAccess.java @@ -14,6 +14,7 @@ import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.OneToOne; +import javax.persistence.Transient; /** * @@ -21,6 +22,7 @@ * @author skraffmi */ @Entity +@ValidateTermsOfUseAndAccess public class TermsOfUseAndAccess implements Serializable { @Id @@ -275,6 +277,17 @@ public enum License { NONE, CC0 } + @Transient + private String validationMessage; + + public String getValidationMessage() { + return validationMessage; + } + + public void setValidationMessage(String validationMessage) { + this.validationMessage = validationMessage; + } + /** * @todo What does the GUI use for a default license? What does the "native" * API use? See also https://github.com/IQSS/dataverse/issues/1385 diff --git a/src/main/java/edu/harvard/iq/dataverse/TermsOfUseAndAccessValidator.java b/src/main/java/edu/harvard/iq/dataverse/TermsOfUseAndAccessValidator.java index dfa9e9f6c77..394d0f359ac 100644 --- a/src/main/java/edu/harvard/iq/dataverse/TermsOfUseAndAccessValidator.java +++ b/src/main/java/edu/harvard/iq/dataverse/TermsOfUseAndAccessValidator.java @@ -21,12 +21,46 @@ public void initialize(ValidateTermsOfUseAndAccess constraintAnnotation) { @Override public boolean isValid(TermsOfUseAndAccess value, ConstraintValidatorContext context) { - //if both null invalid - //if(value.getTemplate() == null && value.getDatasetVersion() == null) return false; + //must allow access requests or have terms of access filled in. - //if both not null invalid - //return !(value.getTemplate() != null && value.getDatasetVersion() != null); - return true; + boolean valid = value.isFileAccessRequest() == true || (value.getTermsOfAccess() != null && !value.getTermsOfAccess().isEmpty()) ; + if (!valid) { + try { + + + if ( context != null) { + context.buildConstraintViolationWithTemplate( "If Request Access is false then Terms of Access must be provided.").addConstraintViolation(); + } + + String message = "Constraint violation found in Terms of Use and Access. " + + " If Request Access to restricted files is set to false then Terms of Access must be provided."; + + value.setValidationMessage(message); + } catch (NullPointerException e) { + return false; + } + return false; + } + + + return valid; + } + + public static boolean isTOUAValid(TermsOfUseAndAccess value, ConstraintValidatorContext context){ + + boolean valid = value.isFileAccessRequest() == true || (value.getTermsOfAccess() != null && !value.getTermsOfAccess().isEmpty()); + if (!valid) { + + if (context != null) { + context.buildConstraintViolationWithTemplate("If Request Access is false then Terms of Access must be provided.").addConstraintViolation(); + } + + String message = "Constraint violation found in Terms of Use and Access. " + + " If Request Access to restricted files is set to false then Terms of Access must be provided."; + + value.setValidationMessage(message); + } + return valid; } - + } diff --git a/src/main/java/propertyFiles/Bundle.properties b/src/main/java/propertyFiles/Bundle.properties index fbbda5213ad..621b9116381 100644 --- a/src/main/java/propertyFiles/Bundle.properties +++ b/src/main/java/propertyFiles/Bundle.properties @@ -2124,8 +2124,8 @@ citationFrame.banner.countdownMessage.seconds=seconds #file-edit-popup-fragment.xhtml #editFilesFragment.xhtml dataset.access.accessHeader=Restrict Files and Add Dataset Terms of Access -dataset.access.description=Restricting limits access to published files. You can add or edit Terms of Access for the dataset, and allow people to Request Access to restricted files. - +dataset.access.description=Restricting limits access to published files. Providing information about access to restricted files is required. By default people who want to use these files can request access to them. You can provide Terms of Access instead by unchecking the box and adding them. These settings can be changed when you edit the dataset. Learn about restricting files and dataset access in the User Guide. +dataset.access.description.line.2=One of the following methods for communicating access must be active, and applies to all restricted files in this dataset. #datasetFieldForEditFragment.xhtml dataset.AddReplication=Add "Replication Data for" to Title dataset.replicationDataFor=Replication Data for: diff --git a/src/main/webapp/dataset-license-terms.xhtml b/src/main/webapp/dataset-license-terms.xhtml index c5bdc8638cf..cf623ec8c8a 100644 --- a/src/main/webapp/dataset-license-terms.xhtml +++ b/src/main/webapp/dataset-license-terms.xhtml @@ -277,26 +277,38 @@ -
- -
- -
-
+

+ + + + +

+

+ #{bundle['dataset.access.description.line.2']} +

+
+
- +
+
+ +
+ +
+
@@ -370,7 +382,7 @@ data-toggle="tooltip" data-placement="auto right" data-original-title="#{bundle['file.dataFilesTab.terms.list.termsOfAccess.addInfo.dataAccessPlace.title']}">
- +
diff --git a/src/main/webapp/editFilesFragment.xhtml b/src/main/webapp/editFilesFragment.xhtml index e5e12201fc8..e9cd978c690 100644 --- a/src/main/webapp/editFilesFragment.xhtml +++ b/src/main/webapp/editFilesFragment.xhtml @@ -593,36 +593,49 @@

- #{bundle['dataset.access.description']} -

-
+ + + + +

+

+ #{bundle['dataset.access.description.line.2']} +

+

-
+
-
-
+

-
-
+ From 5a075218be1b83b1273f2af441a0829d18322467 Mon Sep 17 00:00:00 2001 From: Stephen Kraffmiller Date: Wed, 9 Feb 2022 09:46:29 -0500 Subject: [PATCH 18/49] #8191 remove duplicate popup --- .../edu/harvard/iq/dataverse/DatasetPage.java | 10 +++- src/main/webapp/dataset.xhtml | 20 +++---- src/main/webapp/editFilesFragment.xhtml | 58 +------------------ .../webapp/file-edit-popup-fragment.xhtml | 6 +- 4 files changed, 23 insertions(+), 71 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java index cbe64994252..6b608d57dc3 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java @@ -3280,15 +3280,17 @@ public List completeHostDataverseMenuList(String query) { public String restrictFiles(boolean restricted) throws CommandException { List filesToRestrict = new ArrayList(); - if (fileMetadataForAction != null) { filesToRestrict.add(fileMetadataForAction); } else { filesToRestrict = this.getSelectedFiles(); } - restrictFiles(filesToRestrict, restricted); - return save(); + if (editMode == EditMode.CREATE) { + return ""; + } else { + return save(); + } } private void restrictFiles(List filesToRestrict, boolean restricted) throws CommandException { @@ -3622,6 +3624,8 @@ public String save() { if (editMode != null) { if (editMode.equals(EditMode.CREATE)) { + + System.out.print("adding files..."); // We allow users to upload files on Create: int nNewFiles = newFiles.size(); logger.fine("NEW FILES: "+nNewFiles); diff --git a/src/main/webapp/dataset.xhtml b/src/main/webapp/dataset.xhtml index 5f841ad890d..e4721aaf13c 100644 --- a/src/main/webapp/dataset.xhtml +++ b/src/main/webapp/dataset.xhtml @@ -927,17 +927,15 @@ - - - - - - - - - - - + + + + + + + + +

#{bundle['dataset.share.datasetShare.tip']}

diff --git a/src/main/webapp/editFilesFragment.xhtml b/src/main/webapp/editFilesFragment.xhtml index 362ae279187..6558bb47b38 100644 --- a/src/main/webapp/editFilesFragment.xhtml +++ b/src/main/webapp/editFilesFragment.xhtml @@ -440,11 +440,12 @@
  • + update="@([id$=accessPopup])" + oncomplete="PF('accessPopup').show();bind_bsui_components();"> +
  • @@ -608,59 +609,6 @@
  • - - -

    - #{bundle['dataset.access.description']} -

    -

    - - - - -

    -

    -

    - -
    - - - -
    -
    - -
    - -
    - - - -
    -
    -

    -
    - - -
    -
    diff --git a/src/main/webapp/file-edit-popup-fragment.xhtml b/src/main/webapp/file-edit-popup-fragment.xhtml index f194a91c914..50fafc66d31 100644 --- a/src/main/webapp/file-edit-popup-fragment.xhtml +++ b/src/main/webapp/file-edit-popup-fragment.xhtml @@ -44,7 +44,8 @@ data-toggle="tooltip" data-placement="auto right" data-original-title="#{bundle['file.dataFilesTab.terms.list.termsOfAccess.requestAccess.title']}">
    - @@ -59,7 +60,7 @@
    - +
    @@ -72,6 +73,7 @@
    -
    Date: Fri, 11 Feb 2022 17:24:15 -0500 Subject: [PATCH 21/49] #8191 remove out of date comment/code --- .../edu/harvard/iq/dataverse/TermsOfUseAndAccess.java | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/TermsOfUseAndAccess.java b/src/main/java/edu/harvard/iq/dataverse/TermsOfUseAndAccess.java index c4f52d7ffca..a8616283332 100644 --- a/src/main/java/edu/harvard/iq/dataverse/TermsOfUseAndAccess.java +++ b/src/main/java/edu/harvard/iq/dataverse/TermsOfUseAndAccess.java @@ -300,14 +300,6 @@ public void setValidationMessage(String validationMessage) { this.validationMessage = validationMessage; } - /** - * @todo What does the GUI use for a default license? What does the "native" - * API use? See also https://github.com/IQSS/dataverse/issues/1385 - */ - /* - public static TermsOfUseAndAccess.License defaultLicense = TermsOfUseAndAccess.License.CC0; - public static String CC0_URI = "https://creativecommons.org/publicdomain/zero/1.0/"; - */ @Override public int hashCode() { int hash = 0; From 7279c800fab3745634a3f1b4c01ec5094574c9f5 Mon Sep 17 00:00:00 2001 From: Stephen Kraffmiller Date: Wed, 23 Feb 2022 11:07:53 -0500 Subject: [PATCH 22/49] #8191 consolidate delete function --- .../edu/harvard/iq/dataverse/DatasetPage.java | 44 +++++++------------ src/main/webapp/editFilesFragment.xhtml | 6 ++- 2 files changed, 21 insertions(+), 29 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java index 80917d58a1c..cb0539738c6 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java @@ -143,6 +143,7 @@ import edu.harvard.iq.dataverse.search.SearchServiceBean; import edu.harvard.iq.dataverse.search.SearchUtil; import edu.harvard.iq.dataverse.search.SolrClientService; +import edu.harvard.iq.dataverse.util.FileMetadataUtil; import java.util.Comparator; import org.apache.solr.client.solrj.SolrQuery; import org.apache.solr.client.solrj.impl.HttpSolrClient; @@ -3374,7 +3375,16 @@ public String deleteFiles() throws CommandException{ } deleteFiles(filesToDelete); - String retVal = save(); + String retVal; + + if (editMode == EditMode.CREATE) { + workingVersion.setFileMetadatas(new ArrayList<>()); + retVal = ""; + } else { + retVal = save(); + } + + //And delete them only after the dataset is updated for(Embargo emb: orphanedEmbargoes) { embargoService.deleteById(emb.getId(), ((AuthenticatedUser)session.getUser()).getUserIdentifier()); @@ -3409,32 +3419,12 @@ private void deleteFiles(List filesToDelete) { // So below we are deleting the metadata from the version; we are // NOT adding the file to the filesToBeDeleted list that will be // passed to the UpdateDatasetCommand. -- L.A. Aug 2017 - Iterator fmit = dataset.getEditVersion().getFileMetadatas().iterator(); - while (fmit.hasNext()) { - FileMetadata fmd = fmit.next(); - if (markedForDelete.getDataFile().getStorageIdentifier().equals(fmd.getDataFile().getStorageIdentifier())) { - // And if this is an image file that happens to be assigned - // as the dataset thumbnail, let's null the assignment here: - - if (fmd.getDataFile().equals(dataset.getThumbnailFile())) { - dataset.setThumbnailFile(null); - } - /* It should not be possible to get here if this file - is not in fact released! - so the code block below - is not needed. - //if not published then delete identifier - if (!fmd.getDataFile().isReleased()){ - try{ - commandEngine.submit(new DeleteDataFileCommand(fmd.getDataFile(), dvRequestService.getDataverseRequest())); - } catch (CommandException e){ - //this command is here to delete the identifier of unreleased files - //if it fails then a reserved identifier may still be present on the remote provider - } - } */ - fmit.remove(); - break; - } - } + + FileMetadataUtil.removeFileMetadataFromList(workingVersion.getFileMetadatas(), markedForDelete); + + FileMetadataUtil.removeDataFileFromList(newFiles, markedForDelete.getDataFile()); + FileUtil.deleteTempFile(markedForDelete.getDataFile(), dataset, ingestService); + } } diff --git a/src/main/webapp/editFilesFragment.xhtml b/src/main/webapp/editFilesFragment.xhtml index 6558bb47b38..f6b5157a1a5 100644 --- a/src/main/webapp/editFilesFragment.xhtml +++ b/src/main/webapp/editFilesFragment.xhtml @@ -434,8 +434,10 @@
    - -

    #{bundle['file.deleteFileDialog.tip']}

    - -

    #{bundle['file.deleteFileDialog.failed.tip']}

    -
    -
    - - -
    -
    From 76c7c70012cd8382be9deed3b463f510f4f577ab Mon Sep 17 00:00:00 2001 From: Stephen Kraffmiller Date: Fri, 4 Mar 2022 16:43:37 -0500 Subject: [PATCH 24/49] #8191 fix edit metadata popup --- src/main/webapp/dataset.xhtml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/webapp/dataset.xhtml b/src/main/webapp/dataset.xhtml index e4721aaf13c..4a470804ea8 100644 --- a/src/main/webapp/dataset.xhtml +++ b/src/main/webapp/dataset.xhtml @@ -1900,14 +1900,16 @@ function editTerms(){ linkEditTerms(); } - function editMetadata(){ + function editMetadata(){ var validTOA = document.getElementById("datasetForm:validTermsofAccess").value; - if (validTOA === false){ + if (validTOA === 'false'){ PF('blockDatasetForm').show(); PF('accessPopup').show(); - } - editMedatdataCommand(); + } else { + editMedatdataCommand(); + } } + function testCheckBoxes() { var count = PF('versionsTable').getSelectedRowsCount(); if (count !== 2) { From 22fde437e5b5da6bc7f8bc0fcc1020debedc1974 Mon Sep 17 00:00:00 2001 From: Stephen Kraffmiller Date: Mon, 7 Mar 2022 10:08:15 -0500 Subject: [PATCH 25/49] #8191 hide block ds on cancel --- src/main/webapp/file-edit-popup-fragment.xhtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/webapp/file-edit-popup-fragment.xhtml b/src/main/webapp/file-edit-popup-fragment.xhtml index 50fafc66d31..e65670addd4 100644 --- a/src/main/webapp/file-edit-popup-fragment.xhtml +++ b/src/main/webapp/file-edit-popup-fragment.xhtml @@ -75,7 +75,7 @@ disabled="#{empty bean.termsOfAccess and !bean.fileAccessRequest}" onclick="PF('accessPopup').hide();" update=":messagePanel" /> - From 9b782a77009f78dcd667f12d28122b5da464a340 Mon Sep 17 00:00:00 2001 From: Stephen Kraffmiller Date: Wed, 9 Mar 2022 09:31:02 -0500 Subject: [PATCH 26/49] #8191 add validate or die to commands --- .../dataverse/TermsOfUseAndAccessValidator.java | 2 +- .../command/impl/AbstractDatasetCommand.java | 16 +++++++++++----- .../CuratePublishedDatasetVersionCommand.java | 2 +- .../impl/FinalizeDatasetPublicationCommand.java | 4 +++- .../command/impl/PublishDatasetCommand.java | 3 ++- src/main/java/propertyFiles/Bundle.properties | 2 +- 6 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/TermsOfUseAndAccessValidator.java b/src/main/java/edu/harvard/iq/dataverse/TermsOfUseAndAccessValidator.java index cf3edb29d5f..ee094d772e2 100644 --- a/src/main/java/edu/harvard/iq/dataverse/TermsOfUseAndAccessValidator.java +++ b/src/main/java/edu/harvard/iq/dataverse/TermsOfUseAndAccessValidator.java @@ -39,7 +39,7 @@ public static boolean isTOUAValid(TermsOfUseAndAccess value, ConstraintValidator if (!valid) { try { if (context != null) { - context.buildConstraintViolationWithTemplate("If Request Access is false then Terms of Access must be provided.").addConstraintViolation(); + context.buildConstraintViolationWithTemplate(BundleUtil.getStringFromBundle("toua.invalid")).addConstraintViolation(); } value.setValidationMessage(BundleUtil.getStringFromBundle("toua.invalid")); diff --git a/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/AbstractDatasetCommand.java b/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/AbstractDatasetCommand.java index e66b5c9043d..49b357a940b 100644 --- a/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/AbstractDatasetCommand.java +++ b/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/AbstractDatasetCommand.java @@ -21,6 +21,7 @@ import static java.util.stream.Collectors.joining; import javax.validation.ConstraintViolation; import edu.harvard.iq.dataverse.GlobalIdServiceBean; +import edu.harvard.iq.dataverse.TermsOfUseAndAccess; import edu.harvard.iq.dataverse.pidproviders.FakePidProviderServiceBean; /** @@ -96,18 +97,23 @@ protected void createDatasetUser(CommandContext ctxt) { */ protected void validateOrDie(DatasetVersion dsv, Boolean lenient) throws CommandException { Set constraintViolations = dsv.validate(); + if (!constraintViolations.isEmpty()) { if (lenient) { - // populate invalid fields with N/A - constraintViolations.stream() + // populate invalid fields with N/A + // ignore invalid toua + constraintViolations.stream().filter(cv -> cv.getRootBean() instanceof DatasetField) .map(cv -> ((DatasetField) cv.getRootBean())) - .forEach(f -> f.setSingleValue(DatasetField.NA_VALUE)); - - } else { + .forEach(f -> f.setSingleValue(DatasetField.NA_VALUE)); + } else { // explode with a helpful message String validationMessage = constraintViolations.stream() .map(cv -> cv.getMessage() + " (Invalid value:" + cv.getInvalidValue() + ")") .collect(joining(", ", "Validation Failed: ", ".")); + + validationMessage += constraintViolations.stream() + .filter(cv -> cv.getRootBean() instanceof TermsOfUseAndAccess) + .map(cv -> cv.toString()); throw new IllegalCommandException(validationMessage, this); } diff --git a/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/CuratePublishedDatasetVersionCommand.java b/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/CuratePublishedDatasetVersionCommand.java index 24966f0a548..fcc0cda11fc 100644 --- a/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/CuratePublishedDatasetVersionCommand.java +++ b/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/CuratePublishedDatasetVersionCommand.java @@ -34,7 +34,7 @@ public class CuratePublishedDatasetVersionCommand extends AbstractDatasetCommand { private static final Logger logger = Logger.getLogger(CuratePublishedDatasetVersionCommand.class.getCanonicalName()); - final private boolean validateLenient = true; + final private boolean validateLenient = false; public CuratePublishedDatasetVersionCommand(Dataset theDataset, DataverseRequest aRequest) { super(aRequest, theDataset); diff --git a/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/FinalizeDatasetPublicationCommand.java b/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/FinalizeDatasetPublicationCommand.java index 01ac0cf5804..52b7e1c5376 100644 --- a/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/FinalizeDatasetPublicationCommand.java +++ b/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/FinalizeDatasetPublicationCommand.java @@ -84,7 +84,9 @@ public Dataset execute(CommandContext ctxt) throws CommandException { validateDataFiles(theDataset, ctxt); // (this will throw a CommandException if it fails) } - + + validateOrDie(theDataset.getLatestVersion(), false); + /* * Try to register the dataset identifier. For PID providers that have registerWhenPublished == false (all except the FAKE provider at present) * the registerExternalIdentifier command will make one try to create the identifier if needed (e.g. if reserving at dataset creation wasn't done/failed). diff --git a/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/PublishDatasetCommand.java b/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/PublishDatasetCommand.java index 665172a1e9f..8a0e9b91066 100644 --- a/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/PublishDatasetCommand.java +++ b/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/PublishDatasetCommand.java @@ -70,8 +70,9 @@ public PublishDatasetResult execute(CommandContext ctxt) throws CommandException // When importing a released dataset, the latest version is marked as RELEASED. Dataset theDataset = getDataset(); - + validateOrDie(theDataset.getLatestVersion(), false); + //ToDo - any reason to set the version in publish versus finalize? Failure in a prepub workflow or finalize will leave draft versions with an assigned version number as is. //Changing the dataset in this transaction also potentially makes a race condition with a prepub workflow, possibly resulting in an OptimisticLockException there. diff --git a/src/main/java/propertyFiles/Bundle.properties b/src/main/java/propertyFiles/Bundle.properties index 26aed12ab65..1d8601211bf 100644 --- a/src/main/java/propertyFiles/Bundle.properties +++ b/src/main/java/propertyFiles/Bundle.properties @@ -2301,7 +2301,7 @@ email.invalid=is not a valid email address. url.invalid=is not a valid URL. #TermsOfUseAndAccessValidator -toua.invalid=Constraint violation found in Terms of Use and Access. If Request Access to restricted files is set to false then Terms of Access must be provided. +toua.invalid=Constraint violation found in Terms of Use and Access. If restricted files are present then Request Access must be allowed or Terms of Access must be provided. #HarvestingClientsPage.java From 57813947aa310c8d85d03ec45abf926b3c230d5f Mon Sep 17 00:00:00 2001 From: Stephen Kraffmiller Date: Wed, 9 Mar 2022 10:53:42 -0500 Subject: [PATCH 27/49] #8191 add integration test for req/toa validation --- src/main/java/propertyFiles/Bundle.properties | 1 + .../harvard/iq/dataverse/api/DatasetsIT.java | 65 +++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/src/main/java/propertyFiles/Bundle.properties b/src/main/java/propertyFiles/Bundle.properties index 9b22c83ac74..64eab5f3554 100644 --- a/src/main/java/propertyFiles/Bundle.properties +++ b/src/main/java/propertyFiles/Bundle.properties @@ -2510,6 +2510,7 @@ access.api.allowRequests.failure.noSave=Problem saving dataset {0}: {1} access.api.allowRequests.allows=allows access.api.allowRequests.disallows=disallows access.api.allowRequests.success=Dataset {0} {1} file access requests. +access.api.fileAccess.failure.noSave=Could not update Request Access for {0} Error Message {1} access.api.fileAccess.failure.noUser=Could not find user to execute command: {0} access.api.requestAccess.failure.commandError=Problem trying request access on {0} : {1} access.api.requestAccess.failure.requestExists=An access request for this file on your behalf already exists. diff --git a/src/test/java/edu/harvard/iq/dataverse/api/DatasetsIT.java b/src/test/java/edu/harvard/iq/dataverse/api/DatasetsIT.java index 23c17c071ff..96354c37cc3 100644 --- a/src/test/java/edu/harvard/iq/dataverse/api/DatasetsIT.java +++ b/src/test/java/edu/harvard/iq/dataverse/api/DatasetsIT.java @@ -2584,4 +2584,69 @@ public void testFilesUnchangedAfterDatasetMetadataUpdate() throws IOException { } + /** + * In this test we are restricting a file and testing that terms of accees + * or request access is required + * + * Export at the dataset level is always the public version. + * + */ + @Test + public void testRestrictFileTermsOfUseAndAccess() throws IOException { + + Response createUser = UtilIT.createRandomUser(); + createUser.prettyPrint(); + String authorUsername = UtilIT.getUsernameFromResponse(createUser); + String authorApiToken = UtilIT.getApiTokenFromResponse(createUser); + + Response createDataverse = UtilIT.createRandomDataverse(authorApiToken); + createDataverse.prettyPrint(); + createDataverse.then().assertThat() + .statusCode(CREATED.getStatusCode()); + String dataverseAlias = UtilIT.getAliasFromResponse(createDataverse); + + Response createDataset = UtilIT.createRandomDatasetViaNativeApi(dataverseAlias, authorApiToken); + createDataset.prettyPrint(); + createDataset.then().assertThat() + .statusCode(CREATED.getStatusCode()); + + Integer datasetId = UtilIT.getDatasetIdFromResponse(createDataset); + String datasetPid = JsonPath.from(createDataset.asString()).getString("data.persistentId"); + + Path pathToFile = Paths.get(java.nio.file.Files.createTempDirectory(null) + File.separator + "data.csv"); + String contentOfCsv = "" + + "name,pounds,species\n" + + "Marshall,40,dog\n" + + "Tiger,17,cat\n" + + "Panther,21,cat\n"; + java.nio.file.Files.write(pathToFile, contentOfCsv.getBytes()); + + Response uploadFile = UtilIT.uploadFileViaNative(datasetId.toString(), pathToFile.toString(), authorApiToken); + uploadFile.prettyPrint(); + uploadFile.then().assertThat() + .statusCode(OK.getStatusCode()) + .body("data.files[0].label", equalTo("data.csv")); + + String fileId = JsonPath.from(uploadFile.body().asString()).getString("data.files[0].dataFile.id"); + + assertTrue("Failed test if Ingest Lock exceeds max duration " + pathToFile, UtilIT.sleepForLock(datasetId.longValue(), "Ingest", authorApiToken, UtilIT.MAXIMUM_INGEST_LOCK_DURATION)); + + Response restrictFile = UtilIT.restrictFile(fileId, true, authorApiToken); + restrictFile.prettyPrint(); + restrictFile.then().assertThat().statusCode(OK.getStatusCode()); + + Response publishDataverse = UtilIT.publishDataverseViaNativeApi(dataverseAlias, authorApiToken); + publishDataverse.then().assertThat().statusCode(OK.getStatusCode()); + Response publishDataset = UtilIT.publishDatasetViaNativeApi(datasetPid, "major", authorApiToken); + publishDataset.then().assertThat().statusCode(OK.getStatusCode()); + + + //not allowed to remove request access if there are retricted files + + Response disallowRequestAccess = UtilIT.allowAccessRequests(datasetPid, false, authorApiToken); + disallowRequestAccess.prettyPrint(); + disallowRequestAccess.then().assertThat().statusCode(BAD_REQUEST.getStatusCode()); + + } + } From 8da1b43921f2e7d0ee1bd5c824fd5e10eb3e5370 Mon Sep 17 00:00:00 2001 From: Stephen Kraffmiller Date: Thu, 10 Mar 2022 11:11:32 -0500 Subject: [PATCH 28/49] #8191 fix default values disable edits --- .../edu/harvard/iq/dataverse/DatasetPage.java | 3 ++- .../harvard/iq/dataverse/DatasetVersion.java | 1 + src/main/webapp/dataset.xhtml | 17 ++++++++++++++--- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java index 2374c3841fd..24830722a5b 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java @@ -2056,7 +2056,8 @@ private String init(boolean initFull) { JH.addMessage(FacesMessage.SEVERITY_WARN, BundleUtil.getStringFromBundle("dataset.message.label.fileAccess"), BundleUtil.getStringFromBundle("dataset.message.publicInstall")); } - + setFileAccessRequest(workingVersion.getTermsOfUseAndAccess().isFileAccessRequest()); + setTermsOfAccess(workingVersion.getTermsOfUseAndAccess().getTermsOfAccess()); resetVersionUI(); // FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Add New Dataset", " - Enter metadata to create the dataset's citation. You can add more metadata about this dataset after it's created.")); diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java b/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java index c2fe5dd646b..fc8f31c1aaa 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java @@ -647,6 +647,7 @@ public void initDefaultValues(License license) { TermsOfUseAndAccess terms = new TermsOfUseAndAccess(); terms.setDatasetVersion(this); terms.setLicense(license); + terms.setFileAccessRequest(true); this.setTermsOfUseAndAccess(terms); } diff --git a/src/main/webapp/dataset.xhtml b/src/main/webapp/dataset.xhtml index 19a2b0204a0..a322cf1c3f9 100644 --- a/src/main/webapp/dataset.xhtml +++ b/src/main/webapp/dataset.xhtml @@ -370,14 +370,25 @@