login.php 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. <?php
  2. namespace Grav\Plugin;
  3. use Grav\Common\Language\Language;
  4. use Grav\Common\Page\Page;
  5. use Grav\Common\Page\Pages;
  6. use Grav\Common\Plugin;
  7. use Grav\Common\Twig;
  8. use Grav\Common\Uri;
  9. use Grav\Common\User\User;
  10. use Grav\Plugin\Admin;
  11. use RocketTheme\Toolbox\Session\Message;
  12. use RocketTheme\Toolbox\Session\Session;
  13. class LoginPlugin extends Plugin
  14. {
  15. /** @var string */
  16. protected $route;
  17. /**
  18. * @var bool
  19. */
  20. protected $authenticated = true;
  21. protected $authorized = true;
  22. /**
  23. * @return array
  24. */
  25. public static function getSubscribedEvents()
  26. {
  27. return [
  28. 'onPluginsInitialized' => ['initialize', 10000],
  29. 'onTask.login.login' => ['loginController', 0],
  30. 'onTask.login.logout' => ['loginController', 0],
  31. 'onPageInitialized' => ['authorizePage', 0],
  32. 'onTwigTemplatePaths' => ['onTwigTemplatePaths', 0],
  33. 'onTwigSiteVariables' => ['onTwigSiteVariables', -100000]
  34. ];
  35. }
  36. /**
  37. * Initialize login plugin if path matches.
  38. */
  39. public function initialize()
  40. {
  41. // Define session message service.
  42. $this->grav['messages'] = function ($c) {
  43. $session = $c['session'];
  44. if (!isset($session->messages)) {
  45. $session->messages = new Message;
  46. }
  47. return $session->messages;
  48. };
  49. // Define current user service.
  50. $this->grav['user'] = function ($c) {
  51. $session = $c['session'];
  52. if (!isset($session->user)) {
  53. $session->user = new User;
  54. }
  55. return $session->user;
  56. };
  57. // Register route to login page if it has been set.
  58. $this->route = $this->config->get('plugins.login.route');
  59. if ($this->route) {
  60. $this->enable([
  61. 'onPagesInitialized' => ['addLoginPage', 0]
  62. ]);
  63. }
  64. }
  65. public function addLoginPage()
  66. {
  67. /** @var Pages $pages */
  68. $pages = $this->grav['pages'];
  69. $page = $pages->dispatch($this->route);
  70. if (!$page) {
  71. // Only add login page if it hasn't already been defined.
  72. $page = new Page;
  73. $page->init(new \SplFileInfo(__DIR__ . "/pages/login.md"));
  74. $page->slug(basename($this->route));
  75. $pages->addPage($page, $this->route);
  76. }
  77. }
  78. public function loginController()
  79. {
  80. /** @var Uri $uri */
  81. $uri = $this->grav['uri'];
  82. $task = !empty($_POST['task']) ? $_POST['task'] : $uri->param('task');
  83. $task = substr($task, strlen('login.'));
  84. $post = !empty($_POST) ? $_POST : [];
  85. require_once __DIR__ . '/classes/controller.php';
  86. $controller = new LoginController($this->grav, $task, $post);
  87. $controller->execute();
  88. $controller->redirect();
  89. }
  90. public function authorizePage()
  91. {
  92. /** @var Page $page */
  93. $page = $this->grav['page'];
  94. $header = $page->header();
  95. $rules = isset($header->access) ? (array) $header->access : [];
  96. // Continue to the page if it has no ACL rules.
  97. if (!$rules) {
  98. return;
  99. }
  100. /** @var User $user */
  101. $user = $this->grav['user'];
  102. // Continue to the page if user is authorized to access the page.
  103. foreach ($rules as $rule => $value) {
  104. if ($user->authorize($rule) == $value) {
  105. return;
  106. }
  107. }
  108. // User is not logged in; redirect to login page.
  109. if ($this->route && !$user->authenticated) {
  110. $this->grav->redirect($this->route, 302);
  111. }
  112. /** @var Language $l */
  113. $l = $this->grav['language'];
  114. // Reset page with login page.
  115. if (!$user->authenticated) {
  116. $page = new Page;
  117. $page->init(new \SplFileInfo(__DIR__ . "/pages/login.md"));
  118. $page->slug(basename($this->route));
  119. $this->authenticated = false;
  120. unset($this->grav['page']);
  121. $this->grav['page'] = $page;
  122. } else {
  123. $this->grav['messages']->add($l->translate('LOGIN_PLUGIN.ACCESS_DENIED'), 'info');
  124. $this->authenticated = false;
  125. $twig = $this->grav['twig'];
  126. $twig->twig_vars['notAuthorized'] = true;
  127. }
  128. }
  129. /**
  130. * Add twig paths to plugin templates.
  131. */
  132. public function onTwigTemplatePaths()
  133. {
  134. $twig = $this->grav['twig'];
  135. $twig->twig_paths[] = __DIR__ . '/templates';
  136. }
  137. /**
  138. * Set all twig variables for generating output.
  139. */
  140. public function onTwigSiteVariables()
  141. {
  142. /** @var Twig $twig */
  143. $twig = $this->grav['twig'];
  144. $extension = $this->grav['uri']->extension();
  145. $extension = $extension ?: 'html';
  146. if (!$this->authenticated) {
  147. $twig->template = "login." . $extension . ".twig";
  148. }
  149. // add CSS for frontend if required
  150. if (!$this->isAdmin() && $this->config->get('plugins.login.built_in_css')) {
  151. $this->grav['assets']->add('plugin://login/css/login.css');
  152. }
  153. }
  154. }