RequestPlugin::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 18
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 8
c 1
b 0
f 0
nc 1
nop 8
dl 0
loc 18
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\Connector\Sabre;
23
24
use OCA\RansomwareDetection\Classifier;
25
use OCA\RansomwareDetection\AppInfo\Application;
26
use OCA\RansomwareDetection\Analyzer\SequenceAnalyzer;
27
use OCA\RansomwareDetection\Service\FileOperationService;
28
use OCP\Notification\IManager;
0 ignored issues
show
Bug introduced by
The type OCP\Notification\IManager 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...
29
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...
30
use OCP\ISession;
0 ignored issues
show
Bug introduced by
The type OCP\ISession 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\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...
32
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...
33
use Sabre\DAV\Server;
0 ignored issues
show
Bug introduced by
The type Sabre\DAV\Server 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 Sabre\DAV\ServerPlugin;
0 ignored issues
show
Bug introduced by
The type Sabre\DAV\ServerPlugin 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 Sabre\HTTP\RequestInterface;
0 ignored issues
show
Bug introduced by
The type Sabre\HTTP\RequestInterface 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 Sabre\HTTP\ResponseInterface;
0 ignored issues
show
Bug introduced by
The type Sabre\HTTP\ResponseInterface 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
38
class RequestPlugin extends ServerPlugin
39
{
40
    /** @var Server */
41
    protected $server;
42
43
    /** @var ILogger */
44
    protected $logger;
45
46
    /** @var IConfig */
47
    protected $config;
48
49
    /** @var IUserSession */
50
    protected $userSession;
51
52
    /** @var ISession */
53
    protected $session;
54
55
    /** @var FileOperationService */
56
    protected $service;
57
58
    /** @var IManager */
59
    protected $notifications;
60
61
    /** @var Classifier */
62
    protected $classifier;
63
64
    /** @var SequenceAnalyzer */
65
    protected $sequenceAnalyzer;
66
67
    const PROPFIND_COUNT = 6;
68
69
    /**
70
     * @param ILogger              $logger
71
     * @param IConfig              $config
72
     * @param IUserSession         $userSession
73
     * @param ISession             $session
74
     * @param FileOperationService $service
75
     * @param IManager             $notifications
76
     * @param Classifier           $classifer
77
     * @param SequenceAnalyzer     $sequenceAnalyzer
78
     */
79
    public function __construct(
80
        ILogger $logger,
81
        IConfig $config,
82
        IUserSession $userSession,
83
        ISession $session,
84
        FileOperationService $service,
85
        IManager $notifications,
86
        Classifier $classifier,
87
        SequenceAnalyzer $sequenceAnalyzer
88
    ) {
89
        $this->logger = $logger;
90
        $this->config = $config;
91
        $this->userSession = $userSession;
92
        $this->session = $session;
93
        $this->service = $service;
94
        $this->notifications = $notifications;
95
        $this->classifier = $classifier;
96
        $this->sequenceAnalyzer = $sequenceAnalyzer;
97
    }
98
99
    public function initialize(Server $server)
100
    {
101
        $this->server = $server;
102
        $server->on('method:PROPFIND', [$this, 'beforeHttpPropFind'], 100);
103
        $server->on('method:PUT', [$this, 'beforeHttpPut'], 100);
104
        $server->on('method:DELETE', [$this, 'beforeHttpDelete'], 100);
105
        $server->on('method:GET', [$this, 'beforeHttpGet'], 100);
106
        $server->on('method:POST', [$this, 'beforeHttpPost'], 100);
107
    }
108
109
    public function beforeHttpPropFind(RequestInterface $request, ResponseInterface $response)
110
    {
111
        if ($this->userSession !== null && $this->userSession->getUser() !== null) {
112
            // only process the propfind request if there is a active user session
113
            $propfindCount = $this->config->getUserValue($this->userSession->getUser()->getUID(), Application::APP_ID, 'propfind_count:'.$this->session->getId(), 0);
114
            if ($propfindCount + 1 < self::PROPFIND_COUNT) {
115
                // less than PROPFIND_COUNT + 1 PROPFIND requests
116
                $this->config->setUserValue($this->userSession->getUser()->getUID(), Application::APP_ID, 'propfind_count:'.$this->session->getId(), $propfindCount + 1);
117
            } else {
118
                // more than PROPFIND_COUNT PROPFIND requests and no file is uploading
119
                $sequenceId = $this->config->getUserValue($this->userSession->getUser()->getUID(), Application::APP_ID, 'sequence_id', 0);
120
                $sequence = $this->service->findSequenceById([$sequenceId]);
121
                if (sizeof($sequence) > 0) {
122
                    // get old sequence id
123
                    // start a new sequence by increasing the sequence id
124
                    $this->config->setUserValue($this->userSession->getUser()->getUID(), Application::APP_ID, 'sequence_id', $sequenceId + 1);
125
                    $this->config->setUserValue($this->userSession->getUser()->getUID(), Application::APP_ID, 'propfind_count:'.$this->session->getId(), 0);
126
                    $this->classifySequence($sequence);
127
                }
128
            }
129
        }
130
    }
131
132
    public function beforeHttpPut(RequestInterface $request, ResponseInterface $response)
133
    {
134
        // extend if necessary
135
    }
136
137
    public function beforeHttpDelete(RequestInterface $request, ResponseInterface $response)
138
    {
139
        // extend if necessary
140
    }
141
142
    public function beforeHttpGet(RequestInterface $request, ResponseInterface $response)
143
    {
144
        // extend if necessary
145
    }
146
147
    public function beforeHttpPost(RequestInterface $request, ResponseInterface $response)
148
    {
149
        // extend if necessary
150
    }
151
152
    /**
153
     * Triggers a notification.
154
     */
155
    private function triggerNotification($notification)
156
    {
157
        $notification->setApp(Application::APP_ID);
158
        $notification->setDateTime(new \DateTime());
159
        $notification->setObject('ransomware', 'ransomware');
160
        $notification->setSubject('ransomware_attack_detected', []);
161
        $notification->setUser($this->userSession->getUser()->getUID());
162
163
        $this->notifications->notify($notification);
164
    }
165
166
    /**
167
     * Classify sequence and if suspicion level is reached
168
     * trigger a notification.
169
     *
170
     * @param array $sequence
171
     */
172
    private function classifySequence($sequence)
173
    {
174
        $sequenceSuspicionLevel = $this->config->getAppValue(Application::APP_ID, 'suspicion_level', 2);
175
176
        foreach ($sequence as $file) {
177
            $this->classifier->classifyFile($file);
178
        }
179
180
        // sequence suspicion level
181
        if ($sequenceSuspicionLevel === 1) {
182
            $level = 2;
183
        } else {
184
            $level = 4;
185
        }
186
187
        // sequence id is irrelevant so we use 0
188
        $sequenceResult = $this->sequenceAnalyzer->analyze(0, $sequence);
189
        if ($sequenceResult->getSuspicionScore() >= $level) {
190
            $this->triggerNotification($this->notifications->createNotification());
191
        }
192
    }
193
}
194