Advertisement
Guest User

Untitled

a guest
May 23rd, 2018
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 11.71 KB | None | 0 0
  1. <?php
  2. /**
  3.  * @link http://www.yiiframework.com/
  4.  * @copyright Copyright (c) 2008 Yii Software LLC
  5.  * @license http://www.yiiframework.com/license/
  6.  */
  7. namespace yii\rbac;
  8. use Yii;
  9. use yii\base\InvalidArgumentException;
  10. use yii\base\InvalidCallException;
  11. use yii\helpers\VarDumper;
  12.  
  13. class PhpManager extends BaseManager
  14. {
  15.     /**
  16.      * @var string the path of the PHP script that contains the authorization items.
  17.      * This can be either a file path or a [path alias](guide:concept-aliases) to the file.
  18.      * Make sure this file is writable by the Web server process if the authorization needs to be changed online.
  19.      * @see loadFromFile()
  20.      * @see saveToFile()
  21.      */
  22.     public $itemFile = '@app/rbac/items.php';
  23.     /**
  24.      * @var string the path of the PHP script that contains the authorization assignments.
  25.      * This can be either a file path or a [path alias](guide:concept-aliases) to the file.
  26.      * Make sure this file is writable by the Web server process if the authorization needs to be changed online.
  27.      * @see loadFromFile()
  28.      * @see saveToFile()
  29.      */
  30.     public $assignmentFile = '@app/rbac/assignments.php';
  31.     /**
  32.      * @var string the path of the PHP script that contains the authorization rules.
  33.      * This can be either a file path or a [path alias](guide:concept-aliases) to the file.
  34.      * Make sure this file is writable by the Web server process if the authorization needs to be changed online.
  35.      * @see loadFromFile()
  36.      * @see saveToFile()
  37.      */
  38.     public $ruleFile = '@app/rbac/rules.php';
  39.     /**
  40.      * @var Item[]
  41.      */
  42.     protected $items = []; // itemName => item
  43.     /**
  44.      * @var array
  45.      */
  46.     protected $children = []; // itemName, childName => child
  47.     /**
  48.      * @var array
  49.      */
  50.     protected $assignments = []; // userId, itemName => assignment
  51.     /**
  52.      * @var Rule[]
  53.      */
  54.     protected $rules = []; // ruleName => rule
  55.     /**
  56.      * Initializes the application component.
  57.      * This method overrides parent implementation by loading the authorization data
  58.      * from PHP script.
  59.      */
  60.     public function init()
  61.     {
  62.         parent::init();
  63.         $this->itemFile = Yii::getAlias($this->itemFile);
  64.         $this->assignmentFile = Yii::getAlias($this->assignmentFile);
  65.         $this->ruleFile = Yii::getAlias($this->ruleFile);
  66.         $this->load();
  67.     }
  68.     /**
  69.      * {@inheritdoc}
  70.      */
  71.     public function checkAccess($userId, $permissionName, $params = [])
  72.     {
  73.         $assignments = $this->getAssignments($userId);
  74.         if ($this->hasNoAssignments($assignments)) {
  75.             return false;
  76.         }
  77.         return $this->checkAccessRecursive($userId, $permissionName, $params, $assignments);
  78.     }
  79.     /**
  80.      * {@inheritdoc}
  81.      */
  82.     public function getAssignments($userId)
  83.     {
  84.         return isset($this->assignments[$userId]) ? $this->assignments[$userId] : [];
  85.     }
  86.     /**
  87.      * Performs access check for the specified user.
  88.      * This method is internally called by [[checkAccess()]].
  89.      *
  90.      * @param string|int $user the user ID. This should can be either an integer or a string representing
  91.      * the unique identifier of a user. See [[\yii\web\User::id]].
  92.      * @param string $itemName the name of the operation that need access check
  93.      * @param array $params name-value pairs that would be passed to rules associated
  94.      * with the tasks and roles assigned to the user. A param with name 'user' is added to this array,
  95.      * which holds the value of `$userId`.
  96.      * @param Assignment[] $assignments the assignments to the specified user
  97.      * @return bool whether the operations can be performed by the user.
  98.      */
  99.     protected function checkAccessRecursive($user, $itemName, $params, $assignments)
  100.     {
  101.         if (!isset($this->items[$itemName])) {
  102.             return false;
  103.         }
  104.         /* @var $item Item */
  105.         $item = $this->items[$itemName];
  106.         Yii::debug($item instanceof Role ? "Checking role: $itemName" : "Checking permission : $itemName", __METHOD__);
  107.         if (!$this->executeRule($user, $item, $params)) {
  108.             return false;
  109.         }
  110.         if (isset($assignments[$itemName]) || in_array($itemName, $this->defaultRoles)) {
  111.             return true;
  112.         }
  113.         foreach ($this->children as $parentName => $children) {
  114.             if (isset($children[$itemName]) && $this->checkAccessRecursive($user, $parentName, $params, $assignments)) {
  115.                 return true;
  116.             }
  117.         }
  118.         return false;
  119.     }
  120.     /**
  121.      * {@inheritdoc}
  122.      * @since 2.0.8
  123.      */
  124.     public function canAddChild($parent, $child)
  125.     {
  126.         return !$this->detectLoop($parent, $child);
  127.     }
  128.     /**
  129.      * Checks whether there is a loop in the authorization item hierarchy.
  130.      *
  131.      * @param Item $parent parent item
  132.      * @param Item $child the child item that is to be added to the hierarchy
  133.      * @return bool whether a loop exists
  134.      */
  135.     protected function detectLoop($parent, $child)
  136.     {
  137.         if ($child->name === $parent->name) {
  138.             return true;
  139.         }
  140.         if (!isset($this->children[$child->name], $this->items[$parent->name])) {
  141.             return false;
  142.         }
  143.         foreach ($this->children[$child->name] as $grandchild) {
  144.             /* @var $grandchild Item */
  145.             if ($this->detectLoop($parent, $grandchild)) {
  146.                 return true;
  147.             }
  148.         }
  149.         return false;
  150.     }
  151.     /**
  152.      * {@inheritdoc}
  153.      */
  154.     public function hasChild($parent, $child)
  155.     {
  156.         return isset($this->children[$parent->name][$child->name]);
  157.     }
  158.     /**
  159.      * {@inheritdoc}
  160.      */
  161.     public function getAssignment($roleName, $userId)
  162.     {
  163.         return isset($this->assignments[$userId][$roleName]) ? $this->assignments[$userId][$roleName] : null;
  164.     }
  165.     /**
  166.      * {@inheritdoc}
  167.      */
  168.     public function getItems($type)
  169.     {
  170.         $items = [];
  171.         foreach ($this->items as $name => $item) {
  172.             /* @var $item Item */
  173.             if ($item->type == $type) {
  174.                 $items[$name] = $item;
  175.             }
  176.         }
  177.         return $items;
  178.     }
  179.  
  180.     /**
  181.      * {@inheritdoc}
  182.      */
  183.     public function getItem($name)
  184.     {
  185.         return isset($this->items[$name]) ? $this->items[$name] : null;
  186.     }
  187.     /**
  188.      * {@inheritdoc}
  189.      */
  190.     public function updateRule($name, $rule)
  191.     {
  192.         if ($rule->name !== $name) {
  193.             unset($this->rules[$name]);
  194.         }
  195.         $this->rules[$rule->name] = $rule;
  196.         $this->saveRules();
  197.         return true;
  198.     }
  199.     /**
  200.      * {@inheritdoc}
  201.      */
  202.     public function getRule($name)
  203.     {
  204.         return isset($this->rules[$name]) ? $this->rules[$name] : null;
  205.     }
  206.     /**
  207.      * {@inheritdoc}
  208.      */
  209.     public function getRules()
  210.     {
  211.         return $this->rules;
  212.     }
  213.     /**
  214.      * {@inheritdoc}
  215.      * The roles returned by this method include the roles assigned via [[$defaultRoles]].
  216.      */
  217.     public function getRolesByUser($userId)
  218.     {
  219.         $roles = $this->getDefaultRoleInstances();
  220.         foreach ($this->getAssignments($userId) as $name => $assignment) {
  221.             $role = $this->items[$assignment->roleName];
  222.             if ($role->type === Item::TYPE_ROLE) {
  223.                 $roles[$name] = $role;
  224.             }
  225.         }
  226.         return $roles;
  227.     }
  228.     /**
  229.      * {@inheritdoc}
  230.      */
  231.     public function getChildRoles($roleName)
  232.     {
  233.         $role = $this->getRole($roleName);
  234.         if ($role === null) {
  235.             throw new InvalidArgumentException("Role \"$roleName\" not found.");
  236.         }
  237.         $result = [];
  238.         $this->getChildrenRecursive($roleName, $result);
  239.         $roles = [$roleName => $role];
  240.         $roles += array_filter($this->getRoles(), function (Role $roleItem) use ($result) {
  241.             return array_key_exists($roleItem->name, $result);
  242.         });
  243.         return $roles;
  244.     }
  245.     /**
  246.      * {@inheritdoc}
  247.      */
  248.     public function getPermissionsByRole($roleName)
  249.     {
  250.         $result = [];
  251.         $this->getChildrenRecursive($roleName, $result);
  252.         if (empty($result)) {
  253.             return [];
  254.         }
  255.         $permissions = [];
  256.         foreach (array_keys($result) as $itemName) {
  257.             if (isset($this->items[$itemName]) && $this->items[$itemName] instanceof Permission) {
  258.                 $permissions[$itemName] = $this->items[$itemName];
  259.             }
  260.         }
  261.         return $permissions;
  262.     }
  263.     /**
  264.      * Recursively finds all children and grand children of the specified item.
  265.      *
  266.      * @param string $name the name of the item whose children are to be looked for.
  267.      * @param array $result the children and grand children (in array keys)
  268.      */
  269.     protected function getChildrenRecursive($name, &$result)
  270.     {
  271.         if (isset($this->children[$name])) {
  272.             foreach ($this->children[$name] as $child) {
  273.                 $result[$child->name] = true;
  274.                 $this->getChildrenRecursive($child->name, $result);
  275.             }
  276.         }
  277.     }
  278.     /**
  279.      * {@inheritdoc}
  280.      */
  281.     public function getPermissionsByUser($userId)
  282.     {
  283.         $directPermission = $this->getDirectPermissionsByUser($userId);
  284.         $inheritedPermission = $this->getInheritedPermissionsByUser($userId);
  285.         return array_merge($directPermission, $inheritedPermission);
  286.     }
  287.     /**
  288.      * Returns all permissions that are directly assigned to user.
  289.      * @param string|int $userId the user ID (see [[\yii\web\User::id]])
  290.      * @return Permission[] all direct permissions that the user has. The array is indexed by the permission names.
  291.      * @since 2.0.7
  292.      */
  293.     protected function getDirectPermissionsByUser($userId)
  294.     {
  295.         $permissions = [];
  296.         foreach ($this->getAssignments($userId) as $name => $assignment) {
  297.             $permission = $this->items[$assignment->roleName];
  298.             if ($permission->type === Item::TYPE_PERMISSION) {
  299.                 $permissions[$name] = $permission;
  300.             }
  301.         }
  302.         return $permissions;
  303.     }
  304.     /**
  305.      * Returns all permissions that the user inherits from the roles assigned to him.
  306.      * @param string|int $userId the user ID (see [[\yii\web\User::id]])
  307.      * @return Permission[] all inherited permissions that the user has. The array is indexed by the permission names.
  308.      * @since 2.0.7
  309.      */
  310.     protected function getInheritedPermissionsByUser($userId)
  311.     {
  312.         $assignments = $this->getAssignments($userId);
  313.         $result = [];
  314.         foreach (array_keys($assignments) as $roleName) {
  315.             $this->getChildrenRecursive($roleName, $result);
  316.         }
  317.         if (empty($result)) {
  318.             return [];
  319.         }
  320.         $permissions = [];
  321.         foreach (array_keys($result) as $itemName) {
  322.             if (isset($this->items[$itemName]) && $this->items[$itemName] instanceof Permission) {
  323.                 $permissions[$itemName] = $this->items[$itemName];
  324.             }
  325.         }
  326.         return $permissions;
  327.     }
  328.     /**
  329.      * {@inheritdoc}
  330.      */
  331.     public function getChildren($name)
  332.     {
  333.         return isset($this->children[$name]) ? $this->children[$name] : [];
  334.     }
  335.  
  336.     /**
  337.      * {@inheritdoc}
  338.      * @since 2.0.7
  339.      */
  340.     public function getUserIdsByRole($roleName)
  341.     {
  342.         $result = [];
  343.         foreach ($this->assignments as $userID => $assignments) {
  344.             foreach ($assignments as $userAssignment) {
  345.                 if ($userAssignment->roleName === $roleName && $userAssignment->userId == $userID) {
  346.                     $result[] = (string) $userID;
  347.                 }
  348.             }
  349.         }
  350.         return $result;
  351.     }
  352. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement