Completed
Pull Request — master (#4701)
by Morris
12:55
created
apps/dav/lib/Connector/Sabre/Node.php 1 patch
Indentation   +306 added lines, -306 removed lines patch added patch discarded remove patch
@@ -43,315 +43,315 @@
 block discarded – undo
43 43
 
44 44
 abstract class Node implements \Sabre\DAV\INode {
45 45
 
46
-	/**
47
-	 * @var \OC\Files\View
48
-	 */
49
-	protected $fileView;
50
-
51
-	/**
52
-	 * The path to the current node
53
-	 *
54
-	 * @var string
55
-	 */
56
-	protected $path;
57
-
58
-	/**
59
-	 * node properties cache
60
-	 *
61
-	 * @var array
62
-	 */
63
-	protected $property_cache = null;
64
-
65
-	/**
66
-	 * @var \OCP\Files\FileInfo
67
-	 */
68
-	protected $info;
69
-
70
-	/**
71
-	 * @var IManager
72
-	 */
73
-	protected $shareManager;
74
-
75
-	/**
76
-	 * Sets up the node, expects a full path name
77
-	 *
78
-	 * @param \OC\Files\View $view
79
-	 * @param \OCP\Files\FileInfo $info
80
-	 * @param IManager $shareManager
81
-	 */
82
-	public function __construct(View $view, FileInfo $info, IManager $shareManager = null) {
83
-		$this->fileView = $view;
84
-		$this->path = $this->fileView->getRelativePath($info->getPath());
85
-		$this->info = $info;
86
-		if ($shareManager) {
87
-			$this->shareManager = $shareManager;
88
-		} else {
89
-			$this->shareManager = \OC::$server->getShareManager();
90
-		}
91
-	}
92
-
93
-	protected function refreshInfo() {
94
-		$this->info = $this->fileView->getFileInfo($this->path);
95
-	}
96
-
97
-	/**
98
-	 *  Returns the name of the node
99
-	 *
100
-	 * @return string
101
-	 */
102
-	public function getName() {
103
-		return $this->info->getName();
104
-	}
105
-
106
-	/**
107
-	 * Returns the full path
108
-	 *
109
-	 * @return string
110
-	 */
111
-	public function getPath() {
112
-		return $this->path;
113
-	}
114
-
115
-	/**
116
-	 * Renames the node
117
-	 *
118
-	 * @param string $name The new name
119
-	 * @throws \Sabre\DAV\Exception\BadRequest
120
-	 * @throws \Sabre\DAV\Exception\Forbidden
121
-	 */
122
-	public function setName($name) {
123
-
124
-		// rename is only allowed if the update privilege is granted
125
-		if (!$this->info->isUpdateable()) {
126
-			throw new \Sabre\DAV\Exception\Forbidden();
127
-		}
128
-
129
-		list($parentPath,) = \Sabre\HTTP\URLUtil::splitPath($this->path);
130
-		list(, $newName) = \Sabre\HTTP\URLUtil::splitPath($name);
131
-
132
-		// verify path of the target
133
-		$this->verifyPath();
134
-
135
-		$newPath = $parentPath . '/' . $newName;
136
-
137
-		$this->fileView->rename($this->path, $newPath);
138
-
139
-		$this->path = $newPath;
140
-
141
-		$this->refreshInfo();
142
-	}
143
-
144
-	public function setPropertyCache($property_cache) {
145
-		$this->property_cache = $property_cache;
146
-	}
147
-
148
-	/**
149
-	 * Returns the last modification time, as a unix timestamp
150
-	 *
151
-	 * @return int timestamp as integer
152
-	 */
153
-	public function getLastModified() {
154
-		$timestamp = $this->info->getMtime();
155
-		if (!empty($timestamp)) {
156
-			return (int)$timestamp;
157
-		}
158
-		return $timestamp;
159
-	}
160
-
161
-	/**
162
-	 *  sets the last modification time of the file (mtime) to the value given
163
-	 *  in the second parameter or to now if the second param is empty.
164
-	 *  Even if the modification time is set to a custom value the access time is set to now.
165
-	 */
166
-	public function touch($mtime) {
167
-		$this->fileView->touch($this->path, $mtime);
168
-		$this->refreshInfo();
169
-	}
170
-
171
-	/**
172
-	 * Returns the ETag for a file
173
-	 *
174
-	 * An ETag is a unique identifier representing the current version of the
175
-	 * file. If the file changes, the ETag MUST change.  The ETag is an
176
-	 * arbitrary string, but MUST be surrounded by double-quotes.
177
-	 *
178
-	 * Return null if the ETag can not effectively be determined
179
-	 *
180
-	 * @return string
181
-	 */
182
-	public function getETag() {
183
-		return '"' . $this->info->getEtag() . '"';
184
-	}
185
-
186
-	/**
187
-	 * Sets the ETag
188
-	 *
189
-	 * @param string $etag
190
-	 *
191
-	 * @return int file id of updated file or -1 on failure
192
-	 */
193
-	public function setETag($etag) {
194
-		return $this->fileView->putFileInfo($this->path, array('etag' => $etag));
195
-	}
196
-
197
-	/**
198
-	 * Returns the size of the node, in bytes
199
-	 *
200
-	 * @return integer
201
-	 */
202
-	public function getSize() {
203
-		return $this->info->getSize();
204
-	}
205
-
206
-	/**
207
-	 * Returns the cache's file id
208
-	 *
209
-	 * @return int
210
-	 */
211
-	public function getId() {
212
-		return $this->info->getId();
213
-	}
214
-
215
-	/**
216
-	 * @return string|null
217
-	 */
218
-	public function getFileId() {
219
-		if ($this->info->getId()) {
220
-			$instanceId = \OC_Util::getInstanceId();
221
-			$id = sprintf('%08d', $this->info->getId());
222
-			return $id . $instanceId;
223
-		}
224
-
225
-		return null;
226
-	}
227
-
228
-	/**
229
-	 * @return integer
230
-	 */
231
-	public function getInternalFileId() {
232
-		return $this->info->getId();
233
-	}
234
-
235
-	/**
236
-	 * @param string $user
237
-	 * @return int
238
-	 */
239
-	public function getSharePermissions($user) {
240
-
241
-		// check of we access a federated share
242
-		if ($user !== null) {
243
-			try {
244
-				$share = $this->shareManager->getShareByToken($user);
245
-				return $share->getPermissions();
246
-			} catch (ShareNotFound $e) {
247
-				// ignore
248
-			}
249
-		}
250
-
251
-		$storage = $this->info->getStorage();
252
-
253
-		$path = $this->info->getInternalPath();
254
-
255
-		if ($storage->instanceOfStorage('\OCA\Files_Sharing\SharedStorage')) {
256
-			/** @var \OCA\Files_Sharing\SharedStorage $storage */
257
-			$permissions = (int)$storage->getShare()->getPermissions();
258
-		} else {
259
-			$permissions = $storage->getPermissions($path);
260
-		}
261
-
262
-		/*
46
+    /**
47
+     * @var \OC\Files\View
48
+     */
49
+    protected $fileView;
50
+
51
+    /**
52
+     * The path to the current node
53
+     *
54
+     * @var string
55
+     */
56
+    protected $path;
57
+
58
+    /**
59
+     * node properties cache
60
+     *
61
+     * @var array
62
+     */
63
+    protected $property_cache = null;
64
+
65
+    /**
66
+     * @var \OCP\Files\FileInfo
67
+     */
68
+    protected $info;
69
+
70
+    /**
71
+     * @var IManager
72
+     */
73
+    protected $shareManager;
74
+
75
+    /**
76
+     * Sets up the node, expects a full path name
77
+     *
78
+     * @param \OC\Files\View $view
79
+     * @param \OCP\Files\FileInfo $info
80
+     * @param IManager $shareManager
81
+     */
82
+    public function __construct(View $view, FileInfo $info, IManager $shareManager = null) {
83
+        $this->fileView = $view;
84
+        $this->path = $this->fileView->getRelativePath($info->getPath());
85
+        $this->info = $info;
86
+        if ($shareManager) {
87
+            $this->shareManager = $shareManager;
88
+        } else {
89
+            $this->shareManager = \OC::$server->getShareManager();
90
+        }
91
+    }
92
+
93
+    protected function refreshInfo() {
94
+        $this->info = $this->fileView->getFileInfo($this->path);
95
+    }
96
+
97
+    /**
98
+     *  Returns the name of the node
99
+     *
100
+     * @return string
101
+     */
102
+    public function getName() {
103
+        return $this->info->getName();
104
+    }
105
+
106
+    /**
107
+     * Returns the full path
108
+     *
109
+     * @return string
110
+     */
111
+    public function getPath() {
112
+        return $this->path;
113
+    }
114
+
115
+    /**
116
+     * Renames the node
117
+     *
118
+     * @param string $name The new name
119
+     * @throws \Sabre\DAV\Exception\BadRequest
120
+     * @throws \Sabre\DAV\Exception\Forbidden
121
+     */
122
+    public function setName($name) {
123
+
124
+        // rename is only allowed if the update privilege is granted
125
+        if (!$this->info->isUpdateable()) {
126
+            throw new \Sabre\DAV\Exception\Forbidden();
127
+        }
128
+
129
+        list($parentPath,) = \Sabre\HTTP\URLUtil::splitPath($this->path);
130
+        list(, $newName) = \Sabre\HTTP\URLUtil::splitPath($name);
131
+
132
+        // verify path of the target
133
+        $this->verifyPath();
134
+
135
+        $newPath = $parentPath . '/' . $newName;
136
+
137
+        $this->fileView->rename($this->path, $newPath);
138
+
139
+        $this->path = $newPath;
140
+
141
+        $this->refreshInfo();
142
+    }
143
+
144
+    public function setPropertyCache($property_cache) {
145
+        $this->property_cache = $property_cache;
146
+    }
147
+
148
+    /**
149
+     * Returns the last modification time, as a unix timestamp
150
+     *
151
+     * @return int timestamp as integer
152
+     */
153
+    public function getLastModified() {
154
+        $timestamp = $this->info->getMtime();
155
+        if (!empty($timestamp)) {
156
+            return (int)$timestamp;
157
+        }
158
+        return $timestamp;
159
+    }
160
+
161
+    /**
162
+     *  sets the last modification time of the file (mtime) to the value given
163
+     *  in the second parameter or to now if the second param is empty.
164
+     *  Even if the modification time is set to a custom value the access time is set to now.
165
+     */
166
+    public function touch($mtime) {
167
+        $this->fileView->touch($this->path, $mtime);
168
+        $this->refreshInfo();
169
+    }
170
+
171
+    /**
172
+     * Returns the ETag for a file
173
+     *
174
+     * An ETag is a unique identifier representing the current version of the
175
+     * file. If the file changes, the ETag MUST change.  The ETag is an
176
+     * arbitrary string, but MUST be surrounded by double-quotes.
177
+     *
178
+     * Return null if the ETag can not effectively be determined
179
+     *
180
+     * @return string
181
+     */
182
+    public function getETag() {
183
+        return '"' . $this->info->getEtag() . '"';
184
+    }
185
+
186
+    /**
187
+     * Sets the ETag
188
+     *
189
+     * @param string $etag
190
+     *
191
+     * @return int file id of updated file or -1 on failure
192
+     */
193
+    public function setETag($etag) {
194
+        return $this->fileView->putFileInfo($this->path, array('etag' => $etag));
195
+    }
196
+
197
+    /**
198
+     * Returns the size of the node, in bytes
199
+     *
200
+     * @return integer
201
+     */
202
+    public function getSize() {
203
+        return $this->info->getSize();
204
+    }
205
+
206
+    /**
207
+     * Returns the cache's file id
208
+     *
209
+     * @return int
210
+     */
211
+    public function getId() {
212
+        return $this->info->getId();
213
+    }
214
+
215
+    /**
216
+     * @return string|null
217
+     */
218
+    public function getFileId() {
219
+        if ($this->info->getId()) {
220
+            $instanceId = \OC_Util::getInstanceId();
221
+            $id = sprintf('%08d', $this->info->getId());
222
+            return $id . $instanceId;
223
+        }
224
+
225
+        return null;
226
+    }
227
+
228
+    /**
229
+     * @return integer
230
+     */
231
+    public function getInternalFileId() {
232
+        return $this->info->getId();
233
+    }
234
+
235
+    /**
236
+     * @param string $user
237
+     * @return int
238
+     */
239
+    public function getSharePermissions($user) {
240
+
241
+        // check of we access a federated share
242
+        if ($user !== null) {
243
+            try {
244
+                $share = $this->shareManager->getShareByToken($user);
245
+                return $share->getPermissions();
246
+            } catch (ShareNotFound $e) {
247
+                // ignore
248
+            }
249
+        }
250
+
251
+        $storage = $this->info->getStorage();
252
+
253
+        $path = $this->info->getInternalPath();
254
+
255
+        if ($storage->instanceOfStorage('\OCA\Files_Sharing\SharedStorage')) {
256
+            /** @var \OCA\Files_Sharing\SharedStorage $storage */
257
+            $permissions = (int)$storage->getShare()->getPermissions();
258
+        } else {
259
+            $permissions = $storage->getPermissions($path);
260
+        }
261
+
262
+        /*
263 263
 		 * We can always share non moveable mount points with DELETE and UPDATE
264 264
 		 * Eventually we need to do this properly
265 265
 		 */
266
-		$mountpoint = $this->info->getMountPoint();
267
-		if (!($mountpoint instanceof MoveableMount)) {
268
-			$mountpointpath = $mountpoint->getMountPoint();
269
-			if (substr($mountpointpath, -1) === '/') {
270
-				$mountpointpath = substr($mountpointpath, 0, -1);
271
-			}
272
-
273
-			if ($mountpointpath === $this->info->getPath()) {
274
-				$permissions |= \OCP\Constants::PERMISSION_DELETE | \OCP\Constants::PERMISSION_UPDATE;
275
-			}
276
-		}
277
-
278
-		/*
266
+        $mountpoint = $this->info->getMountPoint();
267
+        if (!($mountpoint instanceof MoveableMount)) {
268
+            $mountpointpath = $mountpoint->getMountPoint();
269
+            if (substr($mountpointpath, -1) === '/') {
270
+                $mountpointpath = substr($mountpointpath, 0, -1);
271
+            }
272
+
273
+            if ($mountpointpath === $this->info->getPath()) {
274
+                $permissions |= \OCP\Constants::PERMISSION_DELETE | \OCP\Constants::PERMISSION_UPDATE;
275
+            }
276
+        }
277
+
278
+        /*
279 279
 		 * Files can't have create or delete permissions
280 280
 		 */
281
-		if ($this->info->getType() === \OCP\Files\FileInfo::TYPE_FILE) {
282
-			$permissions &= ~(\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_DELETE);
283
-		}
284
-
285
-		return $permissions;
286
-	}
287
-
288
-	/**
289
-	 * @return string
290
-	 */
291
-	public function getDavPermissions() {
292
-		$p = '';
293
-		if ($this->info->isShared()) {
294
-			$p .= 'S';
295
-		}
296
-		if ($this->info->isShareable()) {
297
-			$p .= 'R';
298
-		}
299
-		if ($this->info->isMounted()) {
300
-			$p .= 'M';
301
-		}
302
-		if ($this->info->isDeletable()) {
303
-			$p .= 'D';
304
-		}
305
-		if ($this->info->isUpdateable()) {
306
-			$p .= 'NV'; // Renameable, Moveable
307
-		}
308
-		if ($this->info->getType() === \OCP\Files\FileInfo::TYPE_FILE) {
309
-			if ($this->info->isUpdateable()) {
310
-				$p .= 'W';
311
-			}
312
-		} else {
313
-			if ($this->info->isCreatable()) {
314
-				$p .= 'CK';
315
-			}
316
-		}
317
-		return $p;
318
-	}
319
-
320
-	public function getOwner() {
321
-		return $this->info->getOwner();
322
-	}
323
-
324
-	protected function verifyPath() {
325
-		try {
326
-			$fileName = basename($this->info->getPath());
327
-			$this->fileView->verifyPath($this->path, $fileName);
328
-		} catch (\OCP\Files\InvalidPathException $ex) {
329
-			throw new InvalidPath($ex->getMessage());
330
-		}
331
-	}
332
-
333
-	/**
334
-	 * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
335
-	 */
336
-	public function acquireLock($type) {
337
-		$this->fileView->lockFile($this->path, $type);
338
-	}
339
-
340
-	/**
341
-	 * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
342
-	 */
343
-	public function releaseLock($type) {
344
-		$this->fileView->unlockFile($this->path, $type);
345
-	}
346
-
347
-	/**
348
-	 * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
349
-	 */
350
-	public function changeLock($type) {
351
-		$this->fileView->changeLock($this->path, $type);
352
-	}
353
-
354
-	public function getFileInfo() {
355
-		return $this->info;
356
-	}
281
+        if ($this->info->getType() === \OCP\Files\FileInfo::TYPE_FILE) {
282
+            $permissions &= ~(\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_DELETE);
283
+        }
284
+
285
+        return $permissions;
286
+    }
287
+
288
+    /**
289
+     * @return string
290
+     */
291
+    public function getDavPermissions() {
292
+        $p = '';
293
+        if ($this->info->isShared()) {
294
+            $p .= 'S';
295
+        }
296
+        if ($this->info->isShareable()) {
297
+            $p .= 'R';
298
+        }
299
+        if ($this->info->isMounted()) {
300
+            $p .= 'M';
301
+        }
302
+        if ($this->info->isDeletable()) {
303
+            $p .= 'D';
304
+        }
305
+        if ($this->info->isUpdateable()) {
306
+            $p .= 'NV'; // Renameable, Moveable
307
+        }
308
+        if ($this->info->getType() === \OCP\Files\FileInfo::TYPE_FILE) {
309
+            if ($this->info->isUpdateable()) {
310
+                $p .= 'W';
311
+            }
312
+        } else {
313
+            if ($this->info->isCreatable()) {
314
+                $p .= 'CK';
315
+            }
316
+        }
317
+        return $p;
318
+    }
319
+
320
+    public function getOwner() {
321
+        return $this->info->getOwner();
322
+    }
323
+
324
+    protected function verifyPath() {
325
+        try {
326
+            $fileName = basename($this->info->getPath());
327
+            $this->fileView->verifyPath($this->path, $fileName);
328
+        } catch (\OCP\Files\InvalidPathException $ex) {
329
+            throw new InvalidPath($ex->getMessage());
330
+        }
331
+    }
332
+
333
+    /**
334
+     * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
335
+     */
336
+    public function acquireLock($type) {
337
+        $this->fileView->lockFile($this->path, $type);
338
+    }
339
+
340
+    /**
341
+     * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
342
+     */
343
+    public function releaseLock($type) {
344
+        $this->fileView->unlockFile($this->path, $type);
345
+    }
346
+
347
+    /**
348
+     * @param int $type \OCP\Lock\ILockingProvider::LOCK_SHARED or \OCP\Lock\ILockingProvider::LOCK_EXCLUSIVE
349
+     */
350
+    public function changeLock($type) {
351
+        $this->fileView->changeLock($this->path, $type);
352
+    }
353
+
354
+    public function getFileInfo() {
355
+        return $this->info;
356
+    }
357 357
 }
Please login to merge, or discard this patch.
apps/dav/lib/Connector/Sabre/Directory.php 1 patch
Indentation   +393 added lines, -393 removed lines patch added patch discarded remove patch
@@ -49,397 +49,397 @@
 block discarded – undo
49 49
 use Sabre\DAV\Exception\NotFound;
50 50
 
51 51
 class Directory extends \OCA\DAV\Connector\Sabre\Node
52
-	implements \Sabre\DAV\ICollection, \Sabre\DAV\IQuota, \Sabre\DAV\IMoveTarget {
53
-
54
-	/**
55
-	 * Cached directory content
56
-	 *
57
-	 * @var \OCP\Files\FileInfo[]
58
-	 */
59
-	private $dirContent;
60
-
61
-	/**
62
-	 * Cached quota info
63
-	 *
64
-	 * @var array
65
-	 */
66
-	private $quotaInfo;
67
-
68
-	/**
69
-	 * @var ObjectTree|null
70
-	 */
71
-	private $tree;
72
-
73
-	/**
74
-	 * Sets up the node, expects a full path name
75
-	 *
76
-	 * @param \OC\Files\View $view
77
-	 * @param \OCP\Files\FileInfo $info
78
-	 * @param ObjectTree|null $tree
79
-	 * @param \OCP\Share\IManager $shareManager
80
-	 */
81
-	public function __construct(View $view, FileInfo $info, $tree = null, $shareManager = null) {
82
-		parent::__construct($view, $info, $shareManager);
83
-		$this->tree = $tree;
84
-	}
85
-
86
-	/**
87
-	 * Creates a new file in the directory
88
-	 *
89
-	 * Data will either be supplied as a stream resource, or in certain cases
90
-	 * as a string. Keep in mind that you may have to support either.
91
-	 *
92
-	 * After successful creation of the file, you may choose to return the ETag
93
-	 * of the new file here.
94
-	 *
95
-	 * The returned ETag must be surrounded by double-quotes (The quotes should
96
-	 * be part of the actual string).
97
-	 *
98
-	 * If you cannot accurately determine the ETag, you should not return it.
99
-	 * If you don't store the file exactly as-is (you're transforming it
100
-	 * somehow) you should also not return an ETag.
101
-	 *
102
-	 * This means that if a subsequent GET to this new file does not exactly
103
-	 * return the same contents of what was submitted here, you are strongly
104
-	 * recommended to omit the ETag.
105
-	 *
106
-	 * @param string $name Name of the file
107
-	 * @param resource|string $data Initial payload
108
-	 * @return null|string
109
-	 * @throws Exception\EntityTooLarge
110
-	 * @throws Exception\UnsupportedMediaType
111
-	 * @throws FileLocked
112
-	 * @throws InvalidPath
113
-	 * @throws \Sabre\DAV\Exception
114
-	 * @throws \Sabre\DAV\Exception\BadRequest
115
-	 * @throws \Sabre\DAV\Exception\Forbidden
116
-	 * @throws \Sabre\DAV\Exception\ServiceUnavailable
117
-	 */
118
-	public function createFile($name, $data = null) {
119
-
120
-		try {
121
-			// for chunked upload also updating a existing file is a "createFile"
122
-			// because we create all the chunks before re-assemble them to the existing file.
123
-			if (isset($_SERVER['HTTP_OC_CHUNKED'])) {
124
-
125
-				// exit if we can't create a new file and we don't updatable existing file
126
-				$chunkInfo = \OC_FileChunking::decodeName($name);
127
-				if (!$this->fileView->isCreatable($this->path) &&
128
-					!$this->fileView->isUpdatable($this->path . '/' . $chunkInfo['name'])
129
-				) {
130
-					throw new \Sabre\DAV\Exception\Forbidden();
131
-				}
132
-
133
-			} else {
134
-				// For non-chunked upload it is enough to check if we can create a new file
135
-				if (!$this->fileView->isCreatable($this->path)) {
136
-					throw new \Sabre\DAV\Exception\Forbidden();
137
-				}
138
-			}
139
-
140
-			$this->fileView->verifyPath($this->path, $name);
141
-
142
-			$path = $this->fileView->getAbsolutePath($this->path) . '/' . $name;
143
-			// in case the file already exists/overwriting
144
-			$info = $this->fileView->getFileInfo($this->path . '/' . $name);
145
-			if (!$info) {
146
-				// use a dummy FileInfo which is acceptable here since it will be refreshed after the put is complete
147
-				$info = new \OC\Files\FileInfo($path, null, null, [], null);
148
-			}
149
-			$node = new \OCA\DAV\Connector\Sabre\File($this->fileView, $info);
150
-			$node->acquireLock(ILockingProvider::LOCK_SHARED);
151
-			return $node->put($data);
152
-		} catch (\OCP\Files\StorageNotAvailableException $e) {
153
-			throw new \Sabre\DAV\Exception\ServiceUnavailable($e->getMessage());
154
-		} catch (InvalidPathException $ex) {
155
-			throw new InvalidPath($ex->getMessage());
156
-		} catch (ForbiddenException $ex) {
157
-			throw new Forbidden($ex->getMessage(), $ex->getRetry());
158
-		} catch (LockedException $e) {
159
-			throw new FileLocked($e->getMessage(), $e->getCode(), $e);
160
-		}
161
-	}
162
-
163
-	/**
164
-	 * Creates a new subdirectory
165
-	 *
166
-	 * @param string $name
167
-	 * @throws FileLocked
168
-	 * @throws InvalidPath
169
-	 * @throws \Sabre\DAV\Exception\Forbidden
170
-	 * @throws \Sabre\DAV\Exception\ServiceUnavailable
171
-	 */
172
-	public function createDirectory($name) {
173
-		try {
174
-			if (!$this->info->isCreatable()) {
175
-				throw new \Sabre\DAV\Exception\Forbidden();
176
-			}
177
-
178
-			$this->fileView->verifyPath($this->path, $name);
179
-			$newPath = $this->path . '/' . $name;
180
-			if (!$this->fileView->mkdir($newPath)) {
181
-				throw new \Sabre\DAV\Exception\Forbidden('Could not create directory ' . $newPath);
182
-			}
183
-		} catch (\OCP\Files\StorageNotAvailableException $e) {
184
-			throw new \Sabre\DAV\Exception\ServiceUnavailable($e->getMessage());
185
-		} catch (InvalidPathException $ex) {
186
-			throw new InvalidPath($ex->getMessage());
187
-		} catch (ForbiddenException $ex) {
188
-			throw new Forbidden($ex->getMessage(), $ex->getRetry());
189
-		} catch (LockedException $e) {
190
-			throw new FileLocked($e->getMessage(), $e->getCode(), $e);
191
-		}
192
-	}
193
-
194
-	/**
195
-	 * Returns a specific child node, referenced by its name
196
-	 *
197
-	 * @param string $name
198
-	 * @param \OCP\Files\FileInfo $info
199
-	 * @return \Sabre\DAV\INode
200
-	 * @throws InvalidPath
201
-	 * @throws \Sabre\DAV\Exception\NotFound
202
-	 * @throws \Sabre\DAV\Exception\ServiceUnavailable
203
-	 */
204
-	public function getChild($name, $info = null) {
205
-		if (!$this->info->isReadable()) {
206
-			// avoid detecting files through this way
207
-			throw new NotFound();
208
-		}
209
-
210
-		$path = $this->path . '/' . $name;
211
-		if (is_null($info)) {
212
-			try {
213
-				$this->fileView->verifyPath($this->path, $name);
214
-				$info = $this->fileView->getFileInfo($path);
215
-			} catch (\OCP\Files\StorageNotAvailableException $e) {
216
-				throw new \Sabre\DAV\Exception\ServiceUnavailable($e->getMessage());
217
-			} catch (InvalidPathException $ex) {
218
-				throw new InvalidPath($ex->getMessage());
219
-			} catch (ForbiddenException $e) {
220
-				throw new \Sabre\DAV\Exception\Forbidden();
221
-			}
222
-		}
223
-
224
-		if (!$info) {
225
-			throw new \Sabre\DAV\Exception\NotFound('File with name ' . $path . ' could not be located');
226
-		}
227
-
228
-		if ($info['mimetype'] == 'httpd/unix-directory') {
229
-			$node = new \OCA\DAV\Connector\Sabre\Directory($this->fileView, $info, $this->tree, $this->shareManager);
230
-		} else {
231
-			$node = new \OCA\DAV\Connector\Sabre\File($this->fileView, $info, $this->shareManager);
232
-		}
233
-		if ($this->tree) {
234
-			$this->tree->cacheNode($node);
235
-		}
236
-		return $node;
237
-	}
238
-
239
-	/**
240
-	 * Returns an array with all the child nodes
241
-	 *
242
-	 * @return \Sabre\DAV\INode[]
243
-	 * @throws \Sabre\DAV\Exception\Locked
244
-	 * @throws \OCA\DAV\Connector\Sabre\Exception\Forbidden
245
-	 */
246
-	public function getChildren() {
247
-		if (!is_null($this->dirContent)) {
248
-			return $this->dirContent;
249
-		}
250
-		try {
251
-			if (!$this->info->isReadable()) {
252
-				// return 403 instead of 404 because a 404 would make
253
-				// the caller believe that the collection itself does not exist
254
-				throw new Forbidden('No read permissions');
255
-			}
256
-			$folderContent = $this->fileView->getDirectoryContent($this->path);
257
-		} catch (LockedException $e) {
258
-			throw new Locked();
259
-		}
260
-
261
-		$nodes = array();
262
-		foreach ($folderContent as $info) {
263
-			$node = $this->getChild($info->getName(), $info);
264
-			$nodes[] = $node;
265
-		}
266
-		$this->dirContent = $nodes;
267
-		return $this->dirContent;
268
-	}
269
-
270
-	/**
271
-	 * Checks if a child exists.
272
-	 *
273
-	 * @param string $name
274
-	 * @return bool
275
-	 */
276
-	public function childExists($name) {
277
-		// note: here we do NOT resolve the chunk file name to the real file name
278
-		// to make sure we return false when checking for file existence with a chunk
279
-		// file name.
280
-		// This is to make sure that "createFile" is still triggered
281
-		// (required old code) instead of "updateFile".
282
-		//
283
-		// TODO: resolve chunk file name here and implement "updateFile"
284
-		$path = $this->path . '/' . $name;
285
-		return $this->fileView->file_exists($path);
286
-
287
-	}
288
-
289
-	/**
290
-	 * Deletes all files in this directory, and then itself
291
-	 *
292
-	 * @return void
293
-	 * @throws FileLocked
294
-	 * @throws \Sabre\DAV\Exception\Forbidden
295
-	 */
296
-	public function delete() {
297
-
298
-		if ($this->path === '' || $this->path === '/' || !$this->info->isDeletable()) {
299
-			throw new \Sabre\DAV\Exception\Forbidden();
300
-		}
301
-
302
-		try {
303
-			if (!$this->fileView->rmdir($this->path)) {
304
-				// assume it wasn't possible to remove due to permission issue
305
-				throw new \Sabre\DAV\Exception\Forbidden();
306
-			}
307
-		} catch (ForbiddenException $ex) {
308
-			throw new Forbidden($ex->getMessage(), $ex->getRetry());
309
-		} catch (LockedException $e) {
310
-			throw new FileLocked($e->getMessage(), $e->getCode(), $e);
311
-		}
312
-	}
313
-
314
-	/**
315
-	 * Returns available diskspace information
316
-	 *
317
-	 * @return array
318
-	 */
319
-	public function getQuotaInfo() {
320
-		if ($this->quotaInfo) {
321
-			return $this->quotaInfo;
322
-		}
323
-		try {
324
-			$storageInfo = \OC_Helper::getStorageInfo($this->info->getPath(), $this->info);
325
-			if ($storageInfo['quota'] === \OCP\Files\FileInfo::SPACE_UNLIMITED) {
326
-				$free = \OCP\Files\FileInfo::SPACE_UNLIMITED;
327
-			} else {
328
-				$free = $storageInfo['free'];
329
-			}
330
-			$this->quotaInfo = array(
331
-				$storageInfo['used'],
332
-				$free
333
-			);
334
-			return $this->quotaInfo;
335
-		} catch (\OCP\Files\StorageNotAvailableException $e) {
336
-			return array(0, 0);
337
-		}
338
-	}
339
-
340
-	/**
341
-	 * Moves a node into this collection.
342
-	 *
343
-	 * It is up to the implementors to:
344
-	 *   1. Create the new resource.
345
-	 *   2. Remove the old resource.
346
-	 *   3. Transfer any properties or other data.
347
-	 *
348
-	 * Generally you should make very sure that your collection can easily move
349
-	 * the move.
350
-	 *
351
-	 * If you don't, just return false, which will trigger sabre/dav to handle
352
-	 * the move itself. If you return true from this function, the assumption
353
-	 * is that the move was successful.
354
-	 *
355
-	 * @param string $targetName New local file/collection name.
356
-	 * @param string $fullSourcePath Full path to source node
357
-	 * @param INode $sourceNode Source node itself
358
-	 * @return bool
359
-	 * @throws BadRequest
360
-	 * @throws ServiceUnavailable
361
-	 * @throws Forbidden
362
-	 * @throws FileLocked
363
-	 * @throws \Sabre\DAV\Exception\Forbidden
364
-	 */
365
-	public function moveInto($targetName, $fullSourcePath, INode $sourceNode) {
366
-		if (!$sourceNode instanceof Node) {
367
-			// it's a file of another kind, like FutureFile
368
-			if ($sourceNode instanceof IFile) {
369
-				// fallback to default copy+delete handling
370
-				return false;
371
-			}
372
-			throw new BadRequest('Incompatible node types');
373
-		}
374
-
375
-		if (!$this->fileView) {
376
-			throw new ServiceUnavailable('filesystem not setup');
377
-		}
378
-
379
-		$destinationPath = $this->getPath() . '/' . $targetName;
380
-
381
-
382
-		$targetNodeExists = $this->childExists($targetName);
383
-
384
-		// at getNodeForPath we also check the path for isForbiddenFileOrDir
385
-		// with that we have covered both source and destination
386
-		if ($sourceNode instanceof Directory && $targetNodeExists) {
387
-			throw new \Sabre\DAV\Exception\Forbidden('Could not copy directory ' . $sourceNode->getName() . ', target exists');
388
-		}
389
-
390
-		list($sourceDir,) = \Sabre\HTTP\URLUtil::splitPath($sourceNode->getPath());
391
-		$destinationDir = $this->getPath();
392
-
393
-		$sourcePath = $sourceNode->getPath();
394
-
395
-		$isMovableMount = false;
396
-		$sourceMount = \OC::$server->getMountManager()->find($this->fileView->getAbsolutePath($sourcePath));
397
-		$internalPath = $sourceMount->getInternalPath($this->fileView->getAbsolutePath($sourcePath));
398
-		if ($sourceMount instanceof MoveableMount && $internalPath === '') {
399
-			$isMovableMount = true;
400
-		}
401
-
402
-		try {
403
-			$sameFolder = ($sourceDir === $destinationDir);
404
-			// if we're overwriting or same folder
405
-			if ($targetNodeExists || $sameFolder) {
406
-				// note that renaming a share mount point is always allowed
407
-				if (!$this->fileView->isUpdatable($destinationDir) && !$isMovableMount) {
408
-					throw new \Sabre\DAV\Exception\Forbidden();
409
-				}
410
-			} else {
411
-				if (!$this->fileView->isCreatable($destinationDir)) {
412
-					throw new \Sabre\DAV\Exception\Forbidden();
413
-				}
414
-			}
415
-
416
-			if (!$sameFolder) {
417
-				// moving to a different folder, source will be gone, like a deletion
418
-				// note that moving a share mount point is always allowed
419
-				if (!$this->fileView->isDeletable($sourcePath) && !$isMovableMount) {
420
-					throw new \Sabre\DAV\Exception\Forbidden();
421
-				}
422
-			}
423
-
424
-			$fileName = basename($destinationPath);
425
-			try {
426
-				$this->fileView->verifyPath($destinationDir, $fileName);
427
-			} catch (InvalidPathException $ex) {
428
-				throw new InvalidPath($ex->getMessage());
429
-			}
430
-
431
-			$renameOkay = $this->fileView->rename($sourcePath, $destinationPath);
432
-			if (!$renameOkay) {
433
-				throw new \Sabre\DAV\Exception\Forbidden('');
434
-			}
435
-		} catch (StorageNotAvailableException $e) {
436
-			throw new ServiceUnavailable($e->getMessage());
437
-		} catch (ForbiddenException $ex) {
438
-			throw new Forbidden($ex->getMessage(), $ex->getRetry());
439
-		} catch (LockedException $e) {
440
-			throw new FileLocked($e->getMessage(), $e->getCode(), $e);
441
-		}
442
-
443
-		return true;
444
-	}
52
+    implements \Sabre\DAV\ICollection, \Sabre\DAV\IQuota, \Sabre\DAV\IMoveTarget {
53
+
54
+    /**
55
+     * Cached directory content
56
+     *
57
+     * @var \OCP\Files\FileInfo[]
58
+     */
59
+    private $dirContent;
60
+
61
+    /**
62
+     * Cached quota info
63
+     *
64
+     * @var array
65
+     */
66
+    private $quotaInfo;
67
+
68
+    /**
69
+     * @var ObjectTree|null
70
+     */
71
+    private $tree;
72
+
73
+    /**
74
+     * Sets up the node, expects a full path name
75
+     *
76
+     * @param \OC\Files\View $view
77
+     * @param \OCP\Files\FileInfo $info
78
+     * @param ObjectTree|null $tree
79
+     * @param \OCP\Share\IManager $shareManager
80
+     */
81
+    public function __construct(View $view, FileInfo $info, $tree = null, $shareManager = null) {
82
+        parent::__construct($view, $info, $shareManager);
83
+        $this->tree = $tree;
84
+    }
85
+
86
+    /**
87
+     * Creates a new file in the directory
88
+     *
89
+     * Data will either be supplied as a stream resource, or in certain cases
90
+     * as a string. Keep in mind that you may have to support either.
91
+     *
92
+     * After successful creation of the file, you may choose to return the ETag
93
+     * of the new file here.
94
+     *
95
+     * The returned ETag must be surrounded by double-quotes (The quotes should
96
+     * be part of the actual string).
97
+     *
98
+     * If you cannot accurately determine the ETag, you should not return it.
99
+     * If you don't store the file exactly as-is (you're transforming it
100
+     * somehow) you should also not return an ETag.
101
+     *
102
+     * This means that if a subsequent GET to this new file does not exactly
103
+     * return the same contents of what was submitted here, you are strongly
104
+     * recommended to omit the ETag.
105
+     *
106
+     * @param string $name Name of the file
107
+     * @param resource|string $data Initial payload
108
+     * @return null|string
109
+     * @throws Exception\EntityTooLarge
110
+     * @throws Exception\UnsupportedMediaType
111
+     * @throws FileLocked
112
+     * @throws InvalidPath
113
+     * @throws \Sabre\DAV\Exception
114
+     * @throws \Sabre\DAV\Exception\BadRequest
115
+     * @throws \Sabre\DAV\Exception\Forbidden
116
+     * @throws \Sabre\DAV\Exception\ServiceUnavailable
117
+     */
118
+    public function createFile($name, $data = null) {
119
+
120
+        try {
121
+            // for chunked upload also updating a existing file is a "createFile"
122
+            // because we create all the chunks before re-assemble them to the existing file.
123
+            if (isset($_SERVER['HTTP_OC_CHUNKED'])) {
124
+
125
+                // exit if we can't create a new file and we don't updatable existing file
126
+                $chunkInfo = \OC_FileChunking::decodeName($name);
127
+                if (!$this->fileView->isCreatable($this->path) &&
128
+                    !$this->fileView->isUpdatable($this->path . '/' . $chunkInfo['name'])
129
+                ) {
130
+                    throw new \Sabre\DAV\Exception\Forbidden();
131
+                }
132
+
133
+            } else {
134
+                // For non-chunked upload it is enough to check if we can create a new file
135
+                if (!$this->fileView->isCreatable($this->path)) {
136
+                    throw new \Sabre\DAV\Exception\Forbidden();
137
+                }
138
+            }
139
+
140
+            $this->fileView->verifyPath($this->path, $name);
141
+
142
+            $path = $this->fileView->getAbsolutePath($this->path) . '/' . $name;
143
+            // in case the file already exists/overwriting
144
+            $info = $this->fileView->getFileInfo($this->path . '/' . $name);
145
+            if (!$info) {
146
+                // use a dummy FileInfo which is acceptable here since it will be refreshed after the put is complete
147
+                $info = new \OC\Files\FileInfo($path, null, null, [], null);
148
+            }
149
+            $node = new \OCA\DAV\Connector\Sabre\File($this->fileView, $info);
150
+            $node->acquireLock(ILockingProvider::LOCK_SHARED);
151
+            return $node->put($data);
152
+        } catch (\OCP\Files\StorageNotAvailableException $e) {
153
+            throw new \Sabre\DAV\Exception\ServiceUnavailable($e->getMessage());
154
+        } catch (InvalidPathException $ex) {
155
+            throw new InvalidPath($ex->getMessage());
156
+        } catch (ForbiddenException $ex) {
157
+            throw new Forbidden($ex->getMessage(), $ex->getRetry());
158
+        } catch (LockedException $e) {
159
+            throw new FileLocked($e->getMessage(), $e->getCode(), $e);
160
+        }
161
+    }
162
+
163
+    /**
164
+     * Creates a new subdirectory
165
+     *
166
+     * @param string $name
167
+     * @throws FileLocked
168
+     * @throws InvalidPath
169
+     * @throws \Sabre\DAV\Exception\Forbidden
170
+     * @throws \Sabre\DAV\Exception\ServiceUnavailable
171
+     */
172
+    public function createDirectory($name) {
173
+        try {
174
+            if (!$this->info->isCreatable()) {
175
+                throw new \Sabre\DAV\Exception\Forbidden();
176
+            }
177
+
178
+            $this->fileView->verifyPath($this->path, $name);
179
+            $newPath = $this->path . '/' . $name;
180
+            if (!$this->fileView->mkdir($newPath)) {
181
+                throw new \Sabre\DAV\Exception\Forbidden('Could not create directory ' . $newPath);
182
+            }
183
+        } catch (\OCP\Files\StorageNotAvailableException $e) {
184
+            throw new \Sabre\DAV\Exception\ServiceUnavailable($e->getMessage());
185
+        } catch (InvalidPathException $ex) {
186
+            throw new InvalidPath($ex->getMessage());
187
+        } catch (ForbiddenException $ex) {
188
+            throw new Forbidden($ex->getMessage(), $ex->getRetry());
189
+        } catch (LockedException $e) {
190
+            throw new FileLocked($e->getMessage(), $e->getCode(), $e);
191
+        }
192
+    }
193
+
194
+    /**
195
+     * Returns a specific child node, referenced by its name
196
+     *
197
+     * @param string $name
198
+     * @param \OCP\Files\FileInfo $info
199
+     * @return \Sabre\DAV\INode
200
+     * @throws InvalidPath
201
+     * @throws \Sabre\DAV\Exception\NotFound
202
+     * @throws \Sabre\DAV\Exception\ServiceUnavailable
203
+     */
204
+    public function getChild($name, $info = null) {
205
+        if (!$this->info->isReadable()) {
206
+            // avoid detecting files through this way
207
+            throw new NotFound();
208
+        }
209
+
210
+        $path = $this->path . '/' . $name;
211
+        if (is_null($info)) {
212
+            try {
213
+                $this->fileView->verifyPath($this->path, $name);
214
+                $info = $this->fileView->getFileInfo($path);
215
+            } catch (\OCP\Files\StorageNotAvailableException $e) {
216
+                throw new \Sabre\DAV\Exception\ServiceUnavailable($e->getMessage());
217
+            } catch (InvalidPathException $ex) {
218
+                throw new InvalidPath($ex->getMessage());
219
+            } catch (ForbiddenException $e) {
220
+                throw new \Sabre\DAV\Exception\Forbidden();
221
+            }
222
+        }
223
+
224
+        if (!$info) {
225
+            throw new \Sabre\DAV\Exception\NotFound('File with name ' . $path . ' could not be located');
226
+        }
227
+
228
+        if ($info['mimetype'] == 'httpd/unix-directory') {
229
+            $node = new \OCA\DAV\Connector\Sabre\Directory($this->fileView, $info, $this->tree, $this->shareManager);
230
+        } else {
231
+            $node = new \OCA\DAV\Connector\Sabre\File($this->fileView, $info, $this->shareManager);
232
+        }
233
+        if ($this->tree) {
234
+            $this->tree->cacheNode($node);
235
+        }
236
+        return $node;
237
+    }
238
+
239
+    /**
240
+     * Returns an array with all the child nodes
241
+     *
242
+     * @return \Sabre\DAV\INode[]
243
+     * @throws \Sabre\DAV\Exception\Locked
244
+     * @throws \OCA\DAV\Connector\Sabre\Exception\Forbidden
245
+     */
246
+    public function getChildren() {
247
+        if (!is_null($this->dirContent)) {
248
+            return $this->dirContent;
249
+        }
250
+        try {
251
+            if (!$this->info->isReadable()) {
252
+                // return 403 instead of 404 because a 404 would make
253
+                // the caller believe that the collection itself does not exist
254
+                throw new Forbidden('No read permissions');
255
+            }
256
+            $folderContent = $this->fileView->getDirectoryContent($this->path);
257
+        } catch (LockedException $e) {
258
+            throw new Locked();
259
+        }
260
+
261
+        $nodes = array();
262
+        foreach ($folderContent as $info) {
263
+            $node = $this->getChild($info->getName(), $info);
264
+            $nodes[] = $node;
265
+        }
266
+        $this->dirContent = $nodes;
267
+        return $this->dirContent;
268
+    }
269
+
270
+    /**
271
+     * Checks if a child exists.
272
+     *
273
+     * @param string $name
274
+     * @return bool
275
+     */
276
+    public function childExists($name) {
277
+        // note: here we do NOT resolve the chunk file name to the real file name
278
+        // to make sure we return false when checking for file existence with a chunk
279
+        // file name.
280
+        // This is to make sure that "createFile" is still triggered
281
+        // (required old code) instead of "updateFile".
282
+        //
283
+        // TODO: resolve chunk file name here and implement "updateFile"
284
+        $path = $this->path . '/' . $name;
285
+        return $this->fileView->file_exists($path);
286
+
287
+    }
288
+
289
+    /**
290
+     * Deletes all files in this directory, and then itself
291
+     *
292
+     * @return void
293
+     * @throws FileLocked
294
+     * @throws \Sabre\DAV\Exception\Forbidden
295
+     */
296
+    public function delete() {
297
+
298
+        if ($this->path === '' || $this->path === '/' || !$this->info->isDeletable()) {
299
+            throw new \Sabre\DAV\Exception\Forbidden();
300
+        }
301
+
302
+        try {
303
+            if (!$this->fileView->rmdir($this->path)) {
304
+                // assume it wasn't possible to remove due to permission issue
305
+                throw new \Sabre\DAV\Exception\Forbidden();
306
+            }
307
+        } catch (ForbiddenException $ex) {
308
+            throw new Forbidden($ex->getMessage(), $ex->getRetry());
309
+        } catch (LockedException $e) {
310
+            throw new FileLocked($e->getMessage(), $e->getCode(), $e);
311
+        }
312
+    }
313
+
314
+    /**
315
+     * Returns available diskspace information
316
+     *
317
+     * @return array
318
+     */
319
+    public function getQuotaInfo() {
320
+        if ($this->quotaInfo) {
321
+            return $this->quotaInfo;
322
+        }
323
+        try {
324
+            $storageInfo = \OC_Helper::getStorageInfo($this->info->getPath(), $this->info);
325
+            if ($storageInfo['quota'] === \OCP\Files\FileInfo::SPACE_UNLIMITED) {
326
+                $free = \OCP\Files\FileInfo::SPACE_UNLIMITED;
327
+            } else {
328
+                $free = $storageInfo['free'];
329
+            }
330
+            $this->quotaInfo = array(
331
+                $storageInfo['used'],
332
+                $free
333
+            );
334
+            return $this->quotaInfo;
335
+        } catch (\OCP\Files\StorageNotAvailableException $e) {
336
+            return array(0, 0);
337
+        }
338
+    }
339
+
340
+    /**
341
+     * Moves a node into this collection.
342
+     *
343
+     * It is up to the implementors to:
344
+     *   1. Create the new resource.
345
+     *   2. Remove the old resource.
346
+     *   3. Transfer any properties or other data.
347
+     *
348
+     * Generally you should make very sure that your collection can easily move
349
+     * the move.
350
+     *
351
+     * If you don't, just return false, which will trigger sabre/dav to handle
352
+     * the move itself. If you return true from this function, the assumption
353
+     * is that the move was successful.
354
+     *
355
+     * @param string $targetName New local file/collection name.
356
+     * @param string $fullSourcePath Full path to source node
357
+     * @param INode $sourceNode Source node itself
358
+     * @return bool
359
+     * @throws BadRequest
360
+     * @throws ServiceUnavailable
361
+     * @throws Forbidden
362
+     * @throws FileLocked
363
+     * @throws \Sabre\DAV\Exception\Forbidden
364
+     */
365
+    public function moveInto($targetName, $fullSourcePath, INode $sourceNode) {
366
+        if (!$sourceNode instanceof Node) {
367
+            // it's a file of another kind, like FutureFile
368
+            if ($sourceNode instanceof IFile) {
369
+                // fallback to default copy+delete handling
370
+                return false;
371
+            }
372
+            throw new BadRequest('Incompatible node types');
373
+        }
374
+
375
+        if (!$this->fileView) {
376
+            throw new ServiceUnavailable('filesystem not setup');
377
+        }
378
+
379
+        $destinationPath = $this->getPath() . '/' . $targetName;
380
+
381
+
382
+        $targetNodeExists = $this->childExists($targetName);
383
+
384
+        // at getNodeForPath we also check the path for isForbiddenFileOrDir
385
+        // with that we have covered both source and destination
386
+        if ($sourceNode instanceof Directory && $targetNodeExists) {
387
+            throw new \Sabre\DAV\Exception\Forbidden('Could not copy directory ' . $sourceNode->getName() . ', target exists');
388
+        }
389
+
390
+        list($sourceDir,) = \Sabre\HTTP\URLUtil::splitPath($sourceNode->getPath());
391
+        $destinationDir = $this->getPath();
392
+
393
+        $sourcePath = $sourceNode->getPath();
394
+
395
+        $isMovableMount = false;
396
+        $sourceMount = \OC::$server->getMountManager()->find($this->fileView->getAbsolutePath($sourcePath));
397
+        $internalPath = $sourceMount->getInternalPath($this->fileView->getAbsolutePath($sourcePath));
398
+        if ($sourceMount instanceof MoveableMount && $internalPath === '') {
399
+            $isMovableMount = true;
400
+        }
401
+
402
+        try {
403
+            $sameFolder = ($sourceDir === $destinationDir);
404
+            // if we're overwriting or same folder
405
+            if ($targetNodeExists || $sameFolder) {
406
+                // note that renaming a share mount point is always allowed
407
+                if (!$this->fileView->isUpdatable($destinationDir) && !$isMovableMount) {
408
+                    throw new \Sabre\DAV\Exception\Forbidden();
409
+                }
410
+            } else {
411
+                if (!$this->fileView->isCreatable($destinationDir)) {
412
+                    throw new \Sabre\DAV\Exception\Forbidden();
413
+                }
414
+            }
415
+
416
+            if (!$sameFolder) {
417
+                // moving to a different folder, source will be gone, like a deletion
418
+                // note that moving a share mount point is always allowed
419
+                if (!$this->fileView->isDeletable($sourcePath) && !$isMovableMount) {
420
+                    throw new \Sabre\DAV\Exception\Forbidden();
421
+                }
422
+            }
423
+
424
+            $fileName = basename($destinationPath);
425
+            try {
426
+                $this->fileView->verifyPath($destinationDir, $fileName);
427
+            } catch (InvalidPathException $ex) {
428
+                throw new InvalidPath($ex->getMessage());
429
+            }
430
+
431
+            $renameOkay = $this->fileView->rename($sourcePath, $destinationPath);
432
+            if (!$renameOkay) {
433
+                throw new \Sabre\DAV\Exception\Forbidden('');
434
+            }
435
+        } catch (StorageNotAvailableException $e) {
436
+            throw new ServiceUnavailable($e->getMessage());
437
+        } catch (ForbiddenException $ex) {
438
+            throw new Forbidden($ex->getMessage(), $ex->getRetry());
439
+        } catch (LockedException $e) {
440
+            throw new FileLocked($e->getMessage(), $e->getCode(), $e);
441
+        }
442
+
443
+        return true;
444
+    }
445 445
 }
Please login to merge, or discard this patch.