85 lines
2.8 KiB
PHP
85 lines
2.8 KiB
PHP
<?php
|
|
|
|
namespace App\Lib\Helpers;
|
|
|
|
use Illuminate\Contracts\Encryption\DecryptException;
|
|
use Illuminate\Support\Facades\Crypt;
|
|
use Uwil\LaravelCommon\Helpers\ToolboxHelper as BaseToolboxHelper;
|
|
|
|
class ToolboxHelper extends BaseToolboxHelper
|
|
{
|
|
/**
|
|
* Calculate the request signature
|
|
*
|
|
* @param string $secret
|
|
* @param string $uri
|
|
* @param string $method
|
|
* @param array $parameters
|
|
* @return string request signature
|
|
* @throws \RuntimeException If an error occurs.
|
|
*/
|
|
public static function signRequest(string $secret, string $uri, string $method, array $parameters): string
|
|
{
|
|
try {
|
|
$uri = collect(\parse_url($uri));
|
|
$method = \strtolower($method);
|
|
|
|
// * Remove signature from parameters to calculate the hashmac.
|
|
$signature = collect([
|
|
'uri' => sprintf(
|
|
'%s://%s%s',
|
|
$uri->get('scheme'),
|
|
$uri->get('host'),
|
|
$uri->get('path')
|
|
),
|
|
'method' => $method
|
|
]);
|
|
|
|
$flattenRequestArray = function (array $array) use (&$flattenRequestArray) {
|
|
$out = [];
|
|
foreach ($array as $key => $value) {
|
|
if (is_array($value)) {
|
|
$subArray = $flattenRequestArray($value);
|
|
foreach ($subArray as $subKey => $subValue) {
|
|
$out["$key.$subKey"] = $subValue;
|
|
}
|
|
continue;
|
|
}
|
|
$out[$key] = $value;
|
|
}
|
|
return $out;
|
|
};
|
|
|
|
$parameters = $flattenRequestArray($parameters);
|
|
$parameters = collect($parameters);
|
|
|
|
// * Remove signature from parameters.
|
|
$parameters->pull('signature');
|
|
|
|
// * Natural sort all parameters.
|
|
$parameters = $parameters->sortKeys(\SORT_NATURAL)
|
|
->map(function ($value, $key) {
|
|
return sprintf('%s=%s', \rawurlencode($key), \rawurlencode($value));
|
|
});
|
|
|
|
$signature->push($parameters->implode('&'));
|
|
|
|
$calculatedHash = base64_encode(hash_hmac(
|
|
'sha256',
|
|
$signature->implode('\n'),
|
|
Crypt::decryptString($secret),
|
|
true
|
|
));
|
|
|
|
if (!$calculatedHash) {
|
|
throw new \RuntimeException('Failed to calculate requests hash');
|
|
}
|
|
|
|
return $calculatedHash;
|
|
} catch (DecryptException $e) {
|
|
throw new \RuntimeException('Failed to decrypt service credentials', 0, $e);
|
|
} catch (\Exception $e) {
|
|
throw new \RuntimeException('An error occured when authenticating service', 0, $e);
|
|
} //end try
|
|
}
|
|
}
|