Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/ransomware_detection.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'tests/Unit/MonitorTest.php')
-rw-r--r--tests/Unit/MonitorTest.php419
1 files changed, 419 insertions, 0 deletions
diff --git a/tests/Unit/MonitorTest.php b/tests/Unit/MonitorTest.php
new file mode 100644
index 0000000..6047729
--- /dev/null
+++ b/tests/Unit/MonitorTest.php
@@ -0,0 +1,419 @@
+<?php
+
+/**
+ * @copyright Copyright (c) 2017 Matthias Held <matthias.held@uni-konstanz.de>
+ * @author Matthias Held <matthias.held@uni-konstanz.de>
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+namespace OCA\RansomwareDetection\tests\Unit;
+
+use OCA\RansomwareDetection\Monitor;
+use OCA\RansomwareDetection\Analyzer\EntropyAnalyzer;
+use OCA\RansomwareDetection\Analyzer\FileNameAnalyzer;
+use OCA\RansomwareDetection\Analyzer\FileNameResult;
+use OCA\RansomwareDetection\Analyzer\FileCorruptionAnalyzer;
+use OCA\RansomwareDetection\Analyzer\FileCorruptionResult;
+use OCA\RansomwareDetection\Analyzer\EntropyResult;
+use OCA\RansomwareDetection\Db\FileOperation;
+use OCA\RansomwareDetection\Db\FileOperationMapper;
+use OCP\App\IAppManager;
+use OCP\AppFramework\Utility\ITimeFactory;
+use OCP\Files\File;
+use OCP\Files\Folder;
+use OCP\Files\IRootFolder;
+use OCP\Files\Storage\IStorage;
+use OCP\Notification\IManager;
+use OCP\IConfig;
+use OCP\ILogger;
+use OCP\IRequest;
+use OCP\ISession;
+use Test\TestCase;
+
+class MonitorTest extends TestCase
+{
+ /** @var IRequest|\PHPUnit_Framework_MockObject_MockObject */
+ protected $request;
+
+ /** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */
+ protected $config;
+
+ /** @var ITimeFactory|\PHPUnit_Framework_MockObject_MockObject */
+ protected $time;
+
+ /** @var IAppManager|\PHPUnit_Framework_MockObject_MockObject */
+ protected $appManager;
+
+ /** @var ILogger|\PHPUnit_Framework_MockObject_MockObject */
+ protected $logger;
+
+ /** @var IRootFolder|\PHPUnit_Framework_MockObject_MockObject */
+ protected $rootFolder;
+
+ /** @var EntropyAnalyzer|\PHPUnit_Framework_MockObject_MockObject */
+ protected $entropyAnalyzer;
+
+ /** @var FileOperationMapper|\PHPUnit_Framework_MockObject_MockObject */
+ protected $mapper;
+
+ /** @var FileNameAnalyzer|\PHPUnit_Framework_MockObject_MockObject */
+ protected $fileNameAnalyzer;
+
+ /** @var FileCorruptionAnalyzer|\PHPUnit_Framework_MockObject_MockObject */
+ protected $fileCorruptionAnalyzer;
+
+ /** @var string */
+ protected $userId = 'john';
+
+ public function setUp()
+ {
+ parent::setUp();
+
+ $this->request = $this->createMock(IRequest::class);
+ $this->config = $this->createMock(IConfig::class);
+ $this->time = $this->createMock(ITimeFactory::class);
+ $this->appManager = $this->createMock(IAppManager::class);
+ $this->logger = $this->createMock(ILogger::class);
+ $this->rootFolder = $this->createMock(IRootFolder::class);
+ $this->entropyAnalyzer = $this->createMock(EntropyAnalyzer::class);
+ $this->mapper = $this->createMock(FileOperationMapper::class);
+ $this->fileNameAnalyzer = $this->createMock(FileNameAnalyzer::class);
+ $this->fileCorruptionAnalyzer = $this->createMock(FileCorruptionAnalyzer::class);
+ }
+
+ public function dataAnalyze()
+ {
+ return [
+ ['paths' => ['files/', 'files/'], 'mode' => Monitor::RENAME, 'userAgent' => true, 'timestamp' => time()],
+ ['paths' => ['/admin/files/test/files.extension', 'files/'], 'mode' => Monitor::RENAME, 'userAgent' => false, 'timestamp' => time()],
+ ['paths' => ['/admin/files/test/files.extension', 'files/'], 'mode' => Monitor::RENAME, 'userAgent' => true, 'timestamp' => time()],
+ ['paths' => ['/admin/files/test/files.extension', 'files/'], 'mode' => Monitor::READ, 'userAgent' => true, 'timestamp' => time()],
+ ['paths' => ['/admin/files/test/files.extension', 'files/'], 'mode' => Monitor::WRITE, 'userAgent' => true, 'timestamp' => time()],
+ ['paths' => ['/admin/files/test/files.extension', 'files/'], 'mode' => Monitor::DELETE, 'userAgent' => true, 'timestamp' => time()],
+ ['paths' => ['/admin/files/test/files.extension', 'files/'], 'mode' => 100, 'userAgent' => true, 'timestamp' => time()],
+ ];
+ }
+
+ /**
+ * @dataProvider dataAnalyze
+ *
+ * @param array $paths
+ * @param int $mode
+ * @param bool $userAgent
+ * @param int $timestamp
+ */
+ public function testAnalyze($paths, $mode, $userAgent, $timestamp)
+ {
+ $monitor = $this->getMockBuilder(Monitor::class)
+ ->setConstructorArgs([$this->request, $this->config, $this->time,
+ $this->appManager, $this->logger, $this->rootFolder,
+ $this->entropyAnalyzer, $this->mapper, $this->fileNameAnalyzer,
+ $this->fileCorruptionAnalyzer, $this->userId])
+ ->setMethods(['isUploadedFile', 'isCreatingSkeletonFiles', 'classifySequence', 'resetProfindCount', 'triggerAsyncAnalysis'])
+ ->getMock();
+
+ $storage = $this->createMock(IStorage::class);
+
+ $monitor->expects($this->any())
+ ->method('isUploadedFile')
+ ->with($storage, $paths[0])
+ ->willReturn(true);
+
+ $monitor->expects($this->any())
+ ->method('isCreatingSkeletonFiles')
+ ->willReturn(false);
+
+ $monitor->expects($this->any())
+ ->method('classifySequence');
+
+ $monitor->expects($this->any())
+ ->method('resetProfindCount');
+
+ $monitor->expects($this->any())
+ ->method('triggerAsyncAnalysis');
+
+ $entropyResult = new EntropyResult(EntropyResult::COMPRESSED, 7.99, 0.004);
+
+ $this->entropyAnalyzer->method('analyze')
+ ->willReturn($entropyResult);
+
+ $fileNameResult = new FileNameResult(FileNameResult::NORMAL, true, 4.0);
+
+ $this->fileNameAnalyzer->method('analyze')
+ ->willReturn($fileNameResult);
+
+ $this->request->method('isUserAgent')
+ ->willReturn($userAgent);
+
+ $node = $this->createMock(File::class);
+ $node->method('getInternalPath')
+ ->willReturn('/admin/files/test.file');
+
+ $userRoot = $this->createMock(Folder::class);
+ $userRoot->method('get')
+ ->willReturn($node);
+
+ $folder = $this->createMock(Folder::class);
+ $folder->method('getParent')
+ ->willReturn($userRoot);
+
+ $this->rootFolder->method('getUserFolder')
+ ->willReturn($folder);
+
+ $fileOperation = new FileOperation();
+ $fileOperation->setTimestamp($timestamp);
+
+ $entity = new FileOperation();
+ $entity->id = 1;
+
+ $this->mapper->method('insert')
+ ->willReturn($entity);
+
+ $fileCorruptionResult = new FileCorruptionResult(true);
+ $this->fileCorruptionAnalyzer->method('analyze')
+ ->willReturn($fileCorruptionResult);
+
+ $monitor->analyze($storage, $paths, $mode);
+ $this->assertTrue(true);
+ }
+
+ /**
+ * @dataProvider dataAnalyze
+ *
+ * @param array $paths
+ * @param int $mode
+ * @param bool $userAgent
+ * @param int $timestamp
+ */
+ public function testAnalyzeNotFoundException($paths, $mode, $userAgent, $timestamp)
+ {
+ $monitor = $this->getMockBuilder(Monitor::class)
+ ->setConstructorArgs([$this->request, $this->config, $this->time,
+ $this->appManager, $this->logger, $this->rootFolder,
+ $this->entropyAnalyzer, $this->mapper, $this->fileNameAnalyzer,
+ $this->fileCorruptionAnalyzer, $this->userId])
+ ->setMethods(['isUploadedFile', 'isCreatingSkeletonFiles', 'triggerAsyncAnalysis', 'resetProfindCount'])
+ ->getMock();
+
+ $storage = $this->createMock(IStorage::class);
+
+ $monitor->expects($this->any())
+ ->method('isUploadedFile')
+ ->with($storage, $paths[0])
+ ->willReturn(true);
+
+ $monitor->expects($this->any())
+ ->method('isCreatingSkeletonFiles')
+ ->willReturn(false);
+
+ $this->request->method('isUserAgent')
+ ->willReturn($userAgent);
+
+ $monitor->expects($this->any())
+ ->method('resetProfindCount');
+
+ $monitor->expects($this->any())
+ ->method('triggerAsyncAnalysis');
+
+ $node = $this->createMock(Folder::class);
+ $node->method('getInternalPath')
+ ->willReturn('/admin/files/test.file');
+
+ $userRoot = $this->createMock(Folder::class);
+ $userRoot->method('get')
+ ->willReturn($node);
+
+ $folder = $this->createMock(Folder::class);
+ $folder->method('getParent')
+ ->willReturn($userRoot);
+
+ $this->rootFolder->method('getUserFolder')
+ ->willReturn($folder);
+
+ $fileOperation = new FileOperation();
+ $fileOperation->setTimestamp($timestamp);
+
+ $entity = new FileOperation();
+ $entity->id = 1;
+
+ $this->mapper->method('insert')
+ ->willReturn($entity);
+
+ $fileCorruptionResult = new FileCorruptionResult(true);
+ $this->fileCorruptionAnalyzer->method('analyze')
+ ->willReturn($fileCorruptionResult);
+
+ $monitor->analyze($storage, $paths, $mode);
+ $this->assertTrue(true);
+ }
+
+ public function dataGetFileSize()
+ {
+ return [
+ ['path' => '/files_trashbin/test.jpg', 'size' => 10],
+ ['path' => '/files/test.jpg', 'size' => 10],
+ ];
+ }
+
+ /**
+ * @dataProvider dataGetFileSize
+ *
+ * @param string $path
+ * @param int $size
+ */
+ public function testGetFileSize($path, $size)
+ {
+ $getFileSize = self::getMethod('getFileSize');
+
+ $monitor = new Monitor($this->request, $this->config, $this->time,
+ $this->appManager, $this->logger, $this->rootFolder,
+ $this->entropyAnalyzer, $this->mapper, $this->fileNameAnalyzer,
+ $this->fileCorruptionAnalyzer, $this->userId);
+
+ $node = $this->createMock(File::class);
+ $node->method('getSize')
+ ->willReturn($size);
+
+ $this->rootFolder->method('get')
+ ->willReturn($node);
+
+ $folder = $this->createMock(Folder::class);
+ $userRoot = $this->createMock(Folder::class);
+ $folder->method('getParent')
+ ->willReturn($userRoot);
+
+ $userRoot->method('get')
+ ->willReturn($node);
+
+ $this->rootFolder->method('getUserFolder')
+ ->willReturn($folder);
+
+ $this->assertEquals($getFileSize->invokeArgs($monitor, [$path]), $size);
+ }
+
+ public function dataGetFileSizeNotFoundException()
+ {
+ return [
+ ['path' => '/files_trashbin/test.jpg'],
+ ['path' => '/files/test.jpg'],
+ ];
+ }
+
+ /**
+ * @expectedException OCP\Files\NotFoundException
+ * @dataProvider dataGetFileSizeNotFoundException
+ *
+ * @param string $path
+ */
+ public function testGetFileSizeNotFoundException($path)
+ {
+ $getFileSize = self::getMethod('getFileSize');
+
+ $monitor = new Monitor($this->request, $this->config, $this->time,
+ $this->appManager, $this->logger, $this->rootFolder,
+ $this->entropyAnalyzer, $this->mapper, $this->fileNameAnalyzer,
+ $this->fileCorruptionAnalyzer, $this->userId);
+
+ $node = $this->createMock(Folder::class);
+
+ $this->rootFolder->method('get')
+ ->willReturn($node);
+
+ $folder = $this->createMock(Folder::class);
+ $userRoot = $this->createMock(Folder::class);
+ $folder->method('getParent')
+ ->willReturn($userRoot);
+
+ $userRoot->method('get')
+ ->willReturn($node);
+
+ $this->rootFolder->method('getUserFolder')
+ ->willReturn($folder);
+
+ $getFileSize->invokeArgs($monitor, [$path]);
+ }
+
+ public function dataIsUploadedFile()
+ {
+ return [
+ ['path' => '/files/files.ocTransferId1234', 'return' => false],
+ ['path' => '/files/files.extension', 'return' => false],
+ ['path' => '/admin/files/test/files.extension', 'return' => true],
+ ['path' => '/admin/thumbnails/test/files.extension', 'return' => true],
+ ['path' => '/admin/files_versions/test/files.extension', 'return' => true],
+ ];
+ }
+
+ /**
+ * @dataProvider dataIsUploadedFile
+ *
+ * @param string $path
+ * @param bool $return
+ */
+ public function testIsUploadedFile($path, $return)
+ {
+ $monitor = new Monitor($this->request, $this->config, $this->time,
+ $this->appManager, $this->logger, $this->rootFolder,
+ $this->entropyAnalyzer, $this->mapper, $this->fileNameAnalyzer,
+ $this->fileCorruptionAnalyzer, $this->userId);
+
+ $isUploadedFile = self::getMethod('isUploadedFile');
+ $storage = $this->createMock(IStorage::class);
+ $this->assertEquals($isUploadedFile->invokeArgs($monitor, [$storage, $path]), $return);
+ }
+
+ public function testIsCreatingSkeletonFiles()
+ {
+ $monitor = new Monitor($this->request, $this->config, $this->time,
+ $this->appManager, $this->logger, $this->rootFolder,
+ $this->entropyAnalyzer, $this->mapper, $this->fileNameAnalyzer,
+ $this->fileCorruptionAnalyzer, $this->userId);
+
+ $isCreateingSkeletonFiles = self::getMethod('isCreatingSkeletonFiles');
+ $this->assertFalse($isCreateingSkeletonFiles->invokeArgs($monitor, []));
+ }
+
+ /**
+ * Get protected method.
+ *
+ * @param string $name
+ *
+ * @return $method
+ */
+ protected static function getMethod($name)
+ {
+ $class = new \ReflectionClass(Monitor::class);
+ $method = $class->getMethod($name);
+ $method->setAccessible(true);
+
+ return $method;
+ }
+
+ /**
+ * Sets a protected property on a given object via reflection.
+ *
+ * @param $object - instance in which protected value is being modified
+ * @param $property - property on instance being modified
+ * @param $value - new value of the property being modified
+ */
+ public static function setProtectedProperty($object, $property, $value)
+ {
+ $reflection = new \ReflectionClass($object);
+ $reflection_property = $reflection->getProperty($property);
+ $reflection_property->setAccessible(true);
+ $reflection_property->setValue($object, $value);
+ }
+}