Completed
Push — master ( 24a68b...bc84ac )
by Thomas
22:37 queued 09:54
created

FileLocksBackend::getLocks()   B

Complexity

Conditions 7
Paths 8

Size

Total Lines 44

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
nc 8
nop 2
dl 0
loc 44
rs 8.2826
c 0
b 0
f 0
1
<?php
2
/**
3
 * @author Thomas Müller <[email protected]>
4
 *
5
 * @copyright Copyright (c) 2018, ownCloud GmbH
6
 * @license AGPL-3.0
7
 *
8
 * This code is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Affero General Public License, version 3,
10
 * as published by the Free Software Foundation.
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, version 3,
18
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
19
 *
20
 */
21
22
namespace OCA\DAV\Files;
23
24
use OCA\DAV\Connector\Sabre\Node;
25
use OCP\Files\Storage\IPersistentLockingStorage;
26
use OCP\Lock\Persistent\ILock;
27
use Sabre\DAV\Exception\NotFound;
28
use Sabre\DAV\Locks;
29
use Sabre\DAV\Locks\Backend\BackendInterface;
30
use Sabre\DAV\Tree;
31
32
class FileLocksBackend implements BackendInterface {
33
34
	/** @var Tree */
35
	private $tree;
36
	/** @var bool */
37
	private $useV1;
38
39
	public function __construct($tree, $useV1) {
40
		$this->tree = $tree;
41
		$this->useV1 = $useV1;
42
	}
43
44
	/**
45
	 * Returns a list of Sabre\DAV\Locks\LockInfo objects
46
	 *
47
	 * This method should return all the locks for a particular uri, including
48
	 * locks that might be set on a parent uri.
49
	 *
50
	 * If returnChildLocks is set to true, this method should also look for
51
	 * any locks in the subtree of the uri for locks.
52
	 *
53
	 * @param string $uri
54
	 * @param bool $returnChildLocks
55
	 * @return array
56
	 */
57
	public function getLocks($uri, $returnChildLocks) {
58
		try {
59
			$node = $this->tree->getNodeForPath($uri);
60
		} catch (NotFound $e) {
61
			return [];
62
		}
63
		if (!$node instanceof Node) {
64
			return [];
65
		}
66
67
		$storage = $node->getFileInfo()->getStorage();
68
		if (!$storage->instanceOfStorage(IPersistentLockingStorage::class)) {
69
			return [];
70
		}
71
72
		/** @var IPersistentLockingStorage $storage */
73
		$locks = $storage->getLocks($node->getFileInfo()->getInternalPath(), $returnChildLocks);
74
75
		$davLocks = [];
76
		foreach ($locks as $lock) {
77
			$lockInfo = new Locks\LockInfo();
78
			$fileName = $lock->getAbsoluteDavPath();
79
80
			if ($this->useV1) {
81
				$lockInfo->uri = $fileName;
82
			} else {
83
				$uid = $lock->getDavUserId();
84
				$lockInfo->uri = "files/$uid/$fileName";
85
			}
86
			$lockInfo->token = $lock->getToken();
87
			$lockInfo->created = $lock->getCreatedAt();
88
			$lockInfo->depth = $lock->getDepth();
89
			$lockInfo->owner = $lock->getOwner();
90
			if ($lock->getScope() === ILock::LOCK_SCOPE_EXCLUSIVE) {
91
				$lockInfo->scope = Locks\LockInfo::EXCLUSIVE;
92
			} else {
93
				$lockInfo->scope = Locks\LockInfo::SHARED;
94
			}
95
			$lockInfo->timeout = $lock->getTimeout();
96
97
			$davLocks[] = $lockInfo;
98
		}
99
		return $davLocks;
100
	}
101
102
	/**
103
	 * Locks a uri
104
	 *
105
	 * @param string $uri
106
	 * @param Locks\LockInfo $lockInfo
107
	 * @return bool
108
	 */
109
	public function lock($uri, Locks\LockInfo $lockInfo) {
110
		try {
111
			$node = $this->tree->getNodeForPath($uri);
112
		} catch (NotFound $e) {
113
			return false;
114
		}
115
		if (!$node instanceof Node) {
116
			return false;
117
		}
118
119
		$storage = $node->getFileInfo()->getStorage();
120
		if (!$storage->instanceOfStorage(IPersistentLockingStorage::class)) {
121
			return false;
122
		}
123
124
		/** @var IPersistentLockingStorage $storage */
125
		return $storage->lockNodePersistent($node->getFileInfo()->getInternalPath(), [
126
			'token' => $lockInfo->token,
127
			'scope' => $lockInfo->scope === Locks\LockInfo::EXCLUSIVE ? ILock::LOCK_SCOPE_EXCLUSIVE : ILock::LOCK_SCOPE_SHARED,
128
			'depth' => $lockInfo->depth,
129
			'owner' => $lockInfo->owner
130
		]);
131
	}
132
133
	/**
134
	 * Removes a lock from a uri
135
	 *
136
	 * @param string $uri
137
	 * @param Locks\LockInfo $lockInfo
138
	 * @return bool
139
	 */
140
	public function unlock($uri, Locks\LockInfo $lockInfo) {
141
		try {
142
			$node = $this->tree->getNodeForPath($uri);
143
		} catch (NotFound $e) {
144
			return false;
145
		}
146
		if (!$node instanceof Node) {
147
			return false;
148
		}
149
150
		$storage = $node->getFileInfo()->getStorage();
151
		if (!$storage->instanceOfStorage(IPersistentLockingStorage::class)) {
152
			return false;
153
		}
154
155
		/** @var IPersistentLockingStorage $storage */
156
		return $storage->unlockNodePersistent($node->getFileInfo()->getInternalPath(), [
157
			'token' => $lockInfo->token
158
		]);
159
	}
160
}
161