Skip to content

Commit

Permalink
Merge pull request #5895 from nextcloud/fix/read-only-updates
Browse files Browse the repository at this point in the history
fix: Ignore pushes of update steps for read only sessions
  • Loading branch information
juliusknorr authored Jun 13, 2024
2 parents 3cb126a + 672d3a8 commit 697b5cd
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 1 deletion.
6 changes: 5 additions & 1 deletion lib/Service/DocumentService.php
Original file line number Diff line number Diff line change
Expand Up @@ -220,11 +220,15 @@ public function writeDocumentState(int $documentId, string $content): void {
*/
public function addStep(Document $document, Session $session, array $steps, int $version, ?string $shareToken): array {
$documentId = $session->getDocumentId();
$readOnly = $this->isReadOnly($this->getFileForSession($session, $shareToken), $shareToken);
$stepsToInsert = [];
$querySteps = [];
$newVersion = $version;
foreach ($steps as $step) {
$message = YjsMessage::fromBase64($step);
if ($readOnly && $message->isUpdate()) {
continue;
}
// Filter out query steps as they would just trigger clients to send their steps again
if ($message->getYjsMessageType() === YjsMessage::YJS_MESSAGE_SYNC && $message->getYjsSyncType() === YjsMessage::YJS_MESSAGE_SYNC_STEP1) {
$querySteps[] = $step;
Expand All @@ -233,7 +237,7 @@ public function addStep(Document $document, Session $session, array $steps, int
}
}
if (count($stepsToInsert) > 0) {
if ($this->isReadOnly($this->getFileForSession($session, $shareToken), $shareToken)) {
if ($readOnly) {
throw new NotPermittedException('Read-only client tries to push steps with changes');
}
$newVersion = $this->insertSteps($document, $session, $stepsToInsert);
Expand Down
13 changes: 13 additions & 0 deletions lib/YjsMessage.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,17 @@ public function getYjsSyncType(): int {
return $syncType;
}

/**
* Based on https://github.com/yjs/y-protocols/blob/master/PROTOCOL.md#handling-read-only-users
*/
public function isUpdate(): bool {
if ($this->getYjsMessageType() === self::YJS_MESSAGE_SYNC) {
if (in_array($this->getYjsSyncType(), [self::YJS_MESSAGE_SYNC_STEP2, self::YJS_MESSAGE_SYNC_UPDATE])) {
return true;
}
}

return false;
}

}

0 comments on commit 697b5cd

Please sign in to comment.