How to Handle User Permissions Across a System

domain-driven-designobject-oriented-designpermissions

My team is currently working on a massive refactor of a medium-sized application in PHP. We are doing our best to refactor our code on a module (Orders, Users, Products) basis. The issue that I am currently wondering about has to do with handling what a user is allowed to do on our system.

Currently, this hinges on mostly on the User's Access Level to our system. Sometimes, we may have to reference their owning group to see if the higher level group is allowed to do something (place an order) and pass that permission on transitively to the user.

What I have come up with so far is a class called "Guardian". Guardian takes a User in and then has functions like "canPlaceOrder" or "canViewOrderReport". One benefit to this approach is that we are able to then see all of the actions on our system that require permissions in one place. In addition, this will allow us to separate our permission logic from our front-end and domain models.

However, I could see this not being an entirely scalable solution. Following the OOP principle that a class should be open for extension, closed for modification, I can see that as we add more permissions to our system, our Guardian class will have to add more methods as well.

I do like the benefit of having all of our permissions well defined in a human-readable way using one class, so that we always know that we are checking the correct criteria. However, I'm worried about scalability. Are there other approaches to this problem?

My question is really: What is a good way to handle this? Is my solution okay?

Best Answer

The guardian shold have a

public boolean checkPermission(String permissionTag, int userID);

method.

That way the guardian doesn't have to change when new permissions come to exist.

Usage

if (guardian.checkPermission("PLACE_ORDER",loggedUser)) {
    // place order
}