You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Surface DSpace's Request-a-Copy (request.item.type) for genuinely access-restricted files, without showing it on files that are merely awaiting license confirmation.
Background / why it's off today
Request-a-Copy never appears for two reasons:
The inline link-rewrite in FileDownloadLinkComponent.getBitstreamPath() is commented out (since the 7.5 upgrade, commit eef127f).
The item page render path (clarin-files-section → preview-section → file-description) bypasses ds-file-download-link entirely, so no canDownload/canRequestACopy is ever evaluated there.
Do not re-enable the upstream inline component. On a file with an unsigned license, canDownload=false and canRequestACopy=true (because RequestCopyFeature = !authorizeActionBoolean(READ), and the license exception makes READ false). Re-enabling the upstream if
(!canDownload && canRequestACopy) redirect would therefore render a spurious "Request a copy" button on every license-pending file — the exact conflict we want to avoid.
Where the button goes (and why this is conflict-free)
Put the request button on ClarinBitstreamAuthorizationDeniedComponent — the page that renders clarin.bitstream.authorization.denied.message ("Access to download the … file was denied by the bitstream resource policy").
This is safe by construction, not by luck:
Backend AuthorizeServiceImpl.authorizeAction() throws "Authorization denied…" for a resource-policy failure before the license check (authorizeBitstream) ever runs.
The FE processClarinAuthorization() forks the two failures onto different pages: MISSING_LICENSE_AGREEMENT_EXCEPTION → license-agreement page; AUTHORIZATION_DENIED_EXCEPTION → this denied page.
So a license problem can never land on the denied page. Gate the button on being on this page (the exception), never on canRequestACopy alone — the latter is true on license pages too and would reintroduce the conflict.
Implementation notes for the button:
The denied component only has bitstream$; the request-a-copy route is /items/{itemUuid}/request-a-copy?bitstream={uuid}, so resolve bitstream → parent item first.
The target BitstreamRequestACopyPageComponent re-checks auth and bounces to /forbidden if its check fails — confirm canRequestACopy=true before linking.
With request.item.type=logged, anonymous users on the denied page get canRequestACopy=false (no button) — decide whether to prompt login instead of leaving a dead end.
What's expected of the license on the item
Restricted files that should offer Request-a-Copy: have no READ resource policy and no license mapping. These fail authorize(READ) first → denied page → button. This is the only population the feature targets.
Files with a license: must carry a READ policy + a license mapping; they route to the license page, never the denied page.
To make a license transparent (behave like upstream, no extra gate), attach a license whose confirmation is NOT_REQUIRED — getLicenseToAgree returns null, so READ collapses to pure resource-policy. Use this for items that should behave exactly like stock DSpace.
Configuration
request.item.type = logged (or all) — blank disables the feature.
request.item.reject.email (default true) — whether rejections email the requester.
Grant-side delivery — TBD, blocked on DSpace 9
On approval, the current backend (RequestItemEmailNotifier.sendResponse) emails the raw file bytes as attachments — no link fallback, no size cap. This breaks for large datasets.
The clean fix (secure time-limited download link) is DSpace 9.0 only (issues DSpace/DSpace#10265/DSpace/DSpace#10407, FE DSpace#3984, DSpace/RestContract#307). It is not back-portable cheaply, and the existing dtoken (in our fork) cannot be reused as a substitute: the dtoken is welded to
license_resource_mapping at mint, storage, and verification (findByTokenAndBitstreamId keys on clrua.licenseResourceMapping.bitstream.id), so it can't be issued for a no-mapping file.
Goal
Surface DSpace's Request-a-Copy (request.item.type) for genuinely access-restricted files, without showing it on files that are merely awaiting license confirmation.
Background / why it's off today
Request-a-Copy never appears for two reasons:
Do not re-enable the upstream inline component. On a file with an unsigned license, canDownload=false and canRequestACopy=true (because RequestCopyFeature = !authorizeActionBoolean(READ), and the license exception makes READ false). Re-enabling the upstream if
(!canDownload && canRequestACopy) redirect would therefore render a spurious "Request a copy" button on every license-pending file — the exact conflict we want to avoid.
Where the button goes (and why this is conflict-free)
Put the request button on ClarinBitstreamAuthorizationDeniedComponent — the page that renders clarin.bitstream.authorization.denied.message ("Access to download the … file was denied by the bitstream resource policy").
This is safe by construction, not by luck:
So a license problem can never land on the denied page. Gate the button on being on this page (the exception), never on canRequestACopy alone — the latter is true on license pages too and would reintroduce the conflict.
Implementation notes for the button:
What's expected of the license on the item
Configuration
Grant-side delivery — TBD, blocked on DSpace 9
On approval, the current backend (RequestItemEmailNotifier.sendResponse) emails the raw file bytes as attachments — no link fallback, no size cap. This breaks for large datasets.
The clean fix (secure time-limited download link) is DSpace 9.0 only (issues DSpace/DSpace#10265/DSpace/DSpace#10407, FE DSpace#3984, DSpace/RestContract#307). It is not back-portable cheaply, and the existing dtoken (in our fork) cannot be reused as a substitute: the dtoken is welded to
license_resource_mapping at mint, storage, and verification (findByTokenAndBitstreamId keys on clrua.licenseResourceMapping.bitstream.id), so it can't be issued for a no-mapping file.
References