Completed
Push — master ( 95e8b8...4fe555 )
by Joas
03:38 queued 01:44
created

Operation::isCreatingSkeletonFiles()   B

Complexity

Conditions 6
Paths 3

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 2
Bugs 1 Features 0
Metric Value
c 2
b 1
f 0
dl 0
loc 13
ccs 0
cts 9
cp 0
rs 8.8571
cc 6
eloc 8
nc 3
nop 0
crap 42
1
<?php
2
/**
3
 * @copyright Copyright (c) 2016 Morris Jobke <[email protected]>
4
 *
5
 * @license GNU AGPL version 3 or any later version
6
 *
7
 * This program is free software: you can redistribute it and/or modify
8
 * it under the terms of the GNU Affero General Public License as
9
 * published by the Free Software Foundation, either version 3 of the
10
 * License, or (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU Affero General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Affero General Public License
18
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
 *
20
 */
21
22
namespace OCA\FilesAccessControl;
23
24
25
use OCP\Files\ForbiddenException;
26
use OCP\WorkflowEngine\IManager;
27
28
class Operation {
29
30
	/**
31
	 * AccessControl constructor.
32
	 *
33
	 * @param IManager $manager
34
	 */
35
	public function __construct(IManager $manager) {
36
		$this->manager = $manager;
0 ignored issues
show
Bug introduced by
The property manager does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
37
	}
38
39
	/**
40
	 * @param StorageWrapper $storage
41
	 * @param string $path
42
	 * @throws ForbiddenException
43
	 */
44
	public function checkFileAccess(StorageWrapper $storage, $path) {
45
		if (!$this->isUserFileOrThumbnail($storage, $path) || $this->isCreatingSkeletonFiles()) {
46
			// Allow creating skeletons and theming
47
			// https://github.com/nextcloud/files_accesscontrol/issues/5
48
			// https://github.com/nextcloud/files_accesscontrol/issues/12
49
			return;
50
		}
51
52
		$this->manager->setFileInfo($storage, $path);
53
		$match = $this->manager->getMatchingOperations('OCA\FilesAccessControl\Operation');
54
55
		if (!empty($match)) {
56
			// All Checks of one operation matched: prevent access
57
			throw new ForbiddenException('Access denied', true);
58
		}
59
	}
60
61
	/**
62
	 * @param StorageWrapper $storage
63
	 * @param string $path
64
	 * @return bool
65
	 */
66
	protected function isUserFileOrThumbnail(StorageWrapper $storage, $path) {
67
		$fullPath = $storage->mountPoint . $path;
68
69
		if (substr_count($fullPath, '/') < 3) {
70
			return false;
71
		}
72
73
		// '', admin, 'files', 'path/to/file.txt'
74
		$segment = explode('/', $fullPath, 4);
75
76
		return isset($segment[2]) && in_array($segment[2], ['files', 'thumbnails']);
77
	}
78
79
	/**
80
	 * Check if we are in the LoginController and if so, ignore the firewall
81
	 * @return bool
82
	 */
83
	protected function isCreatingSkeletonFiles() {
84
		$exception = new \Exception();
85
		$trace = $exception->getTrace();
86
87
		foreach ($trace as $step) {
88
			if (isset($step['class']) && $step['class'] === 'OC\Core\Controller\LoginController' &&
89
				isset($step['function']) && $step['function'] === 'tryLogin') {
90
				return true;
91
			}
92
		}
93
94
		return false;
95
	}
96
}
97