first commit

This commit is contained in:
2024-12-17 13:43:22 +01:00
commit 8e6cd8b410
21292 changed files with 3514826 additions and 0 deletions

View File

@@ -0,0 +1,175 @@
<?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
*/
namespace PrestaShop\Module\PsAccounts\Adapter;
class Configuration
{
const PS_ACCOUNTS_FIREBASE_ID_TOKEN = 'PS_ACCOUNTS_FIREBASE_ID_TOKEN';
const PS_PSX_FIREBASE_ID_TOKEN = 'PS_PSX_FIREBASE_ID_TOKEN';
const PS_ACCOUNTS_FIREBASE_REFRESH_TOKEN = 'PS_ACCOUNTS_FIREBASE_REFRESH_TOKEN';
const PS_PSX_FIREBASE_REFRESH_TOKEN = 'PS_PSX_FIREBASE_REFRESH_TOKEN';
const PS_CHECKOUT_SHOP_UUID_V4 = 'PS_CHECKOUT_SHOP_UUID_V4';
const PSX_UUID_V4 = 'PSX_UUID_V4';
const PS_PSX_FIREBASE_ADMIN_TOKEN = 'PS_PSX_FIREBASE_ADMIN_TOKEN';
const PS_ACCOUNTS_FIREBASE_ADMIN_TOKEN = 'PS_ACCOUNTS_FIREBASE_ADMIN_TOKEN';
const PS_PSX_FIREBASE_REFRESH_DATE = 'PS_PSX_FIREBASE_REFRESH_DATE';
const PS_PSX_FIREBASE_EMAIL = 'PS_PSX_FIREBASE_EMAIL';
const PS_ACCOUNTS_FIREBASE_EMAIL = 'PS_ACCOUNTS_FIREBASE_EMAIL';
const PS_PSX_FIREBASE_EMAIL_IS_VERIFIED = 'PS_PSX_FIREBASE_EMAIL_IS_VERIFIED';
const PS_ACCOUNTS_FIREBASE_EMAIL_IS_VERIFIED = 'PS_ACCOUNTS_FIREBASE_EMAIL_IS_VERIFIED';
const PS_PSX_FIREBASE_LOCAL_ID = 'PS_PSX_FIREBASE_LOCAL_ID';
const PS_ACCOUNTS_FIREBASE_LOCAL_ID = 'PS_ACCOUNTS_FIREBASE_LOCAL_ID';
const PS_ACCOUNTS_RSA_PUBLIC_KEY = 'PS_ACCOUNTS_RSA_PUBLIC_KEY';
const PS_ACCOUNTS_RSA_PRIVATE_KEY = 'PS_ACCOUNTS_RSA_PRIVATE_KEY';
const PS_ACCOUNTS_RSA_SIGN_DATA = 'PS_ACCOUNTS_RSA_SIGN_DATA';
/**
* @var int
*/
private $idShop = null;
/**
* @var int
*/
private $idShopGroup = null;
/**
* @var int
*/
private $idLang = null;
/**
* Configuration constructor.
*
* @param \Context $context
*/
public function __construct(\Context $context)
{
$this->setIdShop((int) $context->shop->id);
}
/**
* @return int
*/
public function getIdShop()
{
return $this->idShop;
}
/**
* @param int $idShop
*
* @return void
*/
public function setIdShop($idShop)
{
$this->idShop = $idShop;
}
/**
* @return int
*/
public function getIdShopGroup()
{
return $this->idShopGroup;
}
/**
* @param int $idShopGroup
*
* @return void
*/
public function setIdShopGroup($idShopGroup)
{
$this->idShopGroup = $idShopGroup;
}
/**
* @return int
*/
public function getIdLang()
{
return $this->idLang;
}
/**
* @param int $idLang
*
* @return void
*/
public function setIdLang($idLang)
{
$this->idLang = $idLang;
}
/**
* @param string $key
* @param string|bool $default
*
* @return mixed
*/
public function get($key, $default = false)
{
return $this->getRaw($key, $this->idLang, $this->idShopGroup, $this->idShop, $default);
}
/**
* @param string $key
* @param int|null $idLang
* @param int|null $idShopGroup
* @param int|null $idShop
* @param string|bool $default
*
* @return mixed
*/
public function getRaw($key, $idLang = null, $idShopGroup = null, $idShop = null, $default = false)
{
$value = \Configuration::get($key, $idLang, $idShopGroup, $idShop);
return $value ?: ($default !== false ? $default : $value);
}
/**
* @param string $key
* @param string|array $values
* @param bool $html
*
* @return mixed
*/
public function set($key, $values, $html = false)
{
return $this->setRaw($key, $values, $html, $this->idShopGroup, $this->idShop);
}
/**
* @param string $key
* @param string|array $values
* @param bool $html
* @param int|null $idShopGroup
* @param int|null $idShop
*
* @return mixed
*/
public function setRaw($key, $values, $html = false, $idShopGroup = null, $idShop = null)
{
return \Configuration::updateValue($key, $values, $html, $idShopGroup, $idShop);
}
}

View File

@@ -0,0 +1,87 @@
<?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
*/
namespace PrestaShop\Module\PsAccounts\Adapter;
use PrestaShop\Module\PsAccounts\Context\ShopContext;
/**
* Link adapter
*/
class Link
{
/**
* @var ShopContext
*/
private $shopContext;
/**
* Link object
*
* @var \Link
*/
private $link;
public function __construct(
ShopContext $shopContext,
\Link $link = null
) {
if (null === $link) {
$link = new \Link();
}
$this->shopContext = $shopContext;
$this->link = $link;
}
/**
* Adapter for getAdminLink from prestashop link class
*
* @param string $controller controller name
* @param bool $withToken include or not the token in the url
* @param array $sfRouteParams
* @param array $params
*
* @return string
*
* @throws \PrestaShopException
*/
public function getAdminLink($controller, $withToken = true, $sfRouteParams = [], $params = [])
{
if ($this->shopContext->isShop17()) {
return $this->link->getAdminLink($controller, $withToken, $sfRouteParams, $params);
}
$paramsAsString = '';
foreach ($params as $key => $value) {
$paramsAsString .= "&$key=$value";
}
return \Tools::getShopDomainSsl(true) . __PS_BASE_URI__ . basename(_PS_ADMIN_DIR_) . '/' . $this->link->getAdminLink($controller, $withToken) . $paramsAsString;
}
/**
* @return \Link
*/
public function getLink()
{
return $this->link;
}
}

View File

@@ -0,0 +1,28 @@
<?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
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,120 @@
<?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
*/
namespace PrestaShop\Module\PsAccounts\Api\Client;
use GuzzleHttp\Client;
use PrestaShop\Module\PsAccounts\Configuration\ConfigOptionsResolver;
use PrestaShop\Module\PsAccounts\Exception\OptionResolutionException;
/**
* Handle firebase signIn/signUp.
*/
class FirebaseClient extends GenericClient
{
/**
* Firebase api key.
*
* @var string
*/
protected $apiKey;
/**
* FirebaseClient constructor.
*
* @param array $config
*
* @throws OptionResolutionException
*/
public function __construct(array $config)
{
parent::__construct();
$config = $this->resolveConfig($config);
$client = new Client([
'defaults' => [
'timeout' => $this->timeout,
'exceptions' => $this->catchExceptions,
'allow_redirects' => false,
'query' => [
'key' => $config['api_key'],
],
'headers' => [
'Accept' => 'application/json',
'Content-Type' => 'application/json',
],
],
]);
$this->setClient($client);
}
/**
* @param string $customToken
*
* @return array response
*/
public function signInWithCustomToken($customToken)
{
$this->setRoute('https://identitytoolkit.googleapis.com/v1/accounts:signInWithCustomToken');
return $this->post([
'json' => [
'token' => $customToken,
'returnSecureToken' => true,
],
]);
}
/**
* @see https://firebase.google.com/docs/reference/rest/auth#section-refresh-token Firebase documentation
*
* @param string $refreshToken
*
* @return array response
*/
public function exchangeRefreshTokenForIdToken($refreshToken)
{
$this->setRoute('https://securetoken.googleapis.com/v1/token');
return $this->post([
'json' => [
'grant_type' => 'refresh_token',
'refresh_token' => $refreshToken,
],
]);
}
/**
* @param array $config
* @param array $defaults
*
* @return array
*
* @throws OptionResolutionException
*/
public function resolveConfig(array $config, array $defaults = [])
{
return (new ConfigOptionsResolver([
'api_key',
]))->resolve($config, $defaults);
}
}

View File

@@ -0,0 +1,287 @@
<?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
*/
namespace PrestaShop\Module\PsAccounts\Api\Client;
use GuzzleHttp\Client;
use PrestaShop\Module\PsAccounts\Configuration\Configurable;
use PrestaShop\Module\PsAccounts\Handler\Response\ApiResponseHandler;
/**
* Construct the client used to make call to maasland.
*/
abstract class GenericClient implements Configurable
{
/**
* If set to false, you will not be able to catch the error
* guzzle will show a different error message.
*
* @var bool
*/
protected $catchExceptions = false;
/**
* Guzzle Client.
*
* @var Client
*/
protected $client;
/**
* Class Link in order to generate module link.
*
* @var \Link
*/
protected $link;
/**
* Api route.
*
* @var string
*/
protected $route;
/**
* Set how long guzzle will wait a response before end it up.
*
* @var int
*/
protected $timeout = 10;
/**
* GenericClient constructor.
*/
public function __construct()
{
}
/**
* Getter for client.
*
* @return Client
*/
protected function getClient()
{
return $this->client;
}
/**
* Getter for exceptions mode.
*
* @return bool
*/
protected function getExceptionsMode()
{
return $this->catchExceptions;
}
/**
* Getter for Link.
*
* @return \Link
*/
protected function getLink()
{
return $this->link;
}
/**
* Getter for route.
*
* @return string
*/
protected function getRoute()
{
return $this->route;
}
/**
* Getter for timeout.
*
* @return int
*/
protected function getTimeout()
{
return $this->timeout;
}
/**
* Wrapper of method post from guzzle client.
*
* @param array $options payload
*
* @return array return response or false if no response
*/
protected function post(array $options = [])
{
$response = $this->getClient()->post($this->getRoute(), $options);
$responseHandler = new ApiResponseHandler();
$response = $responseHandler->handleResponse($response);
// If response is not successful only
if (\Configuration::get('PS_ACCOUNTS_DEBUG_LOGS_ENABLED') && !$response['status']) {
/**
* @var \Ps_accounts
*/
$module = \Module::getInstanceByName('ps_accounts');
$logger = $module->getLogger();
$logger->debug('route ' . $this->getRoute());
$logger->debug('options ' . var_export($options, true));
$logger->debug('response ' . var_export($response, true));
}
return $response;
}
/**
* Wrapper of method patch from guzzle client.
*
* @param array $options payload
*
* @return array return response or false if no response
*/
protected function patch(array $options = [])
{
$response = $this->getClient()->patch($this->getRoute(), $options);
$responseHandler = new ApiResponseHandler();
$response = $responseHandler->handleResponse($response);
// If response is not successful only
if (\Configuration::get('PS_ACCOUNTS_DEBUG_LOGS_ENABLED') && !$response['status']) {
/**
* @var \Ps_accounts
*/
$module = \Module::getInstanceByName('ps_accounts');
$logger = $module->getLogger();
$logger->debug('route ' . $this->getRoute());
$logger->debug('options ' . var_export($options, true));
$logger->debug('response ' . var_export($response, true));
}
return $response;
}
/**
* Wrapper of method post from guzzle client.
*
* @param array $options payload
*
* @return array return response or false if no response
*/
protected function get(array $options = [])
{
$response = $this->getClient()->get($this->getRoute(), $options);
$responseHandler = new ApiResponseHandler();
$response = $responseHandler->handleResponse($response);
// If response is not successful only
if (\Configuration::get('PS_ACCOUNTS_DEBUG_LOGS_ENABLED') && !$response['status']) {
/**
* @var \Ps_accounts
*/
$module = \Module::getInstanceByName('ps_accounts');
$logger = $module->getLogger();
$logger->debug('route ' . $this->getRoute());
$logger->debug('options ' . var_export($options, true));
$logger->debug('response ' . var_export($response, true));
}
return $response;
}
/**
* Wrapper of method delete from guzzle client.
*
* @param array $options payload
*
* @return array return response array
*/
protected function delete(array $options = [])
{
$response = $this->getClient()->delete($this->getRoute(), $options);
$responseHandler = new ApiResponseHandler();
$response = $responseHandler->handleResponse($response);
// If response is not successful only
if (\Configuration::get('PS_ACCOUNTS_DEBUG_LOGS_ENABLED') && !$response['status']) {
/**
* @var \Ps_accounts
*/
$module = \Module::getInstanceByName('ps_accounts');
$logger = $module->getLogger();
$logger->debug('route ' . $this->getRoute());
$logger->debug('options ' . var_export($options, true));
$logger->debug('response ' . var_export($response, true));
}
return $response;
}
/**
* Setter for client.
*
* @return void
*/
protected function setClient(Client $client)
{
$this->client = $client;
}
/**
* Setter for exceptions mode.
*
* @param bool $bool
*
* @return void
*/
protected function setExceptionsMode($bool)
{
$this->catchExceptions = $bool;
}
/**
* Setter for link.
*
* @return void
*/
protected function setLink(\Link $link)
{
$this->link = $link;
}
/**
* Setter for route.
*
* @param string $route
*
* @return void
*/
protected function setRoute($route)
{
$this->route = $route;
}
/**
* Setter for timeout.
*
* @param int $timeout
*
* @return void
*/
protected function setTimeout($timeout)
{
$this->timeout = $timeout;
}
}

View File

@@ -0,0 +1,189 @@
<?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
*/
namespace PrestaShop\Module\PsAccounts\Api\Client;
use GuzzleHttp\Client;
use PrestaShop\Module\PsAccounts\Adapter\Link;
use PrestaShop\Module\PsAccounts\Configuration\ConfigOptionsResolver;
use PrestaShop\Module\PsAccounts\Exception\OptionResolutionException;
use PrestaShop\Module\PsAccounts\Exception\TokenNotFoundException;
use PrestaShop\Module\PsAccounts\Provider\ShopProvider;
use PrestaShop\Module\PsAccounts\Service\ShopTokenService;
/**
* Class ServicesAccountsClient
*/
class ServicesAccountsClient extends GenericClient
{
/**
* @var ShopProvider
*/
private $shopProvider;
/**
* @var ShopTokenService
*/
private $shopTokenService;
/**
* ServicesAccountsClient constructor.
*
* @param array $config
* @param ShopProvider $shopProvider
* @param ShopTokenService $shopTokenService
* @param Link $link
* @param Client|null $client
*
* @throws OptionResolutionException
* @throws TokenNotFoundException
* @throws \PrestaShopException
* @throws \Exception
*/
public function __construct(
array $config,
ShopProvider $shopProvider,
ShopTokenService $shopTokenService,
Link $link,
Client $client = null
) {
parent::__construct();
$config = $this->resolveConfig($config);
$this->shopProvider = $shopProvider;
$this->shopTokenService = $shopTokenService;
$shopId = (int) $this->shopProvider->getCurrentShop()['id'];
$token = $this->shopTokenService->getOrRefreshToken();
$this->setLink($link->getLink());
if (!$token) {
throw new TokenNotFoundException('Firebase token not found');
}
// Client can be provided for tests
if (null === $client) {
$client = new Client([
'base_url' => $config['api_url'],
'defaults' => [
'timeout' => $this->timeout,
'exceptions' => $this->catchExceptions,
'headers' => [
// Commented, else does not work anymore with API.
//'Content-Type' => 'application/vnd.accounts.v1+json', // api version to use
'Accept' => 'application/json',
'Authorization' => 'Bearer ' . $token,
'Shop-Id' => $shopId,
'Module-Version' => \Ps_accounts::VERSION, // version of the module
'Prestashop-Version' => _PS_VERSION_, // prestashop version
],
],
]);
}
$this->setClient($client);
}
/**
* @param mixed $shopUuidV4
* @param array $bodyHttp
*
* @return array | false
*/
public function updateShopUrl($shopUuidV4, $bodyHttp)
{
$this->setRoute('/shops/' . $shopUuidV4 . '/url');
return $this->patch([
'body' => $bodyHttp,
]);
}
/**
* @param string $shopUuidV4
*
* @return array
*/
public function deleteShop($shopUuidV4)
{
$this->setRoute('/shop/' . $shopUuidV4);
return $this->delete();
}
/**
* @param array $headers
* @param array $body
*
* @return array
*
* @throws \PrestaShopException
*/
public function verifyWebhook(array $headers, array $body)
{
$correlationId = $headers['correlationId'];
$this->setRoute('/webhooks/' . $correlationId . '/verify');
$shopId = (int) $this->shopProvider->getCurrentShop()['id'];
$hookUrl = $this->link->getModuleLink('ps_accounts', 'DispatchWebHook', [], true, null, $shopId);
$res = $this->post([
'headers' => [
'correlationId' => $correlationId,
'Hook-Url' => $hookUrl,
],
'json' => $body,
]);
if (!$res || $res['httpCode'] < 200 || $res['httpCode'] > 299) {
return [
'httpCode' => $res['httpCode'],
'body' => $res['body']
&& is_array($res['body'])
&& array_key_exists('message', $res['body'])
? $res['body']['message']
: 'Unknown error',
];
}
return [
'httpCode' => 200,
'body' => 'ok',
];
}
/**
* @param array $config
* @param array $defaults
*
* @return array
*
* @throws OptionResolutionException
*/
public function resolveConfig(array $config, array $defaults = [])
{
return (new ConfigOptionsResolver([
'api_url',
]))->resolve($config, $defaults);
}
}

View File

@@ -0,0 +1,158 @@
<?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
*/
namespace PrestaShop\Module\PsAccounts\Api\Client;
use GuzzleHttp\Client;
use PrestaShop\Module\PsAccounts\Adapter\Link;
use PrestaShop\Module\PsAccounts\Configuration\ConfigOptionsResolver;
use PrestaShop\Module\PsAccounts\Exception\OptionResolutionException;
use PrestaShop\Module\PsAccounts\Provider\ShopProvider;
use PrestaShop\Module\PsAccounts\Service\PsAccountsService;
/**
* Handle call api Services
*/
class ServicesBillingClient extends GenericClient
{
/**
* ServicesBillingClient constructor.
*
* @param array $config
* @param PsAccountsService $psAccountsService
* @param ShopProvider $shopProvider
* @param Link $link
* @param Client|null $client
*
* @throws OptionResolutionException
* @throws \PrestaShopException
* @throws \Exception
*/
public function __construct(
array $config,
PsAccountsService $psAccountsService,
ShopProvider $shopProvider,
Link $link,
Client $client = null
) {
parent::__construct();
$config = $this->resolveConfig($config);
$shopId = $shopProvider->getCurrentShop()['id'];
$token = $psAccountsService->getOrRefreshToken();
$this->setLink($link->getLink());
// Client can be provided for tests
if (null === $client) {
$client = new Client([
'base_url' => $config['api_url'],
'defaults' => [
'timeout' => $this->timeout,
'exceptions' => $this->catchExceptions,
'headers' => [
// Commented, else does not work anymore with API.
//'Content-Type' => 'application/vnd.accounts.v1+json', // api version to use
'Accept' => 'application/json',
'Authorization' => 'Bearer ' . $token,
'Shop-Id' => $shopId,
'Module-Version' => \Ps_accounts::VERSION, // version of the module
'Prestashop-Version' => _PS_VERSION_, // prestashop version
],
],
]);
}
$this->setClient($client);
}
/**
* @param mixed $shopUuidV4
*
* @return array | false
*/
public function getBillingCustomer($shopUuidV4)
{
$this->setRoute('/shops/' . $shopUuidV4);
return $this->get();
}
/**
* @param mixed $shopUuidV4
* @param array $bodyHttp
*
* @return array | false
*/
public function createBillingCustomer($shopUuidV4, $bodyHttp)
{
$this->setRoute('/shops/' . $shopUuidV4);
return $this->post([
'body' => $bodyHttp,
]);
}
/**
* @param mixed $shopUuidV4
* @param string $module
*
* @return array | false
*/
public function getBillingSubscriptions($shopUuidV4, $module)
{
$this->setRoute('/shops/' . $shopUuidV4 . '/subscriptions/' . $module);
return $this->get();
}
/**
* @param mixed $shopUuidV4
* @param string $module
* @param array $bodyHttp
*
* @return array | false
*/
public function createBillingSubscriptions($shopUuidV4, $module, $bodyHttp)
{
$this->setRoute('/shops/' . $shopUuidV4 . '/subscriptions/' . $module);
return $this->post([
'body' => $bodyHttp,
]);
}
/**
* @param array $config
* @param array $defaults
*
* @return array
*
* @throws OptionResolutionException
*/
public function resolveConfig(array $config, array $defaults = [])
{
return (new ConfigOptionsResolver([
'api_url',
]))->resolve($config, $defaults);
}
}

View File

@@ -0,0 +1,28 @@
<?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
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,28 @@
<?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
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,68 @@
<?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
*/
namespace PrestaShop\Module\PsAccounts\Configuration;
use PrestaShop\Module\PsAccounts\Exception\OptionResolutionException;
class ConfigOptionsResolver
{
/**
* @var array
*/
private $required;
/**
* @var array
*/
private $defaults;
public function __construct(array $required, array $defaults = [])
{
$this->required = $required;
$this->defaults = $defaults;
}
/**
* @param array $config
* @param array $defaults
*
* @return array
*
* @throws OptionResolutionException
*/
public function resolve(array $config, array $defaults = [])
{
$defaults = array_merge($this->defaults, $defaults);
$diff = array_diff($this->required, array_keys($config), array_keys($defaults));
if (count($diff) > 0) {
throw new OptionResolutionException('Configuration option missing : [' . array_shift($diff) . ']');
}
$config = array_merge($defaults, $config);
//error_log('#### config ' . print_r($config, true));
return $config;
}
}

View File

@@ -0,0 +1,36 @@
<?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
*/
namespace PrestaShop\Module\PsAccounts\Configuration;
use PrestaShop\Module\PsAccounts\Exception\OptionResolutionException;
interface Configurable
{
/**
* @param array $config
* @param array $defaults
*
* @return mixed
*
* @throws OptionResolutionException
*/
public function resolveConfig(array $config, array $defaults = []);
}

View File

@@ -0,0 +1,28 @@
<?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
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,114 @@
<?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
*/
namespace PrestaShop\Module\PsAccounts\Context;
use Context;
use PrestaShop\Module\PsAccounts\Repository\ConfigurationRepository;
/**
* Get the shop context
*/
class ShopContext
{
/**
* @var ConfigurationRepository
*/
private $configuration;
/**
* @var Context
*/
private $context;
/**
* ShopContext constructor.
*
* @param ConfigurationRepository $configuration
* @param Context $context
*/
public function __construct(
ConfigurationRepository $configuration,
Context $context
) {
$this->configuration = $configuration;
$this->context = $context;
}
/**
* @return bool
*/
public function isShop17()
{
return version_compare(_PS_VERSION_, '1.7.0.0', '>=');
}
/**
* @return bool
*/
public function isShop173()
{
return version_compare(_PS_VERSION_, '1.7.3.0', '>=');
}
/**
* @return bool
*/
public function isShopContext()
{
if (\Shop::isFeatureActive() && \Shop::getContext() !== \Shop::CONTEXT_SHOP) {
return false;
}
return true;
}
/**
* @return bool
*/
public function sslEnabled()
{
return $this->configuration->sslEnabled();
}
/**
* @return string
*/
public function getProtocol()
{
return false == $this->sslEnabled() ? 'http' : 'https';
}
/**
* @return Context
*/
public function getContext()
{
return $this->context;
}
/**
* @return ConfigurationRepository
*/
public function getConfiguration()
{
return $this->configuration;
}
}

View File

@@ -0,0 +1,28 @@
<?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
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,116 @@
<?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
*/
namespace PrestaShop\Module\PsAccounts\DependencyInjection;
use PrestaShop\ModuleLibCacheDirectoryProvider\Cache\CacheDirectoryProvider;
use Symfony\Component\Config\ConfigCache;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
class ContainerProvider
{
/**
* @var string Module Name
*/
private $moduleName;
/**
* @var string Module Local Path
*/
private $moduleLocalPath;
/**
* @var string
*/
private $moduleEnv;
/**
* @var CacheDirectoryProvider
*/
private $cacheDirectory;
/**
* @param string $moduleName
* @param string $moduleLocalPath
* @param string $moduleEnv
* @param CacheDirectoryProvider $cacheDirectory
*/
public function __construct(
$moduleName,
$moduleLocalPath,
$moduleEnv,
CacheDirectoryProvider $cacheDirectory
) {
$this->moduleName = $moduleName;
$this->moduleLocalPath = $moduleLocalPath;
$this->moduleEnv = $moduleEnv;
$this->cacheDirectory = $cacheDirectory;
}
/**
* @param string $containerName
*
* @return ContainerInterface
*
* @throws \Exception
*/
public function get($containerName)
{
$containerClassName = ucfirst($this->moduleName)
. ucfirst($containerName)
. 'Container'
;
$containerFilePath = $this->cacheDirectory->getPath() . '/' . $containerClassName . '.php';
$containerConfigCache = new ConfigCache($containerFilePath, _PS_MODE_DEV_);
if ($containerConfigCache->isFresh()) {
require_once $containerFilePath;
return new $containerClassName();
}
$containerBuilder = new ContainerBuilder();
$containerBuilder->set(
$this->moduleName . '.cache.directory',
$this->cacheDirectory
);
$moduleConfigPath = $this->moduleLocalPath
. 'config/'
. $containerName
;
$loader = new YamlFileLoader($containerBuilder, new FileLocator($moduleConfigPath));
$loader->load('services' . ($this->moduleEnv ? '_' . $this->moduleEnv : '') . '.yml');
$containerBuilder->compile();
$dumper = new PhpDumper($containerBuilder);
$containerConfigCache->write(
$dumper->dump(['class' => $containerClassName]),
$containerBuilder->getResources()
);
return $containerBuilder;
}
}

View File

@@ -0,0 +1,107 @@
<?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
*/
namespace PrestaShop\Module\PsAccounts\DependencyInjection;
use PrestaShop\ModuleLibCacheDirectoryProvider\Cache\CacheDirectoryProvider;
//use PrestaShop\ModuleLibServiceContainer\DependencyInjection\ContainerProvider;
use Symfony\Component\DependencyInjection\ContainerInterface;
class ServiceContainer
{
/**
* @var string Module Name
*/
private $moduleName;
/**
* @var string Module Local Path
*/
private $moduleLocalPath;
/**
* @var string
*/
private $moduleEnv;
/**
* @var ContainerInterface
*/
private $container;
/**
* @param string $moduleName
* @param string $moduleLocalPath
* @param string $moduleEnv
*
* @throws \Exception
*/
public function __construct($moduleName, $moduleLocalPath, $moduleEnv)
{
$this->moduleName = $moduleName;
$this->moduleLocalPath = $moduleLocalPath;
$this->moduleEnv = $moduleEnv;
$this->initContainer();
}
/**
* @param string $serviceName
*
* @return object|null
*
* @throws \Exception
*/
public function getService($serviceName)
{
if (null === $this->container) {
$this->initContainer();
}
return $this->container->get($serviceName);
}
/**
* @return ContainerInterface
*/
public function getContainer()
{
return $this->container;
}
/**
* Instantiate a new ContainerProvider
*
* @return void
*
* @throws \Exception
*/
private function initContainer()
{
$cacheDirectory = new CacheDirectoryProvider(
_PS_VERSION_,
_PS_ROOT_DIR_,
_PS_MODE_DEV_
);
$containerProvider = new ContainerProvider($this->moduleName, $this->moduleLocalPath, $this->moduleEnv, $cacheDirectory);
$this->container = $containerProvider->get(defined('_PS_ADMIN_DIR_') || defined('PS_INSTALLATION_IN_PROGRESS') ? 'admin' : 'front');
}
}

View File

@@ -0,0 +1,28 @@
<?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
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,25 @@
<?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
*/
namespace PrestaShop\Module\PsAccounts\Exception;
class BillingException extends \Exception
{
}

View File

@@ -0,0 +1,25 @@
<?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
*/
namespace PrestaShop\Module\PsAccounts\Exception;
class HmacException extends \Exception
{
}

View File

@@ -0,0 +1,25 @@
<?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
*/
namespace PrestaShop\Module\PsAccounts\Exception;
class OptionResolutionException extends \Exception
{
}

View File

@@ -0,0 +1,25 @@
<?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
*/
namespace PrestaShop\Module\PsAccounts\Exception;
class QueryParamsException extends \Exception
{
}

View File

@@ -0,0 +1,25 @@
<?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
*/
namespace PrestaShop\Module\PsAccounts\Exception;
class RsaSignedDataNotFoundException extends \Exception
{
}

View File

@@ -0,0 +1,25 @@
<?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
*/
namespace PrestaShop\Module\PsAccounts\Exception;
class SshKeysNotFoundException extends \Exception
{
}

View File

@@ -0,0 +1,25 @@
<?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
*/
namespace PrestaShop\Module\PsAccounts\Exception;
class TokenNotFoundException extends \Exception
{
}

View File

@@ -0,0 +1,25 @@
<?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
*/
namespace PrestaShop\Module\PsAccounts\Exception;
class WebhookException extends \Exception
{
}

View File

@@ -0,0 +1,28 @@
<?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
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,54 @@
<?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
*/
namespace PrestaShop\Module\PsAccounts\Factory;
use Monolog\Handler\RotatingFileHandler;
use Monolog\Logger;
class PsAccountsLogger
{
const MAX_FILES = 15;
/**
* Create logger.
*
* @return \Monolog\Logger
*/
public static function create()
{
$path = _PS_ROOT_DIR_ . '/var/logs/ps_accounts';
if (version_compare(_PS_VERSION_, '1.7', '<')) {
$path = _PS_ROOT_DIR_ . '/log/ps_accounts';
} elseif (version_compare(_PS_VERSION_, '1.7.4', '<')) {
$path = _PS_ROOT_DIR_ . '/app/logs/ps_accounts';
}
$rotatingFileHandler = new RotatingFileHandler(
$path,
static::MAX_FILES
);
$logger = new Logger('ps_accounts');
$logger->pushHandler($rotatingFileHandler);
return $logger;
}
}

View File

@@ -0,0 +1,28 @@
<?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
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,124 @@
<?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
*/
namespace PrestaShop\Module\PsAccounts\Handler\Error;
use Module;
use PrestaShop\Module\PsAccounts\Adapter\Configuration;
use PrestaShop\Module\PsAccounts\Repository\ConfigurationRepository;
use Ps_accounts;
use Raven_Client;
/**
* Handle Error.
*/
class Sentry
{
/**
* @var Raven_Client
*/
protected $client;
/**
* @var ConfigurationRepository
*/
private $configuration;
/**
* ErrorHandler constructor.
*
* @param string $sentryCredentials
* @param string $environment
* @param ConfigurationRepository $configuration
*
* @throws \Raven_Exception
*/
public function __construct(
$sentryCredentials,
$environment,
ConfigurationRepository $configuration
) {
$this->configuration = $configuration;
$this->client = new Raven_Client(
$sentryCredentials,
[
'level' => 'warning',
'tags' => [
'environment' => $environment,
'php_version' => phpversion(),
'ps_accounts_version' => \Ps_accounts::VERSION,
'prestashop_version' => _PS_VERSION_,
'ps_accounts_is_enabled' => \Module::isEnabled('ps_accounts'),
'ps_accounts_is_installed' => \Module::isInstalled('ps_accounts'),
'email' => $this->configuration->getFirebaseEmail(),
Configuration::PS_ACCOUNTS_FIREBASE_ID_TOKEN => $this->configuration->getFirebaseIdToken(),
Configuration::PS_ACCOUNTS_FIREBASE_REFRESH_TOKEN => $this->configuration->getFirebaseRefreshToken(),
Configuration::PSX_UUID_V4 => $this->configuration->getShopUuid(),
Configuration::PS_ACCOUNTS_FIREBASE_EMAIL_IS_VERIFIED => $this->configuration->firebaseEmailIsVerified(),
Configuration::PS_ACCOUNTS_FIREBASE_EMAIL => $this->configuration->getFirebaseEmail(),
Configuration::PS_ACCOUNTS_RSA_PUBLIC_KEY => $this->configuration->getAccountsRsaPublicKey(),
Configuration::PS_ACCOUNTS_RSA_SIGN_DATA => $this->configuration->getAccountsRsaSignData(),
],
]
);
$this->client->install();
}
/**
* @param \Throwable $exception
*
* @return void
*
* @throws \Exception
*/
public static function capture(\Throwable $exception)
{
/** @var Ps_accounts $psAccounts */
$psAccounts = Module::getInstanceByName('ps_accounts');
/** @var self $instance */
$instance = $psAccounts->getService(self::class);
$instance->client->captureException($exception);
}
/**
* @param \Throwable $exception
*
* @return void
*
* @throws \Throwable
*/
public static function captureAndRethrow(\Throwable $exception)
{
self::capture($exception);
throw $exception;
}
/**
* @return void
*/
private function __clone()
{
}
}

View File

@@ -0,0 +1,28 @@
<?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
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,64 @@
<?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
*/
namespace PrestaShop\Module\PsAccounts\Handler\Response;
use GuzzleHttp\Message\ResponseInterface;
/**
* Handle api response.
*/
class ApiResponseHandler
{
/**
* Format api response.
*
* @return array
*/
public function handleResponse(ResponseInterface $response)
{
$responseContents = json_decode($response->getBody()->getContents(), true);
return [
'status' => $this->responseIsSuccessful($responseContents, $response->getStatusCode()),
'httpCode' => $response->getStatusCode(),
'body' => $responseContents,
];
}
/**
* Check if the response is successful or not (response code 200 to 299).
*
* @param array $responseContents
* @param int $httpStatusCode
*
* @return bool
*/
private function responseIsSuccessful($responseContents, $httpStatusCode)
{
// Directly return true, no need to check the body for a 204 status code
// 204 status code is only send by /payments/order/update
if (204 === $httpStatusCode) {
return true;
}
return '2' === substr((string) $httpStatusCode, 0, 1) && null !== $responseContents;
}
}

View File

@@ -0,0 +1,28 @@
<?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
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,28 @@
<?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
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,173 @@
<?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
*/
namespace PrestaShop\Module\PsAccounts\Installer;
use Module;
use PrestaShop\Module\PsAccounts\Adapter\Link;
use PrestaShop\Module\PsAccounts\Context\ShopContext;
use PrestaShop\Module\PsAccounts\Handler\Error\Sentry;
use PrestaShop\PrestaShop\Adapter\SymfonyContainer;
use PrestaShop\PrestaShop\Core\Addon\Module\ModuleManagerBuilder;
use Tools;
/**
* Install ps_accounts module
*/
class Installer
{
/**
* @var ShopContext
*/
private $shopContext;
/**
* @var Link
*/
private $link;
/**
* Install constructor.
*
* @param ShopContext $shopContext
* @param Link $link
*/
public function __construct(
ShopContext $shopContext,
Link $link
) {
$this->shopContext = $shopContext;
$this->link = $link;
}
/**
* @param string $module
* @param bool $upgrade
*
* @return bool
*
* @throws \Exception
*/
public function installModule($module, $upgrade = true)
{
if (false === $this->shopContext->isShop17()) {
return true;
}
$moduleManager = ModuleManagerBuilder::getInstance()->build();
if (false === $upgrade && true === $moduleManager->isInstalled($module)) {
return true;
}
// install or upgrade module
$moduleIsInstalled = $moduleManager->install($module);
if (false === $moduleIsInstalled) {
Sentry::capture(new \Exception("Module ${module} can't be installed"));
}
return $moduleIsInstalled;
}
/**
* @param string $module
* @param string $psxName
*
* @return string | null
*
* @throws \PrestaShopException
*/
public function getInstallUrl($module, $psxName)
{
if ($this->shopContext->isShop17()) {
$router = SymfonyContainer::getInstance()->get('router');
return Tools::getHttpHost(true) . $router->generate('admin_module_manage_action', [
'action' => 'install',
'module_name' => $module,
]);
}
return $this->link->getAdminLink('AdminModules', true, [], [
'module_name' => $psxName,
'configure' => $psxName,
'install' => $module,
]);
}
/**
* @param string $module
* @param string $psxName
*
* @return string | null
*
* @throws \PrestaShopException
*/
public function getEnableUrl($module, $psxName)
{
if ($this->shopContext->isShop17()) {
$router = SymfonyContainer::getInstance()->get('router');
return Tools::getHttpHost(true) . $router->generate('admin_module_manage_action', [
'action' => 'enable',
'module_name' => $module,
]);
}
return $this->link->getAdminLink('AdminModules', true, [], [
'module_name' => $psxName,
'configure' => $psxName,
//'enable' => $module,
'install' => $module,
]);
}
/**
* @param string $module
*
* @return bool
*/
public function isInstalled($module)
{
if (false === $this->shopContext->isShop17()) {
return Module::isInstalled('ps_eventbus');
}
$moduleManager = ModuleManagerBuilder::getInstance()->build();
return $moduleManager->isInstalled($module);
}
/**
* @param string $module
*
* @return bool
*/
public function isEnabled($module)
{
if (false === $this->shopContext->isShop17()) {
return Module::isEnabled($module);
}
$moduleManager = ModuleManagerBuilder::getInstance()->build();
return $moduleManager->isEnabled($module);
}
}

View File

@@ -0,0 +1,113 @@
<?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
*/
namespace PrestaShop\Module\PsAccounts\Module;
use Tools;
class Install
{
const PARENT_TAB_NAME = -1;
const TAB_ACTIVE = 0;
/**
* @var \Ps_accounts
*/
private $module;
/**
* @var \Db
*/
private $db;
public function __construct(\Ps_accounts $module, \Db $db)
{
$this->module = $module;
$this->db = $db;
}
/**
* installInMenu.
*
* @return bool
*
* @throws \PrestaShopDatabaseException
* @throws \PrestaShopException
*/
public function installInMenu()
{
foreach ($this->module->adminControllers as $controllerName) {
$tabId = (int) \Tab::getIdFromClassName($controllerName);
if (!$tabId) {
$tabId = null;
}
$tab = new \Tab($tabId);
$tab->active = (bool) self::TAB_ACTIVE;
$tab->class_name = $controllerName;
$tab->name = [];
foreach (\Language::getLanguages(true) as $lang) {
$tab->name[$lang['id_lang']] = $this->module->displayName;
}
$tab->id_parent = -1 == self::PARENT_TAB_NAME ? (int) \Tab::getIdFromClassName((string) self::PARENT_TAB_NAME) : -1;
$tab->module = $this->module->name;
$tab->save();
}
return true;
}
/**
* Installs database tables
*
* @return bool
*/
public function installDatabaseTables()
{
$dbInstallFile = "{$this->module->getLocalPath()}/sql/install.sql";
if (!file_exists($dbInstallFile)) {
return false;
}
$sql = Tools::file_get_contents($dbInstallFile);
if (empty($sql) || !is_string($sql)) {
return false;
}
$sql = str_replace(['PREFIX_', 'ENGINE_TYPE'], [_DB_PREFIX_, _MYSQL_ENGINE_], $sql);
$sql = preg_split("/;\s*[\r\n]+/", trim($sql));
if (!empty($sql)) {
foreach ($sql as $query) {
if (!$this->db->execute($query)) {
return false;
}
}
}
return true;
}
}

View File

@@ -0,0 +1,95 @@
<?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
*/
namespace PrestaShop\Module\PsAccounts\Module;
use Tools;
class Uninstall
{
/**
* @var \Ps_accounts
*/
private $module;
/**
* @var \Db
*/
private $db;
public function __construct(\Ps_accounts $module, \Db $db)
{
$this->module = $module;
$this->db = $db;
}
/**
* uninstallMenu.
*
* @return bool
*/
public function uninstallMenu()
{
// foreach( ['configure', 'hmac', 'ajax'] as $aliasController){
foreach ($this->module->adminControllers as $controllerName) {
$tabId = (int) \Tab::getIdFromClassName($controllerName);
if (!$tabId) {
return true;
}
$tab = new \Tab($tabId);
return $tab->delete();
}
return true;
}
/**
* @return bool
*/
public function uninstallDatabaseTables()
{
$dbUninstallFile = "{$this->module->getLocalPath()}/sql/uninstall.sql";
if (!file_exists($dbUninstallFile)) {
return false;
}
$sql = Tools::file_get_contents($dbUninstallFile);
if (empty($sql) || !is_string($sql)) {
return false;
}
$sql = str_replace(['PREFIX_', 'ENGINE_TYPE'], [_DB_PREFIX_, _MYSQL_ENGINE_], $sql);
$sql = preg_split("/;\s*[\r\n]+/", trim($sql));
if (!empty($sql)) {
foreach ($sql as $query) {
if (!$this->db->execute($query)) {
return false;
}
}
}
return true;
}
}

View File

@@ -0,0 +1,28 @@
<?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
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,65 @@
<?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
*/
namespace PrestaShop\Module\PsAccounts\Presenter;
use Module;
use PrestaShop\Module\PsAccounts\Installer\Installer;
use Ps_accounts;
class DependenciesPresenter implements PresenterInterface
{
/**
* @var Installer
*/
private $installer;
public function __construct()
{
/** @var Ps_accounts $psAccounts */
$psAccounts = Module::getInstanceByName('ps_accounts');
$this->installer = $psAccounts->getService(Installer::class);
}
/**
* @param string $psxName
*
* @return array
*
* @throws \PrestaShopException
*/
public function present($psxName = 'ps_accounts')
{
$module = 'ps_eventbus';
return [
'dependencies' => [
$module => [
'isInstalled' => $this->installer->isInstalled($module),
'installLink' => $this->installer->getInstallUrl($module, $psxName),
'isEnabled' => $this->installer->isEnabled($module),
'enableLink' => $this->installer->getEnableUrl($module, $psxName),
],
],
];
}
}

View File

@@ -0,0 +1,34 @@
<?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
*/
namespace PrestaShop\Module\PsAccounts\Presenter;
/**
* Interface StorePresenter defines methods for store presenter.
*/
interface PresenterInterface
{
/**
* Present store
*
* @return array
*/
public function present();
}

View File

@@ -0,0 +1,161 @@
<?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
*/
namespace PrestaShop\Module\PsAccounts\Presenter;
use Module;
use PrestaShop\Module\PsAccounts\Handler\Error\Sentry;
use PrestaShop\Module\PsAccounts\Installer\Installer;
use PrestaShop\Module\PsAccounts\Provider\ShopProvider;
use PrestaShop\Module\PsAccounts\Repository\ConfigurationRepository;
use PrestaShop\Module\PsAccounts\Service\PsAccountsService;
use PrestaShop\Module\PsAccounts\Service\ShopLinkAccountService;
use PrestaShop\Module\PsAccounts\Service\SsoService;
/**
* Construct the psaccounts module.
*/
class PsAccountsPresenter implements PresenterInterface
{
/**
* @var ShopProvider
*/
protected $shopProvider;
/**
* @var ShopLinkAccountService
*/
protected $shopLinkAccountService;
/**
* @var SsoService
*/
protected $ssoService;
/**
* @var ConfigurationRepository
*/
protected $configuration;
/**
* @var Installer
*/
private $installer;
/**
* @var PsAccountsService
*/
private $psAccountsService;
/**
* PsAccountsPresenter constructor.
*
* @param PsAccountsService $psAccountsService
* @param ShopProvider $shopProvider
* @param ShopLinkAccountService $shopLinkAccountService
* @param SsoService $ssoService
* @param Installer $installer
* @param ConfigurationRepository $configuration
*/
public function __construct(
PsAccountsService $psAccountsService,
ShopProvider $shopProvider,
ShopLinkAccountService $shopLinkAccountService,
SsoService $ssoService,
Installer $installer,
ConfigurationRepository $configuration
) {
$this->psAccountsService = $psAccountsService;
$this->shopProvider = $shopProvider;
$this->shopLinkAccountService = $shopLinkAccountService;
$this->ssoService = $ssoService;
$this->installer = $installer;
$this->configuration = $configuration;
}
/**
* Present the PsAccounts module data for JS
*
* @param string $psxName
*
* @return array
*
* @throws \Throwable
*/
public function present($psxName = 'ps_accounts')
{
// FIXME : Do this elsewhere
$this->shopLinkAccountService->manageOnboarding($psxName);
$shopContext = $this->shopProvider->getShopContext();
$isEnabled = $this->installer->isEnabled('ps_accounts');
try {
return array_merge(
[
'psxName' => $psxName,
'psIs17' => $shopContext->isShop17(),
/////////////////////////////
// InstallerPresenter
'psAccountsIsInstalled' => true,
'psAccountsInstallLink' => null,
'psAccountsIsEnabled' => true,
'psAccountsEnableLink' => null,
'psAccountsIsUptodate' => true,
'psAccountsUpdateLink' => null,
////////////////////////////
// PsAccountsPresenter
'onboardingLink' => $this->shopLinkAccountService->getLinkAccountUrl($psxName),
// FIXME : Mix "SSO user" with "Backend user"
'user' => [
'email' => $this->configuration->getFirebaseEmail() ?: null,
'emailIsValidated' => $this->configuration->firebaseEmailIsVerified(),
'isSuperAdmin' => $shopContext->getContext()->employee->isSuperAdmin(),
],
'currentShop' => $this->shopProvider->getCurrentShop($psxName),
'isShopContext' => $shopContext->isShopContext(),
'shops' => $this->shopProvider->getShopsTree($psxName),
'superAdminEmail' => $this->psAccountsService->getSuperAdminEmail(),
// FIXME : move into Vue components .env
'ssoResendVerificationEmail' => $this->ssoService->getSsoResendVerificationEmailUrl(),
'manageAccountLink' => $this->ssoService->getSsoAccountUrl(),
'adminAjaxLink' => $this->psAccountsService->getAdminAjaxUrl(),
],
(new DependenciesPresenter())->present($psxName)
);
} catch (\Exception $e) {
Sentry::captureAndRethrow($e);
}
return [];
}
}

View File

@@ -0,0 +1,138 @@
<?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
*/
namespace PrestaShop\Module\PsAccounts\Presenter\Store\Context;
use Context;
use PrestaShop\Module\PsAccounts\Adapter\Link;
use PrestaShop\Module\PsAccounts\Presenter\PresenterInterface;
use PrestaShop\Module\PsAccounts\Provider\ShopProvider;
use PrestaShop\Module\PsAccounts\Service\PsAccountsService;
use Ps_accounts;
class ContextPresenter implements PresenterInterface
{
/**
* @var Ps_accounts
*/
private $module;
/**
* @var PsAccountsService
*/
private $psAccountsService;
/**
* @var Context
*/
private $context;
public function __construct(Ps_accounts $module, Context $context)
{
$this->module = $module;
$this->context = $context;
$this->psAccountsService = $this->module->getService(PsAccountsService::class);
}
/**
* Check if the merchant is onboarded on ps accounts
*
* @return bool
*/
private function psAccountsIsOnboarded()
{
if ($this->psAccountsService->getRefreshToken() && $this->psAccountsService->isEmailValidated()) {
return true;
}
return false;
}
/**
* Present the Context Vuex
*
* @return array
*
* @throws \PrestaShopException
*/
public function present()
{
/** @var Link $linkAdapter */
$linkAdapter = $this->module->getService(Link::class);
/** @var ShopProvider $shopProvider */
$shopProvider = $this->module->getService(ShopProvider::class);
$currentShop = $shopProvider->getCurrentShop();
return [
'context' => [
'app' => $this->getCurrentVueApp(),
'user' => [
'psAccountsIsOnboarded' => $this->psAccountsIsOnboarded(),
],
'version_ps' => _PS_VERSION_,
'version_module' => $this->module->version,
'shopId' => $this->psAccountsService->getShopUuidV4(),
'isShop17' => version_compare(_PS_VERSION_, '1.7.3.0', '>='),
'configurationLink' => $linkAdapter->getAdminLink('AdminModules', true, [], ['configure' => $this->module->name]),
'controllersLinks' => [
'ajax' => $linkAdapter->getAdminLink('AdminAjaxPsAccounts'),
],
'i18n' => [
'isoCode' => $this->context->language->iso_code,
'languageLocale' => $this->context->language->language_code,
'currencyIsoCode' => $this->context->currency->iso_code,
],
'shop' => [
'domain' => $currentShop['domain'],
'url' => $currentShop['url'],
],
'readmeUrl' => $this->getReadme(),
],
];
}
/**
* Get Vue App to use in terms of context Controller Name
*
* @return string
*/
private function getCurrentVueApp()
{
return 'settings';
}
/**
* Get the documentation url depending on the current language
*
* @return string path of the doc
*/
private function getReadme()
{
$isoCode = $this->context->language->iso_code;
if (!file_exists(_PS_ROOT_DIR_ . _MODULE_DIR_ . $this->module->name . '/docs/readme_' . $isoCode . '.pdf')) {
$isoCode = 'en';
}
return _MODULE_DIR_ . $this->module->name . '/docs/readme_' . $isoCode . '.pdf';
}
}

View File

@@ -0,0 +1,28 @@
<?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
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,92 @@
<?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
*/
namespace PrestaShop\Module\PsAccounts\Presenter\Store;
use Context;
use PrestaShop\Module\PsAccounts\Presenter\PresenterInterface;
use PrestaShop\Module\PsAccounts\Presenter\Store\Context\ContextPresenter;
use PrestaShop\Module\PsAccounts\Translations\SettingsTranslations;
/**
* Present the store to the vuejs app (vuex)
*/
class StorePresenter implements PresenterInterface
{
/**
* @var \Ps_accounts
*/
private $module;
/**
* @var Context
*/
private $context;
/**
* @var array
*/
private $store;
/**
* @param \Ps_accounts $module
* @param Context $context
* @param array|null $store
*/
public function __construct(\Ps_accounts $module, Context $context, array $store = null)
{
// Allow to set a custom store for tests purpose
if (null !== $store) {
$this->store = $store;
}
$this->module = $module;
$this->context = $context;
}
/**
* Build the store required by vuex
*
* @return array
*
* @throws \PrestaShopException
*/
public function present()
{
if (null !== $this->store) {
return $this->store;
}
$contextPresenter = (new ContextPresenter($this->module, $this->context))->present();
// Load a presenter depending on the application to load (dashboard | settings)
$this->store = array_merge(
$contextPresenter,
[
'settings' => [
'faq' => false,
'translations' => (new SettingsTranslations($this->module))->getTranslations(),
],
]
);
return $this->store;
}
}

View File

@@ -0,0 +1,28 @@
<?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
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,28 @@
<?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
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,132 @@
<?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
*/
namespace PrestaShop\Module\PsAccounts\Provider;
use PrestaShop\Module\PsAccounts\Adapter\Link;
use PrestaShop\Module\PsAccounts\Context\ShopContext;
class ShopProvider
{
/**
* @var ShopContext
*/
private $shopContext;
/**
* @var Link
*/
private $link;
/**
* ShopProvider constructor.
*
* @param ShopContext $shopContext
* @param Link $link
*/
public function __construct(
ShopContext $shopContext,
Link $link
) {
$this->shopContext = $shopContext;
$this->link = $link;
}
/**
* @param string $psxName
*
* @return array
*
* @throws \PrestaShopException
*/
public function getCurrentShop($psxName = '')
{
$shop = \Shop::getShop($this->shopContext->getContext()->shop->id);
return [
'id' => $shop['id_shop'],
'name' => $shop['name'],
'domain' => $shop['domain'],
'domainSsl' => $shop['domain_ssl'],
'url' => $this->link->getAdminLink(
'AdminModules',
true,
[],
[
'configure' => $psxName,
'setShopContext' => 's-' . $shop['id_shop'],
]
),
];
}
/**
* @param string $psxName
*
* @return array
*
* @throws \PrestaShopException
*/
public function getShopsTree($psxName)
{
$shopList = [];
if (true === $this->shopContext->isShopContext()) {
return $shopList;
}
foreach (\Shop::getTree() as $groupId => $groupData) {
$shops = [];
foreach ($groupData['shops'] as $shopId => $shopData) {
$shops[] = [
'id' => $shopId,
'name' => $shopData['name'],
'domain' => $shopData['domain'],
'domainSsl' => $shopData['domain_ssl'],
'url' => $this->link->getAdminLink(
'AdminModules',
true,
[],
[
'configure' => $psxName,
'setShopContext' => 's-' . $shopId,
]
),
];
}
$shopList[] = [
'id' => $groupId,
'name' => $groupData['name'],
'shops' => $shops,
];
}
return $shopList;
}
/**
* @return ShopContext
*/
public function getShopContext()
{
return $this->shopContext;
}
}

View File

@@ -0,0 +1,28 @@
<?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
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,256 @@
<?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
*/
namespace PrestaShop\Module\PsAccounts\Repository;
use PrestaShop\Module\PsAccounts\Adapter\Configuration;
class ConfigurationRepository
{
/**
* @var Configuration
*/
private $configuration;
/**
* ConfigurationRepository constructor.
*
* @param Configuration|null $configuration
*/
public function __construct(Configuration $configuration = null)
{
$this->configuration = $configuration;
}
/**
* @return int
*/
public function getShopId()
{
return $this->configuration->getIdShop();
}
/**
* @param int $shopId
*
* @return void
*/
public function setShopId($shopId)
{
$this->configuration->setIdShop($shopId);
}
/**
* @return string
*/
public function getFirebaseIdToken()
{
return $this->configuration->get(Configuration::PS_ACCOUNTS_FIREBASE_ID_TOKEN);
}
/**
* @return string
*/
public function getFirebaseRefreshToken()
{
return $this->configuration->get(Configuration::PS_ACCOUNTS_FIREBASE_REFRESH_TOKEN);
}
/**
* @param string $idToken
* @param string $refreshToken
*
* @return void
*/
public function updateFirebaseIdAndRefreshTokens($idToken, $refreshToken)
{
if (false === $this->configuration->get(Configuration::PS_PSX_FIREBASE_ID_TOKEN)) {
// FIXME: This to avoid mutual disconnect between ps_accounts & ps_checkout
$this->configuration->set(Configuration::PS_PSX_FIREBASE_ID_TOKEN, $idToken);
$this->configuration->set(Configuration::PS_PSX_FIREBASE_REFRESH_TOKEN, $refreshToken);
$this->configuration->set(Configuration::PS_PSX_FIREBASE_REFRESH_DATE, date('Y-m-d H:i:s'));
}
$this->configuration->set(Configuration::PS_ACCOUNTS_FIREBASE_ID_TOKEN, $idToken);
$this->configuration->set(Configuration::PS_ACCOUNTS_FIREBASE_REFRESH_TOKEN, $refreshToken);
}
/**
* Check if we have a refresh token.
*
* @return bool
*/
public function hasFirebaseRefreshToken()
{
return !empty($this->configuration->get(Configuration::PS_ACCOUNTS_FIREBASE_REFRESH_TOKEN));
}
/**
* @return string | null
*/
public function getFirebaseEmail()
{
return $this->configuration->get(Configuration::PS_ACCOUNTS_FIREBASE_EMAIL);
}
/**
* @param string $email
*
* @return void
*/
public function updateFirebaseEmail($email)
{
if (false === $this->configuration->get(Configuration::PS_PSX_FIREBASE_EMAIL)) {
$this->configuration->set(Configuration::PS_PSX_FIREBASE_EMAIL, $email);
}
$this->configuration->set(Configuration::PS_ACCOUNTS_FIREBASE_EMAIL, $email);
}
/**
* @return bool
*/
public function firebaseEmailIsVerified()
{
return in_array(
$this->configuration->get(Configuration::PS_ACCOUNTS_FIREBASE_EMAIL_IS_VERIFIED),
['1', 1, true]
);
}
/**
* @param bool $status
*
* @return void
*/
public function updateFirebaseEmailIsVerified($status)
{
$this->configuration->set(
Configuration::PS_ACCOUNTS_FIREBASE_EMAIL_IS_VERIFIED,
(string) $status
);
}
/**
* @deprecated since v4.0.0
*
* @return string | null
*/
public function getFirebaseLocalId()
{
return $this->configuration->get(Configuration::PS_ACCOUNTS_FIREBASE_LOCAL_ID);
}
/**
* @deprecated sibce v4.0.0
*
* @param string $localId
*
* @return void
*/
public function updateFirebaseLocalId($localId)
{
if (false === $this->configuration->get(Configuration::PS_PSX_FIREBASE_LOCAL_ID)) {
$this->configuration->set(Configuration::PS_PSX_FIREBASE_LOCAL_ID, $localId);
}
$this->configuration->set(Configuration::PS_ACCOUNTS_FIREBASE_LOCAL_ID, $localId);
}
/**
* @return string
*/
public function getShopUuid()
{
return $this->configuration->get(Configuration::PSX_UUID_V4);
}
/**
* @param string $uuid Firebase User UUID
*
* @return void
*/
public function updateShopUuid($uuid)
{
if (false === $this->configuration->get(Configuration::PS_CHECKOUT_SHOP_UUID_V4)) {
$this->configuration->set(Configuration::PS_CHECKOUT_SHOP_UUID_V4, $uuid);
}
$this->configuration->set(Configuration::PSX_UUID_V4, $uuid);
}
/**
* @return string
*/
public function getAccountsRsaPrivateKey()
{
return $this->configuration->get(Configuration::PS_ACCOUNTS_RSA_PRIVATE_KEY);
}
/**
* @param string $key
*
* @return void
*/
public function updateAccountsRsaPrivateKey($key)
{
$this->configuration->set(Configuration::PS_ACCOUNTS_RSA_PRIVATE_KEY, $key);
}
/**
* @return string
*/
public function getAccountsRsaPublicKey()
{
return $this->configuration->get(Configuration::PS_ACCOUNTS_RSA_PUBLIC_KEY);
}
/**
* @param string $key
*
* @return void
*/
public function updateAccountsRsaPublicKey($key)
{
$this->configuration->set(Configuration::PS_ACCOUNTS_RSA_PUBLIC_KEY, $key);
}
/**
* @return string
*/
public function getAccountsRsaSignData()
{
return $this->configuration->get(Configuration::PS_ACCOUNTS_RSA_SIGN_DATA);
}
/**
* @param string $signData
*
* @return void
*/
public function updateAccountsRsaSignData($signData)
{
$this->configuration->set(Configuration::PS_ACCOUNTS_RSA_SIGN_DATA, $signData);
}
/**
* @return bool
*/
public function sslEnabled()
{
return true == $this->configuration->get('PS_SSL_ENABLED');
}
}

View File

@@ -0,0 +1,57 @@
<?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
*/
namespace PrestaShop\Module\PsAccounts\Repository;
use Context;
use Db;
use DbQuery;
class ShopRepository
{
/**
* @var Context
*/
private $context;
/**
* @var Db
*/
private $db;
public function __construct(Context $context, Db $db)
{
$this->context = $context;
$this->db = $db;
}
/**
* @return int
*/
public function getMultiShopCount()
{
$query = new DbQuery();
$query->select('COUNT(id_shop)')
->from('shop')
->where('active = 1 and deleted = 0');
return (int) $this->db->getValue($query);
}
}

View File

@@ -0,0 +1,28 @@
<?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
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,159 @@
<?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
*/
namespace PrestaShop\Module\PsAccounts\Service;
use PrestaShop\Module\PsAccounts\Adapter\Link;
use PrestaShop\Module\PsAccounts\Repository\ConfigurationRepository;
/**
* Class PsAccountsService
*/
class PsAccountsService
{
/**
* @var Link
*/
protected $link;
/**
* @var ConfigurationRepository
*/
private $configuration;
/**
* @var \Ps_accounts
*/
private $module;
/**
* @var ShopTokenService
*/
private $shopTokenService;
/**
* PsAccountsService constructor.
*
* @param \Ps_accounts $module
* @param ShopTokenService $shopTokenService
* @param ConfigurationRepository $configuration
* @param Link $link
*/
public function __construct(
\Ps_accounts $module,
ShopTokenService $shopTokenService,
ConfigurationRepository $configuration,
Link $link
) {
$this->configuration = $configuration;
$this->shopTokenService = $shopTokenService;
$this->module = $module;
$this->link = $link;
}
/**
* @return string
*/
public function getSuperAdminEmail()
{
return (new \Employee(1))->email;
}
/**
* @return string | false
*/
public function getShopUuidV4()
{
return $this->configuration->getShopUuid();
}
/**
* Get the user firebase token.
*
* @return string
*
* @throws \Exception
*/
public function getOrRefreshToken()
{
return $this->shopTokenService->getOrRefreshToken();
}
/**
* @return string|null
*/
public function getRefreshToken()
{
return $this->shopTokenService->getRefreshToken();
}
/**
* @return string|null
*/
public function getToken()
{
return $this->shopTokenService->getToken();
}
/**
* @return bool
*/
public function isEmailValidated()
{
return $this->configuration->firebaseEmailIsVerified();
}
/**
* @return string|null
*/
public function getEmail()
{
return $this->configuration->getFirebaseEmail();
}
/**
* @return bool
*
* @throws \Exception
*/
public function isAccountLinked()
{
/** @var ShopLinkAccountService $shopLinkAccountService */
$shopLinkAccountService = $this->module->getService(ShopLinkAccountService::class);
return $shopLinkAccountService->isAccountLinked();
}
/**
* Generate ajax admin link with token
* available via PsAccountsPresenter into page dom,
* ex :
* let url = window.contextPsAccounts.adminAjaxLink + '&action=unlinkShop'
*
* @return string
*
* @throws \PrestaShopException
*/
public function getAdminAjaxUrl()
{
// Tools::getAdminTokenLite('AdminAjaxPsAccounts'));
return $this->link->getAdminLink('AdminAjaxPsAccounts', true, [], ['ajax' => 1]);
}
}

View File

@@ -0,0 +1,168 @@
<?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
*/
namespace PrestaShop\Module\PsAccounts\Service;
use Context;
use PrestaShop\Module\PsAccounts\Api\Client\ServicesBillingClient;
use PrestaShop\Module\PsAccounts\Exception\BillingException;
use PrestaShop\Module\PsAccounts\Repository\ConfigurationRepository;
/**
* Construct the psbilling service.
*/
class PsBillingService
{
// /**
// * @var \Symfony\Component\DependencyInjection\ContainerInterface
// */
// protected $container;
/**
* @var ConfigurationRepository
*/
private $configuration;
/**
* @var ShopTokenService
*/
private $shopTokenService;
/**
* @var ServicesBillingClient
*/
private $servicesBillingClient;
/**
* PsBillingService constructor.
*
* @param ServicesBillingClient $servicesBillingClient
* @param ShopTokenService $shopTokenService
* @param ConfigurationRepository $configuration
*/
public function __construct(
ServicesBillingClient $servicesBillingClient,
ShopTokenService $shopTokenService,
ConfigurationRepository $configuration
) {
$this->servicesBillingClient = $servicesBillingClient;
$this->shopTokenService = $shopTokenService;
$this->configuration = $configuration;
}
// /**
// * Override of native function to always retrieve Symfony container instead of legacy admin container on legacy context.
// *
// * @param string $serviceName
// *
// * @return mixed
// */
// public function get($serviceName)
// {
// if (null === $this->container) {
// $this->container = \PrestaShop\PrestaShop\Adapter\SymfonyContainer::getInstance();
// }
//
// return $this->container->get($serviceName);
// }
/**
* Create a Billing customer if needed, and subscribe to $planName.
* The $module and $planName must exist in PrestaShop Billing.
* The $ip parameter will help PS Billing to preselect a tax rate and a currency
* from the geolocalized IP. This IP should be the browser IP displaying the backoffice.
*
* @param string $module the name of the module
* @param string $planName The label of the existing plan for this module
* @param mixed $shopId an optional shop ID in multishop context. If left false, the current shop will be selected.
* @param mixed $customerIp an optional element to help Billing choosing the currency and tax rate (depending on the IP's country) for later paying plan
*
* @return mixed An array with subscription identifiers if succeed
*
* @throws \Exception in case of error
*/
public function subscribeToFreePlan($module, $planName, $shopId = false, $customerIp = null)
{
if ($shopId !== false) {
$this->configuration->setShopId($shopId);
}
$uuid = $this->configuration->getShopUuid();
$toReturn = ['shopAccountId' => $uuid];
if ($uuid && strlen($uuid) > 0) {
$billingClient = $this->servicesBillingClient;
$response = $billingClient->getBillingCustomer($uuid);
if (!$response || !array_key_exists('httpCode', $response)) {
throw new BillingException('Billing customer request failed.', 50);
}
if ($response['httpCode'] === 404) {
$response = $billingClient->createBillingCustomer(
$uuid,
$customerIp ? ['created_from_ip' => $customerIp] : []
);
if (!$response || !array_key_exists('httpCode', $response) || $response['httpCode'] !== 201) {
throw new BillingException('Billing customer creation failed.', 60);
}
}
$toReturn['customerId'] = $response['body']['customer']['id'];
$response = $billingClient->getBillingSubscriptions($uuid, $module);
if (!$response || !array_key_exists('httpCode', $response) || $response['httpCode'] >= 500) {
throw new BillingException('Billing subscriptions request failed.', 51);
}
if ($response['httpCode'] === 404) {
$response = $billingClient->createBillingSubscriptions($uuid, $module, ['plan_id' => $planName, 'module' => $module]);
if (!$response || !array_key_exists('httpCode', $response) || $response['httpCode'] >= 400) {
if ($response && array_key_exists('body', $response)
&& array_key_exists('message', $response['body'])
&& array_key_exists(0, $response['body']['message'])
) {
throw new BillingException($response['body']['message'][0]);
}
throw new BillingException('Billing subscription creation failed.', 65);
}
$toReturn['subscriptionId'] = $response['body']['subscription']['id'];
return $toReturn;
} else {
// There is existing subscription. Testing if planName matches the right one.
if (array_key_exists('body', $response) && $response['body']
&& array_key_exists('subscription', $response['body'])
&& array_key_exists('plan_id', $response['body']['subscription'])
&& $response['body']['subscription']['plan_id'] === $planName
) {
$toReturn['subscriptionId'] = $response['body']['subscription']['id'];
$this->shopTokenService->getOrRefreshToken();
return $toReturn;
} else {
throw new BillingException('Subscription plan name mismatch.', 20);
}
}
}
throw new \Exception('Shop account unknown.', 10);
}
}

View File

@@ -0,0 +1,155 @@
<?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
*/
namespace PrestaShop\Module\PsAccounts\Service;
use phpseclib\Crypt\RSA;
use PrestaShop\Module\PsAccounts\Exception\SshKeysNotFoundException;
use PrestaShop\Module\PsAccounts\Repository\ConfigurationRepository;
/**
* Manage RSA
*/
class ShopKeysService
{
const SIGNATURE_DATA = 'data';
/**
* @var RSA
*/
private $rsa;
/**
* @var ConfigurationRepository
*/
private $configuration;
public function __construct(ConfigurationRepository $configuration)
{
$this->rsa = new RSA();
$this->rsa->setHash('sha256');
$this->rsa->setSignatureMode(RSA::SIGNATURE_PKCS1);
$this->configuration = $configuration;
}
/**
* @return array
*/
public function createPair()
{
$this->rsa->setPrivateKeyFormat(RSA::PRIVATE_FORMAT_PKCS1);
$this->rsa->setPublicKeyFormat(RSA::PUBLIC_FORMAT_PKCS1);
return $this->rsa->createKey();
}
/**
* @param string $privateKey
* @param string $data
*
* @return string
*/
public function signData($privateKey, $data)
{
$this->rsa->loadKey($privateKey, RSA::PRIVATE_FORMAT_PKCS1);
return base64_encode($this->rsa->sign($data));
}
/**
* @param string $publicKey
* @param string $signature
* @param string $data
*
* @return bool
*/
public function verifySignature($publicKey, $signature, $data)
{
$this->rsa->loadKey($publicKey, RSA::PUBLIC_FORMAT_PKCS1);
return $this->rsa->verify($data, base64_decode($signature));
}
/**
* @param bool $refresh
*
* @return void
*
* @throws SshKeysNotFoundException
*/
public function generateKeys($refresh = true)
{
if ($refresh || false === $this->hasKeys()) {
$key = $this->createPair();
$this->configuration->updateAccountsRsaPrivateKey($key['privatekey']);
$this->configuration->updateAccountsRsaPublicKey($key['publickey']);
$this->configuration->updateAccountsRsaSignData(
$this->signData(
$this->configuration->getAccountsRsaPrivateKey(),
self::SIGNATURE_DATA
)
);
if (false === $this->hasKeys()) {
throw new SshKeysNotFoundException('No RSA keys found for the shop');
}
}
}
/**
* @return void
*
* @throws SshKeysNotFoundException
*/
public function regenerateKeys()
{
$this->generateKeys(true);
}
/**
* @return bool
*/
public function hasKeys()
{
return false === (
empty($this->configuration->getAccountsRsaPublicKey())
|| empty($this->configuration->getAccountsRsaPrivateKey())
|| empty($this->configuration->getAccountsRsaSignData())
);
}
/**
* @return string
*/
public function getPublicKey()
{
return $this->configuration->getAccountsRsaPublicKey();
}
/**
* @return string
*/
public function getSignature()
{
return $this->configuration->getAccountsRsaSignData();
}
}

View File

@@ -0,0 +1,388 @@
<?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
*/
namespace PrestaShop\Module\PsAccounts\Service;
use Module;
use PrestaShop\Module\PsAccounts\Adapter\Link;
use PrestaShop\Module\PsAccounts\Api\Client\ServicesAccountsClient;
use PrestaShop\Module\PsAccounts\Configuration\ConfigOptionsResolver;
use PrestaShop\Module\PsAccounts\Configuration\Configurable;
use PrestaShop\Module\PsAccounts\Exception\HmacException;
use PrestaShop\Module\PsAccounts\Exception\OptionResolutionException;
use PrestaShop\Module\PsAccounts\Exception\QueryParamsException;
use PrestaShop\Module\PsAccounts\Exception\RsaSignedDataNotFoundException;
use PrestaShop\Module\PsAccounts\Exception\SshKeysNotFoundException;
use PrestaShop\Module\PsAccounts\Provider\ShopProvider;
use PrestaShop\Module\PsAccounts\Repository\ConfigurationRepository;
use Ps_accounts;
class ShopLinkAccountService implements Configurable
{
/**
* @var ShopKeysService
*/
private $shopKeysService;
/**
* @var ShopProvider
*/
private $shopProvider;
/**
* @var ShopTokenService
*/
private $shopTokenService;
/**
* @var ConfigurationRepository
*/
private $configuration;
/**
* @var Link
*/
private $link;
/**
* @var string
*/
private $accountsUiUrl;
/**
* ShopLinkAccountService constructor.
*
* @param array $config
* @param ShopProvider $shopProvider
* @param ShopKeysService $shopKeysService
* @param ShopTokenService $shopTokenService
* @param ConfigurationRepository $configuration
* @param Link $link
*
* @throws OptionResolutionException
*/
public function __construct(
array $config,
ShopProvider $shopProvider,
ShopKeysService $shopKeysService,
ShopTokenService $shopTokenService,
ConfigurationRepository $configuration,
Link $link
) {
$this->accountsUiUrl = $this->resolveConfig($config)['accounts_ui_url'];
$this->shopProvider = $shopProvider;
$this->shopKeysService = $shopKeysService;
$this->shopTokenService = $shopTokenService;
$this->configuration = $configuration;
$this->link = $link;
}
/**
* @return ServicesAccountsClient
*/
public function getServicesAccountsClient()
{
/** @var Ps_accounts $module */
$module = Module::getInstanceByName('ps_accounts');
return $module->getService(ServicesAccountsClient::class);
}
/**
* @param array $bodyHttp
* @param string $trigger
*
* @return mixed
*
* @throws \Exception
*/
public function updateShopUrl($bodyHttp, $trigger)
{
if (array_key_exists('shop_id', $bodyHttp)) {
// id for multishop
$this->configuration->setShopId($bodyHttp['shop_id']);
}
$sslEnabled = $this->shopProvider->getShopContext()->sslEnabled();
$protocol = $this->shopProvider->getShopContext()->getProtocol();
$domain = $sslEnabled ? $bodyHttp['domain_ssl'] : $bodyHttp['domain'];
$uuid = $this->configuration->getShopUuid();
$response = false;
$boUrl = $this->replaceScheme(
$this->link->getAdminLink('AdminModules', true),
$protocol . '://' . $domain
);
if ($uuid && strlen($uuid) > 0) {
$response = $this->getServicesAccountsClient()->updateShopUrl(
$uuid,
[
'protocol' => $protocol,
'domain' => $domain,
'boUrl' => $boUrl,
'trigger' => $trigger,
]
);
}
return $response;
}
/**
* @param string $psxName
*
* @return string
*
* @throws \PrestaShopException
*/
public function getLinkAccountUrl($psxName)
{
$callback = $this->replaceScheme(
$this->link->getAdminLink('AdminModules', true) . '&configure=' . $psxName
);
$protocol = $this->shopProvider->getShopContext()->getProtocol();
$currentShop = $this->shopProvider->getCurrentShop($psxName);
$domainName = $this->shopProvider->getShopContext()->sslEnabled() ? $currentShop['domainSsl'] : $currentShop['domain'];
$queryParams = [
'bo' => $callback,
'pubKey' => $this->shopKeysService->getPublicKey(),
'next' => $this->replaceScheme(
$this->link->getAdminLink('AdminConfigureHmacPsAccounts')
),
'name' => $currentShop['name'],
'lang' => $this->shopProvider->getShopContext()->getContext()->language->iso_code,
];
$queryParamsArray = [];
foreach ($queryParams as $key => $value) {
$queryParamsArray[] = $key . '=' . urlencode($value);
}
$strQueryParams = implode('&', $queryParamsArray);
return $this->accountsUiUrl . '/shop/account/link/' . $protocol . '/' . $domainName
. '/' . $protocol . '/' . $domainName . '/' . $psxName . '?' . $strQueryParams;
}
/**
* @param array $queryParams
* @param string $rootDir
*
* @return string
*
* @throws HmacException
* @throws QueryParamsException
* @throws RsaSignedDataNotFoundException
*/
public function getVerifyAccountUrl(array $queryParams, $rootDir)
{
foreach (
[
'hmac' => '/[a-zA-Z0-9]{8,64}/',
'uid' => '/[a-zA-Z0-9]{8,64}/',
'slug' => '/[-_a-zA-Z0-9]{8,255}/',
] as $key => $value
) {
if (!array_key_exists($key, $queryParams)) {
throw new QueryParamsException('Missing query params');
}
if (!preg_match($value, $queryParams[$key])) {
throw new QueryParamsException('Invalid query params');
}
}
$this->writeHmac($queryParams['hmac'], $queryParams['uid'], $rootDir . '/upload/');
if (empty($this->shopKeysService->getSignature())) {
throw new RsaSignedDataNotFoundException('RSA signature not found');
}
$url = $this->accountsUiUrl;
if ('/' === substr($url, -1)) {
$url = substr($url, 0, -1);
}
return $url . '/shop/account/verify/' . $queryParams['uid']
. '?shopKey=' . urlencode($this->shopKeysService->getSignature());
}
/**
* @return array
*
* @throws SshKeysNotFoundException
*/
public function unlinkShop()
{
$response = $this->getServicesAccountsClient()->deleteShop((string) $this->configuration->getShopUuid());
// Réponse: 200: Shop supprimé avec payload contenant un message de confirmation
// Réponse: 404: La shop n'existe pas (not found)
// Réponse: 401: L'utilisateur n'est pas autorisé à supprimer cette shop
if ($response['status'] && 200 === $response['httpCode']
|| 404 === $response['httpCode']) {
$this->resetOnboardingData();
// FIXME regenerate rsa keys
$this->shopKeysService->regenerateKeys();
}
return $response;
}
/**
* Empty onboarding configuration values
*
* @return void
*/
public function resetOnboardingData()
{
$this->configuration->updateAccountsRsaPrivateKey('');
$this->configuration->updateAccountsRsaPublicKey('');
$this->configuration->updateAccountsRsaSignData('');
$this->configuration->updateFirebaseIdAndRefreshTokens('', '');
$this->configuration->updateFirebaseEmail('');
$this->configuration->updateFirebaseEmailIsVerified(false);
$this->configuration->updateShopUuid('');
}
/**
* @param string $psxName
*
* @return void
*
* @throws SshKeysNotFoundException
* @throws \PrestaShopException
*/
public function manageOnboarding($psxName)
{
$this->shopKeysService->generateKeys();
$this->updateOnboardingData($psxName);
}
/**
* Only callable during onboarding
*
* Prepare onboarding data
*
* @param string $psxName
*
* @return void
*
* @throws \PrestaShopException
* @throws \Exception
*/
public function updateOnboardingData($psxName)
{
$email = \Tools::getValue('email');
$emailVerified = \Tools::getValue('emailVerified');
$customToken = \Tools::getValue('adminToken');
if (is_string($customToken)) {
if (false === $this->shopKeysService->hasKeys()) {
throw new \Exception('SSH keys were not found');
}
if (!$this->shopTokenService->exchangeCustomTokenForIdAndRefreshToken($customToken)) {
throw new \Exception('Unable to get Firebase token');
}
if (!empty($email)) {
$this->configuration->updateFirebaseEmail($email);
if (!empty($emailVerified)) {
$this->configuration->updateFirebaseEmailIsVerified('true' === $emailVerified);
}
// FIXME : quick and dirty fix
\Tools::redirectAdmin(
$this->link->getAdminLink('AdminModules', true, [], [
'configure' => $psxName,
])
);
}
}
}
/**
* @return bool
*/
public function isAccountLinked()
{
return $this->shopTokenService->getToken()
&& $this->configuration->getFirebaseEmail();
}
/**
* @param array $config
* @param array $defaults
*
* @return array|mixed
*
* @throws OptionResolutionException
*/
public function resolveConfig(array $config, array $defaults = [])
{
return (new ConfigOptionsResolver([
'accounts_ui_url',
]))->resolve($config, $defaults);
}
/**
* @param string $hmac
* @param string $uid
* @param string $path
*
* @return void
*
* @throws HmacException
*/
private function writeHmac($hmac, $uid, $path)
{
if (!is_dir($path)) {
mkdir($path);
}
if (!is_writable($path)) {
throw new HmacException('Directory isn\'t writable');
}
file_put_contents($path . $uid . '.txt', $hmac);
}
/**
* @param string $url
* @param string $replacement
*
* @return string
*/
private function replaceScheme($url, $replacement = '')
{
return preg_replace('/^https?:\/\/[^\/]+/', $replacement, $url);
}
}

View File

@@ -0,0 +1,150 @@
<?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
*/
namespace PrestaShop\Module\PsAccounts\Service;
use Lcobucci\JWT\Parser;
use PrestaShop\Module\PsAccounts\Api\Client\FirebaseClient;
use PrestaShop\Module\PsAccounts\Repository\ConfigurationRepository;
class ShopTokenService
{
/**
* @var FirebaseClient
*/
private $firebaseClient;
/**
* @var ConfigurationRepository
*/
private $configuration;
/**
* ShopTokenService constructor.
*
* @param FirebaseClient $firebaseClient
* @param ConfigurationRepository $configuration
*/
public function __construct(
FirebaseClient $firebaseClient,
ConfigurationRepository $configuration
) {
$this->firebaseClient = $firebaseClient;
$this->configuration = $configuration;
}
/**
* @see https://firebase.google.com/docs/reference/rest/auth Firebase documentation
*
* @param string $customToken
*
* @return bool
*/
public function exchangeCustomTokenForIdAndRefreshToken($customToken)
{
$response = $this->firebaseClient->signInWithCustomToken($customToken);
if ($response && true === $response['status']) {
$uid = (new Parser())->parse((string) $customToken)->getClaim('uid');
$this->configuration->updateShopUuid($uid);
$this->configuration->updateFirebaseIdAndRefreshTokens(
$response['body']['idToken'],
$response['body']['refreshToken']
);
return true;
}
return false;
}
/**
* @return bool
*
* @throws \Exception
*/
public function refreshToken()
{
$response = $this->firebaseClient->exchangeRefreshTokenForIdToken(
$this->configuration->getFirebaseRefreshToken()
);
if ($response && true === $response['status']) {
$this->configuration->updateFirebaseIdAndRefreshTokens(
$response['body']['id_token'],
$response['body']['refresh_token']
);
return true;
}
return false;
}
/**
* Get the user firebase token.
*
* @return string
*
* @throws \Exception
*/
public function getOrRefreshToken()
{
if (
$this->configuration->hasFirebaseRefreshToken()
&& $this->isTokenExpired()
) {
$this->refreshToken();
}
return $this->configuration->getFirebaseIdToken();
}
/**
* @return string|null
*/
public function getRefreshToken()
{
return $this->configuration->getFirebaseRefreshToken() ?: null;
}
/**
* @return string|null
*/
public function getToken()
{
return $this->configuration->getFirebaseIdToken() ?: null;
}
/**
* @return bool
*
* @throws \Exception
*/
public function isTokenExpired()
{
// iat, exp
$token = (new Parser())->parse($this->configuration->getFirebaseIdToken());
return $token->isExpired(new \DateTime());
}
}

View File

@@ -0,0 +1,91 @@
<?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
*/
namespace PrestaShop\Module\PsAccounts\Service;
use Context;
use PrestaShop\Module\PsAccounts\Configuration\ConfigOptionsResolver;
use PrestaShop\Module\PsAccounts\Configuration\Configurable;
use PrestaShop\Module\PsAccounts\Exception\OptionResolutionException;
/**
* Class PsAccountsService
*/
class SsoService implements Configurable
{
/**
* @var string
*/
protected $ssoAccountUrl;
/**
* @var string
*/
protected $ssoResendVerificationEmailUrl;
/**
* PsAccountsService constructor.
*
* @param array $config
*
* @throws OptionResolutionException
*/
public function __construct(array $config)
{
$config = $this->resolveConfig($config);
$this->ssoAccountUrl = $config['sso_account_url'];
$this->ssoResendVerificationEmailUrl = $config['sso_resend_verification_email_url'];
}
/**
* @return string
*/
public function getSsoAccountUrl()
{
$url = $this->ssoAccountUrl;
$langIsoCode = Context::getContext()->language->iso_code;
return $url . '?lang=' . substr($langIsoCode, 0, 2);
}
/**
* @return string
*/
public function getSsoResendVerificationEmailUrl()
{
return $this->ssoResendVerificationEmailUrl;
}
/**
* @param array $config
* @param array $defaults
*
* @return array|mixed
*
* @throws OptionResolutionException
*/
public function resolveConfig(array $config, array $defaults = [])
{
return (new ConfigOptionsResolver([
'sso_account_url',
'sso_resend_verification_email_url',
]))->resolve($config, $defaults);
}
}

View File

@@ -0,0 +1,28 @@
<?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
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,71 @@
<?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
*/
namespace PrestaShop\Module\PsAccounts\Translations;
use Context;
use Ps_accounts;
class SettingsTranslations
{
/**
* @var Ps_accounts
*/
private $module;
/**
* __construct
*
* @param Ps_accounts $module
*/
public function __construct(Ps_accounts $module)
{
$this->module = $module;
}
/**
* Create all translations for Settings App
*
* @return array translation list
*/
public function getTranslations()
{
$locale = Context::getContext()->language->iso_code;
$class = 'SettingsTranslations';
$translations[$locale] = [
'general' => [
'settings' => $this->module->l('settings.settings', $class),
'help' => $this->module->l('settings.help', $class),
],
'configure' => [
'incentivePanel' => [
'title' => $this->module->l('settings.title', $class),
'howTo' => $this->module->l('settings.sub_title', $class),
'createPsAccount' => $this->module->l('settings.step_1', $class),
'linkPsAccount' => $this->module->l('settings.step_2', $class),
],
],
];
return $translations;
}
}

View File

@@ -0,0 +1,28 @@
<?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
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,219 @@
<?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
*/
namespace PrestaShop\Module\PsAccounts\WebHook;
use Context;
use PrestaShop\Module\PsAccounts\Api\Client\ServicesAccountsClient;
use PrestaShop\Module\PsAccounts\Exception\WebhookException;
use PrestaShop\Module\PsAccounts\Repository\ConfigurationRepository;
class Validator
{
const HEADER_DATA_ERROR = 'CorrelationId in headers can\'t be empty';
const BODY_ERROR = 'Body can\'t be empty';
const BODY_SERVICE_ERROR = 'Service can\'t be empty';
const BODY_ACTION_ERROR = 'Action can\'t be empty';
const BODY_DATA_ERROR = 'Data can\'t be empty';
const BODY_DATA_OWNERID_ERROR = 'OwnerId can\'t be empty';
const BODY_DATA_SHOPID_ERROR = 'ShopId can\'t be empty';
const BODY_OTHER_ERROR = 'ShopId can\'t be empty';
/**
* @var int
*/
private $statusCode = 200;
/**
* @var string
*/
private $message = '';
/**
* @var Context
*/
private $context;
/**
* @var ConfigurationRepository
*/
private $configuration;
/**
* @var ServicesAccountsClient
*/
private $accountsClient;
/**
* Validator constructor.
*
* @param ServicesAccountsClient $accountsClient
* @param ConfigurationRepository $configuration
* @param Context $context
*/
public function __construct(
ServicesAccountsClient $accountsClient,
ConfigurationRepository $configuration,
Context $context
) {
$this->accountsClient = $accountsClient;
$this->configuration = $configuration;
$this->context = $context;
}
/**
* Validates the webHook data
*
* @param array $headerValues
* @param array $payload
*
* @return array
*/
public function validateData($headerValues = [], $payload = [])
{
// TODO check empty
return array_merge(
$this->validateHeaderData($headerValues),
$this->validateBodyData($payload)
);
}
/**
* Validates the webHook header data
*
* @param array $headerValues
*
* @return array
*/
public function validateHeaderData(array $headerValues)
{
$errors = [];
if (empty($headerValues['correlationId'])) {
$errors[] = self::HEADER_DATA_ERROR;
}
return $errors;
}
/**
* Validates the webHook body data
*
* @param array $payload
*
* @return array
*/
public function validateBodyData(array $payload)
{
$errors = [];
if (empty($payload)) {
$errors[] = self::BODY_ERROR;
}
if (empty($payload['service'])) {
$errors[] = self::BODY_SERVICE_ERROR;
}
if (empty($payload['action'])) {
$errors[] = self::BODY_ACTION_ERROR;
}
if (empty($payload['data'])) {
$errors[] = self::BODY_DATA_ERROR;
}
if (empty($payload['data']['ownerId'])) {
$errors[] = self::BODY_DATA_OWNERID_ERROR;
}
if (empty($payload['data']['shopId'])) {
$errors[] = self::BODY_DATA_SHOPID_ERROR;
}
return $errors;
}
/**
* Validates the webHook data
*
* @param array $headerValues
* @param array $bodyValues
*
* @return void
*
* @throws WebhookException
* @throws \PrestaShopException
*/
public function validate($headerValues = [], $bodyValues = [])
{
$errors = $this->validateData($headerValues, $bodyValues);
// No verifyWebhook if data validation fails.
$errors = empty($errors) ? $this->verifyWebhook($headerValues, $bodyValues) : $errors;
if (!empty($errors)) {
throw new WebhookException((string) json_encode($errors));
}
}
/**
* Check the IP whitelist and Shop, Merchant and Psx Ids
*
* @param array $shopId
*
* @return bool
*
* @throws \Exception
*/
private function checkExecutionPermissions($shopId)
{
$dbShopId = $this->configuration->getShopUuid();
if ($shopId != $dbShopId) {
$output = [
'status_code' => 500,
'message' => 'ShopId don\'t match. You aren\'t authorized',
];
}
return true;
}
/**
* Check if the Webhook comes from the PSL
*
* @param array $headerValues
* @param array $bodyValues
*
* @return array
*
* @throws \PrestaShopException
*/
private function verifyWebhook(array $headerValues = [], array $bodyValues = [])
{
//$response = (new AccountsClient($this->context->link))->checkWebhookAuthenticity($headerValues, $bodyValues);
$response = $this->accountsClient->verifyWebhook($headerValues, $bodyValues);
if (!$response || 200 > $response['httpCode'] || 299 < $response['httpCode']) {
return [$response['body'] ? $response['body'] : 'Webhook not verified'];
}
return [];
}
}

View File

@@ -0,0 +1,28 @@
<?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
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,28 @@
<?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
*/
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;