If non-admin users can see some user accounts but not others...

Submitted by Frederic Marand on

After a massive user import to a customer's site, said customer noticed that, while he could see any user profile when logged, he could only see some of them when he was not logged in, receiving an "access denied" on the other accounts.

Now, with the administer users permission, a user can see any profile, so this didn't come into consideration, but since anonymous users could see some profiles and not others, the permissions granting anonymous access to the profiles were obviously set up correctly. So what could be wrong ?

Now, to understand what's going on in such a case, a small trip to user.module is necessary. In Drupal 4.7.x and 5.x, access to user/% is controlled directly in user_menu, and the rule for such an access is as follows:

<?php
$view_access
= user_access('access user profiles');
[..
snip..]
if (
$user !== FALSE) {
 
$view_access |= $user->uid == arg(1);
 
$view_access &= $account->status || $admin_access;
?>

...meaning any user can see his own account or any non-blocked account, assuming he has access user profiles permission, meaning this problem cannot happen. However in Drupal 6 and Drupal 7, things are a bit different, this access is now controlled by the user_view_access($account) function:

<?php
// From DRUPAL-6--10 (1.892.2.12) and DRUPAL-7-0-UNSTABLE-5 (1.963)
function user_view_access($account) {
  return
$account && $account->uid &&
    (
     
// Always let users view their own profile.
     
($GLOBALS['user']->uid == $account->uid) ||
     
// Administrators can view all accounts.
     
user_access('administer users') ||
     
// The user is not blocked and logged in at least once.
     
($account->access && $account->status && user_access('access user profiles'))
    );
}
?>

And the rules have slightly changed in the meantime: any user can now see his own account, or any non-blocked account which has logged in at least once, due to the test on $account->access.

So here is the key : after a mass import, most accounts will likely just have been created, and the just imported accounts won't have "access" set to a non zero value, meaning they won't be visible to any user without administer users permission. Solution: either be satisfied with it or set access to any non-zero value during the import.

Thank you very much for your explanation! After an import, where thousands of users were created using Drupal API, some profile could not be accessed...