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,22 @@
# EditorConfig is awesome: http://EditorConfig.org
# top-most EditorConfig file
root = true
# Unix-style newlines with a newline ending every file
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = space
indent_size = 2
[*.php]
indent_size = 4
[*.md]
trim_trailing_whitespace = false
[Makefile]
indent_style = tabs

View File

@@ -0,0 +1,34 @@
<?php
/**
* 2007-2020 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* 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.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
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,72 @@
name: Accounts Quality Control PHP
on: [pull_request]
jobs:
php-linter:
name: PHP Syntax check 5.6|7.2|7.3
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2.0.0
- name: PHP syntax checker 5.6
uses: prestashop/github-action-php-lint/5.6@master
- name: PHP syntax checker 7.2
uses: prestashop/github-action-php-lint/7.2@master
- name: PHP syntax checker 7.3
uses: prestashop/github-action-php-lint/7.3@master
php-cs-fixer:
name: PHP-CS-FIXER
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2.0.0
- name: Run PHP-CS-Fixer
uses: prestashopcorp/github-action-php-cs-fixer@master
phpstan:
name: PHPSTAN
runs-on: ubuntu-latest
strategy:
matrix:
presta-versions: ['latest', '1.7.0.3', '1.6.1.21','1.6.1.0']
steps:
- name: Checkout
uses: actions/checkout@v2.0.0
- name: Cache vendor folder
uses: actions/cache@v1
with:
path: vendor
key: php-${{ hashFiles('composer.lock') }}
- name: Cache composer folder
uses: actions/cache@v1
with:
path: ~/.composer/cache
key: php-composer-cache
- name: git clone ps_accounts
run: |
git clone https://${{ secrets.ACCESS_TOKEN }}@github.com/PrestaShopCorp/ps_accounts.git ~/ps_accounts
cd ~/ps_accounts
- name: composer install
run: composer install && cd ~/ps_accounts && composer install
- name: Pull PrestaShop files (Tag ${{ matrix.presta-versions }})
run: docker run -tid --rm -v ps-volume:/var/www/html --name temp-ps prestashop/prestashop:${{ matrix.presta-versions }}
- name: Select .neon file to run with PHPStan
id: neon
run: |
PS_VERSION=$(docker exec temp-ps bash -c 'echo "$PS_VERSION"')
[[ "${PS_VERSION:0:3}" != '1.7' ]] && echo ::set-output name=filename::phpstan-PS-1.6.neon || echo ::set-output name=filename::phpstan-PS-1.7.neon
- name : Run PHPStan
run: docker run --rm --volumes-from temp-ps -v $PWD:/web/module -v ~/ps_accounts:/web/ps_accounts -e _PS_ROOT_DIR_=/var/www/html --workdir=/web/module phpstan/phpstan:0.12 analyse --configuration=/web/module/tests/phpstan/${{steps.neon.outputs.filename}}
phpunit:
name: PHPUNIT
runs-on: ubuntu-latest
steps:
- name: checkout project
uses: actions/checkout@v1
- name: composer install missing files
run: composer install
- name: PHPUnit tests
uses: php-actions/phpunit@v5
with:
config: ./phpunit.xml
bootstrap: ./tests/bootstrap.php

View File

@@ -0,0 +1,34 @@
<?php
/**
* 2007-2020 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* 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.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
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,6 @@
.idea/
.php_cs.cache
.env
composer-dev.json
composer-dev.lock
vendor

View File

@@ -0,0 +1,11 @@
<?php
$config = new PrestaShop\CodingStandards\CsFixer\Config();
$config
->setUsingCache(false)
->getFinder()
->in(__DIR__)
->exclude('vendor');
return $config;

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 PrestaShopCorp
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,153 @@
# prestashop_accounts_auth
## Community Service & PrestaShop X modules
To work as a Community Service or as PrestaShop X, a module needs three parts:
### [module ps_accounts](http://github.com/PrestaShopCorp/ps_accounts)
* Contains all the controllers
### [library npm](http://github.com/PrestaShopCorp/prestashop_accounts_vue_components)
* Contains all the vuejs components to manage onboarding
### [library composer](http://github.com/PrestaShopCorp/prestashop_accounts_auth)
* Wraps all the calls to ps_accounts
* Contains all the Firebase logic
## Installation
```bash
composer require prestashop/prestashop-accounts-auth
```
## Usage
Each PrestaShop X modules require that the module ps_accounts is installed in order to precess to the onboarding.
PrestaShop X modules need to install ps_accounts in their install() method. In order to simplify that, we have created a method that handle it for you:
```php
(new PrestaShop\AccountsAuth\Installer\Install())->installPsAccounts()
```
eg: You need to call the method above in the install() method in the main class of your module:
```php
/**
* Function executed at the install of the module
*
* @return bool
*/
public function install()
{
return (new PrestaShop\AccountsAuth\Installer\Install())->installPsAccounts() &&
parent::install();
}
```
In your PrestaShop X or Community Service module:
- In the module's controllers and/or main class, get onboarding presenter and go to the view used by the
[viewsjs component](https://github.com/PrestaShopCorp/prestashop_accounts_vue_components)
```php
$psAccountPresenter = new PrestaShop\AccountsAuth\Presenter\PsAccountsPresenter($this->name);
Media::addJsDef([
'contextPsAccounts' => $psAccountPresenter->present(),
]);
```
The $psAccountPresenter format is:
```php
[
'psIs17' => bool,
'psAccountsInstallLink' => null|string,
'psAccountsEnableLink' => null|string,
'onboardingLink' => string,
'user' => [
'email' => null|string,
'emailIsValidated' => bool,
'isSuperAdmin' => bool,
],
'currentShop' => [
'id' => string,
'name' => string,
'domain' => string,
'domainSsl' => string,
'url' => string,
],
'shops' => [],
'firebaseRefreshToken' => null|string,
'superAdminEmail' => string,
'ssoResendVerificationEmail' => string,
];
```
## Billing
This library also provides PrestaShop Billing features and helpers to let
your module call PrestaShop Billing API.
*N.B.: To be able to call Billing API, you need to onboard the shop first*
### Subscribe to a free plan after onboarding
After a successful onboarding, you should probably register your merchant to
a base Billing plan (if you have multiple levels of services, the base one is
probably free). Let it go:
```php
$billingService = new \PrestaShop\AccountsAuth\Service\PsBillingService();
$shopId = false; // Set this ID to the current shop in multishop context. False otherwise.
$ip = null; // Set this to the browser IP (the call is made from the backoffice by the merchant).
$result = $billingService->subscribeToFreePlan('<your_module>', '<your_basic_plan>', $shopId, $ip);
```
The `result` will present these IDs:
```php
[
'shopAccountId' => '<The PS Accounts shop ID, set after onboarding>',
'customerId' => '<The PS Billing customer ID, linked to shop account>',
'subscriptionId' => '<The subscription ID of the given plan>'
]
```
Or an `\Exception` will be thrown in case of error:
* Code `10`: 'Shop account unknown.'. The shop is not fully onboarded into PS Account process.
* Code `20`: 'Subscription plan name mismatch.'. The given plan does not match an available one.
* Code `50`: 'Billing customer request failed.'. The API call cannot be done.
* Code `51`: 'Billing subscriptions request failed.'. The API call cannot be done.
* Code `60`: 'Billing customer creation failed.'. The Billing customer cannot be created.
* Code `65`: 'Billing subscription creation failed.'. The Billing subscription cannot be created.
## Testing
Run php-cs-fixer
```bash
php vendor/bin/php-cs-fixer fix
```
Run phpstan for prestashop 1.6.1.0
```bash
git@github.com:PrestaShopCorp/prestashop_accounts_auth.git path/to/clone
docker run -tid --rm -v ps-volume:/var/www/html --name temp-ps prestashop/prestashop:1.6.1.0;
docker run --rm --volumes-from temp-ps -v $PWD:/web/module -v path/to/clone:/web/ps_accounts -e _PS_ROOT_DIR_=/var/www/html --workdir=/web/module phpstan/phpstan:0.12 analyse --configuration=/web/module/tests/phpstan/phpstan-PS-1.6.neon
```
Run phpstan for prestashop 1.7.0.3
```bash
git@github.com:PrestaShopCorp/prestashop_accounts_auth.git path/to/clone
docker run -tid --rm -v ps-volume:/var/www/html --name temp-ps prestashop/prestashop:1.7.0.3;
docker run --rm --volumes-from temp-ps -v $PWD:/web/module -v path/to/clone:/web/ps_accounts -e _PS_ROOT_DIR_=/var/www/html --workdir=/web/module phpstan/phpstan:0.12 analyse --configuration=/web/module/tests/phpstan/phpstan-PS-1.7.neon
```

View File

@@ -0,0 +1,30 @@
{
"name": "prestashop/prestashop-accounts-auth",
"description": "PrestaShop Accounts composer library",
"license": "MIT",
"autoload": {
"psr-4": {
"PrestaShop\\AccountsAuth\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"PrestaShop\\AccountsAuth\\Tests\\": "tests/"
}
},
"require": {
"php": ">=5.6",
"symfony/dotenv": "^3.4",
"phpseclib/phpseclib": "^2.0",
"ext-json": "*",
"guzzlehttp/guzzle": "~5.0",
"lcobucci/jwt": "^3.3",
"sentry/sentry": "^1.0"
},
"require-dev": {
"phpunit/phpunit": "^5.7",
"prestashop/php-dev-tools": "3.*",
"friendsofphp/php-cs-fixer": "^2.16",
"fzaninotto/faker": "^1.9"
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,34 @@
<?php
/**
* 2007-2020 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* 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.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
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,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="./tests/bootstrap.php" colors="true" stopOnFailure="false">
<testsuites>
<testsuite name="Ps account Tests">
<directory suffix="Test.php">./tests</directory>
</testsuite>
</testsuites>
</phpunit>

View File

@@ -0,0 +1,184 @@
<?php
/**
* 2007-2020 PrestaShop and Contributors.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* 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 <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\AccountsAuth\Adapter;
use PrestaShop\AccountsAuth\Context\ShopContext;
use PrestaShop\AccountsAuth\DependencyInjection\PsAccountsServiceProvider;
use PrestaShop\AccountsAuth\Exception\ServiceNotFoundException;
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;
/**
* @var ShopContext
*/
private $context;
/**
* Configuration constructor.
*
* @throws ServiceNotFoundException
*/
public function __construct()
{
$this->context = PsAccountsServiceProvider::getInstance()->get(ShopContext::class);
}
/**
* @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,68 @@
<?php
/**
* 2007-2020 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* 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 <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\AccountsAuth\Adapter;
use PrestaShop\AccountsAuth\Context\ShopContext;
/**
* Link adapter
*/
class LinkAdapter
{
/**
* Link object
*
* @var \Link
*/
private $link;
public function __construct(\Link $link = null)
{
if (null === $link) {
$link = new \Link();
}
$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
*/
public function getAdminLink($controller, $withToken = true, $sfRouteParams = [], $params = [])
{
if ((new 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;
}
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* 2007-2020 PrestaShop and Contributors.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* 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 <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
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,95 @@
<?php
/**
* 2007-2020 PrestaShop and Contributors.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* 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 <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\AccountsAuth\Api\Client;
use GuzzleHttp\Client;
/**
* Handle firebase signIn/signUp.
*/
class FirebaseClient extends GenericClient
{
/**
* Firebase api key.
*
* @var string
*/
protected $apiKey;
public function __construct()
{
parent::__construct();
$client = new Client([
'defaults' => [
'timeout' => $this->timeout,
'exceptions' => $this->catchExceptions,
'allow_redirects' => false,
'query' => [
//'key' => $_ENV['FIREBASE_API_KEY'],
'key' => getenv('FIREBASE_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,
],
]);
}
}

View File

@@ -0,0 +1,293 @@
<?php
/**
* 2007-2020 PrestaShop and Contributors.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* 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 <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\AccountsAuth\Api\Client;
use GuzzleHttp\Client;
use PrestaShop\AccountsAuth\DependencyInjection\PsAccountsServiceProvider;
use PrestaShop\AccountsAuth\Environment\Env;
use PrestaShop\AccountsAuth\Exception\ServiceNotFoundException;
use PrestaShop\AccountsAuth\Handler\Response\ResponseApiHandler;
/**
* Construct the client used to make call to maasland.
*/
abstract class GenericClient
{
/**
* 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.
*
* @throws ServiceNotFoundException
*/
public function __construct()
{
// FIXME : should not be called here
PsAccountsServiceProvider::getInstance()->get(Env::class);
}
/**
* 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 ResponseApiHandler();
$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 ResponseApiHandler();
$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 transitionalDelete(array $options = [])
{
$response = $this->getClient()->delete($this->getRoute(), $options);
$responseHandler = new ResponseApiHandler();
$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 ResponseApiHandler();
$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,97 @@
<?php
/**
* 2007-2020 PrestaShop and Contributors.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* 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 <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\AccountsAuth\Api\Client;
use GuzzleHttp\Client;
use PrestaShop\AccountsAuth\Service\PsAccountsService;
/**
* Handle call api Services
*/
class ServicesAccountsClient extends GenericClient
{
/**
* ServicesAccountsClient constructor.
*
* @param \Link $link
* @param Client|null $client
*
* @throws \ReflectionException
* @throws \Exception
*/
public function __construct(\Link $link, Client $client = null)
{
parent::__construct();
$psAccountsService = new PsAccountsService();
$shopId = $psAccountsService->getCurrentShop()['id'];
$token = $psAccountsService->getOrRefreshToken();
$this->setLink($link);
// Client can be provided for tests
if (null === $client) {
$client = new Client([
'base_url' => $_ENV['ACCOUNTS_SVC_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 changeUrl($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->transitionalDelete();
}
}

View File

@@ -0,0 +1,126 @@
<?php
/**
* 2007-2020 PrestaShop and Contributors.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* 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 <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\AccountsAuth\Api\Client;
use GuzzleHttp\Client;
use PrestaShop\AccountsAuth\Service\PsAccountsService;
/**
* Handle call api Services
*/
class ServicesBillingClient extends GenericClient
{
/**
* ServicesBillingClient constructor.
*
* @param \Link $link
* @param Client|null $client
*
* @throws \ReflectionException
* @throws \Exception
*/
public function __construct(\Link $link, Client $client = null)
{
parent::__construct();
$psAccountsService = new PsAccountsService();
$shopId = $psAccountsService->getCurrentShop()['id'];
$token = $psAccountsService->getOrRefreshToken();
$this->setLink($link);
// Client can be provided for tests
if (null === $client) {
$client = new Client([
'base_url' => $_ENV['BILLING_SVC_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);
$this->setRoute('/shops');
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=' . $module);
return $this->get();
}
/**
* @param mixed $shopUuidV4
* @param array $bodyHttp
*
* @return array | false
*/
public function createBillingSubscriptions($shopUuidV4, $bodyHttp)
{
$this->setRoute('/shops/' . $shopUuidV4 . '/subscriptions');
return $this->post([
'body' => $bodyHttp,
]);
}
}

View File

@@ -0,0 +1,34 @@
<?php
/**
* 2007-2020 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* 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.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
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
/**
* 2007-2020 PrestaShop and Contributors.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* 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 <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
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,35 @@
<?php
/**
* 2007-2020 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* 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 <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\AccountsAuth\Context;
/**
* Get the shop context
*/
class ShopContext
{
/**
* @return bool
*/
public function isShop17()
{
return version_compare(_PS_VERSION_, '1.7.0.0', '>=');
}
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* 2007-2020 PrestaShop and Contributors.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* 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 <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
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,56 @@
<?php
namespace PrestaShop\AccountsAuth\DependencyInjection;
use Context;
use Module;
use PrestaShop\AccountsAuth\Adapter\Configuration;
use PrestaShop\AccountsAuth\Adapter\LinkAdapter;
use PrestaShop\AccountsAuth\Api\Client\FirebaseClient;
use PrestaShop\AccountsAuth\Context\ShopContext;
use PrestaShop\AccountsAuth\Environment\Env;
use PrestaShop\AccountsAuth\Repository\ConfigurationRepository;
class PsAccountsServiceProvider extends ServiceProvider
{
/**
* {@inheritdoc}
*/
public function register()
{
$this->singleton(Env::class, static function () {
return new Env();
});
$this->singleton(FirebaseClient::class, static function () {
return new FirebaseClient();
});
$this->singleton(Module::class, static function () {
return Module::getInstanceByName('ps_accounts');
});
$this->singleton(Context::class, static function () {
return Context::getContext();
});
$this->singleton(ShopContext::class, static function () {
return new ShopContext();
});
$this->singleton(LinkAdapter::class, function () {
return new LinkAdapter($this->get(Context::class)->link);
});
$this->singleton(Configuration::class, function () {
$configuration = new Configuration();
$configuration->setIdShop((int) $this->get(Context::class)->shop->id);
return $configuration;
});
$this->singleton(ConfigurationRepository::class, function () {
return new ConfigurationRepository($this->get(Configuration::class));
});
}
}

View File

@@ -0,0 +1,123 @@
<?php
namespace PrestaShop\AccountsAuth\DependencyInjection;
use PrestaShop\AccountsAuth\Exception\ServiceNotFoundException;
abstract class ServiceProvider
{
/**
* @var array kinda service container
*/
protected $container = [];
/**
* @var static
*/
protected static $instance;
final public function __construct()
{
$this->register();
}
/**
* @return void
*/
abstract public function register();
/**
* @return static
*/
public static function getInstance()
{
if (self::$instance === null) {
self::$instance = new static();
}
return self::$instance;
}
/**
* @param string $class
*
* @return mixed
*
* @throws ServiceNotFoundException
*/
public function get($class)
{
if (false === array_key_exists($class, $this->container)) {
$msg = 'Dependency not found : ' . $class;
error_log($msg);
throw new ServiceNotFoundException($msg);
}
$dependency = $this->container[$class];
if (is_callable($dependency)) {
$this->container[$class] = $dependency();
}
return $this->container[$class];
}
/**
* @param mixed $class
* @param mixed $instance
*
* @return void
*/
public function singleton($class, $instance = null)
{
if (func_num_args() == 1) {
$instance = $class;
$class = get_class($instance);
}
$this->container[$class] = $instance;
}
/**
* Empties dependency cache
*
* @return void
*/
public function reset()
{
$this->container = [];
$this->register();
}
/**
* Utility method to build dependencies for a given method
*
* @param mixed $method
* @param array $params
*
* @return array
*
* @throws \ReflectionException
* @throws \Exception
*/
public function buildMethodDependencies($method, array $params = [])
{
$reflectionMethod = $method;
if (!$method instanceof \ReflectionMethod) {
$reflectionMethod = new \ReflectionMethod(get_class($method), '__construct');
}
$dependencies = [];
foreach ($reflectionMethod->getParameters() as $index => $reflectionParameter) {
$param = $reflectionParameter->getName();
if (!isset($params[$index]) || $params[$index] == null) {
$dependencies[$param] = $this->get($reflectionParameter->getClass()->getName());
} else {
$dependencies[$param] = $params[$index];
}
}
return $dependencies;
}
}

View File

@@ -0,0 +1,34 @@
<?php
/**
* 2007-2020 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* 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.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
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,110 @@
<?php
/**
* 2007-2020 PrestaShop and Contributors.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* 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 <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\AccountsAuth\Environment;
use PrestaShop\AccountsAuth\Exception\EnvironmentFileException;
use Symfony\Component\Dotenv\Dotenv;
/**
* Load environment variables.
*/
class Env
{
/**
* Firebase public api key.
*
* @var string
*/
private $firebaseApiKey;
/**
* @var Env
*/
private static $instance;
/**
* Env constructor.
*
* @throws EnvironmentFileException
*/
public function __construct()
{
$dotenv = new Dotenv();
// load prestashop var env
if (file_exists(_PS_ROOT_DIR_ . '.env')) {
$dotenv->load(_PS_ROOT_DIR_ . '.env');
}
// load module var env
if (file_exists(_PS_MODULE_DIR_ . 'ps_accounts/.env')) {
$dotenv->load(_PS_MODULE_DIR_ . 'ps_accounts/.env');
}
// load lib var env
elseif (file_exists(dirname(__FILE__) . '/.env')) {
$dotenv->load(dirname(__FILE__) . '/.env');
} else {
$dotenv->load(dirname(__FILE__) . '/env');
}
$this->setFirebaseApiKey(getenv('FIREBASE_API_KEY') ?: null);
}
/**
* getter for firebaseApiKey.
*
* @return string
*/
public function getFirebaseApiKey()
{
return $this->firebaseApiKey;
}
/**
* setter for firebaseApiKey.
*
* @param string $apiKey
*
* @return void
*/
private function setFirebaseApiKey($apiKey)
{
$this->firebaseApiKey = $apiKey;
}
/**
* @return Env
*
* @throws EnvironmentFileException
*/
public static function getInstance()
{
if (self::$instance === null) {
self::$instance = new Env();
}
return self::$instance;
}
/**
* @return void
*/
private function __clone()
{
}
}

View File

@@ -0,0 +1,14 @@
FIREBASE_API_KEY=AIzaSyBEm26bA2KR893rY68enLdVGpqnkoW2Juo
ACCOUNTS_SVC_UI_URL=https://accounts.psessentials.net
ACCOUNTS_SVC_API_URL=https://accounts-api.psessentials.net
BILLING_SVC_API_URL=https://billing-api.psessentials.net
SSO_RESEND_VERIFICATION_EMAIL=https://auth.prestashop.com/account/send-verification-email
SSO_MANAGE_ACCOUNT=https://auth.prestashop.com/login
SENTRY_CREDENTIALS=https://4c7f6c8dd5aa405b8401a35f5cf26ada@o298402.ingest.sentry.io/5354585
EVENT_BUS_PROXY_API_URL="https://eventbus-proxy.psessentials.net"
EVENT_BUS_SYNC_API_URL="https://eventbus-sync.psessentials.net"

View File

@@ -0,0 +1,28 @@
<?php
/**
* 2007-2020 PrestaShop and Contributors.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* 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 <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
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
/**
* 2007-2020 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* 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 <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\AccountsAuth\Exception;
class BillingException extends \Exception
{
}

View File

@@ -0,0 +1,25 @@
<?php
/**
* 2007-2020 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* 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 <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\AccountsAuth\Exception;
class EnvVarException extends \Exception
{
}

View File

@@ -0,0 +1,25 @@
<?php
/**
* 2007-2020 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* 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 <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\AccountsAuth\Exception;
class EnvironmentFileException extends \Exception
{
}

View File

@@ -0,0 +1,25 @@
<?php
/**
* 2007-2020 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* 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 <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\AccountsAuth\Exception;
class ServiceNotFoundException extends \Exception
{
}

View File

@@ -0,0 +1,25 @@
<?php
/**
* 2007-2020 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* 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 <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\AccountsAuth\Exception;
class SshKeysNotFoundException extends \Exception
{
}

View File

@@ -0,0 +1,34 @@
<?php
/**
* 2007-2020 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* 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.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
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,118 @@
<?php
/**
* 2007-2020 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* 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.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\AccountsAuth\Handler\ErrorHandler;
use PrestaShop\AccountsAuth\Adapter\Configuration;
use PrestaShop\AccountsAuth\Service\PsAccountsService;
use Raven_Client;
/**
* Handle Error.
*/
class ErrorHandler
{
/**
* @var PsAccountsService
*/
private $psAccountsService;
/**
* @var Raven_Client
*/
protected $client;
/**
* @var ErrorHandler
*/
private static $instance;
private function __construct()
{
$this->psAccountsService = new PsAccountsService();
$this->client = new Raven_Client(
$_ENV['SENTRY_CREDENTIALS'],
[
'level' => 'warning',
'tags' => [
'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->psAccountsService->getEmail(),
Configuration::PS_ACCOUNTS_FIREBASE_ID_TOKEN => $this->psAccountsService->getFirebaseIdToken(),
Configuration::PS_ACCOUNTS_FIREBASE_REFRESH_TOKEN => $this->psAccountsService->getFirebaseRefreshToken(),
Configuration::PSX_UUID_V4 => $this->psAccountsService->getShopUuidV4(),
Configuration::PS_ACCOUNTS_FIREBASE_EMAIL_IS_VERIFIED => $this->psAccountsService->isEmailValidated(),
Configuration::PS_ACCOUNTS_FIREBASE_EMAIL => $this->psAccountsService->getEmail(),
Configuration::PS_ACCOUNTS_RSA_PUBLIC_KEY => $this->psAccountsService->getAccountsRsaPublicKey(),
Configuration::PS_ACCOUNTS_RSA_SIGN_DATA => $this->psAccountsService->getAccountsRsaSignData(),
],
]
);
$this->client->install();
}
/**
* @param \Exception $error
* @param mixed $code
* @param bool|null $throw
*
* @return void
*
* @throws \Exception
*/
public function handle($error, $code = null, $throw = true)
{
$code ? $this->client->captureException($error) : $this->client->captureMessage($error);
if ($code && true === $throw) {
http_response_code($code);
throw $error;
}
}
/**
* @return ErrorHandler
*/
public static function getInstance()
{
if (self::$instance === null) {
self::$instance = new ErrorHandler();
}
return self::$instance;
}
/**
* @return void
*/
private function __clone()
{
}
}

View File

@@ -0,0 +1,34 @@
<?php
/**
* 2007-2020 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* 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.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
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,70 @@
<?php
/**
* 2007-2020 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* 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.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\AccountsAuth\Handler\Response;
use GuzzleHttp\Message\ResponseInterface;
/**
* Handle api response.
*/
class ResponseApiHandler
{
/**
* 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,34 @@
<?php
/**
* 2007-2020 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* 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.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
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,34 @@
<?php
/**
* 2007-2020 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* 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.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
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
/**
* 2007-2020 PrestaShop and Contributors
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* 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 <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\AccountsAuth\Installer;
use PrestaShop\AccountsAuth\Context\ShopContext;
use PrestaShop\PrestaShop\Core\Addon\Module\ModuleManagerBuilder;
/**
* Install ps_accounts module
*/
class Install
{
/**
* @var string
*/
private $psAccounts = 'ps_accounts';
/**
* Install ps_accounts module if not installed
* Method to call in every psx modules during the installation process
*
* @return bool
*
* @throws \Exception
*/
public function installPsAccounts()
{
if (true === \Module::isInstalled($this->psAccounts)) {
return true;
}
// if on PrestaShop 1.6, do nothing
if (false === (new ShopContext())->isShop17()) {
return true;
}
$moduleManagerBuilder = ModuleManagerBuilder::getInstance();
$moduleManager = $moduleManagerBuilder->build();
$moduleIsInstalled = $moduleManager->install($this->psAccounts);
if (false === $moduleIsInstalled) {
$errorHandler = \PrestaShop\AccountsAuth\Handler\ErrorHandler\ErrorHandler::getInstance();
$errorHandler->handle(new \Exception('Module ps_accounts can\'t be installed', 500), 500);
}
return $moduleIsInstalled;
}
}

View File

@@ -0,0 +1,34 @@
<?php
/**
* 2007-2020 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* 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.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
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,89 @@
<?php
/**
* 2007-2020 PrestaShop and Contributors.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* 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 <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\AccountsAuth\Presenter;
use Module;
use PrestaShop\AccountsAuth\DependencyInjection\PsAccountsServiceProvider;
use PrestaShop\AccountsAuth\Environment\Env;
use PrestaShop\AccountsAuth\Handler\ErrorHandler\ErrorHandler;
use PrestaShop\AccountsAuth\Service\PsAccountsService;
/**
* Construct the psaccounts module.
*/
class PsAccountsPresenter
{
/**
* @var psAccountsService
*/
protected $psAccountsService;
/**
* @param string $psxName
*
* @throws \Exception
*/
public function __construct($psxName)
{
PsAccountsServiceProvider::getInstance()->get(Env::class);
$this->psAccountsService = new PsAccountsService();
$this->psAccountsService->setPsxName($psxName);
$this->psAccountsService->manageOnboarding();
}
/**
* Present the PsAccounts module for vue.
*
* @return array
*
* @throws \Exception
*/
public function present()
{
try {
return [
'psIs17' => $this->psAccountsService->getShopContext()->isShop17(),
'psAccountsInstallLink' => $this->psAccountsService->getPsAccountsInstallLink(),
'psAccountsEnableLink' => $this->psAccountsService->getPsAccountsEnableLink(),
'psAccountsIsInstalled' => Module::isInstalled('ps_accounts'),
'psAccountsIsEnabled' => Module::isEnabled('ps_accounts'),
'onboardingLink' => $this->psAccountsService->getOnboardingLink(),
'user' => [
'email' => $this->psAccountsService->getEmail(),
'emailIsValidated' => $this->psAccountsService->isEmailValidated(),
'isSuperAdmin' => $this->psAccountsService->getContext()->employee->isSuperAdmin(),
],
'currentShop' => $this->psAccountsService->getCurrentShop(),
'isShopContext' => $this->psAccountsService->isShopContext(),
'shops' => $this->psAccountsService->getShopsTree(),
'superAdminEmail' => $this->psAccountsService->getSuperAdminEmail(),
'ssoResendVerificationEmail' => $_ENV['SSO_RESEND_VERIFICATION_EMAIL'],
'manageAccountLink' => $this->psAccountsService->getManageAccountLink(),
'adminAjaxLink' => $this->psAccountsService->getAdminAjaxLink(),
];
} catch (\Exception $e) {
$errorHandler = ErrorHandler::getInstance();
$errorHandler->handle($e, $e->getCode());
}
return [];
}
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* 2007-2020 PrestaShop and Contributors.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* 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 <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
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,271 @@
<?php
/**
* 2007-2020 PrestaShop and Contributors.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* 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 <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\AccountsAuth\Repository;
use PrestaShop\AccountsAuth\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)) {
$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
);
}
/**
* @return string | null
*/
public function getFirebaseLocalId()
{
return $this->configuration->get(Configuration::PS_ACCOUNTS_FIREBASE_LOCAL_ID);
}
/**
* @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 hasAccountsSshKeys()
{
$sshKeys = [
Configuration::PS_ACCOUNTS_RSA_PUBLIC_KEY,
Configuration::PS_ACCOUNTS_RSA_PRIVATE_KEY,
Configuration::PS_ACCOUNTS_RSA_SIGN_DATA,
];
foreach ($sshKeys as $sshKey) {
if (empty($this->configuration->get($sshKey))) {
return false;
}
}
return true;
}
/**
* @return bool
*/
public function sslEnabled()
{
return true == $this->configuration->get('PS_SSL_ENABLED');
}
}

View File

@@ -0,0 +1,34 @@
<?php
/**
* 2007-2020 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* 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.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
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,695 @@
<?php
/**
* 2007-2020 PrestaShop and Contributors.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* 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 <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\AccountsAuth\Service;
use Context;
use Lcobucci\JWT\Parser;
use Module;
use PrestaShop\AccountsAuth\Adapter\LinkAdapter;
use PrestaShop\AccountsAuth\Api\Client\FirebaseClient;
use PrestaShop\AccountsAuth\Api\Client\ServicesAccountsClient;
use PrestaShop\AccountsAuth\Context\ShopContext;
use PrestaShop\AccountsAuth\DependencyInjection\PsAccountsServiceProvider;
use PrestaShop\AccountsAuth\Environment\Env;
use PrestaShop\AccountsAuth\Exception\EnvVarException;
use PrestaShop\AccountsAuth\Exception\ServiceNotFoundException;
use PrestaShop\AccountsAuth\Exception\SshKeysNotFoundException;
use PrestaShop\AccountsAuth\Repository\ConfigurationRepository;
use Tools;
/**
* Construct the psaccounts service.
*/
class PsAccountsService
{
const STR_TO_SIGN = 'data';
/**
* @var Module
*/
public $module;
/**
* @var Context
*/
public $context;
/**
* @var ShopContext
*/
public $shopContext;
/**
* @var string | null
*/
public $psxName = null;
/**
* @var \Symfony\Component\DependencyInjection\ContainerInterface
*/
protected $container;
/**
* @var PsAccountsServiceProvider
*/
protected $psAccountContainer;
/**
* @var LinkAdapter
*/
protected $linkAdapter;
/**
* @var ConfigurationRepository
*/
private $configuration;
/**
* @var FirebaseClient
*/
private $firebaseClient;
/**
* PsAccountsService constructor.
*
* @throws ServiceNotFoundException
*/
public function __construct()
{
$this->psAccountContainer = PsAccountsServiceProvider::getInstance();
$this->psAccountContainer->get(Env::class);
$this->configuration = $this->psAccountContainer->get(ConfigurationRepository::class);
$this->firebaseClient = $this->psAccountContainer->get(FirebaseClient::class);
$this->module = $this->psAccountContainer->get(Module::class);
$this->context = $this->psAccountContainer->get(Context::class);
$this->shopContext = $this->psAccountContainer->get(ShopContext::class);
$this->linkAdapter = $this->psAccountContainer->get(LinkAdapter::class);
}
/**
* @return ShopContext
*/
public function getShopContext()
{
return $this->shopContext;
}
/**
* @return Context
*/
public function getContext()
{
return $this->context;
}
/**
* @param string $psxName
*
* @return void
*/
public function setPsxName($psxName)
{
$this->psxName = $psxName;
}
/**
* @return string | null
*/
public function getPsxName()
{
return $this->psxName;
}
/**
* 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);
}
/**
* @return bool
*/
public function isShopContext()
{
if (\Shop::isFeatureActive() && \Shop::getContext() !== \Shop::CONTEXT_SHOP) {
return false;
}
return true;
}
/**
* @return array
*/
public function getCurrentShop()
{
$shop = \Shop::getShop($this->context->shop->id);
return [
'id' => $shop['id_shop'],
'name' => $shop['name'],
'domain' => $shop['domain'],
'domainSsl' => $shop['domain_ssl'],
'url' => $this->linkAdapter->getAdminLink(
'AdminModules',
true,
[],
[
'configure' => $this->psxName,
'setShopContext' => 's-' . $shop['id_shop'],
]
),
];
}
/**
* @return array
*/
public function getShopsTree()
{
$shopList = [];
if (true === $this->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->linkAdapter->getAdminLink(
'AdminModules',
true,
[],
[
'configure' => $this->psxName,
'setShopContext' => 's-' . $shopId,
]
),
];
}
$shopList[] = [
'id' => $groupId,
'name' => $groupData['name'],
'shops' => $shops,
];
}
return $shopList;
}
/**
* @return string | null
*/
public function getFirebaseRefreshToken()
{
return $this->configuration->getFirebaseRefreshToken() ?: null;
}
/**
* @return string | null
*/
public function getFirebaseIdToken()
{
return $this->configuration->getFirebaseIdToken() ?: null;
}
/**
* @return string
*/
public function getSuperAdminEmail()
{
$employee = new \Employee(1);
return $employee->email;
}
/**
* @return string | null
*/
public function getEmail()
{
return $this->configuration->getFirebaseEmail() ?: null;
}
/**
* @return bool
*/
public function isEmailValidated()
{
return $this->configuration->firebaseEmailIsVerified();
}
/**
* @return bool
*/
public function sslEnabled()
{
return $this->configuration->sslEnabled();
}
/**
* @return string
*/
public function getProtocol()
{
return false == $this->sslEnabled() ? 'http' : 'https';
}
/**
* @return string
*/
public function getDomainName()
{
$currentShop = $this->getCurrentShop();
return false == $this->sslEnabled() ? $currentShop['domain'] : $currentShop['domainSsl'];
}
/**
* @return string | false
*/
public function getShopUuidV4()
{
return $this->configuration->getShopUuid();
}
/**
* @return string | null
*/
public function getPsAccountsInstallLink()
{
if (true === Module::isInstalled('ps_accounts')) {
return null;
}
if ($this->shopContext->isShop17()) {
$router = $this->get('router');
return Tools::getHttpHost(true) . $router->generate('admin_module_manage_action', [
'action' => 'install',
'module_name' => 'ps_accounts',
]);
}
return $this->linkAdapter->getAdminLink('AdminModules', true, [], [
'module_name' => $this->psxName,
'configure' => $this->psxName,
'install' => 'ps_accounts',
]);
}
/**
* @return string | null
*/
public function getPsAccountsEnableLink()
{
if (true === Module::isEnabled('ps_accounts')) {
return null;
}
if ($this->shopContext->isShop17()) {
$router = $this->get('router');
return Tools::getHttpHost(true) . $router->generate('admin_module_manage_action', [
'action' => 'enable',
'module_name' => 'ps_accounts',
]);
}
return $this->linkAdapter->getAdminLink('AdminModules', true, [], [
'module_name' => $this->psxName,
'configure' => $this->psxName,
'enable' => 'ps_accounts',
]);
}
/**
* @return string
*
* @throws \Exception
*/
public function getOnboardingLink()
{
if (false === Module::isInstalled('ps_accounts')) {
return '';
}
$callback = preg_replace(
'/^https?:\/\/[^\/]+/',
'',
$this->linkAdapter->getAdminLink('AdminModules', true) . '&configure=' . $this->psxName
);
$uiSvcBaseUrl = $_ENV['ACCOUNTS_SVC_UI_URL'];
if (false === $uiSvcBaseUrl) {
throw new EnvVarException('Environmenrt variable ACCOUNTS_SVC_UI_URL should not be empty');
}
$protocol = $this->getProtocol();
$domainName = $this->getDomainName();
$currentShop = $this->getCurrentShop();
$queryParams = [
'bo' => $callback,
'pubKey' => $this->configuration->getAccountsRsaPublicKey(),
'next' => preg_replace(
'/^https?:\/\/[^\/]+/',
'',
$this->linkAdapter->getAdminLink('AdminConfigureHmacPsAccounts')
),
'name' => $currentShop['name'],
'lang' => $this->context->language->iso_code,
];
$queryParamsArray = [];
foreach ($queryParams as $key => $value) {
$queryParamsArray[] = $key . '=' . urlencode($value);
}
$strQueryParams = implode('&', $queryParamsArray);
return $uiSvcBaseUrl . '/shop/account/link/' . $protocol . '/' . $domainName
. '/' . $protocol . '/' . $domainName . '/' . $this->psxName . '?' . $strQueryParams;
}
/**
* @param array $bodyHttp
* @param string $trigger
*
* @return mixed
*
* @throws \ReflectionException
*/
public function changeUrl($bodyHttp, $trigger)
{
if (array_key_exists('shop_id', $bodyHttp)) {
// id for multishop
$this->configuration->setShopId($bodyHttp['shop_id']);
}
$sslEnabled = $this->sslEnabled();
$protocol = $this->getProtocol();
$domain = $sslEnabled ? $bodyHttp['domain_ssl'] : $bodyHttp['domain'];
$uuid = $this->getShopUuidV4();
$response = false;
$boUrl = preg_replace(
'/^https?:\/\/[^\/]+/',
$protocol . '://' . $domain,
$this->linkAdapter->getAdminLink('AdminModules', true)
);
if ($uuid && strlen($uuid) > 0) {
$response = (new ServicesAccountsClient($this->getContext()->link))->changeUrl(
$uuid,
[
'protocol' => $protocol,
'domain' => $domain,
'boUrl' => $boUrl,
'trigger' => $trigger,
]
);
}
return $response;
}
/**
* @return array
*
* @throws \ReflectionException
*/
public function unlinkShop()
{
$response = (new ServicesAccountsClient($this->getContext()->link))
->deleteShop((string) $this->getShopUuidV4());
// 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'] && $response['httpCode'] === 200) {
$this->resetOnboardingData();
}
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('');
}
/**
* @return void
*
* @throws \Exception
*/
public function manageOnboarding()
{
$this->generateSshKey();
$this->updateOnboardingData();
}
/**
* @return void
*
* @throws SshKeysNotFoundException
*/
public function generateSshKey()
{
if (false === $this->configuration->hasAccountsSshKeys()) {
$sshKey = new SshKey();
$key = $sshKey->generate();
$this->configuration->updateAccountsRsaPrivateKey($key['privatekey']);
$this->configuration->updateAccountsRsaPublicKey($key['publickey']);
$this->configuration->updateAccountsRsaSignData(
$sshKey->signData(
$this->configuration->getAccountsRsaPrivateKey(),
self::STR_TO_SIGN
)
);
if (empty($this->configuration->getAccountsRsaPrivateKey())) {
throw new SshKeysNotFoundException('SshKeys not found');
}
}
}
/**
* Only callable during onboarding
*
* Prepare onboarding data
*
* @return void
*
* @throws \Exception
*/
public function updateOnboardingData()
{
$email = \Tools::getValue('email');
$emailVerified = \Tools::getValue('emailVerified');
$customToken = \Tools::getValue('adminToken');
if (false === $this->configuration->hasAccountsSshKeys()) {
throw new \Exception('SSH keys were not found');
}
if (!$this->exchangeCustomTokenForIdAndRefreshToken($customToken)) {
return;
}
if (!empty($email)) {
$this->configuration->updateFirebaseEmail($email);
if (!empty($emailVerified)) {
$this->configuration->updateFirebaseEmailIsVerified('true' === $emailVerified);
}
}
}
/**
* 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 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 refreshToken.
*
* @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;
}
/**
* Check the token validity. The token expire time is set to 3600 seconds.
*
* @return bool
*
* @throws \Exception
*/
public function isTokenExpired()
{
/*$refresh_date = $this->configuration->get(Configuration::PS_PSX_FIREBASE_REFRESH_DATE);
if (empty($refresh_date)) {
return true;
}
return strtotime($refresh_date) + 3600 < time();*/
// iat, exp
$token = (new Parser())->parse($this->configuration->getFirebaseIdToken());
return $token->isExpired(new \DateTime());
}
/**
* @return string
*/
public function getManageAccountLink()
{
$url = $_ENV['SSO_MANAGE_ACCOUNT'];
$langIsoCode = $this->context->language->iso_code;
return $url . '?lang=' . substr($langIsoCode, 0, 2);
}
/**
* @return string
*/
public function getAccountsRsaPublicKey()
{
return $this->configuration->getAccountsRsaPublicKey();
}
/**
* @return string
*/
public function getAccountsRsaSignData()
{
return $this->configuration->getAccountsRsaSignData();
}
/**
* Generate ajax admin link with token
* available via PsAccountsPresenter into page dom,
* ex :
* let url = window.contextPsAccounts.adminAjaxLink + '&action=unlinkShop'
*
* @return string
*/
public function getAdminAjaxLink()
{
// Tools::getAdminTokenLite('AdminAjaxPsAccounts'));
return $this->linkAdapter->getAdminLink('AdminAjaxPsAccounts', true, [], ['ajax' => 1]);
}
}

View File

@@ -0,0 +1,189 @@
<?php
/**
* 2007-2020 PrestaShop and Contributors.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* 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 <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\AccountsAuth\Service;
use Context;
use PrestaShop\AccountsAuth\Adapter\LinkAdapter;
use PrestaShop\AccountsAuth\Api\Client\ServicesBillingClient;
use PrestaShop\AccountsAuth\Context\ShopContext;
use PrestaShop\AccountsAuth\DependencyInjection\PsAccountsServiceProvider;
use PrestaShop\AccountsAuth\Environment\Env;
use PrestaShop\AccountsAuth\Exception\BillingException;
use PrestaShop\AccountsAuth\Exception\ServiceNotFoundException;
use PrestaShop\AccountsAuth\Repository\ConfigurationRepository;
/**
* Construct the psbilling service.
*/
class PsBillingService
{
/**
* @var Context
*/
public $context;
/**
* @var ShopContext
*/
public $shopContext;
/**
* @var \Symfony\Component\DependencyInjection\ContainerInterface
*/
protected $container;
/**
* @var LinkAdapter
*/
protected $linkAdapter;
/**
* PsBillingService constructor.
*
* @throws ServiceNotFoundException
*/
public function __construct()
{
PsAccountsServiceProvider::getInstance()->get(Env::class);
$this->context = Context::getContext();
$this->shopContext = new ShopContext();
}
/**
* @return ShopContext
*/
public function getShopContext()
{
return $this->shopContext;
}
/**
* @return Context
*/
public function getContext()
{
return $this->context;
}
/**
* 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)
{
$psAccountsService = new PsAccountsService();
if ($shopId !== false) {
/** @var ConfigurationRepository $configurationRepository */
$configurationRepository = PsAccountsServiceProvider::getInstance()
->get(ConfigurationRepository::class);
$configurationRepository->setShopId($shopId);
}
$uuid = $psAccountsService->getShopUuidV4();
$toReturn = ['shopAccountId' => $uuid];
if ($uuid && strlen($uuid) > 0) {
$billingClient = new ServicesBillingClient($this->getContext()->link);
$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'] !== 200) {
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, ['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'];
$psAccountsService->getOrRefreshToken();
return $toReturn;
} else {
throw new BillingException('Subscription plan name mismatch.', 20);
}
}
}
throw new \Exception('Shop account unknown.', 10);
}
}

View File

@@ -0,0 +1,79 @@
<?php
/**
* 2007-2020 PrestaShop and Contributors.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* 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 <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\AccountsAuth\Service;
use phpseclib\Crypt\RSA;
/**
* Manage RSA
*/
class SshKey
{
/**
* @var \phpseclib\Crypt\RSA
*/
private $rsa;
public function __construct()
{
$this->rsa = new RSA();
$this->rsa->setHash('sha256');
$this->rsa->setSignatureMode(RSA::SIGNATURE_PKCS1);
}
/**
* @return array
*/
public function generate()
{
$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);
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);
return $this->rsa->verify($data, base64_decode($signature));
}
}

View File

@@ -0,0 +1,34 @@
<?php
/**
* 2007-2020 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* 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.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
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,34 @@
<?php
/**
* 2007-2020 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* 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.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
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,16 @@
<?php
class Context
{
public $link;
public function __construct()
{
$this->link = new \Link();
}
public static function getContext()
{
return new self();
}
}

View File

@@ -0,0 +1,5 @@
<?php
class Link
{
}

View File

@@ -0,0 +1,9 @@
<?php
class Module
{
public static function getInstanceByName($name)
{
return new self();
}
}

View File

@@ -0,0 +1,11 @@
<?php
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,83 @@
<?php
namespace PrestaShop\AccountsAuth\Tests;
use PrestaShop\AccountsAuth\Adapter\Configuration;
use PrestaShop\AccountsAuth\DependencyInjection\PsAccountsServiceProvider;
class TestCase extends \PHPUnit\Framework\TestCase
{
/**
* @var \Faker\Generator
*/
public $faker;
/**
* @var PsAccountsServiceProvider
*/
public $container;
/**
* @var array
*/
private $config;
public function __construct($name = null, array $data = [], $dataName = '')
{
parent::__construct($name, $data, $dataName);
}
/**
* @return void
*/
protected function setUp()
{
parent::setUp();
$this->faker = \Faker\Factory::create();
$this->container = PsAccountsServiceProvider::getInstance();
$this->container->reset();
}
/**
* @param array $valueMap
*
* @return \PHPUnit_Framework_MockObject_MockObject
*/
public function getConfigurationMock(array $valueMap)
{
if (!$this->config) {
$this->config = $valueMap;
}
$configuration = $this->createMock(Configuration::class);
$configuration->method('get')
->will($this->returnCallback(function ($key, $default = false) {
foreach ($this->config as $map) {
$return = array_pop($map);
if ([$key, $default] === $map) {
return $return;
}
}
return null;
}));
//->will($this->returnValueMap($valueMap));
$configuration->method('set')
->will($this->returnCallback(function ($key, $values, $html = false) use ($configuration) {
foreach ($this->config as &$row) {
if ($row[0] == $key) {
$row[2] = (string) $values;
return;
}
}
$this->config[] = [$key, false, (string) $values];
}));
return $configuration;
}
}

View File

@@ -0,0 +1,34 @@
<?php
/**
* 2007-2020 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* 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.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
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,55 @@
<?php
namespace PrestaShop\AccountsAuth\Tests\Unit\Repository\ConfigurationRespository;
use PrestaShop\AccountsAuth\Adapter\Configuration;
use PrestaShop\AccountsAuth\Repository\ConfigurationRepository;
use PrestaShop\AccountsAuth\Tests\TestCase;
class setShopIdTest extends TestCase
{
/**
* @test
*/
public function it_should_pass_shop_id_calling_get()
{
$shopId = $this->faker->randomNumber();
$configMock = $this->getMockBuilder(Configuration::class)
->setMethods(['getRaw'])
->getMock();
$configMock->expects($this->once())
->method('getRaw')
->with(Configuration::PS_ACCOUNTS_FIREBASE_EMAIL, null, null, $shopId, false);
$configuration = new ConfigurationRepository($configMock);
$configuration->setShopId($shopId);
$configuration->getFirebaseEmail();
}
/**
* @test
*/
public function it_should_pass_shop_id_calling_update()
{
$shopId = $this->faker->randomNumber();
$email = $this->faker->safeEmail;
$configMock = $this->getMockBuilder(Configuration::class)
->setMethods(['setRaw', 'get'])
->getMock();
$configMock->expects($this->once())
->method('get')
->with(Configuration::PS_PSX_FIREBASE_EMAIL);
$configMock->expects($this->once())
->method('setRaw')
->with(Configuration::PS_ACCOUNTS_FIREBASE_EMAIL, $email, false, null, $shopId);
$configuration = new ConfigurationRepository($configMock);
$configuration->setShopId($shopId);
$configuration->updateFirebaseEmail($email);
}
}

View File

@@ -0,0 +1,34 @@
<?php
/**
* 2007-2020 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* 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.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
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,57 @@
<?php
namespace PrestaShop\AccountsAuth\Tests\Unit\Service\PsAccountsService;
use PrestaShop\AccountsAuth\Adapter\Configuration;
use PrestaShop\AccountsAuth\Exception\ServiceNotFoundException;
use PrestaShop\AccountsAuth\Repository\ConfigurationRepository;
use PrestaShop\AccountsAuth\Service\PsAccountsService;
use PrestaShop\AccountsAuth\Service\SshKey;
use PrestaShop\AccountsAuth\Tests\TestCase;
class GenerateSshKeyTest extends TestCase
{
/**
* @test
*
* @throws \ReflectionException
* @throws ServiceNotFoundException
*/
public function it_should_update_ssh_keys()
{
/** @var Configuration $configMock */
$configMock = $this->getConfigurationMock([
[Configuration::PS_ACCOUNTS_RSA_PRIVATE_KEY, false, null],
[Configuration::PS_ACCOUNTS_RSA_PUBLIC_KEY, false, null],
[Configuration::PS_ACCOUNTS_RSA_SIGN_DATA, false, null],
]);
$this->container->singleton(Configuration::class, $configMock);
$configuration = $this->container->get(ConfigurationRepository::class);
$service = new PsAccountsService();
$this->assertEmpty($configuration->getAccountsRsaPrivateKey());
$this->assertEmpty($configuration->getAccountsRsaPublicKey());
$this->assertEmpty($configuration->getAccountsRsaSignData());
$service->generateSshKey();
$this->assertNotEmpty($configuration->getAccountsRsaPrivateKey());
$this->assertNotEmpty($configuration->getAccountsRsaPublicKey());
$this->assertNotEmpty($configuration->getAccountsRsaSignData());
$sshKey = new SshKey();
$data = $this->faker->sentence();
$signedData = $sshKey->signData($configuration->getAccountsRsaPrivateKey(), $data);
$this->assertTrue(
$sshKey->verifySignature(
$configuration->getAccountsRsaPublicKey(),
$signedData,
$data
)
);
}
}

View File

@@ -0,0 +1,91 @@
<?php
namespace PrestaShop\AccountsAuth\Tests\Unit\Service\PsAccountsService;
use Lcobucci\JWT\Builder;
use PrestaShop\AccountsAuth\Adapter\Configuration;
use PrestaShop\AccountsAuth\Api\Client\FirebaseClient;
use PrestaShop\AccountsAuth\Service\PsAccountsService;
use PrestaShop\AccountsAuth\Tests\TestCase;
class GetOrRefreshTokenTest extends TestCase
{
/**
* @test
*
* @throws \Exception
*/
public function it_should_return_valid_token()
{
//$date = (new \DateTime('tomorrow'));
$date = $this->faker->dateTimeBetween('now', '+2 hours');
$idToken = (new Builder())
->expiresAt($date->getTimestamp())
//->withClaim('uid', $this->faker->uuid)
->getToken();
$refreshToken = (new Builder())->getToken();
/** @var Configuration $configMock */
$configMock = $this->getConfigurationMock([
[Configuration::PS_PSX_FIREBASE_REFRESH_DATE, false, $date->format('Y-m-d h:m:s')],
[Configuration::PS_ACCOUNTS_FIREBASE_REFRESH_TOKEN, false, (string) $refreshToken],
[Configuration::PS_ACCOUNTS_FIREBASE_ID_TOKEN, false, (string) $idToken],
]);
$this->container->singleton(Configuration::class, $configMock);
$service = new PsAccountsService();
$this->assertEquals((string) $idToken, $service->getOrRefreshToken());
}
/**
* @test
*
* @throws \Exception
*/
public function it_should_refresh_expired_token()
{
$date = $this->faker->dateTime('now');
$idToken = (new Builder())
->expiresAt($date->getTimestamp())
//->withClaim('uid', $this->faker->uuid)
->getToken();
$idTokenRefreshed = (new Builder())
->expiresAt($this->faker->dateTimeBetween('+2 hours', '+4 hours')->getTimestamp())
//->withClaim('uid', $this->faker->uuid)
->getToken();
$refreshToken = (new Builder())->getToken();
/** @var FirebaseClient $firebaseClient */
$firebaseClient = $this->createMock(FirebaseClient::class);
$firebaseClient->method('exchangeRefreshTokenForIdToken')
->willReturn([
'status' => true,
'body' => [
'id_token' => $idTokenRefreshed,
'refresh_token' => $refreshToken,
],
]);
/** @var Configuration $configMock */
$configMock = $this->getConfigurationMock([
[Configuration::PS_PSX_FIREBASE_REFRESH_DATE, false, $date->format('Y-m-d h:m:s')],
[Configuration::PS_ACCOUNTS_FIREBASE_REFRESH_TOKEN, false, (string) $refreshToken],
[Configuration::PS_ACCOUNTS_FIREBASE_ID_TOKEN, false, (string) $idToken],
]);
$this->container->singleton(Configuration::class, $configMock);
$this->container->singleton(FirebaseClient::class, $firebaseClient);
$service = new PsAccountsService();
$this->assertEquals((string) $idTokenRefreshed, $service->getOrRefreshToken());
}
}

View File

@@ -0,0 +1,58 @@
<?php
namespace PrestaShop\AccountsAuth\Tests\Unit\Service\PsAccountsService;
use PrestaShop\AccountsAuth\Adapter\Configuration;
use PrestaShop\AccountsAuth\Exception\ServiceNotFoundException;
use PrestaShop\AccountsAuth\Repository\ConfigurationRepository;
use PrestaShop\AccountsAuth\Service\PsAccountsService;
use PrestaShop\AccountsAuth\Tests\TestCase;
class IsEmailValidatedTest extends TestCase
{
/**
* @test
*
* @throws ServiceNotFoundException
* @throws \ReflectionException
*/
public function it_should_return_true()
{
/** @var Configuration $configMock */
$configMock = $this->getConfigurationMock([]);
$this->container->singleton(Configuration::class, $configMock);
$service = new PsAccountsService();
/** @var ConfigurationRepository $configuration */
$configuration = $this->container->get(ConfigurationRepository::class);
$configuration->updateFirebaseEmailIsVerified(1);
$this->assertTrue($service->isEmailValidated());
}
/**
* @test
*
* @throws ServiceNotFoundException
* @throws \ReflectionException
*/
public function it_should_return_false()
{
/** @var Configuration $configMock */
$configMock = $this->getConfigurationMock([]);
$this->container->singleton(Configuration::class, $configMock);
$service = new PsAccountsService();
/** @var ConfigurationRepository $configuration */
$configuration = $this->container->get(ConfigurationRepository::class);
$configuration->updateFirebaseEmailIsVerified(0);
$this->assertFalse($service->isEmailValidated());
}
}

View File

@@ -0,0 +1,75 @@
<?php
namespace PrestaShop\AccountsAuth\Tests\Unit\Service\PsAccountsService;
use Lcobucci\JWT\Builder;
use PrestaShop\AccountsAuth\Adapter\Configuration;
use PrestaShop\AccountsAuth\Service\PsAccountsService;
use PrestaShop\AccountsAuth\Tests\TestCase;
class IsTokenExpiredTest extends TestCase
{
/**
* @test
*
* @throws \Exception
*/
public function it_should_return_true()
{
$date = $this->faker->dateTime('now');
$idToken = (new Builder())
->expiresAt($date->getTimestamp())
//->withClaim('uid', $this->faker->uuid)
->getToken();
$refreshToken = (new Builder())->getToken();
/** @var Configuration $configMock */
$configMock = $this->getConfigurationMock([
[Configuration::PS_PSX_FIREBASE_REFRESH_DATE, false, $date->format('Y-m-d h:m:s')],
[Configuration::PS_ACCOUNTS_FIREBASE_REFRESH_TOKEN, false, (string) $refreshToken],
[Configuration::PS_ACCOUNTS_FIREBASE_ID_TOKEN, false, (string) $idToken],
]);
$this->container->singleton(Configuration::class, $configMock);
$service = new PsAccountsService(
//new ConfigurationRepository($configMock)
);
$this->assertTrue($service->isTokenExpired());
}
/**
* @test
*
* @throws \Exception
*/
public function it_should_return_false()
{
$date = $this->faker->dateTimeBetween('+2 hours', '+4 hours');
$idToken = (new Builder())
->expiresAt($date->getTimestamp())
//->withClaim('uid', $this->faker->uuid)
->getToken();
$refreshToken = (new Builder())->getToken();
/** @var Configuration $configMock */
$configMock = $this->getConfigurationMock([
[Configuration::PS_PSX_FIREBASE_REFRESH_DATE, false, $date->format('Y-m-d h:m:s')],
[Configuration::PS_ACCOUNTS_FIREBASE_REFRESH_TOKEN, false, (string) $refreshToken],
[Configuration::PS_ACCOUNTS_FIREBASE_ID_TOKEN, false, (string) $idToken],
]);
$this->container->singleton(Configuration::class, $configMock);
$service = new PsAccountsService(
//new ConfigurationRepository($configMock)
);
$this->assertFalse($service->isTokenExpired());
}
}

View File

@@ -0,0 +1,131 @@
<?php
/**
* 2007-2020 PrestaShop and Contributors.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* 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 <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\AccountsAuth\Tests\Unit\Service\PsAccountsService;
use Lcobucci\JWT\Builder;
use PrestaShop\AccountsAuth\Adapter\Configuration;
use PrestaShop\AccountsAuth\Api\Client\FirebaseClient;
use PrestaShop\AccountsAuth\Repository\ConfigurationRepository;
use PrestaShop\AccountsAuth\Service\PsAccountsService;
use PrestaShop\AccountsAuth\Tests\TestCase;
class RefreshTokenTest extends TestCase
{
public function __construct()
{
define('_PS_ROOT_DIR_', '');
}
/**
* @test
*
* @throws \Exception
*/
public function it_should_handle_response_success()
{
$idToken = (new Builder())
->expiresAt($this->faker->dateTimeBetween('now', '+2 hours')->getTimestamp())
//->withClaim('uid', $this->faker->uuid)
->getToken();
$idTokenRefreshed = (new Builder())
->expiresAt($this->faker->dateTimeBetween('+2 hours', '+4 hours')->getTimestamp())
//->withClaim('uid', $this->faker->uuid)
->getToken();
$refreshToken = (new Builder())->getToken();
/** @var FirebaseClient $firebaseClient */
$firebaseClient = $this->createMock(FirebaseClient::class);
$firebaseClient->method('exchangeRefreshTokenForIdToken')
->willReturn([
'status' => true,
'body' => [
'id_token' => $idTokenRefreshed,
'refresh_token' => $refreshToken,
],
]);
/** @var Configuration $configMock */
$configMock = $this->getConfigurationMock([
[Configuration::PS_ACCOUNTS_FIREBASE_ID_TOKEN, false, (string) $idToken],
[Configuration::PS_ACCOUNTS_FIREBASE_REFRESH_TOKEN, false, (string) $refreshToken],
]);
$this->container->singleton(Configuration::class, $configMock);
$this->container->singleton(FirebaseClient::class, $firebaseClient);
$configuration = $this->container->get(ConfigurationRepository::class);
$service = new PsAccountsService();
$this->assertTrue($service->refreshToken());
$this->assertEquals((string) $idTokenRefreshed, $configuration->getFirebaseIdToken());
$this->assertEquals((string) $refreshToken, $configuration->getFirebaseRefreshToken());
}
/**
* @test
*
* @throws \Exception
*/
public function it_should_handle_response_error()
{
$idToken = (new Builder())
->expiresAt($this->faker->dateTimeBetween('now', '+2 hours')->getTimestamp())
//->withClaim('uid', $this->faker->uuid)
->getToken();
$refreshToken = (new Builder())->getToken();
/** @var FirebaseClient $firebaseClient */
$firebaseClient = $this->createMock(FirebaseClient::class);
$firebaseClient->method('exchangeRefreshTokenForIdToken')
->willReturn([
'status' => false,
]);
/** @var Configuration $configMock */
$configMock = $this->getConfigurationMock([
[Configuration::PS_ACCOUNTS_FIREBASE_ID_TOKEN, false, (string) $idToken],
[Configuration::PS_ACCOUNTS_FIREBASE_REFRESH_TOKEN, false, (string) $refreshToken],
]);
$configuration = new ConfigurationRepository($configMock);
$this->container->singleton(Configuration::class, $configMock);
$this->container->singleton(FirebaseClient::class, $firebaseClient);
$configuration = $this->container->get(ConfigurationRepository::class);
$service = new PsAccountsService();
$this->assertFalse($service->refreshToken());
$this->assertEquals((string) $idToken, $configuration->getFirebaseIdToken());
$this->assertEquals((string) $refreshToken, $configuration->getFirebaseRefreshToken());
}
}

View File

@@ -0,0 +1,34 @@
<?php
/**
* 2007-2020 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* 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.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
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
/**
* 2007-2020 PrestaShop and Contributors.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-3.0)
* that is bundled with this package in the file LICENSE.txt.
* 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 <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
namespace PrestaShop\AccountsAuth\Tests\Unit\Service;
use PHPUnit\Framework\TestCase;
use PrestaShop\AccountsAuth\Service\SshKey;
class SshKeyTest extends TestCase
{
public function testGenerate()
{
$sshKey = new SshKey();
$key = $sshKey->generate();
$this->assertArrayHasKey('privatekey', $key, "Key 'privatekey' don't exist in Array");
$this->assertArrayHasKey('publickey', $key, "Key 'publickey' don't exist in Array");
$this->assertEquals('string', gettype($key['privatekey']), "'privatekey' isn't string");
$this->assertEquals('string', gettype($key['publickey']), "'privatekey' isn't string");
}
public function testVerifyDecryptRsaKey()
{
$sshKey = new SshKey();
$key = $sshKey->generate();
$privateKey = '-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQCeksA2G79u1InvLc8tKcerLCLa66be0h/CD9RhDnQh5CXQxe5H
URMyTWy6DpyFyddg6cnOh1RavMWUvdvjwtcgxVmmwtBA7kS8sKuxRUBFHjxB7i9N
cLlbhBTQl15zjpHcI7ggBulqTS1b5jwEuZSv8d+NW0pCTZk/4Xm4d2i+9QIDAQAB
AoGAGkMnvk5eKBbfOVOW6l3vCbRnmWZJ3sFiLRu+Cs0AAtTsRmVhj0IoMb6M8UuW
NLo3B3/wwlm7aMO23WmMT25nfm0ozMD5JBhsHhMjNf936+eul+brSL0yw3OBWHrn
rhRAibzy3Oe7lHqhJseGPddb7k3rrYHiCL3XjD4aUnSqxokCQQDQ4jOaP75srmWw
drR4NbJy18+BOQOKLew0mDdMwfeCskWEiFDftRTSlOFtcG4p8MhsT5XKeFGKzrEe
fYPqnuZbAkEAwldsIp+UWOudQb6/sqCLyrPYtH5K1SZs2eqaauuFVz0tTMONznaa
3QESWSqPNjVXmtZQNh64lR9SrGBugB4Q7wJACol+pOdWSdE6W/6A+BdtWxG76/7e
SNgsNDMBhyO5wqQPkbH2snJGDKFqBcVIKWF2GtCg88fCBUiL8sfOIcXGRQJAFpBB
3M88UQqiCnUUGrArKtCws1wKYi8A6lgjr5BCvfs7XDNELpl0p34tXC7ly7xrvG1v
iKkOczncxmi3y6Yx/wJABjuZp1et+/uNQ33vv/NlHRNqfR4B/ZVbn+GvdAiuDEdU
3+trKNmdcTb/7oQ/5RygDWjjXVvaZhheA3LCHFwiSg==
-----END RSA PRIVATE KEY-----';
$publicKey = 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQCeksA2G79u1InvLc8tKcerLCLa66be0h/CD9RhDnQh5CXQxe5HURMyTWy6DpyFyddg6cnOh1RavMWUvdvjwtcgxVmmwtBA7kS8sKuxRUBFHjxB7i9NcLlbhBTQl15zjpHcI7ggBulqTS1b5jwEuZSv8d+NW0pCTZk/4Xm4d2i+9Q== phpseclib-generated-key';
$data = 'hmac';
$signature = $sshKey->signData($privateKey, $data);
$this->assertEquals(1, $sshKey->verifySignature($publicKey, $signature, $data), "Data doesn't signed");
}
}

View File

@@ -0,0 +1,34 @@
<?php
/**
* 2007-2020 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* 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.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
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,34 @@
<?php
/**
* 2007-2020 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* 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.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
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,12 @@
<?php
require_once __DIR__ . '/../vendor/autoload.php';
// Empty shells
require_once __DIR__ . '/Mock/Link.php';
require_once __DIR__ . '/Mock/Context.php';
require_once __DIR__ . '/Mock/Module.php';
if (!defined('_PS_MODULE_DIR_')) {
define('_PS_MODULE_DIR_', '');
}

View File

@@ -0,0 +1,34 @@
<?php
/**
* 2007-2020 PrestaShop.
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* 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.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2020 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
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,11 @@
<?php
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,23 @@
includes:
- %currentWorkingDirectory%/vendor/prestashop/php-dev-tools/phpstan/ps-module-extension.neon
parameters:
autoload_files:
- /web/ps_accounts/vendor/autoload.php
checkMissingIterableValueType: false
reportUnmatchedIgnoredErrors: false
paths:
- ../../src
dynamicConstantNames:
- _PS_VERSION_
ignoreErrors:
- '#Result of \|\| is always false.#'
- '#Strict comparison using === between false and string will always evaluate to false.#'
- '#Access to an undefined property Language::\$locale.#'
- '#Call to static method getInstance\(\) on an unknown class PrestaShop\\PrestaShop\\Adapter\\SymfonyContainer.#'
- '#Call to static method getInstance\(\) on an unknown class PrestaShop\\PrestaShop\\Core\\Addon\\Module\\ModuleManagerBuilder.#'
- '#Call to method get\(\) on an unknown class Symfony\\Component\\DependencyInjection\\ContainerInterface.#'
- '#Property PrestaShop\\AccountsAuth\\Service\\PsAccountsService::\$container has unknown class Symfony\\Component\\DependencyInjection\\ContainerInterface as its type.#'
- '#Property PrestaShop\\AccountsAuth\\Service\\PsBillingService::\$container has unknown class Symfony\\Component\\DependencyInjection\\ContainerInterface as its type.#'
- '#Method LinkCore::getAdminLink\(\) invoked with 4 parameters, 1-2 required.#'
level: 7

View File

@@ -0,0 +1,18 @@
includes:
- %currentWorkingDirectory%/vendor/prestashop/php-dev-tools/phpstan/ps-module-extension.neon
parameters:
autoload_files:
- /web/ps_accounts/vendor/autoload.php
checkMissingIterableValueType: false
reportUnmatchedIgnoredErrors: false
paths:
- ../../src
dynamicConstantNames:
- _PS_VERSION_
ignoreErrors:
- '#Result of \|\| is always false.#'
- '#Strict comparison using === between false and string will always evaluate to false.#'
- '#Call to static method getInstance\(\) on an unknown class PrestaShop\\PrestaShop\\Adapter\\SymfonyContainer.#'
- '#Method LinkCore::getAdminLink\(\) invoked with 4 parameters, 1-2 required.#'
level: 7