2012.5.11 continue 2
>>> Role-based access control continue 2 <<<
1. 新建管理员,角色将设置为owner 用户名/密码:
root/pass01!!
2. 在mysql命令行执行:
create table pwr_dev_user_role
(
dev_mac char(11) NOT NULL,
user_id char(10) NOT NULL,
role VARCHAR(64) NOT NULL,
primary key (dev_mac,user_id,role),
foreign key (dev_mac) references pwr_device(dev_mac),
foreign key (user_id) references pwr_user (user_id),
foreign key (role) references AuthItem (name)
);
3. create Model and CRUD for table pwr_device,参考log.txt.
4. edit protected/models/Device.php
add following content:
public function associateUserToRole($role, $userId)
{
$sql = "INSERT INTO pwr_dev_user_role (dev_mac, user_id, role) VALUES (:mac, :userId, :role)";
$command = Yii::app()->db->createCommand($sql);
$command->bindValue(":mac", $this->dev_mac, PDO::PARAM_STR);
$command->bindValue(":userId", $userId, PDO::PARAM_STR);
$command->bindValue(":role", $role, PDO::PARAM_STR);
return $command->execute();
}
/**
* removes an association between the project, the user and the user's role within the project
*/
public function removeUserFromRole($role, $userId) {
$sql = "DELETE FROM pwr_dev_user_role WHERE dev_mac=:mac AND user_id=:userId AND role=:role";
$command = Yii::app()->db->createCommand($sql);
$command->bindValue(":mac", $this->dev_mac, PDO::PARAM_STR);
$command->bindValue(":userId", $userId, PDO::PARAM_STR);
$command->bindValue(":role", $role, PDO::PARAM_STR);
return $command->execute();
}
public function isUserInRole($role)
{
$sql = "SELECT role FROM pwr_dev_user_role WHERE dev_mac=:mac AND user_id=:userId AND role=:role";
$command = Yii::app()->db->createCommand($sql);
$command->bindValue(":mac", $this->dev_mac, PDO::PARAM_STR);
$command->bindValue(":userId", Yii::app()->user->getUser_id(), PDO::PARAM_STR);
$command->bindValue(":role", $role, PDO::PARAM_STR);
return $command->execute()==1 ? true : false;
}
/**
* Returns an array of available roles in which a user can be placed when being added to a project
*/
public static function getUserRoleOptions()
{
return CHtml::listData(Yii::app()->authManager->getRoles(), 'name', 'name');
}
/**
* Makes an association between a user and a the project
*/
public function associateUserToDevice($user)
{
$sql = "INSERT INTO pwr_dev_user_role (dev_mac, user_id) VALUES (:mac, :userId)";
$command = Yii::app()->db->createCommand($sql);
$command->bindValue(":mac", $this->dev_mac, PDO::PARAM_STR);
$command->bindValue(":userId", $user->user_id, PDO::PARAM_STR);
return $command->execute();
}
/**
* Determines whether or not a user is already part of a project
*/
public function isUserInDevice($user)
{
$sql = "SELECT user_id FROM pwr_dev_user_role WHERE dev_mac=:mac AND user_id=:userId";
$command = Yii::app()->db->createCommand($sql);
$command->bindValue(":mac", $this->dev_mac, PDO::PARAM_STR);
$command->bindValue(":userId", $user->user_id, PDO::PARAM_STR);
return $command->execute()==1 ? true : false;
}
5. create protected/models/DeviceUserForm.php
as following:
/**
* DeviceUserForm class.
* DeviceUserForm is the data structure for keeping
* the form data related to adding an existing user to a device. It is used by the 'Adduser' action of 'DeviceController'.
*/
class DeviceUserForm extends CFormModel
{
/**
* @var string username of the user being added to the device
*/
public $user_id;
/**
* @var string the role to which the user will be associated within the device
*/
public $role;
/**
* @var object an instance of the Device AR model class
*/
public $device;
/**
* Declares the validation rules.
* The rules state that username and password are required,
* and password needs to be authenticated using the verify() method
*/
public function rules()
{
return array(
// username and password are required
array('user_id, role', 'required'),
// password needs to be authenticated
//array('username', 'verify'),
array('user_id', 'exist', 'className'=>'User'),
array('user_id', 'verify'),
);
}
/**
* Authenticates the existence of the user in the system.
* If valid, it will also make the association between the user,
* role and device * This is the 'verify' validator as declared in rules().
*/
public function verify($attribute,$params)
{
if(!$this->hasErrors()) // we only want to authenticate when no other input errors are present
{
$user = User::model()->findByAttributes(array('user_id'=> $this->user_id));
if($this->device->isUserInDevice($user)) {
$this->addError('username','This user has already been added to the device.');
} else {
$this->device->associateUserToDevice($user);
$this->device->associateUserToRole($this->role, $user->user_id);
$auth = Yii::app()->authManager;
$bizRule='return isset($params["device"]) && $params["device"]->isUserInRole("'.$this->role.'");';
$auth->assign($this->role,$user->user_id, $bizRule);
}
}
}
}
6. add following function to protected/controllers/DeviceController.php
public function actionAdduser()
{
$device = $this->loadModel();
if(!Yii::app()->user->checkAccess('createUser', array('device'=>$device)))
{
throw new CHttpException(403,'You are not authorized to per-form this action.');
}
$form=new DeviceUserForm;
// collect user input data
if(isset($_POST['DeviceUserForm'])) {
$form->attributes=$_POST['DeviceUserForm'];
$form->device = $device; // validate user input and set a sucessfull flassh message if valid
if($form->validate())
{
Yii::app()->user->setFlash('success',$form->user_id . " has been added to the device." );
$form=new DeviceUserForm;
}
}
// display the add user form
$users = User::model()->findAll();
$usernames=array();
foreach($users as $user)
{
$usernames[]=$user->user_id;
}
$form->device = $device;
$this->render('adduser',array('model'=>$form, 'usernames'=>$usernames));
}
7. edit protected/controllers/DeviceController.php
public function accessRules()
{
return array(
array('allow', // allow all users to perform 'index' and 'view' actions
'actions'=>array('index','view','adduser'),
'users'=>array('@'),
),
...
8. create protected/views/device/adduser.php
as following:
$this->pageTitle=Yii::app()->name . ' - Add User To Device';
$this->breadcrumbs=array(
$model->device->dev_mac=>array('view','dev_mac'=>$model->device->dev_mac),
'Add User',
);
$this->menu=array(
array('label'=>'Back To Device',
'url'=>array('view','id'=>$model->device->dev_mac)),
);
?>
Add User To device->dev_mac; ?>
user->hasFlash('success')):?>
user->getFlash('success'); ?>
9. edit protected/views/device/show.php
according from the book, you can do following,but I do not have project
add following lines:
[$model->projectId)); ?>]
10.edit protected/views/device/_view.php
according from the book, you can do following,but I do not have project
$this->menu=array(
array('label'=>'List Project', 'url'=>array('index')),
array('label'=>'Create Project', 'url'=>array('create')),
array('label'=>'Update Project', 'url'=>array('update', 'id'=>$model->id)),
array('label'=>'Delete Project', 'url'=>'#',
'linkOptions'=>array(
'submit'=>array('delete','id'=>$model->id),
'confirm'=>'Are you sure you want to delete this item?'
)
),
array('label'=>'Manage Project', 'url'=>array('admin')),
array('label'=>'Create Issue', 'url'=>array('issue/create', 'pid'=>$model->id)),
);
if(Yii::app()->user->checkAccess('createUser',array('project'=>$model)))
{
$this->menu[] = array(
'label'=>'Add User To Project',
'url'=>array('adduser', 'id'=>$model->id)
);
}
>>> Role-based access control continue 2 <<<