diff --git a/modules/user/user.admin.inc b/modules/user/user.admin.inc index 6ca330b013..7df93f2164 100644 --- a/modules/user/user.admin.inc +++ b/modules/user/user.admin.inc @@ -312,6 +312,18 @@ function user_admin_settings() { '#description' => t('This role will be automatically assigned new permissions whenever a module is enabled. Changing this setting will not affect existing permissions.'), ); + // Settings for separating the administer users and edit user settings. + $form['permission_settings'] = array( + '#type' => 'fieldset', + '#title' => t('Separate administer account settings permission'), + ); + $form['permission_settings']['user_enable_separate_account_settings'] = array( + '#type' => 'checkbox', + '#title' => t('Separate administer account settings permission'), + '#default_value' => variable_get('user_enable_separate_account_settings', FALSE), + '#description' => t('With this option you can have seperate permissions for editing this page and for administering users.'), + ); + // User registration settings. $form['registration_cancellation'] = array( '#type' => 'fieldset', @@ -658,11 +670,29 @@ function user_admin_settings() { '#default_value' => _user_mail_text('status_canceled_body', NULL, array(), FALSE), '#rows' => 3, ); + $form['#submit'][] = 'user_admin_settings_submit'; return system_settings_form($form); } /** + * Form submit handler for the user_admin_settings() form. + */ +function user_admin_settings_submit($form, $form_state) { + // If we are changing the settings for separating the administer users and + // account settings we have to clear the menu cache to make the new access + // arguments take effect. + if ((bool) $form_state['values']['user_enable_separate_account_settings'] != (bool) variable_get('user_enable_separate_account_settings', FALSE)) { + // Since the actual saving of the variable will happen in the form submit + // provided by system_settings_form, we just override the $conf value for + // now, so the hook_menu implementation knows what to do. + $GLOBALS['conf'] ['user_enable_separate_account_settings'] = $form_state['values']['user_enable_separate_account_settings']; + entity_info_cache_clear(); + menu_rebuild(); + } +} + +/** * Menu callback: administer permissions. * * @ingroup forms diff --git a/modules/user/user.module b/modules/user/user.module index b818d79ab5..028f5b7e38 100644 --- a/modules/user/user.module +++ b/modules/user/user.module @@ -183,6 +183,9 @@ function user_entity_info() { ), ), ); + if (variable_get('user_enable_separate_account_settings', FALSE)) { + $return['user']['bundles']['user']['admin']['access arguments'] = array('administer account settings'); + } return $return; } @@ -870,7 +873,7 @@ function user_has_role($rid, $account = NULL) { * Implements hook_permission(). */ function user_permission() { - return array( + $perms = array( 'administer permissions' => array( 'title' => t('Administer permissions'), 'restrict access' => TRUE, @@ -894,6 +897,16 @@ function user_permission() { 'restrict access' => TRUE, ), ); + // If the option for separating the account settings and administering users + // is enabled, then we must include another permission for this. + if (variable_get('user_enable_separate_account_settings', FALSE)) { + $perms['administer account settings'] = array( + 'title' => t('Administer account settings'), + 'description' => t('Manage settings that apply to all user accounts.'), + 'restrict access' => TRUE, + ); + } + return $perms; } /** @@ -1780,6 +1793,11 @@ function user_menu() { 'file' => 'user.admin.inc', 'weight' => -10, ); + // If the option for separating the account settings and administering users + // is enabled, then we change the access argument for this item. + if (variable_get('user_enable_separate_account_settings', FALSE)) { + $items['admin/config/people/accounts']['access arguments'] = array('administer account settings'); + } $items['admin/config/people/accounts/settings'] = array( 'title' => 'Settings', 'type' => MENU_DEFAULT_LOCAL_TASK, diff --git a/modules/user/user.test b/modules/user/user.test index 63143c3ced..ccb46f4a90 100644 --- a/modules/user/user.test +++ b/modules/user/user.test @@ -1508,6 +1508,40 @@ class UserAdminTestCase extends DrupalWebTestCase { $this->assertEqual($account1->status, 1, 'User D unblocked'); $this->assertMail("to", $account1->mail, "Activation mail sent to user D"); } + + /** + * Test separating the user settings from user administering. + */ + function testSeparateAccountSettings() { + // First see that the admin user can access the account settings page. + $admin_user = $this->drupalCreateUser(array('administer users')); + // Find the new role ID - it must be the maximum. + $all_rids = array_keys($admin_user->roles); + sort($all_rids); + $rid = array_pop($all_rids); + $this->drupalLogin($admin_user); + $this->drupalGet('admin/config/people/accounts'); + $this->assertResponse(200); + + // Change settings. + $edit['user_enable_separate_account_settings'] = 1; + $this->drupalPost('admin/config/people/accounts', $edit, t('Save configuration')); + $this->assertText(t('The configuration options have been saved.'), 'Successful save message displayed.'); + // Interestingly enough, this should actually make the user not have access + // to the page they are looking at. + $this->assertResponse(403); + // Just to be sure, let's also try to go to the page, and see that we get + // "access denied" still. + $this->drupalGet('admin/config/people/accounts'); + $this->assertResponse(403); + + // Then add the permission in question. + user_role_grant_permissions($rid, array('administer account settings')); + // We should now be allowed again. + $this->drupalGet('admin/config/people/accounts'); + $this->assertResponse(200); + + } } /**