checkLoginState(); } catch (CantLoginException $e) { return $this->redirect($response, '/'); } if ($request->getParam('login') !== null) { $this->assignView('username', escape($request->getParam('login'))); } $returnUrl = $request->getParam('returnurl') ?? $this->container->environment['HTTP_REFERER'] ?? null; $this ->assignView('returnurl', escape($returnUrl)) ->assignView('remember_user_default', $this->container->conf->get('privacy.remember_user_default', true)) ->assignView('pagetitle', t('Login') . ' - ' . $this->container->conf->get('general.title', 'Shaarli')) ; return $response->write($this->render(TemplatePage::LOGIN)); } /** * POST /login - Process login */ public function login(Request $request, Response $response): Response { if (!$this->container->sessionManager->checkToken($request->getParam('token'))) { throw new WrongTokenException(); } try { $this->checkLoginState(); } catch (CantLoginException $e) { return $this->redirect($response, '/'); } if ( !$this->container->loginManager->checkCredentials( client_ip_id($this->container->environment), $request->getParam('login'), $request->getParam('password') ) ) { $this->container->loginManager->handleFailedLogin($this->container->environment); $this->container->sessionManager->setSessionParameter( SessionManager::KEY_ERROR_MESSAGES, [t('Wrong login/password.')] ); // Call controller directly instead of unnecessary redirection return $this->index($request, $response); } $this->container->loginManager->handleSuccessfulLogin($this->container->environment); $cookiePath = $this->container->basePath . '/'; $expirationTime = $this->saveLongLastingSession($request, $cookiePath); $this->renewUserSession($cookiePath, $expirationTime); // Force referer from given return URL $this->container->environment['HTTP_REFERER'] = $request->getParam('returnurl'); return $this->redirectFromReferer($request, $response, ['login', 'install']); } /** * Make sure that the user is allowed to login and/or displaying the login page: * - not already logged in * - not open shaarli * - not banned */ protected function checkLoginState(): bool { if ( $this->container->loginManager->isLoggedIn() || $this->container->conf->get('security.open_shaarli', false) ) { throw new CantLoginException(); } if (true !== $this->container->loginManager->canLogin($this->container->environment)) { throw new LoginBannedException(); } return true; } /** * @return int Session duration in seconds */ protected function saveLongLastingSession(Request $request, string $cookiePath): int { if (empty($request->getParam('longlastingsession'))) { // Standard session expiration (=when browser closes) $expirationTime = 0; } else { // Keep the session cookie even after the browser closes $this->container->sessionManager->setStaySignedIn(true); $expirationTime = $this->container->sessionManager->extendSession(); } $this->container->cookieManager->setCookieParameter( CookieManager::STAY_SIGNED_IN, $this->container->loginManager->getStaySignedInToken(), $expirationTime, $cookiePath ); return $expirationTime; } protected function renewUserSession(string $cookiePath, int $expirationTime): void { // Send cookie with the new expiration date to the browser $this->container->sessionManager->destroy(); $this->container->sessionManager->cookieParameters( $expirationTime, $cookiePath, $this->container->environment['SERVER_NAME'] ); $this->container->sessionManager->start(); $this->container->sessionManager->regenerateId(true); } }