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