Skip to content

Add read-only mode for termui and webui#457

Open
achimnol wants to merge 3 commits intomainfrom
resolve/386-add-read-only-mode
Open

Add read-only mode for termui and webui#457
achimnol wants to merge 3 commits intomainfrom
resolve/386-add-read-only-mode

Conversation

@achimnol
Copy link
Member

Resolves #386

Summary

Add a readonly parameter to Monitor and start_monitor() that, when True, prevents destructive operations (task cancellation, signal sending, console access) in both the terminal UI and web UI. This protects production environments from accidental task cancellation.

Implementation Plan

Approach

Thread a readonly boolean through Monitor.__init__() and start_monitor() that guards destructive commands in termui (cancel, signal, console) and the webui cancel endpoint (DELETE /api/task), while hiding cancel buttons in the frontend.

Steps

  1. monitor.py: Add readonly parameter to Monitor.__init__ and start_monitor; add guard in cancel_monitored_task
  2. termui/commands.py: Add read-only guards to do_cancel, do_signal, do_console; update intro message
  3. webui/app.py: Guard cancel_task endpoint with 403; pass readonly to template; add readonly to WebUIContext
  4. webui/templates/index.html: Hide cancel button via Alpine.js store; add read-only banner
  5. tests/test_monitor.py: Add tests for read-only behavior

Files to Modify

  • aiomonitor/monitor.py — Add readonly param, property, and defense-in-depth guard
  • aiomonitor/termui/commands.py — Guard do_cancel, do_signal, do_console
  • aiomonitor/webui/app.py — Guard cancel endpoint, pass readonly to template
  • aiomonitor/webui/templates/index.html — Conditional cancel button, read-only banner
  • tests/test_monitor.py — New tests for read-only mode

Edge Cases

  • Backward compatibility: readonly defaults to False
  • Defense-in-depth: cancel_monitored_task raises PermissionError even if UI guards are bypassed
  • command_done event handling for commands that don't use @auto_command_done
  • Mustache templates are client-side rendered, so Alpine.js store is used for conditional rendering

Test Plan

  • Test Monitor(loop, readonly=True) constructor
  • Test cancel command rejected in read-only mode
  • Test signal command rejected in read-only mode
  • Test console command rejected in read-only mode
  • Test cancel_monitored_task raises PermissionError in read-only mode
  • Test read-only commands (ps, where, etc.) still work in read-only mode
  • Test webui cancel endpoint returns 403 in read-only mode

Add a `readonly` parameter to Monitor and start_monitor() that prevents
destructive operations (cancel, signal, console) in production environments.

- Guard termui commands: cancel, signal, console
- Guard webui DELETE /api/task endpoint with 403 response
- Hide cancel button in webui via Alpine.js when readonly
- Show read-only banner in webui dashboard
- Defense-in-depth: cancel_monitored_task raises PermissionError
- Add comprehensive tests for read-only mode
- Fix pre-existing bug: do_console console_enabled=False path now sets
  command_done event to prevent telnet session hang
- Replace Alpine.js x-show with CSS-based approach for hiding cancel
  button in read-only mode (works reliably with HTMX/Mustache)
- Add webui API tests for read-only cancel endpoint (403) and
  non-readonly cancel endpoint
- Fix import ordering in tests
@achimnol
Copy link
Member Author

Automated Review (iteration 2) — Follow-up

Local Checks

  • Lint (ruff): PASS
  • Tests (pytest): PASS — 16/16 tests pass

CI Status

  • pre-commit.ci: PASS
  • Ruff lint: PASS
  • Type annotations: PASS
  • Tests on 3.10: PASS
  • Tests on 3.11: PASS
  • Tests on 3.12: PASS
  • Tests on 3.13: PASS
  • Build source distribution: PASS

Previous Findings Status

# Finding Status
1 Pre-existing bug: do_console console_enabled=False path doesn't set command_done event ✅ FIXED — Added command_done.get().set() call
3 Alpine.js x-show inside Mustache template may not initialize on HTMX swaps ✅ FIXED — Replaced with CSS class .task-cancel-btn + display:none style injected by Jinja2
6 No web UI (HTTP endpoint) tests for read-only mode ✅ FIXED — Added test_readonly_cancel_webui (403) and test_webui_cancel_allowed_when_not_readonly

New Issues

None

Summary

All 3 previous findings have been addressed. No new issues introduced. All local and CI checks pass.

@achimnol achimnol marked this pull request as ready for review February 13, 2026 09:29
@achimnol
Copy link
Member Author

Resolution Complete

This PR is now ready for human review.

Summary of Changes

Added a readonly parameter to Monitor and start_monitor() that prevents destructive operations in production environments:

  • monitor.py: New readonly parameter on Monitor.__init__ and start_monitor(); defense-in-depth guard in cancel_monitored_task() that raises PermissionError
  • termui/commands.py: Guards on do_cancel, do_signal, and do_console commands; read-only indicator in telnet intro message; also fixed pre-existing bug where do_console with console_enabled=False didn't set the command_done event
  • webui/app.py: Guard on DELETE /api/task endpoint returning 403; passes readonly flag to template
  • webui/templates/index.html: CSS-based hiding of cancel buttons in read-only mode; yellow banner indicating read-only status
  • Tests: 8 new tests covering termui commands, core API, constructor, and webui endpoint

Review Iterations

2 iterations — initial implementation + review fixes

Test Coverage

  • test_readonly_cancel_termui — cancel command blocked in read-only mode
  • test_readonly_signal_termui — signal command blocked in read-only mode
  • test_readonly_console_termui — console command blocked in read-only mode
  • test_readonly_cancel_monitored_task — core API raises PermissionError
  • test_readonly_ps_still_works — read-only commands still function
  • test_readonly_ctor — constructor correctly stores flag
  • test_readonly_cancel_webui — webui returns 403 in read-only mode
  • test_webui_cancel_allowed_when_not_readonly — webui allows cancel when not readonly

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.

Add the read-only mode

1 participant

Comments