Current File : /var/www/prestashop/modules/ps_accounts/controllers/admin/AdminOAuth2PsAccountsController.php |
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
use PrestaShop\Module\PsAccounts\Entity\EmployeeAccount;
use PrestaShop\Module\PsAccounts\Exception\AccountLogin\AccountLoginException;
use PrestaShop\Module\PsAccounts\Exception\AccountLogin\EmailNotVerifiedException;
use PrestaShop\Module\PsAccounts\Exception\AccountLogin\EmployeeNotFoundException;
use PrestaShop\Module\PsAccounts\Exception\AccountLogin\Oauth2Exception;
use PrestaShop\Module\PsAccounts\Exception\AccountLogin\OtherErrorException;
use PrestaShop\Module\PsAccounts\Provider\OAuth2\PrestaShopLoginTrait;
use PrestaShop\Module\PsAccounts\Provider\OAuth2\PrestaShopSession;
use PrestaShop\Module\PsAccounts\Provider\OAuth2\ShopProvider;
use PrestaShop\Module\PsAccounts\Repository\EmployeeAccountRepository;
use PrestaShop\Module\PsAccounts\Service\AnalyticsService;
use PrestaShop\Module\PsAccounts\Service\PsAccountsService;
use PrestaShop\Module\PsAccounts\Session\Session;
use PrestaShop\Module\PsAccounts\Vendor\League\OAuth2\Client\Provider\Exception\IdentityProviderException;
use PrestaShop\OAuth2\Client\Provider\PrestaShopUser;
/**
* Controller for all ajax calls.
*/
class AdminOAuth2PsAccountsController extends \ModuleAdminController
{
use PrestaShopLoginTrait;
/**
* @var Ps_accounts
*/
public $module;
/**
* @var AnalyticsService
*/
private $analyticsService;
/**
* @var PsAccountsService
*/
private $psAccountsService;
/**
* @throws PrestaShopException
* @throws Exception
*/
public function __construct()
{
parent::__construct();
$this->analyticsService = $this->module->getService(AnalyticsService::class);
$this->psAccountsService = $this->module->getService(PsAccountsService::class);
$this->ajax = true;
$this->content_only = true;
}
/**
* @return bool
*/
protected function isAnonymousAllowed()
{
return 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 (IdentityProviderException $e) {
$this->onLoginFailed(new Oauth2Exception(null, $e->getMessage()));
} catch (EmailNotVerifiedException $e) {
$this->onLoginFailed($e);
} catch (EmployeeNotFoundException $e) {
$this->onLoginFailed($e);
} catch (Exception $e) {
$this->onLoginFailed(new OtherErrorException(null, $e->getMessage()));
}
parent::init();
}
/**
* @param PrestaShopUser $user
*
* @return bool
*
* @throws EmailNotVerifiedException
* @throws EmployeeNotFoundException
* @throws Exception
*/
private function initUserSession(PrestaShopUser $user)
{
$this->oauth2ErrorLog((string) json_encode($user->toArray(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
$context = $this->context;
$emailVerified = $user->getEmailVerified();
$context->employee = $this->getEmployeeByUidOrEmail($user->getId(), $user->getEmail());
if (!$context->employee->id || empty($emailVerified)) {
$context->employee->logout();
if (empty($emailVerified)) {
throw new EmailNotVerifiedException($user);
}
throw new EmployeeNotFoundException($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->trackLoginEvent($user);
return true;
}
/**
* @param AccountLoginException $e
*
* @return void
*
* @throws PrestaShopException
* @throws Exception
*/
private function onLoginFailed(AccountLoginException $e)
{
if ($this->module->isShopEdition() && (
$e instanceof EmployeeNotFoundException ||
$e instanceof EmailNotVerifiedException
)) {
$this->trackLoginFailedEvent($e);
}
$this->oauth2ErrorLog($e->getMessage());
$this->setLoginError($e->getType());
Tools::redirectAdmin(
$this->context->link->getAdminLink('AdminLogin', true, [], [
'logout' => 1,
])
);
}
/**
* @return ShopProvider
*
* @throws Exception
*/
private function getProvider()
{
return $this->module->getService(ShopProvider::class);
}
/**
* @return void
*/
private function redirectAfterLogin()
{
$returnTo = $this->getSessionReturnTo() ?: 'AdminDashboard';
if (preg_match('/^([A-Z][a-z0-9]+)+$/', $returnTo)) {
$returnTo = $this->context->link->getAdminLink($returnTo);
}
Tools::redirectAdmin($returnTo);
}
/**
* @return Session
*
* @throws Exception
*/
private function getSession()
{
return $this->module->getSession();
}
/**
* @param mixed $error
*
* @return void
*
* @throws Exception
*/
private function setLoginError($error)
{
$this->getSession()->set('loginError', $error);
}
/**
* @return PrestaShopSession
*
* @throws Exception
*/
protected function getOauth2Session()
{
return $this->module->getService(PrestaShopSession::class);
}
/**
* @param PrestaShopUser $user
*
* @return void
*
* @throws Exception
*/
private function trackLoginEvent(PrestaShopUser $user)
{
if ($this->module->isShopEdition()) {
$this->analyticsService->identify(
$user->getId(),
$user->getName(),
$user->getEmail()
);
$this->analyticsService->group(
$user->getId(),
(string) $this->psAccountsService->getShopUuid()
);
$this->analyticsService->trackUserSignedIntoApp(
$user->getId(),
'smb-edition'
);
}
}
/**
* @param EmployeeNotFoundException|EmailNotVerifiedException $e
*
* @return void
*
* @throws Exception
*/
private function trackLoginFailedEvent($e)
{
$user = $e->getPrestaShopUser();
$this->analyticsService->identify(
$user->getId(),
$user->getName(),
$user->getEmail()
);
$this->analyticsService->group(
$user->getId(),
(string) $this->psAccountsService->getShopUuid()
);
$this->analyticsService->trackBackOfficeSSOSignInFailed(
$user->getId(),
$e->getType(),
$e->getMessage()
);
}
/**
* @param string $uid
* @param string $email
*
* @return Employee
*
* @throws Exception
*/
private function getEmployeeByUidOrEmail($uid, $email)
{
$repository = new EmployeeAccountRepository();
if ($repository->isCompatPs16()) {
$employeeAccount = $repository->findByUid($uid);
/* @phpstan-ignore-next-line */
if ($employeeAccount) {
$employee = new Employee($employeeAccount->getEmployeeId());
} else {
$employeeAccount = new EmployeeAccount();
$employee = new Employee();
$employee->getByEmail($email);
}
// Update account
if ($employee->id) {
$repository->upsert(
$employeeAccount
->setEmployeeId($employee->id)
->setUid($uid)
->setEmail($email)
);
}
} else {
$employee = new Employee();
$employee->getByEmail($email);
}
return $employee;
}
}