Try to prevent infinite loop of state changes with double puppeting

Fixes #464
This commit is contained in:
Tulir Asokan
2020-05-27 12:36:50 +03:00
parent 7f69e9f329
commit 2dd39fddf0
3 changed files with 24 additions and 20 deletions
+5
View File
@@ -392,6 +392,11 @@ class MatrixHandler(BaseMatrixHandler):
def filter_matrix_event(self, evt: Event) -> bool: def filter_matrix_event(self, evt: Event) -> bool:
if not isinstance(evt, (RedactionEvent, MessageEvent, StateEvent, EncryptedEvent)): if not isinstance(evt, (RedactionEvent, MessageEvent, StateEvent, EncryptedEvent)):
return True return True
if evt.content.get("net.maunium.telegram.puppet", False):
puppet = pu.Puppet.get_by_custom_mxid(evt.sender)
if puppet:
self.log.debug("Ignoring puppet-sent event %s", evt.event_id)
return True
return evt.sender and (evt.sender == self.az.bot_mxid return evt.sender and (evt.sender == self.az.bot_mxid
or pu.Puppet.get_id_from_mxid(evt.sender) is not None) or pu.Puppet.get_id_from_mxid(evt.sender) is not None)
-5
View File
@@ -371,11 +371,6 @@ class PortalMatrix(BasePortal, MautrixBasePortal, ABC):
self.log.debug(f"Ignoring message {event_id} in {self.mxid} without body or msgtype") self.log.debug(f"Ignoring message {event_id} in {self.mxid} without body or msgtype")
return return
puppet = p.Puppet.get_by_custom_mxid(sender.mxid)
if puppet and content.get("net.maunium.telegram.puppet", False):
self.log.debug("Ignoring puppet-sent message by confirmed puppet user %s", sender.mxid)
return
logged_in = not await sender.needs_relaybot(self) logged_in = not await sender.needs_relaybot(self)
client = sender.client if logged_in else self.bot.client client = sender.client if logged_in else self.bot.client
sender_id = sender.tgid if logged_in else self.bot.tgid sender_id = sender.tgid if logged_in else self.bot.tgid
+19 -15
View File
@@ -30,8 +30,9 @@ from telethon.tl.types import (
from mautrix.errors import MForbidden from mautrix.errors import MForbidden
from mautrix.types import (RoomID, UserID, RoomCreatePreset, EventType, Membership, Member, from mautrix.types import (RoomID, UserID, RoomCreatePreset, EventType, Membership, Member,
PowerLevelStateEventContent) PowerLevelStateEventContent, RoomTopicStateEventContent,
from mautrix.appservice import IntentAPI RoomNameStateEventContent, RoomAvatarStateEventContent,
StateEventContent)
from ..types import TelegramID from ..types import TelegramID
from ..context import Context from ..context import Context
@@ -638,15 +639,18 @@ class PortalMetadata(BasePortal, ABC):
self.save() self.save()
return True return True
async def _try_use_intent(self, sender: Optional['p.Puppet'], async def _try_set_state(self, sender: Optional['p.Puppet'], evt_type: EventType,
action: Callable[[IntentAPI], Awaitable[None]]) -> None: content: StateEventContent) -> None:
if sender: if sender:
try: try:
await action(sender.intent_for(self)) intent = sender.intent_for(self)
if sender.is_real_user:
content[self.az.real_user_content_key] = True
await intent.send_state_event(self.mxid, evt_type, content)
except MForbidden: except MForbidden:
await action(self.main_intent) await self.main_intent.send_state_event(self.mxid, evt_type, content)
else: else:
await action(self.main_intent) await self.main_intent.send_state_event(self.mxid, evt_type, content)
async def _update_about(self, about: str, sender: Optional['p.Puppet'] = None, async def _update_about(self, about: str, sender: Optional['p.Puppet'] = None,
save: bool = False) -> bool: save: bool = False) -> bool:
@@ -654,8 +658,8 @@ class PortalMetadata(BasePortal, ABC):
return False return False
self.about = about self.about = about
await self._try_use_intent(sender, await self._try_set_state(sender, EventType.ROOM_TOPIC,
lambda intent: intent.set_room_topic(self.mxid, self.about)) RoomTopicStateEventContent(topic=self.about))
if save: if save:
self.save() self.save()
return True return True
@@ -666,8 +670,8 @@ class PortalMetadata(BasePortal, ABC):
return False return False
self.title = title self.title = title
await self._try_use_intent(sender, await self._try_set_state(sender, EventType.ROOM_NAME,
lambda intent: intent.set_room_name(self.mxid, self.title)) RoomNameStateEventContent(name=self.title))
if save: if save:
self.save() self.save()
return True return True
@@ -693,16 +697,16 @@ class PortalMetadata(BasePortal, ABC):
raise ValueError(f"Unknown photo type {type(photo)}") raise ValueError(f"Unknown photo type {type(photo)}")
if self.photo_id != photo_id: if self.photo_id != photo_id:
if not photo_id: if not photo_id:
await self._try_use_intent(sender, await self._try_set_state(sender, EventType.ROOM_AVATAR,
lambda intent: intent.set_room_avatar(self.mxid, None)) RoomAvatarStateEventContent(url=None))
self.photo_id = "" self.photo_id = ""
if save: if save:
self.save() self.save()
return True return True
file = await util.transfer_file_to_matrix(user.client, self.main_intent, loc) file = await util.transfer_file_to_matrix(user.client, self.main_intent, loc)
if file: if file:
await self._try_use_intent(sender, lambda intent: intent.set_room_avatar(self.mxid, await self._try_set_state(sender, EventType.ROOM_AVATAR,
file.mxc)) RoomAvatarStateEventContent(url=file.mxc))
self.photo_id = photo_id self.photo_id = photo_id
if save: if save:
self.save() self.save()