Skip to content

IBX-12042: Deprecated filename-less download route in favor of filename-validated variant#775

Open
wiewiurdp wants to merge 2 commits into
5.0from
IBX-12042-Deprecate-filename-less-download-route-content-download-contentId-fieldId-and-replace-it-with-a-filename-validated-variant
Open

IBX-12042: Deprecated filename-less download route in favor of filename-validated variant#775
wiewiurdp wants to merge 2 commits into
5.0from
IBX-12042-Deprecate-filename-less-download-route-content-download-contentId-fieldId-and-replace-it-with-a-filename-validated-variant

Conversation

@wiewiurdp

@wiewiurdp wiewiurdp commented Jul 6, 2026

Copy link
Copy Markdown
Contributor
🎫 Issue IBX-12042

Description:

The ibexa.content.download.field_id route accepts plain integer parameters only, which allows enumerating and mass-downloading all accessible files with a simple loop over contentId × fieldId (see IBX-11681, where filename validation was added to the main download route — this route bypassed it).

Changes:

  • Added a new ibexa.content.download.field_id.filename route (/content/download/{contentId}/{fieldId}/{filename}), which validates the filename against the field value and returns 404 on mismatch. It is defined before ibexa.content.download so that a numeric {fieldId} takes precedence over {fieldIdentifier}.
  • ContentDownloadUrlGenerator now generates the new route, so all field value URLs (uri in PHP API and REST) include the filename.
  • Deprecated the filename-less route: requests without a filename still work but trigger a deprecation. To be removed in 6.0.
  • Deprecated the unused DownloadRedirectionController (no route has referenced it since the GHSA-g95c-xc83-8353 fix).

@wiewiurdp wiewiurdp force-pushed the IBX-12042-Deprecate-filename-less-download-route-content-download-contentId-fieldId-and-replace-it-with-a-filename-validated-variant branch from e495713 to 5aa6a94 Compare July 6, 2026 15:17
@wiewiurdp wiewiurdp requested a review from a team July 7, 2026 09:52
@ibexa-workflow-automation-1 ibexa-workflow-automation-1 Bot requested review from Steveb-p, ViniTou, alongosz, barw4, bnowak, ciastektk, konradoboza, mikadamczyk and tbialcz and removed request for a team July 7, 2026 09:52
@wiewiurdp wiewiurdp marked this pull request as ready for review July 7, 2026 09:56
Comment thread src/lib/MVC/Symfony/Controller/Content/DownloadController.php Outdated
Comment thread src/lib/MVC/Symfony/FieldType/BinaryBase/ContentDownloadUrlGenerator.php Outdated
Comment thread tests/lib/MVC/Symfony/FieldType/BinaryBase/ContentDownloadUrlGeneratorTest.php Outdated
Comment thread tests/lib/MVC/Symfony/FieldType/BinaryBase/ContentDownloadUrlGeneratorTest.php Outdated

@konradoboza konradoboza 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.

Apart from one comment and Andrew's remarks.

Comment thread src/lib/MVC/Symfony/FieldType/BinaryBase/ContentDownloadUrlGenerator.php Outdated
@sonarqubecloud

sonarqubecloud Bot commented Jul 7, 2026

Copy link
Copy Markdown

@wiewiurdp wiewiurdp requested a review from alongosz July 7, 2026 12:05
ibexa.user_hash:
path: /_fos_user_context_hash

# Must be defined before ibexa.content.download, so that numeric {fieldId} takes precedence over {fieldIdentifier}

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.

We could add requirement for filename as well here and use https://github.com/symfony/routing/blob/7.4/Requirement/Requirement.php as their value source, eg. replace \d+ with Requirement::DIGITS

The same for missing requirements in ibexa.content.download. This way, I think we'll be secure about route ordering here as their expected argument types won't conflict with each other

{
/** @var \Symfony\Component\Routing\RouterInterface */
private $router;
private const string ROUTE = 'ibexa.content.download.field_id.filename';

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.

Do we need that const if use only in one place in this class?

}

if ($filename !== null && $field->value->fileName !== $filename) {
throw new NotFoundException('File', $filename);

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.

Is it worth to add test for that exception?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants