Anvil.users.get_user() and security

You could create your own wrapper for this:

from functools import wraps
def admin(func):
  @wraps
  def wrapper(*args, **kwargs):
      admin_role = app_tables.roles.get(name='admin')
      user = anvil.users.get_user()
      if user is not None and admin_role in user['roles']:
          return func(*args, **kwargs)
      else:
          raise anvil.users.AuthenticationFailed('not an admin')
  return wrapper


@anvil.server.callable
@admin
def get_data_for_admin():
  user = anvil.users.get_user()
  return app_tables.data.search(user=user)

which uses the access_control ideas suggested by @alcampopiano in his post


Generalise the approach for multiple roles

and for a more advanced option to generalise this approach for multiple roles you could do something inspired by this post:

passing args to a decorator
from functools import wraps

class access_control:
    def __init__(self, role):
        self.role = role
    def __call__(self, func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            role_row = app_tables.roles.get(name=self.role)
            user = anvil.users.get_user()
            if user is not None and role_row in user['roles']:
                return func(*args, **kwargs)
            else:
                raise anvil.users.AuthenticationFailed(f'user does not have the role: {self.role}')
        return wrapper


@anvil.server.callable
@access_control('admin')
def get_data_for_admin():
  user = anvil.users.get_user()
  return app_tables.data.search(user=user)

or as a function rather than a class

def access_control(role):
    def decorator(self, func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            role_row = app_tables.roles.get(name=role)
            user = anvil.users.get_user()
            if user is not None and role_row in user['roles']:
                return func(*args, **kwargs)
            else:
                raise anvil.users.AuthenticationFailed(f'user does not have the role: {role}')
        return wrapper
    return decorator

3 Likes