Hi,
I am developing an ERP application and the authorization requirements are crazy complicated. I'm pretty sure I need object-level security as stated in the
Auth tutorial of Pyramid by Michael Merickel. The problem is that it's my first time doing this and I'm a bit overwhelmed by this.
So....I have Products, Orders and Customers. A logged in user can either belong to a group called "Backoffice" or "Agent". "Backoffice" is actually an Admin who can do pretty much everything. "Agent" is a bit tricky, and this is my problem.
My understanding from Michael's tutorial is that you place the most general (this is also the group-level security stuff) ACLs in the Factories and the more specific ones as ACL properties in the object classes that the factories return. Is this correct so far?
I have this business requirement that just makes my head explode: "An agent can view, create, edit and delete (if these are the only permissions in the system, then this means ALL_PERMISSIONS right?) customers. However, he can only view customers that belong to the same country as the agent's address." Here's an attempt to setup the factory and customer object:
class CustomerFactory(object):
__acl__= [
(Allow, 'Backoffice', ALL_PERMISSIONS) <---- THE GENERAL STUFF
] __name__ = "CustomerFactory"
__parent__ = None
def __init__(self, request):
self.request = request
def __getitem__(self, id):
if id == "list":
new_customer = CustomerModel()
new_customer.__parent__ = self
new_customer.__name__ = id
return new_customer
class Customer(object):
@property
def __acl__(self):
return [
(Allow, 'Agent', ALL_PERMISSIONS)
]
Then in my code I would have to (1) find whether the current logged in user is an Agent, (2) find which country he is from and finally (3) filter the list of customers in the database based on the country. Is this the correct way OR is there a much better and smarter way to do this? To my understanding it seems that the Pyramid authorization only handles what a given user can do, be it edit/view/create/delete. If we want to limit what the user can view, this has to be handled in the views.