Problem/Motivation
File Gate reports two security findings on the status report from file_gate_requirements() in file_gate.install:
- a gated field that stores files on a public file system, so the gate never runs;
- a named secret that has a value but no field scope, so it can authenticate and mint nothing.
Drupal 11.3 replaced the procedural hook with hook_runtime_requirements(), hook_update_requirements() and an install-time class. Core now logs this on every container rebuild:
file_gate_requirements without a #[LegacyRequirementsHook] attribute is deprecated in drupal:11.3.0 and removed in drupal:13.0.0. See https://www.drupal.org/node/3549685
The notice is the small part. Drupal 13 stops calling the procedural hook, and nothing fails when that happens: the two findings leave the status report and the site reads as healthy. A check that guards a security boundary should not be able to disappear without an error.
The module's tests would not catch it. They call file_gate_requirements('runtime') directly, so they pass whether or not core ever invokes the function.
Steps to reproduce
- Install File Gate 1.9.2 on Drupal 11.4.
- Rebuild the container, or run any kernel test that enables the module, with deprecations shown.
- The notice above is logged for
file_gate_requirements.
Proposed resolution
The module already requires Drupal 11.4, so it does not need the legacy attribute or a transition period.
- Move both checks to a hook class that implements
hook_runtime_requirements(), with the entity type manager and the secret registry injected. - Remove
file_gate_requirements(). It only ever acted in the runtime phase. - Use
RequirementSeverity::Errorin place of theREQUIREMENT_ERRORconstant, which is deprecated since 11.2. - Change the tests to invoke the hook through the module handler, the way the status report does, so they fail if the hook stops being called.
Remaining tasks
- Patch and tests.
- Review.
User interface changes
None. The two status report rows keep their keys, titles, severity and text.
API changes
file_gate_requirements() is removed. It was a hook implementation, not a public API. Code that called it directly should invoke runtime_requirements through the module handler.
Data model changes
None.
Comments
Comment #4
jmcerdaThe fix is on 1.x (comment #3). Both status report findings now come from
hook_runtime_requirements()inDrupal\file_gate\Hook\FileGateRequirements, andfile_gate_requirements()is gone. Keys, titles, severity and text are unchanged.Checked on Drupal 11.4.6 with a public field deliberately marked as gated:
drush core:requirementsreportsfile_gate_public_gated_fieldsat Error, naming the field. The deprecation notice forfile_gate_requirementsno longer appears.One commit is still to land (comment #2). On 1.x the two tests that assert no finding can pass even if the hook is never invoked, because the module handler returns NULL for a module with no implementation and the tests treated that as an empty list. The commit makes them assert that the implementation exists. It also adds
#[RunTestsInSeparateProcesses]to the last kernel test without it, which Drupal 12 requires. I will set this to Fixed when that is on 1.x.After updating, rebuild caches (
drush updatedbordrush cr): the compiled container lists the removed function until it is rebuilt.Comment #6
jmcerdaBoth commits are on 1.x: the move to
hook_runtime_requirements()(comment #3) and the test follow-up (comment #5). The requirements tests now assert that the implementation exists, so they fail if the hook stops being called; with the#[Hook]attribute removed, all four fail. Every kernel test in the project carries#[RunTestsInSeparateProcesses].Setting this to Fixed. It will be in the next 1.x release. Rebuild caches after updating.