Completed
Push — master ( b4a090...ed1dd0 )
by Roeland
10s
created

BackgroundScanner::tearDownFilesystem()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 4
cp 0
rs 10
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 0
crap 2
1
<?php
2
/**
3
 * Copyright (c) 2012 Bart Visscher <[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 Doctrine\DBAL\Platforms\MySqlPlatform;
12
use OCA\Files_Antivirus\Scanner\ScannerFactory;
13
use OC\Files\Filesystem;
14
use OCP\Files\IMimeTypeLoader;
15
use OCP\IDBConnection;
16
use OCP\IL10N;
17
use OCP\Files\Folder;
18
use OCP\Files\IRootFolder;
19
use OCP\ILogger;
20
use OCP\IUser;
21
use OCP\IUserManager;
22
use OCP\IUserSession;
23
24
class BackgroundScanner {
25
26
	const BATCH_SIZE = 10;
27
28
	/** @var IRootFolder */
29
	protected $rootFolder;
30
31
	/** @var Folder[] */
32
	protected $userFolders;
33
34
	/** @var ScannerFactory */
35
	private $scannerFactory;
36
37
	/** @var IL10N */
38
	private $l10n;
39
40
	/** @var  AppConfig  */
41
	private $appConfig;
42
43
	/** @var string */
44
	protected $currentFilesystemUser;
45
46
	/** @var IUserSession */
47
	protected $userSession;
48
49
	/** @var ILogger */
50
	protected $logger;
51
52
	/** @var IUserManager */
53
	protected $userManager;
54
55
	/** @var IDBConnection */
56
	protected $db;
57
58
	/** @var IMimeTypeLoader */
59
	protected $mimeTypeLoader;
60
61
	/**
62
	 * A constructor
63
	 *
64
	 * @param ScannerFactory $scannerFactory
65
	 * @param IL10N $l10n
66
	 * @param AppConfig $appConfig
67
	 * @param IRootFolder $rootFolder
68
	 * @param IUserSession $userSession
69
	 * @param ILogger $logger
70
	 * @param IUserManager $userManager
71
	 * @param IDBConnection $db
72
	 * @param IMimeTypeLoader $mimeTypeLoader
73
	 */
74
	public function __construct(ScannerFactory $scannerFactory,
75
								IL10N $l10n,
76
								AppConfig $appConfig,
77
								IRootFolder $rootFolder,
78
								IUserSession $userSession,
79
								ILogger $logger,
80
								IUserManager $userManager,
81
								IDBConnection $db,
82
								IMimeTypeLoader $mimeTypeLoader
83
	){
84
		$this->rootFolder = $rootFolder;
85
		$this->scannerFactory = $scannerFactory;
86
		$this->l10n = $l10n;
87
		$this->appConfig = $appConfig;
88
		$this->userSession = $userSession;
89
		$this->logger = $logger;
90
		$this->userManager = $userManager;
91
		$this->db = $db;
92
		$this->mimeTypeLoader = $mimeTypeLoader;
93
	}
94
	
95
	/**
96
	 * Background scanner main job
97
	 */
98
	public function run(){
99
		// locate files that are not checked yet
100
		try {
101
			$result = $this->getFilesForScan();
102
		} catch(\Exception $e) {
103
			$this->logger->error( __METHOD__ . ', exception: ' . $e->getMessage(), ['app' => 'files_antivirus']);
104
			return;
105
		}
106
107
		$cnt = 0;
108
		while (($row = $result->fetch()) && $cnt < self::BATCH_SIZE) {
109
			try {
110
				$fileId = $row['fileid'];
111
				$userId = $row['user_id'];
112
				/** @var IUser $owner */
113
				$owner = $this->userManager->get($userId);
114
				if (!$owner instanceof IUser){
0 ignored issues
show
Bug introduced by
The class OCP\IUser does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
115
					continue;
116
				}
117
				$this->scanOneFile($owner, $fileId);
118
				// increased only for successfully scanned files
119
				$cnt = $cnt + 1;
120
			} catch (\Exception $e) {
121
				$this->logger->error( __METHOD__ . ', exception: ' . $e->getMessage(), ['app' => 'files_antivirus']);
122
			}
123
		}
124
		$this->tearDownFilesystem();
125
	}
126
127
	protected function getFilesForScan(){
128
		$dirMimeTypeId = $this->mimeTypeLoader->getId('httpd/unix-directory');
129
130
		$qb = $this->db->getQueryBuilder();
131
		if ($this->db->getDatabasePlatform() instanceof MySqlPlatform) {
0 ignored issues
show
Bug introduced by
The class Doctrine\DBAL\Platforms\MySqlPlatform does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
132
			$concatFunction = $qb->createFunction(
133
				"CONCAT('/', mnt.user_id, '/')"
134
			);
135
		} else {
136
			$concatFunction = $qb->createFunction(
137
				"'/' || " . $qb->getColumnName('mnt.user_id') . " || '/'"
138
			);
139
		}
140
141
		$sizeLimit = (int)$this->appConfig->getAvMaxFileSize();
142
		if ( $sizeLimit === -1 ){
143
			$sizeLimitExpr = $qb->expr()->neq('fc.size', $qb->expr()->literal('0'));
144
		} else {
145
			$sizeLimitExpr = $qb->expr()->andX(
146
				$qb->expr()->neq('fc.size', $qb->expr()->literal('0')),
147
				$qb->expr()->lt('fc.size', $qb->expr()->literal((string) $sizeLimit))
148
			);
149
		}
150
151
		$qb->select(['fc.fileid', 'mnt.user_id'])
152
			->from('filecache', 'fc')
153
			->leftJoin('fc', 'files_antivirus', 'fa', $qb->expr()->eq('fa.fileid', 'fc.fileid'))
154
			->innerJoin(
155
				'fc',
156
				'mounts',
157
				'mnt',
158
				$qb->expr()->andX(
159
					$qb->expr()->eq('fc.storage', 'mnt.storage_id'),
160
					$qb->expr()->eq('mnt.mount_point', $concatFunction)
161
				)
162
			)
163
			->where(
164
				$qb->expr()->neq('fc.mimetype', $qb->expr()->literal($dirMimeTypeId))
165
			)
166
			->andWhere(
167
				$qb->expr()->orX(
168
					$qb->expr()->isNull('fa.fileid'),
169
					$qb->expr()->gt('fc.mtime', 'fa.check_time')
170
				)
171
			)
172
			->andWhere(
173
				$qb->expr()->like('fc.path', $qb->expr()->literal('files/%'))
174
			)
175
			->andWhere( $sizeLimitExpr )
176
		;
177
		return $qb->execute();
178
	}
179
180
	/**
181
	 * @param IUser $owner
182
	 * @param int $fileId
183
	 */
184
	protected function scanOneFile($owner, $fileId){
185
		$this->initFilesystemForUser($owner);
186
		$view = Filesystem::getView();
187
		$path = $view->getPath($fileId);
188
		if (!is_null($path)) {
189
			$item = new Item($this->l10n, $view, $path, $fileId);
190
			$scanner = $this->scannerFactory->getScanner();
191
			$status = $scanner->scan($item);
192
			$status->dispatch($item, true);
193
		}
194
	}
195
196
	/**
197
	 * @param \OCP\IUser $user
198
	 * @return \OCP\Files\Folder
199
	 */
200
	protected function getUserFolder(IUser $user) {
201
		if (!isset($this->userFolders[$user->getUID()])) {
202
			$userFolder = $this->rootFolder->getUserFolder($user->getUID());
203
			$this->userFolders[$user->getUID()] = $userFolder;
204
		}
205
		return $this->userFolders[$user->getUID()];
206
	}
207
208
	/**
209
	 * @param IUser $user
210
	 */
211
	protected function initFilesystemForUser(IUser $user) {
212
		if ($this->currentFilesystemUser !== $user->getUID()) {
213
			if ($this->currentFilesystemUser !== '') {
214
				$this->tearDownFilesystem();
215
			}
216
			Filesystem::init($user->getUID(), '/' . $user->getUID() . '/files');
217
			$this->userSession->setUser($user);
218
			$this->currentFilesystemUser = $user->getUID();
219
			Filesystem::initMountPoints($user->getUID());
220
		}
221
	}
222
223
	/**
224
	 *
225
	 */
226
	protected function tearDownFilesystem(){
227
		$this->userSession->setUser(null);
228
		\OC_Util::tearDownFS();
229
	}
230
231
	/**
232
	 * @deprecated since  v8.0.0
233
	 */
234
	public static function check(){
235
	}
236
}
237