Impersonate in Layers...

134 views
Skip to first unread message

Joe Barnhart

unread,
Apr 17, 2014, 3:26:11 AM4/17/14
to web...@googlegroups.com
I find I need the "impersonate" feature for a website I'm building -- it is the perfect solution to supporting users who forget how to work the website or need help setting up their profile information.  In fact, I have a group called "support" who I am tasking with this chore and I want them to be able impersonate any of the users.

EXCEPT, of course, me.  I have a group for the people who run and control every aspect of the website, and only my partner and I have logons at this level.  I don't want any "support" group members to be able to impersonate my "root" group.  I may add a "manager" group at some point who should also not be accessible to the support staff.  I guess I should also prevent support staff from impersonating each other as well.  I'm no killjoy, but I want to prevent "pranking" and epic April Fools jokes between my support reps before they even get started.

And I, of course, as "root" want to be able to impersonate anybody on my site.  The only difference between me and the NSA is that my employees won't have to wonder or guess if I'm looking over their shoulder -- I'll tell them straight up!  (just kidding.  NSA also has a larger budget and cooler toys.  there are actually several differences)

I can see how I can add an "impersonate" group, and add it to either the auth_user table or specific rows, but that doesn't give me the layers I'm looking for.  That is:

support --> impersonate users
managers --> impersonate support, users
root --> impersonate all of the above

Have I missed something obvious?

-- Joe "benevolent dictator" B.

Joe Barnhart

unread,
Oct 1, 2016, 4:56:11 AM10/1/16
to web2py-users
Still looking for a reply for this message!  C'mon, it's only been...what... 2-1/2 years??  Seriously. I was just looking at this again and thought to myself, "I remember asking that on web2py-user... I wonder if I missed the response?"  Turns out I didn't!

-- Joe

Marlysson Silva

unread,
Oct 3, 2016, 11:17:53 AM10/3/16
to web2py-users
You want create a user that can handle other admin users? Remove, alter permissions , add

Massimo Di Pierro

unread,
Oct 3, 2016, 3:47:27 PM10/3/16
to web2py-users
Hello Joe,

sorry this fell through the cracks. The easiest way is this:


class JoeAuth(Auth):

    def impersonate(self, user_id=DEFAULT):

        """                                                                                                                                                                                                                To use this make a POST to                                                                                                                                                                     `http://..../impersonate request.post_vars.user_id=<id>`                                                                                                                             Set request.post_vars.user_id to 0 to restore original user.                                                                                                                       requires impersonator is logged in and::                                                                                                                                                         has_permission('impersonate', 'auth_user', user_id)                                                                                                                              """

        request = current.request

        session = current.session

        auth = session.auth

        table_user = self.table_user()

        if not self.is_logged_in():

            raise HTTP(401, "Not Authorized")

        current_id = auth.user.id

        requested_id = user_id

        user = None

        if user_id is DEFAULT:

            user_id = current.request.post_vars.user_id

        if user_id and user_id != self.user.id and user_id != '0':


            # joe's rules!

            if not (self.has_membership('root') or 

                      (self.has_membership('manager') and 

                        not self.has_membership('manager',user_id) and 

                        not self.has_membership('root',user_id))):

                raise HTTP(403, "Forbidden")


            user = table_user(user_id)            

            if not user:

                raise HTTP(401, "Not Authorized")

            auth.impersonator = pickle.dumps(session, pickle.HIGHEST_PROTOCOL)

            auth.user.update(

                table_user._filter_fields(user, True))

            self.user = auth.user

            self.update_groups()

            log = self.messages['impersonate_log']

            self.log_event(log, dict(id=current_id, other_id=auth.user.id))

            self.run_login_onaccept()

        elif user_id in (0, '0'):

            if self.is_impersonating():

                session.clear()

                session.update(pickle.loads(auth.impersonator))

                self.user = session.auth.user

                self.update_groups()

                self.run_login_onaccept()

            return None

        if requested_id is DEFAULT and not request.post_vars:

            return SQLFORM.factory(Field('user_id', 'integer'))

        elif not user:

            return None

        else:

            return SQLFORM(table_user, user.id, readonly=True)

 
put it in a module, import it, than use JoeAuth in place of Auth.

Anthony

unread,
Oct 4, 2016, 12:22:38 PM10/4/16
to web2py-users
I suppose you could also move the "Joe's rules" logic to the user() function (or whatever action you use to control impersonation):

def user():
   
if request.args(0) == 'impersonate':
       
[Joe's rules]
    return dict(form=auth())

Anthony

Joe Barnhart

unread,
Oct 4, 2016, 2:26:33 PM10/4/16
to web2py-users
Ah.  I see.  I understand the logic perfectly.

I think I'm going to go with Anthony's solution as I already expose the auth forms thru my 'default' controller anyway.

Thanks for the response!  (If it were urgent, I would have rattled your cage long ago...)

-- Joe
Reply all
Reply to author
Forward
0 new messages