Problem/Motivation
Steps to reproduce copied from http://drupal.org/node/1986140#comment-7437524 :
- D8 as of http://drupalcode.org/project/drupal.git/commit/2de137060a292be8bdc7bdf7...
- Create blank database
- Install using the minimal install profile
- Enable layout module
- Visit /user/1
- Receive "Access Denied" and this error:
Warning: Illegal offset type in isset or empty in Drupal\Component\Plugin\Discovery\ProcessDecorator->getDefinition() (line 54 of core/lib/Drupal/Component/Plugin/Discovery/ProcessDecorator.php).
Proposed resolution
layout_user_access() is being called on this page and passing a full user object into getDefinition(). When you try to use that as an array index, you get the error, the access check fails, and 403.
The underlying issue is that layout_user_access is interpreted as an implementation of hook_entity_access. That hook is not currently documented, but can be found in /core/lib/Drupal/Core/Entity/EntityAccessController.php.
To avoid this unintended collision, the proposed solution is to rename "layout_user_access" to "layout_check_user_access." This avoids the error and the 403, without changing the access behavior of the layout module.
| Comment | File | Size | Author |
|---|---|---|---|
| #29 | 1986140-layout_user_access-29.patch | 838 bytes | phl3tch |
| #19 | 1986140-layout_user_access.patch | 828 bytes | gcassie |
Comments
Comment #1
xmacinfoI should have reinstalled from scratch.
Comment #2
neRok commentedWarning: Illegal offset type in isset or empty in Drupal\Component\Plugin\Discovery\ProcessDecorator->getDefinition() (line 54 of core\lib\Drupal\Component\Plugin\Discovery\ProcessDecorator.php).I have installed D8 with todays latest dev and got the error. Standard profile, disabled overlay and enabled book and forum (if they make a difference). When clicking
My Account, which the link shows the url as/user, it redirects to/user/1and I have the error, plus its an Access Denied page. The user account isadmin, which is Administrator role, and all permissions are enabled for that role (default).Comment #3
aspilicious commentedPlease read #1. A clean install (whipe everything and reinstall) worked. HEAD 2 HEAD updates aren't supported yet...
Comment #4
neRok commentedIt was my first Drupal 8 install on my dev machine. So it was unzipped files from downloaded file, new database, ran install.php, etc. It was "installed from scratch".
Comment #5
aspilicious commentedHmm thats not good :)
Comment #6
xmacinfo@neRok: Can you reproduce with a new install? New download and new database?
Comment #7
neRok commentedI did a new install, checked the profile, no errors. Tweaked some modules as per the first time, no errors.
I did another new install, tweaked the modules, checked the profile, no errors.
So yer, cannot reproduce on a new install.
However, the first install I did (#2) still has the problem, so something is going wrong and needs fixing.
Comment #8
xmacinfo@neRok: As aspilicious mentionned, HEAD 2 HEAD updates aren’t supported. You will need to wait until the next phase of development to start seeing support for updates.
Comment #9
neRok commentedThe first time I had the error was with fresh/new/virgin install. NO UPDATE OF ANY FORM!
Maybe the 2nd and 3rd time I did fresh installs did not replicate the error, but it doesnt discount the fact there was (and still is on that first install) an error.
I believe this should be open and investigated.
Comment #10
pztrick commentedI also encountered this also on a fresh/virgin Drupal 8 spark distribution install. So the issue may require further investigation...
Additional (perhaps relevant) information: My install.php is hanging at step 38 (first install) and step 41 (second install on completely clean drupal folder, dropped database, etc) -- this may or may not be related to this issue manifesting.
If I encounter another install.php hang at step XX I will probably openly a separate issue.#1991334: update module fails to install on Ubuntu 12.04 host
Comment #11
mrP commentedI'm encountering this bug and it only happens with the core layout module enabled. When disabled, no error. When enabled:
Access denied
Warning: Illegal offset type in isset or empty in Drupal\Component\Plugin\Discovery\ProcessDecorator->getDefinition() (line 54 of core\lib\Drupal\Component\Plugin\Discovery\ProcessDecorator.php).
Comment #12
mrP commentedtagging appropriate component
Comment #13
xmacinfoLooks like you can reproduce. Would you mind writing up a few steps to reproduce correctly?
Comment #14
mrP commentedSure:
1. D8 as of http://drupalcode.org/project/drupal.git/commit/2de137060a292be8bdc7bdf7...
2. Create blank database
3. Install using the minimal install profile
4. Enable layout module
5. Error
Comment #15
mrP commentedEDIT: Just tested a fresh install with the standard install profile and
noerrors after enabling layout and going to user/1.Comment #16
neRok commentedWith this new info, I went to my broken install from #2, and disabled Layout module.
The following error appeared
Warning: Invalid argument supplied for foreach() in _drupal_schema_initialize() (line 313 of core\includes\schema.inc).I can now access the user profile view and edit pages.
I re-enabled the Layout module, and access to user profile is once again access denied.
When enabling the Layout module, I also received the above error twice.
Comment #17
yesct commentedneeds the issue summary template http://drupal.org/issue-summaries
and those great steps to reproduce from #14 need to be in the issue summary
Comment #18
gcassie commentedAlso able to reproduce this error. Seems to be because layout_user_access() is passing a full user object into getDefinition() and then things choke on trying to use an object as an array index. Poking it a bit now and will come back w/ finding and/or issue summary.
Comment #19
gcassie commentedUpdated the issue summary. Patch attached.
Comment #20
phl3tch commentedAble to reproduce the error (with a fresh standard install). The patch fixes it, though I'm at a loss to understand why it works or why the error is even occurring. I'm fairly new to D8, and I must admit I don't fully grep the whole plugin API yet, but what baffles me is why an access callback for admin/structure/templates/manage/% is coming into play on user/%. This patch definitely vanquishes the error, but I wonder if the error isn't indicative of a deeper problem.
I'm not going to change the status. If someone can cue me in as to what's happening here and I can trace my way through it, I'll happily give it a thumbs up.
Comment #21
xmacinfo@gcassie: Thanks for the issue summary and the patch. Marked as RTBC as per @phl3tch comment, although why tracker and layout would need an underscore-prefix function is not clear.
Comment #22
catchThe access callback could be due to a menu link from that page, although if it is then that's a sign of a deeper problem.
Also this suggests we've got very little functional test coverage of layout module so seems worth adding.
Comment #23
gcassie commentedIt seems to have something to do with that leading underscore. If you, for example, remove it from the tracker module's _tracker_user_access() and the menu access callback, the whole site throws a server error. Also noticed devel prefaces its custom access callback with an underscore. What I can't find is why/where it matters.
Comment #24
neRok commentedAFAIK, the leading underscore makes the function private (ie only for that module).
Comment #25
phl3tch commentedTrue, but that's just a coding convention — for the sake of us humans reading the code. It doesn't (shouldn't anyway) cause any change in functionality.
Comment #26
phl3tch commentedAlright, I did a bit of digging and figured out what's going on here. It seems that the access callback is colliding with hook_entity_access, which is as yet undocumented, but can be found in /core/lib/Drupal/Core/Entity/EntityAccessController.php.
When the callback is named layout_user_access, it's interpreted to be a hook implementation, and Drupal dutifully passes the user object to it instead of whatever $key is supposed to be. When the callback is renamed _layout_user_access, it no longer matches the hook signature and thus no longer functions as a hook. It's not that the underscore is "doing" anything per se — you'd get the same effect if you named it banana_user_access.
So that's why the patch works. It's pretty clear the callback was not intended to be a hook implementation, so I think we can safely say the patch is good to go.
Comment #27
catchLet's add a comment explaining that the function name will collide without the underscore so no-one tries to rename it back.
The bug is silly enough I don't think it needs an automated test though.
Comment #28
neRok commentedOr call it something completely different like layout_check_user_access?
Comment #29
phl3tch commentedGood call.
Comment #30
gcassie commentedLooks good. Probably another issue, but should _tracker_user_access() be similarly renamed?
Comment #31
phl3tch commentedYep. I'll make a new issue for that shortly.
Comment #32
attiks commentedremoving 'needs tests' tag
Comment #33
attiks commented#30 Follow up created #2003432: Rename _tracker_user_access
Comment #34
BrockBoland commentedNeeds an issue summary: http://drupal.org/node/1427826
Comment #35
ndewhurstHere at Drupalcon Portland 2013. I'll take a crack at adding the issue summary.
Comment #35.0
ndewhurstadding issue summary - http://drupal.org/issue-summaries
Comment #36
ndewhurstUpdated issue summary to include hook_entity_access explanation.
Comment #36.0
ndewhurstndewhurst
Comment #37
xmacinfoRenaming layout_user_access() and tracker_user_access() is one thing.
Fixing /core/lib/Drupal/Core/Entity/EntityAccessController.php uses of hook_entity_access is another.
1. We should document hook_entity_access.
2. We should see if we can use that hook to give the correct permission to the user, or just rename the functions for Layout and Tracker.
Once hook_entity_access is properly documented, it should be easier to see what is missing.
Leaving as RTBC for now.
Comment #38
xmacinfoThe Translation entity module might give us the correct example on how use the hook_entity_access:
and
the following
translation_entity_permission()function.Although I cannot find where is defined the hook_entity_access.
Comment #39
alexpottThis will be fixed by #1978910: Convert layout_page_view to a Controller