Yii-rights params/data for bizrule
Asked Answered
K

2

5

Scenerio:

Using Yii-rights + Yii-user module in my project. In Rights, I generated operations based on my controller action, under update I added a child UpdateOwn.

For UpdateOwn, the bizrule is suppose to be a simple comparison that the logged in user's ID is equal to $model->user_id field.

Problem:

I understand yii checkaccess allow you to pass in variables as parameters and comparing with your defined bizrule. But how does it work for Yii-rights module? How or what are the data/params passed in to be used in bizrule? How can I define or pass my own data/params?

Kruter answered 18/8, 2013 at 14:39 Comment(0)
C
3

The yii-rights module has the following properties:

/**
* @property boolean whether to enable business rules.
*/
public $enableBizRule = true;

/**
* @property boolean whether to enable data for business rules.
*/
public $enableBizRuleData = false;

To set bizrule data via the web interface you have to set $enableBizRuleData = true in your application configuration.

Please note that the UI is limited and you can set data only for Auth-Items not for Auth-Assignments. Also the value for data has to be a serialized PHP variable.

As mentioned by @ineersa you can access $data in unserialized form in your bizRule.

It's also worth noting, that Yii checks first the bizRule for the Auth-Item and then additionally for the Auth-Assignment.

[edit] added example

Auth Item

bizRule

Check if the assignment has all the keys specified in the item data

return BizRule::compareKeys($params, $data, 'Editor');

data

a:1:{s:8:"language";b:1;}

Auth Assignment

Check if the application language matches the assignment data

bizRule

return BizRule::compareApplicationLanguage($params, $data);

data

a:1:{s:8:"language";s:5:"de_de";}

[edit] added code link

Here is the full Helper Code

Cattima answered 28/8, 2013 at 14:10 Comment(3)
So if I need value from say the model, it will be better if I just do it in the PHP rather than in the module UI?Kruter
You can do both, just pass the model (value) as a param. I just created a static helper, because I don't wanted to have lengthy code in my database and I found it also to be more stable, when it comes to updates or additions of the rule logic.Cattima
If you plan on using RController to automatically enforce rights through a filter, then using @schmunk's suggestion, you are in a better position to use a helper class with static method. Note, in that case your filter runs before your action is executed, so $model is not available. But you can use Yii::app()->request->getParam('myparam') in your bizRule to get hold of any query parameters you use to loadup your $model. bizRule="return(User::isOwner($params, $data, Yii::app()->request->getParam('id')));" .. public static function isOwner($params, $data, $userId) { .. }Derange
F
5

Yii-rights is a wrapper for standart yii-rbac. In rights module you have web-interface for your RBAC. When you creating AuthItem (Operation in rights web interface) you can define your own bizrule.

Here is code for creating AuthItem:

$item = $this->_authorizer->createAuthItem($formModel->name, $type, $formModel->description, $formModel->bizRule, $formModel->data);
$item = $this->_authorizer->attachAuthItemBehavior($item);

_authorizer here is an example of RAuthorizer class. Then we go to RDbAuthManager, which extends CDbAuthManager, where we createAuthItem function:

public function createAuthItem($name,$type,$description='',$bizRule=null,$data=null)
    {
        $this->db->createCommand()
            ->insert($this->itemTable, array(
                'name'=>$name,
                'type'=>$type,
                'description'=>$description,
                'bizrule'=>$bizRule,
                'data'=>serialize($data)
            ));
        return new CAuthItem($this,$name,$type,$description,$bizRule,$data);
    } 

This is how created AuthItem, in rights. Personally i prefer to use web interface. It have alot of great fetures and much easier to handle then go to code each time.

Then when we perform checkAccess() on AuthItem we call execute bizRule:

public function executeBizRule($bizRule,$params,$data)
    {
        return $bizRule==='' || $bizRule===null || ($this->showErrors ? eval($bizRule)!=0 : @eval($bizRule)!=0);
    }

This is how RBAC in yii work, and rights is just a cool wrapper for it. Rights doesn't change logic of how things must be done.

So in basic yii-rbac if you want to allow update only Own records you do:

$bizRule='return Yii::app()->user->id==$params["user"]->username;';

$task=$auth->createTask('updateOwnUser','update a your own account',$bizRule);

$task->addChild('updateUser');

Then you call it like this:

$user=$this->loadUser();
$params = array('user' => $user);
if(Yii::app()->user->checkAccess('updateOwnUser', $params){
..................
}

In rights it's already implemented with filters. Only thing what you need to do is add to your controller:

class MyController extends RController{
.............
 public function filters()
    {
        return array(
            'rights', 
            ............
         );
    }
.............
}

So define your bizrule for item in web interface, change your controller code, and actually thats it. To know what variables to use in bizrule you can watch on RightsFilter.php code, where checkAccess() performed.

And on top of all of this i'll say about how checkAccess() does :

  1. For each assigned auth item of the user, it first checks if the bizRule for the assignment returns true.

  2. If true, it calls the item's checkAccess method. If the item's bizRule returns true,

2.1. If the item name is the same as the name passed in the original checkAccess() method, it returns true;

2.2. Otherwise, for every child item, it calls its checkAccess.

Hope this will clarify some aspects of RBAC and help in your task.

Fulvia answered 22/8, 2013 at 14:6 Comment(2)
In RightsFilter.php the line if( $user->checkAccess($authItem)!==true ) doesn't have any thing passed to the params, how do I determine what sort of data is available for me to do a comparison using Rights' web interface Bizrule?Kruter
I just realized there's a data field when creating new authItem. What is available for me to input into that field? Eg. I'm adding Post.UpdateOwn as a child of Post.Update, I will need to throw in the data from Post Model to do comparison in Bizrule, how can I do this?Kruter
C
3

The yii-rights module has the following properties:

/**
* @property boolean whether to enable business rules.
*/
public $enableBizRule = true;

/**
* @property boolean whether to enable data for business rules.
*/
public $enableBizRuleData = false;

To set bizrule data via the web interface you have to set $enableBizRuleData = true in your application configuration.

Please note that the UI is limited and you can set data only for Auth-Items not for Auth-Assignments. Also the value for data has to be a serialized PHP variable.

As mentioned by @ineersa you can access $data in unserialized form in your bizRule.

It's also worth noting, that Yii checks first the bizRule for the Auth-Item and then additionally for the Auth-Assignment.

[edit] added example

Auth Item

bizRule

Check if the assignment has all the keys specified in the item data

return BizRule::compareKeys($params, $data, 'Editor');

data

a:1:{s:8:"language";b:1;}

Auth Assignment

Check if the application language matches the assignment data

bizRule

return BizRule::compareApplicationLanguage($params, $data);

data

a:1:{s:8:"language";s:5:"de_de";}

[edit] added code link

Here is the full Helper Code

Cattima answered 28/8, 2013 at 14:10 Comment(3)
So if I need value from say the model, it will be better if I just do it in the PHP rather than in the module UI?Kruter
You can do both, just pass the model (value) as a param. I just created a static helper, because I don't wanted to have lengthy code in my database and I found it also to be more stable, when it comes to updates or additions of the rule logic.Cattima
If you plan on using RController to automatically enforce rights through a filter, then using @schmunk's suggestion, you are in a better position to use a helper class with static method. Note, in that case your filter runs before your action is executed, so $model is not available. But you can use Yii::app()->request->getParam('myparam') in your bizRule to get hold of any query parameters you use to loadup your $model. bizRule="return(User::isOwner($params, $data, Yii::app()->request->getParam('id')));" .. public static function isOwner($params, $data, $userId) { .. }Derange

© 2022 - 2024 — McMap. All rights reserved.