RBAC: decoupled rules from assignments and items, implemented php manager

This commit is contained in:
Alexander Makarov
2014-04-04 04:40:06 +04:00
parent 4f50295f41
commit 0e6cbda43e
14 changed files with 477 additions and 139 deletions

View File

@@ -0,0 +1,22 @@
<?php
namespace yiiunit\framework\rbac;
use yii\rbac\Rule;
/**
* Checks if authorID matches userID passed via params
*/
class AuthorRule extends Rule
{
public $name = 'isAuthor';
public $reallyReally = false;
/**
* @inheritdoc
*/
public function execute($params, $data)
{
return $params['authorID'] == $params['userID'];
}
}

View File

@@ -8,7 +8,7 @@ use yiiunit\TestCase;
abstract class ManagerTestCase extends TestCase
{
/** @var \yii\rbac\PhpManager|\yii\rbac\DbManager */
/** @var \yii\rbac\Manager */
protected $auth;
public function testCreateItem()
@@ -16,24 +16,24 @@ abstract class ManagerTestCase extends TestCase
$type = Item::TYPE_TASK;
$name = 'editUser';
$description = 'edit a user';
$bizRule = 'checkUserIdentity()';
$ruleName = 'isAuthor';
$data = [1, 2, 3];
$item = $this->auth->createItem($name, $type, $description, $bizRule, $data);
$item = $this->auth->createItem($name, $type, $description, $ruleName, $data);
$this->assertTrue($item instanceof Item);
$this->assertEquals($item->type, $type);
$this->assertEquals($item->name, $name);
$this->assertEquals($item->description, $description);
$this->assertEquals($item->bizRule, $bizRule);
$this->assertEquals($item->ruleName, $ruleName);
$this->assertEquals($item->data, $data);
// test shortcut
$name2 = 'createUser';
$item2 = $this->auth->createRole($name2, $description, $bizRule, $data);
$item2 = $this->auth->createRole($name2, $description, $ruleName, $data);
$this->assertEquals($item2->type, Item::TYPE_ROLE);
// test adding an item with the same name
$this->setExpectedException('\yii\base\Exception');
$this->auth->createItem($name, $type, $description, $bizRule, $data);
$this->auth->createItem($name, $type, $description, $ruleName, $data);
}
public function testGetItem()
@@ -102,7 +102,7 @@ abstract class ManagerTestCase extends TestCase
$this->assertTrue($auth instanceof Assignment);
$this->assertEquals($auth->userId, 'new user');
$this->assertEquals($auth->itemName, 'createPost');
$this->assertEquals($auth->bizRule, 'rule');
$this->assertEquals($auth->ruleName, 'rule');
$this->assertEquals($auth->data, 'data');
$this->setExpectedException('\yii\base\Exception');
@@ -168,14 +168,64 @@ abstract class ManagerTestCase extends TestCase
$this->auth->addItemChild('readPost', 'readPost');
}
public function testExecuteBizRule()
public function testGetRule()
{
$this->assertTrue($this->auth->executeBizRule(null, [], null));
$this->assertTrue($this->auth->executeBizRule('return 1 == true;', [], null));
$this->assertTrue($this->auth->executeBizRule('return $params[0] == $params[1];', [1, '1'], null));
if (!defined('HHVM_VERSION')) { // invalid code crashes on HHVM
$this->assertFalse($this->auth->executeBizRule('invalid;', [], null));
$rule = $this->auth->getRule('isAuthor');
$this->assertInstanceOf('yii\rbac\Rule', $rule);
$this->assertEquals('isAuthor', $rule->name);
$rule = $this->auth->getRule('nonExisting');
$this->assertNull($rule);
}
public function testSaveRule()
{
$ruleName = 'isReallyReallyAuthor';
$rule = new AuthorRule($ruleName, ['reallyReally' => true]);
$this->auth->saveRule($rule);
/** @var AuthorRule $rule */
$rule = $this->auth->getRule($ruleName);
$this->assertEquals($ruleName, $rule->name);
$this->assertEquals(true, $rule->reallyReally);
$rule->reallyReally = false;
$this->auth->saveRule($rule);
/** @var AuthorRule $rule */
$rule = $this->auth->getRule($ruleName);
$this->assertEquals(false, $rule->reallyReally);
}
public function testGetRules()
{
$rule = new AuthorRule('isReallyReallyAuthor', ['reallyReally' => true]);
$this->auth->saveRule($rule);
$rules = $this->auth->getRules();
$ruleNames = [];
foreach ($rules as $rule) {
$ruleNames[] = $rule->name;
}
$this->assertContains('isReallyReallyAuthor', $ruleNames);
$this->assertContains('isAuthor', $ruleNames);
}
public function testRemoveRule()
{
$this->auth->removeRule('isAuthor');
$rules = $this->auth->getRules();
$this->assertEmpty($rules);
}
public function testExecuteRule()
{
$this->assertTrue($this->auth->executeRule(null, [], null));
$this->assertTrue($this->auth->executeRule('isAuthor', ['userID' => 1, 'authorID' => 1], null));
$this->assertFalse($this->auth->executeRule('isAuthor', ['userID' => 1, 'authorID' => 2], null));
}
public function testCheckAccess()
@@ -231,12 +281,14 @@ abstract class ManagerTestCase extends TestCase
protected function prepareData()
{
$this->auth->saveRule(new AuthorRule());
$this->auth->createOperation('createPost', 'create a post');
$this->auth->createOperation('readPost', 'read a post');
$this->auth->createOperation('updatePost', 'update a post');
$this->auth->createOperation('deletePost', 'delete a post');
$task = $this->auth->createTask('updateOwnPost', 'update a post by author himself', 'return $params["authorID"] == $params["userID"];');
$task = $this->auth->createTask('updateOwnPost', 'update a post by author himself', 'isAuthor');
$task->addChild('updatePost');
$role = $this->auth->createRole('reader');

View File

@@ -7,6 +7,7 @@ use yii\rbac\PhpManager;
/**
* @group rbac
* @property \yii\rbac\PhpManager $auth
*/
class PhpManagerTest extends ManagerTestCase
{