Skip to content

fix: possible locally fair dataset download fix - #12581

Open
srmanda-cs wants to merge 2 commits into
IQSS:developfrom
uncch-rdmc:12579-locally-fair-dataset-ui-download-fix
Open

fix: possible locally fair dataset download fix#12581
srmanda-cs wants to merge 2 commits into
IQSS:developfrom
uncch-rdmc:12579-locally-fair-dataset-ui-download-fix

Conversation

@srmanda-cs

Copy link
Copy Markdown
Contributor

What this PR does / why we need it:
Fixes the locally FAIR dataset download issue outlined in #12579 that prevents dataset files within a locally FAIR dataverse from being downloaded

Which issue(s) this PR closes:

Special notes for your reviewer:
N/A

Suggestions on how to test this:
Spin up a docker container on develop, verify that dataset downloads don't work. Spin up this branch and verify that dataset downloads start working once again

Does this PR introduce a user interface change? If mockups are available, please link/include them here:
N/A

Is there a release notes update needed for this change?:
N/A

Additional documentation:
N/A

Copilot AI review requested due to automatic review settings August 1, 2026 00:25

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a UI download failure (404) for files in datasets under a Locally FAIR-enabled Dataverse by ensuring Locally FAIR visibility checks are performed with the session-backed DataverseRequest rather than a GuestUser request derived from the JAX-RS ContainerRequestContext.

Changes:

  • Adjust findDataFileUserCanSeeOrDieWrapper to swap in dvRequestService.getDataverseRequest() when the incoming request user is GuestUser.
  • Ensures Locally FAIR access checks in AbstractApiBean.findDataFileUserCanSeeOrDie(...) receive an authenticated/session user where applicable, preventing false “not found” outcomes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/main/java/edu/harvard/iq/dataverse/api/Access.java
Comment on lines +283 to +285
if (req.getUser() instanceof GuestUser) {
req = dvRequestService.getDataverseRequest();
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pending IQSS team review and suggestions.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fix takes the right approach, but I think this is too broad, as it affects all APIs and is essentially the same as https://guides.dataverse.org/en/latest/installation/config.html#dataverse-feature-api-session-auth, with the same risk noted in the Guides. (Nominally a work-around for testing LFAIR though). The access apis are special in that they are the only ones called from the JSF UI directly, so we need to allow session auth just for them even when the flag is off. This is currently being handled in a few related Access methods - see

// checkAuthorization is a convenience method; it calls the boolean method
// isAccessAuthorized(), the actual workhorse, and throws a 403 exception if not.
private void checkAuthorization(User initialUser, DataFile df) throws WebApplicationException {
User user = getRequestor(initialUser);
if (!isAccessAuthorized(user, df)) {
throw new ForbiddenException();
}
}
private User getRequestor(User user) {
// CompoundAuthMechanism should find the user by API Key/Token, Workflow, etc. And for SPA the Bearer Token
// For JSF check if CompoundAuthMechanism couldn't find the user then try to get it from the session
if (session!=null && user instanceof GuestUser) {
user = session.getUser();
}
return user;
}
and
private boolean checkGuestbookRequiredResponse(User user, UriInfo uriInfo, DataFile df, String gbrids) throws WebApplicationException {
// Check if guestbook response is required
Dataset d = df.getOwner();
boolean required = df.getOwner().hasEnabledGuestbook() && !d.getEffectiveGuestbookEntryAtRequest();
boolean wasWrittenInPost = false;
if (required) {
User requestor = getRequestor(user);
if (requestor instanceof AuthenticatedUser && permissionService.userOn(requestor, df.getOwner()).has(Permission.EditDataset)) {
required = false;
}
// Check if we are downloading a thumbnail image which doesn't require a guestbook response
boolean imageThumb = uriInfo.getQueryParameters().containsKey("imageThumb");
if (imageThumb) {
required = false;
}
if (required && gbrids != null && !gbrids.isEmpty()) {
try {
// verify that this id is good
GuestbookResponse gbr = guestbookResponseService.findById(Long.valueOf(gbrids));
if (gbr == null) {
throw new NotFoundException("GuestbookResponse Not Found for id:" + gbrids);
}
Long delta = Instant.now().toEpochMilli() - gbr.getResponseTime().getTime();
wasWrittenInPost = gbr.getDataset().getId().equals(df.getOwner().getId()) && delta <= (GUESTBOOK_RESPONSE_SIGNEDURL_TIMEOUT_MINUTES * 60000L);
} catch (NumberFormatException | DateTimeParseException ex) {
throw new BadRequestException(ex.getMessage());
}
}
}
return required && !wasWrittenInPost;
}
, which are known to have bugs related to privateUrl users - see #12569, #12548, etc. There is also a PR coming that shuffles a lot of this code #12479.

We probably need to discuss this more, but I might suggest we simplify by just exempting the access apis in https://github.com/IQSS/dataverse/blob/develop/src/main/java/edu/harvard/iq/dataverse/api/auth/SessionCookieAuthMechanism.java which should resolve this issue, and the private URL one and clean up the code. I'll put this in triage so this gets on the radar Monday.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the detailed review and context!

My original fix was definitely intended as a minimal proof-of-concept to get the root cause and a workaround on the team's radar.

Your suggestion to handle this at the SessionCookieAuthMechanism level makes a lot of sense. I am happy to pause or close this PR and let the team discuss the best path forward.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@donsizemore

Copy link
Copy Markdown
Contributor

may also close #12563

@qqmyers qqmyers moved this to Ready for Triage in IQSS Dataverse Project Aug 1, 2026
@qqmyers qqmyers added this to the 6.12 milestone Aug 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Ready for Triage

Development

Successfully merging this pull request may close these issues.

UI Downloads do not work in datasets with a locally FAIR enabled Dataverse

4 participants