Has anyone in this group implemented any sort of login-as-another-user
functionality with Django? Maybe if I at least know it's possible
it'll steer me in the right direction.

On May 2, 8:42 am, Dave Brueck <dave.bru...@gmail.com> wrote:
> Hi all,
>
> I would like an admin user on my site to be able to temporarily
> "become" a normal user and see the site as if logged in as that normal
> user. However, I also need to retain one admin-related permission
> after I become the normal user.
>
> On my site there are admin users that aren't staff or superusers from
> Django's perspective - instead they are users that belong to an admin
> group and, by extension, have an 'app.is_admin' permission.
>
> To support this "login as" functionality, I created a custom
> authentication backend and added it to my list in settings.py. This
> backend subclasses ModelBackend so that for the most part permissions
> and so forth work normally, except that authentication happens purely
> based on user ID:
>
> class LoginAsBackend(ModelBackend):
>     '''Special-case backend for when the admin needs to login as
> another user'''
>     def authenticate(self, id=None, **kwargs):
>         try:
>             return User.objects.get(id=id)
>         except User.DoesNotExist:
>             return None
>
>     def has_perm(self, user, perm):
>         # If we authenticated this user, then they are an admin
>         if perm == 'app.is_admin' and user.backend ==
> 'app.backends.LoginAsBackend':
>             return True
>
>         # for other permissions, though, look them up from the usual
> place
>         return super(LoginAsBackend, self).has_perm(user, perm)
>
> The overridden has_perm method is supposed to allow this user to
> continue to be a site admin, otherwise as soon as you become the
> normal user, you're effectively logged out as an admin, which means if
> you need to look at the account for multiple users you'd have to re-
> login using your own credentials each time.
>
> The problem I'm having is that the above successfully gets me logged
> in as the desired user, but I lose the knowledge that I used to be an
> admin - when has_perm is called, the user object does not have a
> backend property.
>
> The view to become another user looks something like this:
>
> @permission_required('app.is_admin', login_url='/user/noperm/')
> def UserLoginAs(r, id):
>     user = authenticate(id=id) # id is a user ID here
>     assert user
>     login(r, user)
>     return HttpResponseRedirect('/')
>
> Immediately after the login() call, user.backend *does* exist and does
> have the name of my custom backend, but on any subsequent requests the
> user object does not have backend set (probably because in a later
> request, it's a different instance of the user object or something).
>
> All of the site admin functionality is wrapped in permission_required
> calls that require the app.is_admin permission, so I just need some
> way for this user to have that permission - but only for the current
> session. I don't want to actually give the user that permission since
> it's temporary.
>
> Is there some better way to do all this? Or am I on the right track
> but just missing a step?
>
> I also noticed that the user's session retains knowledge of which
> backend was used (req.session['_auth_user_backend']) but I couldn't
> figure out a good way to make use of that via permission_required.
> Maybe I need to change all uses of permission_required to a custom
> decorator that does what I need? (ugh)
>
> Thanks for any help you can give me!
> -Dave
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to 
django-users+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to