]> git.immae.eu Git - github/shaarli/Shaarli.git/blame - application/front/controller/visitor/LoginController.php
Merge pull request #1601 from ArthurHoaro/feature/psr3
[github/shaarli/Shaarli.git] / application / front / controller / visitor / LoginController.php
CommitLineData
6c50a6cc
A
1<?php
2
3declare(strict_types=1);
4
2899ebb5 5namespace Shaarli\Front\Controller\Visitor;
6c50a6cc 6
a8c11451 7use Shaarli\Front\Exception\CantLoginException;
6c50a6cc 8use Shaarli\Front\Exception\LoginBannedException;
a8c11451 9use Shaarli\Front\Exception\WrongTokenException;
1a8ac737 10use Shaarli\Render\TemplatePage;
a8c11451
A
11use Shaarli\Security\CookieManager;
12use Shaarli\Security\SessionManager;
6c50a6cc
A
13use Slim\Http\Request;
14use Slim\Http\Response;
15
16/**
17 * Class LoginController
18 *
19 * Slim controller used to render the login page.
20 *
21 * The login page is not available if the user is banned
22 * or if open shaarli setting is enabled.
6c50a6cc 23 */
2899ebb5 24class LoginController extends ShaarliVisitorController
6c50a6cc 25{
a8c11451
A
26 /**
27 * GET /login - Display the login page.
28 */
6c50a6cc
A
29 public function index(Request $request, Response $response): Response
30 {
a8c11451
A
31 try {
32 $this->checkLoginState();
33 } catch (CantLoginException $e) {
9c75f877 34 return $this->redirect($response, '/');
6c50a6cc
A
35 }
36
a8c11451
A
37 if ($request->getParam('login') !== null) {
38 $this->assignView('username', escape($request->getParam('login')));
6c50a6cc
A
39 }
40
a8c11451 41 $returnUrl = $request->getParam('returnurl') ?? $this->container->environment['HTTP_REFERER'] ?? null;
6c50a6cc
A
42
43 $this
a8c11451 44 ->assignView('returnurl', escape($returnUrl))
27ceea2a
A
45 ->assignView('remember_user_default', $this->container->conf->get('privacy.remember_user_default', true))
46 ->assignView('pagetitle', t('Login') .' - '. $this->container->conf->get('general.title', 'Shaarli'))
6c50a6cc
A
47 ;
48
1a8ac737 49 return $response->write($this->render(TemplatePage::LOGIN));
6c50a6cc 50 }
a8c11451
A
51
52 /**
53 * POST /login - Process login
54 */
55 public function login(Request $request, Response $response): Response
56 {
57 if (!$this->container->sessionManager->checkToken($request->getParam('token'))) {
58 throw new WrongTokenException();
59 }
60
61 try {
62 $this->checkLoginState();
63 } catch (CantLoginException $e) {
64 return $this->redirect($response, '/');
65 }
66
67 if (!$this->container->loginManager->checkCredentials(
a8c11451
A
68 client_ip_id($this->container->environment),
69 $request->getParam('login'),
70 $request->getParam('password')
71 )
72 ) {
73 $this->container->loginManager->handleFailedLogin($this->container->environment);
74
75 $this->container->sessionManager->setSessionParameter(
76 SessionManager::KEY_ERROR_MESSAGES,
77 [t('Wrong login/password.')]
78 );
79
80 // Call controller directly instead of unnecessary redirection
81 return $this->index($request, $response);
82 }
83
84 $this->container->loginManager->handleSuccessfulLogin($this->container->environment);
85
86 $cookiePath = $this->container->basePath . '/';
87 $expirationTime = $this->saveLongLastingSession($request, $cookiePath);
88 $this->renewUserSession($cookiePath, $expirationTime);
89
90 // Force referer from given return URL
91 $this->container->environment['HTTP_REFERER'] = $request->getParam('returnurl');
92
a285668e 93 return $this->redirectFromReferer($request, $response, ['login', 'install']);
a8c11451
A
94 }
95
96 /**
97 * Make sure that the user is allowed to login and/or displaying the login page:
98 * - not already logged in
99 * - not open shaarli
100 * - not banned
101 */
102 protected function checkLoginState(): bool
103 {
104 if ($this->container->loginManager->isLoggedIn()
105 || $this->container->conf->get('security.open_shaarli', false)
106 ) {
107 throw new CantLoginException();
108 }
109
110 if (true !== $this->container->loginManager->canLogin($this->container->environment)) {
111 throw new LoginBannedException();
112 }
113
114 return true;
115 }
116
117 /**
118 * @return int Session duration in seconds
119 */
120 protected function saveLongLastingSession(Request $request, string $cookiePath): int
121 {
122 if (empty($request->getParam('longlastingsession'))) {
123 // Standard session expiration (=when browser closes)
124 $expirationTime = 0;
125 } else {
126 // Keep the session cookie even after the browser closes
127 $this->container->sessionManager->setStaySignedIn(true);
128 $expirationTime = $this->container->sessionManager->extendSession();
129 }
130
131 $this->container->cookieManager->setCookieParameter(
132 CookieManager::STAY_SIGNED_IN,
133 $this->container->loginManager->getStaySignedInToken(),
134 $expirationTime,
135 $cookiePath
136 );
137
138 return $expirationTime;
139 }
140
141 protected function renewUserSession(string $cookiePath, int $expirationTime): void
142 {
143 // Send cookie with the new expiration date to the browser
144 $this->container->sessionManager->destroy();
145 $this->container->sessionManager->cookieParameters(
146 $expirationTime,
147 $cookiePath,
148 $this->container->environment['SERVER_NAME']
149 );
150 $this->container->sessionManager->start();
151 $this->container->sessionManager->regenerateId(true);
152 }
6c50a6cc 153}