2

I have been trying to implement a Role Class Model pattern to my website User access mechanism (written in PHP). I have a few doubts though. Here is a simplified version of relevant code:

class User 
{
        public $role;
        public $uid;        
        public function setRole($role)
        {
            $this->role = $role;
        }
} 
// role classes responsible for restricted actions
class BaseRole {} 
class AdminRole extends BaseRole
{ 
       // do something adminish + log action into database (with User ID)
       public function SomethingAdminish($admin_id) { }
}
$user = new User();
$user->setRole(new AdminRole());

// pass Admin ID (User ID) into method
$user->rola->SomethingAdminish($user->uid);

I see some weakness here:

  1. Passing any other $user->uid into "SomethingAdminish" method will log incorrect information in to my log system (wrong User ID)
  2. If I decide to log other User information in the above method, essentially I would have to pass whole User object as an argument, like so:

    $user->rola->SomethingAdminish($user);

I am probably missing something essential here. Could you guys shed some light on the subject, please?

BenMorel
  • 34,448
  • 50
  • 182
  • 322
marcinsvr
  • 21
  • 2

1 Answers1

0

Personally I would set up and use an Access Control List (ACL) pattern.

"a resource is an object to which access is controlled.

a role is an object that may request access to a Resource.

Put simply, roles request access to resources. For example, if a parking attendant requests access to a car, then the parking attendant is the requesting role, and the car is the resource, since access to the car may not be granted to everyone."

Here is a basic example (using your code above) of how the ACL flow would look.

// Create an ACL object to store roles and resources. The ACL also grants
// and denys access to resources.
$acl = new Acl();

// Create 2 roles. 
$adminRole = new Acl_Role('admin');
$editorRole = new Acl_Role('editor');

// Add the Roles to the ACL.
$acl->addRole($adminRole)
    ->addRole($editorRole);

// Create an example Resource. A somethingAdminish() function in this case.
$exampleResource = new Acl_Resource('somethingAdminish');

// Add the Resource to the ACL.
$acl->add($exampleResource);

// Define the rules. admins can are allowed access to the somethingAdminish
// resource, editors are denied access to the somethingAdminish resource.
$acl->allow('admin', 'somethingAdminish');
$acl->deny('editor', 'somethingAdminish');

Here is how a User object would interact with the ACL

// Load the User
$userID = 7;
$user = User::load($userID);

// Set the User's Role. admin in this case.
$user->setRole($adminRole);

// Query the ACL to see if this User can access the somethingAdminish resource.
if ($acl->isAllowed($user, 'somethingAdminish')){

    // Call the somethingAdminish function. Eg:
    somethingAdminish();

    // Log the action and pass the User object in so you can take any information
    // you require from the User data.
    $acl->logAction('somethingAdminish', $user)

}else{
    die('You dont have permission to perform the somethingAdminish action.')
}
jmat
  • 320
  • 2
  • 10