- Patch #46149 by Senpai, sun, alexanderpas, hunmonk, ChrisKennedy, tstoeckler, cwgordon7: prevent account cancellation for uid 1.
parent
0bc9acfad3
commit
dfebdecfa7
|
@ -2747,10 +2747,29 @@ function user_multiple_cancel_confirm($form, &$form_state) {
|
|||
$edit = $form_state['input'];
|
||||
|
||||
$form['accounts'] = array('#prefix' => '<ul>', '#suffix' => '</ul>', '#tree' => TRUE);
|
||||
// array_filter() returns only elements with TRUE values.
|
||||
foreach (array_filter($edit['accounts']) as $uid => $value) {
|
||||
$user = db_query('SELECT name FROM {users} WHERE uid = :uid', array(':uid' => $uid))->fetchField();
|
||||
$form['accounts'][$uid] = array('#type' => 'hidden', '#value' => $uid, '#prefix' => '<li>', '#suffix' => check_plain($user) . "</li>\n");
|
||||
$accounts = user_load_multiple(array_keys(array_filter($edit['accounts'])));
|
||||
foreach ($accounts as $uid => $account) {
|
||||
// Prevent user 1 from being canceled.
|
||||
if ($uid <= 1) {
|
||||
continue;
|
||||
}
|
||||
$form['accounts'][$uid] = array(
|
||||
'#type' => 'hidden',
|
||||
'#value' => $uid,
|
||||
'#prefix' => '<li>',
|
||||
'#suffix' => check_plain($account->name) . "</li>\n",
|
||||
);
|
||||
}
|
||||
|
||||
// Output a notice that user 1 cannot be canceled.
|
||||
if (isset($accounts[1])) {
|
||||
$redirect = (count($accounts) == 1);
|
||||
$message = t('The user account %name cannot be cancelled.', array('%name' => $accounts[1]->name));
|
||||
drupal_set_message($message, $redirect ? 'error' : 'warning');
|
||||
// If only user 1 was selected, redirect to the overview.
|
||||
if ($redirect) {
|
||||
drupal_goto('admin/people');
|
||||
}
|
||||
}
|
||||
|
||||
$form['operation'] = array('#type' => 'hidden', '#value' => 'cancel');
|
||||
|
@ -2799,6 +2818,10 @@ function user_multiple_cancel_confirm_submit($form, &$form_state) {
|
|||
|
||||
if ($form_state['values']['confirm']) {
|
||||
foreach ($form_state['values']['accounts'] as $uid => $value) {
|
||||
// Prevent programmatic form submissions from cancelling user 1.
|
||||
if ($uid <= 1) {
|
||||
continue;
|
||||
}
|
||||
// Prevent user administrators from deleting themselves without confirmation.
|
||||
if ($uid == $user->uid) {
|
||||
$admin_form_state = $form_state;
|
||||
|
@ -2812,7 +2835,6 @@ function user_multiple_cancel_confirm_submit($form, &$form_state) {
|
|||
}
|
||||
}
|
||||
$form_state['redirect'] = 'admin/people';
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -248,7 +248,7 @@ function user_profile_form($form, &$form_state, $account, $category = 'account')
|
|||
'#value' => t('Cancel account'),
|
||||
'#weight' => 31,
|
||||
'#submit' => array('user_edit_cancel_submit'),
|
||||
'#access' => ($account->uid == $user->uid && user_access('cancel account')) || user_access('administer users'),
|
||||
'#access' => $account->uid > 1 && (($account->uid == $user->uid && user_access('cancel account')) || user_access('administer users')),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -362,6 +362,44 @@ class UserCancelTestCase extends DrupalWebTestCase {
|
|||
$this->assertTrue(($test_node->uid == $account->uid && $test_node->status == 1), t('Node of the user has not been altered.'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that user account for uid 1 cannot be cancelled.
|
||||
*
|
||||
* This should never be possible, or the site owner would become unable to
|
||||
* administer the site.
|
||||
*/
|
||||
function testUserCancelUid1() {
|
||||
// Update uid 1's name and password to we know it.
|
||||
$password = user_password();
|
||||
require_once DRUPAL_ROOT . '/' . variable_get('password_inc', 'includes/password.inc');
|
||||
$account = array(
|
||||
'name' => 'user1',
|
||||
'pass' => user_hash_password(trim($password)),
|
||||
);
|
||||
// We cannot use user_save() here or the password would be hashed again.
|
||||
db_update('users')
|
||||
->fields($account)
|
||||
->condition('uid', 1)
|
||||
->execute();
|
||||
|
||||
// Reload and log in uid 1.
|
||||
$user1 = user_load(1, TRUE);
|
||||
$user1->pass_raw = $password;
|
||||
|
||||
// Try to cancel uid 1's account with a different user.
|
||||
$this->admin_user = $this->drupalCreateUser(array('administer users'));
|
||||
$this->drupalLogin($this->admin_user);
|
||||
$edit = array(
|
||||
'operation' => 'cancel',
|
||||
'accounts[1]' => TRUE,
|
||||
);
|
||||
$this->drupalPost('admin/people', $edit, t('Update'));
|
||||
|
||||
// Verify that uid 1's account was not cancelled.
|
||||
$user1 = user_load(1, TRUE);
|
||||
$this->assertEqual($user1->status, 1, t('User #1 still exists and is not blocked.'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt invalid account cancellations.
|
||||
*/
|
||||
|
@ -647,6 +685,8 @@ class UserCancelTestCase extends DrupalWebTestCase {
|
|||
$edit['accounts[' . $uid . ']'] = TRUE;
|
||||
}
|
||||
$edit['accounts[' . $admin_user->uid . ']'] = TRUE;
|
||||
// Also try to cancel uid 1.
|
||||
$edit['accounts[1]'] = TRUE;
|
||||
$this->drupalPost('admin/people', $edit, t('Update'));
|
||||
$this->assertText(t('Are you sure you want to cancel these user accounts?'), t('Confirmation form to cancel accounts displayed.'));
|
||||
$this->assertText(t('When cancelling these accounts'), t('Allows to select account cancellation method.'));
|
||||
|
@ -666,6 +706,10 @@ class UserCancelTestCase extends DrupalWebTestCase {
|
|||
$this->assertText(t('A confirmation request to cancel your account has been sent to your e-mail address.'), t('Account cancellation request mailed message displayed.'));
|
||||
$admin_user = user_load($admin_user->uid);
|
||||
$this->assertTrue($admin_user->status == 1, t('Administrative user is found in the database and enabled.'));
|
||||
|
||||
// Verify that uid 1's account was not cancelled.
|
||||
$user1 = user_load(1, TRUE);
|
||||
$this->assertEqual($user1->status, 1, t('User #1 still exists and is not blocked.'));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue