user.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
  1. <?php
  2. /**
  3. * @author Aldo "xoen" Giambelluca <xoen@xoen.org>
  4. * @author Andreas Fischer <bantu@owncloud.com>
  5. * @author Arthur Schiwon <blizzz@owncloud.com>
  6. * @author Bartek Przybylski <bart.p.pl@gmail.com>
  7. * @author Bart Visscher <bartv@thisnet.nl>
  8. * @author Björn Schießle <schiessle@owncloud.com>
  9. * @author Dominik Schmidt <dev@dominik-schmidt.de>
  10. * @author Florian Preinstorfer <nblock@archlinux.us>
  11. * @author Georg Ehrke <georg@owncloud.com>
  12. * @author Jakob Sack <mail@jakobsack.de>
  13. * @author Jörn Friedrich Dreyer <jfd@butonic.de>
  14. * @author Lukas Reschke <lukas@owncloud.com>
  15. * @author Morris Jobke <hey@morrisjobke.de>
  16. * @author Robin Appelman <icewind@owncloud.com>
  17. * @author Robin McCorkell <rmccorkell@karoshi.org.uk>
  18. * @author Scrutinizer Auto-Fixer <auto-fixer@scrutinizer-ci.com>
  19. * @author shkdee <louis.traynard@m4x.org>
  20. * @author Thomas Müller <thomas.mueller@tmit.eu>
  21. * @author Tom Needham <tom@owncloud.com>
  22. * @author Victor Dubiniuk <dubiniuk@owncloud.com>
  23. *
  24. * @copyright Copyright (c) 2015, ownCloud, Inc.
  25. * @license AGPL-3.0
  26. *
  27. * This code is free software: you can redistribute it and/or modify
  28. * it under the terms of the GNU Affero General Public License, version 3,
  29. * as published by the Free Software Foundation.
  30. *
  31. * This program is distributed in the hope that it will be useful,
  32. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  33. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  34. * GNU Affero General Public License for more details.
  35. *
  36. * You should have received a copy of the GNU Affero General Public License, version 3,
  37. * along with this program. If not, see <http://www.gnu.org/licenses/>
  38. *
  39. */
  40. /**
  41. * This class provides wrapper methods for user management. Multiple backends are
  42. * supported. User management operations are delegated to the configured backend for
  43. * execution.
  44. *
  45. * Hooks provided:
  46. * pre_createUser(&run, uid, password)
  47. * post_createUser(uid, password)
  48. * pre_deleteUser(&run, uid)
  49. * post_deleteUser(uid)
  50. * pre_setPassword(&run, uid, password, recoveryPassword)
  51. * post_setPassword(uid, password, recoveryPassword)
  52. * pre_login(&run, uid, password)
  53. * post_login(uid)
  54. * logout()
  55. */
  56. class OC_User {
  57. /**
  58. * @return \OC\User\Session
  59. */
  60. public static function getUserSession() {
  61. return OC::$server->getUserSession();
  62. }
  63. /**
  64. * @return \OC\User\Manager
  65. * @deprecated Use \OC::$server->getUserManager()
  66. */
  67. public static function getManager() {
  68. return OC::$server->getUserManager();
  69. }
  70. private static $_backends = array();
  71. private static $_usedBackends = array();
  72. private static $_setupedBackends = array();
  73. // bool, stores if a user want to access a resource anonymously, e.g if he opens a public link
  74. private static $incognitoMode = false;
  75. /**
  76. * registers backend
  77. *
  78. * @param string $backend name of the backend
  79. * @deprecated Add classes by calling OC_User::useBackend() with a class instance instead
  80. * @return bool
  81. *
  82. * Makes a list of backends that can be used by other modules
  83. */
  84. public static function registerBackend($backend) {
  85. self::$_backends[] = $backend;
  86. return true;
  87. }
  88. /**
  89. * gets available backends
  90. *
  91. * @deprecated
  92. * @return array an array of backends
  93. *
  94. * Returns the names of all backends.
  95. */
  96. public static function getBackends() {
  97. return self::$_backends;
  98. }
  99. /**
  100. * gets used backends
  101. *
  102. * @deprecated
  103. * @return array an array of backends
  104. *
  105. * Returns the names of all used backends.
  106. */
  107. public static function getUsedBackends() {
  108. return array_keys(self::$_usedBackends);
  109. }
  110. /**
  111. * Adds the backend to the list of used backends
  112. *
  113. * @param string|OC_User_Interface $backend default: database The backend to use for user management
  114. * @return bool
  115. *
  116. * Set the User Authentication Module
  117. */
  118. public static function useBackend($backend = 'database') {
  119. if ($backend instanceof OC_User_Interface) {
  120. self::$_usedBackends[get_class($backend)] = $backend;
  121. self::getManager()->registerBackend($backend);
  122. } else {
  123. // You'll never know what happens
  124. if (null === $backend OR !is_string($backend)) {
  125. $backend = 'database';
  126. }
  127. // Load backend
  128. switch ($backend) {
  129. case 'database':
  130. case 'mysql':
  131. case 'sqlite':
  132. OC_Log::write('core', 'Adding user backend ' . $backend . '.', OC_Log::DEBUG);
  133. self::$_usedBackends[$backend] = new OC_User_Database();
  134. self::getManager()->registerBackend(self::$_usedBackends[$backend]);
  135. break;
  136. default:
  137. OC_Log::write('core', 'Adding default user backend ' . $backend . '.', OC_Log::DEBUG);
  138. $className = 'OC_USER_' . strToUpper($backend);
  139. self::$_usedBackends[$backend] = new $className();
  140. self::getManager()->registerBackend(self::$_usedBackends[$backend]);
  141. break;
  142. }
  143. }
  144. return true;
  145. }
  146. /**
  147. * remove all used backends
  148. */
  149. public static function clearBackends() {
  150. self::$_usedBackends = array();
  151. self::getManager()->clearBackends();
  152. }
  153. /**
  154. * setup the configured backends in config.php
  155. */
  156. public static function setupBackends() {
  157. OC_App::loadApps(array('prelogin'));
  158. $backends = OC_Config::getValue('user_backends', array());
  159. foreach ($backends as $i => $config) {
  160. $class = $config['class'];
  161. $arguments = $config['arguments'];
  162. if (class_exists($class)) {
  163. if (array_search($i, self::$_setupedBackends) === false) {
  164. // make a reflection object
  165. $reflectionObj = new ReflectionClass($class);
  166. // use Reflection to create a new instance, using the $args
  167. $backend = $reflectionObj->newInstanceArgs($arguments);
  168. self::useBackend($backend);
  169. self::$_setupedBackends[] = $i;
  170. } else {
  171. OC_Log::write('core', 'User backend ' . $class . ' already initialized.', OC_Log::DEBUG);
  172. }
  173. } else {
  174. OC_Log::write('core', 'User backend ' . $class . ' not found.', OC_Log::ERROR);
  175. }
  176. }
  177. }
  178. /**
  179. * Create a new user
  180. *
  181. * @param string $uid The username of the user to create
  182. * @param string $password The password of the new user
  183. * @throws Exception
  184. * @return bool true/false
  185. *
  186. * Creates a new user. Basic checking of username is done in OC_User
  187. * itself, not in its subclasses.
  188. *
  189. * Allowed characters in the username are: "a-z", "A-Z", "0-9" and "_.@-"
  190. * @deprecated Use \OC::$server->getUserManager()->createUser($uid, $password)
  191. */
  192. public static function createUser($uid, $password) {
  193. return self::getManager()->createUser($uid, $password);
  194. }
  195. /**
  196. * delete a user
  197. *
  198. * @param string $uid The username of the user to delete
  199. * @return bool
  200. *
  201. * Deletes a user
  202. * @deprecated Use \OC::$server->getUserManager()->get() and then run delete() on the return
  203. */
  204. public static function deleteUser($uid) {
  205. $user = self::getManager()->get($uid);
  206. if ($user) {
  207. return $user->delete();
  208. } else {
  209. return false;
  210. }
  211. }
  212. /**
  213. * Try to login a user
  214. *
  215. * @param string $loginname The login name of the user to log in
  216. * @param string $password The password of the user
  217. * @return boolean|null
  218. *
  219. * Log in a user and regenerate a new session - if the password is ok
  220. */
  221. public static function login($loginname, $password) {
  222. session_regenerate_id(true);
  223. $result = self::getUserSession()->login($loginname, $password);
  224. if ($result) {
  225. //we need to pass the user name, which may differ from login name
  226. $user = self::getUserSession()->getUser()->getUID();
  227. OC_Util::setupFS($user);
  228. //trigger creation of user home and /files folder
  229. \OC::$server->getUserFolder($user);
  230. }
  231. return $result;
  232. }
  233. /**
  234. * Try to login a user using the magic cookie (remember login)
  235. *
  236. * @param string $uid The username of the user to log in
  237. * @param string $token
  238. * @return bool
  239. */
  240. public static function loginWithCookie($uid, $token) {
  241. return self::getUserSession()->loginWithCookie($uid, $token);
  242. }
  243. /**
  244. * Try to login a user, assuming authentication
  245. * has already happened (e.g. via Single Sign On).
  246. *
  247. * Log in a user and regenerate a new session.
  248. *
  249. * @param \OCP\Authentication\IApacheBackend $backend
  250. * @return bool
  251. */
  252. public static function loginWithApache(\OCP\Authentication\IApacheBackend $backend) {
  253. $uid = $backend->getCurrentUserId();
  254. $run = true;
  255. OC_Hook::emit("OC_User", "pre_login", array("run" => &$run, "uid" => $uid));
  256. if ($uid) {
  257. self::setUserId($uid);
  258. self::setDisplayName($uid);
  259. self::getUserSession()->setLoginName($uid);
  260. OC_Hook::emit("OC_User", "post_login", array("uid" => $uid, 'password' => ''));
  261. return true;
  262. }
  263. return false;
  264. }
  265. /**
  266. * Verify with Apache whether user is authenticated.
  267. *
  268. * @return boolean|null
  269. * true: authenticated
  270. * false: not authenticated
  271. * null: not handled / no backend available
  272. */
  273. public static function handleApacheAuth() {
  274. $backend = self::findFirstActiveUsedBackend();
  275. if ($backend) {
  276. OC_App::loadApps();
  277. //setup extra user backends
  278. self::setupBackends();
  279. self::unsetMagicInCookie();
  280. return self::loginWithApache($backend);
  281. }
  282. return null;
  283. }
  284. /**
  285. * Sets user id for session and triggers emit
  286. */
  287. public static function setUserId($uid) {
  288. $userSession = \OC::$server->getUserSession();
  289. $userManager = \OC::$server->getUserManager();
  290. if ($user = $userManager->get($uid)) {
  291. $userSession->setUser($user);
  292. } else {
  293. \OC::$server->getSession()->set('user_id', $uid);
  294. }
  295. }
  296. /**
  297. * Sets user display name for session
  298. *
  299. * @param string $uid
  300. * @param null $displayName
  301. * @return bool Whether the display name could get set
  302. */
  303. public static function setDisplayName($uid, $displayName = null) {
  304. if (is_null($displayName)) {
  305. $displayName = $uid;
  306. }
  307. $user = self::getManager()->get($uid);
  308. if ($user) {
  309. return $user->setDisplayName($displayName);
  310. } else {
  311. return false;
  312. }
  313. }
  314. /**
  315. * Logs the current user out and kills all the session data
  316. *
  317. * Logout, destroys session
  318. */
  319. public static function logout() {
  320. self::getUserSession()->logout();
  321. }
  322. /**
  323. * Tries to login the user with HTTP Basic Authentication
  324. */
  325. public static function tryBasicAuthLogin() {
  326. if (!empty($_SERVER['PHP_AUTH_USER']) && !empty($_SERVER['PHP_AUTH_PW'])) {
  327. \OC_User::login($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']);
  328. }
  329. }
  330. /**
  331. * Check if the user is logged in, considers also the HTTP basic credentials
  332. *
  333. * @return bool
  334. */
  335. public static function isLoggedIn() {
  336. if (\OC::$server->getSession()->get('user_id') !== null && self::$incognitoMode === false) {
  337. return self::userExists(\OC::$server->getSession()->get('user_id'));
  338. }
  339. return false;
  340. }
  341. /**
  342. * set incognito mode, e.g. if a user wants to open a public link
  343. *
  344. * @param bool $status
  345. */
  346. public static function setIncognitoMode($status) {
  347. self::$incognitoMode = $status;
  348. }
  349. /**
  350. * get incognito mode status
  351. *
  352. * @return bool
  353. */
  354. public static function isIncognitoMode() {
  355. return self::$incognitoMode;
  356. }
  357. /**
  358. * Supplies an attribute to the logout hyperlink. The default behaviour
  359. * is to return an href with '?logout=true' appended. However, it can
  360. * supply any attribute(s) which are valid for <a>.
  361. *
  362. * @return string with one or more HTML attributes.
  363. */
  364. public static function getLogoutAttribute() {
  365. $backend = self::findFirstActiveUsedBackend();
  366. if ($backend) {
  367. return $backend->getLogoutAttribute();
  368. }
  369. return 'href="' . link_to('', 'index.php') . '?logout=true&requesttoken=' . urlencode(OC_Util::callRegister()) . '"';
  370. }
  371. /**
  372. * Check if the user is an admin user
  373. *
  374. * @param string $uid uid of the admin
  375. * @return bool
  376. */
  377. public static function isAdminUser($uid) {
  378. if (OC_Group::inGroup($uid, 'admin') && self::$incognitoMode === false) {
  379. return true;
  380. }
  381. return false;
  382. }
  383. /**
  384. * get the user id of the user currently logged in.
  385. *
  386. * @return string|bool uid or false
  387. */
  388. public static function getUser() {
  389. $uid = \OC::$server->getSession() ? \OC::$server->getSession()->get('user_id') : null;
  390. if (!is_null($uid) && self::$incognitoMode === false) {
  391. return $uid;
  392. } else {
  393. return false;
  394. }
  395. }
  396. /**
  397. * get the display name of the user currently logged in.
  398. *
  399. * @param string $uid
  400. * @return string uid or false
  401. */
  402. public static function getDisplayName($uid = null) {
  403. if ($uid) {
  404. $user = self::getManager()->get($uid);
  405. if ($user) {
  406. return $user->getDisplayName();
  407. } else {
  408. return $uid;
  409. }
  410. } else {
  411. $user = self::getUserSession()->getUser();
  412. if ($user) {
  413. return $user->getDisplayName();
  414. } else {
  415. return false;
  416. }
  417. }
  418. }
  419. /**
  420. * Autogenerate a password
  421. *
  422. * @return string
  423. *
  424. * generates a password
  425. */
  426. public static function generatePassword() {
  427. return \OC::$server->getSecureRandom()->getMediumStrengthGenerator()->generate(30);
  428. }
  429. /**
  430. * Set password
  431. *
  432. * @param string $uid The username
  433. * @param string $password The new password
  434. * @param string $recoveryPassword for the encryption app to reset encryption keys
  435. * @return bool
  436. *
  437. * Change the password of a user
  438. */
  439. public static function setPassword($uid, $password, $recoveryPassword = null) {
  440. $user = self::getManager()->get($uid);
  441. if ($user) {
  442. return $user->setPassword($password, $recoveryPassword);
  443. } else {
  444. return false;
  445. }
  446. }
  447. /**
  448. * Check whether user can change his avatar
  449. *
  450. * @param string $uid The username
  451. * @return bool
  452. *
  453. * Check whether a specified user can change his avatar
  454. */
  455. public static function canUserChangeAvatar($uid) {
  456. $user = self::getManager()->get($uid);
  457. if ($user) {
  458. return $user->canChangeAvatar();
  459. } else {
  460. return false;
  461. }
  462. }
  463. /**
  464. * Check whether user can change his password
  465. *
  466. * @param string $uid The username
  467. * @return bool
  468. *
  469. * Check whether a specified user can change his password
  470. */
  471. public static function canUserChangePassword($uid) {
  472. $user = self::getManager()->get($uid);
  473. if ($user) {
  474. return $user->canChangePassword();
  475. } else {
  476. return false;
  477. }
  478. }
  479. /**
  480. * Check whether user can change his display name
  481. *
  482. * @param string $uid The username
  483. * @return bool
  484. *
  485. * Check whether a specified user can change his display name
  486. */
  487. public static function canUserChangeDisplayName($uid) {
  488. $user = self::getManager()->get($uid);
  489. if ($user) {
  490. return $user->canChangeDisplayName();
  491. } else {
  492. return false;
  493. }
  494. }
  495. /**
  496. * Check if the password is correct
  497. *
  498. * @param string $uid The username
  499. * @param string $password The password
  500. * @return string|false user id a string on success, false otherwise
  501. *
  502. * Check if the password is correct without logging in the user
  503. * returns the user id or false
  504. */
  505. public static function checkPassword($uid, $password) {
  506. $manager = self::getManager();
  507. $username = $manager->checkPassword($uid, $password);
  508. if ($username !== false) {
  509. return $username->getUID();
  510. }
  511. return false;
  512. }
  513. /**
  514. * @param string $uid The username
  515. * @return string
  516. *
  517. * returns the path to the users home directory
  518. * @deprecated Use \OC::$server->getUserManager->getHome()
  519. */
  520. public static function getHome($uid) {
  521. $user = self::getManager()->get($uid);
  522. if ($user) {
  523. return $user->getHome();
  524. } else {
  525. return OC_Config::getValue('datadirectory', OC::$SERVERROOT . '/data') . '/' . $uid;
  526. }
  527. }
  528. /**
  529. * Get a list of all users
  530. *
  531. * @return array an array of all uids
  532. *
  533. * Get a list of all users.
  534. * @param string $search
  535. * @param integer $limit
  536. * @param integer $offset
  537. */
  538. public static function getUsers($search = '', $limit = null, $offset = null) {
  539. $users = self::getManager()->search($search, $limit, $offset);
  540. $uids = array();
  541. foreach ($users as $user) {
  542. $uids[] = $user->getUID();
  543. }
  544. return $uids;
  545. }
  546. /**
  547. * Get a list of all users display name
  548. *
  549. * @param string $search
  550. * @param int $limit
  551. * @param int $offset
  552. * @return array associative array with all display names (value) and corresponding uids (key)
  553. *
  554. * Get a list of all display names and user ids.
  555. * @deprecated Use \OC::$server->getUserManager->searchDisplayName($search, $limit, $offset) instead.
  556. */
  557. public static function getDisplayNames($search = '', $limit = null, $offset = null) {
  558. $displayNames = array();
  559. $users = self::getManager()->searchDisplayName($search, $limit, $offset);
  560. foreach ($users as $user) {
  561. $displayNames[$user->getUID()] = $user->getDisplayName();
  562. }
  563. return $displayNames;
  564. }
  565. /**
  566. * check if a user exists
  567. *
  568. * @param string $uid the username
  569. * @return boolean
  570. */
  571. public static function userExists($uid) {
  572. return self::getManager()->userExists($uid);
  573. }
  574. /**
  575. * disables a user
  576. *
  577. * @param string $uid the user to disable
  578. */
  579. public static function disableUser($uid) {
  580. $user = self::getManager()->get($uid);
  581. if ($user) {
  582. $user->setEnabled(false);
  583. }
  584. }
  585. /**
  586. * enable a user
  587. *
  588. * @param string $uid
  589. */
  590. public static function enableUser($uid) {
  591. $user = self::getManager()->get($uid);
  592. if ($user) {
  593. $user->setEnabled(true);
  594. }
  595. }
  596. /**
  597. * checks if a user is enabled
  598. *
  599. * @param string $uid
  600. * @return bool
  601. */
  602. public static function isEnabled($uid) {
  603. $user = self::getManager()->get($uid);
  604. if ($user) {
  605. return $user->isEnabled();
  606. } else {
  607. return false;
  608. }
  609. }
  610. /**
  611. * Set cookie value to use in next page load
  612. *
  613. * @param string $username username to be set
  614. * @param string $token
  615. */
  616. public static function setMagicInCookie($username, $token) {
  617. self::getUserSession()->setMagicInCookie($username, $token);
  618. }
  619. /**
  620. * Remove cookie for "remember username"
  621. */
  622. public static function unsetMagicInCookie() {
  623. self::getUserSession()->unsetMagicInCookie();
  624. }
  625. /**
  626. * Returns the first active backend from self::$_usedBackends.
  627. *
  628. * @return OCP\Authentication\IApacheBackend|null if no backend active, otherwise OCP\Authentication\IApacheBackend
  629. */
  630. private static function findFirstActiveUsedBackend() {
  631. foreach (self::$_usedBackends as $backend) {
  632. if ($backend instanceof OCP\Authentication\IApacheBackend) {
  633. if ($backend->isSessionActive()) {
  634. return $backend;
  635. }
  636. }
  637. }
  638. return null;
  639. }
  640. }