vendor/contao/core-bundle/src/Resources/contao/modules/ModuleLogin.php line 120

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of Contao.
  4.  *
  5.  * (c) Leo Feyer
  6.  *
  7.  * @license LGPL-3.0-or-later
  8.  */
  9. namespace Contao;
  10. use Contao\CoreBundle\Security\Exception\LockedException;
  11. use Nyholm\Psr7\Uri;
  12. use Scheb\TwoFactorBundle\Security\Authentication\Exception\InvalidTwoFactorCodeException;
  13. use Scheb\TwoFactorBundle\Security\TwoFactor\Event\TwoFactorAuthenticationEvent;
  14. use Scheb\TwoFactorBundle\Security\TwoFactor\Event\TwoFactorAuthenticationEvents;
  15. use Symfony\Component\Security\Core\Exception\AuthenticationException;
  16. /**
  17.  * Front end module "login".
  18.  */
  19. class ModuleLogin extends Module
  20. {
  21.     /**
  22.      * Template
  23.      * @var string
  24.      */
  25.     protected $strTemplate 'mod_login';
  26.     /**
  27.      * Flash type
  28.      * @var string
  29.      */
  30.     protected $strFlashType 'contao.FE.error';
  31.     /**
  32.      * @var string
  33.      */
  34.     private $targetPath '';
  35.     /**
  36.      * Display a login form
  37.      *
  38.      * @return string
  39.      */
  40.     public function generate()
  41.     {
  42.         $request System::getContainer()->get('request_stack')->getCurrentRequest();
  43.         if ($request && System::getContainer()->get('contao.routing.scope_matcher')->isBackendRequest($request))
  44.         {
  45.             $objTemplate = new BackendTemplate('be_wildcard');
  46.             $objTemplate->wildcard '### ' $GLOBALS['TL_LANG']['FMD']['login'][0] . ' ###';
  47.             $objTemplate->title $this->headline;
  48.             $objTemplate->id $this->id;
  49.             $objTemplate->link $this->name;
  50.             $objTemplate->href StringUtil::specialcharsUrl(System::getContainer()->get('router')->generate('contao_backend', array('do'=>'themes''table'=>'tl_module''act'=>'edit''id'=>$this->id)));
  51.             return $objTemplate->parse();
  52.         }
  53.         // If the form was submitted and the credentials were wrong, take the target
  54.         // path from the submitted data as otherwise it would take the current page
  55.         if ($request && $request->isMethod('POST'))
  56.         {
  57.             $this->targetPath base64_decode($request->request->get('_target_path'));
  58.         }
  59.         elseif ($request && $this->redirectBack)
  60.         {
  61.             if ($request->query->has('redirect'))
  62.             {
  63.                 $uriSigner System::getContainer()->get('uri_signer');
  64.                 // We cannot use $request->getUri() here as we want to work with the original URI (no query string reordering)
  65.                 if ($uriSigner->check($request->getSchemeAndHttpHost() . $request->getBaseUrl() . $request->getPathInfo() . (null !== ($qs $request->server->get('QUERY_STRING')) ? '?' $qs '')))
  66.                 {
  67.                     $this->targetPath $request->query->get('redirect');
  68.                 }
  69.             }
  70.             elseif ($referer $request->headers->get('referer'))
  71.             {
  72.                 $refererUri = new Uri($referer);
  73.                 $requestUri = new Uri($request->getUri());
  74.                 // Use the HTTP referer as a fallback, but only if scheme and host matches with the current request (see #5860)
  75.                 if ($refererUri->getScheme() === $requestUri->getScheme() && $refererUri->getHost() === $requestUri->getHost() && $refererUri->getPort() === $requestUri->getPort())
  76.                 {
  77.                     $this->targetPath = (string) $refererUri;
  78.                 }
  79.             }
  80.         }
  81.         return parent::generate();
  82.     }
  83.     /**
  84.      * Generate the module
  85.      */
  86.     protected function compile()
  87.     {
  88.         /** @var PageModel $objPage */
  89.         global $objPage;
  90.         $container System::getContainer();
  91.         $request $container->get('request_stack')->getCurrentRequest();
  92.         $exception null;
  93.         $lastUsername '';
  94.         $this->Template->requestToken $container->get('contao.csrf.token_manager')->getDefaultTokenValue();
  95.         // Only call the authentication utils if there is an active session to prevent starting an empty session
  96.         if ($request && $request->hasSession() && ($request->hasPreviousSession() || $request->getSession()->isStarted()))
  97.         {
  98.             $authUtils $container->get('security.authentication_utils');
  99.             $exception $authUtils->getLastAuthenticationError();
  100.             $lastUsername $authUtils->getLastUsername();
  101.         }
  102.         $authorizationChecker $container->get('security.authorization_checker');
  103.         if ($authorizationChecker->isGranted('ROLE_MEMBER'))
  104.         {
  105.             $this->import(FrontendUser::class, 'User');
  106.             $strRedirect Environment::get('base') . Environment::get('request');
  107.             // Redirect to last page visited
  108.             if ($this->redirectBack && $this->targetPath)
  109.             {
  110.                 $strRedirect $this->targetPath;
  111.             }
  112.             // Redirect home if the page is protected
  113.             elseif ($objPage->protected)
  114.             {
  115.                 $strRedirect Environment::get('base');
  116.             }
  117.             $this->Template->logout true;
  118.             $this->Template->formId 'tl_logout_' $this->id;
  119.             $this->Template->slabel StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['logout']);
  120.             $this->Template->loggedInAs sprintf($GLOBALS['TL_LANG']['MSC']['loggedInAs'], $this->User->username);
  121.             $this->Template->action $container->get('security.logout_url_generator')->getLogoutPath();
  122.             $this->Template->targetPath StringUtil::specialchars($strRedirect);
  123.             if ($this->User->lastLogin 0)
  124.             {
  125.                 $this->Template->lastLogin sprintf($GLOBALS['TL_LANG']['MSC']['lastLogin'][1], Date::parse($objPage->datimFormat$this->User->lastLogin));
  126.             }
  127.             return;
  128.         }
  129.         if ($exception instanceof LockedException)
  130.         {
  131.             $this->Template->hasError true;
  132.             $this->Template->message sprintf($GLOBALS['TL_LANG']['ERR']['accountLocked'], $exception->getLockedMinutes());
  133.         }
  134.         elseif ($exception instanceof InvalidTwoFactorCodeException)
  135.         {
  136.             $this->Template->hasError true;
  137.             $this->Template->message $GLOBALS['TL_LANG']['ERR']['invalidTwoFactor'];
  138.         }
  139.         elseif ($exception instanceof AuthenticationException)
  140.         {
  141.             $this->Template->hasError true;
  142.             $this->Template->message $GLOBALS['TL_LANG']['ERR']['invalidLogin'];
  143.         }
  144.         $blnRedirectBack false;
  145.         $strRedirect Environment::get('base') . Environment::get('request');
  146.         // Redirect to the last page visited
  147.         if ($this->redirectBack && $this->targetPath)
  148.         {
  149.             $blnRedirectBack true;
  150.             $strRedirect $this->targetPath;
  151.         }
  152.         // Redirect to the jumpTo page
  153.         elseif (($objTarget $this->objModel->getRelated('jumpTo')) instanceof PageModel)
  154.         {
  155.             /** @var PageModel $objTarget */
  156.             $strRedirect $objTarget->getAbsoluteUrl();
  157.         }
  158.         $this->Template->formId 'tl_login_' $this->id;
  159.         $this->Template->forceTargetPath = (int) $blnRedirectBack;
  160.         $this->Template->targetPath StringUtil::specialchars(base64_encode($strRedirect));
  161.         if ($authorizationChecker->isGranted('IS_AUTHENTICATED_2FA_IN_PROGRESS'))
  162.         {
  163.             // Dispatch 2FA form event to prepare 2FA providers
  164.             $token $container->get('security.token_storage')->getToken();
  165.             $event = new TwoFactorAuthenticationEvent($request$token);
  166.             $container->get('event_dispatcher')->dispatch($eventTwoFactorAuthenticationEvents::FORM);
  167.             $this->Template->twoFactorEnabled true;
  168.             $this->Template->authCode $GLOBALS['TL_LANG']['MSC']['twoFactorVerification'];
  169.             $this->Template->slabel StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['continue']);
  170.             $this->Template->cancel $GLOBALS['TL_LANG']['MSC']['cancelBT'];
  171.             $this->Template->twoFactorAuthentication $GLOBALS['TL_LANG']['MSC']['twoFactorAuthentication'];
  172.             return;
  173.         }
  174.         $this->Template->username $GLOBALS['TL_LANG']['MSC']['username'];
  175.         $this->Template->password $GLOBALS['TL_LANG']['MSC']['password'][0];
  176.         $this->Template->slabel StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['login']);
  177.         $this->Template->value Input::encodeInsertTags(StringUtil::specialchars($lastUsername));
  178.         $this->Template->autologin $this->autologin;
  179.         $this->Template->autoLabel $GLOBALS['TL_LANG']['MSC']['autologin'];
  180.     }
  181. }
  182. class_alias(ModuleLogin::class, 'ModuleLogin');