Problem/Motivation
When a Views exposed role filter is applied on the user listing page
(e.g. admin/people), the administerusersbyrole
access control query tag stops filtering users correctly. Users that the
current account should not be able to see may appear in the results, or
the listing may return no results at all.
The root cause is in administerusersbyrole_query_alter(). The
LEFT JOIN that performs the access anti-join uses users_roles
as the table reference in its ON clause:
$query->leftjoin(
'users_roles',
'administerusersbyrole',
'users_roles.uid=users.uid AND users_roles.rid IN (:exclude)',
array(':exclude' => $exclude)
);
When Views applies a role filter it adds its own
INNER JOIN users_roles ON ... using users_roles
as the alias. The ON clause of the subsequent LEFT JOIN then resolves
users_roles to that already-existing alias rather than to
the new administerusersbyrole alias being declared. As a
result the anti-join operates only on the role-filtered subset of
users_roles rows instead of the full role assignment table,
and the access restriction no longer works correctly.
Steps to reproduce
- Install and enable
administerusersbyrole,
admin_views, andviews. - Create two roles, e.g. Editor and Manager.
- Create a user account with only the Manager role and grant
it theaccess users overviewpermission and edit
permission for the Editor role only (not
Manager). - Create several users: some with Editor, some with
Manager, some with both. - Log in as the Manager account and navigate to
admin/people. - Apply the Role exposed filter and select
Editor. - Observe that users with the Manager role (which the
current account has no edit permission for) appear in the filtered
results.
Proposed resolution
Change the ON clause of the LEFT JOIN in
administerusersbyrole_query_alter() to reference the JOIN's
own alias (administerusersbyrole) instead of the table name
(users_roles), consistent with how the
users_roles_2 join immediately above it is already written.
Before:
$query->leftjoin(
'users_roles',
'administerusersbyrole',
'users_roles.uid=users.uid AND users_roles.rid IN (:exclude)',
array(':exclude' => $exclude)
);
After:
$query->leftjoin(
'users_roles',
'administerusersbyrole',
'administerusersbyrole.uid=users.uid AND administerusersbyrole.rid IN (:exclude)',
array(':exclude' => $exclude)
);
Remaining tasks
- Review and confirm the fix.
- Write a regression test covering the role filter + access
restriction combination. - Commit and tag a new release.
User interface changes
None.
API changes
None.
Data model changes
None.
Comments
Comment #2
kaustubhb commentedThis patch fixes the issue
Comment #3
kaustubhb commentedThis Patch has security fix
Comment #4
kaustubhb commentedAdding a patch which is compatible with patch for below issue
https://www.drupal.org/project/administerusersbyrole/issues/3311129
Comment #5
kaustubhb commentedComment #6
kaustubhb commented