I have an app which has an admin module. I have a beforeControllerAction in my module file to check if user isGuest and if so I redirect them to login. Thats great.
What I have in my users table besides name, email, password, etc. is a field for isAdmin.
If isAdmin=0 they are a ‘user’ and isAdmin=1 they are admin.
I need to be able to restrict ‘users’ from the admin sections, allow admins only. How should I proceed?
In the access controloe set the actions that are only for the admin.
public function accessRules()
{
return array(
array('allow', // allow all users to perform 'index' and 'view' actions
'actions'=>array('index','view'),
'users'=>array('@'),
),
array('allow', // allow authenticated user to perform 'create' and 'update' actions
'actions'=>array('create','update'),
'users'=>array('@'),
),
array('allow', // allow admin user to perform 'admin' and 'delete' actions
'actions'=>array('admin','delete'), // Add all the actions that are performed by the admin only
'users'=>array('admin'),
),
array('deny', // deny all users
'users'=>array('*'),
),
);
}
I did something a bit different. I am not using AccessRules because I want a simple solution to stop all non-admin access to any part of the admin module.
In my users table I have a simple isAdmin flag. 0=user, 1=admin. At login I evaluate the result of that flag and use setState to save user role.
What I ended up doing was using the beforeAction function in my admin base controller. I have two conditions in this function:
If a guest, redirect to login form.
If role is not admin, throw a 403 forbidden.
This way, I have all my other admin controllers inherit from the base controller which effectively locks out non admins without having to use AccessRules at all. Any downside to this approach?
Edit: My base adminController code
public function isOwnerOrAdmin()
{
return ( isset(Yii::app()->user->role) && (Yii::app()->user->role==='admin') ) || ( isset($_GET['id']) && (Yii::app()->user->id==$_GET['id']) );
}
public function beforeAction()
{
if(Yii::App()->user->isGuest) {
$this->redirect(Yii::app()->user->loginUrl);
return false;
} elseif (!$this->isOwnerOrAdmin()) {
throw new CHttpException(403, 'Action is forbidden.');
}
return true;
}
$admins=getAdmins();
// Then use it as
array('allow', // allow admin user to perform 'admin' and 'delete' actions
'actions'=>array('admin','delete'), // Add all the actions that are performed by the admin only
'users'=>$admins,
),
By this, you can also set the access based on user level
Nice solution dniznick, is the one I like to use in my projects.
@PeRoChAk: access rules accept also expression. You can implement a function in WebUser isAdmin, and then check with:
array('allow', // allow admin user to perform 'admin' and 'delete' actions
'actions'=>array('admin','delete'), // Add all the actions that are performed by the admin only
'expression'=>"Yii::app()->user->isAdmin",