There are actually two interleaved issues here.
The current node_access_grants() code still assumes procedural style, taking $account = NULL as an argument. If NULL, the $account is assumed to be the (deprecated) global user.
Methods that call node_access_grants() pass an AccountInterface $account, which, it seems, is an instance of Drupal\Core\Session\UserSession, which is not a fully-loaded $account entity, which is what an API consumer would expect, since hook_node_grants() has always passed a user entity. We need to ensure that behavior is consistent.
So things that need deciding / fixing:
- Should the caller always pass an $account?
- What format should that $account be in?
- When should $account be transformed into a user entity?
Comments
Comment #1
agentrickardAnd a patch to get things started.
Comment #3
dawehnerI doubt that we should ever load the user. The code uses the AccountInterface and not the UserInterface, so if anything relies on the user, it should load the user for themself.
Comment #4
agentrickardNo. That's a bad assumption. Access checks like this may depend on account information that is only accessible via a UserInterface object.
Why this ever loaded an AccountInterface is the real question.
The API expects to pass a $user object. Always has. $account has been a stand-in to remind people not to assume the global $user object when making an access check.
At the very least, node_access_grants should supply a proper $user object to the hook implementation.
Comment #5
agentrickardOh, and the facepalm of the year. Look at the parent access method, which calls EntityAccessController::prepareUser().
That method proves that we are meant to have a full user object. It's just being loaded improperly from the deprecated GLOBAL $user.
Comment #6
tkuldeep17 commentedHi agentrickard
I am agree with you, that we have to pass AccountInterface object to node_access_grants,
But Access check mechanism requires only uid, which is provided by AccountInterface object.
So we don't need to explicitly load user through entity_load method.
And also we should use
\Drupal::moduleHandler()->alter('node_grants', $grants, $account, $op);instead ofdrupal_alter('node_grants', $grants, $account, $op);Comment #7
tkuldeep17 commentedSubmitting my patch..
Comment #8
tkuldeep17 commentedchanges status...
Comment #9
agentrickardWould then be:
There are places in node.api.php that need updating as well.
Comment #10
martin107 commentedComment text changed as suggested in the previous comment.
NB this patch needed a reroll because another patch has corrected the following code.
- if (!isset($account)) {
- $account = $GLOBALS['user'];
- }
This issue is still relevant because of the 'alter' line of code and the other patch was not careful enough to update the function parameters of the funciton, or update the comments.
finally ( minor house keeping ) I have removed unused use statement from top of the code.
Comment #11
martin107 commentedComment #12
dawehnerPlease move the whitespace from 1636 to the beginning of 1638 :p
Comment #13
tim.plunkettRerolled.
Comment #15
tim.plunkettHah! node_test_node_grants() does not use either parameter, which let NodeAccessRecordsTest call it directly with the params in the wrong order. Now that we're typehinting, it broke.
Comment #16
agentrickardLooks good, tests green.
Comment #18
webchickWow, nice catches!
Side note: It's funny that everywhere else we use $account, $op except here. Can see why the tests got confused.
Committed and pushed to 8.x. Thanks!