From 4da4f4c1afe9542502f370875562d44cce01ed00 Mon Sep 17 00:00:00 2001
From: Dries Buytaert <dries@buytaert.net>
Date: Sat, 21 Jan 2006 08:28:55 +0000
Subject: [PATCH] - Patch #44379 by Moshe: code improvements: always grant the
 'authenticated user' role to authenticated users.  Fixed glitch with udpate
 path.

---
 database/database.mysql  |  3 ---
 database/updates.inc     |  8 +++++-
 includes/bootstrap.inc   |  4 +++
 includes/session.inc     |  7 +++++-
 modules/user.module      | 53 ++++++++++++++++------------------------
 modules/user/user.module | 53 ++++++++++++++++------------------------
 6 files changed, 59 insertions(+), 69 deletions(-)

diff --git a/database/database.mysql b/database/database.mysql
index cb6917c3b606..87c97c837600 100644
--- a/database/database.mysql
+++ b/database/database.mysql
@@ -884,9 +884,6 @@ INSERT INTO users (uid, name, mail) VALUES ('0', '', '');
 INSERT INTO role (rid, name) VALUES (1, 'anonymous user');
 INSERT INTO role (rid, name) VALUES (2, 'authenticated user');
 
-INSERT INTO users_roles (uid, rid) VALUES (0, 1);
-INSERT INTO users_roles (uid, rid) VALUES (1, 2);
-
 INSERT INTO permission VALUES (1,'access content',0);
 INSERT INTO permission VALUES (2,'access comments, access content, post comments, post comments without approval',0);
 
diff --git a/database/updates.inc b/database/updates.inc
index c82f445f5756..a45a457705b3 100644
--- a/database/updates.inc
+++ b/database/updates.inc
@@ -1470,7 +1470,7 @@ function system_update_169() {
 
 /**
  * Converts tables to UTF-8 encoding.
- * 
+ *
  * This update is designed to be re-usable by contrib modules and is
  * used by system_update_169().
  */
@@ -1579,3 +1579,9 @@ function system_update_170() {
   }
   return array();
 }
+
+function system_update_171() {
+  $ret = array();
+  $ret[] = update_sql('DELETE FROM {users_roles} WHERE rid IN ('. DRUPAL_ANONYMOUS_RID. ', '. DRUPAL_AUTHENTICATED_RID. ')');
+  return $ret;
+}
diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc
index 79f69fadd8fb..111e4507c7ae 100644
--- a/includes/bootstrap.inc
+++ b/includes/bootstrap.inc
@@ -21,6 +21,10 @@
 define('DRUPAL_BOOTSTRAP_PAGE_CACHE', 2);
 define('DRUPAL_BOOTSTRAP_FULL', 3);
 
+// these values should match the'role' table
+define('DRUPAL_ANONYMOUS_RID', 1);
+define('DRUPAL_AUTHENTICATED_RID', 2);
+
 /**
  * Start the timer with the specified name.  If you start and stop
  * the same timer multiple times, the measured intervals will be
diff --git a/includes/session.inc b/includes/session.inc
index a28a9a57140a..a838bdc94864 100644
--- a/includes/session.inc
+++ b/includes/session.inc
@@ -30,8 +30,13 @@ function sess_read($key) {
   $user = drupal_unpack($user);
   $user->roles = array();
 
+  if ($user->uid) {
+    $user->roles[DRUPAL_AUTHENTICATED_RID] = 'authenticated user';
+  }
+  else {
+    $user->roles[DRUPAL_ANONYMOUS_RID] = 'anonymous user';
+  }
   $result = db_query("SELECT r.rid, r.name FROM {role} r INNER JOIN {users_roles} ur ON ur.rid = r.rid WHERE ur.uid = %d", $user->uid);
-
   while ($role = db_fetch_object($result)) {
     $user->roles[$role->rid] = $role->name;
   }
diff --git a/modules/user.module b/modules/user.module
index d23deda981b9..c14320529a31 100644
--- a/modules/user.module
+++ b/modules/user.module
@@ -67,7 +67,7 @@ function user_load($array = array()) {
     $user = db_fetch_object($result);
     $user = drupal_unpack($user);
 
-    $user->roles = array();
+    $user->roles[DRUPAL_AUTHENTICATED_RID] = 'authenticated user';
     $result = db_query('SELECT r.rid, r.name FROM {role} r INNER JOIN {users_roles} ur ON ur.rid = r.rid WHERE ur.uid = %d', $user->uid);
     while ($role = db_fetch_object($result)) {
       $user->roles[$role->rid] = $role->name;
@@ -133,7 +133,9 @@ function user_save($account, $array = array(), $category = 'account') {
       db_query('DELETE FROM {users_roles} WHERE uid = %d', $account->uid);
 
       foreach (array_keys($array['roles']) as $rid) {
-        db_query('INSERT INTO {users_roles} (uid, rid) VALUES (%d, %d)', $account->uid, $rid);
+        if (!in_array($rid, array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID))) {
+          db_query('INSERT INTO {users_roles} (uid, rid) VALUES (%d, %d)', $account->uid, $rid);
+        }
       }
     }
 
@@ -170,7 +172,7 @@ function user_save($account, $array = array(), $category = 'account') {
 
     // Reload user roles (delete just to be safe).
     db_query('DELETE FROM {users_roles} WHERE uid = %d', $array['uid']);
-    foreach ($array['roles'] as $rid) {
+    foreach ((array)$array['roles'] as $rid) {
       db_query('INSERT INTO {users_roles} (uid, rid) VALUES (%d, %d)', $array['uid'], $rid);
     }
 
@@ -335,8 +337,8 @@ function user_access($string, $account = NULL) {
 
   // To reduce the number of SQL queries, we cache the user's permissions
   // in a static variable.
-  if (!isset($perm[$account->uid])) {
-    $result = db_query('SELECT DISTINCT(p.perm) FROM {role} r INNER JOIN {permission} p ON p.rid = r.rid INNER JOIN {users_roles} ur ON ur.rid = r.rid WHERE ur.uid = %d', $account->uid);
+  if (!isset($perm[$account->uid]) && count($user->roles)) {
+    $result = db_query("SELECT DISTINCT(p.perm) FROM {role} r INNER JOIN {permission} p ON p.rid = r.rid WHERE r.rid IN (%s)", implode(',', array_keys($account->roles)));
 
     $perm[$account->uid] = '';
     while ($row = db_fetch_object($result)) {
@@ -928,7 +930,7 @@ function user_authenticate($name, $pass) {
           if (variable_get('user_register', 1) == 1) {
             $account = user_load(array('name' => "$name@$server"));
             if (!$account->uid) { // Register this new user.
-              $user = user_save('', array('name' => "$name@$server", 'pass' => user_password(), 'init' => "$name@$server", 'status' => 1, "authname_$module" => "$name@$server", 'roles' => array(_user_authenticated_id())));
+              $user = user_save('', array('name' => "$name@$server", 'pass' => user_password(), 'init' => "$name@$server", 'status' => 1, "authname_$module" => "$name@$server"));
               watchdog('user', t('New external user: %user using module %module.', array('%user' => theme('placeholder', $name .'@'. $server), '%module' => theme('placeholder', $module))), WATCHDOG_NOTICE, l(t('edit'), 'user/'. $user->uid .'/edit'));
               break;
             }
@@ -940,10 +942,6 @@ function user_authenticate($name, $pass) {
   return $user;
 }
 
-function _user_authenticated_id() {
-  return db_result(db_query("SELECT rid FROM {role} WHERE name = 'authenticated user'"));
-}
-
 /**
  * Menu callback; logs the current user out, and redirects to the home page.
  */
@@ -1122,7 +1120,7 @@ function user_register_submit($form_id, $form_values) {
     drupal_goto('user/register');
   }
 
-  $account = user_save('', array_merge($form_values, array('pass' => $pass, 'init' => $mail, 'roles' => array('authenticated user' => _user_authenticated_id()), 'status' => ($admin || variable_get('user_register', 1) == 1))));
+  $account = user_save('', array_merge($form_values, array('pass' => $pass, 'init' => $mail, 'status' => ($admin || variable_get('user_register', 1) == 1))));
   watchdog('user', t('New user: %name %email.', array('%name' => theme('placeholder', $name), '%email' => theme('placeholder', '<'. $mail .'>'))), WATCHDOG_NOTICE, l(t('edit'), 'user/'. $account->uid .'/edit'));
 
   $variables = array('%username' => $name, '%site' => variable_get('site_name', 'drupal'), '%password' => $pass, '%uri' => $base_url, '%uri_brief' => substr($base_url, strlen('http://')), '%mailto' => $mail, '%date' => format_date(time()), '%login_uri' => url('user', NULL, NULL, TRUE), '%edit_uri' => url('user/'. $account->uid .'/edit', NULL, NULL, TRUE), '%login_url' => user_pass_reset_url($account));
@@ -1180,7 +1178,11 @@ function user_edit_form($uid, $edit) {
     $form['account']['status'] = array('#type' => 'radios', '#title' => t('Status'), '#default_value' => $edit['status'], '#options' => array(t('Blocked'), t('Active')));
   }
   if (user_access('administer access control')) {
-    $form['account']['roles'] = array('#type' => 'checkboxes', '#title' => t('Roles'), '#default_value' => array_keys((array)$edit['roles']), '#options' => user_roles(1), '#description' => t('Select at least one role.  The user receives the combined permissions of all of the selected roles.'), '#required' => TRUE);
+    $roles = user_roles(1);
+    unset($roles[DRUPAL_AUTHENTICATED_RID]);
+    if ($roles) {
+      $form['account']['roles'] = array('#type' => 'checkboxes', '#title' => t('Roles'), '#default_value' => array_keys((array)$edit['roles']), '#options' => $roles, '#description' => t('The user receives the combined permissions of the %au role, and all roles selected here.', array('%au' => theme('placeholder', t('authenticated user')))), '#required' => TRUE);
+    }
   }
 
   // Picture/avatar:
@@ -1222,13 +1224,6 @@ function _user_edit_validate($uid, &$edit) {
     form_set_error('mail', t('The e-mail address %email has been denied access.', array('%email' => theme('placeholder', $edit['mail']))));
   }
 
-  // Validate the user roles:
-  if (user_access('administer access control') && $_GET['q'] != 'admin/user/create') {
-    if (!$edit['roles']) {
-      form_set_error('roles', t('You must select at least one role.'));
-    }
-  }
-
   // If required, validate the uploaded picture.
   if ($file = file_check_upload('picture')) {
     user_validate_picture($file, $edit, $user);
@@ -1557,7 +1552,7 @@ function user_roles($membersonly = 0, $permission = 0) {
     $result = db_query('SELECT * FROM {role} ORDER BY name');
   }
   while ($role = db_fetch_object($result)) {
-    if (!$membersonly || ($membersonly && $role->name != 'anonymous user')) {
+    if (!$membersonly || ($membersonly && $role->rid != DRUPAL_ANONYMOUS_RID)) {
       $roles[$role->rid] = $role->name;
     }
   }
@@ -1642,7 +1637,7 @@ function theme_user_admin_perm($form) {
         $row[] = array('data' => form_render($form['permission'][$key]), 'class' => 'permission');
         foreach (element_children($form['checkboxes']) as $rid) {
           if (is_array($form['checkboxes'][$rid])) {
-            $row[] = array('data' => form_render($form['checkboxes'][$rid][$key]), 'align' => 'center');
+            $row[] = array('data' => form_render($form['checkboxes'][$rid][$key]), 'align' => 'center', 'title' => $key);
           }
         }
       }
@@ -1721,9 +1716,6 @@ function user_admin_role() {
       db_query('DELETE FROM {users_roles} WHERE rid = %d AND uid IN (%s)', $id, implode(', ', $uid));
     }
 
-    // Users with only the deleted role are put back in the authenticated users pool.
-    db_query('UPDATE {users_roles} SET rid = %d WHERE rid = %d', _user_authenticated_id(), $id);
-
     drupal_set_message(t('The role has been deleted.'));
     drupal_goto('admin/access/roles');
   }
@@ -1751,16 +1743,13 @@ function user_admin_role() {
 }
 
 function theme_user_admin_new_role($form) {
-  // Render the role overview.
-  $result = db_query('SELECT * FROM {role} ORDER BY name');
-
   $header = array(t('Name'), t('Operations'));
-  while ($role = db_fetch_object($result)) {
-    if ($role->name != 'anonymous user' && $role->name != 'authenticated user') {
-      $rows[] = array($role->name, l(t('edit'), 'admin/access/roles/edit/'. $role->rid));
+  foreach (user_roles() as $rid => $name) {
+    if (!in_array($rid, array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID))) {
+      $rows[] = array($name, l(t('edit'), 'admin/access/roles/edit/'. $rid));
     }
     else {
-      $rows[] = array($role->name, '<span class="disabled">'. t('locked') .'</span>');
+      $rows[] = array($name, '<span class="disabled">'. t('locked') .'</span>');
     }
   }
   $rows[] = array(form_render($form['name']), form_render($form['submit']));
@@ -1885,7 +1874,7 @@ function user_help($section) {
       return t('<p>Roles allow you to fine tune the security and administration of Drupal. A role defines a group of users that have certain privileges as defined in <a href="%permissions">user permissions</a>. Examples of roles include: anonymous user, authenticated user, moderator, administrator and so on. In this area you will define the <em>role names</em> of the various roles. To delete a role choose "edit".</p><p>By default, Drupal comes with two user roles:</p>
       <ul>
       <li>Anonymous user: this role is used for users that don\'t have a user account or that are not authenticated.</li>
-      <li>Authenticated user: this role is assigned automatically to authenticated users. Most registered users will belong to this user role unless specified otherwise.</li>
+      <li>Authenticated user: this role is automatically granted to all logged in users.</li>
       </ul>', array('%permissions' => url('admin/access/permissions')));
     case 'admin/user/search':
       return t('<p>Enter a simple pattern ("*" may be used as a wildcard match) to search for a username.  For example, one may search for "br" and Drupal might return "brian", "brad", and "brenda".</p>');
diff --git a/modules/user/user.module b/modules/user/user.module
index d23deda981b9..c14320529a31 100644
--- a/modules/user/user.module
+++ b/modules/user/user.module
@@ -67,7 +67,7 @@ function user_load($array = array()) {
     $user = db_fetch_object($result);
     $user = drupal_unpack($user);
 
-    $user->roles = array();
+    $user->roles[DRUPAL_AUTHENTICATED_RID] = 'authenticated user';
     $result = db_query('SELECT r.rid, r.name FROM {role} r INNER JOIN {users_roles} ur ON ur.rid = r.rid WHERE ur.uid = %d', $user->uid);
     while ($role = db_fetch_object($result)) {
       $user->roles[$role->rid] = $role->name;
@@ -133,7 +133,9 @@ function user_save($account, $array = array(), $category = 'account') {
       db_query('DELETE FROM {users_roles} WHERE uid = %d', $account->uid);
 
       foreach (array_keys($array['roles']) as $rid) {
-        db_query('INSERT INTO {users_roles} (uid, rid) VALUES (%d, %d)', $account->uid, $rid);
+        if (!in_array($rid, array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID))) {
+          db_query('INSERT INTO {users_roles} (uid, rid) VALUES (%d, %d)', $account->uid, $rid);
+        }
       }
     }
 
@@ -170,7 +172,7 @@ function user_save($account, $array = array(), $category = 'account') {
 
     // Reload user roles (delete just to be safe).
     db_query('DELETE FROM {users_roles} WHERE uid = %d', $array['uid']);
-    foreach ($array['roles'] as $rid) {
+    foreach ((array)$array['roles'] as $rid) {
       db_query('INSERT INTO {users_roles} (uid, rid) VALUES (%d, %d)', $array['uid'], $rid);
     }
 
@@ -335,8 +337,8 @@ function user_access($string, $account = NULL) {
 
   // To reduce the number of SQL queries, we cache the user's permissions
   // in a static variable.
-  if (!isset($perm[$account->uid])) {
-    $result = db_query('SELECT DISTINCT(p.perm) FROM {role} r INNER JOIN {permission} p ON p.rid = r.rid INNER JOIN {users_roles} ur ON ur.rid = r.rid WHERE ur.uid = %d', $account->uid);
+  if (!isset($perm[$account->uid]) && count($user->roles)) {
+    $result = db_query("SELECT DISTINCT(p.perm) FROM {role} r INNER JOIN {permission} p ON p.rid = r.rid WHERE r.rid IN (%s)", implode(',', array_keys($account->roles)));
 
     $perm[$account->uid] = '';
     while ($row = db_fetch_object($result)) {
@@ -928,7 +930,7 @@ function user_authenticate($name, $pass) {
           if (variable_get('user_register', 1) == 1) {
             $account = user_load(array('name' => "$name@$server"));
             if (!$account->uid) { // Register this new user.
-              $user = user_save('', array('name' => "$name@$server", 'pass' => user_password(), 'init' => "$name@$server", 'status' => 1, "authname_$module" => "$name@$server", 'roles' => array(_user_authenticated_id())));
+              $user = user_save('', array('name' => "$name@$server", 'pass' => user_password(), 'init' => "$name@$server", 'status' => 1, "authname_$module" => "$name@$server"));
               watchdog('user', t('New external user: %user using module %module.', array('%user' => theme('placeholder', $name .'@'. $server), '%module' => theme('placeholder', $module))), WATCHDOG_NOTICE, l(t('edit'), 'user/'. $user->uid .'/edit'));
               break;
             }
@@ -940,10 +942,6 @@ function user_authenticate($name, $pass) {
   return $user;
 }
 
-function _user_authenticated_id() {
-  return db_result(db_query("SELECT rid FROM {role} WHERE name = 'authenticated user'"));
-}
-
 /**
  * Menu callback; logs the current user out, and redirects to the home page.
  */
@@ -1122,7 +1120,7 @@ function user_register_submit($form_id, $form_values) {
     drupal_goto('user/register');
   }
 
-  $account = user_save('', array_merge($form_values, array('pass' => $pass, 'init' => $mail, 'roles' => array('authenticated user' => _user_authenticated_id()), 'status' => ($admin || variable_get('user_register', 1) == 1))));
+  $account = user_save('', array_merge($form_values, array('pass' => $pass, 'init' => $mail, 'status' => ($admin || variable_get('user_register', 1) == 1))));
   watchdog('user', t('New user: %name %email.', array('%name' => theme('placeholder', $name), '%email' => theme('placeholder', '<'. $mail .'>'))), WATCHDOG_NOTICE, l(t('edit'), 'user/'. $account->uid .'/edit'));
 
   $variables = array('%username' => $name, '%site' => variable_get('site_name', 'drupal'), '%password' => $pass, '%uri' => $base_url, '%uri_brief' => substr($base_url, strlen('http://')), '%mailto' => $mail, '%date' => format_date(time()), '%login_uri' => url('user', NULL, NULL, TRUE), '%edit_uri' => url('user/'. $account->uid .'/edit', NULL, NULL, TRUE), '%login_url' => user_pass_reset_url($account));
@@ -1180,7 +1178,11 @@ function user_edit_form($uid, $edit) {
     $form['account']['status'] = array('#type' => 'radios', '#title' => t('Status'), '#default_value' => $edit['status'], '#options' => array(t('Blocked'), t('Active')));
   }
   if (user_access('administer access control')) {
-    $form['account']['roles'] = array('#type' => 'checkboxes', '#title' => t('Roles'), '#default_value' => array_keys((array)$edit['roles']), '#options' => user_roles(1), '#description' => t('Select at least one role.  The user receives the combined permissions of all of the selected roles.'), '#required' => TRUE);
+    $roles = user_roles(1);
+    unset($roles[DRUPAL_AUTHENTICATED_RID]);
+    if ($roles) {
+      $form['account']['roles'] = array('#type' => 'checkboxes', '#title' => t('Roles'), '#default_value' => array_keys((array)$edit['roles']), '#options' => $roles, '#description' => t('The user receives the combined permissions of the %au role, and all roles selected here.', array('%au' => theme('placeholder', t('authenticated user')))), '#required' => TRUE);
+    }
   }
 
   // Picture/avatar:
@@ -1222,13 +1224,6 @@ function _user_edit_validate($uid, &$edit) {
     form_set_error('mail', t('The e-mail address %email has been denied access.', array('%email' => theme('placeholder', $edit['mail']))));
   }
 
-  // Validate the user roles:
-  if (user_access('administer access control') && $_GET['q'] != 'admin/user/create') {
-    if (!$edit['roles']) {
-      form_set_error('roles', t('You must select at least one role.'));
-    }
-  }
-
   // If required, validate the uploaded picture.
   if ($file = file_check_upload('picture')) {
     user_validate_picture($file, $edit, $user);
@@ -1557,7 +1552,7 @@ function user_roles($membersonly = 0, $permission = 0) {
     $result = db_query('SELECT * FROM {role} ORDER BY name');
   }
   while ($role = db_fetch_object($result)) {
-    if (!$membersonly || ($membersonly && $role->name != 'anonymous user')) {
+    if (!$membersonly || ($membersonly && $role->rid != DRUPAL_ANONYMOUS_RID)) {
       $roles[$role->rid] = $role->name;
     }
   }
@@ -1642,7 +1637,7 @@ function theme_user_admin_perm($form) {
         $row[] = array('data' => form_render($form['permission'][$key]), 'class' => 'permission');
         foreach (element_children($form['checkboxes']) as $rid) {
           if (is_array($form['checkboxes'][$rid])) {
-            $row[] = array('data' => form_render($form['checkboxes'][$rid][$key]), 'align' => 'center');
+            $row[] = array('data' => form_render($form['checkboxes'][$rid][$key]), 'align' => 'center', 'title' => $key);
           }
         }
       }
@@ -1721,9 +1716,6 @@ function user_admin_role() {
       db_query('DELETE FROM {users_roles} WHERE rid = %d AND uid IN (%s)', $id, implode(', ', $uid));
     }
 
-    // Users with only the deleted role are put back in the authenticated users pool.
-    db_query('UPDATE {users_roles} SET rid = %d WHERE rid = %d', _user_authenticated_id(), $id);
-
     drupal_set_message(t('The role has been deleted.'));
     drupal_goto('admin/access/roles');
   }
@@ -1751,16 +1743,13 @@ function user_admin_role() {
 }
 
 function theme_user_admin_new_role($form) {
-  // Render the role overview.
-  $result = db_query('SELECT * FROM {role} ORDER BY name');
-
   $header = array(t('Name'), t('Operations'));
-  while ($role = db_fetch_object($result)) {
-    if ($role->name != 'anonymous user' && $role->name != 'authenticated user') {
-      $rows[] = array($role->name, l(t('edit'), 'admin/access/roles/edit/'. $role->rid));
+  foreach (user_roles() as $rid => $name) {
+    if (!in_array($rid, array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID))) {
+      $rows[] = array($name, l(t('edit'), 'admin/access/roles/edit/'. $rid));
     }
     else {
-      $rows[] = array($role->name, '<span class="disabled">'. t('locked') .'</span>');
+      $rows[] = array($name, '<span class="disabled">'. t('locked') .'</span>');
     }
   }
   $rows[] = array(form_render($form['name']), form_render($form['submit']));
@@ -1885,7 +1874,7 @@ function user_help($section) {
       return t('<p>Roles allow you to fine tune the security and administration of Drupal. A role defines a group of users that have certain privileges as defined in <a href="%permissions">user permissions</a>. Examples of roles include: anonymous user, authenticated user, moderator, administrator and so on. In this area you will define the <em>role names</em> of the various roles. To delete a role choose "edit".</p><p>By default, Drupal comes with two user roles:</p>
       <ul>
       <li>Anonymous user: this role is used for users that don\'t have a user account or that are not authenticated.</li>
-      <li>Authenticated user: this role is assigned automatically to authenticated users. Most registered users will belong to this user role unless specified otherwise.</li>
+      <li>Authenticated user: this role is automatically granted to all logged in users.</li>
       </ul>', array('%permissions' => url('admin/access/permissions')));
     case 'admin/user/search':
       return t('<p>Enter a simple pattern ("*" may be used as a wildcard match) to search for a username.  For example, one may search for "br" and Drupal might return "brian", "brad", and "brenda".</p>');
-- 
GitLab