Skip to content

Commit

Permalink
Try to prevent infinite loop of state changes with double puppeting
Browse files Browse the repository at this point in the history
Fixes #464
  • Loading branch information
tulir committed May 27, 2020
1 parent 7f69e9f commit 2dd39fd
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 20 deletions.
5 changes: 5 additions & 0 deletions mautrix_telegram/matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,11 @@ async def handle_typing(self, room_id: RoomID, now_typing: Set[UserID]) -> None:
def filter_matrix_event(self, evt: Event) -> bool:
if not isinstance(evt, (RedactionEvent, MessageEvent, StateEvent, EncryptedEvent)):
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
or pu.Puppet.get_id_from_mxid(evt.sender) is not None)

Expand Down
5 changes: 0 additions & 5 deletions mautrix_telegram/portal/matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -371,11 +371,6 @@ async def handle_matrix_message(self, sender: 'u.User', content: MessageEventCon
self.log.debug(f"Ignoring message {event_id} in {self.mxid} without body or msgtype")
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)
client = sender.client if logged_in else self.bot.client
sender_id = sender.tgid if logged_in else self.bot.tgid
Expand Down
34 changes: 19 additions & 15 deletions mautrix_telegram/portal/metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@

from mautrix.errors import MForbidden
from mautrix.types import (RoomID, UserID, RoomCreatePreset, EventType, Membership, Member,
PowerLevelStateEventContent)
from mautrix.appservice import IntentAPI
PowerLevelStateEventContent, RoomTopicStateEventContent,
RoomNameStateEventContent, RoomAvatarStateEventContent,
StateEventContent)

from ..types import TelegramID
from ..context import Context
Expand Down Expand Up @@ -638,24 +639,27 @@ async def _update_username(self, username: str, save: bool = False) -> bool:
self.save()
return True

async def _try_use_intent(self, sender: Optional['p.Puppet'],
action: Callable[[IntentAPI], Awaitable[None]]) -> None:
async def _try_set_state(self, sender: Optional['p.Puppet'], evt_type: EventType,
content: StateEventContent) -> None:
if sender:
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:
await action(self.main_intent)
await self.main_intent.send_state_event(self.mxid, evt_type, content)
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,
save: bool = False) -> bool:
if self.about == about:
return False

self.about = about
await self._try_use_intent(sender,
lambda intent: intent.set_room_topic(self.mxid, self.about))
await self._try_set_state(sender, EventType.ROOM_TOPIC,
RoomTopicStateEventContent(topic=self.about))
if save:
self.save()
return True
Expand All @@ -666,8 +670,8 @@ async def _update_title(self, title: str, sender: Optional['p.Puppet'] = None,
return False

self.title = title
await self._try_use_intent(sender,
lambda intent: intent.set_room_name(self.mxid, self.title))
await self._try_set_state(sender, EventType.ROOM_NAME,
RoomNameStateEventContent(name=self.title))
if save:
self.save()
return True
Expand All @@ -693,16 +697,16 @@ async def _update_avatar(self, user: 'AbstractUser', photo: TypeChatPhoto,
raise ValueError(f"Unknown photo type {type(photo)}")
if self.photo_id != photo_id:
if not photo_id:
await self._try_use_intent(sender,
lambda intent: intent.set_room_avatar(self.mxid, None))
await self._try_set_state(sender, EventType.ROOM_AVATAR,
RoomAvatarStateEventContent(url=None))
self.photo_id = ""
if save:
self.save()
return True
file = await util.transfer_file_to_matrix(user.client, self.main_intent, loc)
if file:
await self._try_use_intent(sender, lambda intent: intent.set_room_avatar(self.mxid,
file.mxc))
await self._try_set_state(sender, EventType.ROOM_AVATAR,
RoomAvatarStateEventContent(url=file.mxc))
self.photo_id = photo_id
if save:
self.save()
Expand Down

0 comments on commit 2dd39fd

Please sign in to comment.