fix: split subscription_lock, fix safe_get None semantics, validate notification enums

P-01: Replace single subscription_lock with two fine-grained locks:
- _task_lock guards active_subscriptions (task lifecycle operations)
- _data_lock guards resource_data (WebSocket message writes and reads)
Eliminates serialization between WebSocket updates and tool reads.

CQ-05: safe_get now preserves explicit None at terminal key.
Uses sentinel _MISSING to distinguish "key absent" (returns default)
from "key=null" (returns None). Fixes conflation that masked
intentional null values from the Unraid API.

SEC-M04: Validate list_type, importance, and notification_type against
known enums before dispatching to GraphQL. Prevents wasting rate-limited
requests on invalid values and avoids leaking schema details in errors.
This commit is contained in:
Jacob Magar
2026-03-13 02:44:26 -04:00
parent bdb2155366
commit ac5639301c
5 changed files with 794 additions and 14 deletions

View File

@@ -26,6 +26,7 @@ from .tools.info import register_info_tool
from .tools.keys import register_keys_tool
from .tools.notifications import register_notifications_tool
from .tools.rclone import register_rclone_tool
from .tools.settings import register_settings_tool
from .tools.storage import register_storage_tool
from .tools.users import register_users_tool
from .tools.virtualization import register_vm_tool
@@ -62,6 +63,7 @@ def register_all_modules() -> None:
register_users_tool,
register_keys_tool,
register_health_tool,
register_settings_tool,
]
for registrar in registrars:
registrar(mcp)