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

github.com/undo-ransomware/ransomware_detection.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Controller')
-rw-r--r--lib/Controller/DetectionController.php80
-rw-r--r--lib/Controller/FileOperationController.php296
-rw-r--r--lib/Controller/MonitoringController.php324
-rw-r--r--lib/Controller/PageController.php (renamed from lib/Controller/RecoverController.php)23
-rw-r--r--lib/Controller/RecoveredFileOperationController.php303
-rw-r--r--lib/Controller/ScanController.php447
-rw-r--r--lib/Controller/SettingsController.php (renamed from lib/Controller/BasicController.php)43
7 files changed, 697 insertions, 819 deletions
diff --git a/lib/Controller/DetectionController.php b/lib/Controller/DetectionController.php
new file mode 100644
index 0000000..dc0a527
--- /dev/null
+++ b/lib/Controller/DetectionController.php
@@ -0,0 +1,80 @@
+<?php
+
+/**
+ * @copyright Copyright (c) 2018 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\Controller;
+
+use OCA\RansomwareDetection\AppInfo\Application;
+use OCA\RansomwareDetection\Service\DetectionService;
+use OCP\AppFramework\Http;
+use OCP\AppFramework\Http\JSONResponse;
+use OCP\AppFramework\Controller;
+use OCP\IConfig;
+use OCP\IUserSession;
+use OCP\IRequest;
+
+class DetectionController extends Controller
+{
+ /** @var DetectionService */
+ protected $detectionService;
+
+ /**
+ * @param string $appName
+ * @param IRequest $request
+ * @param DetectionService $detectionService
+ */
+ public function __construct(
+ $appName,
+ IRequest $request,
+ DetectionService $detectionService
+ ) {
+ parent::__construct($appName, $request);
+
+ $this->detectionService = $detectionService;
+ }
+
+ /**
+ * List detections.
+ *
+ * @NoCSRFRequired
+ * @NoAdminRequired
+ *
+ * @return JSONResponse
+ */
+ public function findAll() {
+ $detections = $this->detectionService->getDetections();
+
+ return new JSONResponse($detections, Http::STATUS_OK);
+ }
+
+ /**
+ * Find detection with $id.
+ *
+ * @NoCSRFRequired
+ * @NoAdminRequired
+ *
+ * @return JSONResponse
+ */
+ public function find($id) {
+ $detection = $this->detectionService->getDetection($id);
+
+ return new JSONResponse($detection, Http::STATUS_OK);
+ }
+} \ No newline at end of file
diff --git a/lib/Controller/FileOperationController.php b/lib/Controller/FileOperationController.php
new file mode 100644
index 0000000..1cfb281
--- /dev/null
+++ b/lib/Controller/FileOperationController.php
@@ -0,0 +1,296 @@
+<?php
+
+/**
+ * @copyright Copyright (c) 2018 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\Controller;
+
+use OCA\RansomwareDetection\Monitor;
+use OCA\RansomwareDetection\Classifier;
+use OCA\RansomwareDetection\AppInfo\Application;
+use OCA\RansomwareDetection\Db\FileOperation;
+use OCA\RansomwareDetection\Service\FileOperationService;
+use OCA\Files_Trashbin\Trashbin;
+use OCA\Files_Trashbin\Helper;
+use OCP\AppFramework\Http;
+use OCP\AppFramework\Http\JSONResponse;
+use OCP\AppFramework\Controller;
+use OCP\Files\File;
+use OCP\Files\Folder;
+use OCP\IConfig;
+use OCP\IUserSession;
+use OCP\IRequest;
+use OCP\ILogger;
+
+class FileOperationController extends Controller
+{
+ /** @var IConfig */
+ protected $config;
+
+ /** @var IUserSession */
+ protected $userSession;
+
+ /** @var ILogger */
+ protected $logger;
+
+ /** @var Folder */
+ protected $userFolder;
+
+ /** @var FileOperationService */
+ protected $service;
+
+ /** @var Classifier */
+ protected $classifier;
+
+ /** @var string */
+ protected $userId;
+
+ /**
+ * @param string $appName
+ * @param IRequest $request
+ * @param IUserSession $userSession
+ * @param IConfig $config
+ * @param ILogger $logger
+ * @param Folder $userFolder
+ * @param FileOperationService $service
+ * @param Classifier $classifier
+ * @param string $userId
+ */
+ public function __construct(
+ $appName,
+ IRequest $request,
+ IUserSession $userSession,
+ IConfig $config,
+ ILogger $logger,
+ Folder $userFolder,
+ FileOperationService $service,
+ Classifier $classifier,
+ $userId
+ ) {
+ parent::__construct($appName, $request);
+
+ $this->config = $config;
+ $this->userSession = $userSession;
+ $this->userFolder = $userFolder;
+ $this->logger = $logger;
+ $this->service = $service;
+ $this->classifier = $classifier;
+ $this->userId = $userId;
+ }
+
+ /**
+ * Lists the files.
+ *
+ * @NoAdminRequired
+ * @NoCSRFRequired
+ *
+ * @return JSONResponse
+ */
+ public function findAll()
+ {
+ $files = $this->service->findAll();
+
+ foreach ($files as $file) {
+ $this->classifier->classifyFile($file);
+ }
+
+ return new JSONResponse($files, Http::STATUS_OK);
+ }
+
+ /**
+ * Find file with id.
+ *
+ * @NoAdminRequired
+ * @NoCSRFRequired
+ *
+ * @return JSONResponse
+ */
+ public function find($id)
+ {
+ $file = $this->service->find($id);
+
+ $this->classifier->classifyFile($file);
+
+ return new JSONResponse($file, Http::STATUS_OK);
+ }
+
+ /**
+ * Recover files from trashbin or remove them from normal storage.
+ *
+ * @NoAdminRequired
+ * @NoCSRFRequired
+ *
+ * @param array $ids file operation id
+ *
+ * @return JSONResponse
+ */
+ public function recover($ids)
+ {
+ $deleted = 0;
+ $recovered = 0;
+ $filesRecovered = array();
+ $error = false;
+ $badRequest = false;
+
+ foreach ($ids as $id) {
+ try {
+ $file = $this->service->find($id);
+ switch ($file->getCommand()) {
+ case Monitor::WRITE:
+ // Recover new created files by deleting them
+ $filePath = $file->getPath().'/'.$file->getOriginalName();
+ if ($this->deleteFromStorage($filePath)) {
+ $this->service->deleteById($id, true);
+
+ $deleted++;
+ array_push($filesRecovered, $id);
+ } else {
+ // File cannot be deleted
+ $error = true;
+ }
+ break;
+ case Monitor::DELETE:
+ // Recover deleted files by restoring them from the trashbin
+ // It's not necessary to use the real path
+ $dir = '/';
+ $candidate = $this->findCandidateToRestore($dir, $file->getOriginalName());
+ if ($candidate !== null) {
+ $path = $dir.'/'.$candidate['name'].'.d'.$candidate['mtime'];
+ if (Trashbin::restore($path, $candidate['name'], $candidate['mtime']) !== false) {
+ $this->service->deleteById($id, true);
+
+ $recovered++;
+ array_push($filesRecovered, $id);
+ }
+ // File does not exist
+ $badRequest = false;
+ } else {
+ // No candidate found
+ $badRequest = false;
+ }
+ break;
+ case Monitor::RENAME:
+ $this->service->deleteById($id, true);
+
+ $deleted++;
+ array_push($filesRecovered, $id);
+ break;
+ case Monitor::CREATE:
+ // Recover new created files/folders
+ $filePath = $file->getPath().'/'.$file->getOriginalName();
+ if ($this->deleteFromStorage($filePath)) {
+ $this->service->deleteById($id, true);
+
+ $deleted++;
+ array_push($filesRecovered, $id);
+ } else {
+ // File cannot be deleted
+ $error = true;
+ }
+ break;
+ default:
+ // All other commands need no recovery
+ $this->service->deleteById($id, false);
+
+ $deleted++;
+ array_push($filesRecovered, $id);
+ break;
+ }
+ } catch (\OCP\AppFramework\Db\MultipleObjectsReturnedException $exception) {
+ // Found more than one with the same file name
+ $this->logger->debug('recover: Found more than one with the same file name.', array('app' => Application::APP_ID));
+
+ $badRequest = false;
+ } catch (\OCP\AppFramework\Db\DoesNotExistException $exception) {
+ // Nothing found
+ $this->logger->debug('recover: Files does not exist.', array('app' => Application::APP_ID));
+
+ $badRequest = false;
+ }
+ }
+ if ($error) {
+ return new JSONResponse(array('recovered' => $recovered, 'deleted' => $deleted, 'filesRecovered' => $filesRecovered), Http::STATUS_INTERNAL_SERVER_ERROR);
+ }
+ if ($badRequest) {
+ return new JSONResponse(array('recovered' => $recovered, 'deleted' => $deleted, 'filesRecovered' => $filesRecovered), Http::STATUS_BAD_REQUEST);
+ }
+ return new JSONResponse(array('recovered' => $recovered, 'deleted' => $deleted, 'filesRecovered' => $filesRecovered), Http::STATUS_OK);
+ }
+
+ /**
+ * Deletes a file from the storage.
+ *
+ * @param string $path
+ *
+ * @return bool
+ */
+ private function deleteFromStorage($path)
+ {
+ try {
+ $node = $this->userFolder->get($path);
+ if ($node->isDeletable()) {
+ $node->delete();
+ } else {
+ return false;
+ }
+
+ return true;
+ } catch (\OCP\Files\NotFoundException $exception) {
+ // Nothing found
+ $this->logger->debug('deleteFromStorage: Not found exception.', array('app' => Application::APP_ID));
+
+ return true;
+ }
+ }
+
+ /**
+ * Finds a candidate to restore if a file with the specific does not exist.
+ *
+ * @param string $dir
+ * @param string $fileName
+ *
+ * @return FileInfo
+ */
+ private function findCandidateToRestore($dir, $fileName)
+ {
+ $files = array();
+ $trashBinFiles = $this->getTrashFiles($dir);
+
+ foreach ($trashBinFiles as $trashBinFile) {
+ if (strcmp($trashBinFile['name'], $fileName) === 0) {
+ $files[] = $trashBinFile;
+ }
+ }
+
+ return array_pop($files);
+ }
+
+ /**
+ * Workaround for testing.
+ *
+ * @param string $dir
+ *
+ * @return array
+ */
+ private function getTrashFiles($dir)
+ {
+ return Helper::getTrashFiles($dir, $this->userId, 'mtime', false);
+ }
+
+} \ No newline at end of file
diff --git a/lib/Controller/MonitoringController.php b/lib/Controller/MonitoringController.php
deleted file mode 100644
index b309361..0000000
--- a/lib/Controller/MonitoringController.php
+++ /dev/null
@@ -1,324 +0,0 @@
-<?php
-
-/**
- * @copyright Copyright (c) 2018 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\Controller;
-
-use OCA\RansomwareDetection\Monitor;
-use OCA\RansomwareDetection\Classifier;
-use OCA\RansomwareDetection\Analyzer\SequenceAnalyzer;
-use OCA\RansomwareDetection\AppInfo\Application;
-use OCA\RansomwareDetection\Db\FileOperation;
-use OCA\RansomwareDetection\Service\FileOperationService;
-use OCA\Files_Trashbin\Trashbin;
-use OCA\Files_Trashbin\Helper;
-use OCP\AppFramework\Http;
-use OCP\AppFramework\Http\JSONResponse;
-use OCP\AppFramework\OCSController;
-use OCP\Files\File;
-use OCP\Files\Folder;
-use OCP\IConfig;
-use OCP\IUserSession;
-use OCP\IRequest;
-use OCP\ILogger;
-
-class MonitoringController extends OCSController
-{
- /** @var IConfig */
- protected $config;
-
- /** @var IUserSession */
- protected $userSession;
-
- /** @var Classifier */
- protected $classifier;
-
- /** @var ILogger */
- protected $logger;
-
- /** @var Folder */
- protected $userFolder;
-
- /** @var FileOperationService */
- protected $service;
-
- /** @var SequenceAnalyzer */
- protected $sequenceAnalyzer;
-
- /** @var string */
- protected $userId;
-
- /**
- * @param string $appName
- * @param IRequest $request
- * @param IUserSession $userSession
- * @param IConfig $config
- * @param Classifier $classifier
- * @param ILogger $logger
- * @param Folder $userFolder
- * @param FileOperationService $service
- * @param SequenceAnalyzer $sequenceAnalyzer
- * @param string $userId
- */
- public function __construct(
- $appName,
- IRequest $request,
- IUserSession $userSession,
- IConfig $config,
- Classifier $classifier,
- ILogger $logger,
- Folder $userFolder,
- FileOperationService $service,
- SequenceAnalyzer $sequenceAnalyzer,
- $userId
- ) {
- parent::__construct($appName, $request);
-
- $this->config = $config;
- $this->userSession = $userSession;
- $this->classifier = $classifier;
- $this->userFolder = $userFolder;
- $this->logger = $logger;
- $this->service = $service;
- $this->sequenceAnalyzer = $sequenceAnalyzer;
- $this->userId = $userId;
- }
-
- /**
- * Lists the classified files and sequences.
- *
- * @NoAdminRequired
- *
- * @return JSONResponse
- */
- public function listFileOperations()
- {
- $files = $this->service->findAll();
-
- $sequences = [];
-
- // Classify files and put together the sequences.
- foreach ($files as $file) {
- $this->classifier->classifyFile($file);
- $sequences[$file->getSequence()][] = $file;
- }
-
- $result = [];
-
- foreach ($sequences as $sequenceId => $sequence) {
- if (sizeof($sequence) >= $this->config->getAppValue(Application::APP_ID, 'minimum_sequence_length', 0)) {
- usort($sequence, function ($a, $b) {
- return $b->getId() - $a->getId();
- });
- $sequenceResult = $this->sequenceAnalyzer->analyze($sequenceId, $sequence);
- $sequenceInformation = ['id' => $sequenceId, 'suspicionScore' => $sequenceResult->getSuspicionScore(), 'sequence' => $sequence];
- $result[] = $sequenceInformation;
- }
- }
-
- usort($result, function ($a, $b) {
- return $b['id'] - $a['id'];
- });
-
- return new JSONResponse($result, Http::STATUS_ACCEPTED);
- }
-
- /**
- * Exports classification and analysis data.
- *
- * @NoAdminRequired
- * @NoCSRFRequired
- *
- * @param int $sequence
- *
- * @return JSONResponse
- */
- public function export()
- {
- $files = $this->service->findAll();
-
- $sequences = [];
-
- // Classify files and put together the sequences.
- foreach ($files as $file) {
- $this->classifier->classifyFile($file);
- $sequences[$file->getSequence()][] = $file;
- }
-
- $result = [];
-
- foreach ($sequences as $sequenceId => $sequence) {
- if (sizeof($sequence) >= $this->config->getAppValue(Application::APP_ID, 'minimum_sequence_length', 0)) {
- $result[] = $this->sequenceAnalyzer->analyze($sequenceId, $sequence);
- }
- }
-
- return new JSONResponse($result, Http::STATUS_ACCEPTED);
- }
-
- /**
- * Deletes a sequence from the database.
- *
- * @NoAdminRequired
- *
- * @param int $sequence
- *
- * @return JSONResponse
- */
- public function deleteSequence($sequence)
- {
- $files = $this->service->deleteSequenceById($sequence);
-
- return new JSONResponse(['status' => 'success'], Http::STATUS_ACCEPTED);
- }
-
- /**
- * Recover files from trashbin or remove them from normal storage.
- *
- * @NoAdminRequired
- *
- * @param int $id file operation id
- *
- * @return JSONResponse
- */
- public function recover($id)
- {
- try {
- $file = $this->service->find($id);
- if ($file->getCommand() === Monitor::WRITE) {
- // Recover new created files by deleting them
- $filePath = $file->getPath().'/'.$file->getOriginalName();
- if ($this->deleteFromStorage($filePath)) {
- $this->service->deleteById($id);
-
- return new JSONResponse(['status' => 'success', 'id' => $id], Http::STATUS_OK);
- } else {
- return new JSONResponse(['status' => 'error', 'message' => 'File cannot be deleted.'], Http::STATUS_BAD_REQUEST);
- }
- } elseif ($file->getCommand() === Monitor::DELETE) {
- // Recover deleted files by restoring them from the trashbin
- // It's not necessary to use the real path
- $dir = '/';
- $candidate = $this->findCandidateToRestore($dir, $file->getOriginalName());
- if ($candidate !== null) {
- $path = $dir.'/'.$candidate['name'].'.d'.$candidate['mtime'];
- if (Trashbin::restore($path, $candidate['name'], $candidate['mtime']) !== false) {
- $this->service->deleteById($id);
-
- return new JSONResponse(['status' => 'success', 'id' => $id], Http::STATUS_OK);
- }
-
- return new JSONResponse(['status' => 'error', 'message' => 'File does not exist.', 'path' => $path, 'name' => $candidate['name'], 'mtime' => $candidate['mtime']], Http::STATUS_BAD_REQUEST);
- } else {
- return new JSONResponse(['status' => 'error', 'message' => 'No candidate found.'], Http::STATUS_BAD_REQUEST);
- }
- } elseif ($file->getCommand() === Monitor::RENAME) {
- $this->service->deleteById($id);
-
- return new JSONResponse(['status' => 'success', 'id' => $id], Http::STATUS_OK);
- } elseif ($file->getCommand() === Monitor::CREATE) {
- // Recover new created folders
- $filePath = $file->getPath().'/'.$file->getOriginalName();
- if ($this->deleteFromStorage($filePath)) {
- $this->service->deleteById($id);
-
- return new JSONResponse(['status' => 'success', 'id' => $id], Http::STATUS_OK);
- } else {
- return new JSONResponse(['status' => 'error', 'message' => 'File cannot be deleted.'], Http::STATUS_BAD_REQUEST);
- }
- } else {
- // All other commands need no recovery
- $this->service->deleteById($id);
-
- return new JSONResponse(['id' => $id], Http::STATUS_OK);
- }
- } catch (\OCP\AppFramework\Db\MultipleObjectsReturnedException $exception) {
- // Found more than one with the same file name
- $this->logger->debug('recover: Found more than one with the same file name.', array('app' => Application::APP_ID));
-
- return new JSONResponse(['status' => 'error', 'message' => 'Found more than one with the same file name.'], Http::STATUS_BAD_REQUEST);
- } catch (\OCP\AppFramework\Db\DoesNotExistException $exception) {
- // Nothing found
- $this->logger->debug('recover: Files does not exist.', array('app' => Application::APP_ID));
-
- return new JSONResponse(['status' => 'error', 'message' => 'Files does not exist.'], Http::STATUS_BAD_REQUEST);
- }
- }
-
- /**
- * Deletes a file from the storage.
- *
- * @param string $path
- *
- * @return bool
- */
- private function deleteFromStorage($path)
- {
- try {
- $node = $this->userFolder->get($path);
- if ($node->isDeletable()) {
- $node->delete();
- } else {
- return false;
- }
-
- return true;
- } catch (\OCP\Files\NotFoundException $exception) {
- // Nothing found
- $this->logger->debug('deleteFromStorage: Not found exception.', array('app' => Application::APP_ID));
-
- return true;
- }
- }
-
- /**
- * Finds a candidate to restore if a file with the specific does not exist.
- *
- * @param string $dir
- * @param string $fileName
- *
- * @return FileInfo
- */
- private function findCandidateToRestore($dir, $fileName)
- {
- $files = array();
- $trashBinFiles = $this->getTrashFiles($dir);
-
- foreach ($trashBinFiles as $trashBinFile) {
- if (strcmp($trashBinFile['name'], $fileName) === 0) {
- $files[] = $trashBinFile;
- }
- }
-
- return array_pop($files);
- }
-
- /**
- * Workaround for testing.
- *
- * @param string $dir
- *
- * @return array
- */
- private function getTrashFiles($dir)
- {
- return Helper::getTrashFiles($dir, $this->userId, 'mtime', false);
- }
-}
diff --git a/lib/Controller/RecoverController.php b/lib/Controller/PageController.php
index 52497df..6827f5d 100644
--- a/lib/Controller/RecoverController.php
+++ b/lib/Controller/PageController.php
@@ -22,27 +22,23 @@
namespace OCA\RansomwareDetection\Controller;
use OCA\RansomwareDetection\AppInfo\Application;
+use OCA\RansomwareDetection\Service\FileOperationService;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\IRequest;
-class RecoverController extends Controller
+class PageController extends Controller
{
- /** @var int */
- private $userId;
/**
* @param string $appName
* @param IRequest $request
- * @param string $userId
*/
public function __construct(
$appName,
- IRequest $request,
- $userId
+ IRequest $request
) {
parent::__construct($appName, $request);
- $this->userId = $userId;
}
/**
@@ -57,17 +53,4 @@ class RecoverController extends Controller
{
return new TemplateResponse(Application::APP_ID, 'index');
}
-
- /**
- * Scan page.
- *
- * @NoAdminRequired
- * @NoCSRFRequired
- *
- * @return TemplateResponse
- */
- public function scan()
- {
- return new TemplateResponse(Application::APP_ID, 'scan');
- }
}
diff --git a/lib/Controller/RecoveredFileOperationController.php b/lib/Controller/RecoveredFileOperationController.php
new file mode 100644
index 0000000..e17d3c3
--- /dev/null
+++ b/lib/Controller/RecoveredFileOperationController.php
@@ -0,0 +1,303 @@
+<?php
+
+/**
+ * @copyright Copyright (c) 2018 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\Controller;
+
+use OCA\RansomwareDetection\Monitor;
+use OCA\RansomwareDetection\Classifier;
+use OCA\RansomwareDetection\AppInfo\Application;
+use OCA\RansomwareDetection\Db\FileOperation;
+use OCA\RansomwareDetection\Service\RecoveredFileOperationService;
+use OCA\Files_Trashbin\Trashbin;
+use OCA\Files_Trashbin\Helper;
+use OCP\AppFramework\Http;
+use OCP\AppFramework\Http\JSONResponse;
+use OCP\AppFramework\Controller;
+use OCP\Files\File;
+use OCP\Files\Folder;
+use OCP\IConfig;
+use OCP\IUserSession;
+use OCP\IRequest;
+use OCP\ILogger;
+
+class RecoveredFileOperationController extends Controller
+{
+ /** @var IConfig */
+ protected $config;
+
+ /** @var IUserSession */
+ protected $userSession;
+
+ /** @var ILogger */
+ protected $logger;
+
+ /** @var Folder */
+ protected $userFolder;
+
+ /** @var RecoveredFileOperationService */
+ protected $service;
+
+ /** @var Classifier */
+ protected $classifier;
+
+ /** @var string */
+ protected $userId;
+
+ /**
+ * @param string $appName
+ * @param IRequest $request
+ * @param IUserSession $userSession
+ * @param IConfig $config
+ * @param ILogger $logger
+ * @param Folder $userFolder
+ * @param RecoveredFileOperationService $service
+ * @param Classifier $classifier
+ * @param string $userId
+ */
+ public function __construct(
+ $appName,
+ IRequest $request,
+ IUserSession $userSession,
+ IConfig $config,
+ ILogger $logger,
+ Folder $userFolder,
+ RecoveredFileOperationService $service,
+ Classifier $classifier,
+ $userId
+ ) {
+ parent::__construct($appName, $request);
+
+ $this->config = $config;
+ $this->userSession = $userSession;
+ $this->userFolder = $userFolder;
+ $this->logger = $logger;
+ $this->service = $service;
+ $this->classifier = $classifier;
+ $this->userId = $userId;
+ }
+
+ /**
+ * Lists the files.
+ *
+ * @NoAdminRequired
+ * @NoCSRFRequired
+ *
+ * @return JSONResponse
+ */
+ public function findAll()
+ {
+ $files = $this->service->findAll();
+
+ foreach ($files as $file) {
+ $this->classifier->classifyFile($file);
+ }
+
+ return new JSONResponse($files, Http::STATUS_OK);
+ }
+
+ /**
+ * Find file with id.
+ *
+ * @NoAdminRequired
+ * @NoCSRFRequired
+ *
+ * @return JSONResponse
+ */
+ public function find($id)
+ {
+ $file = $this->service->find($id);
+
+ $this->classifier->classifyFile($file);
+
+ return new JSONResponse($file, Http::STATUS_OK);
+ }
+
+ /**
+ * Recover files from trashbin or remove them from normal storage.
+ *
+ * @NoAdminRequired
+ * @NoCSRFRequired
+ *
+ * @param array $ids file operation id
+ *
+ * @return JSONResponse
+ */
+ public function recover($ids)
+ {
+ $deleted = 0;
+ $recovered = 0;
+ $filesRecovered = array();
+ $error = false;
+ $badRequest = false;
+
+ foreach ($ids as $id) {
+ try {
+ $file = $this->service->find($id);
+ switch ($file->getCommand()) {
+ case Monitor::DELETE:
+ // Recover new created files by deleting them
+ $filePath = $file->getPath().'/'.$file->getOriginalName();
+ if ($this->deleteFromStorage($filePath)) {
+ $this->service->deleteById($id);
+
+ $deleted++;
+ array_push($filesRecovered, $id);
+ } else {
+ // File cannot be deleted
+ $error = true;
+ }
+ break;
+ case Monitor::WRITE:
+ // Recover deleted files by restoring them from the trashbin
+ // It's not necessary to use the real path
+ $dir = '/';
+ $candidate = $this->findCandidateToRestore($dir, $file->getOriginalName());
+ if ($candidate !== null) {
+ $path = $dir.'/'.$candidate['name'].'.d'.$candidate['mtime'];
+ if (Trashbin::restore($path, $candidate['name'], $candidate['mtime']) !== false) {
+ $this->service->deleteById($id);
+
+ $recovered++;
+ array_push($filesRecovered, $id);
+ }
+ // File does not exist
+ $badRequest = false;
+ } else {
+ // No candidate found
+ $badRequest = false;
+ }
+ break;
+ case Monitor::RENAME:
+ $this->service->deleteById($id);
+
+ $deleted++;
+ array_push($filesRecovered, $id);
+ break;
+ case Monitor::CREATE:
+ // Recover deleted files by restoring them from the trashbin
+ // It's not necessary to use the real path
+ $dir = '/';
+ $candidate = $this->findCandidateToRestore($dir, $file->getOriginalName());
+ if ($candidate !== null) {
+ $path = $dir.'/'.$candidate['name'].'.d'.$candidate['mtime'];
+ if (Trashbin::restore($path, $candidate['name'], $candidate['mtime']) !== false) {
+ $this->service->deleteById($id);
+
+ $recovered++;
+ array_push($filesRecovered, $id);
+ }
+ // File does not exist
+ $badRequest = false;
+ } else {
+ // No candidate found
+ $badRequest = false;
+ }
+ break;
+ default:
+ // All other commands need no recovery
+ $this->service->deleteById($id);
+
+ $deleted++;
+ array_push($filesRecovered, $id);
+ break;
+ }
+ } catch (\OCP\AppFramework\Db\MultipleObjectsReturnedException $exception) {
+ // Found more than one with the same file name
+ $this->logger->debug('recover: Found more than one with the same file name.', array('app' => Application::APP_ID));
+
+ $badRequest = false;
+ } catch (\OCP\AppFramework\Db\DoesNotExistException $exception) {
+ // Nothing found
+ $this->logger->debug('recover: Files does not exist.', array('app' => Application::APP_ID));
+
+ $badRequest = false;
+ }
+ }
+ if ($error) {
+ return new JSONResponse(array('recovered' => $recovered, 'deleted' => $deleted, 'filesRecovered' => $filesRecovered), Http::STATUS_INTERNAL_SERVER_ERROR);
+ }
+ if ($badRequest) {
+ return new JSONResponse(array('recovered' => $recovered, 'deleted' => $deleted, 'filesRecovered' => $filesRecovered), Http::STATUS_BAD_REQUEST);
+ }
+ return new JSONResponse(array('recovered' => $recovered, 'deleted' => $deleted, 'filesRecovered' => $filesRecovered), Http::STATUS_OK);
+ }
+
+ /**
+ * Deletes a file from the storage.
+ *
+ * @param string $path
+ *
+ * @return bool
+ */
+ private function deleteFromStorage($path)
+ {
+ try {
+ $node = $this->userFolder->get($path);
+ if ($node->isDeletable()) {
+ $node->delete();
+ } else {
+ return false;
+ }
+
+ return true;
+ } catch (\OCP\Files\NotFoundException $exception) {
+ // Nothing found
+ $this->logger->debug('deleteFromStorage: Not found exception.', array('app' => Application::APP_ID));
+
+ return true;
+ }
+ }
+
+ /**
+ * Finds a candidate to restore if a file with the specific does not exist.
+ *
+ * @param string $dir
+ * @param string $fileName
+ *
+ * @return FileInfo
+ */
+ private function findCandidateToRestore($dir, $fileName)
+ {
+ $files = array();
+ $trashBinFiles = $this->getTrashFiles($dir);
+
+ foreach ($trashBinFiles as $trashBinFile) {
+ if (strcmp($trashBinFile['name'], $fileName) === 0) {
+ $files[] = $trashBinFile;
+ }
+ }
+
+ return array_pop($files);
+ }
+
+ /**
+ * Workaround for testing.
+ *
+ * @param string $dir
+ *
+ * @return array
+ */
+ private function getTrashFiles($dir)
+ {
+ return Helper::getTrashFiles($dir, $this->userId, 'mtime', false);
+ }
+
+} \ No newline at end of file
diff --git a/lib/Controller/ScanController.php b/lib/Controller/ScanController.php
deleted file mode 100644
index a7eca58..0000000
--- a/lib/Controller/ScanController.php
+++ /dev/null
@@ -1,447 +0,0 @@
-<?php
-
-/**
- * @copyright Copyright (c) 2018 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\Controller;
-
-use OCA\RansomwareDetection\Monitor;
-use OCA\RansomwareDetection\Classifier;
-use OCA\RansomwareDetection\Analyzer\SequenceAnalyzer;
-use OCA\RansomwareDetection\Analyzer\EntropyAnalyzer;
-use OCA\RansomwareDetection\Analyzer\FileCorruptionAnalyzer;
-use OCA\RansomwareDetection\Analyzer\FileExtensionAnalyzer;
-use OCA\RansomwareDetection\Analyzer\FileExtensionResult;
-use OCA\RansomwareDetection\AppInfo\Application;
-use OCA\RansomwareDetection\Db\FileOperation;
-use OCA\RansomwareDetection\Exception\NotAFileException;
-use OCA\RansomwareDetection\Service\FileOperationService;
-use OCA\RansomwareDetection\Scanner\StorageStructure;
-use OCP\Files\NotFoundException;
-use OCA\Files_Trashbin\Trashbin;
-use OCA\Files_Trashbin\Helper;
-use OCP\AppFramework\Http;
-use OCP\AppFramework\Http\JSONResponse;
-use OCP\AppFramework\OCSController;
-use OCP\Files\File;
-use OCP\Files\Folder;
-use OCP\IConfig;
-use OCP\IUserSession;
-use OCP\IRequest;
-use OCP\IDBConnection;
-use OCP\ILogger;
-
-class ScanController extends OCSController
-{
- /** @var IConfig */
- protected $config;
-
- /** @var IUserSession */
- protected $userSession;
-
- /** @var Classifier */
- protected $classifier;
-
- /** @var ILogger */
- protected $logger;
-
- /** @var Folder */
- protected $userFolder;
-
- /** @var FileOperationService */
- protected $service;
-
- /** @var SequenceAnalyzer */
- protected $sequenceAnalyzer;
-
- /** @var EntropyAnalyzer */
- protected $entropyAnalyzer;
-
- /** @var FileCorruptionAnalyzer */
- protected $fileCorruptionAnalyzer;
-
- /** @var FileExtensionAnalyzer */
- protected $fileExtensionAnalyzer;
-
- /** @var IDBConnection */
- protected $connection;
-
- /** @var string */
- protected $userId;
-
- /**
- * @param string $appName
- * @param IRequest $request
- * @param IUserSession $userSession
- * @param IConfig $config
- * @param Classifier $classifier
- * @param ILogger $logger
- * @param Folder $userFolder
- * @param FileOperationService $service
- * @param SequenceAnalyzer $sequenceAnalyzer
- * @param EntropyAnalyzer $entropyAnalyzer
- * @param FileCorruptionAnalyzer $fileCorruptionAnalyzer
- * @param FileExtensionAnalyzer $fileExtensionAnalyzer
- * @param IDBConnection $connection
- * @param string $userId
- */
- public function __construct(
- $appName,
- IRequest $request,
- IUserSession $userSession,
- IConfig $config,
- Classifier $classifier,
- ILogger $logger,
- Folder $userFolder,
- FileOperationService $service,
- SequenceAnalyzer $sequenceAnalyzer,
- EntropyAnalyzer $entropyAnalyzer,
- FileCorruptionAnalyzer $fileCorruptionAnalyzer,
- FileExtensionAnalyzer $fileExtensionAnalyzer,
- IDBConnection $connection,
- $userId
- ) {
- parent::__construct($appName, $request);
-
- $this->config = $config;
- $this->userSession = $userSession;
- $this->classifier = $classifier;
- $this->userFolder = $userFolder;
- $this->logger = $logger;
- $this->service = $service;
- $this->sequenceAnalyzer = $sequenceAnalyzer;
- $this->entropyAnalyzer = $entropyAnalyzer;
- $this->fileCorruptionAnalyzer = $fileCorruptionAnalyzer;
- $this->fileExtensionAnalyzer = $fileExtensionAnalyzer;
- $this->connection = $connection;
- $this->userId = $userId;
- }
-
- /**
- * Post scan recovery.
- *
- * @NoAdminRequired
- *
- * @param integer $id
- * @param integer $sequence
- * @param integer $command
- * @param string $path
- * @param string $name
- * @param integer $timestamp
- *
- * @return JSONResponse
- */
- public function recover($id, $sequence, $command, $path, $name, $timestamp)
- {
- if ($command === Monitor::WRITE) {
- // Delete file
- if ($this->deleteFromStorage($path . '/' . $name)) {
- return new JSONResponse(['status' => 'success', 'id' => $id, 'sequence' => $sequence], Http::STATUS_OK);
- } else {
- return new JSONResponse(['status' => 'error', 'message' => 'File cannot be deleted.'], Http::STATUS_OK);
- }
- } else if ($command === Monitor::DELETE) {
- // Restore file
- $trashPath = '/'.$name.'.d'.$timestamp;;
- if ($this->restoreFromTrashbin($trashPath, $name, $timestamp) !== false) {
- return new JSONResponse(['status' => 'success', 'id' => $id, 'sequence' => $sequence], Http::STATUS_OK);
- }
-
- return new JSONResponse(['status' => 'error', 'message' => 'File does not exist.', 'path' => $trashPath, 'name' => $name, 'mtime' => $timestamp], Http::STATUS_OK);
- } else {
- // Scan can only detect WRITE and DELETE this should never happen.
- $this->logger->error('postRecover: RENAME or CREATE operation.', array('app' => Application::APP_ID));
- return new JSONResponse(['status' => 'error', 'message' => 'Wrong command.'], Http::STATUS_BAD_REQUEST);
- }
-
- }
-
- /**
- * The files to scan.
- *
- * @NoAdminRequired
- *
- * @return JSONResponse
- */
- public function filesToScan()
- {
- $start = time();
- $storageStructure = $this->getStorageStructure($this->userFolder);
- $trashStorageStructure = $this->getTrashStorageStructure();
-
- $allFiles = array();
-
- // convert file to json and merge into one array
- $files = $storageStructure->getFiles();
- for ($i = 0; $i < count($files); $i++) {
- $allFiles[] = ['id' => $files[$i]->getId(), 'path' => $files[$i]->getInternalPath(), 'timestamp' => $this->getLastActivity($files[$i]->getId())['timestamp']];
- }
- $trashFiles = $trashStorageStructure->getFiles();
- for ($i = 0; $i < count($trashFiles); $i++) {
- $allFiles[] = ['id' => $trashFiles[$i]->getId(), 'path' => $trashFiles[$i]->getInternalPath(), 'timestamp' => $trashFiles[$i]->getMtime()];
- }
-
- // sort ASC for timestamp
- usort($allFiles, function ($a, $b) {
- if ($a['timestamp'] === $b['timestamp']) {
- return 0;
- }
- return $a['timestamp'] - $b['timestamp'];
- });
-
- // build sequences
- $sequencesArray = array();
- $sequence = array();
- for ($i = 0; $i < count($allFiles); $i++) {
- if ($i === 0) {
- $sequence = array();
- } else {
- if ($allFiles[$i]['timestamp'] - $allFiles[$i - 1]['timestamp'] > 180) {
- $sequencesArray[] = $sequence;
- $sequence = array();
- }
- }
- $sequence[] = $allFiles[$i];
- }
- $sequencesArray[] = $sequence;
- $end = time();
-
- return new JSONResponse(['status' => 'success', 'sequences' => $sequencesArray, 'numberOfFiles' => $storageStructure->getNumberOfFiles(), 'scanDuration' => $end - $start], Http::STATUS_OK);
- }
-
- /**
- * Scan sequence.
- *
- * @NoAdminRequired
- *
- * @param string $sequence
- * @return JSONResponse
- */
- public function scanSequence($sequence) {
- if (sizeof($sequence) > $this->config->getAppValue(Application::APP_ID, 'minimum_sequence_length', 0)) {
- $sequenceResults = array();
- foreach ($sequence as $file) {
- try {
- $fileOperation = $this->buildFileOperation($file);
- } catch (NotAFileException $exception) {
- $this->logger->debug('scanSequence: Path to file doesn\'t lead to file object.', array('app' => Application::APP_ID));
- continue;
- } catch (NotFoundException $exception) {
- $this->logger->debug('scanSequence: Not found.', array('app' => Application::APP_ID));
- continue;
- }
-
- $this->classifier->classifyFile($fileOperation);
- $jsonSequence[] = ['userId' => $fileOperation->getUserId(), 'path' => $fileOperation->getPath(), 'originalName' => preg_replace('/.d[0-9]{10}/', '', $fileOperation->getOriginalName()),
- 'type' => $fileOperation->getType(), 'mimeType' => $fileOperation->getMimeType(), 'size' => $fileOperation->getSize(), 'corrupted' => $fileOperation->getCorrupted(), 'timestamp' => $fileOperation->getTimestamp(), 'entropy' => $fileOperation->getEntropy(),
- 'standardDeviation' => $fileOperation->getStandardDeviation(), 'command' => $fileOperation->getCommand(), 'fileClass' => $fileOperation->getFileClass(), 'fileExtensionClass' => $fileOperation->getFileExtensionClass(), 'suspicionClass' => $fileOperation->getSuspicionClass()];
- $fileOperationSequence[] = $fileOperation;
- }
- if (sizeof($fileOperationSequence) > 0) {
- $sequenceResult = $this->sequenceAnalyzer->analyze(0, $fileOperationSequence);
- return new JSONResponse(['status' => 'success', 'suspicionScore' => $sequenceResult->getSuspicionScore(), 'sequence' => $jsonSequence], Http::STATUS_OK);
- } else {
- return new JSONResponse(['status' => 'error', 'message' => 'The file(s) requested do(es) not exist.']);
- }
- } else {
- return new JSONResponse(['status' => 'error', 'message' => 'Sequence is to short.'], Http::STATUS_OK);
- }
- }
-
- /**
- * Just for testing purpose to mock the external static method.
- *
- * @return array
- */
- protected function getTrashFiles() {
- return Helper::getTrashFiles("/", $this->userId, 'mtime', false);
- }
-
- /**
- * Just for testing purpose to mock the external static method.
- *
- * @param string $trashPath
- * @param array $pathInfo
- * @param integer $timestamp
- * @return boolean
- */
- protected function restoreFromTrashbin($trashPath, $name, $timestamp)
- {
- return Trashbin::restore($trashPath, $name, $timestamp);
- }
-
- /**
- * Get last activity.
- * Visibility 'protected' is that it's possible to mock the database access.
- *
- * @param $objectId
- */
- protected function getLastActivity($objectId)
- {
- $query = $this->connection->getQueryBuilder();
- $query->select('*')->from('activity');
- $query->where($query->expr()->eq('affecteduser', $query->createNamedParameter($this->userId)))
- ->andWhere($query->expr()->eq('object_id', $query->createNamedParameter($objectId)));
- $result = $query->execute();
- while ($row = $result->fetch()) {
- $rows[] = $row;
- }
- $result->closeCursor();
- if (isset($rows) && is_array($rows)) {
- return array_pop($rows);
- } else {
- $this->logger->debug('getLastActivity: No activity found.', array('app' => Application::APP_ID));
- return 0;
- }
- }
-
- /**
- * Builds a file operations from a file info array.
- *
- * @param array $file
- * @return FileOperation
- */
- private function buildFileOperation($file)
- {
- $fileOperation = new FileOperation();
- $fileOperation->setUserId($this->userId);
- if (strpos($file['path'], 'files_trashbin') !== false) {
- $node = $this->userFolder->getParent()->get($file['path'] . '.d' . $file['timestamp']);
- $fileOperation->setCommand(Monitor::DELETE);
- $fileOperation->setTimestamp($file['timestamp']);
- $pathInfo = pathinfo($node->getInternalPath());
- $fileOperation->setPath($pathInfo['dirname']);
- } else {
- $node = $this->userFolder->getParent()->get($file['path']);
- $lastActivity = $this->getLastActivity($file['id']);
- $fileOperation->setCommand(Monitor::WRITE);
- $fileOperation->setTimestamp($lastActivity['timestamp']);
- $pathInfo = pathinfo($node->getInternalPath());
- $fileOperation->setPath(str_replace('files', '', $pathInfo['dirname']));
- }
- if (!($node instanceof File)) {
- throw new NotAFileException();
- }
- $fileOperation->setOriginalName($node->getName());
- $fileOperation->setType('file');
- $fileOperation->setMimeType($node->getMimeType());
- $fileOperation->setSize($node->getSize());
- $fileOperation->setTimestamp($file['timestamp']);
-
- // file extension analysis
- $fileExtensionResult = $this->fileExtensionAnalyzer->analyze($node->getInternalPath());
- $fileOperation->setFileExtensionClass($fileExtensionResult->getFileExtensionClass());
-
- $fileCorruptionResult = $this->fileCorruptionAnalyzer->analyze($node);
- $isCorrupted = $fileCorruptionResult->isCorrupted();
- $fileOperation->setCorrupted($isCorrupted);
- if ($isCorrupted) {
- $fileOperation->setFileExtensionClass(FileExtensionResult::SUSPICIOUS);
- }
-
- // entropy analysis
- $entropyResult = $this->entropyAnalyzer->analyze($node);
- $fileOperation->setEntropy($entropyResult->getEntropy());
- $fileOperation->setStandardDeviation($entropyResult->getStandardDeviation());
- $fileOperation->setFileClass($entropyResult->getFileClass());
-
- return $fileOperation;
- }
-
- /**
- * Get trash storage structure.
- *
- * @return StorageStructure
- */
- private function getTrashStorageStructure()
- {
- $storageStructure = new StorageStructure(0, []);
- $nodes = $this->getTrashFiles();
- foreach ($nodes as $node) {
- $storageStructure->addFile($node);
- $storageStructure->increaseNumberOfFiles();
- }
- return $storageStructure;
- }
-
- /**
- * Get storage structure recursively.
- *
- * @param INode $node
- *
- * @return StorageStructure
- */
- private function getStorageStructure($node)
- {
- // set count for node to 0
- $storageStructure = new StorageStructure(0, []);
- if ($node instanceof Folder) {
- // it's a folder
- $nodes = $node->getDirectoryListing();
- if (count($nodes) === 0) {
- // folder is empty so nothing to do
- return $storageStructure;
- }
- foreach ($nodes as $tmpNode) {
- // analyse files in subfolder
- $tmpStorageStructure = $this->getStorageStructure($tmpNode);
- $storageStructure->setFiles(array_merge($storageStructure->getFiles(), $tmpStorageStructure->getFiles()));
- $storageStructure->setNumberOfFiles($storageStructure->getNumberOfFiles() + $tmpStorageStructure->getNumberOfFiles());
- }
- return $storageStructure;
- }
- else if ($node instanceof File) {
- // it's a file
- $storageStructure->addFile($node);
- $storageStructure->increaseNumberOfFiles();
- return $storageStructure;
- }
- else {
- // it's me Mario.
- // there is nothing else than file or folder
- $this->logger->error('getStorageStructure: Neither file nor folder.', array('app' => Application::APP_ID));
- }
- }
-
- /**
- * Deletes a file from the storage.
- *
- * @param string $path
- *
- * @return bool
- */
- private function deleteFromStorage($path)
- {
- try {
- $node = $this->userFolder->get($path);
- if ($node instanceof File && $node->isDeletable()) {
- $node->delete();
- } else {
- return false;
- }
-
- return true;
- } catch (\OCP\Files\NotFoundException $exception) {
- // Nothing found
- $this->logger->debug('deleteFromStorage: Not found exception.', array('app' => Application::APP_ID));
-
- return true;
- }
- }
-}
diff --git a/lib/Controller/BasicController.php b/lib/Controller/SettingsController.php
index 2d72f50..dd00909 100644
--- a/lib/Controller/BasicController.php
+++ b/lib/Controller/SettingsController.php
@@ -22,14 +22,15 @@
namespace OCA\RansomwareDetection\Controller;
use OCA\RansomwareDetection\AppInfo\Application;
+use OCA\RansomwareDetection\Model\Settings;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\JSONResponse;
-use OCP\AppFramework\OCSController;
+use OCP\AppFramework\Controller;
use OCP\IConfig;
use OCP\IUserSession;
use OCP\IRequest;
-class BasicController extends OCSController
+class SettingsController extends Controller
{
/** @var IConfig */
protected $config;
@@ -62,46 +63,32 @@ class BasicController extends OCSController
}
/**
- * Get debug mode.
+ * Get settings.
*
+ * @NoCSRFRequired
* @NoAdminRequired
*
* @return JSONResponse
*/
- public function getDebugMode()
- {
- $debugMode = $this->config->getAppValue(Application::APP_ID, 'debug', 0);
+ public function findAll() {
+ $debug = $this->config->getAppValue(Application::APP_ID, 'debug', 0);
+ $color = $this->config->getUserValue($this->userId, Application::APP_ID, 'color_mode', 0);
+ $settings = new Settings($debug, $color);
- return new JSONResponse(['status' => 'success', 'message' => 'Get debug mode.', 'debugMode' => $debugMode], Http::STATUS_ACCEPTED);
+ return new JSONResponse($settings, Http::STATUS_OK);
}
/**
- * Get color mode.
+ * Set settings.
*
+ * @NoCSRFRequired
* @NoAdminRequired
*
* @return JSONResponse
*/
- public function getColorMode()
- {
- $colorMode = $this->config->getUserValue($this->userId, Application::APP_ID, 'color_mode', 0);
+ public function update($color, $debug) {
+ $this->config->setUserValue($this->userId, Application::APP_ID, 'color_mode', $color);
- return new JSONResponse(['status' => 'success', 'message' => 'Get color mode.', 'colorMode' => $colorMode], Http::STATUS_ACCEPTED);
- }
-
- /**
- * Changes color mode.
- *
- * @NoAdminRequired
- *
- * @param int $colorMode
- *
- * @return JSONResponse
- */
- public function changeColorMode($colorMode)
- {
- $this->config->setUserValue($this->userId, Application::APP_ID, 'color_mode', $colorMode);
-
- return new JSONResponse(['status' => 'success', 'message' => 'Color mode changed.'], Http::STATUS_ACCEPTED);
+ return new JSONResponse(null, Http::STATUS_OK);
}
}