PageRenderTime 51ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/plugins/Login/Auth.php

https://github.com/CodeYellowBV/piwik
PHP | 250 lines | 117 code | 26 blank | 107 comment | 9 complexity | cafd78bc601c21615426eb76ad793d54 MD5 | raw file
Possible License(s): LGPL-3.0, JSON, MIT, GPL-3.0, LGPL-2.1, GPL-2.0, AGPL-1.0, BSD-2-Clause, BSD-3-Clause
  1. <?php
  2. /**
  3. * Piwik - free/libre analytics platform
  4. *
  5. * @link http://piwik.org
  6. * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
  7. *
  8. */
  9. namespace Piwik\Plugins\Login;
  10. use Exception;
  11. use Piwik\AuthResult;
  12. use Piwik\Config;
  13. use Piwik\Cookie;
  14. use Piwik\Db;
  15. use Piwik\Piwik;
  16. use Piwik\Plugins\UsersManager\API;
  17. use Piwik\Plugins\UsersManager\Model;
  18. use Piwik\ProxyHttp;
  19. use Piwik\Session;
  20. /**
  21. *
  22. */
  23. class Auth implements \Piwik\Auth
  24. {
  25. protected $login = null;
  26. protected $token_auth = null;
  27. /**
  28. * Authentication module's name, e.g., "Login"
  29. *
  30. * @return string
  31. */
  32. public function getName()
  33. {
  34. return 'Login';
  35. }
  36. /**
  37. * Authenticates user
  38. *
  39. * @return AuthResult
  40. */
  41. public function authenticate()
  42. {
  43. if (is_null($this->login)) {
  44. $model = new Model();
  45. $user = $model->getUserByTokenAuth($this->token_auth);
  46. if (!empty($user['login'])) {
  47. $code = $user['superuser_access'] ? AuthResult::SUCCESS_SUPERUSER_AUTH_CODE : AuthResult::SUCCESS;
  48. return new AuthResult($code, $user['login'], $this->token_auth);
  49. }
  50. } else if (!empty($this->login)) {
  51. $model = new Model();
  52. $user = $model->getUser($this->login);
  53. if (!empty($user['token_auth'])
  54. && (($this->getHashTokenAuth($this->login, $user['token_auth']) === $this->token_auth)
  55. || $user['token_auth'] === $this->token_auth)
  56. ) {
  57. $this->setTokenAuth($user['token_auth']);
  58. $code = !empty($user['superuser_access']) ? AuthResult::SUCCESS_SUPERUSER_AUTH_CODE : AuthResult::SUCCESS;
  59. return new AuthResult($code, $this->login, $user['token_auth']);
  60. }
  61. }
  62. return new AuthResult(AuthResult::FAILURE, $this->login, $this->token_auth);
  63. }
  64. /**
  65. * Authenticates the user and initializes the session.
  66. */
  67. public function initSession($login, $md5Password, $rememberMe)
  68. {
  69. $this->regenerateSessionId();
  70. $authResult = $this->doAuthenticateSession($login, $md5Password);
  71. if (!$authResult->wasAuthenticationSuccessful()) {
  72. $this->processFailedSession($rememberMe);
  73. } else {
  74. $this->processSuccessfulSession($login, $authResult->getTokenAuth(), $rememberMe);
  75. }
  76. /**
  77. * Triggered after session initialize.
  78. * This event notify about end of init session process.
  79. *
  80. * **Example**
  81. *
  82. * Piwik::addAction('Login.initSession.end', function () {
  83. * // session has been initialized
  84. * });
  85. */
  86. Piwik::postEvent('Login.initSession.end');
  87. }
  88. /**
  89. * Accessor to set login name
  90. *
  91. * @param string $login user login
  92. */
  93. public function setLogin($login)
  94. {
  95. $this->login = $login;
  96. }
  97. /**
  98. * Accessor to set authentication token
  99. *
  100. * @param string $token_auth authentication token
  101. */
  102. public function setTokenAuth($token_auth)
  103. {
  104. $this->token_auth = $token_auth;
  105. }
  106. /**
  107. * Accessor to compute the hashed authentication token
  108. *
  109. * @param string $login user login
  110. * @param string $token_auth authentication token
  111. * @return string hashed authentication token
  112. */
  113. public function getHashTokenAuth($login, $token_auth)
  114. {
  115. return md5($login . $token_auth);
  116. }
  117. /**
  118. * @param $login
  119. * @param $md5Password
  120. * @return AuthResult
  121. * @throws \Exception
  122. */
  123. protected function doAuthenticateSession($login, $md5Password)
  124. {
  125. $tokenAuth = API::getInstance()->getTokenAuth($login, $md5Password);
  126. $this->setLogin($login);
  127. $this->setTokenAuth($tokenAuth);
  128. /**
  129. * Triggered before authenticate function.
  130. * This event propagate login and token_auth which will be using in authenticate process.
  131. *
  132. * This event exists to enable possibility for user authentication prevention.
  133. * For example when user is locked or inactive.
  134. *
  135. * **Example**
  136. *
  137. * Piwik::addAction('Login.authenticate', function ($login, $tokenAuth) {
  138. * if (!UserActivityManager::isActive ($login, $tokenAuth) {
  139. * throw new Exception('Your account is inactive.');
  140. * }
  141. * });
  142. *
  143. * @param string $login User login.
  144. * @param string $tokenAuth User token auth.
  145. */
  146. Piwik::postEvent(
  147. 'Login.authenticate',
  148. array(
  149. $login,
  150. $tokenAuth
  151. )
  152. );
  153. $authResult = $this->authenticate();
  154. return $authResult;
  155. }
  156. /**
  157. * @param $rememberMe
  158. * @return Cookie
  159. */
  160. protected function getAuthCookie($rememberMe)
  161. {
  162. $authCookieName = Config::getInstance()->General['login_cookie_name'];
  163. $authCookieExpiry = $rememberMe ? time() + Config::getInstance()->General['login_cookie_expire'] : 0;
  164. $authCookiePath = Config::getInstance()->General['login_cookie_path'];
  165. $cookie = new Cookie($authCookieName, $authCookieExpiry, $authCookiePath);
  166. return $cookie;
  167. }
  168. /**
  169. * Executed when the session could not authenticate
  170. * @param $rememberMe
  171. * @throws \Exception
  172. */
  173. protected function processFailedSession($rememberMe)
  174. {
  175. $cookie = $this->getAuthCookie($rememberMe);
  176. $cookie->delete();
  177. throw new Exception(Piwik::translate('Login_LoginPasswordNotCorrect'));
  178. }
  179. /**
  180. * Executed when the session was successfully authenticated
  181. * @param $login
  182. * @param $tokenAuth
  183. * @param $rememberMe
  184. */
  185. protected function processSuccessfulSession($login, $tokenAuth, $rememberMe)
  186. {
  187. /**
  188. * Triggered after successful authenticate, but before cookie creation.
  189. * This event propagate login and token_auth which was used in authenticate process.
  190. *
  191. * This event exists to enable the ability to custom action before the cookie will be created,
  192. * but after a successful authentication.
  193. * For example when user have to fill survey or change password.
  194. *
  195. * **Example**
  196. *
  197. * Piwik::addAction('Login.authenticate.successful', function ($login, $tokenAuth) {
  198. * // redirect to change password action
  199. * });
  200. *
  201. * @param string $login User login.
  202. * @param string $tokenAuth User token auth.
  203. */
  204. Piwik::postEvent(
  205. 'Login.authenticate.successful',
  206. array(
  207. $login,
  208. $tokenAuth
  209. )
  210. );
  211. $cookie = $this->getAuthCookie($rememberMe);
  212. $cookie->set('login', $login);
  213. $cookie->set('token_auth', $this->getHashTokenAuth($login, $tokenAuth));
  214. $cookie->setSecure(ProxyHttp::isHttps());
  215. $cookie->setHttpOnly(true);
  216. $cookie->save();
  217. // remove password reset entry if it exists
  218. Login::removePasswordResetInfo($login);
  219. }
  220. protected function regenerateSessionId()
  221. {
  222. Session::regenerateId();
  223. }
  224. }