fix(matrix,gateway): Matrix E2EE installs full dep set; plugins respect is_connected - #31688
Conversation
…ct is_connected Fixes #31116 — two distinct bugs in fresh-install Matrix gateway: 1. Matrix E2EE setup installed only mautrix[encryption], leaving asyncpg / aiosqlite / Markdown / aiohttp-socks uninstalled. The first encrypted connect failed with 'No module named asyncpg' deep inside MatrixAdapter.connect(). Root cause: the setup wizard hand-rolled a pip install of one package instead of using lazy_deps.ensure( 'platform.matrix'), and check_matrix_requirements() short-circuited the runtime installer on 'import mautrix' alone — so the other 4 packages were never pulled in. 2. Discord auto-enabled itself on every gateway start, even when the user never selected Discord and had no DISCORD_BOT_TOKEN. Root cause: gateway/config.py plugin-enablement loop gated enablement on entry.check_fn() (just 'is the SDK importable?') and ignored entry.is_connected (the 'did the user configure credentials?' probe). Same bug class as commit 7849a3d fixed for _platform_status in the setup wizard; this is the runtime counterpart. Affects Discord, Teams, and Google Chat. Changes: - hermes_cli/setup.py::_setup_matrix — install via lazy_deps.ensure('platform.matrix') to pull the full feature group. - gateway/platforms/matrix.py::_check_e2ee_deps — verify asyncpg + aiosqlite + PgCryptoStore in addition to OlmMachine, so E2EE failures surface at startup instead of at first encrypted-room connect. - gateway/platforms/matrix.py::check_matrix_requirements — use feature_missing('platform.matrix') as the install gate instead of a single 'import mautrix' check, so partial installs trigger the lazy installer correctly. - gateway/config.py plugin-enablement loop — consult entry.is_connected before flipping enabled=True. Explicit YAML enabled=true still wins. Tests: 3 new in tests/gateway/test_matrix.py (asyncpg-required, aiosqlite-required, partial-install lazy-runs), 5 new in tests/gateway/test_platform_registry.py (is_connected=False blocks, is_connected=True enables, is_connected=None falls back to check_fn, raising probe doesn't enable, explicit YAML wins). Validation: 310 tests across affected test modules pass.
🚨 CRITICAL Supply Chain Risk DetectedThis PR contains a pattern that has been used in real supply chain attacks. A maintainer must review the flagged code carefully before merging. 🚨 CRITICAL: Install-hook file added or modifiedThese files can execute code during package installation or interpreter startup. Files: Scanner only fires on high-signal indicators: .pth files, base64+exec/eval combos, subprocess with encoded commands, or install-hook files. Low-signal warnings were removed intentionally — if you're seeing this comment, the finding is worth inspecting. |
🔎 Lint report:
|
| Rule | Count |
|---|---|
unresolved-import |
2 |
invalid-assignment |
1 |
First entries
gateway/platforms/matrix.py:272: [invalid-assignment] invalid-assignment: Object of type `None` is not assignable to `def ensure_and_bind(feature: str, importer: () -> dict[str, Any], target_globals: dict[Unknown, Unknown], *, prompt: bool = False) -> bool`
gateway/platforms/matrix.py:232: [unresolved-import] unresolved-import: Cannot resolve imported module `asyncpg`
gateway/platforms/matrix.py:233: [unresolved-import] unresolved-import: Cannot resolve imported module `aiosqlite`
✅ Fixed issues (1):
| Rule | Count |
|---|---|
unresolved-import |
1 |
First entries
gateway/platforms/matrix.py:243: [unresolved-import] unresolved-import: Cannot resolve imported module `mautrix`
Unchanged: 4838 pre-existing issues carried over.
Diagnostics are surfaced as warnings — this check never fails the build.
|
Supersedes #31236 — same two-bug fix (Matrix E2EE deps + Discord auto-enable) cherry-picked by maintainer onto current main and merged. |
Summary
Fresh-install Matrix gateway now connects with E2EE, and plugin platforms (Discord/Teams/Google Chat) no longer auto-enable themselves uninvited. Closes #31116.
Two distinct bugs surfaced by the reporter:
1. Matrix E2EE missing 4 of 5 deps.
The setup wizard installed only `mautrix[encryption]`, leaving `asyncpg`, `aiosqlite`, `Markdown`, and `aiohttp-socks` uninstalled. `MatrixAdapter.connect()` uses `PgCryptoStore` (needs asyncpg) and `Database.create("sqlite:///...")` (needs aiosqlite), so the first encrypted connect failed with `No module named 'asyncpg'`. The runtime guard `check_matrix_requirements()` short-circuited the lazy installer on `import mautrix` alone, so the missing 4 packages were never pulled in. `_check_e2ee_deps()` only tested `OlmMachine` import, so health-checks reported "all good" while connect kept crashing.
2. Discord auto-enabled uninvited.
`gateway/config.py` plugin-enablement loop gated `enabled=True` on `entry.check_fn()` alone ("is the SDK importable?") and ignored `entry.is_connected` ("did the user configure credentials?"). Same bug class as commit 7849a3d fixed for `_platform_status` in the setup wizard; this is the runtime counterpart. Affects every plugin that registers both hooks — Discord, Teams, Google Chat.
Changes
Tests
3 new in `tests/gateway/test_matrix.py`:
5 new in `tests/gateway/test_platform_registry.py` (new `TestPluginEnablementGate` class):
Validation
Infographic