Completed
Pull Request — master (#19)
by Morris
02:45
created

Operation   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 71
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 0%

Importance

Changes 4
Bugs 1 Features 0
Metric Value
wmc 14
c 4
b 1
f 0
lcom 1
cbo 1
dl 0
loc 71
ccs 0
cts 28
cp 0
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A checkFileAccess() 0 16 4
A isUserFileOrThumbnail() 0 12 3
B isCreatingSkeletonFiles() 0 15 6
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 (array_key_exists('class', $step) &&
89
				array_key_exists('function', $step) &&
90
				$step['class'] === 'OC\Core\Controller\LoginController' &&
91
				$step['function'] === 'tryLogin') {
92
				return true;
93
			}
94
		}
95
96
		return false;
97
	}
98
}
99