Fix delete remote directory hang and add UMASK env var#92
Fix delete remote directory hang and add UMASK env var#92nitrobass24 merged 2 commits intodevelopfrom
Conversation
The UI loading spinner never cleared when deleting a remote directory that was already downloaded, because ngOnChanges only checked for status changes. For DELETE_REMOTE on a DOWNLOADED file, the status stays DOWNLOADED (file still exists locally) — only remoteSize changes to 0. - Clear activeAction when isRemotelyDeletable/isLocallyDeletable transitions from true to false (not just on status changes) - Remove silent SshcpError catch in DeleteRemoteProcess so errors propagate; add INFO-level logging for delete start/success - Wrap propagate_exception() in controller cleanup_commands so command process failures log a warning instead of crashing the controller - Add unit tests for the new ngOnChanges spinner-clearing logic Fixes #86 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review infoConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro 📒 Files selected for processing (4)
📝 WalkthroughWalkthroughAdds unit tests for FileComponent.onChanges, tightens frontend logic to clear action when status or deletability changes, makes controller cleanup tolerant to propagate_exception failures, and simplifies remote-delete SSH handling and logging. Changes
Sequence Diagram(s)sequenceDiagram
participant Client as File UI
participant Frontend as FileComponent
participant Controller as Backend Controller
participant DeleteProc as DeleteProcess
participant SSH as Remote SSH
Client->>Frontend: user triggers delete remote
Frontend->>Controller: send delete request
Controller->>DeleteProc: start remote delete
DeleteProc->>SSH: execute rm -rf <escaped-path>
SSH-->>DeleteProc: command output / exit status
DeleteProc-->>Controller: success / failure
Controller->>Controller: cleanup commands
Controller--xDeleteProc: propagate_exception() guarded (logged on exception)
Controller-->>Frontend: respond with operation result
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/python/controller/delete/delete_process.py`:
- Around line 50-53: The branch that handles file paths starting with "~"
currently calls escape_remote_path_double which leaves the path wrapped in
double quotes and allows shell expansion; instead expand the tilde to the actual
home path (e.g., via os.path.expanduser or equivalent) and then call
escape_remote_path_single so the resolved path is single-quote escaped and
prevents shell expansion/injection; update the code path where
file_path.startswith("~") to first expand the user and then pass the result to
escape_remote_path_single (referencing file_path.startswith,
escape_remote_path_double, escape_remote_path_single).
ℹ️ Review info
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (4)
src/angular/src/app/pages/files/file.component.spec.tssrc/angular/src/app/pages/files/file.component.tssrc/python/controller/controller.pysrc/python/controller/delete/delete_process.py
| if file_path.startswith("~"): | ||
| escaped_path = escape_remote_path_double(file_path) | ||
| else: | ||
| escaped_path = escape_remote_path_single(file_path) |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# First, locate and examine the escape helper functions
echo "=== Searching for escape_remote_path helpers ==="
find src/python -type f -name "*.py" | xargs grep -l "def escape_remote_path"
# Then get the implementation details
echo ""
echo "=== Helper implementations and usage context ==="
rg -n -C5 'def escape_remote_path_double|def escape_remote_path_single' src/python/
# Check the delete_process.py context around lines 50-53
echo ""
echo "=== Context around delete_process.py lines 50-53 ==="
rg -n -C8 'startswith\("~"\)' src/python/controller/delete/delete_process.pyRepository: nitrobass24/seedsync
Length of output: 2382
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Get the complete escape_remote_path_double function
cat src/python/common/remote_path_utils.pyRepository: nitrobass24/seedsync
Length of output: 684
Harden ~ path escaping to avoid shell expansion/injection.
At line 51, the ~ branch uses escape_remote_path_double(), which converts ~ to $HOME and wraps in double quotes. However, double quotes do not escape shell-expanding characters ($, backticks, \, "), allowing crafted file names to execute arbitrary commands. For example, a path like ~/.ssh/$(malicious_command) would execute the embedded command.
Use single-quote escaping (which prevents all expansion) after resolving the home directory:
🔧 Safer approach
- if file_path.startswith("~"):
- escaped_path = escape_remote_path_double(file_path)
- else:
- escaped_path = escape_remote_path_single(file_path)
+ if file_path.startswith("~"):
+ remote_home = self.__ssh.shell('printf "%s" "$HOME"').decode("utf-8", errors="strict")
+ file_path = remote_home + file_path[1:]
+ escaped_path = escape_remote_path_single(file_path)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/python/controller/delete/delete_process.py` around lines 50 - 53, The
branch that handles file paths starting with "~" currently calls
escape_remote_path_double which leaves the path wrapped in double quotes and
allows shell expansion; instead expand the tilde to the actual home path (e.g.,
via os.path.expanduser or equivalent) and then call escape_remote_path_single so
the resolved path is single-quote escaped and prevents shell
expansion/injection; update the code path where file_path.startswith("~") to
first expand the user and then pass the result to escape_remote_path_single
(referencing file_path.startswith, escape_remote_path_double,
escape_remote_path_single).
Allow users to set a UMASK via Docker environment variable so downloaded and extracted files get permissive permissions (e.g. 666/777), enabling other services like Plex and Sonarr to read/write files on shared volumes. Fixes #91. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary
UMASKenv var (e.g.002for 775/664,000for 777/666), so other services like Plex and Sonarr can read/write files on shared volumes. Fixes BUG: 0.12.4 - DL file permissions #91.Test plan
make buildUMASK=000, download a file, verify permissions are 666/777UMASK=002, verify permissions are 664/775🤖 Generated with Claude Code
Summary by CodeRabbit
Bug Fixes
Tests
Documentation / Deployment