[development] Rules action to impersonate a user

Lluís Forns enboig at gmail.com
Wed Jan 23 13:46:58 UTC 2013


It is ok to me; you can take my code as start if you want. I think it
wouldn't be any problem (and action calling die() could help to check this)
if you don't "close" the rule as long as you use
"session_save_session(FALSE);" (I read your project); but it will not hurt.

<?php

/**
 * Implementation of hook_rules_action_info().
 */
function rules_switch_user_rules_action_info() {
  return array(
    'mymodule_action_impersonate' => array(
      'label' => t('Select the user to masquerade as'),
      'arguments' => array(
        'uid' => array('type' => 'string', 'label' => t('uid')),
      ),
      'module' => 'WU',
      'help' => t('Use this action to change the user for next actions'),
    ),
    'mymodule_action_unimpersonate' => array(
      'label' => t('Return to previous user'),
      'help' => t('It returns to the user who called the rule.'),
      'module' => 'WU',
    ),
  );
}

function rules_switch_user_action_impersonate($uid) {
  global $user;
  if (!array_key_exists('rules_switch_user_action_impersonate', $_SESSION))
{
    $_SESSION['rules_switch_user_action_impersonate'] = array();
  }
  array_push($_SESSION['rules_switch_user_action_impersonate'], $user);
  session_save_session(FALSE);
  $user = user_load($uid);
  user_load($uid);
}

function rules_switch_user_action_unimpersonate() {
  global $user;
  if (array_key_exists('rules_switch_user_action_impersonate', $_SESSION)) {
    if (!empty($_SESSION['rules_switch_user_action_impersonate'])) {
      $user = array_pop($_SESSION['rules_switch_user_action_impersonate']);
    }
    if (empty($_SESSION['rules_switch_user_action_impersonate'])) {
      unset($_SESSION['rules_switch_user_action_impersonate']);
    }
  }
  session_save_session(TRUE);
}


2013/1/23 Michael Moritz <mimo at gn.apc.org>

> Hi
>
> I got inspired by this and created a very basic module to have these
> actions
> available in Rules http://drupal.org/project/rules_switch_user
>
> What do you think?
>
> Regards,
>
> mimo
>
> On Tuesday 22 Jan 2013 15:00:38 Lluís Forns wrote:
> > Ok.
> >
> > Till now I have created a pair of actions; one which I call at the start
> of
> > my rule to impersonate "node changing user", and one at last to change
> > back. Using this I can call scheduled rules with the user who triggered
> > them. It is all I need to the moment, so I will stop looking further into
> > batching actions (limited time).
> >
> > Thanks.
> >
> >
> > 2013/1/21 Earnie Boyd <earnie at users.sourceforge.net>
> >
> > > drupal_static() is not equivalent to PHP static.  The example you've
> > > given is using PHP static and yes, it will not be available in another
> > > function.
> > >
> > >
> > >
> http://api.drupal.org/api/drupal/includes%21bootstrap.inc/function/drupal_
> > > static/7>
> > > On Mon, Jan 21, 2013 at 11:21 AM, Lluís Forns <enboig at gmail.com>
> wrote:
> > > > I know we are going OT, but I also want to understand this;
> > > >
> > > > what about:
> > > >
> > > >
> > > > function mymodule_complex_calculation() {
> > > >
> > > >   static $cache;
> > > >   if (isset($cache)) {
> > > >
> > > >     return $cache;
> > > >
> > > >   }
> > > >   // Otherwise we need to perform our calculations
> > > >   // ...some complex calculation that returns
> > > >   $cache = complex_calculation();
> > > >   return $cache;
> > > >
> > > > }
> > >
> > >
> http://techblog.zabuchy.net/2011/enhancing-drupal-performance-with-drupal_
> > > static/>
> > > > You are saying that if I instantiate a variable in
> > >
> > > "mymodule_impersonate()"
> > >
> > > > it will not be available in "mymodule_unimpersonate()"?
> > > >
> > > >
> > > > 2013/1/21 Earnie Boyd <earnie at users.sourceforge.net>
> > > >
> > > >> You "think" wrongly.  A static variable has local scope to the
> > > >> function declaring the static variable.
> > > >>
> > > >> On Mon, Jan 21, 2013 at 11:03 AM, Lluís Forns <enboig at gmail.com>
> wrote:
> > > >> > I think static are also available to other functions, use them to
> > >
> > > store
> > >
> > > >> > cached information across my code and they work.
> > > >> >
> > > >> >
> > > >> > 2013/1/21 Darren Oh <darrenoh at sidepotsinternational.com>
> > > >> >
> > > >> >> Static variables are only saved for a single function. Global
> > >
> > > variables
> > >
> > > >> >> are available to all functions during a single page request.
> Session
> > > >> >> variables are available to all page requests during a session.
> > > >> >>
> > > >> >> On Jan 21, 2013, at 10:08 AM, Lluís Forns wrote:
> > > >> >>
> > > >> >> Darren, thanks for the link. What is the difference between using
> > > >> >> global
> > > >> >> or static to save the data?
> > > >> >>
> > > >> >>
> > > >> >>
> > > >> >> 2013/1/21 Lluís Forns <enboig at gmail.com>
> > > >> >>
> > > >> >>> My code was from a module where impersonation recursively could
> > > >> >>> happen,
> > > >> >>> this is why I use a stack to save user state. I am also saving
> it
> > > >> >>> to
> > > >> >>> session
> > > >> >>> and not using a static variable because I may uses batch
> functions.
> > > >> >>>
> > > >> >>> But I see some problems right now:
> > > >> >>> - To be safe impersonation should be saved into static variables
> > >
> > > (and
> > >
> > > >> >>> "using session_save_session(FALSE);" ), so if anything goes
> wrong,
> > > >> >>> $user is
> > > >> >>> not afected.
> > > >> >>> - If I want to be able to execute every Rules action in a
> batch, I
> > > >> >>> need
> > > >> >>> to change user "per action"
> > > >> >>>
> > > >> >>> Any idea of how to "inject" code before and after a rule action?
> > > >> >>>
> > > >> >>>
> > > >> >>> 2013/1/21 Walt Daniels <wdlists at gmail.com>
> > > >> >>>
> > > >> >>>> We do the latter simple trick in our store code so we can show
> > >
> > > people
> > >
> > > >> >>>> the member prices. We have a dummy id that is a member so we
> > > >> >>>> switch
> > > >> >>>> to it,
> > > >> >>>> pick up the price and use it so we can show both member and
> > > >> >>>> non-member
> > > >> >>>> prices on the screen.
> > > >> >>>>
> > > >> >>>>
> > > >> >>>> On Mon, Jan 21, 2013 at 9:18 AM, Christian López Espínola
> > > >> >>>>
> > > >> >>>> <penyaskito at computer.org> wrote:
> > > >> >>>>> Haven't tested your code, but maybe you want to take a look at
> > >
> > > >> >>>>> masquerade_switch_user and masquerade_switch_back:
> > >
> http://drupalcode.org/project/masquerade.git/blob/HEAD:/masquerade.module.
> > >
> > > >> >>>>> And if the impersonation is only for the given request, maybe
> > > >> >>>>> just
> > > >> >>>>>
> > > >> >>>>>  global $user;
> > > >> >>>>>  $previous = $user;
> > > >> >>>>>  $user = user_load($uid);
> > > >> >>>>>
> > > >> >>>>> // Do your stuff.
> > > >> >>>>>
> > > >> >>>>>  $user = $previous;
> > > >> >>>>>
> > > >> >>>>> would work.
> > > >> >>>>>
> > > >> >>>>>
> > > >> >>>>>
> > > >> >>>>> On Mon, Jan 21, 2013 at 10:37 AM, Lluís Forns <
> enboig at gmail.com>
> > > >> >>>>>
> > > >> >>>>> wrote:
> > > >> >>>>>> Some of my scheduled task needs to run as the user who
> triggered
> > > >> >>>>>> them
> > > >> >>>>>> (not anonymous neither admin); so I thought of writing two
> > >
> > > actions:
> > > >> >>>>>> - One to impersonate a user, which will receive uid as an
> > >
> > > argument.
> > >
> > > >> >>>>>> - Another to undo the impersonate.
> > > >> >>>>>> All the called actions should be between them.
> > > >> >>>>>>
> > > >> >>>>>> Anybody see any fault in this idea or the actions code?
> > > >> >>>>>>
> > > >> >>>>>> Thanks.
> > > >> >>>>>>
> > > >> >>>>>> function wu_action_impersonate($uid) {
> > > >> >>>>>>
> > > >> >>>>>>   global $user;
> > > >> >>>>>>   if (!array_key_exists('wu_action_impersonate', $_SESSION))
> {
> > > >> >>>>>>
> > > >> >>>>>>     $_SESSION['wu_action_impersonate'] = array();
> > > >> >>>>>>
> > > >> >>>>>>   }
> > > >> >>>>>>   array_push($_SESSION['wu_action_impersonate'], $user);
> > > >> >>>>>>   session_save_session(FALSE);
> > > >> >>>>>>   $user = user_load($uid);
> > > >> >>>>>>   user_load($uid);
> > > >> >>>>>>
> > > >> >>>>>> }
> > > >> >>>>>>
> > > >> >>>>>> function wu_action_unimpersonate() {
> > > >> >>>>>>
> > > >> >>>>>>   global $user;
> > > >> >>>>>>   if (array_key_exists('wu_action_impersonate', $_SESSION)) {
> > > >> >>>>>>
> > > >> >>>>>>     if (!empty($_SESSION['wu_action_impersonate'])) {
> > > >> >>>>>>
> > > >> >>>>>>       $user = array_pop($_SESSION['wu_action_impersonate']);
> > > >> >>>>>>
> > > >> >>>>>>     }
> > > >> >>>>>>     if (empty($_SESSION['wu_action_impersonate'])) {
> > > >> >>>>>>
> > > >> >>>>>>       unset($_SESSION['wu_action_impersonate']);
> > > >> >>>>>>
> > > >> >>>>>>     }
> > > >> >>>>>>
> > > >> >>>>>>   }
> > > >> >>>>>>   session_save_session(TRUE);
> > > >> >>>>>>
> > > >> >>>>>> }
> > > >> >>>>>>
> > > >> >>>>>> --
> > > >> >>>>>> *Ser freak no és imprescindible per ser informàtic, però
> ajuda.
> > > >> >>>>>> *La vida no ha de ser feliç, ha de ser plena.
> > > >> >>>>>> *Abans d'imprimir aquest missatge, pensa en el medi ambient.
> > > >> >>>>>
> > > >> >>>>> --
> > > >> >>>>> Cheers,
> > > >> >>>>>
> > > >> >>>>> Christian López Espínola <penyaskito AT computer DOT org>
> > > >> >>>>> http://twitter.com/penyaskito | http://penyaskito.com
> > > >> >>>
> > > >> >>> --
> > > >> >>> *Ser freak no és imprescindible per ser informàtic, però ajuda.
> > > >> >>> *La vida no ha de ser feliç, ha de ser plena.
> > > >> >>> *Abans d'imprimir aquest missatge, pensa en el medi ambient.
> > > >> >>
> > > >> >> --
> > > >> >> *Ser freak no és imprescindible per ser informàtic, però ajuda.
> > > >> >> *La vida no ha de ser feliç, ha de ser plena.
> > > >> >> *Abans d'imprimir aquest missatge, pensa en el medi ambient.
> > > >> >
> > > >> > --
> > > >> > *Ser freak no és imprescindible per ser informàtic, però ajuda.
> > > >> > *La vida no ha de ser feliç, ha de ser plena.
> > > >> > *Abans d'imprimir aquest missatge, pensa en el medi ambient.
> > > >>
> > > >> --
> > > >> Earnie
> > > >> -- https://sites.google.com/site/earnieboyd
> > > >
> > > > --
> > > > *Ser freak no és imprescindible per ser informàtic, però ajuda.
> > > > *La vida no ha de ser feliç, ha de ser plena.
> > > > *Abans d'imprimir aquest missatge, pensa en el medi ambient.
> > >
> > > --
> > > Earnie
> > > -- https://sites.google.com/site/earnieboyd
>



-- 
*Ser freak no és imprescindible per ser informàtic, però ajuda.
*La vida no ha de ser feliç, ha de ser plena.
*Abans d'imprimir aquest missatge, pensa en el medi ambient.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.drupal.org/pipermail/development/attachments/20130123/e07282c6/attachment-0001.html 


More information about the development mailing list