3 declare(strict_types
=1);
5 namespace Shaarli\Front\Controller\Visitor
;
7 use Shaarli\Front\Exception\CantLoginException
;
8 use Shaarli\Front\Exception\LoginBannedException
;
9 use Shaarli\Front\Exception\WrongTokenException
;
10 use Shaarli\Render\TemplatePage
;
11 use Shaarli\Security\CookieManager
;
12 use Shaarli\Security\SessionManager
;
13 use Slim\Http\Request
;
14 use Slim\Http\Response
;
17 * Class LoginController
19 * Slim controller used to render the login page.
21 * The login page is not available if the user is banned
22 * or if open shaarli setting is enabled.
24 class LoginController
extends ShaarliVisitorController
27 * GET /login - Display the login page.
29 public function index(Request
$request, Response
$response): Response
32 $this->checkLoginState();
33 } catch (CantLoginException
$e) {
34 return $this->redirect($response, '/');
37 if ($request->getParam('login') !== null) {
38 $this->assignView('username', escape($request->getParam('login')));
41 $returnUrl = $request->getParam('returnurl') ?? $this->container
->environment
['HTTP_REFERER'] ?? null;
44 ->assignView('returnurl', escape($returnUrl))
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'))
49 return $response->write($this->render(TemplatePage
::LOGIN
));
53 * POST /login - Process login
55 public function login(Request
$request, Response
$response): Response
57 if (!$this->container
->sessionManager
->checkToken($request->getParam('token'))) {
58 throw new WrongTokenException();
62 $this->checkLoginState();
63 } catch (CantLoginException
$e) {
64 return $this->redirect($response, '/');
67 if (!$this->container
->loginManager
->checkCredentials(
68 client_ip_id($this->container
->environment
),
69 $request->getParam('login'),
70 $request->getParam('password')
73 $this->container
->loginManager
->handleFailedLogin($this->container
->environment
);
75 $this->container
->sessionManager
->setSessionParameter(
76 SessionManager
::KEY_ERROR_MESSAGES
,
77 [t('Wrong login/password.')]
80 // Call controller directly instead of unnecessary redirection
81 return $this->index($request, $response);
84 $this->container
->loginManager
->handleSuccessfulLogin($this->container
->environment
);
86 $cookiePath = $this->container
->basePath
. '/';
87 $expirationTime = $this->saveLongLastingSession($request, $cookiePath);
88 $this->renewUserSession($cookiePath, $expirationTime);
90 // Force referer from given return URL
91 $this->container
->environment
['HTTP_REFERER'] = $request->getParam('returnurl');
93 return $this->redirectFromReferer($request, $response, ['login', 'install']);
97 * Make sure that the user is allowed to login and/or displaying the login page:
98 * - not already logged in
102 protected function checkLoginState(): bool
104 if ($this->container
->loginManager
->isLoggedIn()
105 || $this->container
->conf
->get('security.open_shaarli', false)
107 throw new CantLoginException();
110 if (true !== $this->container
->loginManager
->canLogin($this->container
->environment
)) {
111 throw new LoginBannedException();
118 * @return int Session duration in seconds
120 protected function saveLongLastingSession(Request
$request, string $cookiePath): int
122 if (empty($request->getParam('longlastingsession'))) {
123 // Standard session expiration (=when browser closes)
126 // Keep the session cookie even after the browser closes
127 $this->container
->sessionManager
->setStaySignedIn(true);
128 $expirationTime = $this->container
->sessionManager
->extendSession();
131 $this->container
->cookieManager
->setCookieParameter(
132 CookieManager
::STAY_SIGNED_IN
,
133 $this->container
->loginManager
->getStaySignedInToken(),
138 return $expirationTime;
141 protected function renewUserSession(string $cookiePath, int $expirationTime): void
143 // Send cookie with the new expiration date to the browser
144 $this->container
->sessionManager
->destroy();
145 $this->container
->sessionManager
->cookieParameters(
148 $this->container
->environment
['SERVER_NAME']
150 $this->container
->sessionManager
->start();
151 $this->container
->sessionManager
->regenerateId(true);