Skip to content

Commit d021c18

Browse files
committed
fix: allow renaming files with just update permissions
Signed-off-by: Robin Appelman <robin@icewind.nl>
1 parent 8e996fc commit d021c18

2 files changed

Lines changed: 41 additions & 8 deletions

File tree

apps/dav/lib/Connector/Sabre/FilesPlugin.php

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -205,10 +205,19 @@ public function checkMove(string $source, string $target): void {
205205
// First check copyable (move only needs additional delete permission)
206206
$this->checkCopy($source, $target);
207207

208-
// The source needs to be deletable for moving
209-
$sourceNodeFileInfo = $sourceNode->getFileInfo();
210-
if (!$sourceNodeFileInfo->isDeletable()) {
211-
throw new Forbidden($source . ' cannot be deleted');
208+
[$sourceDir] = \Sabre\Uri\split($source);
209+
[$destinationDir, ] = \Sabre\Uri\split($target);
210+
211+
if ($sourceDir === $destinationDir) {
212+
if (!$sourceNode->canRename()) {
213+
throw new Forbidden($source . ' cannot be renamed');
214+
}
215+
} else {
216+
// The source needs to be deletable for moving
217+
$sourceNodeFileInfo = $sourceNode->getFileInfo();
218+
if (!$sourceNodeFileInfo->isDeletable()) {
219+
throw new Forbidden($source . ' cannot be deleted');
220+
}
212221
}
213222

214223
// The source is not allowed to be the parent of the target

apps/dav/lib/Connector/Sabre/Node.php

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
use OCP\Server;
2424
use OCP\Share\Exceptions\ShareNotFound;
2525
use OCP\Share\IManager;
26+
use Sabre\DAV\Exception\Forbidden;
2627

2728
abstract class Node implements \Sabre\DAV\INode {
2829
/**
@@ -110,6 +111,31 @@ public function getPath() {
110111
return $this->path;
111112
}
112113

114+
/**
115+
* Check if this node can be renamed
116+
*/
117+
public function canRename(): bool {
118+
// the root of a movable mountpoint can be renamed regardless of the file permissions
119+
if ($this->info->getMountPoint() instanceof MoveableMount && $this->info->getInternalPath() === '') {
120+
return true;
121+
}
122+
123+
// we allow renaming the file if either the file has update permissions
124+
if ($this->info->isUpdateable()) {
125+
return true;
126+
}
127+
128+
// or the file can be deleted and the parent has create permissions
129+
[$parentPath,] = \Sabre\Uri\split($this->path);
130+
if ($parentPath === null) {
131+
// can't rename the users home
132+
return false;
133+
}
134+
135+
$parent = $this->node->getParent();
136+
return $this->info->isDeletable() && $parent->isCreatable();
137+
}
138+
113139
/**
114140
* Renames the node
115141
*
@@ -118,10 +144,8 @@ public function getPath() {
118144
* @throws \Sabre\DAV\Exception\Forbidden
119145
*/
120146
public function setName($name) {
121-
// rename is only allowed if the delete privilege is granted
122-
// (basically rename is a copy with delete of the original node)
123-
if (!($this->info->isDeletable() || ($this->info->getMountPoint() instanceof MoveableMount && $this->info->getInternalPath() === ''))) {
124-
throw new \Sabre\DAV\Exception\Forbidden();
147+
if (!$this->canRename()) {
148+
throw new Forbidden('');
125149
}
126150

127151
[$parentPath,] = \Sabre\Uri\split($this->path);

0 commit comments

Comments
 (0)