From 73c2194b9f7214adb463017d88a225a24e4aeba7 Mon Sep 17 00:00:00 2001
From: Alex Pott <alex.a.pott@googlemail.com>
Date: Thu, 5 Sep 2013 22:29:45 +0200
Subject: [PATCH] Issue #366950 by amontero, boombatower, brianV, univate,
 hefox, stpaultim, EllaTheHarpy, babruix: Fixed 'Administer Users' permission
 should be separate from 'Administer Account Settings'.

---
 .../contact/Tests/ContactPersonalTest.php     |  2 +-
 .../contact/Tests/ContactSitewideTest.php     |  1 +
 .../Drupal/field_ui/Tests/FieldUiTestBase.php |  2 +-
 .../Upgrade/UserPermissionUpgradePathTest.php | 64 +++++++++++++++++++
 .../drupal-7.user_permission.database.php     | 60 +++++++++++++++++
 .../lib/Drupal/user/Tests/UserAdminTest.php   |  2 +-
 .../Drupal/user/Tests/UserPermissionsTest.php |  2 +-
 core/modules/user/user.install                | 28 ++++++--
 core/modules/user/user.module                 |  5 ++
 core/modules/user/user.routing.yml            |  2 +-
 10 files changed, 159 insertions(+), 9 deletions(-)
 create mode 100644 core/modules/system/lib/Drupal/system/Tests/Upgrade/UserPermissionUpgradePathTest.php
 create mode 100644 core/modules/system/tests/upgrade/drupal-7.user_permission.database.php

diff --git a/core/modules/contact/lib/Drupal/contact/Tests/ContactPersonalTest.php b/core/modules/contact/lib/Drupal/contact/Tests/ContactPersonalTest.php
index 7e1bd7188c95..e73518087b46 100644
--- a/core/modules/contact/lib/Drupal/contact/Tests/ContactPersonalTest.php
+++ b/core/modules/contact/lib/Drupal/contact/Tests/ContactPersonalTest.php
@@ -54,7 +54,7 @@ function setUp() {
     parent::setUp();
 
     // Create an admin user.
-    $this->admin_user = $this->drupalCreateUser(array('administer contact forms', 'administer users'));
+    $this->admin_user = $this->drupalCreateUser(array('administer contact forms', 'administer users', 'administer account settings'));
 
     // Create some normal users with their contact forms enabled by default.
     \Drupal::config('contact.settings')->set('user_default_enabled', 1)->save();
diff --git a/core/modules/contact/lib/Drupal/contact/Tests/ContactSitewideTest.php b/core/modules/contact/lib/Drupal/contact/Tests/ContactSitewideTest.php
index 56b902ed3ce9..b524dfafef20 100644
--- a/core/modules/contact/lib/Drupal/contact/Tests/ContactSitewideTest.php
+++ b/core/modules/contact/lib/Drupal/contact/Tests/ContactSitewideTest.php
@@ -39,6 +39,7 @@ function testSiteWideContact() {
       'access site-wide contact form',
       'administer contact forms',
       'administer users',
+      'administer account settings',
       'administer contact_message fields',
     ));
     $this->drupalLogin($admin_user);
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Tests/FieldUiTestBase.php b/core/modules/field_ui/lib/Drupal/field_ui/Tests/FieldUiTestBase.php
index c8360236862a..8d397f1ad2ae 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/Tests/FieldUiTestBase.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/Tests/FieldUiTestBase.php
@@ -26,7 +26,7 @@ function setUp() {
     parent::setUp();
 
     // Create test user.
-    $admin_user = $this->drupalCreateUser(array('access content', 'administer content types', 'administer node fields', 'administer node form display', 'administer node display', 'administer taxonomy', 'administer taxonomy_term fields', 'administer taxonomy_term display', 'administer users', 'administer user display', 'bypass node access'));
+    $admin_user = $this->drupalCreateUser(array('access content', 'administer content types', 'administer node fields', 'administer node form display', 'administer node display', 'administer taxonomy', 'administer taxonomy_term fields', 'administer taxonomy_term display', 'administer users', 'administer account settings', 'administer user display', 'bypass node access'));
     $this->drupalLogin($admin_user);
 
     // Create content type, with underscores.
diff --git a/core/modules/system/lib/Drupal/system/Tests/Upgrade/UserPermissionUpgradePathTest.php b/core/modules/system/lib/Drupal/system/Tests/Upgrade/UserPermissionUpgradePathTest.php
new file mode 100644
index 000000000000..ecb8b3a2e1a8
--- /dev/null
+++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/UserPermissionUpgradePathTest.php
@@ -0,0 +1,64 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\system\Tests\Upgrade\UserPermissionUpgradePathTest.
+ */
+
+namespace Drupal\system\Tests\Upgrade;
+
+use Drupal\Core\Session\UserSession;
+
+/**
+ * Tests upgrading a bare database with user role data.
+ *
+ * Loads a bare installation of Drupal 7 with role data and runs the
+ * upgrade process on it. Tests for the upgrade of user permissions.
+ */
+class UserPermissionUpgradePathTest extends UpgradePathTestBase {
+  public static function getInfo() {
+    return array(
+      'name'  => 'User permission upgrade test',
+      'description'  => 'Upgrade tests for user permissions.',
+      'group' => 'Upgrade path',
+    );
+  }
+
+  public function setUp() {
+    $this->databaseDumpFiles = array(
+      drupal_get_path('module', 'system') . '/tests/upgrade/drupal-7.bare.standard_all.database.php.gz',
+      drupal_get_path('module', 'system') . '/tests/upgrade/drupal-7.user_permission.database.php',
+    );
+    parent::setUp();
+  }
+
+  /**
+   * Tests user-related permissions after a successful upgrade.
+   */
+  public function testUserPermissionUpgrade() {
+    $this->assertTrue($this->performUpgrade(), 'The upgrade was completed successfully.');
+
+    $this->drupalGet('');
+    $this->assertResponse(200);
+
+    // Verify that we are still logged in.
+    $this->drupalGet('user');
+    $this->clickLink(t('Edit'));
+    $this->assertEqual($this->getUrl(), url('user/1/edit', array('absolute' => TRUE)), 'We are still logged in as admin at the end of the upgrade.');
+
+    // Login as another 'administrator' role user whose uid != 1
+    $this->drupalLogout();
+    $user = new UserSession(array(
+      'uid' => 2,
+      'name' => 'user1',
+      'pass_raw' => 'user1',
+    ));
+    $this->drupalLogin($user);
+
+    // Check that user with permission 'administer users' also gets
+    // 'administer account settings' access.
+    $this->drupalGet('admin/config/people/accounts');
+    $this->assertResponse(200, '"Administer account settings" page was found.');
+  }
+
+}
diff --git a/core/modules/system/tests/upgrade/drupal-7.user_permission.database.php b/core/modules/system/tests/upgrade/drupal-7.user_permission.database.php
new file mode 100644
index 000000000000..dc6cd5ace3ed
--- /dev/null
+++ b/core/modules/system/tests/upgrade/drupal-7.user_permission.database.php
@@ -0,0 +1,60 @@
+<?php
+
+/**
+ * @file
+ * Database additions for user permissions tests. Used in
+ * \Drupal\system\Tests\Upgrade\UserPermissionUpgradePathTest.
+ *
+ * This dump only contains data and schema components relevant for user data
+ * permission upgrade tests. The drupal-7.bare.standard_all.database.php.gz
+ * file is imported before this dump, so the two form the database
+ * structure expected in tests altogether.
+ */
+
+db_insert('users_roles')->fields(array(
+  'uid',
+  'rid',
+))
+->values(array(
+  'uid' => '2',
+  'rid' => '3',
+))
+->execute();
+
+db_insert('users')->fields(array(
+  'uid',
+  'name',
+  'pass',
+  'mail',
+  'theme',
+  'signature',
+  'signature_format',
+  'created',
+  'access',
+  'login',
+  'status',
+  'timezone',
+  'language',
+  'picture',
+  'init',
+  'data',
+))
+->values(array(
+  'uid' => '2',
+  'name' => 'user1',
+  'pass' => '$S$D9JgycE33DawX/9Iv2SfAjkQEi5alDZhxycfan6dDkUKf9lH0Nfo',
+  'mail' => 'user1@example.com',
+  'theme' => '',
+  'signature' => '',
+  'signature_format' => NULL,
+  'created' => '1376147347',
+  'access' => '0',
+  'login' => '0',
+  'status' => '1',
+  'timezone' => 'Europe/Berlin',
+  'language' => '',
+  'picture' => '0',
+  'init' => 'user1@example.com',
+  'data' => NULL,
+))
+->execute();
diff --git a/core/modules/user/lib/Drupal/user/Tests/UserAdminTest.php b/core/modules/user/lib/Drupal/user/Tests/UserAdminTest.php
index 0b61e236485c..077eeed61ceb 100644
--- a/core/modules/user/lib/Drupal/user/Tests/UserAdminTest.php
+++ b/core/modules/user/lib/Drupal/user/Tests/UserAdminTest.php
@@ -120,7 +120,7 @@ function testUserAdmin() {
    */
   function testNotificationEmailAddress() {
     // Test that the Notification E-mail address field is on the config page.
-    $admin_user = $this->drupalCreateUser(array('administer users'));
+    $admin_user = $this->drupalCreateUser(array('administer users', 'administer account settings'));
     $this->drupalLogin($admin_user);
     $this->drupalGet('admin/config/people/accounts');
     $this->assertRaw('id="edit-mail-notification-address"', 'Notification E-mail address field exists');
diff --git a/core/modules/user/lib/Drupal/user/Tests/UserPermissionsTest.php b/core/modules/user/lib/Drupal/user/Tests/UserPermissionsTest.php
index 40f8d6064768..857f0b69e541 100644
--- a/core/modules/user/lib/Drupal/user/Tests/UserPermissionsTest.php
+++ b/core/modules/user/lib/Drupal/user/Tests/UserPermissionsTest.php
@@ -25,7 +25,7 @@ public static function getInfo() {
   function setUp() {
     parent::setUp();
 
-    $this->admin_user = $this->drupalCreateUser(array('administer permissions', 'access user profiles', 'administer site configuration', 'administer modules', 'administer users'));
+    $this->admin_user = $this->drupalCreateUser(array('administer permissions', 'access user profiles', 'administer site configuration', 'administer modules', 'administer account settings'));
 
     // Find the new role ID.
     $all_rids = $this->admin_user->getRoles();
diff --git a/core/modules/user/user.install b/core/modules/user/user.install
index 6d15166962b5..2d5b03e5d525 100644
--- a/core/modules/user/user.install
+++ b/core/modules/user/user.install
@@ -1011,12 +1011,32 @@ function user_update_8016() {
   db_drop_field('users', 'data');
 }
 
+/**
+ * Grant "administer account settings" to roles with "administer users."
+ */
+function user_update_8017() {
+  $rids = db_query("SELECT rid FROM {role_permission} WHERE permission = :perm", array(':perm' => 'administer users'))->fetchCol();
+  // None found.
+  if (empty($rids)) {
+    return;
+  }
+  $insert = db_insert('role_permission')->fields(array('rid', 'permission', 'module'));
+  foreach ($rids as $rid) {
+    $insert->values(array(
+      'rid' => $rid,
+      'permission' => 'administer account settings',
+      'module' => 'user'
+    ));
+  }
+  $insert->execute();
+}
+
 /**
  * Migrate user roles into configuration.
  *
  * @ingroup config_upgrade
  */
-function user_update_8017() {
+function user_update_8018() {
   $uuid = new Uuid();
 
   $roles = db_select('role', 'r')
@@ -1038,7 +1058,7 @@ function user_update_8017() {
 /**
  * Use the maximum allowed module name length in module name database fields.
  */
-function user_update_8018() {
+function user_update_8019() {
   if (db_field_exists('role_permission', 'module')) {
     $spec = array(
       'type' => 'varchar',
@@ -1095,7 +1115,7 @@ function _user_update_map_rid($rid) {
  *
  * @ingroup config_upgrade
  */
-function user_update_8019() {
+function user_update_8020() {
   $db_permissions = db_select('role_permission', 'p')
     ->fields('p')
     ->execute()
@@ -1117,7 +1137,7 @@ function user_update_8019() {
 /**
  * Create the 'register' form mode.
  */
-function user_update_8020() {
+function user_update_8021() {
   $uuid = new Uuid();
 
   Drupal::config("entity.form_mode.user.register")
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index 75de3cc5bb03..53eaf99aaabe 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -466,6 +466,11 @@ function user_permission() {
       'title' => t('Administer permissions'),
       'restrict access' => TRUE,
     ),
+    'administer account settings' => array(
+      'title' => t('Administer account settings'),
+      'description' => t('Configure site-wide settings and behavior for <a href="@url">user accounts and registration</a>.', array('@url' => url('admin/config/people'))),
+      'restrict access' => TRUE,
+    ),
     'administer users' => array(
       'title' => t('Administer users'),
       'restrict access' => TRUE,
diff --git a/core/modules/user/user.routing.yml b/core/modules/user/user.routing.yml
index 2e8dcb3d068c..ba753898d155 100644
--- a/core/modules/user/user.routing.yml
+++ b/core/modules/user/user.routing.yml
@@ -38,7 +38,7 @@ user_account_settings:
   defaults:
     _form: '\Drupal\user\AccountSettingsForm'
   requirements:
-    _permission: 'administer users'
+    _permission: 'administer account settings'
 
 user_admin_create:
   pattern: '/admin/people/create'
-- 
GitLab