Explorar el Código

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

handle authorization failures in more places
Sumner Evans hace 3 años
padre
commit
984ab27771

+ 10 - 3
mautrix_signal/matrix.py

@@ -133,9 +133,16 @@ class MatrixHandler(BaseMatrixHandler):
             return
 
         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:
         pass

+ 2 - 8
mautrix_signal/portal.py

@@ -26,7 +26,7 @@ import os.path
 import pathlib
 import time
 
-from mausignald.errors import NotConnected, ResponseError, RPCError
+from mausignald.errors import NotConnected, RPCError
 from mausignald.types import (
     AccessControlMode,
     Address,
@@ -64,13 +64,11 @@ from mautrix.types import (
     MessageType,
     PowerLevelStateEventContent,
     RoomID,
-    SingleReceiptEventContent,
     TextMessageEventContent,
     UserID,
     VideoInfo,
 )
 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.message_send_checkpoint import MessageSendCheckpointStatus
 
@@ -309,11 +307,7 @@ class Portal(DBPortal, BasePortal):
                 message.msgtype,
                 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(
                 self.main_intent,
                 TextMessageEventContent(

+ 33 - 17
mautrix_signal/user.py

@@ -21,6 +21,7 @@ from datetime import datetime
 from uuid import UUID
 import asyncio
 
+from mausignald.errors import ResponseError
 from mausignald.types import (
     Account,
     Address,
@@ -146,6 +147,13 @@ class User(DBUser, BaseUser):
             state.state_event = BridgeStateEvent.TRANSIENT_DISCONNECT
         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:
         if not self.address:
             return None
@@ -263,33 +271,41 @@ class User(DBUser, BaseUser):
         try:
             async with self._sync_lock:
                 await self._sync_contacts()
-        except Exception:
+        except Exception as e:
             self.log.exception("Error while syncing contacts")
+            await self.handle_auth_failure(e)
 
     async def sync_groups(self) -> None:
         try:
             async with self._sync_lock:
                 await self._sync_groups()
-        except Exception:
+        except Exception as e:
             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:
         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:
         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.types import Account, Address
 from mautrix.types import UserID
-from mautrix.util.bridge_state import BridgeStateEvent
 from mautrix.util.logging import TraceLogger
 
 from .. import user as u
@@ -126,10 +125,7 @@ class ProvisioningAPI:
                 )
             except Exception as e:
                 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"] = {
                     "number": user.username,