Commit 48b42b9a authored by Predhumeau Manon's avatar Predhumeau Manon Committed by Guillaume Perréal
Browse files

Add antivirus analyse (xenelop quahog)

parent 1c62bf2d
No related merge requests found
This commit is part of merge request !1. Comments created here will be created in the context of that merge request.
Showing with 91 additions and 65 deletions
+91 -65
......@@ -6,9 +6,10 @@
namespace Irstea\FileUploadBundle\Listener;
use CL\Tissue\Adapter\AdapterInterface;
use Xenolope\Quahog\Client;
use Irstea\FileUploadBundle\Event\FileUploadCompleteEvent;
use Irstea\FileUploadBundle\Exception\RejectedFileException;
use Xenolope\Quahog\Exception\ConnectionException;
/**
* Description of AntivirusListener.
......@@ -16,42 +17,57 @@ use Irstea\FileUploadBundle\Exception\RejectedFileException;
class VirusScannerListener
{
/**
* @var AdapterInterface
* @var Client
*/
private $scanner;
private $client;
/**
* @param AdapterInterface $scanner
* @param Client $client
*/
public function __construct(AdapterInterface $scanner)
public function __construct(Client $client)
{
$this->scanner = $scanner;
$this->client = $client;
try {
// Check clamd server's state
$this->client->ping();
// Reload the virus database
$this->client->reload();
} catch (ConnectionException $connectionException) {
$this->client->shutdown();
$this->client = null;
}
}
/**
* @param FileUploadCompleteEvent $event
*/
public function onFileUploadCompleted(FileUploadCompleteEvent $event)
{
$file = $event->getUploadedFile();
$path = $file->getLocalPath();
$result = $this->scanner->scan([$path]);
if ($this->client != null) {
$file = $event->getUploadedFile();
$path = $file->getLocalPath();
$meta = $file->getMetadata();
$result = $this->client->scanFile($path);
$hasVirus = $result['status'] == Client::RESULT_FOUND;
$meta['virus_scanner'] = ['has_virus' => $result->hasVirus()];
$meta = $file->getMetadata();
$meta['virus_scanner'] = ['has_virus' => $hasVirus];
if ($result->hasVirus()) {
if (null !== $desc = $result->getDetections()[0]->getDescription()) {
$meta['virus_scanner']['detected'] = $desc;
if ($hasVirus) {
$desc = $result['reason'];
$meta['virus_scanner']['detected'] = $result['reason'];
}
}
$file->setMetadata($meta);
$file->setMetadata($meta);
if ($result->hasVirus()) {
throw new RejectedFileException($file, $desc ? sprintf('Found the %s virus !', $desc) : 'Virus found !');
if ($hasVirus) {
throw new RejectedFileException($file, $desc ? sprintf('Found the %s virus !', $desc) : 'Virus found !');
}
$this->client->shutdown();
}
}
}
......@@ -10,6 +10,10 @@ parameters:
irstea_file_upload.max_chunk_size: 0
irstea_file_upload.clamav_socket_path: unix:///var/run/clamav/clamd.ctl
irstea_file_upload.client_timeout: 30
irstea_file_upload.client_mode: PHP_NORMAL_READ
services:
# Le gestionnaire de fichiers
......@@ -70,12 +74,24 @@ services:
- "%irstea_file_upload.filesystem.name%"
# Scanner anti-virus
# irstea_file_upload.virus_scanner:
# class: Irstea\FileUploadBundle\Listener\VirusScannerListener
# arguments:
# - @cl_tissue.scanner
# tags:
# - { name: kernel.event_listener, event: file_upload.complete, method: onFileUploadCompleted }
irstea_file_upload.socket:
class: Socket\Raw\Socket
arguments:
- "%irstea_file_upload.clamav_socket_path"
irstea_file_upload.client:
class: Xenolope\Quahog\Client
arguments:
- "@irstea_file_upload.socket"
- "%irstea_file_upload.client_timeout"
- "%irstea_file_upload.client_mode"
irstea_file_upload.virus_scanner:
class: Irstea\FileUploadBundle\Listener\VirusScannerListener
arguments:
- "@irstea_file_upload.client"
tags:
- { name: kernel.event_listener, event: file_upload.complete, method: onFileUploadCompleted }
# Extension Twig
irstea_file_upload.twig_extension:
......
......@@ -6,12 +6,12 @@
namespace Irstea\FileUploadBundle\Tests\Listener;
use CL\Tissue\Model\Detection;
use CL\Tissue\Model\ScanResult;
use Irstea\FileUploadBundle\Event\FileUploadCompleteEvent;
use Irstea\FileUploadBundle\Listener\VirusScannerListener;
use PHPUnit_Framework_MockObject_MockObject;
use PHPUnit_Framework_TestCase;
use Irstea\FileUploadBundle\Model\UploadedFileInterface;
use Xenolope\Quahog\Client;
/**
* Generated by PHPUnit_SkeletonGenerator on 2015-01-29 at 14:43:16.
......@@ -26,7 +26,7 @@ class VirusScannerListenerTest extends PHPUnit_Framework_TestCase
/**
* @var PHPUnit_Framework_MockObject_MockObject
*/
protected $scanner;
protected $client;
/**
* @var FileUploadCompleteEvent
......@@ -43,38 +43,27 @@ class VirusScannerListenerTest extends PHPUnit_Framework_TestCase
*/
protected function setUp()
{
self::markTestSkipped('No CL\Tissue');
}
$this->client = $this->getMockBuilder(Client::class)->disableOriginalConstructor()->getMock();
public function testOnFileUploadCompletedResultOk()
{
$result = new ScanResult(
['foopath'],
['foopath'],
[]
);
$this->scanner->expects(static::once())->method('scan')->with(['foopath'])->willReturn($result);
$this->file = $this->getMock(UploadedFileInterface::class);
$this->file->expects(static::once())->method('getLocalPath')->willReturn('foopath');
$this->file->expects(static::once())->method('getMetadata')->willReturn([]);
$this->file->expects(static::once())->method('setMetadata')->with(['virus_scanner' => ['has_virus' => false]]);
$this->event = new FileUploadCompleteEvent($this->file);
$this->listener->onFileUploadCompleted($this->event);
$this->listener = new VirusScannerListener($this->client);
}
/**
* @expectedException \Irstea\FileUploadBundle\Exception\RejectedFileException
*/
public function testOnFileUploadCompletedVirusFound()
public function testOnFileUploadCompletedResultOk()
{
$result = new ScanResult(
['foopath'],
['foopath'],
[new Detection('foopath', Detection::TYPE_VIRUS, 'BAR')]
);
$this->scanner->expects(static::once())->method('scan')->with(['foopath'])->willReturn($result);
$result = [
'filename' => 'footpath',
'reason' => null,
'status' => Client::RESULT_OK
];
$this->file->expects(static::once())->method('setMetadata')->with(
['virus_scanner' => ['has_virus' => true, 'detected' => 'BAR']]
);
$this->client->expects(static::once())->method('scanFile')->with('foopath')->willReturn($result);
$this->file->expects(static::once())->method('setMetadata')->with(['virus_scanner' => ['has_virus' => false]]);
$this->listener->onFileUploadCompleted($this->event);
}
......@@ -82,18 +71,22 @@ class VirusScannerListenerTest extends PHPUnit_Framework_TestCase
/**
* @expectedException \Irstea\FileUploadBundle\Exception\RejectedFileException
*/
public function testOnFileUploadCompletedVirusFoundNoDescription()
public function testOnFileUploadCompletedVirusFound()
{
$result = new ScanResult(
['foopath'],
['foopath'],
[new Detection('foopath', Detection::TYPE_VIRUS)]
);
$this->scanner->expects(static::once())->method('scan')->with(['foopath'])->willReturn($result);
$this->file->expects(static::once())->method('setMetadata')->with(
['virus_scanner' => ['has_virus' => true]]
);
$result = [
'filename' => 'footpath',
'reason' => 'Terrible virus',
'status' => Client::RESULT_FOUND
];
$this->client->expects($this->any())
->method('scanFile')
->with('foopath')
->willReturn($result);
$this->file->expects(static::once())
->method('setMetadata')
->with(['virus_scanner' => ['has_virus' => true, 'detected' => 'Terrible virus']]);
$this->listener->onFileUploadCompleted($this->event);
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment