Problem/Motivation
When using a simplified custom access checker (as documented at https://www.drupal.org/node/2122195#access-custom), the method does not have access to the Request object. According to the documentation"the available arguments are the same as for the service defined method.". But when the method has a argument type-hinted with Symfony\Component\HttpFoundation\Request a null value is received.
This is a very useful feature if you're doing some one off JWT style query access or some session based access control. These are the sort of use cases you might logically use a one off custom access test and it is possible with additional boiler plate but it doesn't really match expectations when writing a custom access check.
Steps to reproduce
When using the following route and controller:
# test_module.routing.yml
test_module.test_route:
path: '/test'
defaults:
_controller: '\Drupal\test_module\Controller\TestController::test'
requirements:
_custom_access: '\Drupal\test_module\Controller\TestController::access'
namespace Drupal\test_module\Controller;
use Symfony\Component\HttpFoundation\Request;
class TestController extends ControllerBase implements AccessInterface {
public function access(Request $request) {
// ...
}
public function test(Request $request) {
// ...
}
}
Accessing the route trigger the following error: Uncaught PHP Exception RuntimeException: "Callable "Drupal\test_module\Controller\TestController::access" requires a value for the "$request" argument.
If the same code is used as a service with the following config:
# test_module.routing.yml
test_module.test_route:
path: '/test'
defaults:
_controller: '\Drupal\test_module\Controller\TestController::test'
requirements:
_test_access_check: 'TRUE'
# test_module.services.yml
services:
test_module.test_access_check:
class: Drupal\test_module\Controller\TestController
tags:
- { name: access_check, applies_to: _test_access_check }
Then the access check works as expected and receive a request object.
Proposed resolution
Add request to injected argument list.
Remaining tasks
Review/Commit
User interface changes
N/A
API changes
No changes to existing API's and fully BC compatible with existing implementations..
Data model changes
n/a
Release notes snippet
TODO
| Comment | File | Size | Author |
|---|---|---|---|
| #73 | Screenshot from 2023-09-07 14-21-56.png | 78.15 KB | roshni27 |
| #73 | Screenshot from 2023-09-07 14-21-56.png | 78.15 KB | roshni27 |
| #73 | drupal-2786941-73.patch | 6.68 KB | roshni27 |
| #68 | drupal-2786941-68.patch | 6.79 KB | lamp5 |
| #44 | 2786941-44.patch | 6.82 KB | neclimdul |
Comments
Comment #2
pbuyle commentedComment #3
dawehnerYeah for some reason (no idea why)
\Drupal\Core\Access\CustomAccessCheck::accessjust passes along the$route_matchas well as$request.Comment #5
dawehnerHere is a bugfix for it.
Comment #9
gnugetRebase of #5
Comment #13
littletiger commentedHi, I can confirm this patch works for Drupal 8.5.5.
Funny to be learning something new, run into errors and discover it's a bug to be solved in Drupal 8.7 ;D
Why not 8.6 ?
Note, I didn't run the test, don't know why it's failing in #9 ?
Comment #14
gnugetAll the bugs are fixed first in the development version and later if necessary/possible are backported to the stable version.
So, 8.6 is almost out (The first alpha has been already released) so any new fix first will be commited to 8.7 and later can be backported to 8.6.
I will run again the tests on #9 to see if it was a random error.
Comment #15
littletiger commentedAnytime I navigate to /user/# I get the error "The website encountered an unexpected error. Please try again later.".
Watchdog log shows the following error :
RuntimeException: Callable "Drupal\Core\Access\CustomAccessCheck::access" requires a value for the "$request" argument. in Drupal\Component\Utility\ArgumentsResolver->handleUnresolvedArgument() (line 142 of /srv/bindings/37df6945aeee4c2cb52bb8fb431fc585/code/core/lib/Drupal/Component/Utility/ArgumentsResolver.php).
After applying the patch... still no luck :-( This should be related, if not the same, no?
Comment #16
wengerkRe-roll the patch from #09 for
8.7.x.Here are my changes the following declaration (impossible to generate an interdiff see below):
1. Make the $request optional to prevent breaking the whole custom Access:
PS: I wasn't able to generate the
interdifffile sorry guys ...Comment #19
firfin commentedSolves the problem for me. Luckily I found this post, I was trying to learn D8 routing, menu and access systems and this bug was driving me crazy for days! My problems are not completely solved. But getting a lot less WSODs now.
Does not apply to D8.8 though. I will try and re-roll an D8.9 version tomorrow
Comment #20
firfin commentedREstoring status
Comment #22
sadashiv commentedHi,
I am attaching patch rolled again for 8.9.x and 9.1.x
Thanks,
Sadashiv.
Comment #25
sadashiv commentedForgot to fix getMock deprecation, now fixed
Thanks,
Sadashiv.
Comment #26
firfin commentedTested with my D8 project in which I encountered this bug and #25 works for me, thanks @sadashiv.
Will try and test with D9 some time soon.
Comment #28
ollie222 commentedUsing Drupal 8.9.8 the patch in #25 applies cleanly.
If I use a simple route and access check similar to #1 such as
then when I access the route directly $request is available in the access check so the patch looks to work correctly.
Now this is probably outside of the remit of this problem but it's sort of linked.
What should happen if the route is used as a tab on a node view page?
If I do this then when viewing the node view/edit page the access check is called but $request is missing again.
Should $request be available on these pages, is this caused by something else?
Comment #29
firfin commentedIs good for D8.
Comment #30
catch#28 looks relevant are we missing something passing request when checking access to a route for a tab?
Comment #31
dawehnerFrom my understanding this is already the case for any other access checker on local tasks, see https://git.drupalcode.org/project/drupal/-/blob/9.2.x/core/lib/Drupal/C...
This code is calling
\Drupal\Core\Access\AccessManager::checkNamedRoute, which sets $request as null.Maybe the documentation could be better:
Comment #32
abhijith s commentedFixed the custom command fail issue in patch #25
Comment #34
joachim commentedComment #35
catchNeeds a re-roll, and could also use the comment improvement from #31.
Comment #36
kishor_kolekar commentedplease review the patch.
Comment #38
kostyashupenkoComment #39
sadashiv commentedRerolling the patch with all changes.
Thanks,
Sadashiv.
Comment #41
sadashiv commentedRetrying with minor changes
Comment #43
neclimdulPretty sure this is a soft merge failure caused by #3217717: Replace usages of the at() matcher, which is deprecated. There are now two calls to controllerResolved->expect($this->exactly(3)) which I assume means there are suppose to be... 6? I need to dig into this test more but mocks are kinda inscrutable so it might take a few.
Comment #44
neclimdulyeah, was definitely that issue but I didn't notice the patches here where still using the
at()method which is why they weren't working.This is a reroll of the RTBC'd #32 without the later changes + the at() changes in the interdiff.
Comment #45
neclimdulDid a review and everything in this is pretty straightforward and looks good to go. Didn't really touch anything other then fixing the tests(feel free to adjust credit accordingly) but probably not appropriate to RTBC.
Touched up the summary into template and document why this is useful and other issue cleanup. Technically this is working by design just missing some very expected functionality so updating this to a feature as well.
Comment #47
froboyThe changes above have passed tests and I've reconfirmed that this patch applies cleanly and does its job. Look to be RTBC to me.
Comment #49
froboyWomp womp. I'll try to take a look at this.
Comment #50
froboyTests seem to be failing due to #3255836: Test fails due to Composer 2.2. I guess we'll just wait until that's resolved. Not flipping back to RTBC until we can get those to pass.
Comment #51
froboyNew tests passed, marking this RTBC again.
Comment #53
neclimdulThis seems to be a random failure.
Comment #55
neclimdulDrupal\Tests\layout_builder\FunctionalJavascript\*againComment #56
pfrenssenRTBC++
Comment #58
renrhaf+1 RTBC
Comment #59
yogeshmpawar+1 RTBC. Hope the random test failures are resolved now.
Comment #60
geek-merlinOuch, just ran into this DX pita. +1 for commit.
Comment #62
ravi.shankar commentedBack to RTBC.
Comment #65
dieterholvoet commentedBack to RTBC after more random test failures (#3269085: [random test failure] Random test fail in EntityAutocompleteTest).
Comment #68
lamp5Reroll 9.5.x-dev
Comment #70
frobIs there anything stopping this from getting committed? It has been RTBCed and rerolled for over 3 years.
Comment #71
neclimdulI'm not really sure. While I remember _why_ I got here, but its been so long I honestly don't remember the code at all...
That said, the current patch looks the same as all the other RTBC patches and applies cleanly so putting it back to RTBC.
Comment #72
catchDoesn't apply to 11.x
Comment #73
roshni27 commentedIssue #68 is functional; it requires only minor adjustments. The patch has been updated for versions 10.x. However, it wasn't originally applied to 11.x, but after making the necessary changes in the 11.x branch, the patch is now successfully applied. As discussed earlier, the patch modifications resolve the issue effectively, so it functionality remains as is.
Comment #74
smustgrave commentedRestoring status after reroll
Comment #76
catchCommitted/pushed to 11.x, thanks!
Comment #78
froboyFixing my credit.