Security update for Core, with self-updated composer
[yaffs-website] / web / core / modules / user / tests / src / Traits / UserCreationTrait.php
diff --git a/web/core/modules/user/tests/src/Traits/UserCreationTrait.php b/web/core/modules/user/tests/src/Traits/UserCreationTrait.php
new file mode 100644 (file)
index 0000000..ccccfa7
--- /dev/null
@@ -0,0 +1,213 @@
+<?php
+
+namespace Drupal\Tests\user\Traits;
+
+use Drupal\Component\Utility\SafeMarkup;
+use Drupal\Core\Session\AccountInterface;
+use Drupal\user\Entity\Role;
+use Drupal\user\Entity\User;
+use Drupal\user\RoleInterface;
+
+/**
+ * Provides methods to create additional test users and switch the currently
+ * logged in one.
+ *
+ * This trait is meant to be used only by test classes.
+ */
+trait UserCreationTrait {
+
+  /**
+   * Switch the current logged in user.
+   *
+   * @param \Drupal\Core\Session\AccountInterface $account
+   *   The user account object.
+   */
+  protected function setCurrentUser(AccountInterface $account) {
+    \Drupal::currentUser()->setAccount($account);
+  }
+
+  /**
+   * Create a user with a given set of permissions.
+   *
+   * @param array $permissions
+   *   Array of permission names to assign to user. Note that the user always
+   *   has the default permissions derived from the "authenticated users" role.
+   * @param string $name
+   *   The user name.
+   * @param bool $admin
+   *   (optional) Whether the user should be an administrator
+   *   with all the available permissions.
+   *
+   * @return \Drupal\user\Entity\User|false
+   *   A fully loaded user object with pass_raw property, or FALSE if account
+   *   creation fails.
+   */
+  protected function createUser(array $permissions = [], $name = NULL, $admin = FALSE) {
+    // Create a role with the given permission set, if any.
+    $rid = FALSE;
+    if ($permissions) {
+      $rid = $this->createRole($permissions);
+      if (!$rid) {
+        return FALSE;
+      }
+    }
+
+    // Create a user assigned to that role.
+    $edit = [];
+    $edit['name'] = !empty($name) ? $name : $this->randomMachineName();
+    $edit['mail'] = $edit['name'] . '@example.com';
+    $edit['pass'] = user_password();
+    $edit['status'] = 1;
+    if ($rid) {
+      $edit['roles'] = [$rid];
+    }
+
+    if ($admin) {
+      $edit['roles'][] = $this->createAdminRole();
+    }
+
+    $account = User::create($edit);
+    $account->save();
+
+    $this->assertTrue($account->id(), SafeMarkup::format('User created with name %name and pass %pass', ['%name' => $edit['name'], '%pass' => $edit['pass']]), 'User login');
+    if (!$account->id()) {
+      return FALSE;
+    }
+
+    // Add the raw password so that we can log in as this user.
+    $account->pass_raw = $edit['pass'];
+    // Support BrowserTestBase as well.
+    $account->passRaw = $account->pass_raw;
+    return $account;
+  }
+
+  /**
+   * Creates an administrative role.
+   *
+   * @param string $rid
+   *   (optional) The role ID (machine name). Defaults to a random name.
+   * @param string $name
+   *   (optional) The label for the role. Defaults to a random string.
+   * @param int $weight
+   *   (optional) The weight for the role. Defaults NULL so that entity_create()
+   *   sets the weight to maximum + 1.
+   *
+   * @return string
+   *   Role ID of newly created role, or FALSE if role creation failed.
+   */
+  protected function createAdminRole($rid = NULL, $name = NULL, $weight = NULL) {
+    $rid = $this->createRole([], $rid, $name, $weight);
+    if ($rid) {
+      /** @var \Drupal\user\RoleInterface $role */
+      $role = Role::load($rid);
+      $role->setIsAdmin(TRUE);
+      $role->save();
+    }
+    return $rid;
+  }
+
+  /**
+   * Creates a role with specified permissions.
+   *
+   * @param array $permissions
+   *   Array of permission names to assign to role.
+   * @param string $rid
+   *   (optional) The role ID (machine name). Defaults to a random name.
+   * @param string $name
+   *   (optional) The label for the role. Defaults to a random string.
+   * @param int $weight
+   *   (optional) The weight for the role. Defaults NULL so that entity_create()
+   *   sets the weight to maximum + 1.
+   *
+   * @return string
+   *   Role ID of newly created role, or FALSE if role creation failed.
+   */
+  protected function createRole(array $permissions, $rid = NULL, $name = NULL, $weight = NULL) {
+    // Generate a random, lowercase machine name if none was passed.
+    if (!isset($rid)) {
+      $rid = strtolower($this->randomMachineName(8));
+    }
+    // Generate a random label.
+    if (!isset($name)) {
+      // In the role UI role names are trimmed and random string can start or
+      // end with a space.
+      $name = trim($this->randomString(8));
+    }
+
+    // Check the all the permissions strings are valid.
+    if (!$this->checkPermissions($permissions)) {
+      return FALSE;
+    }
+
+    // Create new role.
+    $role = Role::create([
+      'id' => $rid,
+      'label' => $name,
+    ]);
+    if (isset($weight)) {
+      $role->set('weight', $weight);
+    }
+    $result = $role->save();
+
+    $this->assertIdentical($result, SAVED_NEW, SafeMarkup::format('Created role ID @rid with name @name.', [
+      '@name' => var_export($role->label(), TRUE),
+      '@rid' => var_export($role->id(), TRUE),
+    ]), 'Role');
+
+    if ($result === SAVED_NEW) {
+      // Grant the specified permissions to the role, if any.
+      if (!empty($permissions)) {
+        $this->grantPermissions($role, $permissions);
+        $assigned_permissions = Role::load($role->id())->getPermissions();
+        $missing_permissions = array_diff($permissions, $assigned_permissions);
+        if (!$missing_permissions) {
+          $this->pass(SafeMarkup::format('Created permissions: @perms', ['@perms' => implode(', ', $permissions)]), 'Role');
+        }
+        else {
+          $this->fail(SafeMarkup::format('Failed to create permissions: @perms', ['@perms' => implode(', ', $missing_permissions)]), 'Role');
+        }
+      }
+      return $role->id();
+    }
+    else {
+      return FALSE;
+    }
+  }
+
+  /**
+   * Checks whether a given list of permission names is valid.
+   *
+   * @param array $permissions
+   *   The permission names to check.
+   *
+   * @return bool
+   *   TRUE if the permissions are valid, FALSE otherwise.
+   */
+  protected function checkPermissions(array $permissions) {
+    $available = array_keys(\Drupal::service('user.permissions')->getPermissions());
+    $valid = TRUE;
+    foreach ($permissions as $permission) {
+      if (!in_array($permission, $available)) {
+        $this->fail(SafeMarkup::format('Invalid permission %permission.', ['%permission' => $permission]), 'Role');
+        $valid = FALSE;
+      }
+    }
+    return $valid;
+  }
+
+  /**
+   * Grant permissions to a user role.
+   *
+   * @param \Drupal\user\RoleInterface $role
+   *   The ID of a user role to alter.
+   * @param array $permissions
+   *   (optional) A list of permission names to grant.
+   */
+  protected function grantPermissions(RoleInterface $role, array $permissions) {
+    foreach ($permissions as $permission) {
+      $role->grantPermission($permission);
+    }
+    $role->trustData()->save();
+  }
+
+}