Compare commits
No commits in common. "b7d24cd74922e6d18071ca1cb6693cec1cc093d4" and "ab1562212f9bf609fe923b25840b28035acd1e0f" have entirely different histories.
b7d24cd749
...
ab1562212f
File diff suppressed because it is too large
Load Diff
|
|
@ -10,5 +10,4 @@ return [
|
||||||
Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true],
|
Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true],
|
||||||
Symfony\UX\StimulusBundle\StimulusBundle::class => ['all' => true],
|
Symfony\UX\StimulusBundle\StimulusBundle::class => ['all' => true],
|
||||||
Symfony\UX\Chartjs\ChartjsBundle::class => ['all' => true],
|
Symfony\UX\Chartjs\ChartjsBundle::class => ['all' => true],
|
||||||
Symfony\UX\TwigComponent\TwigComponentBundle::class => ['all' => true],
|
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
twig_component:
|
|
||||||
anonymous_template_directory: 'components/'
|
|
||||||
defaults:
|
|
||||||
# Namespace & directory for components
|
|
||||||
App\Twig\Components\: 'components/'
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
controllers_sign_document:
|
controllers:
|
||||||
resource:
|
resource:
|
||||||
path: ../src/SignDocument/Controller/
|
path: ../src/Controller/
|
||||||
namespace: App\SignDocument\Controller
|
namespace: App\Controller
|
||||||
type: attribute
|
type: attribute
|
||||||
|
|
@ -28,6 +28,6 @@ services:
|
||||||
|
|
||||||
GuzzleHttp\Client: '@guzzle.http_client'
|
GuzzleHttp\Client: '@guzzle.http_client'
|
||||||
|
|
||||||
App\SignDocument\Api\ApiParams:
|
App\Api\ApiParams:
|
||||||
arguments:
|
arguments:
|
||||||
$endPointUrl: '%env(DOT_DOT_URL)%'
|
$endPointUrl: '%env(DOT_DOT_URL)%'
|
||||||
|
|
@ -2,10 +2,11 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace App\SignDocument\Api;
|
namespace App\Api;
|
||||||
|
|
||||||
use App\Infrastructure\External\Api\AbstractApi;
|
use App\Infrastructure\External\Api\AbstractApi;
|
||||||
use App\Infrastructure\External\Api\BinaryStringFileResult;
|
use App\Infrastructure\External\Api\BinaryStringFileResult;
|
||||||
|
use GuzzleHttp\Psr7\Request;
|
||||||
use GuzzleHttp\RequestOptions;
|
use GuzzleHttp\RequestOptions;
|
||||||
|
|
||||||
class Api extends AbstractApi
|
class Api extends AbstractApi
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace App\SignDocument\Api;
|
namespace App\Api;
|
||||||
|
|
||||||
class ApiParams
|
class ApiParams
|
||||||
{
|
{
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace App\SignDocument\Api\Request;
|
namespace App\Api\Request;
|
||||||
|
|
||||||
use App\Infrastructure\Http\RequestDtoInterface;
|
use App\Infrastructure\Http\RequestDtoInterface;
|
||||||
|
|
||||||
|
|
@ -2,15 +2,15 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace App\SignDocument\Controller;
|
namespace App\Controller;
|
||||||
|
|
||||||
use App\SignDocument\Api\Request\SignRequest;
|
use App\Api\Request\SignRequest;
|
||||||
use App\SignDocument\Services\SignService;
|
use App\SignService;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
|
||||||
use Symfony\Component\Routing\Annotation\Route;
|
use Symfony\Component\Routing\Annotation\Route;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
|
||||||
class SignController extends AbstractController
|
class SignController extends AbstractController
|
||||||
{
|
{
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace App\SignDocument\Services;
|
namespace App;
|
||||||
|
|
||||||
class DevSignService
|
class DevSignService
|
||||||
{
|
{
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Infrastructure\Api\Response;
|
|
||||||
|
|
||||||
// Абстрактный респонс - от него наследуются нужные респонсы для стандартизации ответа в ApiHelperTrait -> createNewJsonResponse
|
|
||||||
|
|
||||||
abstract class AbstractResponse
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
@ -4,8 +4,6 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace App\Infrastructure\External\Api;
|
namespace App\Infrastructure\External\Api;
|
||||||
|
|
||||||
use RuntimeException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Враппер бинарных фалов, при создании класса содает новый временный файл,
|
* Враппер бинарных фалов, при создании класса содает новый временный файл,
|
||||||
* при необходимости сохраняет файл под новым именем
|
* при необходимости сохраняет файл под новым именем
|
||||||
|
|
@ -25,14 +23,4 @@ class BinaryStringFileResult
|
||||||
$this->tempFileName = sprintf('%s/%s_%s', sys_get_temp_dir(), 'Document', time());
|
$this->tempFileName = sprintf('%s/%s_%s', sys_get_temp_dir(), 'Document', time());
|
||||||
file_put_contents($this->tempFileName, $content);
|
file_put_contents($this->tempFileName, $content);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function remove(): bool
|
|
||||||
{
|
|
||||||
if (file_exists($this->tempFileName)) {
|
|
||||||
unlink($this->tempFileName);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new RuntimeException('Temp file not found');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,51 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Infrastructure\Traits;
|
|
||||||
|
|
||||||
use App\Infrastructure\Api\Response\AbstractResponse;
|
|
||||||
use ReflectionClass;
|
|
||||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
|
||||||
|
|
||||||
trait ApiHelperTrait
|
|
||||||
{
|
|
||||||
public function createJsonResponse(array $body, string $message = 'OK', int $code = 200): JsonResponse
|
|
||||||
{
|
|
||||||
return new JsonResponse([
|
|
||||||
'message' => $message,
|
|
||||||
'body' => $body,
|
|
||||||
], $code);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function createPaginateJsonResponse(array $items, int $limit, int $totalCount): JsonResponse
|
|
||||||
{
|
|
||||||
return $this->createJsonResponse(
|
|
||||||
[
|
|
||||||
'items' => $items,
|
|
||||||
'pages' => ceil($totalCount / $limit),
|
|
||||||
'totalCount' => $totalCount,
|
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function createJsonResponseFromObject(AbstractResponse $body, string $message = 'OK', int $code = 200): JsonResponse
|
|
||||||
{
|
|
||||||
return new JsonResponse([
|
|
||||||
'message' => $message,
|
|
||||||
'body' => $this->toArray($body),
|
|
||||||
], $code);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function toArray(AbstractResponse $body): array
|
|
||||||
{
|
|
||||||
$reflect = new ReflectionClass($body);
|
|
||||||
$props = $reflect->getProperties();
|
|
||||||
$array = [];
|
|
||||||
foreach ($props as $prop) {
|
|
||||||
$prop->setAccessible(true);
|
|
||||||
$array[$prop->getName()] = $prop->getValue($body);
|
|
||||||
$prop->setAccessible(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $array;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
|
||||||
namespace App\SignDocument\Services;
|
namespace App;
|
||||||
|
|
||||||
|
|
||||||
class ProdSignService
|
class ProdSignService
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace App\SignDocument\Api\Request;
|
|
||||||
|
|
||||||
use App\Infrastructure\Http\RequestDtoInterface;
|
|
||||||
|
|
||||||
class DigitalSignatureRequest implements RequestDtoInterface
|
|
||||||
{
|
|
||||||
public string $url;
|
|
||||||
public string $apiToken;
|
|
||||||
}
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
|
|
||||||
namespace App\SignDocument\Api\Response;
|
|
||||||
|
|
||||||
use App\Infrastructure\Api\Response\AbstractResponse;
|
|
||||||
|
|
||||||
class DigitalSignatureResponse extends AbstractResponse
|
|
||||||
{
|
|
||||||
public function __construct(
|
|
||||||
public string $hash,
|
|
||||||
public string $content,
|
|
||||||
)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace App\SignDocument\Controller;
|
|
||||||
|
|
||||||
use App\Infrastructure\Traits\ApiHelperTrait;
|
|
||||||
use App\SignDocument\Api\Request\DigitalSignatureRequest;
|
|
||||||
use App\SignDocument\Services\DigitalSignatureService;
|
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
|
||||||
use Symfony\Component\Routing\Annotation\Route;
|
|
||||||
|
|
||||||
class DigitalSignatureController extends AbstractController
|
|
||||||
{
|
|
||||||
use ApiHelperTrait;
|
|
||||||
public function __construct(
|
|
||||||
private readonly DigitalSignatureService $digitalSignatureService
|
|
||||||
){
|
|
||||||
}
|
|
||||||
|
|
||||||
#[Route(path: '/digital/sign', name: 'app.digital.sign', methods: ['POST'])]
|
|
||||||
public function __invoke(Request $request, DigitalSignatureRequest $digitalSignatureRequest): Response
|
|
||||||
{
|
|
||||||
$token = $request->server->get('HTTP_AUTHORIZATION');
|
|
||||||
|
|
||||||
return $this->createJsonResponseFromObject(
|
|
||||||
$this->digitalSignatureService->getSignature($digitalSignatureRequest, $token)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,55 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace App\SignDocument\Services;
|
|
||||||
|
|
||||||
use App\Infrastructure\External\Api\BinaryStringFileResult;
|
|
||||||
use App\SignDocument\Api\Api;
|
|
||||||
use App\SignDocument\Api\ApiParams;
|
|
||||||
use App\SignDocument\Api\Request\DigitalSignatureRequest;
|
|
||||||
use App\SignDocument\Api\Response\DigitalSignatureResponse;
|
|
||||||
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
|
||||||
use Exception;
|
|
||||||
use RuntimeException;
|
|
||||||
|
|
||||||
class DigitalSignatureService
|
|
||||||
{
|
|
||||||
private BinaryStringFileResult $document;
|
|
||||||
|
|
||||||
public function __construct(
|
|
||||||
private readonly Api $api,
|
|
||||||
private readonly ApiParams $apiParams,
|
|
||||||
){
|
|
||||||
}
|
|
||||||
|
|
||||||
public function __destruct()
|
|
||||||
{
|
|
||||||
$this->document->remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getSignature(DigitalSignatureRequest $request, string $token): DigitalSignatureResponse
|
|
||||||
{
|
|
||||||
if ($_ENV['API_TOKEN'] !== $request->apiToken) {
|
|
||||||
throw new AccessDeniedHttpException('Доступ запрещен');
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->api->apiParams = $this->apiParams;
|
|
||||||
|
|
||||||
try {
|
|
||||||
$this->document = $this->api->download($request->url, $token);
|
|
||||||
|
|
||||||
exec(sprintf('cp %s %s.pdf', $this->document->tempFileName, $this->document->tempFileName));
|
|
||||||
exec(sprintf('cryptcp -sign -detached -der %s.pdf', $this->document->tempFileName));
|
|
||||||
|
|
||||||
$response = base64_encode(file_get_contents($this->document->tempFileName . '.pdf.sgn'));
|
|
||||||
|
|
||||||
return new DigitalSignatureResponse(
|
|
||||||
hash: $response,
|
|
||||||
content: base64_encode(file_get_contents(sprintf('%s.pdf', $this->document->tempFileName)))
|
|
||||||
);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
throw new RuntimeException($e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace App\SignDocument\Services;
|
|
||||||
|
|
||||||
use App\Infrastructure\External\Api\BinaryStringFileResult;
|
|
||||||
|
|
||||||
class RemoveExistingDocumentService
|
|
||||||
{
|
|
||||||
|
|
||||||
public function removeExistingDocument(BinaryStringFileResult $document): void
|
|
||||||
{
|
|
||||||
if (file_exists($document->tempFileName)) {
|
|
||||||
unlink($document->tempFileName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -2,24 +2,27 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace App\SignDocument\Services;
|
namespace App;
|
||||||
|
|
||||||
use App\SignDocument\Api\Api;
|
use App\Api\Api;
|
||||||
use App\SignDocument\Api\ApiParams;
|
use App\Api\ApiParams;
|
||||||
use App\SignDocument\Api\Request\SignRequest;
|
use App\Api\Request\SignRequest;
|
||||||
|
use App\Infrastructure\External\Api\BinaryStringFileResult;
|
||||||
use Exception;
|
use Exception;
|
||||||
use RuntimeException;
|
use RuntimeException;
|
||||||
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
||||||
|
|
||||||
class SignService
|
class SignService
|
||||||
{
|
{
|
||||||
|
private DevSignService $devSignService;
|
||||||
|
private ProdSignService $prodSignService;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private readonly Api $api,
|
private Api $api,
|
||||||
private readonly ApiParams $apiParams,
|
private ApiParams $apiParams
|
||||||
private readonly DevSignService $devSignService,
|
|
||||||
private readonly ProdSignService $prodSignService,
|
|
||||||
private readonly RemoveExistingDocumentService $removeExistingDocumentService,
|
|
||||||
){
|
){
|
||||||
|
$this->devSignService = new DevSignService();
|
||||||
|
$this->prodSignService = new ProdSignService();
|
||||||
}
|
}
|
||||||
public function signDocument(SignRequest $request,string $token): array
|
public function signDocument(SignRequest $request,string $token): array
|
||||||
{
|
{
|
||||||
|
|
@ -36,7 +39,7 @@ class SignService
|
||||||
|
|
||||||
$response = $this->api->send($token, $document->tempFileName . '_sign.pdf', $request->batch);
|
$response = $this->api->send($token, $document->tempFileName . '_sign.pdf', $request->batch);
|
||||||
|
|
||||||
$this->removeExistingDocumentService->removeExistingDocument($document);
|
$this->removeExistingDocument($document);
|
||||||
|
|
||||||
return $response;
|
return $response;
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
|
|
@ -51,4 +54,11 @@ class SignService
|
||||||
'prod' => $this->prodSignService->sign($documentUrl),
|
'prod' => $this->prodSignService->sign($documentUrl),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function removeExistingDocument(BinaryStringFileResult $document): void
|
||||||
|
{
|
||||||
|
if (file_exists($document->tempFileName)) {
|
||||||
|
unlink($document->tempFileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -176,18 +176,6 @@
|
||||||
"symfony/ux-chartjs": {
|
"symfony/ux-chartjs": {
|
||||||
"version": "v2.19.3"
|
"version": "v2.19.3"
|
||||||
},
|
},
|
||||||
"symfony/ux-twig-component": {
|
|
||||||
"version": "2.22",
|
|
||||||
"recipe": {
|
|
||||||
"repo": "github.com/symfony/recipes",
|
|
||||||
"branch": "main",
|
|
||||||
"version": "2.13",
|
|
||||||
"ref": "67814b5f9794798b885cec9d3f48631424449a01"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"config/packages/twig_component.yaml"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"symfony/validator": {
|
"symfony/validator": {
|
||||||
"version": "6.2",
|
"version": "6.2",
|
||||||
"recipe": {
|
"recipe": {
|
||||||
|
|
|
||||||
|
|
@ -5,16 +5,14 @@ server {
|
||||||
root /usr/src/signer/public;
|
root /usr/src/signer/public;
|
||||||
|
|
||||||
|
|
||||||
location / {
|
location ~* \.php$ {
|
||||||
try_files $uri $uri/ /index.php?$args;
|
try_files $uri $uri/ /index.php last;
|
||||||
}
|
fastcgi_split_path_info (.+?\.php)(/.*)$;
|
||||||
|
fastcgi_pass localhost:9000;
|
||||||
location ~ \.php$ {
|
|
||||||
include fastcgi_params;
|
|
||||||
fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
|
|
||||||
fastcgi_pass signer:9000;
|
|
||||||
try_files $uri =404;
|
|
||||||
fastcgi_index index.php;
|
fastcgi_index index.php;
|
||||||
|
include fastcgi_params;
|
||||||
|
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||||
|
fastcgi_param PATH_INFO $fastcgi_path_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
location ~* .php/ {
|
location ~* .php/ {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue