Skip to content

$user->editable returns false even if the current user has the user-admin permission #1322

@schwarzdesign

Description

@schwarzdesign

Short description of the issue

Using $user->editable is unreliable because it returns different results based on the current Process. This results in incorrect behaviour when used in a custom context or Process module. In particular, unless the current user is a superuser, $user->editable evaluates to false even if the current user has the user-admin permission and can, in fact, edit the user in question using ProcessUser.

Expected behavior

$user->editable should always return the correct result (i.e. if the current user can edit the user in question, based on whether they have the required permission), independent of the current Process or context.

Actual behavior

The method responsible for returning the result for editable checks the current Process module and just returns false if it isn't one of the 'whitelisted' ones. See PagePermissions.module#L276-L280

Screenshots/Links that demonstrate the issue

This came up in the context of the Dashboard module, which allows you to display a collection of pages, including edit / view links. The module uses $page->editable to check if the current user can edit the pages in the collection. When using this to display a list of users, the module incorrectly disables the edit link since $page->editable returns false, even if the current user has the user-admin permission (unless they are also a superuser).

Suggestion for a possible fix

The best solution would be to make $user->editable context-independent. Whether a user account is editable should be based on the permission system, not on context / current process. The current implementation will always yield unexpected results, since it can return different results when used in different places, which violates SOLID principles.

If it is unfeasible / too much work to drop the context-dependence, it would be great if ProcessWire could provide an alternative to $user->editable that returns the correct result independent of context. This would allow third-party modules to check for this special case without replicating core logic.

Steps to reproduce the issue

  • Log in as a non-superuser that has the user-admin permission on a site without the user-admin-all or any user-admin-[role] permissions.
  • In a context that is not one of the 'whitelisted' Processes listed above, retrieve any non-superuser account using the API and check $user->editable. It will return false, even through it should be true.

Setup/Environment

  • ProcessWire: 3.0.169
  • PHP: 7.4.14

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions