AuthUserTrait.php 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. <?php
  2. App::uses('Hash', 'Utility');
  3. if (!defined('USER_ROLE_KEY')) {
  4. define('USER_ROLE_KEY', 'Roles');
  5. }
  6. if (!defined('USER_RIGHT_KEY')) {
  7. define('USER_RIGHT_KEY', 'Rights');
  8. }
  9. /**
  10. * Convenience wrapper to access Auth data and check on rights/roles.
  11. *
  12. * Simply add it at the class file:
  13. *
  14. * trait AuthUserTrait;
  15. *
  16. * But needs
  17. *
  18. * protected function _getUser() {}
  19. *
  20. * to be implemented in the using class.
  21. *
  22. * Expects the Role session infos to be either
  23. * - `Auth.User.role_id` (single) or
  24. * - `Auth.User.Role` (multi - flat array of roles, or array role data)
  25. * and can be adjusted via constants and defined().
  26. * Same goes for Right data.
  27. *
  28. * If roles are defined in configuration file (non-db roles setup) the constant
  29. * `USER_ROLE_KEY` has to be defined in `bootstrap.php`.
  30. * ```
  31. * // if role key in User model is role_id
  32. * define('USER_ROLE_KEY', 'role_id');
  33. * ```
  34. *
  35. * Note: This uses AuthComponent internally to work with both stateful and stateless auth.
  36. *
  37. * @author Mark Scherer
  38. * @license MIT
  39. */
  40. trait AuthUserTrait {
  41. /**
  42. * Get the user id of the current session.
  43. *
  44. * This can be used anywhere to check if a user is logged in.
  45. *
  46. * @param string $field Field name. Defaults to `id`.
  47. * @return mixed User id if existent, null otherwise.
  48. */
  49. public function id($field = 'id') {
  50. return $this->user($field);
  51. }
  52. /**
  53. * This check can be used to tell if a record that belongs to some user is the
  54. * current logged in user
  55. *
  56. * @param string|int $userId
  57. * @param string $field Field name. Defaults to `id`.
  58. * @return boolean
  59. */
  60. public function isMe($userId, $field = 'id') {
  61. return ($userId && (string)$userId === (string)$this->user($field));
  62. }
  63. /**
  64. * Get the user data of the current session.
  65. *
  66. * @param string $key Key in dot syntax.
  67. * @return mixed Data
  68. */
  69. public function user($key = null) {
  70. $user = $this->_getUser();
  71. if ($key === null) {
  72. return $user;
  73. }
  74. return Hash::get($user, $key);
  75. }
  76. /**
  77. * Get the role(s) of the current session.
  78. *
  79. * It will return the single role for single role setup, and a flat
  80. * list of roles for multi role setup.
  81. *
  82. * @return mixed String or array of roles or null if inexistent.
  83. */
  84. public function roles() {
  85. $roles = $this->user(USER_ROLE_KEY);
  86. if (!is_array($roles)) {
  87. return $roles;
  88. }
  89. if (isset($roles[0]['id'])) {
  90. $roles = Hash::extract($roles, '{n}.id');
  91. }
  92. return $roles;
  93. }
  94. /**
  95. * Check if the current session has this role.
  96. *
  97. * @param mixed $role
  98. * @param mixed $providedRoles
  99. * @return bool Success
  100. */
  101. public function hasRole($expectedRole, $providedRoles = null) {
  102. if ($providedRoles !== null) {
  103. $roles = (array)$providedRoles;
  104. } else {
  105. $roles = (array)$this->roles();
  106. }
  107. if (empty($roles)) {
  108. return false;
  109. }
  110. if (in_array($expectedRole, $roles)) {
  111. return true;
  112. }
  113. return false;
  114. }
  115. /**
  116. * Check if the current session has one of these roles.
  117. *
  118. * You can either require one of the roles (default), or you can require all
  119. * roles to match.
  120. *
  121. * @param mixed $expectedRoles
  122. * @param bool $oneRoleIsEnough (if all $roles have to match instead of just one)
  123. * @param mixed $providedRoles
  124. * @return bool Success
  125. */
  126. public function hasRoles($expectedRoles, $oneRoleIsEnough = true, $providedRoles = null) {
  127. if ($providedRoles !== null) {
  128. $roles = $providedRoles;
  129. } else {
  130. $roles = $this->roles();
  131. }
  132. $expectedRoles = (array)$expectedRoles;
  133. if (empty($expectedRoles)) {
  134. return false;
  135. }
  136. $count = 0;
  137. foreach ($expectedRoles as $expectedRole) {
  138. if ($this->hasRole($expectedRole, $roles)) {
  139. if ($oneRoleIsEnough) {
  140. return true;
  141. }
  142. $count++;
  143. } else {
  144. if (!$oneRoleIsEnough) {
  145. return false;
  146. }
  147. }
  148. }
  149. if ($count === count($expectedRoles)) {
  150. return true;
  151. }
  152. return false;
  153. }
  154. /**
  155. * Check if the current session has this right.
  156. *
  157. * Rights can be an additional element to give permissions, e.g.
  158. * the right to send messages/emails, to friend request other users,...
  159. * This can be set via Right model and stored in the Auth array upon login
  160. * the same way the roles are.
  161. *
  162. * @param int $expectedRight
  163. * @return bool Success
  164. */
  165. public function hasRight($expectedRight) {
  166. $rights = $this->user(USER_RIGHT_KEY);
  167. $rights = (array)$rights;
  168. if (array_key_exists($expectedRight, $rights) && !empty($rights[$expectedRight])) {
  169. return true;
  170. }
  171. return false;
  172. }
  173. }