2323use OCP \Server ;
2424use OCP \Share \Exceptions \ShareNotFound ;
2525use OCP \Share \IManager ;
26+ use Sabre \DAV \Exception \Forbidden ;
2627
2728abstract 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