Completed
Push — master ( ed1dd0...0d6f9c )
by Roeland
9s
created

AvirWrapper::fopen()   B

Complexity

Conditions 7
Paths 5

Size

Total Lines 67
Code Lines 46

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 36.5012

Importance

Changes 2
Bugs 0 Features 0
Metric Value
dl 0
loc 67
ccs 7
cts 45
cp 0.1555
rs 7.0237
c 2
b 0
f 0
cc 7
eloc 46
nc 5
nop 2
crap 36.5012

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Copyright (c) 2014 Victor Dubiniuk <[email protected]>
4
 * This file is licensed under the Affero General Public License version 3 or
5
 * later.
6
 * See the COPYING-README file.
7
 */
8
9
namespace OCA\Files_Antivirus;
10
11
use Icewind\Streams\CallbackWrapper;
12
use OC\Files\Storage\Wrapper\Wrapper;
13
use OCA\Files_Antivirus\Activity\Provider;
14
use OCA\Files_Antivirus\AppInfo\Application;
15
use OCA\Files_Antivirus\Scanner\ScannerFactory;
16
use OCP\App;
17
use OCP\Files\InvalidContentException;
18
use OCP\IL10N;
19
use OCP\ILogger;
20
21
class AvirWrapper extends Wrapper{
22
	
23
	/**
24
	 * Modes that are used for writing 
25
	 * @var array 
26
	 */
27
	private $writingModes = ['r+', 'w', 'w+', 'a', 'a+', 'x', 'x+', 'c', 'c+'];
28
	
29
	/**
30
	 * @var ScannerFactory
31
	 */
32
	protected $scannerFactory;
33
	
34
	/**
35
	 * @var IL10N 
36
	 */
37
	protected $l10n;
38
	
39
	/**
40
	 * @var ILogger;
41
	 */
42
	protected $logger;
43
44
	/**
45
	 * @param array $parameters
46
	 */
47 4
	public function __construct($parameters) {
48 4
		parent::__construct($parameters);
49 4
		$this->scannerFactory = $parameters['scannerFactory'];
50 4
		$this->l10n = $parameters['l10n'];
51 4
		$this->logger = $parameters['logger'];
52 4
	}
53
	
54
	/**
55
	 * Asynchronously scan data that are written to the file
56
	 * @param string $path
57
	 * @param string $mode
58
	 * @return resource | bool
59
	 */
60 1
	public function fopen($path, $mode){
61 1
		$stream = $this->storage->fopen($path, $mode);
62 1
		if (is_resource($stream) && $this->isWritingMode($mode)) {
63
			try {
64 1
				$scanner = $this->scannerFactory->getScanner();
65
				$scanner->initScanner();
66
				return CallbackWrapper::wrap(
67
					$stream,
68
					null,
69
					function ($data) use ($scanner){
70
						$scanner->onAsyncData($data);
71
					}, 
72
					function () use ($scanner, $path) {
73
						$status = $scanner->completeAsyncScan();
74
						if ((int)$status->getNumericStatus() === Status::SCANRESULT_INFECTED){
75
							//prevent from going to trashbin
76
							if (App::isEnabled('files_trashbin')) {
77
								\OCA\Files_Trashbin\Storage::preRenameHook([
78
									'oldpath' => '',
79
									'newpath' => ''
80
								]);
81
							}
82
							
83
							$owner = $this->getOwner($path);
84
							$this->unlink($path);
85
86
							if (App::isEnabled('files_trashbin')) {
87
								\OCA\Files_Trashbin\Storage::preRenameHook([
88
									'oldpath' => '',
89
									'newpath' => ''
90
								]);
91
							}
92
							$this->logger->warning(
93
								'Infected file deleted. ' . $status->getDetails()
94
								. ' Account: ' . $owner . ' Path: ' . $path,
95
								['app' => 'files_antivirus']
96
							);
97
98
							$activityManager = \OC::$server->getActivityManager();
99
100
							$activity = $activityManager->generateEvent();
101
							$activity->setApp(Application::APP_NAME)
102
								->setSubject(Provider::SUBJECT_VIRUS_DETECTED, [$path, $status->getDetails()])
103
								->setMessage(Provider::MESSAGE_FILE_DELETED)
104
								->setObject('', 0, $path)
105
								->setAffectedUser($owner)
106
								->setType(Provider::TYPE_VIRUS_DETECTED);
107
							$activityManager->publish($activity);
108
109
							$this->logger->error('Infected file deleted. ' . $status->getDetails() . 
110
							' File: ' . $path . ' Acccount: ' . $owner, ['app' => 'files_antivirus']);
111
112
							throw new InvalidContentException(
113
								$this->l10n->t(
114
									'Virus %s is detected in the file. Upload cannot be completed.',
115
									$status->getDetails()
116
								)
117
							);
118
						}
119
					}
120
				);
121 1
			} catch (\Exception $e){
122 1
				$this->logger->logException($e);
123
			}
124
		}
125 1
		return $stream;
126
	}
127
	
128
	/**
129
	 * Checks whether passed mode is suitable for writing 
130
	 * @param string $mode
131
	 * @return bool
132
	 */
133 1
	private function isWritingMode($mode){
134
		// Strip unessential binary/text flags
135 1
		$cleanMode = str_replace(
136 1
			['t', 'b'],
137 1
			['', ''],
138 1
			$mode
139
		);
140 1
		return in_array($cleanMode, $this->writingModes);
141
	}
142
}
143