Skip to content

Fix daemon deauthorize and cancel transfer requests to match Wings API - #2576

Open
lancepioch wants to merge 1 commit into
mainfrom
fix/deauthorize-cancel-transfer-wings-contract
Open

lancepioch wants to merge 1 commit into
mainfrom
fix/deauthorize-cancel-transfer-wings-contract

Conversation

@lancepioch

Copy link
Copy Markdown
Member

Fixes #2566.

RevokeSftpAccessJob always failed when dispatched with a node because deauthorize() read the uninitialized $server typed property, so the job died before sending anything and open SFTP/websocket sessions were never revoked on password change or user deletion. The check is now isset($this->server), which is the only line that treats the property as nullable; the other methods that read $this->server directly are unchanged so an unset server still fails loudly.

While writing tests against the real payload it turned out both deauthorize() and cancelTransfer() wrapped their bodies in a json key, which Laravel's HTTP client nests into the request body, so Wings bound an empty struct. The payloads are now flat, and the destination-node cancel now calls DELETE /api/transfers/{uuid} since the old DELETE /api/transfer route no longer exists in Wings and returned 404.

The existing job tests mocked DaemonServerRepository, which is why none of this was caught; the new tests run the real repository against Http::fake() and assert the wire format Wings binds (postDeauthorizeUser and deleteTransfer in router_system.go/router_transfer.go).

Verified against a real Wings 1.0.0-beta29 instance registered to a local panel: node-path and server-path deauthorize both return 204 (the node path previously threw before any request), and the source-node cancel returns the expected 409 when no transfer is active. Note the destination cancel currently 500s on the Wings side regardless of caller: protected.DELETE("/api/transfers/:server", ...) is registered without middleware.ServerExists() but the handler calls ExtractServer, so it panics; that needs a one-line middleware fix in Wings.

RevokeSftpAccessJob always failed on the node path because deauthorize()
read the uninitialized $server property, so SFTP and websocket sessions
were never revoked on password change or user deletion (#2566). Both
deauthorize() and cancelTransfer() also wrapped their payloads in a
'json' key that Laravel's HTTP client nests into the request body, so
Wings bound an empty payload, and the destination cancel used the stale
DELETE /api/transfer route that current Wings no longer registers.
@coderabbitai

coderabbitai Bot commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Advanced

Run ID: 75298e1c-7a32-43a0-991d-fcc50a5bf2c4

📥 Commits

Reviewing files that changed from the base of the PR and between fdb519e and bbfa5c8.

📒 Files selected for processing (3)
  • app/Repositories/Daemon/DaemonServerRepository.php
  • tests/Integration/Jobs/RevokeSftpAccessJobTest.php
  • tests/Integration/Repositories/Daemon/DaemonServerRepositoryTest.php

Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review.


📝 Walkthrough

Walkthrough

The repository now uses the daemon’s transfer-specific cancellation endpoint and sends flattened deauthorization fields. Integration tests verify deauthorization for nodes and servers, plus transfer cancellation across old and new nodes.

Changes

Daemon request corrections

Layer / File(s) Summary
Deauthorization request handling
app/Repositories/Daemon/DaemonServerRepository.php, tests/Integration/Jobs/RevokeSftpAccessJobTest.php
deauthorize() sends user and servers as top-level fields and uses isset() for the optional server property. Tests verify node and server payloads.
Transfer cancellation endpoint
app/Repositories/Daemon/DaemonServerRepository.php, tests/Integration/Repositories/Daemon/DaemonServerRepositoryTest.php
cancelTransfer() sends DELETE /api/transfers/{uuid} without a payload. The test verifies cancellation requests for both old and new nodes.

Priority: ➖ Normal

Severity of issue fixed: Medium

Merge Risk: ⚪ Minimal · up to bbfa5

The corrected daemon requests match supported Wings transfer routes, with no remaining concrete merge risk identified.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The linked issue is #2566 and covers SFTP deauthorization. The PR also changes cancelTransfer() to call DELETE /api/transfers/{uuid} and adds a transfer-cancellation integration test. These change… Remove the cancelTransfer() implementation change and its transfer-cancellation test from this PR, or link a requirement that explicitly covers transfer cancellation.
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 6 functions across 3 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main changes: fixing daemon deauthorization and transfer cancellation requests to match the Wings API.
Description check ✅ Passed The description is directly related to the changeset and explains the typed-property fix, flattened payloads, updated cancellation endpoint, tests, and known Wings-side limitation.
Linked Issues check ✅ Passed Issue #2566 requires the node path of RevokeSftpAccessJob to complete without reading an uninitialized $server property and to send /api/deauthorize-user. deauthorize() now uses `isset($this->…
Full details: Out of Scope Changes check

Explanation

The linked issue is #2566 and covers SFTP deauthorization. The PR also changes cancelTransfer() to call DELETE /api/transfers/{uuid} and adds a transfer-cancellation integration test. These changes address transfer cancellation, not the linked issue's node deauthorization requirement. The deauthorization payload change and its tests support the linked request behavior.

  • Fix all pre-merge checks with AI

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@lancepioch lancepioch self-assigned this Sep 14, 2026
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.

RevokeSftpAccessJob always fails on the node path: uninitialised $server in deauthorize()

1 participant