Role-based access control continue 2

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'); ?>
   


 

beginWidget('CActiveForm'); ?>
   

Fields with * are required.


       

             labelEx($model,'user_id'); ?>
             widget('CAutoComplete', array(
                 'model'=>$model,
                 'attribute'=>'user_id',
                 'data'=>$usernames,
                 'multiple'=>false,
                 'htmlOptions'=>array('size'=>25),
             )); ?>
             error($model,'user_id'); ?>
       

 
       

            labelEx($model,'role'); ?>
            dropDownList($model,'role', Device::getUserRoleOptions()); ?>
            error($model,'role'); ?>
       

 
       

           
       

endWidget(); ?>


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 <<<


你可能感兴趣的:(Role-based access control continue 2)