Bizrule Of Cdbauthmanager

Hi,

I love Yii but I found very ugly to store PHP code that will be processed with eval(), in the bizrule of auth_item and auth_assignment, to manage the logic of auths.

It would be great to have another solution.

Talking about that here and there, I’m not the only one to have this opinion.

What solution are you talking about exactly? PHP anonymous functions aren’t serializables.

In fact I have no idea to replace that behavior :)

But I’m not the only one who will prefer using another way to store auths because of that PHP in DB + eval() process.

Maybe a class passed in parameter to checkAccess, with a method containing the logic of the bizrule.

One can also answer that I can inherit a class from CdbAuthManager, from which checkAccess will do what I want. Maybe…

My first thought on this was a special class with methods or file with callbacks, like




$bizRuleName = function () {};

$bizRuleName2 = function () {};

$bizRuleNameN = function () {};



How would you store bizRule code in DB?

I don’t :) I store in DB only the names of callback or class&method to call, actual code is stored in .php file on the file system.

It could look something like that:




// Class variant

$bizRule = 'BizRuleClass::SiteIndexAction';

list($class, $method) = explode('::', $bizRule);

$result = $class::$method();


// Callback variant

$bizRule = 'bizRuleSiteAction';

// Loads callbacks from file (of course they are cached after first load)

$callbacks = getBizRuleCallbackArray();

$result = $callbacks[$bizRule]();



File with callbacks can look something like this




return array(

    'bizRuleSiteAction' => function () {return;},

    'bizRuleSiteAbout' => function () {return;},

);



Something like that :) It’s not perfect, I know :)

What’s the goal of storing a part of it in DB and another part in PHP files? Why not storing everything in PHP files then?

Question is what you want to achieve. The current implementation provides a maximum of flexibility, you can basically do everything in the biz-rule without having to modify the applications source. So this is kind of a runtime setting, totally independent from your development cycle.

Obviously, this flexibility comes at a price: First of, whoever manages roles and assignments needs to know about the application internals. And he needs at least basic development skills. So it’s most likely not the best option for average users. If we put that aside and say it’s okay, our users will be comfortable with coding their biz-rules (maybe even enjoy the flexibility that approach gives them), we still face security related problems: do you really want your application to execute arbitrary code? If someone manages to inject something into the DB, he can do everything through biz-rules, right? Another thing are app upgrades. The flexible approach of the current design really pins your components API. Since you can’t know which components get used in the biz-rules, you can’t modify them. At least you had to be very careful with component versioning…

Storing only callbacks as biz-rules prevents customized logic at runtime. With this approach, one always had to code some scripts to make them available in the biz-rule. It might be easier to test such scripts against newer app versions (or even in general), but it is in no way friendlier to end users (those who have no idea about programming and just want to use software). I think the same applied if those callbacks would be raised like events ("onExecuteBizRuleXyz" to which you can subscribe).

Something in between might be a “custom” scripting language which would be allowed in biz-rules. Something that is flexible enough to do most common tasks, but nothing that would be considered dangerous. Something like BBCode does for text formatting, but on source code level. Don’t know if there already is something like that. And of course it might be troublesome to learn another language…

Just some thoughts about the topic. Guess it really comes down to what you want to provide. Does anyone know about how other products solve the issue? I only know from joomla, where you don’t have the possibility to specify anything like bizrules.

Really, it’s one of the ugliest things I’ve ever seen in my life.

ekerazha

Alternatives?

Looking at the subject from another perspective: Do we actually need ultimate flexibility? Are there known applications that can’t know what code to execute for a certain authItem/ authAssignment?

I don’t know if flexibility is the problem. It’s more about security. And code maintenance also.

The thing is that even if we know what we put in the bizrule field of the db, who knows if any application flaw won’t allow to inject arbitrary code instead, and it’s especially dangerous because it concerns auths assignments.

Even php.net warns about the eval() function, that should be avoided as much as possible (http://fr2.php.net/manual/fr/function.eval.php).

My idea would be something like in Zend (http://framework.zend.com/manual/1.12/en/zend.acl.advanced.html): a class passed as a parameter to the method that checks the rights (allow() for zend, checkAccess() for Yii), containing the logic of the bizrule.

I think flexibility is the only argument for storing code in DB and using eval() on it. But I doubt that it really is required (although I might miss some use cases, that’s why I asked for examples). In guess in almost all use cases, you know biz-rules while developing your application. You probably want to parameterize them like in the zend-example. But this can be achieved without executing code from DB. Loading the params from DB would be enough. And it would make a better GUI: compare a few inputs for adjusting params against a code editor input for writing biz-rules…

+1

Just a little correction to be precise: in Zend, Zend_Acl::allow() does not check an assignment like checkAccess in Yii, it is Zend_Acl isAllowed() that does the job.

This actually makes sense. I’m, as well, never really encountered any need for very dynamic rules but I think there should be ones actually using it.

Both: serialization and/or having a class/interface name instead of eval’d code for the biz rules make sense for me. In my personal case I’ve used bizrules for Logged/Not logget users only XD

Serialization of anonymous functions can’t be done efficiently in PHP resulting in strings and eval. Even if it would be possile, it’s still a security issue as was mentioned before.

I override CDbAuthManager on my projects to store a name of a AuthRule class that makes the validation instead of store the PHP code on DB.

Works fine to me.

Can’t we make it configurable? One way that uses eval() bizrules and one way that uses custom PHP classes in files.