浏览代码

Move relay stuff to mautrix-python

Tulir Asokan 3 年之前
父节点
当前提交
f7176a4f77
共有 5 个文件被更改,包括 22 次插入67 次删除
  1. 5 6
      mautrix_signal/example-config.yaml
  2. 10 58
      mautrix_signal/portal.py
  3. 5 1
      mautrix_signal/user.py
  4. 1 1
      optional-requirements.txt
  5. 1 1
      requirements.txt

+ 5 - 6
mautrix_signal/example-config.yaml

@@ -240,7 +240,7 @@ bridge:
         "@admin:example.com": "admin"
 
     relay:
-        # Whether or not relay mode should be allowed. If allowed, `!signal set-relay` can be used to turn any
+        # Whether relay mode should be allowed. If allowed, `!signal set-relay` can be used to turn any
         # authenticated user into a relaybot for that chat.
         enabled: false
         # The formats to use when sending messages to Signal via a relay user.
@@ -255,11 +255,10 @@ bridge:
             m.notice: '$sender_displayname: $message'
             m.emote: '* $sender_displayname $message'
             m.file: '$sender_displayname sent a file'
-            m.image: '$sender_displayname  sent an image'
-            m.audio: '$sender_displayname  sent an audio file'
-            m.video: '$sender_displayname  sent a video'
-            m.location: '$sender_displayname  sent a location'
-
+            m.image: '$sender_displayname sent an image'
+            m.audio: '$sender_displayname sent an audio file'
+            m.video: '$sender_displayname sent a video'
+            m.location: '$sender_displayname sent a location'
 
 # Python logging configuration.
 #

+ 10 - 58
mautrix_signal/portal.py

@@ -90,7 +90,6 @@ class Portal(DBPortal, BasePortal):
     _reaction_dedup: Deque[Tuple[Address, int, str]]
     _reaction_lock: asyncio.Lock
     _pending_members: Optional[Set[UUID]]
-    _relay_user: Optional['u.User']
     _expiration_lock: asyncio.Lock
 
     def __init__(self, chat_id: Union[GroupID, Address], receiver: str,
@@ -112,22 +111,6 @@ class Portal(DBPortal, BasePortal):
         self._relay_user = None
         self._expiration_lock = asyncio.Lock()
 
-    @property
-    def has_relay(self) -> bool:
-        return self.config["bridge.relay.enabled"] and bool(self.relay_user_id)
-
-    async def get_relay_user(self) -> Optional['u.User']:
-        if not self.has_relay:
-            return None
-        if self._relay_user is None:
-            self._relay_user = await u.User.get_by_mxid(self.relay_user_id)
-        return self._relay_user if await self._relay_user.is_logged_in() else None
-
-    async def set_relay_user(self, user: Optional['u.User']) -> None:
-        self._relay_user = user
-        self.relay_user_id = user.mxid if user else None
-        await self.save()
-
     @property
     def main_intent(self) -> IntentAPI:
         if not self._main_intent:
@@ -225,53 +208,22 @@ class Portal(DBPortal, BasePortal):
             data = await self.main_intent.download_media(message.url)
         return self._write_outgoing_file(data)
 
-    async def get_displayname(self, user: 'u.User') -> str:
-        return await self.main_intent.get_room_displayname(self.mxid, user.mxid) or user.mxid
-
-    async def _apply_msg_format(self, sender: 'u.User', content: MessageEventContent) -> None:
-        if not isinstance(content, TextMessageEventContent) or content.format != Format.HTML:
-            content.format = Format.HTML
-            content.formatted_body = escape_html(content.body).replace("\n", "<br/>")
-
-        tpl = (self.config[f"relaybot.message_formats.[{content.msgtype.value}]"]
-               or "$sender_displayname: $message")
-        displayname = await self.get_displayname(sender)
-        username, _ = self.az.intent.parse_user_id(sender.mxid)
-        tpl_args = dict(sender_mxid=sender.mxid,
-                        sender_username=username,
-                        sender_displayname=escape_html(displayname),
-                        message=content.formatted_body,
-                        body=content.body,
-                        formatted_body=content.formatted_body)
-        content.formatted_body = Template(tpl).safe_substitute(tpl_args)
-        content.body = Template(tpl).safe_substitute(tpl_args)
-        if content.msgtype == MessageType.EMOTE:
-            content.msgtype = MessageType.TEXT
-
-    async def _get_relay_sender(self, sender: 'u.User', evt_identifier: str
-                                ) -> Tuple[Optional['u.User'], bool]:
-        if await sender.is_logged_in():
-            return sender, False
-
-        if not self.has_relay:
-            self.log.debug(f"Ignoring {evt_identifier} from non-logged-in user {sender.mxid}"
-                           " in chat with no relay user")
-            return None, True
-        relay_sender = await self.get_relay_user()
-        if not relay_sender:
-            self.log.debug(f"Ignoring {evt_identifier} from non-logged-in user {sender.mxid}: "
-                           f"relay user {self.relay_user_id} is not set up correctly")
-            return None, True
-        return relay_sender, True
-
     async def handle_matrix_message(self, sender: 'u.User', message: MessageEventContent,
                                     event_id: EventID) -> None:
         orig_sender = sender
-        sender, is_relay = await self._get_relay_sender(sender, f"message {event_id}")
+        sender, is_relay = await self.get_relay_sender(sender, f"message {event_id}")
         if not sender:
+            orig_sender.send_remote_checkpoint(
+                status=MessageSendCheckpointStatus.PERM_FAILURE,
+                event_id=event_id,
+                room_id=self.mxid,
+                event_type=EventType.ROOM_MESSAGE,
+                message_type=message.msgtype,
+                error="user is not logged in",
+            )
             return
         elif is_relay:
-            await self._apply_msg_format(orig_sender, message)
+            await self.apply_relay_message_format(orig_sender, message)
 
         request_id = int(time.time() * 1000)
         self._msgts_dedup.appendleft((sender.address, request_id))

+ 5 - 1
mautrix_signal/user.py

@@ -59,7 +59,7 @@ class User(DBUser, BaseUser):
     _sync_lock: asyncio.Lock
     _notice_room_lock: asyncio.Lock
     _connected: bool
-    _websocket_connection_state: Optional[WebsocketConnectionState]
+    _websocket_connection_state: Optional[BridgeStateEvent]
     _latest_non_transient_disconnect_state: Optional[datetime]
 
     def __init__(self, mxid: UserID, username: Optional[str] = None, uuid: Optional[UUID] = None,
@@ -89,6 +89,10 @@ class User(DBUser, BaseUser):
     async def is_logged_in(self) -> bool:
         return bool(self.username)
 
+    async def needs_relay(self, portal: 'po.Portal') -> bool:
+        return not await self.is_logged_in() or (portal.is_direct
+                                                 and portal.receiver != self.username)
+
     async def logout(self) -> None:
         if not self.username:
             return

+ 1 - 1
optional-requirements.txt

@@ -4,7 +4,7 @@
 #/e2be
 python-olm>=3,<4
 pycryptodome>=3,<4
-unpaddedbase64>=1,<2
+unpaddedbase64>=1,<3
 
 #/metrics
 prometheus_client>=0.6,<0.13

+ 1 - 1
requirements.txt

@@ -4,5 +4,5 @@ commonmark>=0.8,<0.10
 aiohttp>=3,<4
 yarl>=1,<2
 attrs>=19.1
-mautrix>=0.13.0,<0.14
+mautrix>=0.13.1,<0.14
 asyncpg>=0.20,<0.26