浏览代码

add invite command, enable relay for invites

Malte E 2 年之前
父节点
当前提交
d38a4a484c
共有 4 个文件被更改,包括 44 次插入3 次删除
  1. 28 0
      mautrix_signal/commands/signal.py
  2. 1 0
      mautrix_signal/config.py
  3. 2 0
      mautrix_signal/example-config.yaml
  4. 13 3
      mautrix_signal/portal.py

+ 28 - 0
mautrix_signal/commands/signal.py

@@ -23,6 +23,7 @@ import json
 from mausignald.errors import UnknownIdentityKey, UnregisteredUserError
 from mausignald.types import Address, GroupID, TrustLevel
 from mautrix.appservice import IntentAPI
+from mautrix.bridge import RejectMatrixInvite
 from mautrix.bridge.commands import SECTION_ADMIN, HelpSection, command_handler
 from mautrix.types import (
     ContentURI,
@@ -586,3 +587,30 @@ async def warn_missing_power(levels: PowerLevelStateEventContent, evt: CommandEv
         or levels.events[EventType.ROOM_TOPIC] >= 50
     ):
         await evt.reply(meta_power_warning)
+
+
+@command_handler(
+    needs_auth=False,
+    management_only=False,
+    help_section=SECTION_SIGNAL,
+    help_text="Invite a Signal user by phone number",
+    help_args="<_phone_>",
+)
+async def invite(evt: CommandEvent) -> EventID:
+    if not evt.is_portal:
+        return await evt.reply("This is not a portal room.")
+    else:
+        portal = evt.portal
+    puppet = await _get_puppet_from_cmd(evt)
+    if not puppet:
+        return
+    levels = await portal.main_intent.get_power_levels(portal.mxid)
+    if levels.get_user_level(puppet.mxid) < levels.invite:
+        return await evt.reply("You do not have permissions to invite users to this room")
+
+    try:
+        info = await portal.handle_matrix_invite(evt.sender, puppet)
+        sender, is_relay = await portal.get_relay_sender(evt.sender, "updating info")
+        await portal.update_info(sender, info)
+    except RejectMatrixInvite as e:
+        return await evt.reply(f"Failed to invite {puppet.name}: {e}")

+ 1 - 0
mautrix_signal/config.py

@@ -94,6 +94,7 @@ class Config(BaseBridgeConfig):
         copy("bridge.relay.enabled")
         copy_dict("bridge.relay.message_formats")
         copy("bridge.relay.relaybot")
+        copy("bridge.relay.invite")
         copy("bridge.bridge_matrix_leave")
         copy("bridge.location_format")
 

+ 2 - 0
mautrix_signal/example-config.yaml

@@ -307,6 +307,8 @@ bridge:
         # and double puppeting working to auto-accept invites. When this user is invited to a room
         # it will automatically be set as the relay user. May be overridden with `set-relay` or `unset-relay`
         relaybot: '@relaybot:example.com'
+        # Whether or not invites from non-logged-in users should be relayed
+        invite: true
 
     # Format for generating URLs from location messages for sending to Signal
     # Google Maps: 'https://www.google.com/maps/place/{lat},{long}'

+ 13 - 3
mautrix_signal/portal.py

@@ -844,14 +844,23 @@ class Portal(DBPortal, BasePortal):
                         )
                         return
 
-    async def handle_matrix_invite(self, invited_by: u.User, user: u.User | p.Puppet) -> None:
+    async def handle_matrix_invite(
+        self, invited_by: u.User, user: u.User | p.Puppet
+    ) -> GroupV2 | None:
         if self.is_direct:
             raise RejectMatrixInvite("You can't invite additional users to private chats.")
-
+        invited_by, is_relay = await self.get_relay_sender(invited_by, "invite")
+        if is_relay:
+            if not self.config["bridge.relay.invite"]:
+                raise RejectMatrixInvite("Relaying invites is not enabled on this bridge")
+            if not invited_by:
+                raise RejectMatrixInvite("There is no relay in this room")
+        update_meta = None
         try:
-            await self.signal.update_group(
+            update_meta = await self.signal.update_group(
                 invited_by.username, self.chat_id, add_members=[user.address]
             )
+            self.revision = update_meta.revision
         except RPCError as e:
             raise RejectMatrixInvite(str(e)) from e
         if user.mxid == self.config["bridge.relay.relaybot"] != "@relaybot:example.com":
@@ -870,6 +879,7 @@ class Portal(DBPortal, BasePortal):
                 await self._update_power_levels(
                     await self.signal.get_group(invited_by.username, self.chat_id)
                 )
+        return update_meta
 
     async def _handle_relaybot_invited(self, user: u.User) -> None:
         if not self.config["bridge.relay.enabled"]: