Issues trying to replace logged in user

Hi all,

I’m trying to implement impersonation, e.g. an admin changing the currently logged in user to someone else with the possibility to revert back to the original admin user account. I’m running into some issues that I can’t seem to resolve.

Impersonation is implemented as follows:

@anvil.server.callable("impersonate")
@has_perm('impersonation')
def impersonate(username):
  saved_user = anvil.users.get_user()
  
  users = app_tables.users.search(username=username)
  if users and len(list(users)):
    try:
      anvil.users.logout()
      anvil.users.force_login(list(users)[0])
      anvil.server.session["user_before_impersonation"] = saved_user
    except Exception, e:
      print e

After calling this server function, I refresh the main form as follows:

# Refresh the main form to activate the new user rights and data
open_form('MainForm')   

# Close alert
self.raise_event("x-close-alert", value=42)

But the first server call in the main form then results in an exception in Anvil code:

KeyError: 'anvil.tables.Row' at /pysrc/anvil/_server.py, line 32
called from /pysrc/anvil/_server.py, line 522 
called from /pysrc/anvil/_server.py, line 489 
called from /pysrc/anvil/_server.py, line 513
called from /pysrc/anvil/_server.py, line 489 
called from /pysrc/anvil/_server.py, line 770 
called from /pysrc/anvil/server.py, line 48 
called from [MainForm, line 24](javascript:void(0)) 
called from [UserInfo, line 34](javascript:void(0))

The second issue I have, is that I save the original admin user’s record in the session (after impersonation, see more complete code snippet above):
anvil.server.session["user_before_impersonation"] = saved_user

but, when I retrieve the object later, it turns out to be None:
print anvil.server.session.get("user_before_impersonation")

I think the way I’m replacing the currently logged in user messes up the session and maybe even the connection between the client and server, resulting in both the exception and the session variable disappearing. Anyone an idea on how to remediate?

Thanks!

I don’t have an answer, but I have a question: what is has_perm?

It’s a decorator I made to check if the user has a certain permission (identified by its textual name).

Users have a single role and every role can have multiple permissions. The decorator checks if the needed permission is assigned to the user (via the role) and raises an exception if not.

Hi there!

This looks like a bug in Anvil - that code should work. I’ve therefore moved this thread to Bug Reports.

However, I’ve tried, and I’m having trouble reproducing this issue on my own. Are you able to share a clone link for your app (either in this thread or via private message to me) that could show me how to reproduce the issue?

Hi Meredydd, thanks for your interest. I didn’t find a way to send a private message through the forum, so I sent you an e-mail yesterday as follow-up.