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 -~----------~----~----~----~------~----~------~--~---