HMAC implementation for signature validation
This commit is contained in:
@ -45,7 +45,8 @@ return [
|
||||
'/api/external' => [
|
||||
'/toku/success' => [
|
||||
'validator' => Incoviba\Service\Venta\MediosPago\Toku::class,
|
||||
'token' => $container->get('TOKU_TOKEN')
|
||||
'token' => $container->get('TOKU_TOKEN'),
|
||||
'secret' => $container->get('TOKU_WEBHOOK_SECRET'),
|
||||
]
|
||||
],
|
||||
]
|
||||
|
17
app/src/Service/HMAC.php
Normal file
17
app/src/Service/HMAC.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
namespace Incoviba\Service;
|
||||
|
||||
use Incoviba\Common\Ideal;
|
||||
|
||||
class HMAC extends Ideal\Service
|
||||
{
|
||||
public static function validate(string $timestamp, string $requestSignature, string $requestId, string $secret): bool
|
||||
{
|
||||
$message = "{$timestamp}.{$requestId}";
|
||||
$encodedSecret = mb_convert_encoding($secret, 'UTF-8');
|
||||
$encodedMessage = mb_convert_encoding($message, 'UTF-8');
|
||||
$hmacObject = hash_hmac('sha256', $encodedMessage, $encodedSecret);
|
||||
$computedSignature = base64_encode($hmacObject);
|
||||
return hash_equals($computedSignature, $requestSignature);
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
<?php
|
||||
namespace Incoviba\Service\Venta\MediosPago;
|
||||
|
||||
use Incoviba\Service\HMAC;
|
||||
use InvalidArgumentException;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Incoviba\Service\Venta\MediosPago\Toku\{Customer,Subscription,Invoice};
|
||||
@ -11,6 +12,7 @@ use Incoviba\Exception\ServiceAction\Read;
|
||||
use Incoviba\Model;
|
||||
use Incoviba\Model\Persona;
|
||||
use Incoviba\Model\Venta\Propietario;
|
||||
use Throwable;
|
||||
|
||||
class Toku extends Ideal\Service
|
||||
{
|
||||
@ -407,12 +409,23 @@ class Toku extends Ideal\Service
|
||||
return false;
|
||||
}
|
||||
|
||||
$tracestate = explode(';', substr($request->getHeaderLine('Tracestate'), strlen('dd=')));
|
||||
$ptid = substr(array_find($tracestate, fn($item) => str_starts_with($item, 't.tid:')), strlen('t.tid:'));
|
||||
$datadogTags = explode(',', $request->getHeaderLine('X-Datadog-Tags'));
|
||||
$tid = array_find($datadogTags, fn($item) => str_contains($item, 'p.tid='));
|
||||
$tid = substr($tid, strpos($tid, 'p.tid=') + strlen('p.tid='));
|
||||
|
||||
return $tid === $ptid;
|
||||
$tokuSignature = $request->getHeaderLine('Toku-Signature');
|
||||
try {
|
||||
list($timestamp, $signature) = array_map(function($elem) {
|
||||
return explode('=', $elem)[1];
|
||||
}, explode(',', $tokuSignature));
|
||||
$body = $request->getBody()->getContents();
|
||||
$json = json_decode($body, true);
|
||||
if (!is_array($json)) {
|
||||
return false;
|
||||
}
|
||||
if (!array_key_exists('id', $json)) {
|
||||
return false;
|
||||
}
|
||||
$eventId = $json['id'];
|
||||
return HMAC::validate($timestamp, $signature, $eventId, $tokenConfig['secret']);
|
||||
} catch (Throwable $throwable) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user