RBAC is not working in yii - php

I have a employee table which it contains emp_id,email,password and roles. I have given user and admin as a value for the field roles. I have also created webuser component which it extends CWebUser. This is my webuser code.
class WebUser extends CWebUser
{
public function checkAccess($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
}
return ($operation === $role);
}
}
This is my UserIdentity code.
class UserIdentity extends CUserIdentity
{
private $_id;
public function authenticate()
{
$user= Employee::model()->find('LOWER(email)=?',array(strtolower($this->username)));
if($user===null)
$this->errorCode=self::ERROR_USERNAME_INVALID;
else if(!$user->validatePassword($this->password))
$this->errorCode=self::ERROR_PASSWORD_INVALID;
else
{
$this->_id=$user->emp_id;
$this->setState('roles',$user->roles);
$this->username=$user->email;
$this->errorCode=self::ERROR_NONE;
}
return $this->errorCode==self::ERROR_NONE;
}
}
This is my controller code.
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'),
'users'=>array('#'),
),
array('allow', // allow admin user to perform 'admin' and 'delete' actions
'actions'=>array('admin','update','delete'),
'roles'=>array('admin'),
),
array('deny', // deny all users
'users'=>array('*'),
),
);
}
It seems everything is fine. But when i try to update then it is not working and i have tried this for a person who have a admin value for the roles. Please correct me if am wrong.

I think problem is in checkAccess - you need to access a model Employee
class WebUser extends CWebUser
{
private $_model = null;
public function getModel(){
if (!$this->isGuest && $this->_model === null) {
$this->_model = Employee::model()->findByPk($this->id);
}
return $this->_model;
}
public function checkAccess($operation, $params=array()){
return $this->model->roles == 'admin';
}
}
If your app will not be compicated this should work.
But better use PhpAuthManager (or DbVersion) with full RBAC support

Related

Authorize users based on roles in CakePHP 3

I would like to authorize users based on few roles. All visitors should be able to reach method show. So I wrote in AppController:
public function beforeFilter(Event $event) {
$this->Auth->allow(['show']);
}
It works.
In initialize() method of AppController I've got also:
$this->loadComponent('Auth', [
'authorize' => 'Controller'
]);
I would like to allow logged users with role "user" to reach all "index", and "add" methods, so I wrote in AppController:
public function isAuthorized($user) {
if (isset($user['role']) && $user['role'] === 'admin') {
return true;
}
if (isset($user['role']) && $user['role'] === 'user') {
$this->Auth->allow(['index', 'logout', 'add']);
}
return false;
}
Admin can reach all methods as expected. User logged with role "user" can't reach "index" or "add" method. How can I fix this?
Instead of using your logic to add additional Auth allows, just use the logic to determine if they're in an action they're allowed, by checking the action, and return true if they're authorized.
public function isAuthorized($user) {
// Admin allowed anywhere
if (isset($user['role']) && $user['role'] === 'admin') {
return true;
}
// 'user' allowed in specific actions
if (isset($user['role']) && $user['role'] === 'user') {
$allowedActions = ['index', 'logout', 'add'];
if(in_array($this->request->action, $allowedActions)) {
return true;
}
}
return false;
}
(obviously this code could be shortened to your liking, but it shows the concept)
I find this solution to be great and easier to maintain.
//in all controllers that you want to restrict access
public function isAuthorized($user)
{
//an array since we might want to add additional roles
$possibleRoles = array('admin');
return $this->confirmAuth($user['role'], $possibleRoles);
}
//in AppController
public function confirmAuth($userRole, $allowedRoles)
{
return in_array($userRole, $allowedRoles);
}

How to assign role and checkaccess method in yii?

I am new in yii for Role Management,
I have 2 Role like Admin1,Admin2
I have 2 controllers and it's action like
(1)UserController - create,update,delete
(2)CategoryController - view,create,update
I want to give checkaccess method for Admin1 like
(1)UserController - update,delete
(2)CategoryController - update
I want to give checkaccess method for Admin2 like
(1)UserController - create,update,delete
(2)CategoryController - create,view
How can i give checkpermission for this 2 controller for particular admin ?
Any help will be really appreciated.
Here is my checkaccess method but it gives me error
class UserIdentity extends CUserIdentity
{
private $_id;
public $role;
public $roleName;
/**
* Authenticates a user.
* #return boolean whether authentication succeeds.
*/
public function authenticate()
{
$username = $this->username;
$password = md5($this->password);
$user=Login_User::model()->findByAttributes(array('Email'=>$username,'Password'=>$password,'Status'=>'1'));
if(empty($user))
{
$this->errorCode=self::ERROR_USERNAME_INVALID;
}
elseif($password != $user->Password)
{
$this->errorCode=self::ERROR_PASSWORD_INVALID;
}
else
{
$this->_id=$user->UserID;
$this->username=$user->Email;
$this->role=$user->RoleID;
$roleQuery = "SELECT * FROM role WHERE RoleID = ".$user->RoleID." ";
$roleData = Yii::app()->db->createCommand($roleQuery)->queryAll();
if(isset($roleData[0]['Title']) && $roleData[0]['Title'] != '') {
$this->roleName = $roleData[0]['Title'];
}
if($user->RoleID != '') {
$query = "SELECT * FROM rolepermission WHERE RoleID = ".$user->RoleID." AND Status = 1 ";
$permissionData = Yii::app()->db->createCommand($query)->queryAll();
}
$auth=Yii::app()->authManager;
$rolePemirssion=$auth->createRole($this->roleName);
foreach($permissionData as $key => $value) {
$rolePemirssion->addChild($value['Controller'].$value['Action']);
}
$this->errorCode=self::ERROR_NONE;
}
return $this->errorCode==self::ERROR_NONE;
}
}
You should use yii access control filters
class UserController extends CController
{
…
public function accessRules()
{
return array(
...
array('allow',
'actions'=>array('update', 'delete'),
'roles'=>array('admin1'),
),
array('allow',
'actions'=>array('update'),
'roles'=>array('admin2'),
),
...
);
}
}
class CategoryController extends CController
{
…
public function accessRules()
{
return array(
...
array('allow',
'actions'=>array('create', 'update', 'delete' ),
'roles'=>array('admin1'),
),
array('allow',
'actions'=>array('create', 'view'),
'roles'=>array('admin2'),
),
...
);
}
}

User Level Access in yii can't run well

I am newbie in yii, I am making an website with yii framework. It is my first time in making USER LEVEL ACCESS. I've created a file EWebUser.php in protected/controllers/, this is my code `
protected function loadUser(){
if ($this->_model === null){
$this->_model= User::model()->findByPk($this->id);
}
return $this->_model;
}
function getLevel(){
$user = $this->loadUser();
if ($user)
return $user->status;
return '';
}
}
then I've also created function namely accessRules in AdminController. This my code
public function accessRules() {
return array(
array('allow',
'actions'=>array('index','delete','btnconf'),
'expression'=>'$user->getLevel()="supadmin"'
)
);
}
`
When I type http://localhost/coretankuyii/index.php/admin/index in URL while I login with user, admin or even has not login can still access it. My hope someone who can access that URL only someone who has status=supadmin. Do you can help me please?
Change the expression to "=="
public function accessRules() {
return array(
array('allow',
'actions'=>array('index','delete','btnconf'),
'expression'=>'$user->getLevel()=="supadmin"'
)
);
}
Or if this does not work try the below
public function accessRules() {
return array(
array('allow',
'actions'=>array('index','delete','btnconf'),
'expression'=>array('AdminController','getLevel');
)
);
}
public function getLevel(){
$user = $this->loadUser();
if($user->status=='supadmin')
return true;
else
return false;
}

Yii Simple RBAC Error

I just a newbie in Yii. I have read http://www.yiiframework.com/wiki/328/simple-rbac/ and followed all instructions there, but I had error User.roles is not defined when I tried to login. Here is my UserIdentity.php
<?php
class UserIdentity extends CUserIdentity
{
private $_id;
public function authenticate()
{
$user = User::model()->findByAttributes(array
('username'=>$this->username));
if($user===null){
$this->errorCode=self::ERROR_USERNAME_INVALID;
}
else{
if($user->password!==$user->encrypt($this->password)){
$this->errorCode=self::ERROR_PASSWORD_INVALID;
}
else{
$this->_id = $user->username;
$this->setState('roles', $user->roles);
$this->errorCode=self::ERROR_NONE;
}
}
return !$this->errorCode;
}
public function getId(){
return $this->_id;
}
}
And then EWebUser.php
<?php
class EWebUser extends CWebUser
{
public function checkAccess($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);
}
}
At last accessRules method in UserController.php
public function accessRules()
{
.....
return array(
array('allow', // allow admin user to perform 'admin' and 'delete' actions
'actions'=>array('admin','delete'),
//'users'=>array('admin'),
'roles'=>array('admin'),
.....
);
}
I hope anyone can help me solve this problwm, thank you very much

How can I specify which field in the user table to be bind to name attribute of the CWebUser?

I found that yii can get and echo the user name by this :
echo Yii::app()->user->name;
my question is how can I specify the field in the table user to be bind with the CWebUser::name
In your config
// application components
'components'=>array(
'user'=>array(
// enable cookie-based authentication
'allowAutoLogin'=>true,
'class'=>'WebUser',
),
WebUser class (example for "email" field from table "user"):
class WebUser extends CWebUser
{
public function getEmail()
{
if(!$this->getState('__email')&&$this->id)
{
$user = User::model()->findByPk($this->id);
$this->setState('__email', $user->email);
}
$state = $this->getState('__email');
return $state;
}
public function login($identity, $duration=0)
{
$this->allowAutoLogin = true;
parent::login($identity, $duration);
$this->id = $identity->id;
if (!$this->isGuest)
{
if($user = User::model()->findByPk($this->id))
{
$this->setState('__email', $user->email);
}
}
}
}
You should write your own UserIdentity component by extending CUserIdentity, and in authenticate() method after user identification declare $this->username = $user->variable;

Categories