mirror of
				https://github.com/yiisoft/yii2.git
				synced 2025-11-04 14:46:19 +08:00 
			
		
		
		
	Enhanced RBAC Rule assignment
* #11254 Enhanced RBAC Rule assignment * Enhanced RBAC Rule assignment
This commit is contained in:
		
				
					committed by
					
						
						Alexander Makarov
					
				
			
			
				
	
			
			
			
						parent
						
							bfa7c7b13b
						
					
				
				
					commit
					0e17d652dc
				
			@ -48,6 +48,7 @@ Yii Framework 2 Change Log
 | 
				
			|||||||
- Enh #11137: Added weak ETag support to `yii\filters\HttpCache`. It could be turned on via setting `$weakEtag` to `true` (particleflux)
 | 
					- Enh #11137: Added weak ETag support to `yii\filters\HttpCache`. It could be turned on via setting `$weakEtag` to `true` (particleflux)
 | 
				
			||||||
- Enh #11139: `yii\validators\EachValidator` injects specific attribute value in error message parameters (silverfire)
 | 
					- Enh #11139: `yii\validators\EachValidator` injects specific attribute value in error message parameters (silverfire)
 | 
				
			||||||
- Enh #11187: migrate command now generates phpdoc for table migrations (Faryshta)
 | 
					- Enh #11187: migrate command now generates phpdoc for table migrations (Faryshta)
 | 
				
			||||||
 | 
					- Enh #11254: Added ability to attach RBAC rule using class name (mdmunir)
 | 
				
			||||||
- Enh: Added `StringHelper::countWords()` that given a string returns number of words in it (samdark)
 | 
					- Enh: Added `StringHelper::countWords()` that given a string returns number of words in it (samdark)
 | 
				
			||||||
- Chg: HTMLPurifier dependency updated to `~4.6` (samdark)
 | 
					- Chg: HTMLPurifier dependency updated to `~4.6` (samdark)
 | 
				
			||||||
- Chg #10726: Added `yii\rbac\ManagerInterface::canAddChild()` (dkhlystov, samdark)
 | 
					- Chg #10726: Added `yii\rbac\ManagerInterface::canAddChild()` (dkhlystov, samdark)
 | 
				
			||||||
 | 
				
			|||||||
@ -115,6 +115,11 @@ abstract class BaseManager extends Component implements ManagerInterface
 | 
				
			|||||||
    public function add($object)
 | 
					    public function add($object)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if ($object instanceof Item) {
 | 
					        if ($object instanceof Item) {
 | 
				
			||||||
 | 
					            if ($object->ruleName && $this->getRule($object->ruleName) === null) {
 | 
				
			||||||
 | 
					                $rule = \Yii::createObject($object->ruleName);
 | 
				
			||||||
 | 
					                $rule->name = $object->ruleName;
 | 
				
			||||||
 | 
					                $this->addRule($rule);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            return $this->addItem($object);
 | 
					            return $this->addItem($object);
 | 
				
			||||||
        } elseif ($object instanceof Rule) {
 | 
					        } elseif ($object instanceof Rule) {
 | 
				
			||||||
            return $this->addRule($object);
 | 
					            return $this->addRule($object);
 | 
				
			||||||
@ -143,6 +148,11 @@ abstract class BaseManager extends Component implements ManagerInterface
 | 
				
			|||||||
    public function update($name, $object)
 | 
					    public function update($name, $object)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if ($object instanceof Item) {
 | 
					        if ($object instanceof Item) {
 | 
				
			||||||
 | 
					            if ($object->ruleName && $this->getRule($object->ruleName) === null) {
 | 
				
			||||||
 | 
					                $rule = \Yii::createObject($object->ruleName);
 | 
				
			||||||
 | 
					                $rule->name = $object->ruleName;
 | 
				
			||||||
 | 
					                $this->addRule($rule);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            return $this->updateItem($name, $object);
 | 
					            return $this->updateItem($name, $object);
 | 
				
			||||||
        } elseif ($object instanceof Rule) {
 | 
					        } elseif ($object instanceof Rule) {
 | 
				
			||||||
            return $this->updateRule($name, $object);
 | 
					            return $this->updateRule($name, $object);
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										16
									
								
								tests/framework/rbac/ActionRule.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								tests/framework/rbac/ActionRule.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,16 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace yiiunit\framework\rbac;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Description of ActionRule
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					class ActionRule extends \yii\rbac\Rule
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public $name = 'action_rule';
 | 
				
			||||||
 | 
					    public $action = 'read';
 | 
				
			||||||
 | 
					    public function execute($user, $item, $params)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->action === 'all' || $this->action === $params['action'];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -387,4 +387,68 @@ abstract class ManagerTestCase extends TestCase
 | 
				
			|||||||
        $this->assertNotEmpty($this->auth->getRules());
 | 
					        $this->assertNotEmpty($this->auth->getRules());
 | 
				
			||||||
        $this->assertNotEmpty($this->auth->getRoles());
 | 
					        $this->assertNotEmpty($this->auth->getRoles());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function testAssignRule()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $auth = $this->auth;
 | 
				
			||||||
 | 
					        $userId = 3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $auth->removeAll();
 | 
				
			||||||
 | 
					        $role = $auth->createRole('Admin');
 | 
				
			||||||
 | 
					        $auth->add($role);
 | 
				
			||||||
 | 
					        $auth->assign($role, $userId);
 | 
				
			||||||
 | 
					        $this->assertTrue($auth->checkAccess($userId, 'Admin'));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // with normal register rule
 | 
				
			||||||
 | 
					        $auth->removeAll();
 | 
				
			||||||
 | 
					        $rule = new ActionRule();
 | 
				
			||||||
 | 
					        $auth->add($rule);
 | 
				
			||||||
 | 
					        $role = $auth->createRole('Reader');
 | 
				
			||||||
 | 
					        $role->ruleName = $rule->name;
 | 
				
			||||||
 | 
					        $auth->add($role);
 | 
				
			||||||
 | 
					        $auth->assign($role, $userId);
 | 
				
			||||||
 | 
					        $this->assertTrue($auth->checkAccess($userId, 'Reader', ['action' => 'read']));
 | 
				
			||||||
 | 
					        $this->assertFalse($auth->checkAccess($userId, 'Reader', ['action' => 'write']));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // using rule class name
 | 
				
			||||||
 | 
					        $auth->removeAll();
 | 
				
			||||||
 | 
					        $role = $auth->createRole('Reader');
 | 
				
			||||||
 | 
					        $role->ruleName = 'yiiunit\framework\rbac\ActionRule';
 | 
				
			||||||
 | 
					        $auth->add($role);
 | 
				
			||||||
 | 
					        $auth->assign($role, $userId);
 | 
				
			||||||
 | 
					        $this->assertTrue($auth->checkAccess($userId, 'Reader', ['action' => 'read']));
 | 
				
			||||||
 | 
					        $this->assertFalse($auth->checkAccess($userId, 'Reader', ['action' => 'write']));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // using DI
 | 
				
			||||||
 | 
					        \Yii::$container->set('write_rule', ['class' => 'yiiunit\framework\rbac\ActionRule', 'action' => 'write']);
 | 
				
			||||||
 | 
					        \Yii::$container->set('delete_rule', ['class' => 'yiiunit\framework\rbac\ActionRule', 'action' => 'delete']);
 | 
				
			||||||
 | 
					        \Yii::$container->set('all_rule', ['class' => 'yiiunit\framework\rbac\ActionRule', 'action' => 'all']);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $role = $auth->createRole('Writer');
 | 
				
			||||||
 | 
					        $role->ruleName = 'write_rule';
 | 
				
			||||||
 | 
					        $auth->add($role);
 | 
				
			||||||
 | 
					        $auth->assign($role, $userId);
 | 
				
			||||||
 | 
					        $this->assertTrue($auth->checkAccess($userId, 'Writer', ['action' => 'write']));
 | 
				
			||||||
 | 
					        $this->assertFalse($auth->checkAccess($userId, 'Writer', ['action' => 'update']));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $role = $auth->createRole('Deleter');
 | 
				
			||||||
 | 
					        $role->ruleName = 'delete_rule';
 | 
				
			||||||
 | 
					        $auth->add($role);
 | 
				
			||||||
 | 
					        $auth->assign($role, $userId);
 | 
				
			||||||
 | 
					        $this->assertTrue($auth->checkAccess($userId, 'Deleter', ['action' => 'delete']));
 | 
				
			||||||
 | 
					        $this->assertFalse($auth->checkAccess($userId, 'Deleter', ['action' => 'update']));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $role = $auth->createRole('Author');
 | 
				
			||||||
 | 
					        $role->ruleName = 'all_rule';
 | 
				
			||||||
 | 
					        $auth->add($role);
 | 
				
			||||||
 | 
					        $auth->assign($role, $userId);
 | 
				
			||||||
 | 
					        $this->assertTrue($auth->checkAccess($userId, 'Author', ['action' => 'update']));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // update role and rule
 | 
				
			||||||
 | 
					        $role = $auth->getRole('Reader');
 | 
				
			||||||
 | 
					        $role->name = 'AdminPost';
 | 
				
			||||||
 | 
					        $role->ruleName = 'all_rule';
 | 
				
			||||||
 | 
					        $auth->update('Reader', $role);
 | 
				
			||||||
 | 
					        $this->assertTrue($auth->checkAccess($userId, 'AdminPost', ['action' => 'print']));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user