Access control based on user level

Hi there,

Yii has a wonderful support for controlling access in either very simple matter (precisely specifying usernames or types - * and @ - directly in accessRules, described in demo application and guide for blog) or a very complex, RBAC access control (described in Definitive Guide and handled by many extensions to Yii).

But can anyone advice me what is the easiest way or best practice to code access control somewhere in between? When user differencing is based on user level specified by tinyint column in DB called level? I can’t use rules (as for RBAC) in this situation, if I’m not mistaken. Should I use AR to generate array holding names of all users in database that have particular level? Like this:


public function accessRules()

{

 	return array

 	(

  	//Allow only specified users to perform user-management operations

  	array

  	(

       	'allow',

       	'actions'=>array('index', 'view', 'create', 'update', 'delete'),

       	'users'=>GoController::generateUserArrayPerLevel(7)

  	),

  	//Deny all other users

  	array

  	(

       	'deny',

       	'users'=>array('*'),

  	),

 	);

}

I have a feeling that this is completely wrong! :confused:

On the login screen you can put the user level in a session like


$this->setState('level',$user->level);

Then on the accessRule you can check for specified level like




...

'users'=>Yii:app()->user->level >= User::LEVELYOUNEED,

...



Where User::LEVELYOUNEED is a constant declared in the User model

for example




const ADMIN 9;

const WRITE 2

const READ 1;

const NONE 0;



Thank you mdomba, very much! :]

Didn’t know that ‘users’ array key might return boolean result. Thought that it has to be subarray of users names. Are you 100% sure this is correct? After you pointed me, where to look for, I read information about CAccessControlFilter and if I’m not mistaken, the example expression you gave me should be put to ‘expression’ array key, not to ‘users’.

And by the way, I have quite similar question. After reading about CAccessControlFilter I also found an optional array key ‘controller’. Am I understanding it correctly that I can have one global accessRules defined in one controller (for example in application default controller) and only bind other controller to it with this key? Of course, if this will satisfy security needs my application have.

What about modules and submodules? If I have ‘admin’ module which holds other administration submodules (all having only one controller called ‘go’), can I define access rules in ‘admin’ module and bind other like for example that:


array

(

...

  'allow',

  'actions'=>array('edit', 'delete'),

  'controllers'=>array('admin/users/go', 'admin/scripts/go', 'admin/config/go'),

...

)



And what about actions? Can I specify in ‘actions’ also actions from binded controlers or only for current controller?

Thank you in advance for clarifying me these problems.

Yes you are right… this goes to ‘expression’ … users can be just authenticated users…

The “controllers” option I haven’t tried yet… but seem to me your thinking is right… best thing to find it out is to try it…

Thank you so much for this info!!!