Skip to content

fix(backup): address CodeRabbit and CodeQL findings on PR #439 - #440

Merged
ChuckBuilds merged 1 commit into
fix/backup-restore-fidelityfrom
claude/coderabbit-findings-review-2y75u0
Aug 7, 2026
Merged

fix(backup): address CodeRabbit and CodeQL findings on PR #439#440
ChuckBuilds merged 1 commit into
fix/backup-restore-fidelityfrom
claude/coderabbit-findings-review-2y75u0

Conversation

@ChuckBuilds

Copy link
Copy Markdown
Owner

Addresses the actionable CodeRabbit review comments and the GitHub Advanced Security (CodeQL) alert posted on #439.

Changes

first_time_install.sh

  • The chown/chmod calls on config_secrets.json no longer swallow failures with || true. Both operations are checked, the final owner/group/mode are verified with stat, and the script exits with a clear troubleshooting message if anything is off — instead of printing "✓ Secrets file owned by..." regardless of whether it actually happened.

web_interface/blueprints/api_v3.py

  • _resolve_backup_export_dir()'s writability probe (preferred / ".writetest") was a predictable, shared path — a concurrent resolver could truncate/delete another process's probe. Replaced with tempfile.NamedTemporaryFile, which is exclusive to the call that created it.
  • When the preferred export directory (beside the install) isn't writable and the code falls back to the reinstall-deleted config/backups/exports, that's now logged (preferred path, fallback path, and the OSError) so a Raspberry Pi operator can tell their backups aren't safe from the next reinstall.
  • backup_restore() now sets result.success = False when result.plugins_failed is non-empty. Previously, a restore whose files all landed but whose plugin reinstalls failed still returned HTTP 200 with status: success.
  • plugin_id values (sourced from an uploaded plugins.json) are stringified before being joined into the error message, so a malformed backup with a non-string id can't raise TypeError and replace the detailed partial-restore response with the generic 500 handler.

src/backup_manager.py + api_v3.py (CodeQL: Information exposure through an exception)

  • Raw exception text from restoring a user-uploaded backup no longer flows into RestoreResult.errors / plugins_failed[].error, which round-trip into the JSON response. Each failure now logs the full exception server-side ([Backup] ..., exc_info=True) and reports a category-level message to the client (e.g. "Failed to restore config.json" instead of embedding the raw OSError string/path).

Tests

  • test/test_registry_id_resolution.py: added test_get_plugin_info_resolves_manifest_id, covering the get_plugin_info() delegation path (network-free, fetch_latest_from_github=False) that the existing tests only exercised via get_registry_info().
  • test/test_backup_manager.py: test_restore_honors_options now also asserts that disabling restore_wifi skips ytm_auth and leaves no ytm_auth.json behind, since it rides on the same flag.

Test plan

  • pytest test/test_backup_manager.py test/test_registry_id_resolution.py — 21 passed
  • bash -n first_time_install.sh — syntax OK
  • python -m py_compile on all touched Python files

Generated by Claude Code

- first_time_install.sh: verify chown/chmod succeed and the final
  owner/group/mode on config_secrets.json before reporting success;
  exit with a clear error otherwise instead of swallowing failures.
- api_v3.py: replace the predictable .writetest probe with an
  exclusive NamedTemporaryFile to avoid a race with concurrent
  resolvers; log the preferred/fallback export path and OSError when
  falling back to the reinstall-deleted directory.
- api_v3.py: mark a restore as failed when plugin reinstalls fail,
  even if file restoration itself succeeded, so the endpoint no longer
  reports HTTP 200 success on a partial restore.
- api_v3.py: stringify plugin IDs before joining them into the error
  message so a malformed backup's non-string plugin_id can't raise a
  TypeError and mask the detailed response.
- backup_manager.py / api_v3.py: stop putting raw exception text (originating
  from a user-controlled backup file) into restore results returned to
  the client; log full details server-side instead. Addresses the
  CodeQL "stack trace information exposure" alert.
- test coverage: add a test for get_plugin_info() resolving a
  manifest id, and assert the disabled restore_wifi path also skips
  and omits ytm_auth.json.
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 1ee3bbee-9850-41fc-af92-160102a11d01

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

@codacy-production

Copy link
Copy Markdown

Not up to standards ⛔

🔴 Issues 1 high

Alerts:
⚠ 1 issue (≤ 0 issues of at least minor severity)

Results:
1 new issue

Category Results
Security 1 high

View in Codacy

🟢 Metrics 0 complexity · 0 duplication

Metric Results
Complexity 0
Duplication 0

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

Copy link
Copy Markdown
Owner Author

Investigated the Codacy "1 high" security alert. The bot's summary comment and the check-run output don't include the specific file/line/rule — only the count — and I don't have access to the Codacy dashboard itself (api.codacy.com isn't reachable from this environment's network policy, and the web UI needs auth I don't have).

To narrow it down anyway: .codacy.yml excludes test/**, so the finding has to be in first_time_install.sh, src/backup_manager.py, or web_interface/blueprints/api_v3.py — the only non-test files this PR touches. I ran Bandit against both Python files (diffed base vs. head) and ShellCheck against the shell script (same diff) as local stand-ins for what Codacy likely runs, plus detect-secrets in case it's a hardcoded-credential match. None of the three surfaced anything new introduced by this diff — the only HIGH-severity Bandit hit in api_v3.py is a pre-existing MD5 usage at line 6792, unrelated to any line this PR changes.

If someone with dashboard access can grab the specific rule/file/line from https://app.codacy.com/gh/ChuckBuilds/LEDMatrix/pull-requests/440/issues, I'll fix it directly rather than guess further. I'll keep watching this PR for the next update either way.


Generated by Claude Code

@ChuckBuilds
ChuckBuilds merged commit b2cb4b4 into fix/backup-restore-fidelity Aug 7, 2026
1 of 2 checks passed
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.

2 participants