]> git.immae.eu Git - github/shaarli/Shaarli.git/blob - application/front/controller/visitor/LoginController.php
Apply PHP Code Beautifier on source code for linter automatic fixes
[github/shaarli/Shaarli.git] / application / front / controller / visitor / LoginController.php
1 <?php
2
3 declare(strict_types=1);
4
5 namespace Shaarli\Front\Controller\Visitor;
6
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;
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.
23 */
24 class LoginController extends ShaarliVisitorController
25 {
26 /**
27 * GET /login - Display the login page.
28 */
29 public function index(Request $request, Response $response): Response
30 {
31 try {
32 $this->checkLoginState();
33 } catch (CantLoginException $e) {
34 return $this->redirect($response, '/');
35 }
36
37 if ($request->getParam('login') !== null) {
38 $this->assignView('username', escape($request->getParam('login')));
39 }
40
41 $returnUrl = $request->getParam('returnurl') ?? $this->container->environment['HTTP_REFERER'] ?? null;
42
43 $this
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'))
47 ;
48
49 return $response->write($this->render(TemplatePage::LOGIN));
50 }
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 (
68 !$this->container->loginManager->checkCredentials(
69 client_ip_id($this->container->environment),
70 $request->getParam('login'),
71 $request->getParam('password')
72 )
73 ) {
74 $this->container->loginManager->handleFailedLogin($this->container->environment);
75
76 $this->container->sessionManager->setSessionParameter(
77 SessionManager::KEY_ERROR_MESSAGES,
78 [t('Wrong login/password.')]
79 );
80
81 // Call controller directly instead of unnecessary redirection
82 return $this->index($request, $response);
83 }
84
85 $this->container->loginManager->handleSuccessfulLogin($this->container->environment);
86
87 $cookiePath = $this->container->basePath . '/';
88 $expirationTime = $this->saveLongLastingSession($request, $cookiePath);
89 $this->renewUserSession($cookiePath, $expirationTime);
90
91 // Force referer from given return URL
92 $this->container->environment['HTTP_REFERER'] = $request->getParam('returnurl');
93
94 return $this->redirectFromReferer($request, $response, ['login', 'install']);
95 }
96
97 /**
98 * Make sure that the user is allowed to login and/or displaying the login page:
99 * - not already logged in
100 * - not open shaarli
101 * - not banned
102 */
103 protected function checkLoginState(): bool
104 {
105 if (
106 $this->container->loginManager->isLoggedIn()
107 || $this->container->conf->get('security.open_shaarli', false)
108 ) {
109 throw new CantLoginException();
110 }
111
112 if (true !== $this->container->loginManager->canLogin($this->container->environment)) {
113 throw new LoginBannedException();
114 }
115
116 return true;
117 }
118
119 /**
120 * @return int Session duration in seconds
121 */
122 protected function saveLongLastingSession(Request $request, string $cookiePath): int
123 {
124 if (empty($request->getParam('longlastingsession'))) {
125 // Standard session expiration (=when browser closes)
126 $expirationTime = 0;
127 } else {
128 // Keep the session cookie even after the browser closes
129 $this->container->sessionManager->setStaySignedIn(true);
130 $expirationTime = $this->container->sessionManager->extendSession();
131 }
132
133 $this->container->cookieManager->setCookieParameter(
134 CookieManager::STAY_SIGNED_IN,
135 $this->container->loginManager->getStaySignedInToken(),
136 $expirationTime,
137 $cookiePath
138 );
139
140 return $expirationTime;
141 }
142
143 protected function renewUserSession(string $cookiePath, int $expirationTime): void
144 {
145 // Send cookie with the new expiration date to the browser
146 $this->container->sessionManager->destroy();
147 $this->container->sessionManager->cookieParameters(
148 $expirationTime,
149 $cookiePath,
150 $this->container->environment['SERVER_NAME']
151 );
152 $this->container->sessionManager->start();
153 $this->container->sessionManager->regenerateId(true);
154 }
155 }