cvs diff: Diffing .
? .project
Index: masquerade.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/masquerade/masquerade.install,v
retrieving revision 1.4.2.4
diff -u -p -r1.4.2.4 masquerade.install
--- masquerade.install	6 Aug 2009 20:15:02 -0000	1.4.2.4
+++ masquerade.install	28 Aug 2009 19:52:52 -0000
@@ -36,7 +36,24 @@ function masquerade_schema() {
         'sid' => array('sid', 'uid_from'),
         'sid_2' => array('sid', 'uid_as')
       )
-    )
+    ),
+    'masquerade_users' => array(
+      'fields' => array(
+        'uid_from' => array(
+          'type' => 'int',
+          'not null' => true,
+          'default' => 0,
+          'disp-width' => 10,
+        ),
+        'uid_to' => array(
+          'type' => 'int',
+          'not null' => true,
+          'default' => 0,
+          'disp-width' => 10,
+        ),
+      ),
+      'primary key' => array('uid_from', 'uid_to'),
+    ),
   );
 }
 
@@ -124,3 +141,31 @@ function masquerade_update_6004() {
   $ret[] = update_sql("UPDATE {system} SET weight = -10 WHERE name = 'masquerade' AND weight = 0");
   return $ret;
 }
+
+/**
+ * Add a table storing specific user pairings a user can masquerade as.
+ */
+function masquerade_update_6005() {
+  $ret = array();
+  $schema = array(
+    'masquerade_users' => array(
+      'fields' => array(
+        'uid_from' => array(
+          'type' => 'int',
+          'not null' => true,
+          'default' => 0,
+          'disp-width' => 10,
+        ),
+        'uid_to' => array(
+          'type' => 'int',
+          'not null' => true,
+          'default' => 0,
+          'disp-width' => 10,
+        ),
+      ),
+      'primary key' => array('uid_from', 'uid_to'),
+    )
+  );
+  db_create_table($ret, 'masquerade_users', $schema['masquerade_users']);
+  return $ret;
+}
Index: masquerade.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/masquerade/masquerade.module,v
retrieving revision 1.16.2.20
diff -u -p -r1.16.2.20 masquerade.module
--- masquerade.module	28 Aug 2009 18:59:29 -0000	1.16.2.20
+++ masquerade.module	28 Aug 2009 19:52:53 -0000
@@ -80,7 +80,7 @@ function masquerade_menu() {
     'page callback' => 'masquerade_switch_user',
     'page arguments' => array(2),
     'access callback' => 'masquerade_access',
-    'access arguments' => array('switch'),
+    'access arguments' => array('switch', 2),
     'type' => MENU_NORMAL_ITEM,
   );
   $items['masquerade/unswitch'] = array(
@@ -104,6 +104,12 @@ function masquerade_menu() {
     'access arguments' => array('autocomplete'),
     'type' => MENU_CALLBACK,
   );
+  $items['masquerade/autocomplete-user'] = array(
+    'title' => 'Masquerade autocomplete',
+    'page callback' => 'masquerade_autocomplete_user',
+    'access arguments' => array('access user profiles'),
+    'type' => MENU_CALLBACK,
+  );
   $items['admin/settings/masquerade'] = array(
     'title' => 'Masquerade',
     'description' => 'Masquerade module allows administrators to masquerade as other users.',
@@ -117,15 +123,37 @@ function masquerade_menu() {
   return $items;
 }
 
-function masquerade_access($type) {
+/**
+ * Determine if the current user has permission to switch users.
+ *
+ * @param string $type
+ *   Either 'switch', 'unswitch', 'user', or 'autocomplete'.
+ *
+ * @param object $uid
+ *   An optional parameter indicating a specific uid to switch to.
+ *   Otherwise, return if the user can switch to any user account.
+ *
+ * @return
+ *   TRUE, if the user can perform the requested action, FALSE otherwise. 
+ */
+function masquerade_access($type, $uid = NULL) {
   switch ($type) {
     case 'unswitch':
       return !empty($_SESSION['masquerading']) || arg(2) == 'menu-customize' || arg(2) == 'menu';
     case 'autocomplete':
       return !empty($_SESSION['masquerading']) || (user_access('masquerade as user') || user_access('masquerade as admin'));
       break;
+    case 'user':
+      global $user;
+      return db_result(db_query("SELECT TRUE FROM {masquerade_users} WHERE uid_from = %d", $user->uid));
+      break;
     case 'switch':
-      return empty($_SESSION['masquerading']) && ((user_access('masquerade as user') || user_access('masquerade as admin')));
+      global $user;
+      if ($uid) {
+        $account = user_load(array('uid' => $uid));
+        $switch_to_account = db_result(db_query("SELECT TRUE FROM {masquerade_users} WHERE uid_from = %d AND uid_to = %d", $user->uid, $account->uid));
+      }
+      return empty($_SESSION['masquerading']) && (user_access('masquerade as user') || user_access('masquerade as admin') || $switch_to_account);
       break;
   }
 }
@@ -252,6 +280,48 @@ function masquerade_user($op, &$edit, &$
         );
       }
       break;
+
+    case 'form':
+      $form = array();
+      $form['masquerade'] = array(
+        '#type' => 'fieldset',
+        '#title' => t('Masquerade settings'),
+        '#access' => user_access('administer permissions'),
+      );
+      $result = db_query("SELECT uid_to FROM {masquerade_users} WHERE uid_from = %d", $edit_user->uid);
+      $masquerade_users = array();
+      while ($uid_to = db_result($result)) {
+        $u = user_load($uid_to);
+        $masquerade_users[] = $u->name;
+      }
+      $form['masquerade']['masquerade_users'] = array(
+        '#type' => 'textfield',
+        '#title' => t('Enter the users this user is able to masquerade as'),
+        '#description' => t('Enter a comma seperated list of user names that this user can masquerade as.'),
+        '#autocomplete_path' => 'masquerade/autocomplete-user',
+        '#default_value' => implode(", ", $masquerade_users),
+      );
+      return $form;
+      break;
+
+    case 'validate':
+      $users = drupal_explode_tags($edit['masquerade_users']);
+      foreach ($users as $user) {
+        if (!user_load(array('name' => $user))) {
+          form_set_error('masquerade_users', t('%user is not a valid user name.', array('%user' => $user)));
+        }
+      }
+      break;
+
+    case 'update':
+    	$users = drupal_explode_tags($edit['masquerade_users']);
+      db_query("DELETE FROM {masquerade_users} WHERE uid_from = %d", $edit_user->uid);
+      foreach ($users as $user) {
+        $u = user_load(array('name' => $user));
+        db_query("INSERT INTO {masquerade_users} VALUES (%d, %d)", $edit_user->uid, $u->uid);
+      }
+      $edit['masquerade_users'] = NULL;
+      break;
   }
 }
 
@@ -265,14 +335,14 @@ function masquerade_block($op = 'list', 
       $blocks[0]['cache'] = BLOCK_CACHE_PER_USER;
       return $blocks;
     case 'view':
-      if (masquerade_access('autocomplete')) {
-        switch ($delta) {
-          case 0:
+      switch ($delta) {
+        case 0:
+          if (masquerade_access('autocomplete') || masquerade_access('user')) {
             $block['subject'] = t('Masquerade');
             $block['content'] = drupal_get_form('masquerade_block_1');
-            break;
-        }
-        return $block;
+            return $block;
+          }
+          break;
       }
       break;
   }
@@ -282,17 +352,24 @@ function masquerade_block($op = 'list', 
  * Masquerade block form.
  */
 function masquerade_block_1($record) {
+  global $user;
   $markup_value = '';
   if ($_SESSION['masquerading']) {
-    global $user;
     $quick_switch_link[] = l(t('Switch back'), 'masquerade/unswitch', array());
     $markup_value = t('You are masquerading as <a href="@user-url">%masq_as</a>.', array('@user-url' => url('user/' . $user->uid), '%masq_as' => $user->name)) . theme('item_list', $quick_switch_link);
   }
   else {
-    // A comma-separated list of users.
     $masquerade_switches = variable_get('masquerade_quick_switches', array());
+    $masquerade_switches = array();
+
+    // Add in user-specific switches.
+    $result = db_query("SELECT uid_to FROM {masquerade_users} WHERE uid_from = %d", $user->uid);
+    while ($uid_to = db_result($result)) {
+      $masquerade_switches[] = $uid_to;
+    }
+
     foreach ($masquerade_switches as $switch_user) {
-      if ($switch_user != $GLOBALS['user']->uid) {
+      if ($switch_user != $_SESSION['user']->uid) {
         $user_name = user_load(array('uid' => $switch_user));
         if ($user_name->uid) {
           $quick_switch_link[] = l($user_name->name, 'masquerade/switch/'. $user_name->uid);
@@ -300,19 +377,21 @@ function masquerade_block_1($record) {
       }
     }
 
-	$markup_value .= t('Enter a username to masquerade as.') . '<br /><br />';
-    $form['masquerade_user_field'] = array(
-      '#prefix' => '<div class="container-inline">',
-      '#type' => 'textfield',
-      '#size' => '18',
-      '#default_value' => $_SESSION['masquerading'] ? t('Switch back to use') : '',
-      '#autocomplete_path' => 'masquerade/autocomplete',
-    );
-    $form['submit'] = array(
-      '#type' => 'submit',
-      '#value' => t('Go'),
-      '#suffix' => '</div>',
-    );
+    if (masquerade_access('autocomplete')) {
+      $markup_value .= t('Enter username to masquerade as.') . '<br /><br />';
+      $form['masquerade_user_field'] = array(
+        '#prefix' => '<div class="container-inline">',
+        '#type' => 'textfield',
+        '#size' => '18',
+        '#default_value' => $_SESSION['masquerading'] ? t('Switch back to use') : '',
+        '#autocomplete_path' => 'masquerade/autocomplete',
+      );
+      $form['submit'] = array(
+        '#type' => 'submit',
+        '#value' => t('Go'),
+        '#suffix' => '</div>',
+      );
+    }
 
     if (isset($quick_switch_link) && count($quick_switch_link)) {
       $markup_value .= '<div id="quick_switch_links">'. t('Quick switches:') . theme('item_list', $quick_switch_link) .'</div>';
@@ -394,10 +473,31 @@ function masquerade_autocomplete_multipl
 }
 
 /**
+ * Replacement function for user_autocomplete which allows the use of a comma
+ * separated list of user names. 
+ */
+function masquerade_autocomplete_user($string) {
+  $array = drupal_explode_tags($string);
+  $search = trim(array_pop($array));
+  $matches = array();
+  if ($search) {
+    $prefix = count($array) ? implode(', ', $array) .', ' : '';
+    $result = db_query_range("SELECT name FROM {users} WHERE LOWER(name) LIKE LOWER('%s%%')", $search, 0, 10);
+    while ($user = db_fetch_object($result)) {
+      $matches[$prefix . $user->name] = check_plain($user->name);
+    }
+  }
+
+  drupal_json($matches);
+}
+
+/**
  * Page callback that allows a user with the right permissions to become
  * the selected user.
  */
 function masquerade_switch_user($uid) {
+  global $user;
+
   if (!is_numeric($uid)) {
     drupal_set_message(t('A user id was not correctly passed to the switching function.'));
     watchdog('masquerade', 'The user id provided to switch users was not numeric.', NULL, WATCHDOG_ERROR);
@@ -410,13 +510,12 @@ function masquerade_switch_user($uid) {
   $perm = $uid == 1 || array_intersect(array_keys($new_user->roles), $roles) ?
     'masquerade as admin' :
     'masquerade as user';
+
   // check to see if we need admin permission
-  if (!user_access($perm) && !$_SESSION['masquerading']) {
+  if (!user_access($perm) && !$_SESSION['masquerading'] && !db_result(db_query("SELECT TRUE FROM {masquerade_users} WHERE uid_from = %d AND uid_to = %d", $user->uid, $new_user->uid))) {
     return drupal_access_denied();
   }
 
-  global $user;
-
   if ($user->uid == $uid || isset($user->masquerading)) {
     return drupal_access_denied();
   }
