PageRenderTime 44ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/Cake/Model/Permission.php

https://gitlab.com/shubam39/CakeTooDoo
PHP | 257 lines | 157 code | 26 blank | 74 comment | 30 complexity | fe5075010d38e6240487a36f03310349 MD5 | raw file
  1. <?php
  2. /**
  3. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  4. * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  5. *
  6. * Licensed under The MIT License
  7. * For full copyright and license information, please see the LICENSE.txt
  8. * Redistributions of files must retain the above copyright notice.
  9. *
  10. * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  11. * @link http://cakephp.org CakePHP(tm) Project
  12. * @package Cake.Model
  13. * @since CakePHP(tm) v 0.2.9
  14. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  15. */
  16. App::uses('AppModel', 'Model');
  17. /**
  18. * Permissions linking AROs with ACOs
  19. *
  20. * @package Cake.Model
  21. */
  22. class Permission extends AppModel {
  23. /**
  24. * Explicitly disable in-memory query caching
  25. *
  26. * @var bool
  27. */
  28. public $cacheQueries = false;
  29. /**
  30. * Override default table name
  31. *
  32. * @var string
  33. */
  34. public $useTable = 'aros_acos';
  35. /**
  36. * Permissions link AROs with ACOs
  37. *
  38. * @var array
  39. */
  40. public $belongsTo = array('Aro', 'Aco');
  41. /**
  42. * No behaviors for this model
  43. *
  44. * @var array
  45. */
  46. public $actsAs = null;
  47. /**
  48. * Constructor, used to tell this model to use the
  49. * database configured for ACL
  50. */
  51. public function __construct() {
  52. $config = Configure::read('Acl.database');
  53. if (!empty($config)) {
  54. $this->useDbConfig = $config;
  55. }
  56. parent::__construct();
  57. }
  58. /**
  59. * Checks if the given $aro has access to action $action in $aco
  60. *
  61. * @param string $aro ARO The requesting object identifier.
  62. * @param string $aco ACO The controlled object identifier.
  63. * @param string $action Action (defaults to *)
  64. * @return bool Success (true if ARO has access to action in ACO, false otherwise)
  65. */
  66. public function check($aro, $aco, $action = '*') {
  67. if (!$aro || !$aco) {
  68. return false;
  69. }
  70. $permKeys = $this->getAcoKeys($this->schema());
  71. $aroPath = $this->Aro->node($aro);
  72. $acoPath = $this->Aco->node($aco);
  73. if (!$aroPath) {
  74. $this->log(__d('cake_dev',
  75. "%s - Failed ARO node lookup in permissions check. Node references:\nAro: %s\nAco: %s",
  76. 'DbAcl::check()',
  77. print_r($aro, true),
  78. print_r($aco, true)),
  79. E_USER_WARNING
  80. );
  81. return false;
  82. }
  83. if (!$acoPath) {
  84. $this->log(__d('cake_dev',
  85. "%s - Failed ACO node lookup in permissions check. Node references:\nAro: %s\nAco: %s",
  86. 'DbAcl::check()',
  87. print_r($aro, true),
  88. print_r($aco, true)),
  89. E_USER_WARNING
  90. );
  91. return false;
  92. }
  93. if ($action !== '*' && !in_array('_' . $action, $permKeys)) {
  94. $this->log(__d('cake_dev', "ACO permissions key %s does not exist in %s", $action, 'DbAcl::check()'), E_USER_NOTICE);
  95. return false;
  96. }
  97. $inherited = array();
  98. $acoIDs = Hash::extract($acoPath, '{n}.' . $this->Aco->alias . '.id');
  99. $count = count($aroPath);
  100. for ($i = 0; $i < $count; $i++) {
  101. $permAlias = $this->alias;
  102. $perms = $this->find('all', array(
  103. 'conditions' => array(
  104. "{$permAlias}.aro_id" => $aroPath[$i][$this->Aro->alias]['id'],
  105. "{$permAlias}.aco_id" => $acoIDs
  106. ),
  107. 'order' => array($this->Aco->alias . '.lft' => 'desc'),
  108. 'recursive' => 0
  109. ));
  110. if (empty($perms)) {
  111. continue;
  112. }
  113. $perms = Hash::extract($perms, '{n}.' . $this->alias);
  114. foreach ($perms as $perm) {
  115. if ($action === '*') {
  116. foreach ($permKeys as $key) {
  117. if (!empty($perm)) {
  118. if ($perm[$key] == -1) {
  119. return false;
  120. } elseif ($perm[$key] == 1) {
  121. $inherited[$key] = 1;
  122. }
  123. }
  124. }
  125. if (count($inherited) === count($permKeys)) {
  126. return true;
  127. }
  128. } else {
  129. switch ($perm['_' . $action]) {
  130. case -1:
  131. return false;
  132. case 0:
  133. continue;
  134. case 1:
  135. return true;
  136. }
  137. }
  138. }
  139. }
  140. return false;
  141. }
  142. /**
  143. * Allow $aro to have access to action $actions in $aco
  144. *
  145. * @param string $aro ARO The requesting object identifier.
  146. * @param string $aco ACO The controlled object identifier.
  147. * @param string $actions Action (defaults to *) Invalid permissions will result in an exception
  148. * @param int $value Value to indicate access type (1 to give access, -1 to deny, 0 to inherit)
  149. * @return bool Success
  150. * @throws AclException on Invalid permission key.
  151. */
  152. public function allow($aro, $aco, $actions = '*', $value = 1) {
  153. $perms = $this->getAclLink($aro, $aco);
  154. $permKeys = $this->getAcoKeys($this->schema());
  155. $save = array();
  156. if (!$perms) {
  157. $this->log(__d('cake_dev', '%s - Invalid node', 'DbAcl::allow()'), E_USER_WARNING);
  158. return false;
  159. }
  160. if (isset($perms[0])) {
  161. $save = $perms[0][$this->alias];
  162. }
  163. if ($actions === '*') {
  164. $save = array_combine($permKeys, array_pad(array(), count($permKeys), $value));
  165. } else {
  166. if (!is_array($actions)) {
  167. $actions = array('_' . $actions);
  168. }
  169. foreach ($actions as $action) {
  170. if ($action{0} !== '_') {
  171. $action = '_' . $action;
  172. }
  173. if (!in_array($action, $permKeys, true)) {
  174. throw new AclException(__d('cake_dev', 'Invalid permission key "%s"', $action));
  175. }
  176. $save[$action] = $value;
  177. }
  178. }
  179. list($save['aro_id'], $save['aco_id']) = array($perms['aro'], $perms['aco']);
  180. if ($perms['link'] && !empty($perms['link'])) {
  181. $save['id'] = $perms['link'][0][$this->alias]['id'];
  182. } else {
  183. unset($save['id']);
  184. $this->id = null;
  185. }
  186. return ($this->save($save) !== false);
  187. }
  188. /**
  189. * Get an array of access-control links between the given Aro and Aco
  190. *
  191. * @param string $aro ARO The requesting object identifier.
  192. * @param string $aco ACO The controlled object identifier.
  193. * @return array Indexed array with: 'aro', 'aco' and 'link'
  194. */
  195. public function getAclLink($aro, $aco) {
  196. $obj = array();
  197. $obj['Aro'] = $this->Aro->node($aro);
  198. $obj['Aco'] = $this->Aco->node($aco);
  199. if (empty($obj['Aro']) || empty($obj['Aco'])) {
  200. return false;
  201. }
  202. $aro = Hash::extract($obj, 'Aro.0.' . $this->Aro->alias . '.id');
  203. $aco = Hash::extract($obj, 'Aco.0.' . $this->Aco->alias . '.id');
  204. $aro = current($aro);
  205. $aco = current($aco);
  206. return array(
  207. 'aro' => $aro,
  208. 'aco' => $aco,
  209. 'link' => $this->find('all', array('conditions' => array(
  210. $this->alias . '.aro_id' => $aro,
  211. $this->alias . '.aco_id' => $aco
  212. )))
  213. );
  214. }
  215. /**
  216. * Get the crud type keys
  217. *
  218. * @param array $keys Permission schema
  219. * @return array permission keys
  220. */
  221. public function getAcoKeys($keys) {
  222. $newKeys = array();
  223. $keys = array_keys($keys);
  224. foreach ($keys as $key) {
  225. if (!in_array($key, array('id', 'aro_id', 'aco_id'))) {
  226. $newKeys[] = $key;
  227. }
  228. }
  229. return $newKeys;
  230. }
  231. }