PageRenderTime 48ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 1ms

/user/plugins/login/classes/Controller.php

https://gitlab.com/3dplex/3d-plex-main-site
PHP | 524 lines | 300 code | 87 blank | 137 comment | 42 complexity | 0d19fd1832716d92bdedbc37e9e04c5f MD5 | raw file
  1. <?php
  2. namespace Grav\Plugin\Login;
  3. <<<<<<< HEAD
  4. use Grav\Common\Grav;
  5. use Grav\Common\Utils;
  6. use Grav\Plugin\Login\RememberMe;
  7. use Birke\Rememberme\Cookie;
  8. class Controller implements ControllerInterface
  9. =======
  10. use Grav\Common\Config\Config;
  11. use Grav\Common\Grav;
  12. use Grav\Plugin\Login\RememberMe;
  13. use Grav\Common\Language\Language;
  14. use Grav\Common\User\User;
  15. use Grav\Common\Utils;
  16. use Grav\Plugin\Email\Utils as EmailUtils;
  17. use Birke\Rememberme\Cookie;
  18. use RocketTheme\Toolbox\Session\Message;
  19. /**
  20. * Class Controller
  21. * @package Grav\Plugin\Login
  22. */
  23. class Controller
  24. >>>>>>> update grav cms
  25. {
  26. /**
  27. * @var \Grav\Common\Grav
  28. */
  29. public $grav;
  30. /**
  31. * @var string
  32. */
  33. public $action;
  34. /**
  35. * @var array
  36. */
  37. public $post;
  38. /**
  39. * @var string
  40. */
  41. protected $redirect;
  42. /**
  43. * @var int
  44. */
  45. protected $redirectCode;
  46. /**
  47. * @var string
  48. */
  49. <<<<<<< HEAD
  50. protected $prefix = 'do';
  51. =======
  52. protected $prefix = 'task';
  53. >>>>>>> update grav cms
  54. /**
  55. * @var \Birke\Rememberme\Authenticator
  56. */
  57. protected $rememberMe;
  58. /**
  59. <<<<<<< HEAD
  60. =======
  61. * @var Login
  62. */
  63. protected $login;
  64. /**
  65. >>>>>>> update grav cms
  66. * @param Grav $grav
  67. * @param string $action
  68. * @param array $post
  69. */
  70. public function __construct(Grav $grav, $action, $post = null)
  71. {
  72. $this->grav = $grav;
  73. $this->action = $action;
  74. <<<<<<< HEAD
  75. =======
  76. $this->login = isset($this->grav['login']) ? $this->grav['login'] : '';
  77. >>>>>>> update grav cms
  78. $this->post = $this->getPost($post);
  79. $this->rememberMe();
  80. }
  81. /**
  82. * Performs an action.
  83. */
  84. public function execute()
  85. {
  86. // Set redirect if available.
  87. if (isset($this->post['_redirect'])) {
  88. $redirect = $this->post['_redirect'];
  89. unset($this->post['_redirect']);
  90. }
  91. $success = false;
  92. $method = $this->prefix . ucfirst($this->action);
  93. if (!method_exists($this, $method)) {
  94. throw new \RuntimeException('Page Not Found', 404);
  95. }
  96. try {
  97. <<<<<<< HEAD
  98. $success = call_user_func(array($this, $method));
  99. =======
  100. $success = call_user_func([$this, $method]);
  101. >>>>>>> update grav cms
  102. } catch (\RuntimeException $e) {
  103. $this->setMessage($e->getMessage(), 'error');
  104. }
  105. if (!$this->redirect && isset($redirect)) {
  106. $this->setRedirect($redirect);
  107. }
  108. return $success;
  109. }
  110. /**
  111. <<<<<<< HEAD
  112. =======
  113. * Handle login.
  114. *
  115. * @return bool True if the action was performed.
  116. */
  117. public function taskLogin()
  118. {
  119. /** @var Language $t */
  120. $t = $this->grav['language'];
  121. if ($this->authenticate($this->post)) {
  122. $this->login->setMessage($t->translate('PLUGIN_LOGIN.LOGIN_SUCCESSFUL'));
  123. $redirect = $this->grav['config']->get('plugins.login.redirect_after_login');
  124. if (!$redirect) {
  125. $redirect = $this->grav['uri']->referrer('/');
  126. }
  127. $this->setRedirect($redirect);
  128. } else {
  129. $user = $this->grav['user'];
  130. if ($user->username) {
  131. $this->setMessage($t->translate('PLUGIN_LOGIN.ACCESS_DENIED'), 'error');
  132. } else {
  133. $this->setMessage($t->translate('PLUGIN_LOGIN.LOGIN_FAILED'), 'error');
  134. }
  135. }
  136. return true;
  137. }
  138. /**
  139. * Handle logout.
  140. *
  141. * @return bool True if the action was performed.
  142. */
  143. public function taskLogout()
  144. {
  145. /** @var User $user */
  146. $user = $this->grav['user'];
  147. if (!$this->rememberMe->login()) {
  148. $credentials = $user->get('username');
  149. $this->rememberMe->getStorage()->cleanAllTriplets($credentials);
  150. }
  151. $this->rememberMe->clearCookie();
  152. $this->grav['session']->invalidate()->start();
  153. $this->setRedirect('/');
  154. return true;
  155. }
  156. /**
  157. * Handle the email password recovery procedure.
  158. *
  159. * @return bool True if the action was performed.
  160. */
  161. protected function taskForgot()
  162. {
  163. $param_sep = $this->grav['config']->get('system.param_sep', ':');
  164. $data = $this->post;
  165. $username = isset($data['username']) ? $data['username'] : '';
  166. $user = !empty($username) ? User::load($username) : null;
  167. /** @var Language $l */
  168. $language = $this->grav['language'];
  169. $messages = $this->grav['messages'];
  170. if (!isset($this->grav['Email'])) {
  171. $messages->add($language->translate('PLUGIN_LOGIN.FORGOT_EMAIL_NOT_CONFIGURED'), 'error');
  172. $this->setRedirect('/');
  173. return true;
  174. }
  175. if (!$user || !$user->exists()) {
  176. $messages->add($language->translate(['PLUGIN_LOGIN.FORGOT_USERNAME_DOES_NOT_EXIST', $username]), 'error');
  177. $this->setRedirect($this->grav['config']->get('plugins.login.route_forgot'));
  178. return true;
  179. }
  180. if (empty($user->email)) {
  181. $messages->add($language->translate(['PLUGIN_LOGIN.FORGOT_CANNOT_RESET_EMAIL_NO_EMAIL', $username]),
  182. 'error');
  183. $this->setRedirect($this->grav['config']->get('plugins.login.route_forgot'));
  184. return true;
  185. }
  186. $token = md5(uniqid(mt_rand(), true));
  187. $expire = time() + 604800; // next week
  188. $user->reset = $token . '::' . $expire;
  189. $user->save();
  190. $author = $this->grav['config']->get('site.author.name', '');
  191. $fullname = $user->fullname ?: $username;
  192. $reset_link = $this->grav['base_url_absolute'] . $this->grav['config']->get('plugins.login.route_reset') . '/task:login.reset/token' . $param_sep . $token . '/user' . $param_sep . $username . '/nonce' . $param_sep . Utils::getNonce('reset-form');
  193. $sitename = $this->grav['config']->get('site.title', 'Website');
  194. $from = $this->grav['config']->get('plugins.email.from');
  195. if (empty($from)) {
  196. $messages->add($language->translate('PLUGIN_LOGIN.FORGOT_EMAIL_NOT_CONFIGURED'), 'error');
  197. $this->setRedirect($this->grav['config']->get('plugins.login.route_forgot'));
  198. return true;
  199. }
  200. $to = $user->email;
  201. $subject = $language->translate(['PLUGIN_LOGIN.FORGOT_EMAIL_SUBJECT', $sitename]);
  202. $content = $language->translate(['PLUGIN_LOGIN.FORGOT_EMAIL_BODY', $fullname, $reset_link, $author, $sitename]);
  203. $sent = EmailUtils::sendEmail($subject, $content, $to);
  204. if ($sent < 1) {
  205. $messages->add($language->translate('PLUGIN_LOGIN.FORGOT_FAILED_TO_EMAIL'), 'error');
  206. } else {
  207. $messages->add($language->translate(['PLUGIN_LOGIN.FORGOT_INSTRUCTIONS_SENT_VIA_EMAIL', $to]), 'info');
  208. }
  209. $this->setRedirect('/');
  210. return true;
  211. }
  212. /**
  213. * Handle the reset password action.
  214. *
  215. * @return bool True if the action was performed.
  216. */
  217. public function taskReset()
  218. {
  219. $data = $this->post;
  220. $language = $this->grav['language'];
  221. $messages = $this->grav['messages'];
  222. if (isset($data['password'])) {
  223. $username = isset($data['username']) ? $data['username'] : null;
  224. $user = !empty($username) ? User::load($username) : null;
  225. $password = isset($data['password']) ? $data['password'] : null;
  226. $token = isset($data['token']) ? $data['token'] : null;
  227. if (!empty($user) && $user->exists() && !empty($user->reset)) {
  228. list($good_token, $expire) = explode('::', $user->reset);
  229. if ($good_token === $token) {
  230. if (time() > $expire) {
  231. $messages->add($language->translate('PLUGIN_LOGIN.RESET_LINK_EXPIRED'), 'error');
  232. $this->grav->redirect($this->grav['config']->get('plugins.login.route_forgot'));
  233. return true;
  234. }
  235. unset($user->hashed_password);
  236. unset($user->reset);
  237. $user->password = $password;
  238. $user->validate();
  239. $user->filter();
  240. $user->save();
  241. $messages->add($language->translate('PLUGIN_LOGIN.RESET_PASSWORD_RESET'), 'info');
  242. $this->grav->redirect('/');
  243. return true;
  244. }
  245. }
  246. $messages->add($language->translate('PLUGIN_LOGIN.RESET_INVALID_LINK'), 'error');
  247. $this->grav->redirect($this->grav['config']->get('plugins.login.route_forgot'));
  248. return true;
  249. } else {
  250. $user = $this->grav['uri']->param('user');
  251. $token = $this->grav['uri']->param('token');
  252. if (empty($user) || empty($token)) {
  253. $messages->add($language->translate('PLUGIN_LOGIN.RESET_INVALID_LINK'), 'error');
  254. $this->grav->redirect($this->grav['config']->get('plugins.login.route_forgot'));
  255. return true;
  256. }
  257. }
  258. return true;
  259. }
  260. /**
  261. * Authenticate user.
  262. *
  263. * @param array $form Form fields.
  264. *
  265. * @return bool
  266. */
  267. protected function authenticate($form)
  268. {
  269. /** @var User $user */
  270. $user = $this->grav['user'];
  271. if (!$user->authenticated) {
  272. $username = isset($form['username']) ? $form['username'] : $this->rememberMe->login();
  273. // Normal login process
  274. $user = User::load($username);
  275. if ($user->exists()) {
  276. if (!empty($form['username']) && !empty($form['password'])) {
  277. // Authenticate user
  278. $user->authenticated = $user->authenticate($form['password']);
  279. if ($user->authenticated) {
  280. $this->grav['session']->user = $user;
  281. unset($this->grav['user']);
  282. $this->grav['user'] = $user;
  283. // If the user wants to be remembered, create Rememberme cookie
  284. if (!empty($form['rememberme'])) {
  285. $this->rememberMe->createCookie($form['username']);
  286. } else {
  287. $this->rememberMe->clearCookie();
  288. $this->rememberMe->getStorage()->cleanAllTriplets($user->get('username'));
  289. }
  290. }
  291. }
  292. }
  293. }
  294. // Authorize against user ACL
  295. $user_authorized = $user->authorize('site.login');
  296. $user->authenticated = ($user->authenticated && $user_authorized);
  297. return $user->authenticated;
  298. }
  299. /**
  300. >>>>>>> update grav cms
  301. * Redirects an action
  302. */
  303. public function redirect()
  304. {
  305. if ($this->redirect) {
  306. $this->grav->redirect($this->redirect, $this->redirectCode);
  307. <<<<<<< HEAD
  308. } else if ($redirect = $this->grav['config']->get('plugins.login.redirect')) {
  309. $this->grav->redirect($redirect, $this->redirectCode);
  310. =======
  311. >>>>>>> update grav cms
  312. }
  313. }
  314. /**
  315. * Set redirect.
  316. *
  317. <<<<<<< HEAD
  318. * @param $path
  319. =======
  320. * @param $path
  321. >>>>>>> update grav cms
  322. * @param int $code
  323. */
  324. public function setRedirect($path, $code = 303)
  325. {
  326. $this->redirect = $path;
  327. <<<<<<< HEAD
  328. $this->code = $code;
  329. =======
  330. $this->redirectCode = $code;
  331. >>>>>>> update grav cms
  332. }
  333. /**
  334. * Add message into the session queue.
  335. *
  336. * @param string $msg
  337. * @param string $type
  338. */
  339. public function setMessage($msg, $type = 'info')
  340. {
  341. /** @var Message $messages */
  342. $messages = $this->grav['messages'];
  343. $messages->add($msg, $type);
  344. }
  345. /**
  346. * Gets and sets the RememberMe class
  347. *
  348. <<<<<<< HEAD
  349. * @param mixed $var A rememberMe instance to set
  350. *
  351. * @return Authenticator Returns the current rememberMe instance
  352. =======
  353. * @param mixed $var A rememberMe instance to set
  354. *
  355. * @return RememberMe\RememberMe Returns the current rememberMe instance
  356. >>>>>>> update grav cms
  357. */
  358. public function rememberMe($var = null)
  359. {
  360. if ($var !== null) {
  361. $this->rememberMe = $var;
  362. }
  363. <<<<<<< HEAD
  364. =======
  365. >>>>>>> update grav cms
  366. if (!$this->rememberMe) {
  367. /** @var Config $config */
  368. $config = $this->grav['config'];
  369. // Setup storage for RememberMe cookies
  370. $storage = new RememberMe\TokenStorage();
  371. $this->rememberMe = new RememberMe\RememberMe($storage);
  372. $this->rememberMe->setCookieName($config->get('plugins.login.rememberme.name'));
  373. $this->rememberMe->setExpireTime($config->get('plugins.login.rememberme.timeout'));
  374. // Hardening cookies with user-agent and random salt or
  375. // fallback to use system based cache key
  376. <<<<<<< HEAD
  377. $data = $_SERVER['HTTP_USER_AGENT'] . $config->get('security.salt', $this->grav['cache']->getKey());
  378. =======
  379. $server_agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : 'unknown';
  380. $data = $server_agent . $config->get('security.salt', $this->grav['cache']->getKey());
  381. >>>>>>> update grav cms
  382. $this->rememberMe->setSalt(hash('sha512', $data));
  383. // Set cookie with correct base path of Grav install
  384. $cookie = new Cookie();
  385. $cookie->setPath($this->grav['base_url_relative']);
  386. $this->rememberMe->setCookie($cookie);
  387. }
  388. return $this->rememberMe;
  389. }
  390. /**
  391. * Prepare and return POST data.
  392. *
  393. * @param array $post
  394. <<<<<<< HEAD
  395. =======
  396. *
  397. >>>>>>> update grav cms
  398. * @return array
  399. */
  400. protected function &getPost($post)
  401. {
  402. unset($post[$this->prefix]);
  403. // Decode JSON encoded fields and merge them to data.
  404. if (isset($post['_json'])) {
  405. $post = array_merge_recursive($post, $this->jsonDecode($post['_json']));
  406. unset($post['_json']);
  407. }
  408. <<<<<<< HEAD
  409. =======
  410. >>>>>>> update grav cms
  411. return $post;
  412. }
  413. /**
  414. * Recursively JSON decode data.
  415. *
  416. * @param array $data
  417. <<<<<<< HEAD
  418. =======
  419. *
  420. >>>>>>> update grav cms
  421. * @return array
  422. */
  423. protected function jsonDecode(array $data)
  424. {
  425. foreach ($data as &$value) {
  426. if (is_array($value)) {
  427. $value = $this->jsonDecode($value);
  428. } else {
  429. $value = json_decode($value, true);
  430. }
  431. }
  432. <<<<<<< HEAD
  433. =======
  434. >>>>>>> update grav cms
  435. return $data;
  436. }
  437. }