TinyAuthorize.php 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. <?php
  2. App::uses('Inflector', 'Utility');
  3. if (!defined('AUTH_CACHE')) {
  4. define('AUTH_CACHE', CACHE.'persistent'.DS);
  5. }
  6. if (!defined('ACL_FILE')) {
  7. define('ACL_FILE', 'acl.ini');
  8. }
  9. /**
  10. * Probably the most simple and fastest Acl out there.
  11. * Only one config file `roles.ini` necessary
  12. * Doesnt even need a Role Model/table
  13. * @link http://www.dereuromark.de/2011/12/18/tinyauth-the-fastest-and-easiest-authorization-for-cake2
  14. *
  15. * Usage:
  16. * Include it in your beforeFilter() method of the AppController
  17. * $this->Auth->authorize = array('Tools.Tiny');
  18. *
  19. * Or with admin prefix protection only
  20. * $this->Auth->authorize = array('Tools.Tiny'=>array('allowUser'=>true));
  21. *
  22. * @author Mark Scherer
  23. * @cakephp 2.0
  24. * @license MIT
  25. * 2011-12-17 ms
  26. */
  27. class TinyAuthorize extends BaseAuthorize {
  28. protected $_matchArray = array();
  29. protected $_defaults = array(
  30. 'allowUser' => false, # quick way to allow user access to non prefixed urls
  31. 'adminPrefix' => 'admin_'
  32. );
  33. public function __construct(ComponentCollection $Collection, $settings = array()) {
  34. $settings = am($this->_defaults, $settings);
  35. parent::__construct($Collection, $settings);
  36. $this->_matchArray = $this->_getRoles();
  37. }
  38. /**
  39. * Authorize a user using the AclComponent.
  40. * allows single or multi role based authorization
  41. *
  42. * @param array $user The user to authorize
  43. * @param CakeRequest $request The request needing authorization.
  44. * @return boolean
  45. */
  46. public function authorize($user, CakeRequest $request) {
  47. if (isset($user['Role'])) {
  48. $roles = (array)$user['Role'];
  49. } else {
  50. $roles = array($user['role_id']);
  51. }
  52. return $this->validate($roles, $request->params['plugin'], $request->params['controller'], $request->params['action']);
  53. }
  54. /**
  55. * validate the url to the role(s)
  56. * allows single or multi role based authorization
  57. * @return bool $success
  58. */
  59. public function validate($roles, $plugin, $controller, $action) {
  60. $action = Inflector::underscore($action);
  61. $controller = Inflector::underscore($controller);
  62. $plugin = Inflector::underscore($plugin);
  63. if (!empty($this->settings['allowUser'])) {
  64. # all user actions are accessable for logged in users
  65. if (mb_strpos($action, $this->settings['adminPrefix']) !== 0) {
  66. return true;
  67. }
  68. }
  69. if (isset($this->_matchArray[$controller]['*'])) {
  70. $matchArray = $this->_matchArray[$controller]['*'];
  71. if (in_array(-1, $matchArray)) {
  72. return true;
  73. }
  74. foreach ($roles as $role) {
  75. if (in_array($role, $matchArray)) {
  76. return true;
  77. }
  78. }
  79. }
  80. if (!empty($controller) && !empty($action)) {
  81. if (array_key_exists($controller, $this->_matchArray) && !empty($this->_matchArray[$controller][$action])) {
  82. $matchArray = $this->_matchArray[$controller][$action];
  83. # direct access? (even if he has no roles = GUEST)
  84. if (in_array(-1, $matchArray)) {
  85. return true;
  86. }
  87. # normal access (rolebased)
  88. foreach ($roles as $role) {
  89. if (in_array($role, $matchArray)) {
  90. return true;
  91. }
  92. }
  93. }
  94. }
  95. return false;
  96. }
  97. public function getModel() {
  98. return ClassRegistry::init(CLASS_USER);
  99. }
  100. /**
  101. * parse ini files
  102. */
  103. protected function _getRoles() {
  104. $res = array();
  105. if (file_exists(AUTH_CACHE.'roles.tmp') && Configure::read('debug') > 0) {
  106. unlink(AUTH_CACHE.'roles.tmp');
  107. }
  108. if (file_exists(AUTH_CACHE.'roles.tmp')) {
  109. include(AUTH_CACHE.'roles.tmp');
  110. return $roles;
  111. }
  112. if (!file_exists(APP . 'Config' . DS . ACL_FILE)) {
  113. touch(APP . 'Config' . DS . ACL_FILE);
  114. }
  115. $iniArray = parse_ini_file(APP . 'Config' . DS . ACL_FILE, true);
  116. $availableRoles = Configure::read('Role');
  117. if (!is_array($availableRoles)) {
  118. $Model = $this->getModel();
  119. $availableRoles = $Model->Role->find('list', array('fields'=>array('alias', 'id')));
  120. Configure::write('Role', $availableRoles);
  121. }
  122. if (!is_array($availableRoles) || !is_array($iniArray)) {
  123. trigger_error('Invalid Role Setup for TinyAuthorize (no roles found)');
  124. return false;
  125. }
  126. foreach ($iniArray as $key => $array) {
  127. list($plugin, $controllerName) = pluginSplit($key);
  128. $controllerName = Inflector::underscore($controllerName);
  129. foreach ($array as $actions => $roles) {
  130. $actions = explode(',', $actions);
  131. $roles = explode(',', $roles);
  132. foreach ($roles as $key => $role) {
  133. if (!($role = trim($role))) {
  134. continue;
  135. }
  136. if ($role == '*') {
  137. unset($roles[$key]);
  138. $roles = array_merge($roles, array_keys(Configure::read('Role')));
  139. }
  140. }
  141. foreach ($actions as $action) {
  142. if (!($action = trim($action))) {
  143. continue;
  144. }
  145. $actionName = Inflector::underscore($action);
  146. foreach ($roles as $role) {
  147. if (!($role = trim($role)) || $role == '*') {
  148. continue;
  149. }
  150. $newRole = Configure::read('Role.'.strtolower($role));
  151. if (!empty($res[$controllerName][$actionName]) && in_array($newRole, $res[$controllerName][$actionName])) {
  152. continue;
  153. }
  154. $res[$controllerName][$actionName][] = $newRole;
  155. }
  156. }
  157. }
  158. }
  159. file_put_contents(AUTH_CACHE.'roles.tmp', '<?php $roles = ' . var_export($res, true). ';');
  160. return $res;
  161. }
  162. }