115 lines
4.0 KiB
PHP
115 lines
4.0 KiB
PHP
<?php
|
|
namespace ProVM\Service;
|
|
|
|
use ProVM\Exception\Response\EmptyResponse;
|
|
use ProVM\Exception\Response\MissingResponse;
|
|
use Psr\Log\LoggerInterface;
|
|
use function Safe\json_decode;
|
|
|
|
class Attachments
|
|
{
|
|
public function __construct(protected Communicator $communicator, protected LoggerInterface $logger, protected array $passwords, protected string $base_command = 'qpdf') {}
|
|
|
|
protected array $attachments;
|
|
|
|
public function findAll(): \Generator
|
|
{
|
|
$this->logger->info('Finding all downloaded attachment files');
|
|
$folder = '/attachments';
|
|
$files = new \FilesystemIterator($folder);
|
|
foreach ($files as $file) {
|
|
if ($file->isDir()) {
|
|
continue;
|
|
}
|
|
yield $file->getRealPath();
|
|
}
|
|
}
|
|
public function getAll(): array
|
|
{
|
|
if (!isset($this->attachments)) {
|
|
$this->logger->info('Grabbing all attachments');
|
|
$response = $this->communicator->get('/attachments');
|
|
$body = $response->getBody()->getContents();
|
|
if (trim($body) === '') {
|
|
$this->attachments = [];
|
|
return $this->attachments;
|
|
}
|
|
$this->attachments = json_decode($body)->attachments;
|
|
}
|
|
return $this->attachments;
|
|
}
|
|
public function get(int $attachment_id): object
|
|
{
|
|
$this->logger->info("Getting attachment {$attachment_id}");
|
|
$uri = "/attachment/{$attachment_id}";
|
|
$response = $this->communicator->get($uri);
|
|
$body = $response->getBody()->getContents();
|
|
if (trim($body) === '') {
|
|
throw new EmptyResponse($uri);
|
|
}
|
|
$json = json_decode($body);
|
|
if (!isset($json->attachment)) {
|
|
throw new MissingResponse('attachment');
|
|
}
|
|
return $json->attachment;
|
|
}
|
|
public function find(string $filename): int
|
|
{
|
|
$this->logger->info("Finding attachment {$filename}");
|
|
foreach ($this->getAll() as $attachment) {
|
|
if ($attachment->fullfilename === $filename) {
|
|
return $attachment->id;
|
|
}
|
|
}
|
|
throw new \Exception("{$filename} is not in the database");
|
|
}
|
|
public function isEncrypted(string $filename): bool
|
|
{
|
|
if (!file_exists($filename)) {
|
|
throw new \InvalidArgumentException("File not found {$filename}");
|
|
}
|
|
$escaped_filename = escapeshellarg($filename);
|
|
$cmd = "{$this->base_command} --is-encrypted {$escaped_filename}";
|
|
exec($cmd, $output, $retcode);
|
|
return $retcode == 0;
|
|
}
|
|
public function scheduleDecrypt(int $attachment_id): bool
|
|
{
|
|
$this->logger->info("Scheduling decryption of attachment {$attachment_id}");
|
|
$uri = "/attachment/{$attachment_id}/decrypt";
|
|
$response = $this->communicator->get($uri);
|
|
$body = $response->getBody()->getContents();
|
|
if (trim($body) === '') {
|
|
throw new EmptyResponse($uri);
|
|
}
|
|
$json = json_decode($body);
|
|
if (!isset($json->status)) {
|
|
throw new MissingResponse('status');
|
|
}
|
|
return $json->status;
|
|
}
|
|
public function decrypt(string $basename): bool
|
|
{
|
|
$this->logger->info("Decrypting {$basename}");
|
|
$in_filename = implode('/', ['attachments', $basename]);
|
|
$out_filename = implode('/', ['attachments', 'decrypted', $basename]);
|
|
if (file_exists($out_filename)) {
|
|
throw new \Exception("{$basename} already decrypted");
|
|
}
|
|
foreach ($this->passwords as $password) {
|
|
$cmd = $this->base_command . ' -password=' . escapeshellarg($password) . ' -decrypt ' . escapeshellarg($in_filename) . ' ' . escapeshellarg($out_filename);
|
|
exec($cmd, $output, $retcode);
|
|
$success = $retcode == 0;
|
|
if ($success) {
|
|
return true;
|
|
}
|
|
if (file_exists($out_filename)) {
|
|
unlink($out_filename);
|
|
}
|
|
unset($output);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
}
|