Skip to content

Commit

Permalink
Small fixes, change cache key so multiple TAs, one for each config, c…
Browse files Browse the repository at this point in the history
…an coexist
  • Loading branch information
litvinjuan committed May 1, 2024
1 parent b25d967 commit 042fd0e
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 22 deletions.
32 changes: 17 additions & 15 deletions src/AfipSigner.php → src/AfipCmsSigner.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
use litvinjuan\LaravelAfip\Exceptions\AfipSigningException;
use Spatie\TemporaryDirectory\TemporaryDirectory;

class AfipSigner
class AfipCmsSigner
{
private string $certificate;

Expand All @@ -32,13 +32,13 @@ public function sign(string $input): string
File::put($input_filename, $input);

try {
$result = openssl_pkcs7_sign(
$result = openssl_cms_sign(
$input_filename,
$output_filename,
$this->getCertificate(),
[$this->getPrivateKey(), $this->getPrivateKeyPassphrase()],
[],
! PKCS7_DETACHED
! OPENSSL_CMS_DETACHED
);

if (! $result) {
Expand All @@ -49,21 +49,23 @@ public function sign(string $input): string
throw new AfipSigningException('There was an error while signing using the certificate and key');
}

$file = fopen($output_filename, 'r');
$i = 0;
$cms = $this->getCmsFromCmsOutputFile($output_filename);
$temporaryDirectory->delete();

$signed = '';
while (! feof($file)) {
$buffer = fgets($file);
if ($i++ >= 4) {
$signed .= $buffer;
}
}
fclose($file);
return $cms;
}

$temporaryDirectory->delete();
private function getCmsFromCmsOutputFile(string $output_filename): string
{
$cms = File::get($output_filename);

$lastHeader = "Content-Transfer-Encoding: base64";
$lastHeaderPosition = strpos($cms, $lastHeader);
$lastHeaderLength = strlen($lastHeader);

return $signed;
return trim(
substr($cms, $lastHeaderPosition + $lastHeaderLength)
);
}

private function getCertificate()
Expand Down
14 changes: 11 additions & 3 deletions src/AfipConfiguration.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class AfipConfiguration

private bool $production_mode;

private AfipSigner $signer;
private AfipCmsSigner $signer;

public function __construct(string $cuit = null, string $certificate = null, string $private_key = null, string $private_key_passphrase = null, bool $production_mode = true)
{
Expand All @@ -24,14 +24,14 @@ public function __construct(string $cuit = null, string $certificate = null, str
$this->private_key_passphrase = $private_key_passphrase ?? config('afip.key-passphrase');
$this->production_mode = $production_mode ?? config('afip.production', false);

$this->signer = new AfipSigner(
$this->signer = new AfipCmsSigner(
$this->certificate,
$this->private_key,
$this->private_key_passphrase
);
}

public function getSigner(): AfipSigner
public function getSigner(): AfipCmsSigner
{
return $this->signer;
}
Expand All @@ -45,4 +45,12 @@ public function getCuit(): string
{
return $this->cuit;
}

public function getPublicIdentifier(): string
{
$privateKey = openssl_pkey_get_private($this->private_key, $this->private_key_passphrase);
$publicKey = openssl_pkey_get_details($privateKey)['key'];

return hash('sha256', $publicKey);
}
}
4 changes: 2 additions & 2 deletions src/AfipTokenAuthorizationProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ public static function createServiceTokenAuthorization(AfipConfiguration $config
private static function getCacheKey(AfipConfiguration $configuration, AfipService $service): string
{
if ($configuration->isProduction()) {
return "AFIP-TA-{$service->name}";
return "AFIP-TA-{$configuration->getPublicIdentifier()}-{$service->name}";
}

return "AFIP-TA-{$service->name}-dev";
return "AFIP-TA-{$configuration->getPublicIdentifier()}-{$service->name}-dev";
}
}
14 changes: 13 additions & 1 deletion src/WebServices/AfipClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use litvinjuan\LaravelAfip\Exceptions\AfipException;
use litvinjuan\LaravelAfip\Exceptions\AfipSoapException;
use litvinjuan\LaravelAfip\TokenAuthorization;
use SimpleXMLElement;
use SoapClient;

class AfipClient
Expand Down Expand Up @@ -58,7 +59,7 @@ public function call(string $name, ?array $params = [])
$client = $this->getClient();
$rawResponse = $client->{$name}($params);

$response = Arr::get(json_decode(json_encode($rawResponse), true), $this->getReturnKey($name));
$response = $this->convertResponseToJson($rawResponse, $name);

if (Arr::has($response, 'Errors')) {
$this->throwFirstError($response);
Expand Down Expand Up @@ -98,6 +99,17 @@ public function getSign(): string
return $this->getTokenAuthorization()->getSign();
}

private function convertResponseToJson(mixed $response, string $methodName): array
{
$responseKey = $this->getReturnKey($methodName);

if ($this->service === AfipService::wsaa) {
return json_decode(json_encode(new SimpleXMLElement($response->{$responseKey})), true);
}

return Arr::get(json_decode(json_encode($response), true), $responseKey);
}

private function getSoapVersion()
{
return match ($this->service) {
Expand Down
2 changes: 1 addition & 1 deletion src/WebServices/AuthenticationWebService.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public function __construct(AfipConfiguration $configuration = null)
$this->client = new AfipClient(AfipService::wsaa, $this->configuration);
}

public function login(string $cms): AfipService
public function login(string $cms): array
{
try {
return $this->client->call('loginCms', [
Expand Down

0 comments on commit 042fd0e

Please sign in to comment.