LoginController.php 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. <?php
  2. namespace App\Controllers;
  3. use Psr\Http\Message\ResponseInterface as Response;
  4. use Psr\Http\Message\ServerRequestInterface as Request;
  5. class LoginController extends Controller
  6. {
  7. /**
  8. * @param Response $response
  9. *
  10. * @throws \Twig\Error\LoaderError
  11. * @throws \Twig\Error\RuntimeError
  12. * @throws \Twig\Error\SyntaxError
  13. *
  14. * @return Response
  15. */
  16. public function show(Response $response): Response
  17. {
  18. if ($this->session->get('logged', false)) {
  19. return redirect($response, route('home'));
  20. }
  21. return view()->render($response, 'auth/login.twig');
  22. }
  23. /**
  24. * @param Request $request
  25. * @param Response $response
  26. *
  27. * @throws \Exception
  28. *
  29. * @return Response
  30. */
  31. public function login(Request $request, Response $response): Response
  32. {
  33. $username = param($request, 'username');
  34. $result = $this->database->query('SELECT `id`, `email`, `username`, `password`,`is_admin`, `active` FROM `users` WHERE `username` = ? OR `email` = ? LIMIT 1', [$username, $username])->fetch();
  35. if (!$result || !password_verify(param($request, 'password'), $result->password)) {
  36. $this->session->alert(lang('bad_login'), 'danger');
  37. return redirect($response, route('login'));
  38. }
  39. if (isset($this->config['maintenance']) && $this->config['maintenance'] && !$result->is_admin) {
  40. $this->session->alert(lang('maintenance_in_progress'), 'info');
  41. return redirect($response, route('login'));
  42. }
  43. if (!$result->active) {
  44. $this->session->alert(lang('account_disabled'), 'danger');
  45. return redirect($response, route('login'));
  46. }
  47. $this->session->set('logged', true);
  48. $this->session->set('user_id', $result->id);
  49. $this->session->set('username', $result->username);
  50. $this->session->set('admin', $result->is_admin);
  51. $this->session->set('used_space', humanFileSize($this->getUsedSpaceByUser($result->id)));
  52. $this->session->alert(lang('welcome', [$result->username]), 'info');
  53. $this->logger->info("User $result->username logged in.");
  54. if (param($request, 'remember') === 'on') {
  55. $selector = bin2hex(random_bytes(8));
  56. $token = bin2hex(random_bytes(32));
  57. $expire = time() + 604800; // a week
  58. $this->database->query('UPDATE `users` SET `remember_selector`=?, `remember_token`=?, `remember_expire`=? WHERE `id`=?', [
  59. $selector,
  60. password_hash($token, PASSWORD_DEFAULT),
  61. date('Y-m-d\TH:i:s', $expire),
  62. $result->id,
  63. ]);
  64. // Workaround for php <= 7.3
  65. if (PHP_VERSION_ID < 70300) {
  66. setcookie('remember', "{$selector}:{$token}", $expire, '; SameSite=Lax', '', false, true);
  67. } else {
  68. setcookie('remember', "{$selector}:{$token}", [
  69. 'expires' => $expire,
  70. 'httponly' => true,
  71. 'samesite' => 'Lax',
  72. ]);
  73. }
  74. }
  75. if ($this->session->has('redirectTo')) {
  76. return redirect($response, $this->session->get('redirectTo'));
  77. }
  78. return redirect($response, route('home'));
  79. }
  80. /**
  81. * @param Request $request
  82. * @param Response $response
  83. *
  84. * @return Response
  85. */
  86. public function logout(Request $request, Response $response): Response
  87. {
  88. $this->session->clear();
  89. $this->session->set('logged', false);
  90. $this->session->alert(lang('goodbye'), 'warning');
  91. if (!empty($request->getCookieParams()['remember'])) {
  92. setcookie('remember', null);
  93. }
  94. return redirect($response, route('login.show'));
  95. }
  96. }