fix(MAT-258): blacklist unverified E2EE devices + add CI tests
Unverified devices (lacking cross-signing) caused OlmUnverifiedDeviceError in _send_text(), silently breaking all message delivery. Now on_sync() blacklists non-cross-signed devices instead of skipping them, and _send_text() catches E2EE errors gracefully. Adds 12 unit tests for device trust policy and send error handling. CI test job now gates deployment in deploy.yml. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
29
bot.py
29
bot.py
@@ -41,6 +41,7 @@ from nio import (
|
||||
KeyVerificationMac,
|
||||
ToDeviceError,
|
||||
)
|
||||
from nio.exceptions import OlmUnverifiedDeviceError
|
||||
from nio.events.to_device import UnknownToDeviceEvent
|
||||
from nio.crypto.attachments import decrypt_attachment
|
||||
from livekit import api, rtc
|
||||
@@ -1515,7 +1516,8 @@ class Bot:
|
||||
self.client.verify_device(device)
|
||||
logger.info("Cross-sign-verified device %s of %s", device.device_id, user_id)
|
||||
else:
|
||||
logger.debug("Skipped unverified device %s of %s (no cross-signing sig)", device.device_id, user_id)
|
||||
self.client.blacklist_device(device)
|
||||
logger.info("Blacklisted unverified device %s of %s (no cross-signing sig)", device.device_id, user_id)
|
||||
|
||||
async def on_reaction(self, room, event: ReactionEvent):
|
||||
"""Handle reaction events for pipeline approval flow."""
|
||||
@@ -3583,16 +3585,21 @@ class Bot:
|
||||
return None
|
||||
|
||||
async def _send_text(self, room_id: str, text: str):
|
||||
await self.client.room_send(
|
||||
room_id,
|
||||
message_type="m.room.message",
|
||||
content={
|
||||
"msgtype": "m.text",
|
||||
"body": text,
|
||||
"format": "org.matrix.custom.html",
|
||||
"formatted_body": self._md_to_html(text),
|
||||
},
|
||||
)
|
||||
try:
|
||||
await self.client.room_send(
|
||||
room_id,
|
||||
message_type="m.room.message",
|
||||
content={
|
||||
"msgtype": "m.text",
|
||||
"body": text,
|
||||
"format": "org.matrix.custom.html",
|
||||
"formatted_body": self._md_to_html(text),
|
||||
},
|
||||
)
|
||||
except OlmUnverifiedDeviceError as e:
|
||||
logger.error("E2EE send failed in room %s: unverified device — %s", room_id, e)
|
||||
except Exception as e:
|
||||
logger.error("Send failed in room %s: %s", room_id, e)
|
||||
|
||||
async def _get_call_encryption_key(self, room_id: str, sender: str, caller_device_id: str = "") -> bytes | None:
|
||||
"""Read E2EE encryption key from call.member state (MSC4143) or timeline (legacy).
|
||||
|
||||
Reference in New Issue
Block a user