src/Rbac/DbManager.php
protected function checkAccessRecursive($user, $itemName, $params, $assignments)
    {
        return $this->getItem($itemName)
            ->then(function($item) use ($user, $params, $itemName) {
                if ($item === null) {
                    return reject(new Error("Check access recursive - denied"));
                }

                Reaction::debug($item instanceof Role ? "Checking role: $itemName" : "Checking permission: $itemName");

                return $this->executeRule($user, $item, $params);
            })
            ->then(function() use (&$assignments, $itemName, $user, $params) {
                if (isset($assignments[$itemName]) || in_array($itemName, $this->defaultRoles)) {
                    return true;
                }
                $query = new Query();
                return $query->select(['parent'])
                    ->from($this->itemChildTable)
                    ->where(['child' => $itemName])
                    ->column($this->db)
                    ->then(function($parents) use ($user, $params, $assignments) {
                        $promises = [];
                        foreach ($parents as $parent) {
                            $promises[] = $this->checkAccessRecursive($user, $parent, $params, $assignments);
                        }
                        return !empty($promises) ? any($promises) : reject(new Error("Check access recursive - denied"));
                    });
            });
    }
protected function checkAccessRecursive($user, $itemName, $params, $assignments)
    {
        return $this->getItem($itemName)
            ->then(function($item) use ($user, $params, $itemName) {
                if ($item === null) {
                    return reject(new Error("Check access recursive - denied"));
                }

                Reaction::debug($item instanceof Role ? "Checking role: $itemName" : "Checking permission: $itemName");

                return $this->executeRule($user, $item, $params);
            })
            ->then(function() use (&$assignments, $itemName, $user, $params) {
                if (isset($assignments[$itemName]) || in_array($itemName, $this->defaultRoles)) {
                    return true;
                }
                $query = new Query();
                return $query->select(['parent'])
                    ->from($this->itemChildTable)
                    ->where(['child' => $itemName])
                    ->column($this->db)
                    ->then(function($parents) use ($user, $params, $assignments) {
                        $promises = [];
                        foreach ($parents as $parent) {
                            $promises[] = $this->checkAccessRecursive($user, $parent, $params, $assignments);
                        }
                        return !empty($promises) ? any($promises) : reject(new Error("Check access recursive - denied"));
                    });
            });
    }
Performs access check for the specified user.
This method is internally called by [[checkAccess()]].
@param string|int $user the user ID. This should can be either an integer or a string representing
the unique identifier of a user. See [[\yii\web\User::id]].
@param string $itemName the name of the operation that need access check
@param array $params name-value pairs that would be passed to rules associated
with the tasks and roles assigned to the user. A param with name 'user' is added to this array,
which holds the value of `$userId`.
@param Assignment[] $assignments the assignments to the specified user
@return ExtendedPromiseInterface with bool whether the operations can be performed by the user.