Issue #9 invalid

request.impersonator property only set on first request.

Hugo Rodger-Brown
created an issue

Looking into the code (not quite sure at the moment how to write a test for this) - it looks like the .impersonator property will only get set once, and is then lost on subsequent client requests.

I think the steps it goes through are:

  1. Original request comes through to impersonate-start:
  • session attr '_impersonate' is set, and the request is redirected
  • request now contains the impersonator as user, impersonatee as '_impersonate'
  1. Middleware intercepts second request as '_impersonate' is set:
  • request is now switched, and user is now the impersonatee
  • request.impersonator is set for this request
  1. Subsequent requests (user is browsing around):
  • brand new request comes in, attaches to correct session
  • BUT request.user is now the impersonatee, and the impersonator is effectively lost

I think that makes sense (writing it out long form to try and get it correct in my head). The middleware tests pass as they only test the original interception request - what they don't do is test that a subsequent request, where user.is_impersonate is True, has anything set for request.impersonator.

Steps to reproduce:

Add {{ request.impersonator }} to any template (or log file) and you'll see it consistently returns None.

Comments (4)

  1. Peter Sanchez repo owner

    Thank you for catching this. I believe it's only in the default branch right now, not in an actual release. This is something that's been contributed and I haven't had a ton of time to really test and investigate.

    I'll check into this.

  2. Hugo Rodger-Brown reporter

    I have a feeling that I'm wrong in any case - as looking through the contrib.auth code, the '_auth_user_id' is only set on login, and is never overwritten by impersonate, and so it should all work as is.

    Doesn't explain why I have no request.impersonator object in my code however :-S

    I'll mark this as invalid.

  3. Hugo Rodger-Brown reporter

    This is incorrect. The request user is set from the Django Session and Authentication processing, which uses the '_auth_user_id' session key.

    This is never overwritten by impersonate - so even though request.user is set (as stated in the issue description), the next time a request comes in, request.user will be rehydrated from the session key as the impersonator.

    I had thought that setting request.user = new_user would update the session to assume the identity of the new_user, but having dug through the Django code, this is not the case.

    Apologies for raising this.

  4. Log in to comment