Updated: Comment #N
Problem/Motivation
When checking access for a path like "/admin/structure/views", we have no problem, since we can find out the route is views_ui.list
But checking access for a path like "/admin/structure/views/view/frontpage" is a problem, because the actual route is views_ui.edit
, but the path is /admin/structure/views/view/{view}, and we have no way to match that.
Proposed resolution
Add a new method to AccessManager that can parse a route name and an array of parameters:
$this->accessManager->checkNamedRoute('views_ui.edit', array('view' => 'frontpage'));
Remaining tasks
N/A
User interface changes
N/A
API changes
API addition: checkNamedRoute() is added to AccessManager
The constructor change to AccessManager is not an API change because it is a service.
Related Issues
Blocked by this:
#2044539: Implement LocalTask plugins for login/password/register tabs
#2056627: Form API autocomplete is broken for routes
#2045267: LocalTaskBase and LocalTaskInterface has to work with routes containing parameters
#2048969: LocalActionBase and LocalActionInterface has to work with routes containing parameters
#2040065: Remove _account from request and use the current user service instead. (partially)
#2040379: Define contextual entity operations through annotation; remove the context property from hook_menu items
Original report by @pwolanin
motivation:
As we move towards a full route-based system, we need to handle access based on route and parameters rather than tying ourselves in knots reconstructing system paths.
The method we are looking to add should take a route name, an array of parameters, and maybe an optional request objects (defaults to the current one in the DIC) - it would then find the route and load any objects needed before passing off to the actual access checks.
For some use cases, this depends on:
#2031487: When replacing the upcasted values in the request attributes array, retain the original raw value too
Comment | File | Size | Author |
---|---|---|---|
#28 | access-2046737-28.patch | 14.37 KB | tim.plunkett |
#17 | access_manager-2046737-17.patch | 14.37 KB | dawehner |
#17 | interdiff.txt | 5.09 KB | dawehner |
#16 | access_manager-2046737-16.patch | 13.79 KB | dawehner |
#16 | interdiff.txt | 2.13 KB | dawehner |
Comments
Comment #1
pwolanin CreditAttribution: pwolanin commentedthis would be very helpful for local action and local task plugins, and for menu links as we convert those to be route based.
Comment #2
pwolanin CreditAttribution: pwolanin commentedThe method we are looking to add should take a route name, an array of parameters, and maybe an optional request objects (defaults to the current one in the DIC) - it would then find the route and load any objects needed before passing off to the actual access checks.
Comment #2.0
pwolanin CreditAttribution: pwolanin commentedexpand summary
Comment #3
pwolanin CreditAttribution: pwolanin commentedHere's small start.
Comment #4
tim.plunkettIndented wrong.
I just had $$this in another issue, certainly didn't work like I wanted :_
Comment #6
pwolanin CreditAttribution: pwolanin commentedFixes those little issues, but honestly my head is exploding a bit as I trying to find a simple and efficient code path to take a known route + parameters and check access on it. Using the router code to match the request based on a URL seems totally silly - we already know the route.
Comment #7
pwolanin CreditAttribution: pwolanin commentedThis fleshes out the method code a little more, but it feels like a hack.
Comment #8
dawehnerJust did a bit of work on the tests, but no real progress.
Comment #9
dawehnerSome more tracking of work.
Comment #10
dawehnerCompleted the test coverage.
Comment #12
dawehnerOh another one showing a clear lack of sleep.
Comment #13
Crell CreditAttribution: Crell commentedShouldn't this be _account now?
Comment #14
dawehnerYou are totally right.
Thanks for your review!
Comment #15
Crell CreditAttribution: Crell commentedExceptions are expensive. Something like checkedNamedRoute() should be returning True/False, not exceptioning.
Comment #16
dawehnerThis totally makes sense, especially this is simpler.
Comment #17
dawehnerThis replaces to get the current request to get it from an injected version instead of the container.
Comment #18
catchThis looks saner but checkNamedRoute() could use some profiling. Have never been keen on mocking the request for every access check and this adds even more setup.
Comment #19
dawehner.
Comment #20
dawehnerTo be honest the DB query to load the route worries me, but there is no way around that.
Comment #21
pwolanin CreditAttribution: pwolanin commented@catch - I'm not sure the setup is much more than what's in :
https://api.drupal.org/api/drupal/includes%21menu.inc/function/_menu_lin...
we load all the objects there, etc just in an array rather than a Request object.
Comment #22
dawehnerI am fine with creating a profile, but I am not sure what really to profile. The complex bits are probably the route naming but that is cached.
Comment #23
dawehner#17: access_manager-2046737-17.patch queued for re-testing.
Comment #25
pwolanin CreditAttribution: pwolanin commented#17: access_manager-2046737-17.patch queued for re-testing.
Comment #26
pwolanin CreditAttribution: pwolanin commentedI think this is ready to go it- it's blocking several other issues for me as well. It's a small actual change and has added tests.
As a follow-up we should consider a flag for the generator to skip aliases at least? We want to make that step of creating the request object as efficient as possible.
Comment #27
tim.plunkettThis didn't seem critical because all of the work we've done have been with relatively simple routes. Now we're hitting the hard stuff.
Here's a list of issues this blocks, I will add it to the issue summary
#2044539: Implement LocalTask plugins for login/password/register tabs
#2056627: Form API autocomplete is broken for routes
#2045267: LocalTaskBase and LocalTaskInterface has to work with routes containing parameters
#2048969: LocalActionBase and LocalActionInterface has to work with routes containing parameters
#2040065: Remove _account from request and use the current user service instead. (partially)
#2040379: Define contextual entity operations through annotation; remove the context property from hook_menu items
Comment #27.0
tim.plunkettadd 2031487
Comment #28
tim.plunkettThe changes to core.services.yml were next to the newly added CSRF stuff, just a straight reroll.
#22 asks what to even profile here...
Comment #29
catchWell the thing to profile would be when the method gets used a lot of times on the same page. Looks like we've got use cases for this but it's going to be local tasks and contextual links that are the worst which probably isn't so bad. My concern would be if start calling this on regular menu links so in turn create dozens or hundreds of request objects for each access check (not that the performance of that isn't already terrible in general). But we're not doing that yet and might not.
So... committed/pushed to 8.x.
Comment #30
dawehnerLet's figure out first how to do it for local tasks/actions and then discuss how to do it for menu links, because to be honest menu_item_route_access() is doing that already, so we should try to improve the performance here.
Comment #31
dawehnerWrote a changenotice: https://drupal.org/node/2078997
Comment #32
pwolanin CreditAttribution: pwolanin commentedmade a few added tweaks, but looks good.
Comment #34
xjmUntagging. Please remove the tag when the change notification task is completed.
Comment #34.0
xjmupdated