LoginController.php 3.8 KB

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