E530 feat: make direct-edit token consumption transactional and race-safe; defer deletion to successful open paths by joshtrichards · Pull Request #5465 · nextcloud/richdocuments · GitHub
[go: up one dir, main page]

Skip to content

feat: make direct-edit token consumption transactional and race-safe; defer deletion to successful open paths#5465

Draft
joshtrichards wants to merge 5 commits intomainfrom
jtr/direct-editing-token-deletion-robustness
Draft

feat: make direct-edit token consumption transactional and race-safe; defer deletion to successful open paths#5465
joshtrichards wants to merge 5 commits intomainfrom
jtr/direct-editing-token-deletion-robustness

Conversation

@joshtrichards
Copy link
Member
  • Resolves: #
  • Target version: main

Summary

This PR makes one-time direct-edit token handling in DirectViewController::show() transactional and race-safe.

Previously, tokens were deleted immediately after lookup, so transient failures later in the flow could burn a valid link. This change adds transactional row-level locking (getByToken(..., forUpdate)) and moves deletion to success paths:

  • public share success responses,
  • federated redirect (just before redirect),
  • standard editor open (after successful WOPI/response preparation).

Result: better resilience to transient failures and stronger protection against concurrent replay/race scenarios, with semantics shifted from “consume on first access” to “consume on successful open/redirect.”

Additional Details (Expand)

Changed:

  • Wrapped DirectViewController::show() in a DB transaction
  • Added optional row locking support to DirectMapper::getByToken() and used it in the direct-edit flow
  • Moved token deletion from eager/immediate to success-path deletion:
    • Public share path: delete only after successful(ish) response.
    • Federated redirect path: delete immediately before redirect.
    • Standard editor open path: delete after successful WOPI/response preparation.

Why:

  • Avoids premature token burn on transient failures (better UX).
  • Serializes concurrent requests for the same token (better race/replay resistance).
  • Keeps behavior close to existing flow with focused changes.

Security impact:

  • Before: eager deletion could invalidate links on transient failure; concurrent requests had weaker serialization.
  • After: row-level locking + transaction improves concurrency safety and reduces replay via racing requests.
  • Tradeoff: with success-path deletion, strict “consume on first access” semantics become “consume on successful open/redirect.”

Net: positive hardening, especially for concurrency/replay races, with an intentional UX/security tradeoff.

Transaction impact:

The token row lock may be held longer (through more request work), which can increase lock wait time for concurrent hits on the same token. Expected impact is typically modest and localized to that token. A future token state machine could reduce lock duration while preserving correctness.

TODO

  • Add/update tests if we want to merge this

Checklist

  • Code is properly formatted
  • Sign-off message is added to all commits
  • Documentation (manuals or wiki) has been updated or is not required

Signed-off-by: Josh <josh.t.richards@gmail.com>
Signed-off-by: Josh <josh.t.richards@gmail.com>
- strict_types
- parameter type hints
- function return typing

Signed-off-by: Josh <josh.t.richards@gmail.com>
Signed-off-by: Josh <josh.t.richards@gmail.com>
Signed-off-by: Josh <josh.t.richards@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

0