Add functionality to impersonate a user

Created on 25 July 2008, almost 17 years ago
Updated 4 May 2025, 9 days ago

Problem/Motivation

Currently Drupal has no unified API that allows safe user impersonation in code. This functionality is often needed by core and contrib and each module implements it in different ways some of them not secure. This may be considered a security improvement since:

  1. It can help people avoid unsafe impersonation constructs as outlined in Safely Impersonating Another User.
  2. It makes it possible to nest multiple impersonation levels without having the innermost impersonation logic incorrectly re-enable session saving when finished (see #21)

Proposed resolution

Add an AccountSwitcher class with the two methods switchTo($account) and switchBack(). Streamline the use of account "impersonations" throughout core (cron).

Remaining tasks

Commit.

User interface changes

None

API changes

API addition: a new service with two new methods for safely impersonating an account.

Original report by @drewish β†’

I'm trying to write tests for file.inc and several of the validation functions need to switch to a uid=1 and non-uid=1 users. I know about DrupalWebTestCase::drupalLogin() but it affects the web browser's user not the global $user;. chx pointed me toward [#218104] which provided the method for doing this in tests:

<!--break-->
  /**
   * Test the file_validate_extensions() function for the root user.
   */
  function testFileValidateExtensionsUid1() {
    global $user;
    $original_user = $user;
    session_save_session(FALSE);
    $user = user_load(array('uid' => 1));

    // Run these test as user 1
    $file = new stdClass();
    $file->filename = 'asdf.txt';
    $errors = file_validate_extensions($file, 'asdf txt pork');
    $this->assertEqual(count($errors), 0, t("Valid extension accepted."));

    $file->filename = 'asdf.txt';
    $errors = file_validate_extensions($file, 'exe png');
    $this->assertEqual(count($errors), 0, t("Invalid extension also accepted -- they're uid 1."));

    $user = $original_user;
    session_save_session(TRUE);
  }

  /**
   * Test the file_validate_extensions() function for the root user.
   */
  function testFileValidateExtensionsUidNot1() {
    global $user;
    $original_user = $user;
    session_save_session(FALSE);
    $user = $this->drupalCreateUser();

    // Run these test as a regular user
    $file = new stdClass();
    $file->filename = 'asdf.txt';
    $errors = file_validate_extensions($file, 'asdf txt pork');
    $this->assertEqual(count($errors), 0, t("Valid extension accepted."));

    $file->filename = 'asdf.txt';
    $errors = file_validate_extensions($file, 'exe png');
    $this->assertEqual(count($errors), 1, t("Invalid extension blocked."));

    $user = $original_user;
    session_save_session(TRUE);
  }

It's just enough code to be a pain and clutter up the tests. It seems like it be better to have DrupalWebTestCase::drupalSetUser() and ::drupalRestoreUser() or something like that to make this a little saner.

πŸ› Bug report
Status

Fixed

Version

8.0 ⚰️

Component

user system

Created by

πŸ‡ΊπŸ‡ΈUnited States drewish

Live updates comments and jobs are added and updated live.
  • Security improvements

    It makes Drupal less vulnerable to abuse or misuse. Note, this is the preferred tag, though the Security tag has a large body of issues tagged to it. Do NOT publicly disclose security vulnerabilities; contact the security team instead. Anyone (whether security team or not) can apply this tag to security improvements that do not directly present a vulnerability e.g. hardening an API to add filtering to reduce a common mistake in contributed modules.

  • Needs change record

    A change record needs to be drafted before an issue is committed. Note: Change records used to be called change notifications.

  • Needs backport to D7

    After being applied to the 8.x branch, it should be considered for backport to the 7.x branch. Note: This tag should generally remain even after the backport has been written, approved, and committed.

Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

Production build 0.71.5 2024