From e22f67ce16139f9dd5af5e3545df3103fd585d6e Mon Sep 17 00:00:00 2001 From: Jim Myers Date: Tue, 24 Feb 2026 17:01:19 -0500 Subject: [PATCH 01/11] allow preview of public aux file --- .../edu/harvard/iq/dataverse/DatasetPage.java | 50 ++++++++++++++++++- src/main/webapp/filesFragment.xhtml | 2 +- 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java index f72c818fdee..a9d04be14f7 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java @@ -102,6 +102,12 @@ import jakarta.faces.view.ViewScoped; import jakarta.inject.Inject; import jakarta.inject.Named; + +import jakarta.json.Json; +import jakarta.json.JsonArray; +import jakarta.json.JsonObject; +import jakarta.json.JsonObjectBuilder; +import jakarta.json.JsonValue; import jakarta.persistence.OptimisticLockException; import org.apache.commons.lang3.StringUtils; @@ -279,6 +285,8 @@ public enum DisplayMode { DataFileCategoryServiceBean dataFileCategoryService; @Inject GlobusServiceBean globusService; + @Inject + AuxiliaryFileServiceBean auxFileService; private Dataset dataset = new Dataset(); @@ -5963,9 +5971,47 @@ public List getDatasetSummaryFields() { return DatasetUtil.getDatasetSummaryFields(workingVersion, customFields); } - public boolean isShowPreviewButton(DataFile dataFile) { + public boolean isShowPreviewButton(FileMetadata fmd) { + DataFile dataFile = fmd.getDataFile(); List previewTools = getPreviewToolsForDataFile(dataFile); - return previewTools.size() > 0; + if (previewTools.isEmpty()) { + return false; + } + if (fileDownloadHelper.canDownloadFile(fmd)) { + return true; + } + // If the user cannot download the file, we will still show the preview + // button if there is a previewer that requires an auxiliary file(s) + // and those files all exist and are public. + for (ExternalTool tool : previewTools) { + boolean toolHasPublicAuxFiles = false; + String reqString = tool.getRequirements(); + if (!reqString.isBlank()) { + try { + JsonObject reqs = JsonUtil.getJsonObject(reqString); + JsonArray auxFilesExist = reqs.getJsonArray(ExternalTool.AUX_FILES_EXIST); + for (JsonValue jsonValue : auxFilesExist) { + JsonObject auxEntry = jsonValue.asJsonObject(); + String formatTag = auxEntry.getString("formatTag"); + String formatVersion = auxEntry.getString("formatVersion"); + AuxiliaryFile auxFile = auxFileService.lookupAuxiliaryFile(dataFile, formatTag, formatVersion); + if (auxFile == null || !auxFile.getIsPublic()) { + toolHasPublicAuxFiles = false; + break; + } else { + toolHasPublicAuxFiles = true; + } + } + if (toolHasPublicAuxFiles) { + return true; + } + } catch (Exception ex) { + logger.warning("Failed to parse external tool requirements: " + ex.getMessage()); + return false; + } + } + } + return false; } public boolean isShowQueryButton(DataFile dataFile) { diff --git a/src/main/webapp/filesFragment.xhtml b/src/main/webapp/filesFragment.xhtml index 6eb8737091d..886e2ad7506 100644 --- a/src/main/webapp/filesFragment.xhtml +++ b/src/main/webapp/filesFragment.xhtml @@ -559,7 +559,7 @@ - + #{bundle.preview} "#{empty(fileMetadata.directoryLabel) ? "":fileMetadata.directoryLabel.concat("/")}#{fileMetadata.label}" From 76ae296c7fa1caa245588b72829b09f5c2d42110 Mon Sep 17 00:00:00 2001 From: Jim Myers Date: Tue, 24 Feb 2026 17:40:34 -0500 Subject: [PATCH 02/11] add null check --- src/main/java/edu/harvard/iq/dataverse/DatasetPage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java index a9d04be14f7..bf154701d08 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java @@ -5986,7 +5986,7 @@ public boolean isShowPreviewButton(FileMetadata fmd) { for (ExternalTool tool : previewTools) { boolean toolHasPublicAuxFiles = false; String reqString = tool.getRequirements(); - if (!reqString.isBlank()) { + if (!StringUtils.isBlank(reqString)) { try { JsonObject reqs = JsonUtil.getJsonObject(reqString); JsonArray auxFilesExist = reqs.getJsonArray(ExternalTool.AUX_FILES_EXIST); From d40310fe288fff9ab4f159db61da0a4ad949131b Mon Sep 17 00:00:00 2001 From: Jim Myers Date: Thu, 26 Feb 2026 16:20:35 -0500 Subject: [PATCH 03/11] refactor, only cache tools you can use wrt canDownload and public aux --- .../edu/harvard/iq/dataverse/DatasetPage.java | 65 +++++++------------ .../edu/harvard/iq/dataverse/FilePage.java | 3 +- .../ExternalToolServiceBean.java | 10 +-- 3 files changed, 30 insertions(+), 48 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java index bf154701d08..32dc9cf7728 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java @@ -5973,46 +5973,12 @@ public List getDatasetSummaryFields() { public boolean isShowPreviewButton(FileMetadata fmd) { DataFile dataFile = fmd.getDataFile(); - List previewTools = getPreviewToolsForDataFile(dataFile); + List previewTools = getPreviewToolsForDataFile(dataFile, fileDownloadHelper.canDownloadFile(fmd)); if (previewTools.isEmpty()) { return false; } - if (fileDownloadHelper.canDownloadFile(fmd)) { - return true; - } - // If the user cannot download the file, we will still show the preview - // button if there is a previewer that requires an auxiliary file(s) - // and those files all exist and are public. - for (ExternalTool tool : previewTools) { - boolean toolHasPublicAuxFiles = false; - String reqString = tool.getRequirements(); - if (!StringUtils.isBlank(reqString)) { - try { - JsonObject reqs = JsonUtil.getJsonObject(reqString); - JsonArray auxFilesExist = reqs.getJsonArray(ExternalTool.AUX_FILES_EXIST); - for (JsonValue jsonValue : auxFilesExist) { - JsonObject auxEntry = jsonValue.asJsonObject(); - String formatTag = auxEntry.getString("formatTag"); - String formatVersion = auxEntry.getString("formatVersion"); - AuxiliaryFile auxFile = auxFileService.lookupAuxiliaryFile(dataFile, formatTag, formatVersion); - if (auxFile == null || !auxFile.getIsPublic()) { - toolHasPublicAuxFiles = false; - break; - } else { - toolHasPublicAuxFiles = true; - } - } - if (toolHasPublicAuxFiles) { - return true; - } - } catch (Exception ex) { - logger.warning("Failed to parse external tool requirements: " + ex.getMessage()); return false; } - } - } - return false; - } public boolean isShowQueryButton(DataFile dataFile) { @@ -6023,27 +5989,37 @@ public boolean isShowQueryButton(DataFile dataFile) { return false; } - List fileQueryTools = getQueryToolsForDataFile(dataFile); + List fileQueryTools = getQueryToolsForDataFile(dataFile, true); return fileQueryTools.size() > 0; } public List getPreviewToolsForDataFile(DataFile dataFile) { - return getCachedToolsForDataFile(dataFile, ExternalTool.Type.PREVIEW); + return getCachedToolsForDataFile(dataFile, ExternalTool.Type.PREVIEW, null); + } + + public List getPreviewToolsForDataFile(DataFile dataFile, Boolean canDownload) { + return getCachedToolsForDataFile(dataFile, ExternalTool.Type.PREVIEW, canDownload); } public List getQueryToolsForDataFile(DataFile dataFile) { - return getCachedToolsForDataFile(dataFile, ExternalTool.Type.QUERY); + return getCachedToolsForDataFile(dataFile, ExternalTool.Type.QUERY, null); + } + + public List getQueryToolsForDataFile(DataFile dataFile, Boolean canDownload) { + return getCachedToolsForDataFile(dataFile, ExternalTool.Type.QUERY, canDownload); } + //ToDo: currently only shown if the user can Edit the dataset which means they can view files public List getConfigureToolsForDataFile(DataFile dataFile) { - return getCachedToolsForDataFile(dataFile, ExternalTool.Type.CONFIGURE); + return getCachedToolsForDataFile(dataFile, ExternalTool.Type.CONFIGURE, true); } + //ToDo: currently only shown if the user can Edit the dataset which means they can view files public List getExploreToolsForDataFile(DataFile dataFile) { - return getCachedToolsForDataFile(dataFile, ExternalTool.Type.EXPLORE); + return getCachedToolsForDataFile(dataFile, ExternalTool.Type.EXPLORE, true); } - public List getCachedToolsForDataFile(DataFile dataFile, ExternalTool.Type type) { + public List getCachedToolsForDataFile(DataFile dataFile, ExternalTool.Type type, Boolean canDownload) { Long fileId = dataFile.getId(); Map> cachedToolsByFileId = new HashMap<>(); List externalTools = new ArrayList<>(); @@ -6071,7 +6047,12 @@ public List getCachedToolsForDataFile(DataFile dataFile, ExternalT if (cachedTools != null) { //if already queried before and added to list return cachedTools; } - cachedTools = externalToolService.findExternalToolsByFile(externalTools, dataFile); + if(canDownload == null) { + logger.warning("Call to getCachedToolsForDataFile with null canDownload parameter and no cached results"); + //Return the set available to non-downloader in this case (versus an empty list) + canDownload = false; + } + cachedTools = externalToolService.findExternalToolsByFile(externalTools, dataFile, canDownload); cachedToolsByFileId.put(fileId, cachedTools); //add to map so we don't have to do the lifting again return cachedTools; } diff --git a/src/main/java/edu/harvard/iq/dataverse/FilePage.java b/src/main/java/edu/harvard/iq/dataverse/FilePage.java index b08598b2fb8..77982044b19 100644 --- a/src/main/java/edu/harvard/iq/dataverse/FilePage.java +++ b/src/main/java/edu/harvard/iq/dataverse/FilePage.java @@ -372,10 +372,11 @@ public void setDatasetVersionId(Long datasetVersionId) { // findPreviewTools would be a better name private List sortExternalTools(){ + boolean canDownload = fileDownloadHelper.canDownloadFile(fileMetadata); List retList = new ArrayList<>(); List previewTools = externalToolService.findFileToolsByTypeAndContentType(ExternalTool.Type.PREVIEW, file.getContentType()); for (ExternalTool previewTool : previewTools) { - if (externalToolService.meetsRequirements(previewTool, file)) { + if (externalToolService.meetsRequirements(previewTool, file, canDownload)) { retList.add(previewTool); } } diff --git a/src/main/java/edu/harvard/iq/dataverse/externaltools/ExternalToolServiceBean.java b/src/main/java/edu/harvard/iq/dataverse/externaltools/ExternalToolServiceBean.java index 5ee0bf1355d..a38fedd333b 100644 --- a/src/main/java/edu/harvard/iq/dataverse/externaltools/ExternalToolServiceBean.java +++ b/src/main/java/edu/harvard/iq/dataverse/externaltools/ExternalToolServiceBean.java @@ -139,14 +139,14 @@ public ExternalTool save(ExternalTool externalTool) { * file supports The list of tools is passed in so it doesn't hit the * database each time */ - public List findExternalToolsByFile(List allExternalTools, DataFile file) { + public List findExternalToolsByFile(List allExternalTools, DataFile file, boolean canDownload) { List externalTools = new ArrayList<>(); //Map tabular data to it's mimetype (the isTabularData() check assures that this code works the same as before, but it may need to change if tabular data is split into subtypes with differing mimetypes) final String contentType = file.isTabularData() ? DataFileServiceBean.MIME_TYPE_TSV_ALT : file.getContentType(); boolean isAccessible = StorageIO.isDataverseAccessible(DataAccess.getStorageDriverFromIdentifier(file.getStorageIdentifier())); allExternalTools.forEach((externalTool) -> { //Match tool and file type, then check requirements - if (contentType.equals(externalTool.getContentType()) && meetsRequirements(externalTool, file) && (isAccessible || externalTool.accessesAuxFiles())) { + if (contentType.equals(externalTool.getContentType()) && meetsRequirements(externalTool, file, canDownload) && (isAccessible || externalTool.accessesAuxFiles())) { externalTools.add(externalTool); } }); @@ -154,11 +154,11 @@ public List findExternalToolsByFile(List allExternal return externalTools; } - public boolean meetsRequirements(ExternalTool externalTool, DataFile dataFile) { + public boolean meetsRequirements(ExternalTool externalTool, DataFile dataFile, boolean canDownload) { String requirements = externalTool.getRequirements(); if (requirements == null) { logger.fine("Data file id" + dataFile.getId() + ": no requirements for tool id " + externalTool.getId()); - return true; + return canDownload; } boolean meetsRequirements = true; JsonObject requirementsObj = JsonUtil.getJsonObject(requirements); @@ -173,7 +173,7 @@ public boolean meetsRequirements(ExternalTool externalTool, DataFile dataFile) { break; } else { logger.fine("Data file id" + dataFile.getId() + ": found required aux file. formatTag=" + formatTag + ". formatVersion=" + formatVersion); - meetsRequirements = true; + meetsRequirements = canDownload || auxFile.getIsPublic(); } } return meetsRequirements; From b84ad3884cf76d3eb6214070c6f065b87e8d0702 Mon Sep 17 00:00:00 2001 From: Jim Myers Date: Thu, 26 Feb 2026 16:53:42 -0500 Subject: [PATCH 04/11] fix api as well, refactor to separate no aux vs restricted aux --- .../edu/harvard/iq/dataverse/FilePage.java | 3 +- .../edu/harvard/iq/dataverse/api/Files.java | 22 +++++++------- .../ExternalToolServiceBean.java | 30 +++++++++++++------ 3 files changed, 35 insertions(+), 20 deletions(-) diff --git a/src/main/java/edu/harvard/iq/dataverse/FilePage.java b/src/main/java/edu/harvard/iq/dataverse/FilePage.java index 77982044b19..01f12587fe8 100644 --- a/src/main/java/edu/harvard/iq/dataverse/FilePage.java +++ b/src/main/java/edu/harvard/iq/dataverse/FilePage.java @@ -30,6 +30,7 @@ import edu.harvard.iq.dataverse.externaltools.ExternalTool; import edu.harvard.iq.dataverse.externaltools.ExternalToolHandler; import edu.harvard.iq.dataverse.externaltools.ExternalToolServiceBean; +import edu.harvard.iq.dataverse.externaltools.ExternalToolServiceBean.RequirementStatus; import edu.harvard.iq.dataverse.ingest.IngestRequest; import edu.harvard.iq.dataverse.ingest.IngestServiceBean; import edu.harvard.iq.dataverse.makedatacount.MakeDataCountLoggingServiceBean; @@ -376,7 +377,7 @@ private List sortExternalTools(){ List retList = new ArrayList<>(); List previewTools = externalToolService.findFileToolsByTypeAndContentType(ExternalTool.Type.PREVIEW, file.getContentType()); for (ExternalTool previewTool : previewTools) { - if (externalToolService.meetsRequirements(previewTool, file, canDownload)) { + if (RequirementStatus.MET == externalToolService.meetsRequirements(previewTool, file, canDownload)) { retList.add(previewTool); } } diff --git a/src/main/java/edu/harvard/iq/dataverse/api/Files.java b/src/main/java/edu/harvard/iq/dataverse/api/Files.java index 0a1b19985a4..28a43bb98a8 100644 --- a/src/main/java/edu/harvard/iq/dataverse/api/Files.java +++ b/src/main/java/edu/harvard/iq/dataverse/api/Files.java @@ -22,6 +22,7 @@ import io.gdcc.spi.export.ExportException; import edu.harvard.iq.dataverse.externaltools.ExternalTool; import edu.harvard.iq.dataverse.externaltools.ExternalToolHandler; +import edu.harvard.iq.dataverse.externaltools.ExternalToolServiceBean.RequirementStatus; import edu.harvard.iq.dataverse.ingest.IngestRequest; import edu.harvard.iq.dataverse.ingest.IngestServiceBean; import edu.harvard.iq.dataverse.ingest.IngestUtil; @@ -939,9 +940,6 @@ public Response getExternalToolUrl(@Context ContainerRequestContext crc, @PathPa ") does not match file content type (" + fileContentType + ")."); } - if (!externalToolService.meetsRequirements(externalTool, dataFile)) { - return error(BAD_REQUEST, "External tool requirements not met for this file."); - } // Get the current user and create a request object User user = getRequestUser(crc); @@ -957,14 +955,18 @@ public Response getExternalToolUrl(@Context ContainerRequestContext crc, @PathPa boolean isRestricted = dataFile.isRestricted() || fileMetadata.getDatasetVersion().isDraft() || FileUtil.isActivelyEmbargoed(fileMetadata) || fileMetadata.getDatasetVersion().isDeaccessioned() || FileUtil.isRetentionExpired(fileMetadata); - - // Check if user has permission to download the file if it's restricted + boolean hasPermission = true; if (isRestricted) { - boolean hasPermission = permissionSvc.requestOn(req, dataFile).has(Permission.DownloadFile); - if (!hasPermission) { - return error(Response.Status.FORBIDDEN, - "You do not have permission to access this file with the requested external tool."); - } + hasPermission = permissionSvc.requestOn(req, dataFile).has(Permission.DownloadFile); + } + RequirementStatus status = externalToolService.meetsRequirements(externalTool, dataFile, !isRestricted || hasPermission); + if (status == RequirementStatus.FILE_NOT_FOUND) { + return error(BAD_REQUEST, "External tool requirements not met for this file."); + } + if (status == RequirementStatus.INSUFFICIENT_PERMISSIONS) { + return error(Response.Status.FORBIDDEN, + "You do not have permission to access this file with the requested external tool."); + } // Determine if we need an API token for authentication diff --git a/src/main/java/edu/harvard/iq/dataverse/externaltools/ExternalToolServiceBean.java b/src/main/java/edu/harvard/iq/dataverse/externaltools/ExternalToolServiceBean.java index a38fedd333b..2f4f5ce386d 100644 --- a/src/main/java/edu/harvard/iq/dataverse/externaltools/ExternalToolServiceBean.java +++ b/src/main/java/edu/harvard/iq/dataverse/externaltools/ExternalToolServiceBean.java @@ -145,8 +145,8 @@ public List findExternalToolsByFile(List allExternal final String contentType = file.isTabularData() ? DataFileServiceBean.MIME_TYPE_TSV_ALT : file.getContentType(); boolean isAccessible = StorageIO.isDataverseAccessible(DataAccess.getStorageDriverFromIdentifier(file.getStorageIdentifier())); allExternalTools.forEach((externalTool) -> { - //Match tool and file type, then check requirements - if (contentType.equals(externalTool.getContentType()) && meetsRequirements(externalTool, file, canDownload) && (isAccessible || externalTool.accessesAuxFiles())) { + // Match tool and file type, then check requirements + if (contentType.equals(externalTool.getContentType()) && (RequirementStatus.MET == meetsRequirements(externalTool, file, canDownload)) && (isAccessible || externalTool.accessesAuxFiles())) { externalTools.add(externalTool); } }); @@ -154,29 +154,41 @@ public List findExternalToolsByFile(List allExternal return externalTools; } - public boolean meetsRequirements(ExternalTool externalTool, DataFile dataFile, boolean canDownload) { + public enum RequirementStatus { + MET, + FILE_NOT_FOUND, + INSUFFICIENT_PERMISSIONS + } + + public RequirementStatus meetsRequirements(ExternalTool externalTool, DataFile dataFile, boolean canDownload) { String requirements = externalTool.getRequirements(); if (requirements == null) { logger.fine("Data file id" + dataFile.getId() + ": no requirements for tool id " + externalTool.getId()); - return canDownload; + return canDownload ? RequirementStatus.MET : RequirementStatus.INSUFFICIENT_PERMISSIONS; } - boolean meetsRequirements = true; + JsonObject requirementsObj = JsonUtil.getJsonObject(requirements); JsonArray auxFilesExist = requirementsObj.getJsonArray(ExternalTool.AUX_FILES_EXIST); + boolean permissionsMet = true; for (JsonValue jsonValue : auxFilesExist) { String formatTag = jsonValue.asJsonObject().getString("formatTag"); String formatVersion = jsonValue.asJsonObject().getString("formatVersion"); AuxiliaryFile auxFile = auxiliaryFileService.lookupAuxiliaryFile(dataFile, formatTag, formatVersion); if (auxFile == null) { logger.fine("Data file id" + dataFile.getId() + ": cannot find required aux file. formatTag=" + formatTag + ". formatVersion=" + formatVersion); - meetsRequirements = false; - break; + return RequirementStatus.FILE_NOT_FOUND; } else { logger.fine("Data file id" + dataFile.getId() + ": found required aux file. formatTag=" + formatTag + ". formatVersion=" + formatVersion); - meetsRequirements = canDownload || auxFile.getIsPublic(); + if (!auxFile.getIsPublic()) { + permissionsMet = false; + } } } - return meetsRequirements; + if (canDownload || permissionsMet) { + return RequirementStatus.MET; + } else { + return RequirementStatus.INSUFFICIENT_PERMISSIONS; + } } public static ExternalTool parseAddExternalToolManifest(String manifest) { From 7bf8a0507a0cb0a69e69334bf94060a41edbc81f Mon Sep 17 00:00:00 2001 From: Jim Myers Date: Thu, 26 Feb 2026 17:01:54 -0500 Subject: [PATCH 05/11] fix test --- .../iq/dataverse/externaltools/ExternalToolServiceBeanTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/edu/harvard/iq/dataverse/externaltools/ExternalToolServiceBeanTest.java b/src/test/java/edu/harvard/iq/dataverse/externaltools/ExternalToolServiceBeanTest.java index d2a68ea8da6..62c3582c435 100644 --- a/src/test/java/edu/harvard/iq/dataverse/externaltools/ExternalToolServiceBeanTest.java +++ b/src/test/java/edu/harvard/iq/dataverse/externaltools/ExternalToolServiceBeanTest.java @@ -56,7 +56,7 @@ public void testfindAll() { URLTokenUtil externalToolHandler4 = new ExternalToolHandler(externalTool, dataFile, apiToken, fmd, null); List externalTools = new ArrayList<>(); externalTools.add(externalTool); - List availableExternalTools = externalToolService.findExternalToolsByFile(externalTools, dataFile); + List availableExternalTools = externalToolService.findExternalToolsByFile(externalTools, dataFile, true); assertEquals(availableExternalTools.size(), 1); } From b688215309780af6fc352f868db0da4ffe6f27c4 Mon Sep 17 00:00:00 2001 From: Jim Myers Date: Thu, 26 Feb 2026 17:35:20 -0500 Subject: [PATCH 06/11] typo, add debug on file page --- src/main/java/edu/harvard/iq/dataverse/DatasetPage.java | 2 +- src/main/java/edu/harvard/iq/dataverse/FilePage.java | 4 +++- 2 files changed, 4 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 32dc9cf7728..1e5dfd1e832 100644 --- a/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java +++ b/src/main/java/edu/harvard/iq/dataverse/DatasetPage.java @@ -5977,7 +5977,7 @@ public boolean isShowPreviewButton(FileMetadata fmd) { if (previewTools.isEmpty()) { return false; } - return false; + return true; } public boolean isShowQueryButton(DataFile dataFile) { diff --git a/src/main/java/edu/harvard/iq/dataverse/FilePage.java b/src/main/java/edu/harvard/iq/dataverse/FilePage.java index 01f12587fe8..eabfbb26fd9 100644 --- a/src/main/java/edu/harvard/iq/dataverse/FilePage.java +++ b/src/main/java/edu/harvard/iq/dataverse/FilePage.java @@ -377,7 +377,9 @@ private List sortExternalTools(){ List retList = new ArrayList<>(); List previewTools = externalToolService.findFileToolsByTypeAndContentType(ExternalTool.Type.PREVIEW, file.getContentType()); for (ExternalTool previewTool : previewTools) { - if (RequirementStatus.MET == externalToolService.meetsRequirements(previewTool, file, canDownload)) { + RequirementStatus status = externalToolService.meetsRequirements(previewTool, file, canDownload); + logger.info(previewTool.getToolName() + " meets requirements: " + status.name()); + if (RequirementStatus.MET == status) { retList.add(previewTool); } } From ebd93dde5ad0f76031a741b6e15979d26cdaf703 Mon Sep 17 00:00:00 2001 From: Jim Myers Date: Thu, 26 Feb 2026 18:03:46 -0500 Subject: [PATCH 07/11] only tools user can see files for are in the lists now --- src/main/webapp/file.xhtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/webapp/file.xhtml b/src/main/webapp/file.xhtml index 2292ebf4c45..51c4e447e91 100644 --- a/src/main/webapp/file.xhtml +++ b/src/main/webapp/file.xhtml @@ -361,7 +361,7 @@ + rendered="#{(FilePage.toolsWithPreviews.size() > 0 or FilePage.queryTools.size() > 0)}"> From ad489bf1962086a0997f2dd7e536c919b92b9eb8 Mon Sep 17 00:00:00 2001 From: Jim Myers Date: Thu, 26 Feb 2026 18:12:53 -0500 Subject: [PATCH 08/11] remove download check here too --- src/main/webapp/file.xhtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/webapp/file.xhtml b/src/main/webapp/file.xhtml index 51c4e447e91..bbcac14edc3 100644 --- a/src/main/webapp/file.xhtml +++ b/src/main/webapp/file.xhtml @@ -382,7 +382,7 @@