I already had an RBAC schema with many authorization items (I’ll omit some details that are not relevant to the question), e.g.:
$auth->createTask('createTask', 'create task');
$auth->createTask('createMaterial', 'create material');
$role = $auth->createRole('manager', 'manager');
$role->addChild('createTask');
$role->addChild('createMaterial');
$auth->assign('manager', 'user1');
And this has worked fine for me so far.
But now it comes another variable into play (and this is why I refer to an “additional RBAC level”): the plan to which the user has subscribed. Let’s suppose these plans are L1 and L2, so that if the user has subscribed to plan L2 he’ll still be able to create tasks as opposed to subscribers to plan L1, which does not include that right.
To make it more interesting let’s say that subscribers to plan L1 can create a maximum of 10 tasks, and introduce a second user: [font=“Courier New”]user1[/font] subscribes to plan L1 and [font=“Courier New”]user2[/font] to plan L2.
At this point I consider two options:
[list=1]
[*]Combine a new set of rules with the existing ones.
[*]Create specific rules for each plan.
[/list]
So the first option would require additional items defined like this:
$auth->createTask('materials', 'materials');
$auth->createTask('tasks', 'tasks');
$auth->assign('tasks', 'user1');
$auth->assign('tasks', 'user2');
$auth->assign('materials', 'user1');
which would need a double check, e.g. in a controller:
if ($user->checkAccess('materials') and $user->checkAccess('createMaterial'))
...
if ($user->checkAccess('tasks') and $user->checkAccess('createTask'))
...
And the second would be completely replaced with:
$auth->createTask('createTask', 'create task');
$task = $auth->createTask('createTask_L1', 'create task for plan L1 subscribers');
$task->addChild('createTask');
$auth->createTask('createMaterial', 'create material');
$role = $auth->createRole('manager_L1', 'manager for plan L1 subscribers');
$role->addChild('createTask_L1');
$role->addChild('createMaterial');
$auth->assign('manager_L1', 'user1');
$task = $auth->createTask('createTask_L2', 'create task for plan L2 subscribers');
$task->addChild('createTask');
$auth->createTask('createMaterial', 'create material');
$role = $auth->createRole('manager_L2', 'manager for plan L2 subscribers');
$role->addChild('createTask_L2');
$role->addChild('createMaterial');
$auth->assign('manager_L2', 'user2');
without the need to rewrite the checkings, e.g. just:
if ($user->checkAccess('createMaterial'))
...
if ($user->checkAccess('createTask'))
...
The second approach looks better because the controllers are not affected and the checking looks more intuitive. But users can switch plan, and in that case I would need to revoke all permissions associated with the source plan to grant those associated with the target plan based on a suffix, i.e. ‘_L1’ and ‘_L2’ and that sets my teeth on edge.
How would you approach this problem? Thanks in advance.