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'),
),
...
);
}
}
Related
Hi i am new in yii and below is my UserIdentiy function Please let me know how can i add the remember me functionality
public function authenticate()
{
$users = array();
if ($this->usertype == "registration")
{
$users = Login::model()->findByAttributes(array('email' => $this->username));
$users = $users->attributes;
}
if (empty($users)) $this->errorCode = self::ERROR_USERNAME_INVALID;
elseif (!empty($users['password']) && $users['password'] !== md5($this->password))
$this->errorCode = self::ERROR_PASSWORD_INVALID;
elseif (!empty($users['status']) && $users['status'] !== 1)
$this->errorCode = self::STATUS_NOT_ACTIVE;
else
{
$this->_id = $users->id;
$this->errorCode = self::ERROR_NONE;
}
return !$this->errorCode;
}
In protected\config\main.php configuration array is present in that array go to component index. Inside of that user array has associative indexed value 'allowAutoLogin' must have the boolean value true
So it should look like this
'components' => array(
'user' => array(
// enable cookie-based authentication
'allowAutoLogin' => true,
),
...
And You have to use the following property along with login method given below you can achieve remember me easily.
class LoginForm extends CFormModel
{
public $username;
public $password;
public $rememberMe;
private $_identity;
login method should be like this in Login model class
public function login()
{
if($this->_identity===null)
{
$this->_identity=new UserIdentity($this->username, $this->password);
$this->_identity->authenticate();
}
if($this->_identity->errorCode===UserIdentity::ERROR_NONE)
{
$duration=$this->rememberMe ? 3600*24*30 : 0; // 30 days
Yii::app()->user->login($this->_identity,$duration);
return true;
}
else
return false;
}
And this the core code to remember function
Yii::app()->user->login($this->_identity,$duration);
Here
/**
* LoginForm class.
* LoginForm is the data structure for keeping
* user login form data. It is used by the 'login' action of 'SiteController'.
*/
class LoginFormUser extends CFormModel {
public $Username;
public $password;
public $rememberMe;
private $_identity;
// public $verifyCode;
public $verifyCode;
/**
* Declares the validation rules.
* The rules state that Username and password are required,
* and password needs to be authenticated.
*/
public function rules() {
return array(
// Username and password are required
array('Username, password', 'required'),
// rememberMe needs to be a boolean
array('rememberMe', 'boolean'),
// password needs to be authenticated
array('password', 'authenticate', 'skipOnError' => true),
// array('verifyCode', 'CaptchaExtendedValidator', 'allowEmpty'=>!CCaptcha::checkRequirements()),
// array('verifyCode', 'required'),
// array('verifyCode', 'application.extensions.yiiReCaptcha.ReCaptchaValidator'),
);
}
/**
* Declares attribute labels.
*/
public function attributeLabels() {
return array(
'rememberMe' => 'Remember me next time',
'Username' => 'User name',
'password' => 'Password',
// 'verifyCode'=> 'verify Code',
);
}
/**
* Authenticates the password.
* This is the 'authenticate' validator as declared in rules().
*/
public function authenticate($attribute,$params)
{
if(!$this->hasErrors())
{
$this->_identity=new UserIdentity($this->Username,$this->password);
$dataAuthenticate = $this->_identity->authenticate();
if($dataAuthenticate == 1)
$this->addError('Username','username is invalid');
elseif($dataAuthenticate == 2)
$this->addError('password','password is invalid');
elseif($dataAuthenticate === 'lock')
$this->addError('Username', 'Your account has been locked for violating the policy');
elseif($dataAuthenticate == 3)
$this->addError('Username', 'Your account have been locked login in 15 minutes!');
}
}
/**
* Logs in the user using the given Username and password in the model.
* #return boolean whether login is successful
*/
public function login() {
if ($this->_identity === null) {
$this->_identity = new UserIdentity($this->Username, $this->password);
$this->_identity->authenticate();
}
if ($this->_identity->errorCode === UserIdentity::ERROR_NONE) {
$duration=$this->rememberMe ? 3600*24*30 : 0; // 30 days
// if($this->rememberMe == true){
// $duration=3600*24*30; // 30 days
// }else {
// $duration = 0;
// }
Yii::app()->user->login($this->_identity,$duration);
// $get_cookie_first = Yii::app()->request->cookies['loginCookie']->value;
// $cookie = new CHttpCookie('loginCookie', $get_cookie_first);
// $cookie->expire = time() + $duration;
// Yii::app()->request->cookies['loginCookie'] = $cookie;
return true;
}
else
return false;
}
}
We have integrated the yii authenticate acceess rules. In the login page, after submit the
form, it displays the following error message shows
Fatal error: Call to undefined method LoginForm::model() in D:\wamp\www\onlinetest\protected\components\UserIdentity.php on line 13
Here is the controller code
public function actionLogin()
{
$model=new LoginForm;
// if it is ajax validation request
if(isset($_POST['ajax']) && $_POST['ajax']==='login-form')
{
echo CActiveForm::validate($model);
Yii::app()->end();
}
// collect user input data
if(isset($_POST['LoginForm']))
{
$model->attributes=$_POST['LoginForm'];
// validate user input and redirect to the previous page if valid
if($model->validate() && $model->login())
$this->redirect(Yii::app()->user->returnUrl);
}
// display the login form
$this->render('login',array('model'=>$model));
}
Here is the login form model
class LoginForm extends CFormModel
{
public $username;
public $password;
public $rememberMe;
private $_identity;
public function tableName()
{
return 'tbl_login';
}
public function authenticate($attribute,$params)
{
if(!$this->hasErrors()) // we only want to authenticate when no input errors
{
$identity=new UserIdentity($this->username,$this->password);
$identity->authenticate();
switch($identity->errorCode)
{
case UserIdentity::ERROR_NONE:
Yii::app()->user->login($identity);
break;
case UserIdentity::ERROR_USERNAME_INVALID:
$this->addError('username','Username is incorrect.');
break;
default: // UserIdentity::ERROR_PASSWORD_INVALID
$this->addError('password','Password is incorrect.');
break;
}
}
}
public function login()
{
if($this->_identity===null)
{
$this->_identity=new UserIdentity($this->username,$this->password);
$this->_identity->authenticate();
}
if($this->_identity->errorCode===UserIdentity::ERROR_NONE)
{
$duration=$this->rememberMe ? 3600*24*30 : 0; // 30 days
Yii::app()->user->login($this->_identity,$duration);
return true;
}
else
return false;
}
}
Here is the useridentity.php in components
class UserIdentity extends CUserIdentity
{
private $_id;
public function authenticate()
{
$record=LoginForm::model()->findByAttributes(array('VarUser_type'=>$this->username)); // here I use Email as user name which comes from database
if($record===null)
{
$this->_id='user Null';
$this->errorCode=self::ERROR_USERNAME_INVALID;
}
else if($record->E_PASSWORD!==$this->password) // here I compare db password with passwod field
{ $this->_id=$this->username;
$this->errorCode=self::ERROR_PASSWORD_INVALID;
}
else
{
$this->_id=$record['VarUser_type'];
$this->setState('title', $record['VarUser_type']);
$this->errorCode=self::ERROR_NONE;
}
return !$this->errorCode;
}
public function getId() // override Id
{
return $this->_id;
}
}
How can I fix this issue? If you know help me
you can njot use
$record=LoginForm::model()->findByAttributes(array('VarUser_type'=>$this->username));
because LoginForm extends CFormModel
for database retrival it should extends CActiveRecord
see this
see this
your model should be like this
class Users extends CActiveRecord
{
/**
* Returns the static model of the specified AR class.
* #return Users the static model class
*/
private $_identity;
public static function model($className=__CLASS__)
{
return parent::model($className);
}
/**
* #return string the associated database table name
*/
public function tableName()
{
return 'users';
}
/**
* #return array validation rules for model attributes.
*/
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array(' password, user_name,' , 'required', 'on'=>'login' ),
array('user_id, last_name, first_name, address1, address2, city, pincode, state_id, country_id, phone, fax, email, created_date, updated_date, last_login, company_name, tour_id, password, user_name, last_login_from, gender, is_session_on, status, memo, cell, role_type_id, group_contract_template_id, group_policy_id, billing_contact, billing_phone, billing_address, billing_email, after_hours_phone', 'safe', 'on'=>'search'),
);
}
/**
* #return array relational rules.
*/
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
);
}
public function login( $id, $password = "" )
{
$this->_identity = new UserIdentity($username = $id ,$password);
$this->_identity->authenticate();
//Yii::app()->user->login($this->_identity,3600*24*30);
if(Yii::app()->user->login($this->_identity,0*0*0))
{
//echo $this->_identity->errorMessage;
return true;
}
else
{
Yii::app()->user->setState('error', $this->_identity->errorMessage);
return false;
}
}
/**
* #return array customized attribute labels (name=>label)
*/
public function attributeLabels()
{
return array(
'user_id' => 'User',
'last_name' => 'Last Name',
'first_name' => 'First Name',
'address1' => 'Address1',
'email' => 'Email',
);
}
/**
* Retrieves a list of models based on the current search/filter conditions.
* #return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
*/
public function search()
{
// Warning: Please modify the following code to remove attributes that
// should not be searched.
$criteria=new CDbCriteria;
$criteria->compare('user_id',$this->user_id,true);
$criteria->compare('last_name',$this->last_name,true);
$criteria->compare('first_name',$this->first_name,true);
$criteria->compare('email',$this->billing_address,true);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
}
you don't have included the code for model method
public static function model($className=__CLASS__)
{
return parent::model($className);
}
in your model class
Your UserIdentity class method authenticate is incorrect.. Refer to the code below to see how.
public function authenticate()
{
$record=YourUserModel::model()->find(array(
'condition'=>'VarUser_type =:username',
'params'=>array(':username'=>$this->username)
));
if($record===null)
{
$this->_id='user Null';
$this->errorCode=self::ERROR_USERNAME_INVALID;
}
else if($record->E_PASSWORD!==$this->password) // here I compare db password with passwod field
{ $this->_id=$this->username;
$this->errorCode=self::ERROR_PASSWORD_INVALID;
}
else
{
$this->_id=$record['VarUser_type'];
$this->setState('title', $record['VarUser_type']);
$this->errorCode=self::ERROR_NONE;
}
return !$this->errorCode;
}
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
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
I am trying to open a login form on my site. I have written code but some how it's not working.
The problem is that the login form does not return any error or mesage, it only redirects me to the login page.
Also, for some reason the checklogin function is not working.
controller/main:
public function actionLogin()
{
$model = new LoginForm;
$this->render('login',array('model'=>$model));
}
model/LoginForm:
class LoginForm extends CFormModel
{
public $email;
public $password;
private $_identity;
public function rules()
{
return array(
array('email, password', 'required', 'message' => 'error'),
array('email', 'email', 'allowEmpty' => false, 'checkMX' => true, 'message' => 'error'),
array('password', 'authenticate')
);
}
public function authenticate($attribute,$params)
{
$this->_identity = Account::model()->checkLogin($this->email, $this->password);
if(!$this->_identity)
$this->addError('password', 'error');
}
}
model/account:
public static function model()
{
return parent::model(__CLASS__);
}
public function tableName()
{
return 'table';
}
public function primaryKey()
{
return 'id';
}
public function checkLogin($email, md5($password))
{
$user = $this->findByAttributes(array('email' => $email, 'password' => $password));
if($user===null)
{
return false;
}
return false;
views/main/login:
<?php $form=$this->beginWidget('CActiveForm', array('action' => Yii::app()->createUrl('login'))); ?>
<table>
<tr><?php echo $form->errorSummary($model); ?></tr>
<tr> <?php echo $form->emailField($model,'email'); ?></tr>
<tr><?php echo $form->passwordField($model,'password'); ?></tr>
<tr><?php echo CHtml::submitButton('Login'); ?></tr>
</table>
<?php $this->endWidget(); ?>
To implement your authentication you must follow the steps below:
First in your action:
public function actionLogin() {
$model = new LoginForm();
if (isset($_POST['LoginForm'])) {
if (CActiveForm::validate($model) && $model->validate() && $model->login()) {
// Authentication DONE
} else {
//TRY TO GET ERRORS
}
}
}
In your model add the login function:
public function login() {
/*
* if identity property had no value, here we initialize
* identity property
*/
if ($this->identity === null) {
$this->identity = new UserIdentity($this->username, $this->password);
//authenticating
$this->identity->authenticate();
} else {
/*
* if error code was NONE, it means user has been successfully
* authenticated.
*/
if ($this->identity->errorCode === UserIdentity::ERROR_NONE) {
Yii::app()->user->login($this->identity);
return true;
}
}
}
and in your model's authentication method:
public function authenticate() {
//if validation was done and we had no error while validating
if (!$this->hasErrors()) {
//new instance of identity class
$this->identity = new UserIdentity($this->username, $this->password);
if (!$this->identity->authenticate()) {
$this->addError('password', Yii::t('app', 'Invalid Username or Password'));
}
}
}
Then you need to add UserIdentity Class (Put this class in your components directory)
class UserIdentity extends CUserIdentity {
private $_id;
private $_username;
public function authenticate() {
$record = Account::model()->findByAttributes(array(
'username' => $this->username
));
if ($record === null) {
//adds error to user
$this->errorCode = self::ERROR_USERNAME_INVALID;
//authentication failed
return false;
} else if (!CPasswordHelper::verifyPassword($this->password, $record->password)) {
$this->errorCode = self::ERROR_PASSWORD_INVALID;
return false;
} else {
/*
* no error
* user information[username and password are valid]
*/
$this->errorCode = self::ERROR_NONE;
//user's id whitch will be accessible through Yii::app()->user->id
$this->_id = $record->id;
//user's username whitch will be accessible through Yii::app()->user->name
$this->_username = $record->username;
//success
return true;
}
}
/**
* Overriding CUserIdentity's getId() method
* #access public
* #return integer user id
*/
public function getId() {
return $this->_id;
}
/**
* Overriding CUserIdentity's getName() method
* #access public
* #return string username
*/
public function getName() {
return $this->_username;
}
Change checklogin function as given below and try again to fix this.
public function checkLogin($email, md5($password))
{
$user = $this->model()->findByAttributes(array('email' => $email, 'password' => $password));
if($user===null)
{
return false;
}
return false;
}
If you are trying to implement the login functionality separately, then you are missing the whole logic to register the user's auth details using the Yii::app()->login()dependent on the CUserIdentity class.
Master this link -> http://www.yiiframework.com/doc/guide/1.1/en/topics.auth and proceed for post authentication.