diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index f157eb24317..c0d0b076829 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -63,6 +63,7 @@ Yii Framework 2 Change Log - Enh #12748: Added Migration tool automatic generation reference column for foreignKey (MKiselev) - Enh #12748: Migration generator now tries to fetch reference column name for foreignKey from schema if it's not set explicitly (MKiselev) - Enh #12750: `yii\widgets\ListView::itemOptions` can be a closure now (webdevsega, silverfire) +- Enh #12771: Skip \yii\rbac\PhpManager::checkAccessRecursive and \yii\rbac\DbManager::checkAccessRecursive if role assignments are empty (Ni-san) - Enh #12790: Added `scrollToErrorOffset` option for `yii\widgets\ActiveForm` which adds ability to specify offset in pixels when scrolling to error (mg-code) - Enh #12798: Changed `yii\cache\Dependency::getHasChanged()` (deprecated, to be removed in 2.1) to `yii\cache\Dependency::isChanged()` (dynasource) - Enh #12807: Added console controller checks for `yii\console\controllers\HelpController` (schmunk42) diff --git a/framework/rbac/BaseManager.php b/framework/rbac/BaseManager.php index 98460ff198d..f1e4b318614 100644 --- a/framework/rbac/BaseManager.php +++ b/framework/rbac/BaseManager.php @@ -222,4 +222,16 @@ protected function executeRule($user, $item, $params) throw new InvalidConfigException("Rule not found: {$item->ruleName}"); } } + + /** + * Checks whether $assignments array is empty and [[defaultRoles]] are empty as well. + * + * @param Assignment[] $assignments array of user's assignments + * @return bool whether $assignments array is empty and [[defaultRoles]] are empty as well + * @since 2.0.11 + */ + protected function hasNoAssignments(array $assignments) + { + return empty($assignments) && empty($this->defaultRoles); + } } diff --git a/framework/rbac/DbManager.php b/framework/rbac/DbManager.php index b38d5fecad7..1935bdf6e6b 100644 --- a/framework/rbac/DbManager.php +++ b/framework/rbac/DbManager.php @@ -121,6 +121,11 @@ public function init() public function checkAccess($userId, $permissionName, $params = []) { $assignments = $this->getAssignments($userId); + + if ($this->hasNoAssignments($assignments)) { + return false; + } + $this->loadFromCache(); if ($this->items !== null) { return $this->checkAccessFromCache($userId, $permissionName, $params, $assignments); diff --git a/framework/rbac/PhpManager.php b/framework/rbac/PhpManager.php index 432653d376f..71cce73b932 100644 --- a/framework/rbac/PhpManager.php +++ b/framework/rbac/PhpManager.php @@ -99,6 +99,11 @@ public function init() public function checkAccess($userId, $permissionName, $params = []) { $assignments = $this->getAssignments($userId); + + if ($this->hasNoAssignments($assignments)) { + return false; + } + return $this->checkAccessRecursive($userId, $permissionName, $params, $assignments); } diff --git a/tests/framework/rbac/ManagerTestCase.php b/tests/framework/rbac/ManagerTestCase.php index 4fc10d260d2..70c30b11931 100644 --- a/tests/framework/rbac/ManagerTestCase.php +++ b/tests/framework/rbac/ManagerTestCase.php @@ -182,6 +182,16 @@ public function testCheckAccess() 'blablabla' => false, null => false, ], + 'guest' => [ + // all actions denied for guest (user not exists) + 'createPost' => false, + 'readPost' => false, + 'updatePost' => false, + 'deletePost' => false, + 'updateAnyPost' => false, + 'blablabla' => false, + null => false, + ], ]; $params = ['authorID' => 'author B'];