I want to expose permissions
property on ORM User
model:
PERMISSIONS_MAP= {
'admin': ['can_delete'],
}
class DatabaseModel:
pass
class User(DatabaseModel):
def __init__(self, role):
self.role = role
@property
def permissions(self):
return role_permissions.list(self.role)
class RolePermissions:
def __init__(self, permissions_map: dict = PERMISSIONS_MAP):
self.permissions_map = permissions_map
def list(self, role):
print(f'listing permissions')
return [p for p in self.permissions_map.get(role, [])]
role_permissions = RolePermissions()
admin = User('admin')
assert admin.permissions == ['can_delete']
assert admin.permissions == ['can_delete'] # here the permissions will be recalculated, but ideally shouldn't
guest = User('guest')
assert guest.permissions == []
But I don't like 2 things:
- Return value of
permissions
property will be calculated each time the property is called:
I can easily alleviate that by switching property
with functools.cached_property
decorator.
However, I would like to instead improve the design. Would changing to RolePermissions(self.role).list()
from role_permissions.list(self.role)
be a move into a right direction? Where do I go from there to mitigate unwanted recalculations?
User
class is coupled touser_permissions
. I could solve it through dependency injection, yet it feels cumbersome to make thepermissions
property acceptUserPermissions
object. Is there a better way to decouple this?
Any other suggestions are of course welcome!