<?php
namespace IntegrationBundle\Service\Diia;
use CoreBundle\Entity\Dealer;
use CoreBundle\Model\Eusphpe\Eusphpe;
use GuzzleHttp\Client as HttpClient;
use IntegrationBundle\Exception\HandlerNotFoundException;
use IntegrationBundle\Exception\ResponseErrorException;
use Psr\Log\LoggerInterface;
use Symfony\Component\Yaml\Yaml;
class DiiaService
{
const CACHE_KEY = 'diia_token';
const CACHE_LIFETIME_IN_SECONDS = 7100;
const DIIA_CERT = 'Diia_2022.cer';
/* Токен авторизації "Віді страхування" PV-4222*/
const DEF_AUTH_ACQUIRER_TOKEN = 'YWNxdWlyZXJfNDc5OnZpZGlfdGVzdF90b2tlbl85aWt3NDU=';
use MakesHttpRequests;
/**
* The acquirer token, which you can get from the employee of 'Diia' service.
*
* @var string
*/
protected $acquirerToken;
/**
* The session token, which you can get by authorizing with acquirer token.
*
* @var string|null
*/
protected $sessionToken;
/**
* @var SessionHandlerProvider
*/
private $handlerProvider;
/**
* @var Eusphpe
*/
private $eusphpe;
/**
* @var false|string
*/
private $vidiPrivateKey;
/**
* @var false|string
*/
private $vidiPrivateKeyPassword;
/**
* @var false|string
*/
private $diiaSert;
private ?string $diiaCredentialsPath;
private ?string $vidiPrivateKeyFilePath;
private ?string $vidiDefPrivateKey;
private ?string $diiaSertFilePath;
/**
* @param string $acquirerToken
* @param SessionHandlerProvider $handlerProvider
* @param LoggerInterface $logger
* @param Eusphpe $eusphpe
* @param string $diia_credentials_path
* @param string $vidiPrivateKeyFilePath
* @param string $vidiPrivateKeyPasswordFilePath
* @param string $diiaSertFilePath
* @param bool $testingMode
* @param HttpClient|null $guzzle
*/
public function __construct(
string $acquirerToken,
SessionHandlerProvider $handlerProvider,
LoggerInterface $logger,
Eusphpe $eusphpe,
string $diia_credentials_path,
string $vidiPrivateKeyFilePath,
string $vidiPrivateKeyPasswordFilePath,
string $diiaSertFilePath,
bool $testingMode = false,
HttpClient $guzzle = null
) {
$this->acquirerDefToken = $acquirerToken;
$this->testingMode = $testingMode;
$this->handlerProvider = $handlerProvider;
$this->eusphpe = $eusphpe;
// If there were no guzzle instance provided, make the default one.
$this->setLogger($logger);
$this->diiaCredentialsPath = $diia_credentials_path;
if (file_exists($vidiPrivateKeyFilePath)) {
$this->vidiDefPrivateKey = file_get_contents($vidiPrivateKeyFilePath, FILE_USE_INCLUDE_PATH);
}
if (file_exists($vidiPrivateKeyPasswordFilePath)) {
$this->vidiDefPrivateKeyPassword = file_get_contents($vidiPrivateKeyPasswordFilePath, FILE_USE_INCLUDE_PATH);
}
if (file_exists($diiaSertFilePath)) {
$this->diiaDefSert = file_get_contents($diiaSertFilePath, FILE_USE_INCLUDE_PATH);
}
}
/**
* Transform the items of the collection to the given class.
*
* @param array $collection
* @param string $class
* @param array $extraData
* @return array
*/
public function transformCollection(array $collection, $class, $extraData = []): array
{
return array_map(fn($data) => new $class($data + $extraData, $this), $collection);
}
public function getCredentials(Dealer $dealer)
{
if (!file_exists($this->diiaCredentialsPath))
return false;
$credFileContent = Yaml::parseFile($this->diiaCredentialsPath);
$credentials = [];
if ($credFileContent && isset($credFileContent[$dealer->getUniqueId()])){
$credentials = $credFileContent[$dealer->getUniqueId()];
} else {
return false;
}
if (file_exists($credentials['vidiPrivateKey'])) {
$credentials['vidiPrivateKey'] = file_get_contents($credentials['vidiPrivateKey'], FILE_USE_INCLUDE_PATH);
}
if (file_exists($credentials['vidiPrivateKeyPassword'])) {
$credentials['vidiPrivateKeyPassword'] = file_get_contents($credentials['vidiPrivateKeyPassword'], FILE_USE_INCLUDE_PATH);
}
return $credentials;
}
public function setCredentials(Dealer $dealer, $testMode = false)
{
$credentials = self::getCredentials($dealer);
if ($credentials){
$this->acquirerToken = $credentials['acquirerToken'];
if ($testMode == true && $dealer->getId() == 14){
$this->testingMode = true;
$this->acquirerToken = 'vidielite_test_token_byw932';
}
$this->vidiPrivateKey = $credentials['vidiPrivateKey'];
$this->vidiPrivateKeyPassword = $credentials['vidiPrivateKeyPassword'];
$this->diiaSert = $this->diiaDefSert;
$this->initGuzzle(null);
$this->obtainSessionToken($this->acquirerToken, $credentials['auth_acquirer_token'], $dealer->getId());
} else {
$this->acquirerToken = $this->acquirerDefToken;
$this->vidiPrivateKey = $this->vidiDefPrivateKey;
$this->vidiPrivateKeyPassword = $this->vidiDefPrivateKeyPassword;
$this->diiaSert = $this->diiaDefSert;
$this->initGuzzle(null);
$this->obtainSessionToken($this->acquirerToken);
}
}
/**
* Transform the items of the collection to the given class.
*
* @return void
* @throws HandlerNotFoundException
*/
public function invalidateSessionToken()
{
$this->handlerProvider->getSessionKeyHandler($this->getMode());
}
public function decryptData($encodedData)
{
$res =$this->eusphpe->developBankIdData($this->vidiPrivateKey, $this->vidiPrivateKeyPassword, $encodedData, null);
$this->logger->info('decryptData', $res);
return $res;
}
/**
* Obtain session token, using provided acquirer token/
*
* @param string $acquirerToken
* @throws HandlerNotFoundException
*/
protected function obtainSessionToken($acquirerToken, $auth_acquirer_token = self::DEF_AUTH_ACQUIRER_TOKEN, $dealerId)
{
$sessionKeyHandler = $this->handlerProvider->getSessionKeyHandler($this->getMode());
try {
if (!$this->sessionToken = $sessionKeyHandler->handle($dealerId)) {
$this->applyDefaultOptions(['headers' => ['Authorization' => "Basic ". $auth_acquirer_token]]);
$this->sessionToken = $this->get("v1/auth/acquirer/{$acquirerToken}")["token"];
//https://docs.google.com/document/d/1lM7Yd954GwtR1PRfo3afTR89YmC8k8_MrjyWhlZx4xw/edit#heading=h.4enep6lpiym1
//Set session token який був отриманий не раніше, ніж 2 години тому
$sessionKeyHandler->setToken($this->sessionToken, $dealerId);
}
} catch (ResponseErrorException $e) {
$this->logger->critical($e->getMessage());
}
//Для оновлення токена. Проблема в applyDefaultOptions (array_merge_recursive)
if (isset($this->guzzleCurrentOptions['headers']['Authorization'])){
unset($this->guzzleCurrentOptions['headers']['Authorization']);
}
$this->applyDefaultOptions(['headers' => ['Authorization' => "Bearer {$this->sessionToken}"]]);
}
public function hashFiles($files)
{
$hashFiles = [];
foreach ($files as $file){
$hashFiles[] = [
'fileName' => $file['name'],
'fileHash' => $this->eusphpe->hashFile($file['path'], true)
];
}
return $hashFiles;
}
public function hashData($data)
{
$hashFiles = [];
foreach ($data as $file){
$hashFiles[] = [
'fileName' => $file['name'],
'fileHash' => $this->eusphpe->hashFile($file['data'])
];
}
return $hashFiles;
}
public function checkSignature($signature, $hashData)
{
$verify = $this->eusphpe->verify($signature, $hashData);
return $verify;
}
}