unchanged
Title
Simple RBAC
If youare the one whoneed simple Role based access control without the long RBAC process then this article is just for you. Lets jump to the point.On your## The usertable make a column named 'roles'modelWhen you add users you can assign them different roles like 'Admin' / 'user' / 'staff' etc etc.On your user table make a column named 'roles'. Create the model accordingly. It will be named "User" here.On your UserIdentity.php file write something like..When you add users you can assign them a role among 'admin', 'user', 'staff' etc etc. ## The authentication In the file "protected/components/UserIdentity.php" write something like: ~~~ [php] class UserIdentity extends CUserIdentity { private $id; public function authenticate() { $record=User::model()->findByAttributes(array('email'=>$this->username)); if($record===null) $this->errorCode=self::ERROR_USERNAME_INVALID; else if($record->password!==md5($this->password)) $this->errorCode=self::ERROR_PASSWORD_INVALID; else { $this->id=$record->id; $this->setState('roles', $record->roles); $this->errorCode=self::ERROR_NONE; } return !$this->errorCode; } public function getId(){ return $this->id; } } ~~~ The important line is$this->setState('roles', $record->roles);`$this->setState('roles', $record->roles);` It adds user roles to their session. You can fetch the role of the current user with `Yii::app()->user->getState('roles')` or simply `Yii::app()->user->roles`.You are just adding user roles to their session. Now, make a Utils.php file under protected/components directory and implement a simple Role check function based on how many roles you have.## Checking permissions: structure Modify or create the "WebUser.php" file under the "protected/components" directory so that it overloads the `checkAccess()` method. ~~~ [php] <?phpclass Utils{ public function isAdmin(){ if(Yii::app()->user->isGuest) return false; else if(Yii::app()->user->roles == 'Admin') return true; else return false; }class WebUser extends CWebUser { /** * Overrides a Yii method that is used for roles in controllers (accessRules). * * @param string $operation Name of the operation required (here, a role). * @param mixed $params (opt) Parameters for this operation, usually the object to access. * @return bool Permission granted? */ public functionisUser(){ if(Yii::app()->user->isGuest) return false; else if(Yii::app()->user->roles == 'User') return true; elsecheckAccess($operation, $params=array()) { if (empty($this->id)) { // Not identified => no rights return false; } $role = $this->getState("roles"); if ($role === 'admin') { return true; // admin role has access to everything } // allow access if the operation request is the current user's role return ($operation === $role); } } ~~~ You can define your own logic in this `checkAccess()` methods. **Make sure this class is used by Yii.** The config file "protected/config/main.php" must contain:?>~~~ [php] 'components' => array( // ... 'user' => array( 'class' => 'WebUser', ), ~~~And now, from your controller accessRules() function try something like*Sidenote:* [CWebUser::checkAccess()] usually connects to the authorization system loaded in Yii. Here we are replacing it with a simple system that just deals with roles instead of the hierarchical system defined by the derivatives of [CAuthManager]. See the official tutorial, [http://www.yiiframework.com/doc/guide/1.1/en/topics.auth#role-based-access-control](Role-Based Access Control) for details. ## Checking permissions: usage * In your PHP code, use `Yii::app()->user->checkAccess('admin')` to check if the current user has the 'admin' role. The call `Yii::app()->user->checkAccess('staff')` will return true if the user has the role "staff" or "admin". * In your controller, you can filter with `accessRules()` using the "roles" attribute of the rule. See examples below. ### How to filter access to actions The controller must contain: ~~~ [php] public function filters() { return array( 'accessControl', // perform access control for CRUD operations ); } public function accessRules() { return array( array('allow','controllers'=>array('admin'), 'expression'=>'Utils::isAdmin()','action'=>array('admin'), 'roles'=>array('staff', 'devel'), ), array('deny', // deny all users 'users'=>array('*'), ), ); } ~~~ HereI just protect my AdminController.php from otherthe "admin" action of the controller has restricted access: only those with rolesthan Admin. Basically from AdminController.php file accessRules() function it checks"staff" or "devel" can access it. As described in theusers Roles writtenAPI doc of [http://www.yiiframework.com/doc/api/1.1/CAccessRule#roles-detail](CAccessRule), the "roles" attribute will inUtils.php file.fact call `Yii::app()->user->checkAccess()`. ### How to display a different menu according to roles You can also use just one menu for all users based upon different roles. for example ~~~ [php] <?php$this->widget('zii.widgets.CMenu',array( 'items'=>array( array('label'=>'Users',$user = Yii::app()->user; // just a convenience to shorten expressions $this->widget('zii.widgets.CMenu',array( 'items'=>array( array('label'=>'Users', 'url'=>array('/manageUser/admin'),'visible'=>Utils::isAdmin()), array('label'=>'Ideas', 'url'=>array('/manageIdea/admin'), 'visible'=>Utils::isAdmin()), array('label'=>'Page Editor', 'url'=>array('/admin/pageeditor'), 'visible'=>Utils::isAdmin()), array('label'=>'Your'visible'=>$user->checkAcces('staff')), array('label'=>'Your Ideas', 'url'=>array('/userarea/ideaList'),'visible'=>Utils::isUser()), array('label'=>'Add new idea', 'url'=>array('/userarea/create'), 'visible'=>Utils::isUser()), array('label'=>'Login','visible'=>$user->checkAcces('normal')), array('label'=>'Login', 'url'=>array('/site/login'),'visible'=>Yii::app()->user->isGuest), array('label'=>'Logout'visible'=>$user->isGuest), array('label'=>'Logout ('.Yii::app()->user->name.')', 'url'=>array('/site/logout'),'visible'=>!Yii::app()->user->isGuest) ), )); ?>'visible'=>!$user->isGuest) ), )); ?> ~~~I hope## Going further: access context A very usual need is to allow a user to update its own data but not other's. In thislittle codecase, the user's role is meaningless without the context: the data that willhelp yoube modified. This is why [CWebUser::checkAccess()] has an optional "$param" parameter. Now suppose we want to check is a user has the right to update a Post record. We can write: ~~~ [php] if (Yii::app()->user->checkAccess('normal', $post)) { ~~~ThanksOf course `WebUser::checkAccess()` must be extended to use this "$params" parameter. This will depend on your application's logic. For instance, it could be as simple as granting access iff `$post->userId == $this->id`.