Process login through Slim controller
This commit is contained in:
parent
c4ad3d4f06
commit
a8c11451e8
8 changed files with 442 additions and 99 deletions
application/front
|
@ -62,7 +62,9 @@ class ShaarliMiddleware
|
|||
|
||||
return $response->write($this->container->pageBuilder->render('error'));
|
||||
} catch (UnauthorizedException $e) {
|
||||
return $response->withRedirect($this->container->basePath . '/login');
|
||||
$returnUrl = urlencode($this->container->environment['REQUEST_URI']);
|
||||
|
||||
return $response->withRedirect($this->container->basePath . '/login?returnurl=' . $returnUrl);
|
||||
} catch (\Throwable $e) {
|
||||
// Unknown error encountered
|
||||
$this->container->pageBuilder->reset();
|
||||
|
|
|
@ -4,8 +4,12 @@ declare(strict_types=1);
|
|||
|
||||
namespace Shaarli\Front\Controller\Visitor;
|
||||
|
||||
use Shaarli\Front\Exception\CantLoginException;
|
||||
use Shaarli\Front\Exception\LoginBannedException;
|
||||
use Shaarli\Front\Exception\WrongTokenException;
|
||||
use Shaarli\Render\TemplatePage;
|
||||
use Shaarli\Security\CookieManager;
|
||||
use Shaarli\Security\SessionManager;
|
||||
use Slim\Http\Request;
|
||||
use Slim\Http\Response;
|
||||
|
||||
|
@ -19,29 +23,132 @@ use Slim\Http\Response;
|
|||
*/
|
||||
class LoginController extends ShaarliVisitorController
|
||||
{
|
||||
/**
|
||||
* GET /login - Display the login page.
|
||||
*/
|
||||
public function index(Request $request, Response $response): Response
|
||||
{
|
||||
if ($this->container->loginManager->isLoggedIn()
|
||||
|| $this->container->conf->get('security.open_shaarli', false)
|
||||
) {
|
||||
try {
|
||||
$this->checkLoginState();
|
||||
} catch (CantLoginException $e) {
|
||||
return $this->redirect($response, '/');
|
||||
}
|
||||
|
||||
$userCanLogin = $this->container->loginManager->canLogin($request->getServerParams());
|
||||
if ($userCanLogin !== true) {
|
||||
throw new LoginBannedException();
|
||||
if ($request->getParam('login') !== null) {
|
||||
$this->assignView('username', escape($request->getParam('login')));
|
||||
}
|
||||
|
||||
if ($request->getParam('username') !== null) {
|
||||
$this->assignView('username', escape($request->getParam('username')));
|
||||
}
|
||||
$returnUrl = $request->getParam('returnurl') ?? $this->container->environment['HTTP_REFERER'] ?? null;
|
||||
|
||||
$this
|
||||
->assignView('returnurl', escape($request->getServerParam('HTTP_REFERER')))
|
||||
->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(
|
||||
$this->container->environment['REMOTE_ADDR'],
|
||||
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']);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
|
10
application/front/exceptions/CantLoginException.php
Normal file
10
application/front/exceptions/CantLoginException.php
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Shaarli\Front\Exception;
|
||||
|
||||
class CantLoginException extends \Exception
|
||||
{
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue