Эх сурвалжийг харах

Merge pull request #213 from mautrix/sumner/bri-1503

handle authorization failures in more places
Sumner Evans 3 жил өмнө
parent
commit
984ab27771

+ 10 - 3
mautrix_signal/matrix.py

@@ -133,9 +133,16 @@ class MatrixHandler(BaseMatrixHandler):
             return
             return
 
 
         user.log.trace(f"Sending read receipt for {message.timestamp} to {message.sender}")
         user.log.trace(f"Sending read receipt for {message.timestamp} to {message.sender}")
-        await self.signal.send_receipt(
-            user.username, message.sender, timestamps=[message.timestamp], when=data.ts, read=True
-        )
+        try:
+            await self.signal.send_receipt(
+                user.username,
+                message.sender,
+                timestamps=[message.timestamp],
+                when=data.ts,
+                read=True,
+            )
+        except Exception as e:
+            await user.handle_auth_failure(e)
 
 
     async def handle_typing(self, room_id: RoomID, typing: list[UserID]) -> None:
     async def handle_typing(self, room_id: RoomID, typing: list[UserID]) -> None:
         pass
         pass

+ 2 - 8
mautrix_signal/portal.py

@@ -26,7 +26,7 @@ import os.path
 import pathlib
 import pathlib
 import time
 import time
 
 
-from mausignald.errors import NotConnected, ResponseError, RPCError
+from mausignald.errors import NotConnected, RPCError
 from mausignald.types import (
 from mausignald.types import (
     AccessControlMode,
     AccessControlMode,
     Address,
     Address,
@@ -64,13 +64,11 @@ from mautrix.types import (
     MessageType,
     MessageType,
     PowerLevelStateEventContent,
     PowerLevelStateEventContent,
     RoomID,
     RoomID,
-    SingleReceiptEventContent,
     TextMessageEventContent,
     TextMessageEventContent,
     UserID,
     UserID,
     VideoInfo,
     VideoInfo,
 )
 )
 from mautrix.util import ffmpeg, variation_selector
 from mautrix.util import ffmpeg, variation_selector
-from mautrix.util.bridge_state import BridgeStateEvent
 from mautrix.util.format_duration import format_duration
 from mautrix.util.format_duration import format_duration
 from mautrix.util.message_send_checkpoint import MessageSendCheckpointStatus
 from mautrix.util.message_send_checkpoint import MessageSendCheckpointStatus
 
 
@@ -309,11 +307,7 @@ class Portal(DBPortal, BasePortal):
                 message.msgtype,
                 message.msgtype,
                 error=e,
                 error=e,
             )
             )
-            auth_failed = (
-                "org.whispersystems.signalservice.api.push.exceptions.AuthorizationFailedException"
-            )
-            if isinstance(e, ResponseError) and auth_failed in e.data.get("exceptions", []):
-                await sender.push_bridge_state(BridgeStateEvent.BAD_CREDENTIALS, error=str(e))
+            await sender.handle_auth_failure(e)
             await self._send_message(
             await self._send_message(
                 self.main_intent,
                 self.main_intent,
                 TextMessageEventContent(
                 TextMessageEventContent(

+ 33 - 17
mautrix_signal/user.py

@@ -21,6 +21,7 @@ from datetime import datetime
 from uuid import UUID
 from uuid import UUID
 import asyncio
 import asyncio
 
 
+from mausignald.errors import ResponseError
 from mausignald.types import (
 from mausignald.types import (
     Account,
     Account,
     Address,
     Address,
@@ -146,6 +147,13 @@ class User(DBUser, BaseUser):
             state.state_event = BridgeStateEvent.TRANSIENT_DISCONNECT
             state.state_event = BridgeStateEvent.TRANSIENT_DISCONNECT
         return [state]
         return [state]
 
 
+    async def handle_auth_failure(self, e: Exception) -> None:
+        auth_failed = (
+            "org.whispersystems.signalservice.api.push.exceptions.AuthorizationFailedException"
+        )
+        if isinstance(e, ResponseError) and auth_failed in e.data.get("exceptions", []):
+            await self.push_bridge_state(BridgeStateEvent.BAD_CREDENTIALS, error=str(e))
+
     async def get_puppet(self) -> pu.Puppet | None:
     async def get_puppet(self) -> pu.Puppet | None:
         if not self.address:
         if not self.address:
             return None
             return None
@@ -263,33 +271,41 @@ class User(DBUser, BaseUser):
         try:
         try:
             async with self._sync_lock:
             async with self._sync_lock:
                 await self._sync_contacts()
                 await self._sync_contacts()
-        except Exception:
+        except Exception as e:
             self.log.exception("Error while syncing contacts")
             self.log.exception("Error while syncing contacts")
+            await self.handle_auth_failure(e)
 
 
     async def sync_groups(self) -> None:
     async def sync_groups(self) -> None:
         try:
         try:
             async with self._sync_lock:
             async with self._sync_lock:
                 await self._sync_groups()
                 await self._sync_groups()
-        except Exception:
+        except Exception as e:
             self.log.exception("Error while syncing groups")
             self.log.exception("Error while syncing groups")
+            await self.handle_auth_failure(e)
 
 
     async def sync_contact(self, contact: Profile | Address, create_portals: bool = False) -> None:
     async def sync_contact(self, contact: Profile | Address, create_portals: bool = False) -> None:
         self.log.trace("Syncing contact %s", contact)
         self.log.trace("Syncing contact %s", contact)
-        if isinstance(contact, Address):
-            address = contact
-            profile = await self.bridge.signal.get_profile(self.username, address, use_cache=True)
-            if profile and profile.name:
-                self.log.trace("Got profile for %s: %s", address, profile)
-        else:
-            address = contact.address
-            profile = contact
-        puppet = await pu.Puppet.get_by_address(address)
-        await puppet.update_info(profile)
-        if create_portals:
-            portal = await po.Portal.get_by_chat_id(
-                puppet.address, receiver=self.username, create=True
-            )
-            await portal.create_matrix_room(self, profile)
+        try:
+            if isinstance(contact, Address):
+                address = contact
+                profile = await self.bridge.signal.get_profile(
+                    self.username, address, use_cache=True
+                )
+                if profile and profile.name:
+                    self.log.trace("Got profile for %s: %s", address, profile)
+            else:
+                address = contact.address
+                profile = contact
+            puppet = await pu.Puppet.get_by_address(address)
+            await puppet.update_info(profile)
+            if create_portals:
+                portal = await po.Portal.get_by_chat_id(
+                    puppet.address, receiver=self.username, create=True
+                )
+                await portal.create_matrix_room(self, profile)
+        except Exception as e:
+            await self.handle_auth_failure(e)
+            raise
 
 
     async def _sync_group(self, group: Group, create_portals: bool) -> None:
     async def _sync_group(self, group: Group, create_portals: bool) -> None:
         self.log.trace("Syncing group %s", group)
         self.log.trace("Syncing group %s", group)

+ 1 - 5
mautrix_signal/web/provisioning_api.py

@@ -25,7 +25,6 @@ from aiohttp import web
 from mausignald.errors import InternalError, TimeoutException
 from mausignald.errors import InternalError, TimeoutException
 from mausignald.types import Account, Address
 from mausignald.types import Account, Address
 from mautrix.types import UserID
 from mautrix.types import UserID
-from mautrix.util.bridge_state import BridgeStateEvent
 from mautrix.util.logging import TraceLogger
 from mautrix.util.logging import TraceLogger
 
 
 from .. import user as u
 from .. import user as u
@@ -126,10 +125,7 @@ class ProvisioningAPI:
                 )
                 )
             except Exception as e:
             except Exception as e:
                 self.log.exception(f"Failed to get {user.username}'s profile for whoami")
                 self.log.exception(f"Failed to get {user.username}'s profile for whoami")
-
-                auth_failed = "org.whispersystems.signalservice.api.push.exceptions.AuthorizationFailedException"
-                if isinstance(e, InternalError) and auth_failed in e.data.get("exceptions", []):
-                    await user.push_bridge_state(BridgeStateEvent.BAD_CREDENTIALS, error=str(e))
+                await user.handle_auth_failure(e)
 
 
                 data["signal"] = {
                 data["signal"] = {
                     "number": user.username,
                     "number": user.username,