I noticed the following in \Drupal\Core\Access\AccessResult
:
/**
* Creates an allowed access result if the permission is present, neutral otherwise.
*
* Checks the permission and adds a 'user.permissions' cache context.
*
* @param \Drupal\Core\Session\AccountInterface $account
* The account for which to check a permission.
* @param string $permission
* The permission to check for.
*
* @return \Drupal\Core\Access\AccessResult
* If the account has the permission, isAllowed() will be TRUE, otherwise
* isNeutral() will be TRUE.
*/
public static function allowedIfHasPermission(AccountInterface $account, $permission) {
return static::allowedIf($account->hasPermission($permission))->addCacheContexts(['user.permissions']);
}
This varies the cached result by the permissions hash the currently logged in user has, not the permissions hash the user which was passed in through the $account parameter has. Same goes for \Drupal\Core\Access\AccessResult::allowedIfHasPermissions()
It's an edge case because 99% of the time it will probably be the current user the function is dealing with. But in case someone wants to verify if another user can access something, this will cache the result for the permissions of the current user instead.
Proposed solutions:
- Remove the cache context.
- Only add the context if the current user is the passed in account
- ???