There are many instances where you have to check multiple permissions...
if (user_access('change own username') || user_access('administer users')) {
// ...
}
It would be neat if you could pass multiple permissions through to the user_access function:
if (user_access(array('change own username', 'administer users'))) {
// ...
}
This would also help with the menu system, because right now you can't check multiple permissions without implementing your own user access function:
$items['admin/settings/mysettings'] = array(
'title' => 'My settings',
'description' => 'Provides some custom settings.',
'page callback' => 'drupal_get_form',
'page arguments' => array('stringoverrides_admin'),
'access arguments' => array(array('administer site configuration', 'configure mysettings')),
'type' => MENU_NORMAL_ITEM,
);
Any thoughts?
| Comment | File | Size | Author |
|---|---|---|---|
| #15 | 216897-array_user_permission-15.patch | 2.42 KB | pcambra |
| #10 | 216897-user-access.patch | 1.68 KB | klausi |
| #8 | 216897-array_user_permission-8.patch | 2.24 KB | pcambra |
| #6 | 216897-array_user_permission-6.patch | 2.25 KB | pcambra |
| user_access_array.patch | 1.51 KB | robloach |
Comments
Comment #1
moshe weitzman commentedActually what would be more flexible would be for the 'access callback' to accept an array of callbacks. All callbacks would have to return TRUE for access to be granted. This would probably turn the access arguments item into an array of arrays. Or we combine access callback and access arguments into one associative array.
Anyway, the idea proposed here is useful too.
Comment #2
abhigupta commentedI think this patch would be very handy. Plus it doesn't break compatibility with any previous code.
Comment #3
catchMoving to Drupal 8.
Comment #4
t-dub commented+1. I have a utility function that I often use as a menu access callback that does exactly this. Having it as the default
user_access()behavior would be great.Comment #5
enboig commentedI disagree with #1; a menu entry would not always need "all" permissions callbacks, maybe sometimes "any" is enough.
An option would be adding a new parameter to function:
function user_access($permission, $account = NULL, $reset = FALSE, $all = TRUE) {...}
Comment #6
pcambraPatch ported to D8
Comment #7
klausiwhy do you call user_access() recursively? The access information should be in $perm already, no?
And we need to clearly document the policy on multiple permissions given: is one of them enough (OR) or must all permissions be satisfied (AND)?
8 days to next Drupal core point release.
Comment #8
pcambraYou're totally right, I could have used the $perm array, I've modified a little the patch to avoid the recursive call.
I think that AND makes more sense from a code perspective but if you search in the core code, OR would be more used (user_access() || user_access()).
Comment #9
klausiyou introduce a new parameter that is never used in the function?
so this is the AND use case I guess? why do you continue to check permissions if a particular permission isn't satisfied then?
Still no documentation that says that all permissions have to be met (AND).
Comment #10
klausiI would do it like this, patch attached.
I have removed the change in menu.inc, as I think people may want to pass in the $account object there.
I'm not sure if the current AND solution is the best, what is typically use more often? Is OR more common?
Comment #11
pcambraYeah, my idea was to find a solution that we could quickly switch from AND to OR (or even pass a parameter to change it).
AND makes more sense b/c we can exit quicker if one of the permissions is false, but I don't think it is very commonly used in core, I've found a couple of use cases for OR, though.
We could change the $permissions array for something like this:
We'd also need to create a test case.
Comment #12
pcambraWithout the modification of menu.inc for the access arguments, the call to user_access is done with $argument[0] and $argument[1], which both are permissions and not the account as expected.
Example of hook_menu.
I get a bunch of these errors:
Comment #13
klausiYou have to wrap the permissions in an additional array:
The access arguments are taken form the outer array and are passed one by one to the access callback function (user_access() in the default case). ==> we need an additional array to wrap multiple permissions.
Comment #14
pcambraWouldn't it make sense then to have the structure above to define the access arguments? I feel like defining array(array('Permission 1', 'Permission 2')) is not straight away since we need to use 0 and 1 keys for permissions & accounts.
Modifying menu.inc to get $argument['permission'], etc(instead of 0 and 1) and defining hook_menu like this:
Then we could implement the OR way for defining permissions also.
Comment #15
pcambraHere's the patch modified to get sensitive keys
Comment #16
joachim commentedThis appears to change the way 'access arguments' works, but doesn't change its documentation.
26 days to next Drupal core point release.
Comment #19
dpiIt is no longer such an issue since we do not use a
user_accessin routing anymore. The_permissionrequirement also accepts AND,OR conjunctions with+and,. See\Drupal\user\Access\PermissionAccessCheck::accessThe issue of allowing multiple operations is mitigated by:
And lastly, changing the user_access equivalent,
$entity->access, to accept an array of operations would be an API change.Changed title to Drupal 8 terminology