From 42b695871c4faab715d96de6413ef6dfb296b57a Mon Sep 17 00:00:00 2001 From: Eryk Kulikowski Date: Fri, 20 Oct 2023 18:19:27 +0200 Subject: [PATCH 01/44] disable s3 tagging JVM option --- .../10022_upload_redirect_without_tagging.md | 1 + .../source/installation/config.rst | 8 +++ .../iq/dataverse/dataaccess/S3AccessIO.java | 11 ++- .../iq/dataverse/settings/JvmSettings.java | 2 + src/main/webapp/resources/js/fileupload.js | 70 ++++++++++--------- 5 files changed, 57 insertions(+), 35 deletions(-) create mode 100644 doc/release-notes/10022_upload_redirect_without_tagging.md diff --git a/doc/release-notes/10022_upload_redirect_without_tagging.md b/doc/release-notes/10022_upload_redirect_without_tagging.md new file mode 100644 index 00000000000..379c7c8f1e0 --- /dev/null +++ b/doc/release-notes/10022_upload_redirect_without_tagging.md @@ -0,0 +1 @@ +If your S3 store does not support tagging and gives an error when redirecting uploads, from now on, you can disable the tagging by using the ``dataverse.files..disable-tagging`` JVM option. Disabling the tagging can result in leftover files that are not used by your Dataverse instance and should be removed to preserve the storage space. To clean up the leftover files, you can use the [Cleanup Storage of a Dataset](https://guides.dataverse.org/en/5.13/api/native-api.html#cleanup-storage-of-a-dataset) API endpoint. diff --git a/doc/sphinx-guides/source/installation/config.rst b/doc/sphinx-guides/source/installation/config.rst index ce8876b012c..2b5fd75977c 100644 --- a/doc/sphinx-guides/source/installation/config.rst +++ b/doc/sphinx-guides/source/installation/config.rst @@ -792,6 +792,13 @@ Larger installations may want to increase the number of open S3 connections allo ``./asadmin create-jvm-options "-Ddataverse.files..connection-pool-size=4096"`` +By default, when redirecting an upload to the S3 storage, the Dataverse will place a ``temp`` tag on the file being uploaded for an easier cleanup when the file is not added to the dataset after upload (e.g., when the user cancels the operation). +If your S3 store does not support tagging and gives an error when redirecting uploads, you can disable that tag by using the ``dataverse.files..disable-tagging`` JVM option. For example: + +``./asadmin create-jvm-options "-Ddataverse.files..disable-tagging=true"`` + +Disabling the ``temp`` tag can result in leftover files that are not used by your Dataverse instance and should be removed to preserve the storage space. To clean up the leftover files, you can use the [Cleanup Storage of a Dataset](https://guides.dataverse.org/en/5.13/api/native-api.html#cleanup-storage-of-a-dataset) API endpoint. + In case you would like to configure Dataverse to use a custom S3 service instead of Amazon S3 services, please add the options for the custom URL and region as documented below. Please read above if your desired combination has been tested already and what other options have been set for a successful integration. @@ -825,6 +832,7 @@ List of S3 Storage Options dataverse.files..payload-signing ``true``/``false`` Enable payload signing. Optional ``false`` dataverse.files..chunked-encoding ``true``/``false`` Disable chunked encoding. Optional ``true`` dataverse.files..connection-pool-size The maximum number of open connections to the S3 server ``256`` + dataverse.files..disable-tagging ``true``/``false`` Do not place the ``temp`` tag when redirecting the upload to the S3 server ``false`` =========================================== ================== =================================================================================== ============= .. table:: diff --git a/src/main/java/edu/harvard/iq/dataverse/dataaccess/S3AccessIO.java b/src/main/java/edu/harvard/iq/dataverse/dataaccess/S3AccessIO.java index 822ada0b83e..c904651e81f 100644 --- a/src/main/java/edu/harvard/iq/dataverse/dataaccess/S3AccessIO.java +++ b/src/main/java/edu/harvard/iq/dataverse/dataaccess/S3AccessIO.java @@ -39,6 +39,7 @@ import edu.harvard.iq.dataverse.Dataverse; import edu.harvard.iq.dataverse.DvObject; import edu.harvard.iq.dataverse.datavariable.DataVariable; +import edu.harvard.iq.dataverse.settings.JvmSettings; import edu.harvard.iq.dataverse.util.FileUtil; import opennlp.tools.util.StringUtil; @@ -985,7 +986,10 @@ private String generateTemporaryS3UploadUrl(String key, Date expiration) throws GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(bucketName, key).withMethod(HttpMethod.PUT).withExpiration(expiration); //Require user to add this header to indicate a temporary file - generatePresignedUrlRequest.putCustomRequestHeader(Headers.S3_TAGGING, "dv-state=temp"); + final boolean taggingDisabled = JvmSettings.DISABLE_S3_TAGGING.lookupOptional(Boolean.class, this.driverId).orElse(false); + if (!taggingDisabled) { + generatePresignedUrlRequest.putCustomRequestHeader(Headers.S3_TAGGING, "dv-state=temp"); + } URL presignedUrl; try { @@ -1034,7 +1038,10 @@ public JsonObjectBuilder generateTemporaryS3UploadUrls(String globalId, String s } else { JsonObjectBuilder urls = Json.createObjectBuilder(); InitiateMultipartUploadRequest initiationRequest = new InitiateMultipartUploadRequest(bucketName, key); - initiationRequest.putCustomRequestHeader(Headers.S3_TAGGING, "dv-state=temp"); + final boolean taggingDisabled = JvmSettings.DISABLE_S3_TAGGING.lookupOptional(Boolean.class, this.driverId).orElse(false); + if (!taggingDisabled) { + initiationRequest.putCustomRequestHeader(Headers.S3_TAGGING, "dv-state=temp"); + } InitiateMultipartUploadResult initiationResponse = s3.initiateMultipartUpload(initiationRequest); String uploadId = initiationResponse.getUploadId(); for (int i = 1; i <= (fileSize / minPartSize) + (fileSize % minPartSize > 0 ? 1 : 0); i++) { diff --git a/src/main/java/edu/harvard/iq/dataverse/settings/JvmSettings.java b/src/main/java/edu/harvard/iq/dataverse/settings/JvmSettings.java index cc3272413c7..794ffd5e0af 100644 --- a/src/main/java/edu/harvard/iq/dataverse/settings/JvmSettings.java +++ b/src/main/java/edu/harvard/iq/dataverse/settings/JvmSettings.java @@ -50,6 +50,8 @@ public enum JvmSettings { UPLOADS_DIRECTORY(SCOPE_FILES, "uploads"), DOCROOT_DIRECTORY(SCOPE_FILES, "docroot"), GUESTBOOK_AT_REQUEST(SCOPE_FILES, "guestbook-at-request"), + SCOPE_DRIVER(SCOPE_FILES), + DISABLE_S3_TAGGING(SCOPE_DRIVER, "disable-tagging"), // SOLR INDEX SETTINGS SCOPE_SOLR(PREFIX, "solr"), diff --git a/src/main/webapp/resources/js/fileupload.js b/src/main/webapp/resources/js/fileupload.js index 08d6956b62c..03ec82f214b 100644 --- a/src/main/webapp/resources/js/fileupload.js +++ b/src/main/webapp/resources/js/fileupload.js @@ -192,41 +192,45 @@ var fileUpload = class fileUploadClass { progBar.html(''); progBar.append($('').attr('class', 'ui-progressbar ui-widget ui-widget-content ui-corner-all')); if(this.urls.hasOwnProperty("url")) { - $.ajax({ - url: this.urls.url, - headers: { "x-amz-tagging": "dv-state=temp" }, - type: 'PUT', - data: this.file, - context:this, - cache: false, - processData: false, - success: function() { - //ToDo - cancelling abandons the file. It is marked as temp so can be cleaned up later, but would be good to remove now (requires either sending a presigned delete URL or adding a callback to delete only a temp file - if(!cancelled) { - this.reportUpload(); - } - }, - error: function(jqXHR, textStatus, errorThrown) { - console.log('Failure: ' + jqXHR.status); - console.log('Failure: ' + errorThrown); - uploadFailure(jqXHR, thisFile); - }, - xhr: function() { - var myXhr = $.ajaxSettings.xhr(); - if (myXhr.upload) { - myXhr.upload.addEventListener('progress', function(e) { - if (e.lengthComputable) { - var doublelength = 2 * e.total; - progBar.children('progress').attr({ - value: e.loaded, - max: doublelength - }); - } - }); + const url = this.urls.url; + const request = { + url: url, + type: 'PUT', + data: this.file, + context:this, + cache: false, + processData: false, + success: function() { + //ToDo - cancelling abandons the file. It is marked as temp so can be cleaned up later, but would be good to remove now (requires either sending a presigned delete URL or adding a callback to delete only a temp file + if(!cancelled) { + this.reportUpload(); + } + }, + error: function(jqXHR, textStatus, errorThrown) { + console.log('Failure: ' + jqXHR.status); + console.log('Failure: ' + errorThrown); + uploadFailure(jqXHR, thisFile); + }, + xhr: function() { + var myXhr = $.ajaxSettings.xhr(); + if (myXhr.upload) { + myXhr.upload.addEventListener('progress', function(e) { + if (e.lengthComputable) { + var doublelength = 2 * e.total; + progBar.children('progress').attr({ + value: e.loaded, + max: doublelength + }); + } + }); + } + return myXhr; } - return myXhr; + }; + if (url.includes("x-amz-tagging")) { + request.headers = { "x-amz-tagging": "dv-state=temp" }; } - }); + $.ajax(request); } else { var loaded=[]; this.etags=[]; From 61ecb32e1e9836a613cea2f71e8376dee400ac4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20ROUCOU?= Date: Thu, 15 Feb 2024 15:03:33 +0100 Subject: [PATCH 02/44] CVOC : add HTTP request headers --- .../harvard/iq/dataverse/DatasetFieldServiceBean.java | 9 ++++++++- src/main/webapp/datasetFieldForEditFragment.xhtml | 1 + src/main/webapp/metadataFragment.xhtml | 4 ++++ src/main/webapp/search-include-fragment.xhtml | 4 ++++ src/main/webapp/search/advanced.xhtml | 1 + 5 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetFieldServiceBean.java b/src/main/java/edu/harvard/iq/dataverse/DatasetFieldServiceBean.java index ce2b00086ec..b05dd6b40c0 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetFieldServiceBean.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetFieldServiceBean.java @@ -502,7 +502,14 @@ public void process(HttpResponse response, HttpContext context) throws HttpExcep HttpGet httpGet = new HttpGet(retrievalUri); //application/json+ld is for backward compatibility httpGet.addHeader("Accept", "application/ld+json, application/json+ld, application/json"); - + //Adding others custom HTTP request headers if exists + final JsonObject headers = cvocEntry.getJsonObject("headers"); + if (headers != null) { + final Set headerKeys = headers.keySet(); + for (final String hKey: headerKeys) { + httpGet.addHeader(hKey, headers.getString(hKey)); + } + } HttpResponse response = httpClient.execute(httpGet); String data = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8); int statusCode = response.getStatusLine().getStatusCode(); diff --git a/src/main/webapp/datasetFieldForEditFragment.xhtml b/src/main/webapp/datasetFieldForEditFragment.xhtml index e72ee351ea0..d8c005366cb 100644 --- a/src/main/webapp/datasetFieldForEditFragment.xhtml +++ b/src/main/webapp/datasetFieldForEditFragment.xhtml @@ -42,6 +42,7 @@ + diff --git a/src/main/webapp/metadataFragment.xhtml b/src/main/webapp/metadataFragment.xhtml index 200d2917b9a..1cf4ac0bc71 100755 --- a/src/main/webapp/metadataFragment.xhtml +++ b/src/main/webapp/metadataFragment.xhtml @@ -88,6 +88,7 @@ escape="#{dsf.datasetFieldType.isEscapeOutputText()}"> + @@ -100,6 +101,7 @@ escape="#{dsf.datasetFieldType.isEscapeOutputText()}"> + @@ -146,6 +148,7 @@ rendered="${cvocOnCvPart and cvPart.key.datasetFieldType.name.equals(cvocConf.get(cvPart.key.datasetFieldType.id).getString('term-uri-field'))}"> + @@ -156,6 +159,7 @@ rendered="${cvocOnDsf and cvPart.key.datasetFieldType.name.equals(cvocConf.get(dsf.datasetFieldType.id).getString('term-uri-field'))}"> + diff --git a/src/main/webapp/search-include-fragment.xhtml b/src/main/webapp/search-include-fragment.xhtml index af568170157..2eed454800d 100644 --- a/src/main/webapp/search-include-fragment.xhtml +++ b/src/main/webapp/search-include-fragment.xhtml @@ -213,6 +213,7 @@ + @@ -234,6 +235,7 @@ + @@ -384,6 +386,7 @@ + @@ -621,6 +624,7 @@ + diff --git a/src/main/webapp/search/advanced.xhtml b/src/main/webapp/search/advanced.xhtml index 06e662064e7..24b78ba0dc9 100644 --- a/src/main/webapp/search/advanced.xhtml +++ b/src/main/webapp/search/advanced.xhtml @@ -121,6 +121,7 @@ + From 25cf3ff5c54fe8d3ee767688e39ff1527d7ce0d0 Mon Sep 17 00:00:00 2001 From: zearaujo25 Date: Wed, 27 Mar 2024 18:29:53 -0300 Subject: [PATCH 03/44] 9887: Adding new endpoint to make superuser call idempotent --- .../edu/harvard/iq/dataverse/api/Admin.java | 32 +++++++++++++++---- .../edu/harvard/iq/dataverse/api/AdminIT.java | 14 +++++++- .../edu/harvard/iq/dataverse/api/RolesIT.java | 2 +- .../edu/harvard/iq/dataverse/api/UtilIT.java | 5 +++ 4 files changed, 44 insertions(+), 9 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/api/Admin.java b/src/main/java/edu/harvard/iq/dataverse/api/Admin.java index d098c2fe16a..86b4f5ee679 100644 --- a/src/main/java/edu/harvard/iq/dataverse/api/Admin.java +++ b/src/main/java/edu/harvard/iq/dataverse/api/Admin.java @@ -1035,15 +1035,33 @@ public Response toggleSuperuser(@PathParam("identifier") String identifier) { ActionLogRecord alr = new ActionLogRecord(ActionLogRecord.ActionType.Admin, "toggleSuperuser") .setInfo(identifier); try { - AuthenticatedUser user = authSvc.getAuthenticatedUser(identifier); - if (user.isDeactivated()) { - return error(Status.BAD_REQUEST, "You cannot make a deactivated user a superuser."); - } + final AuthenticatedUser user = authSvc.getAuthenticatedUser(identifier); + return changeSuperUserStatus(user, !user.isSuperuser()); + } catch (Exception e) { + alr.setActionResult(ActionLogRecord.Result.InternalError); + alr.setInfo(alr.getInfo() + "// " + e.getMessage()); + return error(Response.Status.INTERNAL_SERVER_ERROR, e.getMessage()); + } finally { + actionLogSvc.log(alr); + } + } - user.setSuperuser(!user.isSuperuser()); + private Response changeSuperUserStatus(AuthenticatedUser user, Boolean isSuperuser) { + if (user.isDeactivated()) { + return error(Status.BAD_REQUEST, "You cannot make a deactivated user a superuser."); + } + user.setSuperuser(isSuperuser); + return ok("User " + user.getIdentifier() + " " + (user.isSuperuser() ? "set" : "removed") + + " as a superuser."); + } - return ok("User " + user.getIdentifier() + " " + (user.isSuperuser() ? "set" : "removed") - + " as a superuser."); + @Path("superuser/{identifier}") + @PUT + public Response changeSuperUserStatus(@PathParam("identifier") String identifier, Boolean isSuperUser) { + ActionLogRecord alr = new ActionLogRecord(ActionLogRecord.ActionType.Admin, "changeSuperUserStatus") + .setInfo(identifier + ":" + isSuperUser); + try { + return changeSuperUserStatus(authSvc.getAuthenticatedUser(identifier), isSuperUser); } catch (Exception e) { alr.setActionResult(ActionLogRecord.Result.InternalError); alr.setInfo(alr.getInfo() + "// " + e.getMessage()); diff --git a/src/test/java/edu/harvard/iq/dataverse/api/AdminIT.java b/src/test/java/edu/harvard/iq/dataverse/api/AdminIT.java index b9bf09cfe68..bb5c2ba34bd 100644 --- a/src/test/java/edu/harvard/iq/dataverse/api/AdminIT.java +++ b/src/test/java/edu/harvard/iq/dataverse/api/AdminIT.java @@ -21,7 +21,8 @@ import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.BeforeAll; - +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import java.util.Map; import java.util.UUID; import java.util.logging.Logger; @@ -895,4 +896,15 @@ private String createTestNonSuperuserApiToken() { createUserResponse.then().assertThat().statusCode(OK.getStatusCode()); return UtilIT.getApiTokenFromResponse(createUserResponse); } + + @ParameterizedTest + @ValueSource(booleans={true,false}) + public void testChangeSuperUserStatus(Boolean status) { + Response createUser = UtilIT.createRandomUser(); + createUser.then().assertThat().statusCode(OK.getStatusCode()); + String username = UtilIT.getUsernameFromResponse(createUser); + Response toggleSuperuser = UtilIT.changeSuperUserStatus(username, status); + toggleSuperuser.then().assertThat() + .statusCode(OK.getStatusCode()); + } } diff --git a/src/test/java/edu/harvard/iq/dataverse/api/RolesIT.java b/src/test/java/edu/harvard/iq/dataverse/api/RolesIT.java index 8b5ac917dea..d15fda3a1a1 100644 --- a/src/test/java/edu/harvard/iq/dataverse/api/RolesIT.java +++ b/src/test/java/edu/harvard/iq/dataverse/api/RolesIT.java @@ -18,7 +18,7 @@ */ public class RolesIT { - private static final Logger logger = Logger.getLogger(AdminIT.class.getCanonicalName()); + private static final Logger logger = Logger.getLogger(RolesIT.class.getCanonicalName()); @BeforeAll public static void setUp() { diff --git a/src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java b/src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java index 080ca0c43e9..9a409ba97fb 100644 --- a/src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java +++ b/src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java @@ -1525,6 +1525,11 @@ static Response makeSuperUser(String username) { return response; } + static Response changeSuperUserStatus(String username, Boolean isSuperUser) { + Response response = given().body(isSuperUser).put("/api/admin/superuser/" + username); + return response; + } + static Response reindexDataset(String persistentId) { Response response = given() .get("/api/admin/index/dataset?persistentId=" + persistentId); From bd929670b70f8ee924ccef1cf91c89704622b766 Mon Sep 17 00:00:00 2001 From: qqmyers Date: Thu, 28 Mar 2024 17:25:58 -0400 Subject: [PATCH 04/44] Always need file list for Globus --- .../edu/harvard/iq/dataverse/globus/GlobusServiceBean.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/globus/GlobusServiceBean.java b/src/main/java/edu/harvard/iq/dataverse/globus/GlobusServiceBean.java index 9fda7a0f7f1..ebd1f943a50 100644 --- a/src/main/java/edu/harvard/iq/dataverse/globus/GlobusServiceBean.java +++ b/src/main/java/edu/harvard/iq/dataverse/globus/GlobusServiceBean.java @@ -1257,11 +1257,11 @@ public void writeGuestbookAndStartTransfer(GuestbookResponse guestbookResponse, Long fileId = Long.parseLong(idAsString); // If we need to create a GuestBookResponse record, we have to // look up the DataFile object for this file: + df = dataFileService.findCheapAndEasy(fileId); + selectedFiles.add(df); if (!doNotSaveGuestbookResponse) { - df = dataFileService.findCheapAndEasy(fileId); guestbookResponse.setDataFile(df); fileDownloadService.writeGuestbookResponseRecord(guestbookResponse); - selectedFiles.add(df); } } catch (NumberFormatException nfe) { logger.warning( From 16ed8cc2255195c88375aa1e380c846f60d8706d Mon Sep 17 00:00:00 2001 From: zearaujo25 Date: Thu, 28 Mar 2024 19:11:27 -0300 Subject: [PATCH 05/44] 9887: Adding documentation and deprecation tag --- .../9887-new-superuser-status-endpoint.md | 1 + doc/sphinx-guides/source/api/native-api.rst | 23 ++++++++++++++++++- .../edu/harvard/iq/dataverse/api/Admin.java | 1 + 3 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 doc/release-notes/9887-new-superuser-status-endpoint.md diff --git a/doc/release-notes/9887-new-superuser-status-endpoint.md b/doc/release-notes/9887-new-superuser-status-endpoint.md new file mode 100644 index 00000000000..4069d3cc04b --- /dev/null +++ b/doc/release-notes/9887-new-superuser-status-endpoint.md @@ -0,0 +1 @@ +Adding a new endpoint to make supersuser status change calls idempotent. Also Deprecating and renaming the old API. \ No newline at end of file diff --git a/doc/sphinx-guides/source/api/native-api.rst b/doc/sphinx-guides/source/api/native-api.rst index 144e3ac8e5e..7fed31c5438 100644 --- a/doc/sphinx-guides/source/api/native-api.rst +++ b/doc/sphinx-guides/source/api/native-api.rst @@ -5306,13 +5306,34 @@ Example: ``curl -H "X-Dataverse-key: $API_TOKEN" -X POST "https://demo.datavers This action changes the identifier of user johnsmith to jsmith. -Make User a SuperUser +Toggle User superuser powers ~~~~~~~~~~~~~~~~~~~~~ Toggles superuser mode on the ``AuthenticatedUser`` whose ``identifier`` (without the ``@`` sign) is passed. :: POST http://$SERVER/api/admin/superuser/$identifier +.. note:: this endpoint is deprecated. Use the change superuser status endpoint + +.. _change-superuser-status: + +Change superuser status +~~~~~~~~~~~~~~~~~~~~~ +Changes a user superuser power status with a boolean value + +.. code-block:: bash + + export SERVER_URL=http://localhost:8080 + export USERNAME=jdoe + export IS_SUPERUSER=true + curl -X PUT "$SERVER/api/admin/superuser/$USERNAME" --data "$IS_SUPERUSER" + +The fully expanded example above (without environment variables) looks like this: + +.. code-block:: bash + + curl -X PUT "http://localhost:8080/api/admin/superuser/jdoe" --data "true" + .. _delete-a-user: Delete a User diff --git a/src/main/java/edu/harvard/iq/dataverse/api/Admin.java b/src/main/java/edu/harvard/iq/dataverse/api/Admin.java index 86b4f5ee679..95dd8899978 100644 --- a/src/main/java/edu/harvard/iq/dataverse/api/Admin.java +++ b/src/main/java/edu/harvard/iq/dataverse/api/Admin.java @@ -1030,6 +1030,7 @@ public Response deleteRole(@Context ContainerRequestContext crc, @PathParam("id" } @Path("superuser/{identifier}") + @Deprecated @POST public Response toggleSuperuser(@PathParam("identifier") String identifier) { ActionLogRecord alr = new ActionLogRecord(ActionLogRecord.ActionType.Admin, "toggleSuperuser") From 5570bec5a2559e5607073cb4b01ac1c104016c58 Mon Sep 17 00:00:00 2001 From: zearaujo25 Date: Thu, 28 Mar 2024 19:20:16 -0300 Subject: [PATCH 06/44] 9887: Fixing documentation --- doc/sphinx-guides/source/api/native-api.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/sphinx-guides/source/api/native-api.rst b/doc/sphinx-guides/source/api/native-api.rst index 7fed31c5438..eec5c17a52d 100644 --- a/doc/sphinx-guides/source/api/native-api.rst +++ b/doc/sphinx-guides/source/api/native-api.rst @@ -5307,7 +5307,7 @@ Example: ``curl -H "X-Dataverse-key: $API_TOKEN" -X POST "https://demo.datavers This action changes the identifier of user johnsmith to jsmith. Toggle User superuser powers -~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Toggles superuser mode on the ``AuthenticatedUser`` whose ``identifier`` (without the ``@`` sign) is passed. :: @@ -5318,7 +5318,7 @@ Toggles superuser mode on the ``AuthenticatedUser`` whose ``identifier`` (withou .. _change-superuser-status: Change superuser status -~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~ Changes a user superuser power status with a boolean value .. code-block:: bash From e1bed704e0ff256f3d4ea8547f038ebe38e080cb Mon Sep 17 00:00:00 2001 From: Jose Lucas Cordeiro Date: Fri, 29 Mar 2024 12:51:30 -0300 Subject: [PATCH 07/44] Update doc/sphinx-guides/source/api/native-api.rst Co-authored-by: Philip Durbin --- doc/sphinx-guides/source/api/native-api.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/sphinx-guides/source/api/native-api.rst b/doc/sphinx-guides/source/api/native-api.rst index eec5c17a52d..48d49ed40ba 100644 --- a/doc/sphinx-guides/source/api/native-api.rst +++ b/doc/sphinx-guides/source/api/native-api.rst @@ -5306,8 +5306,8 @@ Example: ``curl -H "X-Dataverse-key: $API_TOKEN" -X POST "https://demo.datavers This action changes the identifier of user johnsmith to jsmith. -Toggle User superuser powers -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Toggle Superuser Status +~~~~~~~~~~~~~~~~~~~~~~~ Toggles superuser mode on the ``AuthenticatedUser`` whose ``identifier`` (without the ``@`` sign) is passed. :: From e5aca34e452bd8ce1f8c8e5769d96e7b8883b214 Mon Sep 17 00:00:00 2001 From: Jose Lucas Cordeiro Date: Fri, 29 Mar 2024 12:51:44 -0300 Subject: [PATCH 08/44] Update doc/sphinx-guides/source/api/native-api.rst Co-authored-by: Philip Durbin --- doc/sphinx-guides/source/api/native-api.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/doc/sphinx-guides/source/api/native-api.rst b/doc/sphinx-guides/source/api/native-api.rst index 48d49ed40ba..5205cccea5f 100644 --- a/doc/sphinx-guides/source/api/native-api.rst +++ b/doc/sphinx-guides/source/api/native-api.rst @@ -5317,9 +5317,10 @@ Toggles superuser mode on the ``AuthenticatedUser`` whose ``identifier`` (withou .. _change-superuser-status: -Change superuser status -~~~~~~~~~~~~~~~~~~~~~~~ -Changes a user superuser power status with a boolean value +Set Superuser Status +~~~~~~~~~~~~~~~~~~~~ + +Specify the superuser status of a user with a boolean value. .. code-block:: bash From 4444c0a4d9b757f6f6a4a5ef5e85e455c5ba98fc Mon Sep 17 00:00:00 2001 From: Jose Lucas Cordeiro Date: Fri, 29 Mar 2024 12:52:25 -0300 Subject: [PATCH 09/44] Update doc/sphinx-guides/source/api/native-api.rst Co-authored-by: Philip Durbin --- doc/sphinx-guides/source/api/native-api.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/sphinx-guides/source/api/native-api.rst b/doc/sphinx-guides/source/api/native-api.rst index 5205cccea5f..8808c0b5400 100644 --- a/doc/sphinx-guides/source/api/native-api.rst +++ b/doc/sphinx-guides/source/api/native-api.rst @@ -5313,7 +5313,7 @@ Toggles superuser mode on the ``AuthenticatedUser`` whose ``identifier`` (withou POST http://$SERVER/api/admin/superuser/$identifier -.. note:: this endpoint is deprecated. Use the change superuser status endpoint +.. note:: This endpoint is deprecated. Use the set superuser status endpoint instead. .. _change-superuser-status: From 7008b350c28b67cafa8d2db8954532a1426e8971 Mon Sep 17 00:00:00 2001 From: Jose Lucas Cordeiro Date: Fri, 29 Mar 2024 12:52:57 -0300 Subject: [PATCH 10/44] Update doc/release-notes/9887-new-superuser-status-endpoint.md Co-authored-by: Philip Durbin --- doc/release-notes/9887-new-superuser-status-endpoint.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/release-notes/9887-new-superuser-status-endpoint.md b/doc/release-notes/9887-new-superuser-status-endpoint.md index 4069d3cc04b..01b1f539f7a 100644 --- a/doc/release-notes/9887-new-superuser-status-endpoint.md +++ b/doc/release-notes/9887-new-superuser-status-endpoint.md @@ -1 +1 @@ -Adding a new endpoint to make supersuser status change calls idempotent. Also Deprecating and renaming the old API. \ No newline at end of file +The existing API endpoint for toggling the superuser status of a user has been deprecated in favor of a new API endpoint that allows you to explicitly and idempotently set the status as true or false. For details, see [the guides](https://dataverse-guide--10440.org.readthedocs.build/en/10440/api/native-api.html), #9887 and #10440. \ No newline at end of file From 532e7f0e738544413219d730f7763f5c59230623 Mon Sep 17 00:00:00 2001 From: zearaujo25 Date: Fri, 29 Mar 2024 14:12:22 -0300 Subject: [PATCH 11/44] 9887: code review --- doc/sphinx-guides/source/api/changelog.rst | 5 +++++ doc/sphinx-guides/source/api/native-api.rst | 2 +- src/main/java/edu/harvard/iq/dataverse/api/Admin.java | 8 ++++---- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/doc/sphinx-guides/source/api/changelog.rst b/doc/sphinx-guides/source/api/changelog.rst index 025a2069d6e..5e55ff46235 100644 --- a/doc/sphinx-guides/source/api/changelog.rst +++ b/doc/sphinx-guides/source/api/changelog.rst @@ -7,6 +7,11 @@ This API changelog is experimental and we would love feedback on its usefulness. :local: :depth: 1 +v6.3 +---- + +- **/api/admin/superuser/{identifier}**: The POST endpoint is being deprecated in favor for the PUT,which we can specifically set the superuser status in the body. + v6.2 ---- diff --git a/doc/sphinx-guides/source/api/native-api.rst b/doc/sphinx-guides/source/api/native-api.rst index 8808c0b5400..f51eaf31da5 100644 --- a/doc/sphinx-guides/source/api/native-api.rst +++ b/doc/sphinx-guides/source/api/native-api.rst @@ -5333,7 +5333,7 @@ The fully expanded example above (without environment variables) looks like this .. code-block:: bash - curl -X PUT "http://localhost:8080/api/admin/superuser/jdoe" --data "true" + curl -X PUT "http://localhost:8080/api/admin/superuser/jdoe" -d "true" .. _delete-a-user: diff --git a/src/main/java/edu/harvard/iq/dataverse/api/Admin.java b/src/main/java/edu/harvard/iq/dataverse/api/Admin.java index 95dd8899978..1e463a7e19d 100644 --- a/src/main/java/edu/harvard/iq/dataverse/api/Admin.java +++ b/src/main/java/edu/harvard/iq/dataverse/api/Admin.java @@ -1037,7 +1037,7 @@ public Response toggleSuperuser(@PathParam("identifier") String identifier) { .setInfo(identifier); try { final AuthenticatedUser user = authSvc.getAuthenticatedUser(identifier); - return changeSuperUserStatus(user, !user.isSuperuser()); + return setSuperuserStatus(user, !user.isSuperuser()); } catch (Exception e) { alr.setActionResult(ActionLogRecord.Result.InternalError); alr.setInfo(alr.getInfo() + "// " + e.getMessage()); @@ -1047,7 +1047,7 @@ public Response toggleSuperuser(@PathParam("identifier") String identifier) { } } - private Response changeSuperUserStatus(AuthenticatedUser user, Boolean isSuperuser) { + private Response setSuperuserStatus(AuthenticatedUser user, Boolean isSuperuser) { if (user.isDeactivated()) { return error(Status.BAD_REQUEST, "You cannot make a deactivated user a superuser."); } @@ -1058,11 +1058,11 @@ private Response changeSuperUserStatus(AuthenticatedUser user, Boolean isSuperus @Path("superuser/{identifier}") @PUT - public Response changeSuperUserStatus(@PathParam("identifier") String identifier, Boolean isSuperUser) { + public Response setSuperuserStatus(@PathParam("identifier") String identifier, Boolean isSuperUser) { ActionLogRecord alr = new ActionLogRecord(ActionLogRecord.ActionType.Admin, "changeSuperUserStatus") .setInfo(identifier + ":" + isSuperUser); try { - return changeSuperUserStatus(authSvc.getAuthenticatedUser(identifier), isSuperUser); + return setSuperuserStatus(authSvc.getAuthenticatedUser(identifier), isSuperUser); } catch (Exception e) { alr.setActionResult(ActionLogRecord.Result.InternalError); alr.setInfo(alr.getInfo() + "// " + e.getMessage()); From 74f6c4ac8802dadf9355ad9c4af5d3560255a5b2 Mon Sep 17 00:00:00 2001 From: Jose Lucas Cordeiro Date: Fri, 29 Mar 2024 15:19:13 -0300 Subject: [PATCH 12/44] Update doc/sphinx-guides/source/api/changelog.rst Co-authored-by: Philip Durbin --- doc/sphinx-guides/source/api/changelog.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/sphinx-guides/source/api/changelog.rst b/doc/sphinx-guides/source/api/changelog.rst index 5e55ff46235..4c2d332857b 100644 --- a/doc/sphinx-guides/source/api/changelog.rst +++ b/doc/sphinx-guides/source/api/changelog.rst @@ -10,7 +10,7 @@ This API changelog is experimental and we would love feedback on its usefulness. v6.3 ---- -- **/api/admin/superuser/{identifier}**: The POST endpoint is being deprecated in favor for the PUT,which we can specifically set the superuser status in the body. +- **/api/admin/superuser/{identifier}**: The POST endpoint is being deprecated in favor for the PUT, which we can specifically set the superuser status in the body. v6.2 ---- From 9577295f50df9094291cedfeb66af37fe6c0db2d Mon Sep 17 00:00:00 2001 From: zearaujo25 Date: Fri, 29 Mar 2024 16:45:14 -0300 Subject: [PATCH 13/44] 9887: code review --- src/test/java/edu/harvard/iq/dataverse/api/AdminIT.java | 2 +- src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/java/edu/harvard/iq/dataverse/api/AdminIT.java b/src/test/java/edu/harvard/iq/dataverse/api/AdminIT.java index bb5c2ba34bd..32c417a4fae 100644 --- a/src/test/java/edu/harvard/iq/dataverse/api/AdminIT.java +++ b/src/test/java/edu/harvard/iq/dataverse/api/AdminIT.java @@ -899,7 +899,7 @@ private String createTestNonSuperuserApiToken() { @ParameterizedTest @ValueSource(booleans={true,false}) - public void testChangeSuperUserStatus(Boolean status) { + public void testSetSuperUserStatus(Boolean status) { Response createUser = UtilIT.createRandomUser(); createUser.then().assertThat().statusCode(OK.getStatusCode()); String username = UtilIT.getUsernameFromResponse(createUser); diff --git a/src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java b/src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java index 9a409ba97fb..ab0cb4c2426 100644 --- a/src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java +++ b/src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java @@ -1520,6 +1520,7 @@ static Response getMetadataBlockFromDatasetVersion(String persistentId, String v .get("/api/datasets/:persistentId/versions/" + DS_VERSION_LATEST_PUBLISHED + "/metadata/citation?persistentId=" + persistentId); } + @Deprecated static Response makeSuperUser(String username) { Response response = given().post("/api/admin/superuser/" + username); return response; From 12fe4cd002b19309fd92f43a214ba4049c2688e4 Mon Sep 17 00:00:00 2001 From: zearaujo25 Date: Fri, 29 Mar 2024 17:10:39 -0300 Subject: [PATCH 14/44] 9887: renaming function --- src/test/java/edu/harvard/iq/dataverse/api/AdminIT.java | 2 +- src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/edu/harvard/iq/dataverse/api/AdminIT.java b/src/test/java/edu/harvard/iq/dataverse/api/AdminIT.java index 32c417a4fae..44f062e8254 100644 --- a/src/test/java/edu/harvard/iq/dataverse/api/AdminIT.java +++ b/src/test/java/edu/harvard/iq/dataverse/api/AdminIT.java @@ -903,7 +903,7 @@ public void testSetSuperUserStatus(Boolean status) { Response createUser = UtilIT.createRandomUser(); createUser.then().assertThat().statusCode(OK.getStatusCode()); String username = UtilIT.getUsernameFromResponse(createUser); - Response toggleSuperuser = UtilIT.changeSuperUserStatus(username, status); + Response toggleSuperuser = UtilIT.setSuperuserStatus(username, status); toggleSuperuser.then().assertThat() .statusCode(OK.getStatusCode()); } diff --git a/src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java b/src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java index ab0cb4c2426..dc503a92c0a 100644 --- a/src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java +++ b/src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java @@ -1526,7 +1526,7 @@ static Response makeSuperUser(String username) { return response; } - static Response changeSuperUserStatus(String username, Boolean isSuperUser) { + static Response setSuperuserStatus(String username, Boolean isSuperUser) { Response response = given().body(isSuperUser).put("/api/admin/superuser/" + username); return response; } From 08fdc2cfefe00a914552827489b10b46e2eee149 Mon Sep 17 00:00:00 2001 From: qqmyers Date: Fri, 29 Mar 2024 17:04:09 -0400 Subject: [PATCH 15/44] fix mixed logic --- src/main/java/edu/harvard/iq/dataverse/DatasetPage.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java index 4c436715f0d..1d4a8895947 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java @@ -3325,8 +3325,8 @@ public boolean validateFilesForDownload(boolean downloadOriginal){ } //Some are selected and there are non-downloadable ones or there are both downloadable and globus transferable files - if ((!(getSelectedDownloadableFiles().isEmpty() && getSelectedGlobusTransferableFiles().isEmpty()) - && (!getSelectedNonDownloadableFiles().isEmpty()) || (!getSelectedDownloadableFiles().isEmpty() && !getSelectedGlobusTransferableFiles().isEmpty()))) { + if (((!getSelectedDownloadableFiles().isEmpty() && !getSelectedGlobusTransferableFiles().isEmpty()) + || (!getSelectedNonDownloadableFiles().isEmpty()) && (!getSelectedDownloadableFiles().isEmpty() || !getSelectedGlobusTransferableFiles().isEmpty()))) { setValidateFilesOutcome("Mixed"); return true; } From a90254741dd67919f4c4013c821bae260bdab08f Mon Sep 17 00:00:00 2001 From: qqmyers Date: Fri, 29 Mar 2024 17:06:02 -0400 Subject: [PATCH 16/44] further improve separation of download/transfer and messages --- .../edu/harvard/iq/dataverse/DatasetPage.java | 73 +++++++++++++------ src/main/java/propertyFiles/Bundle.properties | 12 +-- src/main/webapp/dataset.xhtml | 54 +++++++++----- src/main/webapp/filesFragment.xhtml | 4 +- 4 files changed, 93 insertions(+), 50 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java index 1d4a8895947..66db438a3dd 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java @@ -1234,8 +1234,17 @@ public boolean canDownloadFiles() { canDownloadFiles = false; for (FileMetadata fmd : workingVersion.getFileMetadatas()) { if (fileDownloadHelper.canDownloadFile(fmd)) { - canDownloadFiles = true; - break; + if (isVersionHasGlobus()) { + String driverId = DataAccess + .getStorageDriverFromIdentifier(fmd.getDataFile().getStorageIdentifier()); + if (StorageIO.isDataverseAccessible(driverId)) { + canDownloadFiles = true; + break; + } + } else { + canDownloadFiles = true; + break; + } } } } @@ -3260,7 +3269,7 @@ public void startDownloadSelectedOriginal() { private void startDownload(boolean downloadOriginal){ boolean guestbookRequired = isDownloadPopupRequired(); - boolean validate = validateFilesForDownload(downloadOriginal); + boolean validate = validateFilesForDownload(downloadOriginal, false); if (validate) { updateGuestbookResponse(guestbookRequired, downloadOriginal, false); if(!guestbookRequired && !getValidateFilesOutcome().equals("Mixed")){ @@ -3283,7 +3292,7 @@ public void setValidateFilesOutcome(String validateFilesOutcome) { this.validateFilesOutcome = validateFilesOutcome; } - public boolean validateFilesForDownload(boolean downloadOriginal){ + public boolean validateFilesForDownload(boolean downloadOriginal, boolean isGlobusTransfer){ if (this.selectedFiles.isEmpty()) { PrimeFaces.current().executeScript("PF('selectFilesForDownload').show()"); return false; @@ -3300,33 +3309,39 @@ public boolean validateFilesForDownload(boolean downloadOriginal){ return false; } - for (FileMetadata fmd : getSelectedDownloadableFiles()) { - DataFile dataFile = fmd.getDataFile(); - if (downloadOriginal && dataFile.isTabularData()) { - bytes += dataFile.getOriginalFileSize() == null ? 0 : dataFile.getOriginalFileSize(); - } else { - bytes += dataFile.getFilesize(); + if (!isGlobusTransfer) { + for (FileMetadata fmd : getSelectedDownloadableFiles()) { + DataFile dataFile = fmd.getDataFile(); + if (downloadOriginal && dataFile.isTabularData()) { + bytes += dataFile.getOriginalFileSize() == null ? 0 : dataFile.getOriginalFileSize(); + } else { + bytes += dataFile.getFilesize(); + } } - } - //if there are two or more files, with a total size - //over the zip limit, post a "too large" popup - if (bytes > settingsWrapper.getZipDownloadLimit() && selectedDownloadableFiles.size() > 1) { - setValidateFilesOutcome("FailSize"); - return false; + // if there are two or more files, with a total size + // over the zip limit, post a "too large" popup + if (bytes > settingsWrapper.getZipDownloadLimit() && selectedDownloadableFiles.size() > 1) { + setValidateFilesOutcome("FailSize"); + return false; + } } - + // If some of the files were restricted and we had to drop them off the // list, and NONE of the files are left on the downloadable list - // - we show them a "you're out of luck" popup: - if (getSelectedDownloadableFiles().isEmpty() && getSelectedGlobusTransferableFiles().isEmpty() && !getSelectedNonDownloadableFiles().isEmpty()) { + // - we show them a "you're out of luck" popup + // Same for globus transfer + if ((!isGlobusTransfer + && (getSelectedDownloadableFiles().isEmpty() && !getSelectedNonDownloadableFiles().isEmpty())) + || (isGlobusTransfer && (getSelectedGlobusTransferableFiles().isEmpty() + && !getSelectedNonGlobusTransferableFiles().isEmpty()))) { setValidateFilesOutcome("FailRestricted"); return false; } - //Some are selected and there are non-downloadable ones or there are both downloadable and globus transferable files - if (((!getSelectedDownloadableFiles().isEmpty() && !getSelectedGlobusTransferableFiles().isEmpty()) - || (!getSelectedNonDownloadableFiles().isEmpty()) && (!getSelectedDownloadableFiles().isEmpty() || !getSelectedGlobusTransferableFiles().isEmpty()))) { + //For download or transfer, there are some that can be downloaded/transferred and some that can't + if ((!isGlobusTransfer && (!getSelectedNonDownloadableFiles().isEmpty() && !getSelectedDownloadableFiles().isEmpty())) || + (isGlobusTransfer && (!getSelectedNonGlobusTransferableFiles().isEmpty() && !getSelectedGlobusTransferableFiles().isEmpty()))) { setValidateFilesOutcome("Mixed"); return true; } @@ -6284,12 +6299,18 @@ public void clearSelectionEmbargo() { PrimeFaces.current().resetInputs("datasetForm:embargoInputs"); } - public boolean isCantDownloadDueToEmbargo() { + public boolean isCantDownloadDueToEmbargoOrDVAccess() { if (getSelectedNonDownloadableFiles() != null) { for (FileMetadata fmd : getSelectedNonDownloadableFiles()) { if (FileUtil.isActivelyEmbargoed(fmd)) { return true; } + if (isVersionHasGlobus()) { + if (StorageIO.isDataverseAccessible( + DataAccess.getStorageDriverFromIdentifier(fmd.getDataFile().getStorageIdentifier()))) { + return true; + } + } } } return false; @@ -6381,7 +6402,11 @@ public void startGlobusTransfer(boolean transferAll, boolean popupShown) { } boolean guestbookRequired = isDownloadPopupRequired(); - boolean validated = validateFilesForDownload(true); + boolean validated = validateFilesForDownload(true, true); + + logger.info("SGT valid: " + validated); + logger.info("SGT outcome: " + getValidateFilesOutcome()); + logger.info("SGT popupshown: " + popupShown); if (validated) { globusTransferRequested = true; boolean mixed = "Mixed".equals(getValidateFilesOutcome()); diff --git a/src/main/java/propertyFiles/Bundle.properties b/src/main/java/propertyFiles/Bundle.properties index 692ab9e0686..33ba587ac9e 100644 --- a/src/main/java/propertyFiles/Bundle.properties +++ b/src/main/java/propertyFiles/Bundle.properties @@ -1665,17 +1665,19 @@ dataset.noSelectedFiles=Please select one or more files. dataset.noSelectedFilesForDownload=Please select a file or files to be downloaded. dataset.noSelectedFilesForRequestAccess=Please select a file or files for access request. dataset.embargoedSelectedFilesForRequestAccess=Embargoed files cannot be accessed. Please select an unembargoed file or files for your access request. -dataset.inValidSelectedFilesForDownload=Restricted Files Selected -dataset.inValidSelectedFilesForDownloadWithEmbargo=Embargoed and/or Restricted Files Selected -dataset.noValidSelectedFilesForDownload=The selected file(s) may not be downloaded because you have not been granted access. +dataset.inValidSelectedFilesForDownload=Restricted Files, or Files only Acessible Via Globus Selected +dataset.inValidSelectedFilesForDownloadWithEmbargo=Embargoed and/or Restricted Files, or Files only acessible via Globus Selected +dataset.inValidSelectedFilesForTransferWithEmbargo=Embargoed and/or Restricted Files, or Files that are not Globus accessible Selected +dataset.noValidSelectedFilesForDownload=The selected file(s) may not be downloaded because you have not been granted access or the files can only be transferred via Globus. +dataset.noValidSelectedFilesForTransfer=The selected file(s) may not be transferred because you have not been granted access or the files are not Globus accessible. dataset.mixedSelectedFilesForDownload=The restricted file(s) selected may not be downloaded because you have not been granted access. -dataset.mixedSelectedFilesForDownloadWithEmbargo=The embargoed and/or restricted file(s) selected may not be downloaded because you have not been granted access. +dataset.mixedSelectedFilesForDownloadWithEmbargo=Any embargoed and/or restricted file(s) selected may not be downloaded because you have not been granted access. Some files may only be accessible via Globus. dataset.mixedSelectedFilesForTransfer=Some file(s) cannot be transferred. (They are restricted, embargoed, or not Globus accessible.) dataset.inValidSelectedFilesForTransfer=Ineligible Files Selected dataset.downloadUnrestricted=Click Continue to download the files you have access to download. dataset.transferUnrestricted=Click Continue to transfer the elligible files. -dataset.requestAccessToRestrictedFiles=You may request access to the restricted file(s) by clicking the Request Access button. +dataset.requestAccessToRestrictedFiles=You may request access any restricted file(s) by clicking the Request Access button. dataset.requestAccessToRestrictedFilesWithEmbargo=Embargoed files cannot be accessed during the embargo period. If your selection contains restricted files, you may request access to them by clicking the Request Access button. dataset.privateurl.infoMessageAuthor=Privately share this dataset before it is published: {0} dataset.privateurl.infoMessageReviewer=This unpublished dataset is being privately shared. diff --git a/src/main/webapp/dataset.xhtml b/src/main/webapp/dataset.xhtml index 7b5db98b9dd..6424cde5ac2 100644 --- a/src/main/webapp/dataset.xhtml +++ b/src/main/webapp/dataset.xhtml @@ -32,7 +32,7 @@ and !permissionsWrapper.canIssuePublishDatasetCommand(DatasetPage.dataset)}"/> - @@ -1053,10 +1054,10 @@ - +

#{bundle['dataset.noValidSelectedFilesForDownload']}

-

#{DatasetPage.cantDownloadDueToEmbargo ? bundle['dataset.requestAccessToRestrictedFilesWithEmbargo'] : bundle['dataset.requestAccessToRestrictedFiles']}

+

#{DatasetPage.cantDownloadDueToEmbargoOrDVAccess ? bundle['dataset.requestAccessToRestrictedFilesWithEmbargo'] : bundle['dataset.requestAccessToRestrictedFiles']}

+ +

#{bundle['dataset.noValidSelectedFilesForTransfer']}

+ +

#{DatasetPage.cantDownloadDueToEmbargoOrDVAccess ? bundle['dataset.requestAccessToRestrictedFilesWithEmbargo'] : bundle['dataset.requestAccessToRestrictedFiles']}

+
+
+ +
+

#{bundle['file.zip.download.exceeds.limit.info']}

@@ -1085,8 +1097,8 @@
- -

#{DatasetPage.cantDownloadDueToEmbargo ? bundle['dataset.mixedSelectedFilesForDownloadWithEmbargo'] : bundle['dataset.mixedSelectedFilesForDownload']}

+ +

#{DatasetPage.cantDownloadDueToEmbargoOrDVAccess ? bundle['dataset.mixedSelectedFilesForDownloadWithEmbargo'] : bundle['dataset.mixedSelectedFilesForDownload']}

@@ -1970,7 +1982,11 @@ PF('downloadTooLarge').show(); } if (outcome ==='FailRestricted'){ - PF('downloadInvalid').show(); + if(isTransfer) { + PF('transferInvalid').show(); + } else { + PF('downloadInvalid').show(); + } } if (outcome ==='GuestbookRequired'){ PF('guestbookAndTermsPopup').show(); diff --git a/src/main/webapp/filesFragment.xhtml b/src/main/webapp/filesFragment.xhtml index 58899ab7062..117710cfd53 100644 --- a/src/main/webapp/filesFragment.xhtml +++ b/src/main/webapp/filesFragment.xhtml @@ -456,7 +456,7 @@ #{bundle.download}