Cms: No events when impersonating another user via control panel

Created on 24 Jun 2020  路  1Comment  路  Source: craftcms/cms

Description

For a project of ours we've developed a module that fetches custom pricing from an external service to override Commerce pricing for a user upon logon (using the User class event EVENT_BEFORE_AUTHENTICATE). In Craft 2 the corresponding equivalent userSession.onBeforeLogin event was also triggered when impersonating/logging in from the control panel as a specific user, but in Craft 3 this seems to have been removed and/or the impersonation logic seems to have been separated from the general authentication logic. I've had a look through Craft's code and couldn't really find any events to hook into unfortunately.

Are there any plans to bring back the events from Craft 2 or to add new events to the impersonation logic? In the meantime, is there another way for us to hook into the impersonation logic to trigger our custom price fetching? Currently we've resorted to asking our users to visit a custom controller action that also triggers the logic, but we feel that is a bit inefficient to them (and they usually forget to do it, so they see default pricing). Thanks!

Steps to reproduce

  1. Impersonate another user via the control panel
  2. No user events are triggered

Additional info

  • Craft version: 3.x
  • PHP version: 7.3
  • Database driver & version: MySQL 5.7
  • Plugins & versions: Custom module
question

Most helpful comment

The way to do it in Craft 3 would be to listen for either the yii\web\User::EVENT_BEFORE_LOGIN or EVENT_AFTER_LOGIN event, and check Craft::$app->session->has(craft\elements\User::IMPERSONATE_KEY). If that returns true, then you know the user is being impersonated by an admin.

use yii\base\Event;
use yii\web\User as UserSession;
use yii\web\UserEvent;
use craft\elements\User;

Event::on(UserSession::class, UserSession::EVENT_AFTER_LOGIN, function(UserEvent $e) {
    if (Craft::$app->session->has(User::IMPERSONATE_KEY)) {
        // user is being impersonated
        // ...
    }
});

If you need to actually know who the admin is, you can call get() instead of has():

    if ($adminId = Craft::$app->session->get(User::IMPERSONATE_KEY)) {
        // user is being impersonated
        $admin = User::findOne($adminId);
        // ...
    }

>All comments

The way to do it in Craft 3 would be to listen for either the yii\web\User::EVENT_BEFORE_LOGIN or EVENT_AFTER_LOGIN event, and check Craft::$app->session->has(craft\elements\User::IMPERSONATE_KEY). If that returns true, then you know the user is being impersonated by an admin.

use yii\base\Event;
use yii\web\User as UserSession;
use yii\web\UserEvent;
use craft\elements\User;

Event::on(UserSession::class, UserSession::EVENT_AFTER_LOGIN, function(UserEvent $e) {
    if (Craft::$app->session->has(User::IMPERSONATE_KEY)) {
        // user is being impersonated
        // ...
    }
});

If you need to actually know who the admin is, you can call get() instead of has():

    if ($adminId = Craft::$app->session->get(User::IMPERSONATE_KEY)) {
        // user is being impersonated
        $admin = User::findOne($adminId);
        // ...
    }
Was this page helpful?
0 / 5 - 0 ratings