From 6c50a6ccceecf54850e62c312ab2397b84d89ab4 Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Sat, 18 Jan 2020 17:50:11 +0100 Subject: Render login page through Slim controller --- application/container/ContainerBuilder.php | 77 ++++++++++++++++++++++ application/container/ShaarliContainer.php | 28 ++++++++ application/front/ShaarliMiddleware.php | 57 ++++++++++++++++ application/front/controllers/LoginController.php | 46 +++++++++++++ .../front/controllers/ShaarliController.php | 31 +++++++++ .../front/exceptions/LoginBannedException.php | 15 +++++ application/front/exceptions/ShaarliException.php | 23 +++++++ application/render/PageBuilder.php | 17 +++++ application/security/SessionManager.php | 6 ++ 9 files changed, 300 insertions(+) create mode 100644 application/container/ContainerBuilder.php create mode 100644 application/container/ShaarliContainer.php create mode 100644 application/front/ShaarliMiddleware.php create mode 100644 application/front/controllers/LoginController.php create mode 100644 application/front/controllers/ShaarliController.php create mode 100644 application/front/exceptions/LoginBannedException.php create mode 100644 application/front/exceptions/ShaarliException.php (limited to 'application') diff --git a/application/container/ContainerBuilder.php b/application/container/ContainerBuilder.php new file mode 100644 index 00000000..ff29825c --- /dev/null +++ b/application/container/ContainerBuilder.php @@ -0,0 +1,77 @@ +conf = $conf; + $this->session = $session; + $this->login = $login; + } + + public function build(): ShaarliContainer + { + $container = new ShaarliContainer(); + $container['conf'] = $this->conf; + $container['sessionManager'] = $this->session; + $container['loginManager'] = $this->login; + $container['plugins'] = function (ShaarliContainer $container): PluginManager { + return new PluginManager($container->conf); + }; + + $container['history'] = function (ShaarliContainer $container): History { + return new History($container->conf->get('resource.history')); + }; + + $container['bookmarkService'] = function (ShaarliContainer $container): BookmarkServiceInterface { + return new BookmarkFileService( + $container->conf, + $container->history, + $container->loginManager->isLoggedIn() + ); + }; + + $container['pageBuilder'] = function (ShaarliContainer $container): PageBuilder { + return new PageBuilder( + $container->conf, + $container->sessionManager->getSession(), + $container->bookmarkService, + $container->sessionManager->generateToken(), + $container->loginManager->isLoggedIn() + ); + }; + + return $container; + } +} diff --git a/application/container/ShaarliContainer.php b/application/container/ShaarliContainer.php new file mode 100644 index 00000000..f5483d5e --- /dev/null +++ b/application/container/ShaarliContainer.php @@ -0,0 +1,28 @@ +container = $container; + } + + /** + * Middleware execution: + * - execute the controller + * - return the response + * + * In case of error, the error template will be displayed with the exception message. + * + * @param Request $request Slim request + * @param Response $response Slim response + * @param callable $next Next action + * + * @return Response response. + */ + public function __invoke(Request $request, Response $response, callable $next) + { + try { + $response = $next($request, $response); + } catch (ShaarliException $e) { + $this->container->pageBuilder->assign('message', $e->getMessage()); + if ($this->container->conf->get('dev.debug', false)) { + $this->container->pageBuilder->assign( + 'stacktrace', + nl2br(get_class($this) .': '. $e->getTraceAsString()) + ); + } + + $response = $response->withStatus($e->getCode()); + $response = $response->write($this->container->pageBuilder->render('error')); + } + + return $response; + } +} diff --git a/application/front/controllers/LoginController.php b/application/front/controllers/LoginController.php new file mode 100644 index 00000000..47fa3ee3 --- /dev/null +++ b/application/front/controllers/LoginController.php @@ -0,0 +1,46 @@ +ci->loginManager->isLoggedIn() || $this->ci->conf->get('security.open_shaarli', false)) { + return $response->withRedirect('./'); + } + + $userCanLogin = $this->ci->loginManager->canLogin($request->getServerParams()); + if ($userCanLogin !== true) { + throw new LoginBannedException(); + } + + if ($request->getParam('username') !== null) { + $this->assignView('username', escape($request->getParam('username'))); + } + + $this + ->assignView('returnurl', escape($request->getServerParam('HTTP_REFERER'))) + ->assignView('remember_user_default', $this->ci->conf->get('privacy.remember_user_default', true)) + ->assignView('pagetitle', t('Login') .' - '. $this->ci->conf->get('general.title', 'Shaarli')) + ; + + return $response->write($this->ci->pageBuilder->render('loginform')); + } +} diff --git a/application/front/controllers/ShaarliController.php b/application/front/controllers/ShaarliController.php new file mode 100644 index 00000000..2a166c3c --- /dev/null +++ b/application/front/controllers/ShaarliController.php @@ -0,0 +1,31 @@ +ci = $ci; + } + + /** + * Assign variables to RainTPL template through the PageBuilder. + * + * @param mixed $value Value to assign to the template + */ + protected function assignView(string $name, $value): self + { + $this->ci->pageBuilder->assign($name, $value); + + return $this; + } +} diff --git a/application/front/exceptions/LoginBannedException.php b/application/front/exceptions/LoginBannedException.php new file mode 100644 index 00000000..b31a4a14 --- /dev/null +++ b/application/front/exceptions/LoginBannedException.php @@ -0,0 +1,15 @@ +tpl->draw($page); } + /** + * Render a specific page as string (using a template file). + * e.g. $pb->render('picwall'); + * + * @param string $page Template filename (without extension). + * + * @return string Processed template content + */ + public function render(string $page): string + { + if ($this->tpl === false) { + $this->initialize(); + } + + return $this->tpl->draw($page, true); + } + /** * Render a 404 page (uses the template : tpl/404.tpl) * usage: $PAGE->render404('The link was deleted') diff --git a/application/security/SessionManager.php b/application/security/SessionManager.php index b8b8ab8d..994fcbe5 100644 --- a/application/security/SessionManager.php +++ b/application/security/SessionManager.php @@ -196,4 +196,10 @@ class SessionManager } return true; } + + /** @return array Local reference to the global $_SESSION array */ + public function getSession(): array + { + return $this->session; + } } -- cgit v1.2.3 From 9e4cc28e2957e1f7df713d52a03e350d728dc58e Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Thu, 23 Jan 2020 20:05:41 +0100 Subject: Fix all existing links and redirection to ?do=login --- application/Utils.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'application') diff --git a/application/Utils.php b/application/Utils.php index 56f5b9a2..4b7fc546 100644 --- a/application/Utils.php +++ b/application/Utils.php @@ -159,7 +159,7 @@ function checkDateFormat($format, $string) */ function generateLocation($referer, $host, $loopTerms = array()) { - $finalReferer = '?'; + $finalReferer = './?'; // No referer if it contains any value in $loopCriteria. foreach (array_filter($loopTerms) as $value) { -- cgit v1.2.3 From 0498b209b551cad5595312583e5d6fb1bc3303a5 Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Thu, 23 Jan 2020 20:06:32 +0100 Subject: Execute common plugin hooks before rendering login page --- application/container/ContainerBuilder.php | 4 +++ application/container/ShaarliContainer.php | 2 ++ application/front/controllers/LoginController.php | 2 +- .../front/controllers/ShaarliController.php | 38 ++++++++++++++++++++++ 4 files changed, 45 insertions(+), 1 deletion(-) (limited to 'application') diff --git a/application/container/ContainerBuilder.php b/application/container/ContainerBuilder.php index ff29825c..e2c78ccc 100644 --- a/application/container/ContainerBuilder.php +++ b/application/container/ContainerBuilder.php @@ -72,6 +72,10 @@ class ContainerBuilder ); }; + $container['pluginManager'] = function (ShaarliContainer $container): PluginManager { + return new PluginManager($container->conf); + }; + return $container; } } diff --git a/application/container/ShaarliContainer.php b/application/container/ShaarliContainer.php index f5483d5e..3fa9116e 100644 --- a/application/container/ShaarliContainer.php +++ b/application/container/ShaarliContainer.php @@ -7,6 +7,7 @@ namespace Shaarli\Container; use Shaarli\Bookmark\BookmarkServiceInterface; use Shaarli\Config\ConfigManager; use Shaarli\History; +use Shaarli\Plugin\PluginManager; use Shaarli\Render\PageBuilder; use Shaarli\Security\LoginManager; use Shaarli\Security\SessionManager; @@ -21,6 +22,7 @@ use Slim\Container; * @property History $history * @property BookmarkServiceInterface $bookmarkService * @property PageBuilder $pageBuilder + * @property PluginManager $pluginManager */ class ShaarliContainer extends Container { diff --git a/application/front/controllers/LoginController.php b/application/front/controllers/LoginController.php index 47fa3ee3..23efb592 100644 --- a/application/front/controllers/LoginController.php +++ b/application/front/controllers/LoginController.php @@ -41,6 +41,6 @@ class LoginController extends ShaarliController ->assignView('pagetitle', t('Login') .' - '. $this->ci->conf->get('general.title', 'Shaarli')) ; - return $response->write($this->ci->pageBuilder->render('loginform')); + return $response->write($this->render('loginform')); } } diff --git a/application/front/controllers/ShaarliController.php b/application/front/controllers/ShaarliController.php index 2a166c3c..99e66d53 100644 --- a/application/front/controllers/ShaarliController.php +++ b/application/front/controllers/ShaarliController.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace Shaarli\Front\Controller; +use Shaarli\Bookmark\BookmarkFilter; use Shaarli\Container\ShaarliContainer; abstract class ShaarliController @@ -28,4 +29,41 @@ abstract class ShaarliController return $this; } + + protected function render(string $template): string + { + $this->assignView('linkcount', $this->ci->bookmarkService->count(BookmarkFilter::$ALL)); + $this->assignView('privateLinkcount', $this->ci->bookmarkService->count(BookmarkFilter::$PRIVATE)); + $this->assignView('plugin_errors', $this->ci->pluginManager->getErrors()); + + $this->executeDefaultHooks($template); + + return $this->ci->pageBuilder->render($template); + } + + /** + * Call plugin hooks for header, footer and includes, specifying which page will be rendered. + * Then assign generated data to RainTPL. + */ + protected function executeDefaultHooks(string $template): void + { + $common_hooks = [ + 'includes', + 'header', + 'footer', + ]; + + foreach ($common_hooks as $name) { + $plugin_data = []; + $this->ci->pluginManager->executeHooks( + 'render_' . $name, + $plugin_data, + [ + 'target' => $template, + 'loggedin' => $this->ci->loginManager->isLoggedIn() + ] + ); + $this->assignView('plugins_' . $name, $plugin_data); + } + } } -- cgit v1.2.3 From 27ceea2aeeed69b43fef4ebff35ec8004fcc2e45 Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Sun, 26 Jan 2020 09:06:13 +0100 Subject: Rename ci attribute to container --- application/front/controllers/LoginController.php | 10 ++++++---- .../front/controllers/ShaarliController.php | 22 +++++++++++----------- 2 files changed, 17 insertions(+), 15 deletions(-) (limited to 'application') diff --git a/application/front/controllers/LoginController.php b/application/front/controllers/LoginController.php index 23efb592..ae3599e0 100644 --- a/application/front/controllers/LoginController.php +++ b/application/front/controllers/LoginController.php @@ -22,11 +22,13 @@ class LoginController extends ShaarliController { public function index(Request $request, Response $response): Response { - if ($this->ci->loginManager->isLoggedIn() || $this->ci->conf->get('security.open_shaarli', false)) { + if ($this->container->loginManager->isLoggedIn() + || $this->container->conf->get('security.open_shaarli', false) + ) { return $response->withRedirect('./'); } - $userCanLogin = $this->ci->loginManager->canLogin($request->getServerParams()); + $userCanLogin = $this->container->loginManager->canLogin($request->getServerParams()); if ($userCanLogin !== true) { throw new LoginBannedException(); } @@ -37,8 +39,8 @@ class LoginController extends ShaarliController $this ->assignView('returnurl', escape($request->getServerParam('HTTP_REFERER'))) - ->assignView('remember_user_default', $this->ci->conf->get('privacy.remember_user_default', true)) - ->assignView('pagetitle', t('Login') .' - '. $this->ci->conf->get('general.title', 'Shaarli')) + ->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('loginform')); diff --git a/application/front/controllers/ShaarliController.php b/application/front/controllers/ShaarliController.php index 99e66d53..2b828588 100644 --- a/application/front/controllers/ShaarliController.php +++ b/application/front/controllers/ShaarliController.php @@ -10,12 +10,12 @@ use Shaarli\Container\ShaarliContainer; abstract class ShaarliController { /** @var ShaarliContainer */ - protected $ci; + protected $container; - /** @param ShaarliContainer $ci Slim container (extended for attribute completion). */ - public function __construct(ShaarliContainer $ci) + /** @param ShaarliContainer $container Slim container (extended for attribute completion). */ + public function __construct(ShaarliContainer $container) { - $this->ci = $ci; + $this->container = $container; } /** @@ -25,20 +25,20 @@ abstract class ShaarliController */ protected function assignView(string $name, $value): self { - $this->ci->pageBuilder->assign($name, $value); + $this->container->pageBuilder->assign($name, $value); return $this; } protected function render(string $template): string { - $this->assignView('linkcount', $this->ci->bookmarkService->count(BookmarkFilter::$ALL)); - $this->assignView('privateLinkcount', $this->ci->bookmarkService->count(BookmarkFilter::$PRIVATE)); - $this->assignView('plugin_errors', $this->ci->pluginManager->getErrors()); + $this->assignView('linkcount', $this->container->bookmarkService->count(BookmarkFilter::$ALL)); + $this->assignView('privateLinkcount', $this->container->bookmarkService->count(BookmarkFilter::$PRIVATE)); + $this->assignView('plugin_errors', $this->container->pluginManager->getErrors()); $this->executeDefaultHooks($template); - return $this->ci->pageBuilder->render($template); + return $this->container->pageBuilder->render($template); } /** @@ -55,12 +55,12 @@ abstract class ShaarliController foreach ($common_hooks as $name) { $plugin_data = []; - $this->ci->pluginManager->executeHooks( + $this->container->pluginManager->executeHooks( 'render_' . $name, $plugin_data, [ 'target' => $template, - 'loggedin' => $this->ci->loginManager->isLoggedIn() + 'loggedin' => $this->container->loginManager->isLoggedIn() ] ); $this->assignView('plugins_' . $name, $plugin_data); -- cgit v1.2.3