107 lines
2.9 KiB
PHP
107 lines
2.9 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Malio\EdnotifBundle\Auth;
|
|
|
|
use Malio\EdnotifBundle\Shared\Exception\EdnotifException;
|
|
use Psr\Cache\CacheItemPoolInterface;
|
|
use Psr\Cache\InvalidArgumentException;
|
|
use RuntimeException;
|
|
use SoapClient;
|
|
use SoapFault;
|
|
|
|
final readonly class TokenProvider
|
|
{
|
|
public function __construct(
|
|
private SoapClient $guichetClient,
|
|
private string $exploitationCode,
|
|
private ?string $zone,
|
|
private ?string $application,
|
|
private string $login,
|
|
private string $password,
|
|
private int $tokenTtlSeconds,
|
|
private CacheItemPoolInterface $cachePool,
|
|
) {}
|
|
|
|
/**
|
|
* @throws InvalidArgumentException
|
|
*/
|
|
public function getToken(): string
|
|
{
|
|
$cacheKey = $this->getCacheKey();
|
|
$item = $this->cachePool->getItem($cacheKey);
|
|
|
|
if ($item->isHit()) {
|
|
$token = $item->get();
|
|
if (is_string($token) && '' !== $token) {
|
|
return $token;
|
|
}
|
|
}
|
|
|
|
$token = $this->createToken();
|
|
|
|
$item->set($token);
|
|
$item->expiresAfter($this->tokenTtlSeconds);
|
|
$this->cachePool->save($item);
|
|
|
|
return $token;
|
|
}
|
|
|
|
/**
|
|
* @throws InvalidArgumentException
|
|
*/
|
|
public function invalidateToken(): void
|
|
{
|
|
$this->cachePool->deleteItem($this->getCacheKey());
|
|
}
|
|
|
|
private function createToken(): string
|
|
{
|
|
$profil = array_filter([
|
|
'Entreprise' => $this->exploitationCode,
|
|
'Zone' => $this->zone,
|
|
'Application' => $this->application,
|
|
], static fn ($v) => null !== $v && '' !== $v);
|
|
|
|
$payload = [
|
|
'Identification' => [
|
|
'UserId' => $this->login,
|
|
'Password' => $this->password,
|
|
'Profil' => $profil,
|
|
],
|
|
];
|
|
|
|
try {
|
|
/** @var object $response */
|
|
$response = $this->guichetClient->__soapCall('tkCreateIdentification', [$payload]);
|
|
} catch (SoapFault $e) {
|
|
throw new RuntimeException('SOAP Fault lors de tkCreateIdentification: '.$e->getMessage(), 0, $e);
|
|
}
|
|
|
|
$rs = $response->ReponseStandard ?? null;
|
|
$ok = is_object($rs) && (($rs->Resultat ?? false) === true);
|
|
|
|
if (!$ok) {
|
|
$anom = $rs->Anomalie ?? null;
|
|
$code = (string) ($anom->Code ?? 'UNKNOWN');
|
|
$sev = (int) ($anom->Severite ?? 1);
|
|
$msg = (string) ($anom->Message ?? 'Authentification refusée');
|
|
|
|
throw new EdnotifException($code, $sev, $msg);
|
|
}
|
|
|
|
$token = $response->Jeton ?? null;
|
|
if (!is_string($token) || '' === $token) {
|
|
throw new RuntimeException('Guichet: réponse OK mais Jeton absent.');
|
|
}
|
|
|
|
return $token;
|
|
}
|
|
|
|
private function getCacheKey(): string
|
|
{
|
|
return 'ednotif.token.'.hash('sha256', $this->exploitationCode.'|'.$this->login);
|
|
}
|
|
}
|