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 $this->container
->environment
['REMOTE_ADDR'],
69 client_ip_id($this->container
->environment
),
70 $request->getParam('login'),
71 $request->getParam('password')
74 $this->container
->loginManager
->handleFailedLogin($this->container
->environment
);
76 $this->container
->sessionManager
->setSessionParameter(
77 SessionManager
::KEY_ERROR_MESSAGES
,
78 [t('Wrong login/password.')]
81 // Call controller directly instead of unnecessary redirection
82 return $this->index($request, $response);
85 $this->container
->loginManager
->handleSuccessfulLogin($this->container
->environment
);
87 $cookiePath = $this->container
->basePath
. '/';
88 $expirationTime = $this->saveLongLastingSession($request, $cookiePath);
89 $this->renewUserSession($cookiePath, $expirationTime);
91 // Force referer from given return URL
92 $this->container
->environment
['HTTP_REFERER'] = $request->getParam('returnurl');
94 return $this->redirectFromReferer($request, $response, ['login', 'install']);
98 * Make sure that the user is allowed to login and/or displaying the login page:
99 * - not already logged in
103 protected function checkLoginState(): bool
105 if ($this->container
->loginManager
->isLoggedIn()
106 || $this->container
->conf
->get('security.open_shaarli', false)
108 throw new CantLoginException();
111 if (true !== $this->container
->loginManager
->canLogin($this->container
->environment
)) {
112 throw new LoginBannedException();
119 * @return int Session duration in seconds
121 protected function saveLongLastingSession(Request
$request, string $cookiePath): int
123 if (empty($request->getParam('longlastingsession'))) {
124 // Standard session expiration (=when browser closes)
127 // Keep the session cookie even after the browser closes
128 $this->container
->sessionManager
->setStaySignedIn(true);
129 $expirationTime = $this->container
->sessionManager
->extendSession();
132 $this->container
->cookieManager
->setCookieParameter(
133 CookieManager
::STAY_SIGNED_IN
,
134 $this->container
->loginManager
->getStaySignedInToken(),
139 return $expirationTime;
142 protected function renewUserSession(string $cookiePath, int $expirationTime): void
144 // Send cookie with the new expiration date to the browser
145 $this->container
->sessionManager
->destroy();
146 $this->container
->sessionManager
->cookieParameters(
149 $this->container
->environment
['SERVER_NAME']
151 $this->container
->sessionManager
->start();
152 $this->container
->sessionManager
->regenerateId(true);