{"record":{"id":"5f62358de8122aee","repo":"nextcloud/server","slug":"only-authors-are-allowed-to-edit-their-comment","errorCode":null,"errorMessage":"Only authors are allowed to edit their comment.","messagePattern":"Only authors are allowed to edit their comment\\.","errorType":"http","errorClass":"Sabre\\DAV\\Exception\\Forbidden","httpStatus":403,"severity":"error","filePath":"apps/dav/lib/Comments/CommentNode.php","lineNumber":96,"sourceCode":"\t\t\t// re-used property names are defined as constants\n\t\t\tself::PROPERTY_NAME_MESSAGE,\n\t\t\tself::PROPERTY_NAME_ACTOR_DISPLAYNAME,\n\t\t\tself::PROPERTY_NAME_UNREAD,\n\t\t\tself::PROPERTY_NAME_MENTIONS,\n\t\t\tself::PROPERTY_NAME_MENTION,\n\t\t\tself::PROPERTY_NAME_MENTION_TYPE,\n\t\t\tself::PROPERTY_NAME_MENTION_ID,\n\t\t\tself::PROPERTY_NAME_MENTION_DISPLAYNAME,\n\t\t];\n\t}\n\n\tprotected function checkWriteAccessOnComment() {\n\t\t$user = $this->userSession->getUser();\n\t\tif ($this->comment->getActorType() !== 'users'\n\t\t\t|| is_null($user)\n\t\t\t|| $this->comment->getActorId() !== $user->getUID()\n\t\t) {\n\t\t\tthrow new Forbidden('Only authors are allowed to edit their comment.');\n\t\t}\n\t}\n\n\t/**\n\t * Deleted the current node\n\t *\n\t * @return void\n\t */\n\t#[\\Override]\n\tpublic function delete() {\n\t\t$this->checkWriteAccessOnComment();\n\t\t$this->commentsManager->delete($this->comment->getId());\n\t}\n\n\t/**\n\t * Returns the name of the node.\n\t *\n\t * This is used to generate the url.","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/nextcloud/server/blob/ecdeb153ffdf227235c9a7e2d13dbe0f9c817bc3/apps/dav/lib/Comments/CommentNode.php#L78-L114","documentation":"Sabre\\DAV\\Exception\\Forbidden thrown by CommentNode::checkWriteAccessOnComment() (apps/dav/lib/Comments/CommentNode.php:96). A comment DAV node may only be modified or deleted by its author: the actor type must be 'users', a user must be logged in, and the comment's actorId must equal the session user's UID.","triggerScenarios":"DELETE or PROPPATCH on /remote.php/dav/comments/files/<fileId>/<commentId> by a session user that differs from the comment author, by an unauthenticated request, or on a comment authored by a non-user actor (guests, bots with other actor types).","commonSituations":"Apps or scripts that try to moderate/edit other users' comments over the DAV API; expired sessions during comment edits; attempting to manage system/actor comments.","solutions":["Authenticate as the user who created the comment before issuing DELETE/PROPPATCH","For moderation, use the CommentsManager API / admin tooling, not the DAV comment node","If editing your own comment fails, re-check that the request carries the correct authenticated session (not app credentials of a different principal)"],"exampleFix":"// before: app tries to delete another user's comment via DAV\n$client->request('DELETE', \"/remote.php/dav/comments/files/$fileId/$commentId\");\n// after: only the author path succeeds; others get 403 - handle it\ntry {\n    $client->request('DELETE', \"/remote.php/dav/comments/files/$fileId/$commentId\");\n} catch (Exception\\Forbidden $e) { /* not the author: ignore or escalate */ }","handlingStrategy":"try-catch","validationCode":"$user = $userSession->getUser();\n$mayEdit = $user !== null\n    && $comment->getActorType() === 'users'\n    && $comment->getActorId() === $user->getUID();\nif (!$mayEdit) {\n    // hide edit affordances instead of letting the request 403\n}","typeGuard":"function canEditComment(?\\OCP\\IUser $user, \\OCP\\Comments\\IComment $comment): bool {\n    return $user !== null\n        && $comment->getActorType() === 'users'\n        && $comment->getActorId() === $user->getUID();\n}","tryCatchPattern":"try {\n    $client->request('DELETE', $commentUri);\n} catch (\\Sabre\\DAV\\Exception\\Forbidden $e) {\n    // not the author: surface 'you can only edit your own comments', never retry\n}","preventionTips":["Show edit/delete controls only to the author","Use CommentsManager or moderation APIs for admin actions","Keep sessions valid; unauthenticated PROPPATCH always 403s"],"tags":["dav","comments","forbidden","http-403","authorization","author-only"],"backgroundTag":"http-403-forbidden","analyzedSha":"ecdeb153ffdf227235c9a7e2d13dbe0f9c817bc3","analyzedAt":"2026-08-17T01:36:13.386Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}