Passed
Pull Request — master (#39)
by Matthias
08:57
created

RecoveredFileOperationController::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 20
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 1
eloc 8
c 1
b 0
f 1
nc 1
nop 9
dl 0
loc 20
rs 10

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
/**
4
 * @copyright Copyright (c) 2018 Matthias Held <[email protected]>
5
 * @author Matthias Held <[email protected]>
6
 * @license GNU AGPL version 3 or any later version
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Affero General Public License as
10
 * published by the Free Software Foundation, either version 3 of the
11
 * License, or (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU Affero General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Affero General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
namespace OCA\RansomwareDetection\Controller;
23
24
use OCA\RansomwareDetection\Monitor;
25
use OCA\RansomwareDetection\Classifier;
26
use OCA\RansomwareDetection\AppInfo\Application;
27
use OCA\RansomwareDetection\Db\FileOperation;
28
use OCA\RansomwareDetection\Service\RecoveredFileOperationService;
29
use OCA\Files_Trashbin\Trashbin;
0 ignored issues
show
Bug introduced by
The type OCA\Files_Trashbin\Trashbin was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
30
use OCA\Files_Trashbin\Helper;
0 ignored issues
show
Bug introduced by
The type OCA\Files_Trashbin\Helper was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
31
use OCP\AppFramework\Http;
0 ignored issues
show
Bug introduced by
The type OCP\AppFramework\Http was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
32
use OCP\AppFramework\Http\JSONResponse;
0 ignored issues
show
Bug introduced by
The type OCP\AppFramework\Http\JSONResponse was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
33
use OCP\AppFramework\Controller;
0 ignored issues
show
Bug introduced by
The type OCP\AppFramework\Controller was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
34
use OCP\Files\File;
0 ignored issues
show
Bug introduced by
The type OCP\Files\File was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
35
use OCP\Files\Folder;
0 ignored issues
show
Bug introduced by
The type OCP\Files\Folder was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
36
use OCP\IConfig;
0 ignored issues
show
Bug introduced by
The type OCP\IConfig was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
37
use OCP\IUserSession;
0 ignored issues
show
Bug introduced by
The type OCP\IUserSession was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
38
use OCP\IRequest;
0 ignored issues
show
Bug introduced by
The type OCP\IRequest was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
39
use OCP\ILogger;
0 ignored issues
show
Bug introduced by
The type OCP\ILogger was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
40
41
class RecoveredFileOperationController extends Controller
42
{
43
    /** @var IConfig */
44
    protected $config;
45
46
    /** @var IUserSession */
47
    protected $userSession;
48
49
    /** @var ILogger */
50
    protected $logger;
51
52
    /** @var Folder */
53
    protected $userFolder;
54
55
    /** @var RecoveredFileOperationService */
56
    protected $service;
57
58
    /** @var Classifier */
59
    protected $classifier;
60
61
    /** @var string */
62
    protected $userId;
63
64
    /**
65
     * @param string               $appName
66
     * @param IRequest             $request
67
     * @param IUserSession         $userSession
68
     * @param IConfig              $config
69
     * @param ILogger              $logger
70
     * @param Folder               $userFolder
71
     * @param RecoveredFileOperationService $service
72
     * @param Classifier           $classifier
73
     * @param string               $userId
74
     */
75
    public function __construct(
76
        $appName,
77
        IRequest $request,
78
        IUserSession $userSession,
79
        IConfig $config,
80
        ILogger $logger,
81
        Folder $userFolder,
82
        RecoveredFileOperationService $service,
83
        Classifier $classifier,
84
        $userId
85
    ) {
86
        parent::__construct($appName, $request);
87
88
        $this->config = $config;
89
        $this->userSession = $userSession;
90
        $this->userFolder = $userFolder;
91
        $this->logger = $logger;
92
        $this->service = $service;
93
        $this->classifier = $classifier;
94
        $this->userId = $userId;
95
    }
96
97
    /**
98
     * Lists the files.
99
     *
100
     * @NoAdminRequired
101
     * @NoCSRFRequired
102
     *
103
     * @return JSONResponse
104
     */
105
    public function findAll()
106
    {
107
        $files = $this->service->findAll();
108
109
        foreach ($files as $file) {
110
            $this->classifier->classifyFile($file);
111
        }
112
113
        return new JSONResponse($files, Http::STATUS_OK);
114
    }
115
116
    /**
117
     * Find file with id.
118
     *
119
     * @NoAdminRequired
120
     * @NoCSRFRequired
121
     *
122
     * @return JSONResponse
123
     */
124
    public function find($id)
125
    {
126
        $file = $this->service->find($id);
127
128
        $this->classifier->classifyFile($file);
129
130
        return new JSONResponse($file, Http::STATUS_OK);
131
    }
132
133
    /**
134
     * Recover files from trashbin or remove them from normal storage.
135
     *
136
     * @NoAdminRequired
137
     * @NoCSRFRequired
138
     *
139
     * @param array $ids file operation id
140
     *
141
     * @return JSONResponse
142
     */
143
    public function recover($ids)
144
    {
145
        $deleted = 0;
146
        $recovered = 0;
147
        $filesRecovered = array();
148
        $error = false;
149
        $badRequest = false;
150
151
        foreach ($ids as $id) {
152
            try {
153
                $file = $this->service->find($id);
154
                switch ($file->getCommand()) {
155
                    case Monitor::DELETE:
156
                        // Recover new created files by deleting them
157
                        $filePath = $file->getPath().'/'.$file->getOriginalName();
158
                        if ($this->deleteFromStorage($filePath)) {
159
                            $this->service->deleteById($id);
160
161
                            $deleted++;
162
                            array_push($filesRecovered, $id);
163
                        } else {
164
                            // File cannot be deleted
165
                            $error = true;
166
                        }
167
                        break;
168
                    case Monitor::WRITE:
169
                        // Recover deleted files by restoring them from the trashbin
170
                        // It's not necessary to use the real path
171
                        $dir = '/';
172
                        $candidate = $this->findCandidateToRestore($dir, $file->getOriginalName());
173
                        if ($candidate !== null) {
174
                            $path = $dir.'/'.$candidate['name'].'.d'.$candidate['mtime'];
175
                            if (Trashbin::restore($path, $candidate['name'], $candidate['mtime']) !== false) {
176
                                $this->service->deleteById($id);
177
178
                                $recovered++;
179
                                array_push($filesRecovered, $id);
180
                            }
181
                            // File does not exist
182
                            $badRequest = false;
183
                        } else {
184
                            // No candidate found
185
                            $badRequest = false;
186
                        }
187
                        break;
188
                    case Monitor::RENAME:
189
                        $this->service->deleteById($id);
190
191
                        $deleted++;
192
                        array_push($filesRecovered, $id);
193
                        break;
194
                    case Monitor::CREATE:
195
                        // Recover deleted files by restoring them from the trashbin
196
                        // It's not necessary to use the real path
197
                        $dir = '/';
198
                        $candidate = $this->findCandidateToRestore($dir, $file->getOriginalName());
199
                        if ($candidate !== null) {
200
                            $path = $dir.'/'.$candidate['name'].'.d'.$candidate['mtime'];
201
                            if (Trashbin::restore($path, $candidate['name'], $candidate['mtime']) !== false) {
202
                                $this->service->deleteById($id);
203
204
                                $recovered++;
205
                                array_push($filesRecovered, $id);
206
                            }
207
                            // File does not exist
208
                            $badRequest = false;
209
                        } else {
210
                            // No candidate found
211
                            $badRequest = false;
212
                        }
213
                        break;
214
                    default:
215
                        // All other commands need no recovery
216
                        $this->service->deleteById($id);
217
218
                        $deleted++;
219
                        array_push($filesRecovered, $id);
220
                        break;
221
                    }
222
            } catch (\OCP\AppFramework\Db\MultipleObjectsReturnedException $exception) {
0 ignored issues
show
Bug introduced by
The type OCP\AppFramework\Db\Mult...bjectsReturnedException was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
223
                // Found more than one with the same file name
224
                $this->logger->debug('recover: Found more than one with the same file name.', array('app' => Application::APP_ID));
225
226
                $badRequest = false;
227
            } catch (\OCP\AppFramework\Db\DoesNotExistException $exception) {
0 ignored issues
show
Bug introduced by
The type OCP\AppFramework\Db\DoesNotExistException was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
228
                // Nothing found
229
                $this->logger->debug('recover: Files does not exist.', array('app' => Application::APP_ID));
230
231
                $badRequest = false;
232
            }
233
        }
234
        if ($error) {
0 ignored issues
show
introduced by
The condition $error is always false.
Loading history...
235
            return new JSONResponse(array('recovered' => $recovered, 'deleted' => $deleted, 'filesRecovered' => $filesRecovered), Http::STATUS_INTERNAL_SERVER_ERROR);
236
        }
237
        if ($badRequest) {
0 ignored issues
show
introduced by
The condition $badRequest is always false.
Loading history...
238
            return new JSONResponse(array('recovered' => $recovered, 'deleted' => $deleted, 'filesRecovered' => $filesRecovered), Http::STATUS_BAD_REQUEST);
239
        }
240
        return new JSONResponse(array('recovered' => $recovered, 'deleted' => $deleted, 'filesRecovered' => $filesRecovered), Http::STATUS_OK);
241
    }
242
243
    /**
244
     * Deletes a file from the storage.
245
     *
246
     * @param string $path
247
     *
248
     * @return bool
249
     */
250
    private function deleteFromStorage($path)
251
    {
252
        try {
253
            $node = $this->userFolder->get($path);
254
            if ($node->isDeletable()) {
255
                $node->delete();
256
            } else {
257
                return false;
258
            }
259
260
            return true;
261
        } catch (\OCP\Files\NotFoundException $exception) {
0 ignored issues
show
Bug introduced by
The type OCP\Files\NotFoundException was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
262
            // Nothing found
263
            $this->logger->debug('deleteFromStorage: Not found exception.', array('app' => Application::APP_ID));
264
265
            return true;
266
        }
267
    }
268
269
    /**
270
     * Finds a candidate to restore if a file with the specific does not exist.
271
     *
272
     * @param string $dir
273
     * @param string $fileName
274
     *
275
     * @return FileInfo
0 ignored issues
show
Bug introduced by
The type OCA\RansomwareDetection\Controller\FileInfo was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
276
     */
277
    private function findCandidateToRestore($dir, $fileName)
278
    {
279
        $files = array();
280
        $trashBinFiles = $this->getTrashFiles($dir);
281
282
        foreach ($trashBinFiles as $trashBinFile) {
283
            if (strcmp($trashBinFile['name'], $fileName) === 0) {
284
                $files[] = $trashBinFile;
285
            }
286
        }
287
288
        return array_pop($files);
289
    }
290
291
    /**
292
     * Workaround for testing.
293
     *
294
     * @param string $dir
295
     *
296
     * @return array
297
     */
298
    private function getTrashFiles($dir)
299
    {
300
        return Helper::getTrashFiles($dir, $this->userId, 'mtime', false);
301
    }
302
303
}