Possibility to get user ids from roles recursively

This commit is contained in:
Marco Piazza
2023-04-03 16:34:48 +02:00
parent 72add6a805
commit 7216c67854
2 changed files with 74 additions and 0 deletions

View File

@ -6,6 +6,7 @@
- Fix: correct viewPath error in LoginWidget (niciz)
- Enh: possibility to call all the api endpoints with either id or username or email (liviuk2)
- Fix: use configured User model in SecurityController 2FA confirmation (jussiaho)
- Enh: possibility to get user ids from roles recursively (mp1509)
## 1.6.0 January 9, 2023

View File

@ -12,8 +12,11 @@
namespace Da\User\Component;
use Da\User\Contracts\AuthManagerInterface;
use yii\base\InvalidArgumentException;
use yii\db\Expression;
use yii\db\Query;
use yii\rbac\DbManager;
use yii\rbac\Role;
class AuthDbManagerComponent extends DbManager implements AuthManagerInterface
{
@ -80,4 +83,74 @@ class AuthDbManagerComponent extends DbManager implements AuthManagerInterface
{
return parent::getItem($name);
}
/**
* @inheritdoc
* @param bool $recursive
* @override to add possibility to get the ids of users assigned to roles that are parents of the given one.
* @since 1.6.1
*/
public function getUserIdsByRole($roleName, $recursive = false)
{
if(!$recursive || empty($roleName)) {
return parent::getUserIdsByRole($roleName);
}
$roles = $this->getParentRoles($roleName);
$userIds = array_reduce($roles, function ($ids, $role) {
$roleIds = parent::getUserIdsByRole($role->name);
return array_merge($ids, $roleIds);
}, []);
return array_unique($userIds);
}
/**
* Returns parent roles of the role specified. Depth isn't limited.
* @param string $roleName name of the role to file parent roles for
* @return Role[] Child roles. The array is indexed by the role names.
* First element is an instance of the parent Role itself.
* @throws \yii\base\InvalidParamException if Role was not found that are getting by $roleName
* @since 1.6.1
*/
public function getParentRoles($roleName)
{
$role = $this->getRole($roleName);
if ($role === null) {
throw new InvalidArgumentException("Role \"$roleName\" not found.");
}
$result = [];
$this->getParentsRecursive($roleName, $result);
$roles = [$roleName => $role];
$roles += $result;
return $roles;
}
/**
* Recursively finds all parents and grandparents of the specified item.
* @param string $name the name of the item whose children are to be looked for.
* @param array $result the children and grand children (in array keys)
* @since 1.6.1
*/
protected function getParentsRecursive($name, &$result = [])
{
$query = (new Query())
->select(['name', 'type', 'description', 'rule_name', 'data', 'created_at', 'updated_at'])
->from([$this->itemTable, $this->itemChildTable])
->where(['child' => $name, 'name' => new Expression('[[parent]]')]);
foreach ($query->all($this->db) as $row) {
if(isset($result[$row['name']])) {
continue;
}
$result[$row['name']] = $this->populateItem($row);
$this->getParentsRecursive($row['name'], $result);
}
}
}