PageRenderTime 46ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/user/manager.php

https://github.com/sezuan/core
PHP | 228 lines | 118 code | 21 blank | 89 comment | 18 complexity | 17ad333f65d453d0e4b52f80a626dbf5 MD5 | raw file
Possible License(s): AGPL-3.0, AGPL-1.0, MPL-2.0-no-copyleft-exception
  1. <?php
  2. /**
  3. * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com>
  4. * This file is licensed under the Affero General Public License version 3 or
  5. * later.
  6. * See the COPYING-README file.
  7. */
  8. namespace OC\User;
  9. use OC\Hooks\PublicEmitter;
  10. /**
  11. * Class Manager
  12. *
  13. * Hooks available in scope \OC\User:
  14. * - preSetPassword(\OC\User\User $user, string $password, string $recoverPassword)
  15. * - postSetPassword(\OC\User\User $user, string $password, string $recoverPassword)
  16. * - preDelete(\OC\User\User $user)
  17. * - postDelete(\OC\User\User $user)
  18. * - preCreateUser(string $uid, string $password)
  19. * - postCreateUser(\OC\User\User $user, string $password)
  20. *
  21. * @package OC\User
  22. */
  23. class Manager extends PublicEmitter {
  24. /**
  25. * @var \OC_User_Backend[] $backends
  26. */
  27. private $backends = array();
  28. private $cachedUsers = array();
  29. public function __construct() {
  30. $cachedUsers = $this->cachedUsers;
  31. $this->listen('\OC\User', 'postDelete', function ($user) use (&$cachedUsers) {
  32. $i = array_search($user, $cachedUsers);
  33. if ($i !== false) {
  34. unset($cachedUsers[$i]);
  35. }
  36. });
  37. }
  38. /**
  39. * register a user backend
  40. *
  41. * @param \OC_User_Backend $backend
  42. */
  43. public function registerBackend($backend) {
  44. $this->backends[] = $backend;
  45. }
  46. /**
  47. * remove a user backend
  48. *
  49. * @param \OC_User_Backend $backend
  50. */
  51. public function removeBackend($backend) {
  52. $this->cachedUsers = array();
  53. if (($i = array_search($backend, $this->backends)) !== false) {
  54. unset($this->backends[$i]);
  55. }
  56. }
  57. /**
  58. * remove all user backends
  59. */
  60. public function clearBackends() {
  61. $this->cachedUsers = array();
  62. $this->backends = array();
  63. }
  64. /**
  65. * get a user by user id
  66. *
  67. * @param string $uid
  68. * @return \OC\User\User
  69. */
  70. public function get($uid) {
  71. if (isset($this->cachedUsers[$uid])) { //check the cache first to prevent having to loop over the backends
  72. return $this->cachedUsers[$uid];
  73. }
  74. foreach ($this->backends as $backend) {
  75. if ($backend->userExists($uid)) {
  76. return $this->getUserObject($uid, $backend);
  77. }
  78. }
  79. return null;
  80. }
  81. /**
  82. * get or construct the user object
  83. *
  84. * @param string $uid
  85. * @param \OC_User_Backend $backend
  86. * @return \OC\User\User
  87. */
  88. protected function getUserObject($uid, $backend) {
  89. if (isset($this->cachedUsers[$uid])) {
  90. return $this->cachedUsers[$uid];
  91. }
  92. $this->cachedUsers[$uid] = new User($uid, $backend, $this);
  93. return $this->cachedUsers[$uid];
  94. }
  95. /**
  96. * check if a user exists
  97. *
  98. * @param string $uid
  99. * @return bool
  100. */
  101. public function userExists($uid) {
  102. $user = $this->get($uid);
  103. return ($user !== null);
  104. }
  105. /**
  106. * search by user id
  107. *
  108. * @param string $pattern
  109. * @param int $limit
  110. * @param int $offset
  111. * @return \OC\User\User[]
  112. */
  113. public function search($pattern, $limit = null, $offset = null) {
  114. $users = array();
  115. foreach ($this->backends as $backend) {
  116. $backendUsers = $backend->getUsers($pattern, $limit, $offset);
  117. if (is_array($backendUsers)) {
  118. foreach ($backendUsers as $uid) {
  119. $users[] = $this->getUserObject($uid, $backend);
  120. if (!is_null($limit)) {
  121. $limit--;
  122. }
  123. if (!is_null($offset) and $offset > 0) {
  124. $offset--;
  125. }
  126. }
  127. }
  128. }
  129. usort($users, function ($a, $b) {
  130. /**
  131. * @var \OC\User\User $a
  132. * @var \OC\User\User $b
  133. */
  134. return strcmp($a->getUID(), $b->getUID());
  135. });
  136. return $users;
  137. }
  138. /**
  139. * search by displayName
  140. *
  141. * @param string $pattern
  142. * @param int $limit
  143. * @param int $offset
  144. * @return \OC\User\User[]
  145. */
  146. public function searchDisplayName($pattern, $limit = null, $offset = null) {
  147. $users = array();
  148. foreach ($this->backends as $backend) {
  149. $backendUsers = $backend->getDisplayNames($pattern, $limit, $offset);
  150. if (is_array($backendUsers)) {
  151. foreach ($backendUsers as $uid => $displayName) {
  152. $users[] = $this->getUserObject($uid, $backend);
  153. if (!is_null($limit)) {
  154. $limit--;
  155. }
  156. if (!is_null($offset) and $offset > 0) {
  157. $offset--;
  158. }
  159. }
  160. }
  161. }
  162. usort($users, function ($a, $b) {
  163. /**
  164. * @var \OC\User\User $a
  165. * @var \OC\User\User $b
  166. */
  167. return strcmp($a->getDisplayName(), $b->getDisplayName());
  168. });
  169. return $users;
  170. }
  171. /**
  172. * @param string $uid
  173. * @param string $password
  174. * @throws \Exception
  175. * @return bool | \OC\User\User the created user of false
  176. */
  177. public function createUser($uid, $password) {
  178. // Check the name for bad characters
  179. // Allowed are: "a-z", "A-Z", "0-9" and "_.@-"
  180. if (preg_match('/[^a-zA-Z0-9 _\.@\-]/', $uid)) {
  181. throw new \Exception('Only the following characters are allowed in a username:'
  182. . ' "a-z", "A-Z", "0-9", and "_.@-"');
  183. }
  184. // No empty username
  185. if (trim($uid) == '') {
  186. throw new \Exception('A valid username must be provided');
  187. }
  188. // No empty password
  189. if (trim($password) == '') {
  190. throw new \Exception('A valid password must be provided');
  191. }
  192. // Check if user already exists
  193. if ($this->userExists($uid)) {
  194. throw new \Exception('The username is already being used');
  195. }
  196. $this->emit('\OC\User', 'preCreateUser', array($uid, $password));
  197. foreach ($this->backends as $backend) {
  198. if ($backend->implementsActions(\OC_USER_BACKEND_CREATE_USER)) {
  199. $backend->createUser($uid, $password);
  200. $user = $this->getUserObject($uid, $backend);
  201. $this->emit('\OC\User', 'postCreateUser', array($user, $password));
  202. return $user;
  203. }
  204. }
  205. return false;
  206. }
  207. }