| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710 | 
							- <?php
 
- namespace common\modules\rbac\components;
 
- use Yii;
 
- use yii\caching\Cache;
 
- use yii\caching\TagDependency;
 
- use yii\db\Connection;
 
- use yii\db\Query;
 
- use yii\di\Instance;
 
- use yii\rbac\Assignment;
 
- use yii\rbac\Item;
 
- use yii\rbac\Permission;
 
- use yii\rbac\Role;
 
- use yii\rbac\Rule;
 
- /**
 
-  * DbManager represents an authorization manager that stores authorization information in database.
 
-  *
 
-  * The database connection is specified by [[$db]]. The database schema could be initialized by applying migration:
 
-  *
 
-  * ~~~
 
-  * yii migrate --migrationPath=@yii/rbac/migrations/
 
-  * ~~~
 
-  *
 
-  * If you don't want to use migration and need SQL instead, files for all databases are in migrations directory.
 
-  *
 
-  * You may change the names of the three tables used to store the authorization data by setting [[\yii\rbac\DbManager::$itemTable]],
 
-  * [[\yii\rbac\DbManager::$itemChildTable]] and [[\yii\rbac\DbManager::$assignmentTable]].
 
-  *
 
-  * @author Misbahul D Munir <misbahuldmunir@gmail.com>
 
-  *
 
-  * @since 1.0
 
-  */
 
- class DbManager extends \yii\rbac\DbManager
 
- {
 
-     const PART_ITEMS = 'mdm.admin.items';
 
-     const PART_CHILDREN = 'mdm.admin.children';
 
-     const PART_RULES = 'mdm.admin.rules';
 
-     /**
 
-      * @var bool Enable caching
 
-      */
 
-     public $enableCaching = false;
 
-     /**
 
-      * @var string|Cache Cache component
 
-      */
 
-     public $cache = 'cache';
 
-     /**
 
-      * @var int Cache duration
 
-      */
 
-     public $cacheDuration = 0;
 
-     /**
 
-      * @var Item[]
 
-      *             itemName => item
 
-      */
 
-     private $_items;
 
-     /**
 
-      * @var array
 
-      *            itemName => childName[]
 
-      */
 
-     private $_children;
 
-     /**
 
-      * @var array
 
-      *            userId => itemName[]
 
-      */
 
-     private $_assignments = [];
 
-     /**
 
-      * @var Rule[]
 
-      *             ruleName => rule
 
-      */
 
-     private $_rules;
 
-     /**
 
-      * {@inheritdoc}
 
-      */
 
-     public function init()
 
-     {
 
-         parent::init();
 
-         $this->db = Instance::ensure($this->db, Connection::className());
 
-         if ($this->enableCaching) {
 
-             $this->cache = Instance::ensure($this->cache, Cache::className());
 
-         } else {
 
-             $this->cache = null;
 
-         }
 
-     }
 
-     /**
 
-      * {@inheritdoc}
 
-      */
 
-     public function checkAccess($userId, $permissionName, $params = [])
 
-     {
 
-         $this->loadItems();
 
-         $this->loadChildren();
 
-         $this->loadRules();
 
-         $assignments = $this->getAssignments($userId);
 
-         return $this->checkAccessRecursive($userId, $permissionName, $params, $assignments);
 
-     }
 
-     /**
 
-      * {@inheritdoc}
 
-      */
 
-     public function getAssignments($userId)
 
-     {
 
-         $this->loadAssignments($userId);
 
-         return isset($this->_assignments[$userId]) ? $this->_assignments[$userId] : [];
 
-     }
 
-     /**
 
-      * {@inheritdoc}
 
-      */
 
-     protected function checkAccessRecursive($user, $itemName, $params, $assignments)
 
-     {
 
-         if (!isset($this->_items[$itemName])) {
 
-             return false;
 
-         }
 
-         /** @var Item $item */
 
-         $item = $this->_items[$itemName];
 
-         Yii::trace($item instanceof Role ? "Checking role: $itemName" : "Checking permission : $itemName", __METHOD__);
 
-         if (!$this->executeRule($user, $item, $params)) {
 
-             return false;
 
-         }
 
-         if (isset($assignments[$itemName]) || in_array($itemName, $this->defaultRoles)) {
 
-             return true;
 
-         }
 
-         foreach ($this->_children as $parentName => $children) {
 
-             if (in_array($itemName, $children) && $this->checkAccessRecursive($user, $parentName, $params, $assignments)) {
 
-                 return true;
 
-             }
 
-         }
 
-         return false;
 
-     }
 
-     /**
 
-      * {@inheritdoc}
 
-      */
 
-     public function addChild($parent, $child)
 
-     {
 
-         $this->loadItems();
 
-         $this->loadChildren();
 
-         parent::addChild($parent, $child);
 
-         $this->_children[$parent->name][] = $child->name;
 
-         $this->invalidate(self::PART_CHILDREN);
 
-         return true;
 
-     }
 
-     /**
 
-      * {@inheritdoc}
 
-      */
 
-     public function removeChild($parent, $child)
 
-     {
 
-         $result = parent::removeChild($parent, $child);
 
-         if ($this->_children !== null) {
 
-             $query = (new Query())
 
-                 ->select('child')
 
-                 ->from($this->itemChildTable)
 
-                 ->where(['parent' => $parent->name]);
 
-             $this->_children[$parent->name] = $query->column($this->db);
 
-         }
 
-         $this->invalidate(self::PART_CHILDREN);
 
-         return $result;
 
-     }
 
-     /**
 
-      * {@inheritdoc}
 
-      */
 
-     public function hasChild($parent, $child)
 
-     {
 
-         $this->loadChildren();
 
-         return isset($this->_children[$parent->name]) && in_array($child->name, $this->_children[$parent->name]);
 
-     }
 
-     /**
 
-      * {@inheritdoc}
 
-      */
 
-     public function assign($role, $userId)
 
-     {
 
-         $assignment = parent::assign($role, $userId);
 
-         if (isset($this->_assignments[$userId])) {
 
-             $this->_assignments[$userId][$role->name] = $assignment;
 
-         }
 
-         return $assignment;
 
-     }
 
-     /**
 
-      * {@inheritdoc}
 
-      */
 
-     public function revoke($role, $userId)
 
-     {
 
-         $result = parent::revoke($role, $userId);
 
-         unset($this->_assignments[$userId]);
 
-         return $result;
 
-     }
 
-     /**
 
-      * {@inheritdoc}
 
-      */
 
-     public function revokeAll($userId)
 
-     {
 
-         if (empty($userId)) {
 
-             return false;
 
-         }
 
-         $result = parent::revokeAll($userId);
 
-         $this->_assignments[$userId] = [];
 
-         return $result;
 
-     }
 
-     /**
 
-      * {@inheritdoc}
 
-      */
 
-     public function getAssignment($roleName, $userId)
 
-     {
 
-         $this->loadItems();
 
-         $this->loadAssignments($userId);
 
-         if (isset($this->_assignments[$userId][$roleName], $this->_items[$roleName])) {
 
-             return $this->_items[$roleName];
 
-         }
 
-         return;
 
-     }
 
-     /**
 
-      * {@inheritdoc}
 
-      */
 
-     protected function getItems($type)
 
-     {
 
-         $this->loadItems();
 
-         $items = [];
 
-         foreach ($this->_items as $name => $item) {
 
-             /** @var Item $item */
 
-             if ($item->type == $type) {
 
-                 $items[$name] = $item;
 
-             }
 
-         }
 
-         return $items;
 
-     }
 
-     /**
 
-      * {@inheritdoc}
 
-      */
 
-     public function removeItem($item)
 
-     {
 
-         parent::removeItem($item);
 
-         $this->_assignments = [];
 
-         $this->_children = $this->_items = null;
 
-         $this->invalidate([self::PART_ITEMS, self::PART_CHILDREN]);
 
-         return true;
 
-     }
 
-     /**
 
-      * {@inheritdoc}
 
-      */
 
-     public function getItem($name)
 
-     {
 
-         $this->loadItems();
 
-         return isset($this->_items[$name]) ? $this->_items[$name] : null;
 
-     }
 
-     /**
 
-      * {@inheritdoc}
 
-      */
 
-     public function updateRule($name, $rule)
 
-     {
 
-         parent::updateRule($name, $rule);
 
-         if ($rule->name !== $name) {
 
-             $this->_items = null;
 
-             $this->invalidate(self::PART_ITEMS);
 
-         }
 
-         if ($this->_rules !== null) {
 
-             unset($this->_rules[$name]);
 
-             $this->_rules[$rule->name] = $rule;
 
-         }
 
-         $this->invalidate(self::PART_RULES);
 
-         return true;
 
-     }
 
-     /**
 
-      * {@inheritdoc}
 
-      */
 
-     public function getRule($name)
 
-     {
 
-         $this->loadRules();
 
-         return isset($this->_rules[$name]) ? $this->_rules[$name] : null;
 
-     }
 
-     /**
 
-      * {@inheritdoc}
 
-      */
 
-     public function getRules()
 
-     {
 
-         $this->loadRules();
 
-         return $this->_rules;
 
-     }
 
-     /**
 
-      * {@inheritdoc}
 
-      */
 
-     public function getRolesByUser($userId)
 
-     {
 
-         $this->loadItems();
 
-         $roles = [];
 
-         foreach ($this->getAssignments($userId) as $name => $asgn) {
 
-             if (isset($this->_items[$name]) && $this->_items[$name]->type == Item::TYPE_ROLE) {
 
-                 $roles[$name] = $this->_items[$name];
 
-             }
 
-         }
 
-         return $roles;
 
-     }
 
-     /**
 
-      * {@inheritdoc}
 
-      */
 
-     public function getPermissionsByRole($roleName)
 
-     {
 
-         $childrenList = $this->getChildrenList();
 
-         $result = [];
 
-         $this->getChildrenRecursive($roleName, $childrenList, $result);
 
-         if (empty($result)) {
 
-             return [];
 
-         }
 
-         $this->loadItems();
 
-         $permissions = [];
 
-         foreach (array_keys($result) as $itemName) {
 
-             if (isset($this->_items[$itemName]) && $this->_items[$itemName] instanceof Permission) {
 
-                 $permissions[$itemName] = $this->_items[$itemName];
 
-             }
 
-         }
 
-         return $permissions;
 
-     }
 
-     /**
 
-      * {@inheritdoc}
 
-      */
 
-     protected function getChildrenList()
 
-     {
 
-         $this->loadChildren();
 
-         return $this->_children;
 
-     }
 
-     /**
 
-      * {@inheritdoc}
 
-      */
 
-     public function getPermissionsByUser($userId)
 
-     {
 
-         $childrenList = $this->getChildrenList();
 
-         $result = [];
 
-         foreach ($this->getAssignments($userId) as $roleName => $asgn) {
 
-             $this->getChildrenRecursive($roleName, $childrenList, $result);
 
-         }
 
-         if (empty($result)) {
 
-             return [];
 
-         }
 
-         $this->loadItems();
 
-         $permissions = [];
 
-         foreach (array_keys($result) as $itemName) {
 
-             if (isset($this->_items[$itemName]) && $this->_items[$itemName] instanceof Permission) {
 
-                 $permissions[$itemName] = $this->_items[$itemName];
 
-             }
 
-         }
 
-         return $permissions;
 
-     }
 
-     /**
 
-      * {@inheritdoc}
 
-      */
 
-     public function getChildren($name)
 
-     {
 
-         $this->loadItems();
 
-         $this->loadChildren();
 
-         $items = [];
 
-         if (isset($this->_children[$name])) {
 
-             foreach ($this->_children[$name] as $itemName) {
 
-                 $items[$itemName] = $this->_items[$itemName];
 
-             }
 
-         }
 
-         return $items;
 
-     }
 
-     /**
 
-      * {@inheritdoc}
 
-      */
 
-     public function removeAll()
 
-     {
 
-         $this->_children = [];
 
-         $this->_items = [];
 
-         $this->_assignments = [];
 
-         $this->_rules = [];
 
-         $this->removeAllAssignments();
 
-         $this->db->createCommand()->delete($this->itemChildTable)->execute();
 
-         $this->db->createCommand()->delete($this->itemTable)->execute();
 
-         $this->db->createCommand()->delete($this->ruleTable)->execute();
 
-         $this->invalidate([self::PART_ITEMS, self::PART_CHILDREN, self::PART_RULES]);
 
-     }
 
-     /**
 
-      * {@inheritdoc}
 
-      */
 
-     protected function removeAllItems($type)
 
-     {
 
-         parent::removeAllItems($type);
 
-         $this->_assignments = [];
 
-         $this->_children = $this->_items = null;
 
-         $this->invalidate([self::PART_ITEMS, self::PART_CHILDREN]);
 
-     }
 
-     /**
 
-      * {@inheritdoc}
 
-      */
 
-     public function removeAllRules()
 
-     {
 
-         parent::removeAllRules();
 
-         $this->_rules = [];
 
-         $this->_items = null;
 
-         $this->invalidate([self::PART_ITEMS, self::PART_RULES]);
 
-     }
 
-     /**
 
-      * {@inheritdoc}
 
-      */
 
-     public function removeAllAssignments()
 
-     {
 
-         parent::removeAllAssignments();
 
-         $this->_assignments = [];
 
-     }
 
-     /**
 
-      * {@inheritdoc}
 
-      */
 
-     protected function removeRule($rule)
 
-     {
 
-         parent::removeRule($rule);
 
-         if ($this->_rules !== null) {
 
-             unset($this->_rules[$rule->name]);
 
-         }
 
-         $this->_items = null;
 
-         $this->invalidate([self::PART_ITEMS, self::PART_RULES]);
 
-         return true;
 
-     }
 
-     /**
 
-      * {@inheritdoc}
 
-      */
 
-     protected function addRule($rule)
 
-     {
 
-         parent::addRule($rule);
 
-         if ($this->_rules !== null) {
 
-             $this->_rules[$rule->name] = $rule;
 
-         }
 
-         $this->invalidate(self::PART_RULES);
 
-         return true;
 
-     }
 
-     /**
 
-      * {@inheritdoc}
 
-      */
 
-     protected function updateItem($name, $item)
 
-     {
 
-         parent::updateItem($name, $item);
 
-         if ($item->name !== $name) {
 
-             $this->_assignments = [];
 
-             $this->_children = null;
 
-             $this->invalidate(self::PART_CHILDREN);
 
-         }
 
-         $this->_items = null;
 
-         $this->invalidate(self::PART_RULES);
 
-         return true;
 
-     }
 
-     /**
 
-      * {@inheritdoc}
 
-      */
 
-     protected function addItem($item)
 
-     {
 
-         parent::addItem($item);
 
-         if ($this->_items !== null) {
 
-             $this->_items[$item->name] = $item;
 
-         }
 
-         $this->invalidate(self::PART_ITEMS);
 
-         return true;
 
-     }
 
-     /**
 
-      * Invalidate cache.
 
-      *
 
-      * @param string $parts
 
-      */
 
-     private function invalidate($parts)
 
-     {
 
-         if ($this->enableCaching) {
 
-             TagDependency::invalidate($this->cache, $parts);
 
-         }
 
-     }
 
-     /**
 
-      * Build key cache.
 
-      *
 
-      * @param string $part
 
-      *
 
-      * @return mixed
 
-      */
 
-     private function buildKey($part)
 
-     {
 
-         return [__CLASS__, $part];
 
-     }
 
-     /**
 
-      * Get data from cache.
 
-      *
 
-      * @param string $part
 
-      *
 
-      * @return mixed
 
-      */
 
-     private function getFromCache($part)
 
-     {
 
-         if ($this->enableCaching) {
 
-             return $this->cache->get($this->buildKey($part));
 
-         }
 
-         return false;
 
-     }
 
-     /**
 
-      * Save data to cache.
 
-      *
 
-      * @param string $part
 
-      * @param mixed  $data
 
-      */
 
-     private function saveToCache($part, $data)
 
-     {
 
-         if ($this->enableCaching) {
 
-             $this->cache->set($this->buildKey($part), $data, $this->cacheDuration, new TagDependency([
 
-                 'tags' => $part,
 
-             ]));
 
-         }
 
-     }
 
-     /**
 
-      * Load data. If avaliable in memory, get from memory
 
-      * If no, get from cache. If no avaliable, get from database.
 
-      */
 
-     private function loadItems()
 
-     {
 
-         $part = self::PART_ITEMS;
 
-         if ($this->_items === null && ($this->_items = $this->getFromCache($part)) === false) {
 
-             $query = (new Query())->from($this->itemTable);
 
-             $this->_items = [];
 
-             foreach ($query->all($this->db) as $row) {
 
-                 $this->_items[$row['name']] = $this->populateItem($row);
 
-             }
 
-             $this->saveToCache($part, $this->_items);
 
-         }
 
-     }
 
-     /**
 
-      * Load data. If avaliable in memory, get from memory
 
-      * If no, get from cache. If no avaliable, get from database.
 
-      */
 
-     private function loadChildren()
 
-     {
 
-         $this->loadItems();
 
-         $part = self::PART_CHILDREN;
 
-         if ($this->_children === null && ($this->_children = $this->getFromCache($part)) === false) {
 
-             $query = (new Query())->from($this->itemChildTable);
 
-             $this->_children = [];
 
-             foreach ($query->all($this->db) as $row) {
 
-                 if (isset($this->_items[$row['parent']], $this->_items[$row['child']])) {
 
-                     $this->_children[$row['parent']][] = $row['child'];
 
-                 }
 
-             }
 
-             $this->saveToCache($part, $this->_children);
 
-         }
 
-     }
 
-     /**
 
-      * Load data. If avaliable in memory, get from memory
 
-      * If no, get from cache. If no avaliable, get from database.
 
-      */
 
-     private function loadRules()
 
-     {
 
-         $part = self::PART_RULES;
 
-         if ($this->_rules === null && ($this->_rules = $this->getFromCache($part)) === false) {
 
-             $query = (new Query())->from($this->ruleTable);
 
-             $this->_rules = [];
 
-             foreach ($query->all($this->db) as $row) {
 
-                 $rule = @unserialize($row['data']);
 
-                 if ($rule instanceof Rule) {
 
-                     $this->_rules[$row['name']] = $rule;
 
-                 }
 
-             }
 
-             $this->saveToCache($part, $this->_rules);
 
-         }
 
-     }
 
-     /**
 
-      * Load data. If avaliable in memory, get from memory
 
-      * If no, get from cache. If no avaliable, get from database.
 
-      */
 
-     private function loadAssignments($userId)
 
-     {
 
-         if (!isset($this->_assignments[$userId]) && !empty($userId)) {
 
-             $query = (new Query())
 
-                 ->from($this->assignmentTable)
 
-                 ->where(['user_id' => (string) $userId]);
 
-             $this->_assignments[$userId] = [];
 
-             foreach ($query->all($this->db) as $row) {
 
-                 $this->_assignments[$userId][$row['item_name']] = new Assignment([
 
-                     'userId' => $row['user_id'],
 
-                     'roleName' => $row['item_name'],
 
-                     'createdAt' => $row['created_at'],
 
-                 ]);
 
-             }
 
-         }
 
-     }
 
-     /**
 
-      * {@inheritdoc}
 
-      */
 
-     public function removeChildren($parent)
 
-     {
 
-         $result = parent::removeChildren($parent);
 
-         if ($this->_children !== null) {
 
-             unset($this->_children[$parent->name]);
 
-         }
 
-         $this->invalidate(self::PART_CHILDREN);
 
-         return $result;
 
-     }
 
-     /**
 
-      * Returns both roles and permissions assigned to user.
 
-      *
 
-      * @param  integer $userId
 
-      * @return array
 
-      */
 
-     public function getItemsByUser($userId)
 
-     {
 
-         if (empty($userId)) {
 
-             return [];
 
-         }
 
-         $query = (new Query)->select('b.*')
 
-             ->from(['a' => $this->assignmentTable, 'b' => $this->itemTable])
 
-             ->where('{{a}}.[[item_name]]={{b}}.[[name]]')
 
-             ->andWhere(['a.user_id' => (string) $userId]);
 
-         $roles = [];
 
-         foreach ($query->all($this->db) as $row) {
 
-             $roles[$row['name']] = $this->populateItem($row);
 
-         }
 
-         return $roles;
 
-     }
 
- }
 
 
  |