You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

session.php 6.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  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\Emitter;
  10. use OCP\IUserSession;
  11. /**
  12. * Class Session
  13. *
  14. * Hooks available in scope \OC\User:
  15. * - preSetPassword(\OC\User\User $user, string $password, string $recoverPassword)
  16. * - postSetPassword(\OC\User\User $user, string $password, string $recoverPassword)
  17. * - preDelete(\OC\User\User $user)
  18. * - postDelete(\OC\User\User $user)
  19. * - preCreateUser(string $uid, string $password)
  20. * - postCreateUser(\OC\User\User $user)
  21. * - preLogin(string $user, string $password)
  22. * - postLogin(\OC\User\User $user, string $password)
  23. * - preRememberedLogin(string $uid)
  24. * - postRememberedLogin(\OC\User\User $user)
  25. * - logout()
  26. *
  27. * @package OC\User
  28. */
  29. class Session implements IUserSession, Emitter {
  30. /**
  31. * @var \OC\User\Manager $manager
  32. */
  33. private $manager;
  34. /**
  35. * @var \OC\Session\Session $session
  36. */
  37. private $session;
  38. /**
  39. * @var \OC\User\User $activeUser
  40. */
  41. protected $activeUser;
  42. /**
  43. * @param \OCP\IUserManager $manager
  44. * @param \OCP\ISession $session
  45. */
  46. public function __construct(\OCP\IUserManager $manager, \OCP\ISession $session) {
  47. $this->manager = $manager;
  48. $this->session = $session;
  49. }
  50. /**
  51. * @param string $scope
  52. * @param string $method
  53. * @param callable $callback
  54. */
  55. public function listen($scope, $method, $callback) {
  56. $this->manager->listen($scope, $method, $callback);
  57. }
  58. /**
  59. * @param string $scope optional
  60. * @param string $method optional
  61. * @param callable $callback optional
  62. */
  63. public function removeListener($scope = null, $method = null, $callback = null) {
  64. $this->manager->removeListener($scope, $method, $callback);
  65. }
  66. /**
  67. * get the manager object
  68. *
  69. * @return \OC\User\Manager
  70. */
  71. public function getManager() {
  72. return $this->manager;
  73. }
  74. /**
  75. * get the session object
  76. *
  77. * @return \OCP\ISession
  78. */
  79. public function getSession() {
  80. return $this->session;
  81. }
  82. /**
  83. * set the session object
  84. *
  85. * @param \OCP\ISession $session
  86. */
  87. public function setSession(\OCP\ISession $session) {
  88. if ($this->session instanceof \OCP\ISession) {
  89. $this->session->close();
  90. }
  91. $this->session = $session;
  92. $this->activeUser = null;
  93. }
  94. /**
  95. * set the currently active user
  96. *
  97. * @param \OC\User\User|null $user
  98. */
  99. public function setUser($user) {
  100. if (is_null($user)) {
  101. $this->session->remove('user_id');
  102. } else {
  103. $this->session->set('user_id', $user->getUID());
  104. }
  105. $this->activeUser = $user;
  106. }
  107. /**
  108. * get the current active user
  109. *
  110. * @return \OC\User\User
  111. */
  112. public function getUser() {
  113. if ($this->activeUser) {
  114. return $this->activeUser;
  115. } else {
  116. $uid = $this->session->get('user_id');
  117. if ($uid !== null) {
  118. $this->activeUser = $this->manager->get($uid);
  119. return $this->activeUser;
  120. } else {
  121. return null;
  122. }
  123. }
  124. }
  125. /**
  126. * set the login name
  127. *
  128. * @param string|null $loginName for the logged in user
  129. */
  130. public function setLoginName($loginName) {
  131. if (is_null($loginName)) {
  132. $this->session->remove('loginname');
  133. } else {
  134. $this->session->set('loginname', $loginName);
  135. }
  136. }
  137. /**
  138. * get the login name of the current user
  139. *
  140. * @return string
  141. */
  142. public function getLoginName() {
  143. if ($this->activeUser) {
  144. return $this->session->get('loginname');
  145. } else {
  146. $uid = $this->session->get('user_id');
  147. if ($uid) {
  148. $this->activeUser = $this->manager->get($uid);
  149. return $this->session->get('loginname');
  150. } else {
  151. return null;
  152. }
  153. }
  154. }
  155. /**
  156. * try to login with the provided credentials
  157. *
  158. * @param string $uid
  159. * @param string $password
  160. * @return boolean|null
  161. */
  162. public function login($uid, $password) {
  163. $this->manager->emit('\OC\User', 'preLogin', array($uid, $password));
  164. $user = $this->manager->checkPassword($uid, $password);
  165. if ($user !== false) {
  166. if (!is_null($user)) {
  167. if ($user->isEnabled()) {
  168. $this->setUser($user);
  169. $this->setLoginName($uid);
  170. $this->manager->emit('\OC\User', 'postLogin', array($user, $password));
  171. return true;
  172. } else {
  173. return false;
  174. }
  175. }
  176. } else {
  177. return false;
  178. }
  179. }
  180. /**
  181. * perform login using the magic cookie (remember login)
  182. *
  183. * @param string $uid the username
  184. * @param string $currentToken
  185. * @return bool
  186. */
  187. public function loginWithCookie($uid, $currentToken) {
  188. $this->manager->emit('\OC\User', 'preRememberedLogin', array($uid));
  189. $user = $this->manager->get($uid);
  190. if (is_null($user)) {
  191. // user does not exist
  192. return false;
  193. }
  194. // get stored tokens
  195. $tokens = \OC::$server->getConfig()->getUserKeys($uid, 'login_token');
  196. // test cookies token against stored tokens
  197. if (!in_array($currentToken, $tokens, true)) {
  198. return false;
  199. }
  200. // replace successfully used token with a new one
  201. \OC::$server->getConfig()->deleteUserValue($uid, 'login_token', $currentToken);
  202. $newToken = \OC::$server->getSecureRandom()->getMediumStrengthGenerator()->generate(32);
  203. \OC::$server->getConfig()->setUserValue($uid, 'login_token', $newToken, time());
  204. $this->setMagicInCookie($user->getUID(), $newToken);
  205. //login
  206. $this->setUser($user);
  207. $this->manager->emit('\OC\User', 'postRememberedLogin', array($user));
  208. return true;
  209. }
  210. /**
  211. * logout the user from the session
  212. */
  213. public function logout() {
  214. $this->manager->emit('\OC\User', 'logout');
  215. $this->setUser(null);
  216. $this->setLoginName(null);
  217. $this->unsetMagicInCookie();
  218. $this->session->clear();
  219. }
  220. /**
  221. * Set cookie value to use in next page load
  222. *
  223. * @param string $username username to be set
  224. * @param string $token
  225. */
  226. public function setMagicInCookie($username, $token) {
  227. $secure_cookie = \OC_Config::getValue("forcessl", false); //TODO: DI for cookies and OC_Config
  228. $expires = time() + \OC_Config::getValue('remember_login_cookie_lifetime', 60 * 60 * 24 * 15);
  229. setcookie("oc_username", $username, $expires, \OC::$WEBROOT, '', $secure_cookie);
  230. setcookie("oc_token", $token, $expires, \OC::$WEBROOT, '', $secure_cookie, true);
  231. setcookie("oc_remember_login", "1", $expires, \OC::$WEBROOT, '', $secure_cookie);
  232. }
  233. /**
  234. * Remove cookie for "remember username"
  235. */
  236. public function unsetMagicInCookie() {
  237. unset($_COOKIE["oc_username"]); //TODO: DI
  238. unset($_COOKIE["oc_token"]);
  239. unset($_COOKIE["oc_remember_login"]);
  240. setcookie('oc_username', '', time() - 3600, \OC::$WEBROOT);
  241. setcookie('oc_token', '', time() - 3600, \OC::$WEBROOT);
  242. setcookie('oc_remember_login', '', time() - 3600, \OC::$WEBROOT);
  243. // old cookies might be stored under /webroot/ instead of /webroot
  244. // and Firefox doesn't like it!
  245. setcookie('oc_username', '', time() - 3600, \OC::$WEBROOT . '/');
  246. setcookie('oc_token', '', time() - 3600, \OC::$WEBROOT . '/');
  247. setcookie('oc_remember_login', '', time() - 3600, \OC::$WEBROOT . '/');
  248. }
  249. }