Hi there,

Is there a way to redirect to a specific page after masquerading?

I am creating a site where the admin user needs to masquerade to access other user's account. I have created an admin section where I've put a list of all the users. In front of each user there is a "log in as this user" button, that redirects to masquerade:

// at the end of a form_submit handler
$form_state['redirect'] = 'masquerade/switch/'.$uid; 

The problem is that after going to the masquerade link, it goes back to the admin page, where non-admin users are not authorized to be. So, I get an "access denied".

Is there a way to do something like this:

// at the end of a form_submit handler
$form_state['redirect'] = 'masquerade/switch/'.$uid.'?destination=some-page'; 

Thanks for a great module, by the way!

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

deviantintegral’s picture

Version: 6.x-1.3 » 6.x-1.x-dev
Status: Active » Needs review
FileSize
5.55 KB

At the end of masquerade_switch_user(), there is:

drupal_goto(referer_uri());

I've attached a patch that refactors masqurade_switch_user() and masqurade_switch_back() into page callbacks and API functions. That way, you should be able to call masqurade_switch_user() directly in your form, without having it mess up your #redirect.

Note this is completely untested as I was on the plane when I wrote it :)

deviantintegral’s picture

Category: support » feature
FileSize
5.51 KB

Reroll against HEAD.

deviantintegral’s picture

Updated patch that properly throws an error if the user doesn't have access to switch to the specified user.

deviantintegral’s picture

And here's a patch against HEAD.

deviantintegral’s picture

Version: 6.x-1.x-dev » 7.x-1.x-dev
Status: Needs review » Patch (to be ported)
FileSize
5.87 KB

I've committed the attached patch to DRUPAL-6--1.

southweb’s picture

FileSize
5.61 KB

Thanks for this. Will have a look. I had the same problem. But I also needed the facility to be able to switch users as an API call ( without FAPI ).

And for this, there may be cases where we don't want any redirect at all.

Also, going to referrer() seems problematic given that you could well be switching back to a page for which the original users doesn't have access to. Or that they have access to it, but are accessing it as the 'wrong' user for the application logic.

My approach was to add the parameter redirect which could be boolean or a path and by default was set to true. In the API scenario you may not want to go anywhere at all after a redirect.

Also, if you do want to redirect, but have not specified the destination, the safest place is the home page;

If you want to specify a redirect, this can be passed as a string (for API users); and finally, the return to the redirect should be the starting point of the original masquerade request - so we store the referrer as $_SESSION['masquerade_redirect'] prior to redirection (see attached).

Anyway, not sure how much help the above is, and I may well be able to achieve all these things with your API patch, so feel free to ignore.

(BTW - this applies Drupal 6 version)

andypost’s picture

@bluffit are you still using your API for switching without formapi? Can ypu post a patch or your code?

southweb’s picture

Hi andypost,

Sorry for the late reply. I am still using the old module (my bad) as the new one would require a major attack.

LEternity’s picture

bluffit, can you make this a patch for the D6 version, so it can be tested?

andypost’s picture

#5 or #6 is a preferable way to implement API switching? Probably this functionality could be used with Rules.

andypost’s picture

When porting we should care about masquerade_user_operations()

obleser’s picture

jenlampton’s picture

I was also looking for this feature (7.x) but managed to accomplish what I needed by using hook_user_login, testing array_key_exists('masquerading', $_SESSION) and calling a drupal_goto.

I'm not sure if we need this feature built directly into Masquerade, but having an API so that other modules could do things while switching users (and switching back) would certainly be helpful.

Edit: Just read the other issue, it looks like that's what the plan is over there. Kudos!

andypost’s picture

For d7 a custom modules could implement hook_drupal_goto_alter()

nevosa’s picture

Issue summary: View changes

followup on andypost, I used:

function HOOK_drupal_goto_alter(&$path, &$options, &$http_response_code) {
	if(strstr(request_path(),'masquerade/switch')) {
		 $path = ''; // go home after masquarading
	}
}
ndenhild’s picture

Thanks Nevos!

cristiroma’s picture

According to the module code http://cgit.drupalcode.org/masquerade/tree/masquerade.module#n711, I am altering the referer, as so:

/**
 * Implements hook_form_alter().
 */
function module_form_masquerade_block_1_alter(&$form, &$form_state) {
  array_unshift($form['#submit'], 'module_form_masquerade_redirect');
}

function module_form_masquerade_redirect() {
  $_SERVER['HTTP_REFERER'] = '/user';
}

Could this pose any problem?
I was wondering if instead of drupal_goto, masquerade would call a hook like "masquerade_post_switch" and let another module what action to take? If the maintainer agrees, I can post a patch.

andypost’s picture

Category: Feature request » Bug report
Status: Patch (to be ported) » Needs work

Using referee uri is bad idea because it mostly empty and could be fake, so having hook a nice idea
Also this needs to be ported to 8.x

cristiroma’s picture

Status: Needs work » Needs review
FileSize
436 bytes

Greetings, I am submitting a patch allowing the module to invoke a hook in the redirect submit block to override the landing page after masquerade. Though I have one question: Is there a security check necessary on the $redirect variable?

Thanks,
Cristian

richardbporter’s picture

I had this use case as well. This is sort-of a follow up on #17.

Using $form_state['redirect'] instead of drupal_goto in masquerade_block_1_submit would allow other modules to redirect as necessary using a form_alter without losing the access check. For example:

/**
 * Implements hook_form_FORM_ID_alter().
 */
function mymodule_form_masquerade_block_1_alter(&$form, &$form_state, $form_id) {
  $form['#submit'][] = 'mymodule_masquerade_block_1_submit';
}

/**
 * Additional submit handler for masquerade_block_1.
 */
function mymodule_masquerade_block_1_submit($form, &$form_state) {
  $form_state['redirect'] = '/node/1';
}

See https://www.drupal.org/node/1975230 for documentation on redirecting a form.

The patch for this is pretty simple. However, is there a specific reason drupal_goto is being used?

richardbporter’s picture

andypost’s picture

is there a specific reason drupal_goto is being used?

Yep, to prevent "destination" override that we have issue in d8