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 %masq_as.', 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.') . '

'; - $form['masquerade_user_field'] = array( - '#prefix' => '
', - '#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' => '
', - ); + if (masquerade_access('autocomplete')) { + $markup_value .= t('Enter username to masquerade as.') . '

'; + $form['masquerade_user_field'] = array( + '#prefix' => '
', + '#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' => '
', + ); + } if (isset($quick_switch_link) && count($quick_switch_link)) { $markup_value .= ''; @@ -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(); }