Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions doc/release-notes/12760-external-tool.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
## BUG ##
API /api/files/{FILE_ID}/externalTool/{TOOL_ID}/toolUrl was not allowing a user to download the file being previewed after entering the guestbook response.
The api now allows the guestbookResponse to be passed in the via the JSON Body. The response will be written to the database and the guestbook id will be included in the callback to allow for guestbook response verification.
Also allows for the private url timeouts for download file with guestbook response to be configured via JVM.
Url timeout defaults to 1 minute configurable by "dataverse.api.guestbook-response-timeout-minutes".
External tool downloads default to 60 minutes configurable by "dataverse.api.guestbook-response-external-tool-timeout-minutes".
2 changes: 2 additions & 0 deletions doc/sphinx-guides/source/api/native-api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6338,6 +6338,7 @@ Get File External Tool URL
This API call generates a URL for accessing an external tool (see :doc:`/installation/external-tools`) that operates at the file level. The URL includes necessary authentication tokens and parameters based on the user's permissions and the tool's configuration.

Authentication is required for draft, restricted, embargoed, or expired (retention period) files; the user must have appropriate permissions.
Where a Guestbook Response is required to access the file the "guestbookResponse" can be passed via the Json body to allow the user to download the file from the external tool.

.. code-block:: bash

Expand All @@ -6362,6 +6363,7 @@ The JSON request body accepts the following optional parameters:

- ``preview``: boolean flag to indicate if the tool should run in preview mode (default: false)
- ``locale``: string specifying the locale for internationalization
- ``guestbookResponse``: JsonObject containing the Guestbook Response

The response includes:

Expand Down
18 changes: 18 additions & 0 deletions doc/sphinx-guides/source/installation/config.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3451,6 +3451,24 @@ Can also be set via any `supported MicroProfile Config API source`_, e.g. the en
.. note::
This setting will be ignored unless the :ref:`dataverse.api.blocked.policy` is set to ``unblock-key``. Otherwise the deprecated :ref:`:BlockedApiKey` will be used

.. _dataverse.api.guestbook-response-timeout-minutes:

dataverse.api.guestbook-response-timeout-minutes
++++++++++++++++++++++++++++++++++++++++++++++++

This setting specifies the timeout between posting a Guestbook Response and downloading the file. The default, if not set, is 1 minute. For example:

``./asadmin create-jvm-options '-Ddataverse.api.guestbook-response-timeout-minutes=1'``

. _dataverse.api.guestbook-response-timeout-minutes:

dataverse.api.guestbook-response-external-tool-timeout-minutes
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

This setting specifies the timeout between posting a Guestbook Response and downloading the file from an external tool. The default, if not set, is 60 minute. For example:

``./asadmin create-jvm-options '-Ddataverse.api.guestbook-response-external-tool-timeout-minutes=60'``


.. _dataverse.legacy.api-response-message-style:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public ExternalToolHandler getConfigurePopupToolHandler() {
}


toolHandler = new ExternalToolHandler(tool, datafileService.find(fileId), apiToken, datafileService.findFileMetadata(fileMetadataId), session.getLocaleCode());
toolHandler = new ExternalToolHandler(tool, datafileService.find(fileId), apiToken, datafileService.findFileMetadata(fileMetadataId), session.getLocaleCode(), null);

return toolHandler;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -503,12 +503,13 @@
* Data Explorer. This method may be invoked directly from the
* xhtml if no popup is required (no terms of use, no guestbook, etc.).
*/
public void explore(GuestbookResponse guestbookResponse, FileMetadata fmd, ExternalTool externalTool) {

Check failure on line 506 in src/main/java/edu/harvard/iq/dataverse/FileDownloadServiceBean.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this method to reduce its Cognitive Complexity from 16 to the 15 allowed.

See more on https://sonarcloud.io/project/issues?id=IQSS_dataverse&issues=AaERyyl5G-Dfj-8j01LU&open=AaERyyl5G-Dfj-8j01LU&pullRequest=12801
ApiToken apiToken = null;
User user = session.getUser();
Long guestbookResponseId = guestbookResponse != null ? guestbookResponse.getId() : null;
DatasetVersion version = fmd.getDatasetVersion();
if (version.isDraft() || fmd.getDatasetVersion().isDeaccessioned() || (fmd.getDataFile().isRestricted())
|| (FileUtil.isActivelyEmbargoed(fmd)) || (FileUtil.isRetentionExpired(fmd))) {
|| (FileUtil.isActivelyEmbargoed(fmd)) || (FileUtil.isRetentionExpired(fmd)) || guestbookResponseId != null) {
apiToken = authService.getValidApiTokenForUser(user);
}
DataFile dataFile = null;
Expand All @@ -520,7 +521,7 @@
}
}
String localeCode = session.getLocaleCode();
ExternalToolHandler externalToolHandler = new ExternalToolHandler(externalTool, dataFile, apiToken, fmd, localeCode);
ExternalToolHandler externalToolHandler = new ExternalToolHandler(externalTool, dataFile, apiToken, fmd, localeCode, guestbookResponseId);
// Persist the name of the tool (i.e. "Data Explorer", etc.)
guestbookResponse.setEventType(externalTool.getDisplayName());
PrimeFaces.current().executeScript(externalToolHandler.getExploreScript());
Expand Down
7 changes: 4 additions & 3 deletions src/main/java/edu/harvard/iq/dataverse/FilePage.java
Original file line number Diff line number Diff line change
Expand Up @@ -1152,18 +1152,19 @@ public void setSelectedTool(ExternalTool selectedTool) {
this.selectedTool = selectedTool;
}

public String preview(ExternalTool externalTool) {
public String preview(ExternalTool externalTool, GuestbookResponse guestbookResponse) {
ApiToken apiToken = null;
User user = session.getUser();
Long guestbookResponseId = guestbookResponse != null ? guestbookResponse.getId() : null;
if (fileMetadata.getDatasetVersion().isDraft() || (fileMetadata.getDataFile().isRestricted())
|| fileMetadata.getDatasetVersion().isDeaccessioned() || (FileUtil.isActivelyEmbargoed(fileMetadata))
|| (FileUtil.isRetentionExpired(fileMetadata))) {
|| (FileUtil.isRetentionExpired(fileMetadata)) || guestbookResponseId != null) {
apiToken = authService.getValidApiTokenForUser(user);
}
if(externalTool == null){
return "";
}
ExternalToolHandler externalToolHandler = new ExternalToolHandler(externalTool, file, apiToken, getFileMetadata(), session.getLocaleCode());
ExternalToolHandler externalToolHandler = new ExternalToolHandler(externalTool, file, apiToken, getFileMetadata(), session.getLocaleCode(), guestbookResponseId);
String toolUrl = externalToolHandler.getToolUrlForPreviewMode();
return toolUrl;
}
Expand Down
15 changes: 15 additions & 0 deletions src/main/java/edu/harvard/iq/dataverse/api/AbstractApiBean.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import edu.harvard.iq.dataverse.util.DateUtil;
import edu.harvard.iq.dataverse.util.FileUtil;
import edu.harvard.iq.dataverse.util.SystemConfig;
import edu.harvard.iq.dataverse.util.json.JsonParseException;
import edu.harvard.iq.dataverse.util.json.JsonParser;
import edu.harvard.iq.dataverse.util.json.JsonUtil;
import edu.harvard.iq.dataverse.util.json.NullSafeJsonBuilder;
Expand Down Expand Up @@ -1201,6 +1202,20 @@ protected static Response error( Status sts, String msg ) {
.add(ApiConstants.MESSAGE_FIELD, msg ).build()
).type(MediaType.APPLICATION_JSON_TYPE).build();
}

protected GuestbookResponse getGuestbookResponseFromBody(DataFile dataFile, String type, String jsonBody, User requestor) throws JsonParseException {
GuestbookResponse guestbookResponse = null;

if (dataFile != null && jsonBody != null && jsonBody.startsWith("{")) {
JsonObject guestbookResponseObj = JsonUtil.getJsonObject(jsonBody).getJsonObject("guestbookResponse");
guestbookResponse = gbRespSvc.initAPIGuestbookResponse(dataFile.getOwner(), dataFile, null, requestor);
guestbookResponse.setEventType(type);
// Parse custom question answers and validate them
jsonParser().parseGuestbookResponse(guestbookResponseObj, guestbookResponse);
}

return guestbookResponse;
}
}

class LazyRef<T> {
Expand Down
Loading
Loading