manager.php 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  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. /**
  29. * @var \OC\User\User[] $cachedUsers
  30. */
  31. private $cachedUsers = array();
  32. public function __construct() {
  33. $cachedUsers = $this->cachedUsers;
  34. $this->listen('\OC\User', 'postDelete', function ($user) use (&$cachedUsers) {
  35. $i = array_search($user, $cachedUsers);
  36. if ($i !== false) {
  37. unset($cachedUsers[$i]);
  38. }
  39. });
  40. }
  41. /**
  42. * register a user backend
  43. *
  44. * @param \OC_User_Backend $backend
  45. */
  46. public function registerBackend($backend) {
  47. $this->backends[] = $backend;
  48. }
  49. /**
  50. * remove a user backend
  51. *
  52. * @param \OC_User_Backend $backend
  53. */
  54. public function removeBackend($backend) {
  55. $this->cachedUsers = array();
  56. if (($i = array_search($backend, $this->backends)) !== false) {
  57. unset($this->backends[$i]);
  58. }
  59. }
  60. /**
  61. * remove all user backends
  62. */
  63. public function clearBackends() {
  64. $this->cachedUsers = array();
  65. $this->backends = array();
  66. }
  67. /**
  68. * get a user by user id
  69. *
  70. * @param string $uid
  71. * @return \OC\User\User
  72. */
  73. public function get($uid) {
  74. if (isset($this->cachedUsers[$uid])) { //check the cache first to prevent having to loop over the backends
  75. return $this->cachedUsers[$uid];
  76. }
  77. foreach ($this->backends as $backend) {
  78. if ($backend->userExists($uid)) {
  79. return $this->getUserObject($uid, $backend);
  80. }
  81. }
  82. return null;
  83. }
  84. /**
  85. * get or construct the user object
  86. *
  87. * @param string $uid
  88. * @param \OC_User_Backend $backend
  89. * @return \OC\User\User
  90. */
  91. protected function getUserObject($uid, $backend) {
  92. if (isset($this->cachedUsers[$uid])) {
  93. return $this->cachedUsers[$uid];
  94. }
  95. $this->cachedUsers[$uid] = new User($uid, $backend, $this);
  96. return $this->cachedUsers[$uid];
  97. }
  98. /**
  99. * check if a user exists
  100. *
  101. * @param string $uid
  102. * @return bool
  103. */
  104. public function userExists($uid) {
  105. $user = $this->get($uid);
  106. return ($user !== null);
  107. }
  108. /**
  109. * search by user id
  110. *
  111. * @param string $pattern
  112. * @param int $limit
  113. * @param int $offset
  114. * @return \OC\User\User[]
  115. */
  116. public function search($pattern, $limit = null, $offset = null) {
  117. $users = array();
  118. foreach ($this->backends as $backend) {
  119. $backendUsers = $backend->getUsers($pattern, $limit, $offset);
  120. if (is_array($backendUsers)) {
  121. foreach ($backendUsers as $uid) {
  122. $users[] = $this->getUserObject($uid, $backend);
  123. if (!is_null($limit)) {
  124. $limit--;
  125. }
  126. if (!is_null($offset) and $offset > 0) {
  127. $offset--;
  128. }
  129. }
  130. }
  131. }
  132. usort($users, function ($a, $b) {
  133. /**
  134. * @var \OC\User\User $a
  135. * @var \OC\User\User $b
  136. */
  137. return strcmp($a->getUID(), $b->getUID());
  138. });
  139. return $users;
  140. }
  141. /**
  142. * search by displayName
  143. *
  144. * @param string $pattern
  145. * @param int $limit
  146. * @param int $offset
  147. * @return \OC\User\User[]
  148. */
  149. public function searchDisplayName($pattern, $limit = null, $offset = null) {
  150. $users = array();
  151. foreach ($this->backends as $backend) {
  152. $backendUsers = $backend->getDisplayNames($pattern, $limit, $offset);
  153. if (is_array($backendUsers)) {
  154. foreach ($backendUsers as $uid => $displayName) {
  155. $users[] = $this->getUserObject($uid, $backend);
  156. if (!is_null($limit)) {
  157. $limit--;
  158. }
  159. if (!is_null($offset) and $offset > 0) {
  160. $offset--;
  161. }
  162. }
  163. }
  164. }
  165. usort($users, function ($a, $b) {
  166. /**
  167. * @var \OC\User\User $a
  168. * @var \OC\User\User $b
  169. */
  170. return strcmp($a->getDisplayName(), $b->getDisplayName());
  171. });
  172. return $users;
  173. }
  174. /**
  175. * @param string $uid
  176. * @param string $password
  177. * @throws \Exception
  178. * @return bool | \OC\User\User the created user of false
  179. */
  180. public function createUser($uid, $password) {
  181. // Check the name for bad characters
  182. // Allowed are: "a-z", "A-Z", "0-9" and "_.@-"
  183. if (preg_match('/[^a-zA-Z0-9 _\.@\-]/', $uid)) {
  184. throw new \Exception('Only the following characters are allowed in a username:'
  185. . ' "a-z", "A-Z", "0-9", and "_.@-"');
  186. }
  187. // No empty username
  188. if (trim($uid) == '') {
  189. throw new \Exception('A valid username must be provided');
  190. }
  191. // No empty password
  192. if (trim($password) == '') {
  193. throw new \Exception('A valid password must be provided');
  194. }
  195. // Check if user already exists
  196. if ($this->userExists($uid)) {
  197. throw new \Exception('The username is already being used');
  198. }
  199. $this->emit('\OC\User', 'preCreateUser', array($uid, $password));
  200. foreach ($this->backends as $backend) {
  201. if ($backend->implementsActions(\OC_USER_BACKEND_CREATE_USER)) {
  202. $backend->createUser($uid, $password);
  203. $user = $this->getUserObject($uid, $backend);
  204. $this->emit('\OC\User', 'postCreateUser', array($user, $password));
  205. return $user;
  206. }
  207. }
  208. return false;
  209. }
  210. }