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