Problem/Motivation

Steps to reproduce copied from http://drupal.org/node/1986140#comment-7437524 :

  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. Visit /user/1
  6. 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.

Comments

xmacinfo’s picture

Status: Active » Closed (cannot reproduce)

I should have reinstalled from scratch.

neRok’s picture

Status: Closed (cannot reproduce) » Active

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).

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/1 and I have the error, plus its an Access Denied page. The user account is admin, which is Administrator role, and all permissions are enabled for that role (default).

aspilicious’s picture

Please read #1. A clean install (whipe everything and reinstall) worked. HEAD 2 HEAD updates aren't supported yet...

neRok’s picture

It 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".

aspilicious’s picture

Hmm thats not good :)

xmacinfo’s picture

@neRok: Can you reproduce with a new install? New download and new database?

neRok’s picture

I 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.

xmacinfo’s picture

Status: Active » Closed (cannot reproduce)

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

neRok’s picture

The 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.

pztrick’s picture

I 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

mrP’s picture

I'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).

mrP’s picture

Component: plugin system » layout.module

tagging appropriate component

xmacinfo’s picture

Status: Closed (cannot reproduce) » Active

Looks like you can reproduce. Would you mind writing up a few steps to reproduce correctly?

mrP’s picture

Sure:

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

mrP’s picture

EDIT: Just tested a fresh install with the standard install profile and no errors after enabling layout and going to user/1.

neRok’s picture

With 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.

yesct’s picture

needs the issue summary template http://drupal.org/issue-summaries
and those great steps to reproduce from #14 need to be in the issue summary

gcassie’s picture

Also 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.

gcassie’s picture

Status: Active » Needs review
StatusFileSize
new828 bytes

Updated the issue summary. Patch attached.

phl3tch’s picture

Able 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.

xmacinfo’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: -Needs issue summary update

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

catch’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs tests, +Needs issue summary update

The 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.

gcassie’s picture

It 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.

neRok’s picture

AFAIK, the leading underscore makes the function private (ie only for that module).

phl3tch’s picture

True, 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.

phl3tch’s picture

Status: Needs work » Reviewed & tested by the community

Alright, 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.

catch’s picture

Status: Reviewed & tested by the community » Needs work

Let'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.

neRok’s picture

Or call it something completely different like layout_check_user_access?

phl3tch’s picture

Status: Needs work » Needs review
StatusFileSize
new838 bytes

Good call.

gcassie’s picture

Status: Needs review » Reviewed & tested by the community

Looks good. Probably another issue, but should _tracker_user_access() be similarly renamed?

phl3tch’s picture

Yep. I'll make a new issue for that shortly.

attiks’s picture

Issue tags: -Needs tests

removing 'needs tests' tag

attiks’s picture

BrockBoland’s picture

Needs an issue summary: http://drupal.org/node/1427826

ndewhurst’s picture

Here at Drupalcon Portland 2013. I'll take a crack at adding the issue summary.

ndewhurst’s picture

Issue summary: View changes

adding issue summary - http://drupal.org/issue-summaries

ndewhurst’s picture

Updated issue summary to include hook_entity_access explanation.

ndewhurst’s picture

Issue summary: View changes

ndewhurst

xmacinfo’s picture

Renaming 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.

xmacinfo’s picture

The Translation entity module might give us the correct example on how use the hook_entity_access:

function translation_entity_access(EntityInterface $entity, $op) {
  return translation_entity_controller($entity->entityType())->getTranslationAccess($entity, $op) ;
}

and

the following translation_entity_permission() function.

Although I cannot find where is defined the hook_entity_access.

alexpott’s picture

Status: Reviewed & tested by the community » Closed (duplicate)