* @copyright Since 2007 PrestaShop SA and Contributors * @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0 */ require_once __DIR__ . '/../../src/AccountLogin/OAuth2LoginTrait.php'; require_once __DIR__ . '/../../src/Polyfill/Traits/AdminController/IsAnonymousAllowed.php'; use PrestaShop\Module\PsAccounts\Account\Command\IdentifyContactCommand; use PrestaShop\Module\PsAccounts\AccountLogin\Exception\AccountLoginException; use PrestaShop\Module\PsAccounts\AccountLogin\Exception\EmailNotVerifiedException; use PrestaShop\Module\PsAccounts\AccountLogin\Exception\EmployeeNotFoundException; use PrestaShop\Module\PsAccounts\AccountLogin\OAuth2LoginTrait; use PrestaShop\Module\PsAccounts\AccountLogin\OAuth2Session; use PrestaShop\Module\PsAccounts\Cqrs\CommandBus; use PrestaShop\Module\PsAccounts\Log\Logger; use PrestaShop\Module\PsAccounts\Polyfill\ConfigurationStorageSession; use PrestaShop\Module\PsAccounts\Polyfill\Traits\AdminController\IsAnonymousAllowed; use PrestaShop\Module\PsAccounts\Service\AnalyticsService; use PrestaShop\Module\PsAccounts\Service\OAuth2\OAuth2Service; use PrestaShop\Module\PsAccounts\Service\OAuth2\Resource\AccessToken; use PrestaShop\Module\PsAccounts\Service\PsAccountsService; use Symfony\Component\HttpFoundation\Session\SessionInterface; class AdminOAuth2PsAccountsController extends \ModuleAdminController { use OAuth2LoginTrait; use IsAnonymousAllowed; /** * @var Ps_accounts */ public $module; /** * @var AnalyticsService */ private $analyticsService; /** * @var PsAccountsService */ private $psAccountsService; /** * @var CommandBus */ private $commandBus; /** * @throws PrestaShopException * @throws Exception */ public function __construct() { parent::__construct(); $this->analyticsService = $this->module->getService(AnalyticsService::class); $this->psAccountsService = $this->module->getService(PsAccountsService::class); $this->commandBus = $this->module->getService(CommandBus::class); $this->ajax = true; $this->content_only = true; } /** * @return bool */ public function checkToken() { return true; } /** * All BO users can access the login page * * @param bool $disable * * @return bool */ public function viewAccess($disable = false) { return true; } /** * @return void * * @throws PrestaShopException */ //public function display() public function init() { try { $this->oauth2Login(); } catch (AccountLoginException $e) { $this->onLoginFailed($e); } catch (Exception $e) { $this->onLoginFailed(new AccountLoginException($e->getMessage(), null, $e)); } // why do this at the end of the method ? parent::init(); } /** * @param AccessToken $accessToken * * @return bool * * @throws EmailNotVerifiedException * @throws EmployeeNotFoundException */ protected function initUserSession(AccessToken $accessToken) { $user = $this->getOAuth2Service()->getUserInfo($accessToken->access_token); Logger::getInstance()->info( '[OAuth2] ' . (string) print_r($user, true) ); if ($this->getOAuthAction() === 'identifyPointOfContact') { $this->commandBus->handle( (new IdentifyContactCommand($accessToken, $user)) ->withSource($this->getSource()) ); return true; } $this->getOauth2Session()->setTokenProvider($accessToken); //$user = $oauth2Session->getUserInfo(); Logger::getInstance()->info( '[OAuth2] ' . (string) print_r($user, true) ); $context = $this->context; $emailVerified = $user->email_verified; $context->employee = $this->getEmployeeByUidOrEmail($user->sub, $user->email); if (!$context->employee->id || empty($emailVerified)) { $context->employee->logout(); if (empty($emailVerified)) { throw new EmailNotVerifiedException('Your account email is not verified', $user); } throw new EmployeeNotFoundException('The email address is not associated to a PrestaShop backoffice account.', $user); } $context->employee->remote_addr = (int) ip2long(Tools::getRemoteAddr()); $cookie = $context->cookie; /* @phpstan-ignore-next-line */ $cookie->id_employee = $context->employee->id; /* @phpstan-ignore-next-line */ $cookie->email = $context->employee->email; /* @phpstan-ignore-next-line */ $cookie->profile = $context->employee->id_profile; /* @phpstan-ignore-next-line */ $cookie->passwd = $context->employee->passwd; /* @phpstan-ignore-next-line */ $cookie->remote_addr = $context->employee->remote_addr; if (class_exists('EmployeeSession') && method_exists($cookie, 'registerSession')) { $cookie->registerSession(new EmployeeSession()); } if (!Tools::getValue('stay_logged_in')) { /* @phpstan-ignore-next-line */ $cookie->last_activity = time(); } $cookie->write(); $this->trackEditionLoginEvent($user); return true; } /** * @return OAuth2Service * * @throws Exception */ protected function getOAuth2Service() { return $this->module->getService(OAuth2Service::class); } /** * @return mixed */ protected function redirectAfterLogin() { if ($this->getOAuthAction() === 'identifyPointOfContact') { $forceSignup = $this->getForceSignup(); $this->getSession()->clear(); $this->closePopup($forceSignup); } $returnTo = $this->getReturnTo() ?: 'AdminDashboard'; if (preg_match('/^([A-Z][a-z0-9]+)+$/', $returnTo)) { $returnTo = $this->context->link->getAdminLink($returnTo); } Tools::redirectAdmin($returnTo); } /** * @return mixed */ protected function logout() { Tools::redirectAdmin( $this->context->link->getAdminLink('AdminLogin', true, [], [ 'logout' => 1, ]) ); } /** * @return mixed */ protected function onLoginFailedRedirect() { if ($this->getOAuthAction() === 'identifyPointOfContact') { $this->closePopup(); } $this->logout(); } /** * @return SessionInterface */ protected function getSession() { if (\Context::getContext()->employee->id) { // FIXME: fallback only for setPointOfContact return $this->module->getService(ConfigurationStorageSession::class); } return $this->module->getSession(); } /** * @return OAuth2Session */ protected function getOauth2Session() { return $this->module->getService(OAuth2Session::class); } /** * @return AnalyticsService */ protected function getAnalyticsService() { return $this->analyticsService; } /** * @return PsAccountsService */ protected function getPsAccountsService() { return $this->psAccountsService; } /** * @param bool $forceSignup * * @return void */ protected function closePopup($forceSignup = false) { if ($forceSignup) { Tools::redirect($this->getSignupUrl()); } else { echo ' '; exit; } } /** * @return string */ protected function getSignupUrl() { return $this->module->getParameter('ps_accounts.accounts_ui_url') . '?signupContext=popup'; } }