diff --git a/CHANGELOG.md b/CHANGELOG.md index 60550bc4..e226c230 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ ### Improved * Redacting reactions on Matrix no longer removes the user's other reactions to the same message (premium users can have up to 3 reactions per message). +* Changes to default user permissions on Telegram are now bridged. ### Fixed diff --git a/mautrix_telegram/abstract_user.py b/mautrix_telegram/abstract_user.py index 31dc86f5..17aaf2db 100644 --- a/mautrix_telegram/abstract_user.py +++ b/mautrix_telegram/abstract_user.py @@ -41,6 +41,7 @@ from telethon.tl.types import ( TypeUpdate, UpdateChannel, UpdateChannelUserTyping, + UpdateChatDefaultBannedRights, UpdateChatParticipantAdmin, UpdateChatParticipants, UpdateChatUserTyping, @@ -346,6 +347,8 @@ class AbstractUser(ABC): await self.update_admin(update) elif isinstance(update, UpdateChatParticipants): await self.update_participants(update) + elif isinstance(update, UpdateChatDefaultBannedRights): + await self.update_default_banned_rights(update) elif isinstance(update, (UpdatePinnedMessages, UpdatePinnedChannelMessages)): await self.update_pinned_messages(update) elif isinstance(update, (UpdateUserName, UpdateUserPhoto)): @@ -392,6 +395,12 @@ class AbstractUser(ABC): if portal and portal.mxid: await portal.update_power_levels(update.participants.participants) + @staticmethod + async def update_default_banned_rights(update: UpdateChatDefaultBannedRights) -> None: + portal = await po.Portal.get_by_entity(update.peer) + if portal and portal.mxid: + await portal.update_default_banned_rights(update.default_banned_rights) + async def update_read_receipt(self, update: UpdateReadHistoryOutbox) -> None: if not isinstance(update.peer, PeerUser): self.log.debug("Unexpected read receipt peer: %s", update.peer) diff --git a/mautrix_telegram/portal.py b/mautrix_telegram/portal.py index 3d804198..a44de293 100644 --- a/mautrix_telegram/portal.py +++ b/mautrix_telegram/portal.py @@ -65,6 +65,7 @@ from telethon.tl.types import ( Channel, ChannelFull, Chat, + ChatBannedRights, ChatFull, ChatPhoto, ChatPhotoEmpty, @@ -994,6 +995,12 @@ class Portal(DBPortal, BasePortal): if await putil.participants_to_power_levels(self, users, levels): await self.main_intent.set_power_levels(self.mxid, levels) + async def update_default_banned_rights(self, dbr: ChatBannedRights) -> None: + self.log.debug("Default rights in chat changed: %s", dbr) + levels = await self.main_intent.get_power_levels(self.mxid) + levels = putil.get_base_power_levels(self, levels, dbr=dbr) + await self.main_intent.set_power_levels(self.mxid, levels) + async def _add_bot_chat(self, bot: User) -> None: if self.bot and bot.id == self.bot.tgid: await self.bot.add_chat(self.tgid, self.peer_type) diff --git a/mautrix_telegram/portal_util/power_levels.py b/mautrix_telegram/portal_util/power_levels.py index be2f44de..8ccc591a 100644 --- a/mautrix_telegram/portal_util/power_levels.py +++ b/mautrix_telegram/portal_util/power_levels.py @@ -34,8 +34,12 @@ from ..types import TelegramID def get_base_power_levels( - portal: po.Portal, levels: PowerLevelContent = None, entity: TypeChat = None + portal: po.Portal, + levels: PowerLevelContent = None, + entity: TypeChat | None = None, + dbr: ChatBannedRights | None = None, ) -> PowerLevelContent: + is_initial = not levels levels = levels or PowerLevelContent() if portal.peer_type == "user": overrides = portal.config["bridge.initial_power_level_overrides.user"] @@ -51,7 +55,7 @@ def get_base_power_levels( levels.events_default = overrides.get("events_default", 0) else: overrides = portal.config["bridge.initial_power_level_overrides.group"] - dbr = entity.default_banned_rights + dbr = dbr or entity.default_banned_rights if not dbr: portal.log.debug(f"default_banned_rights is None in {entity}") dbr = ChatBannedRights( @@ -80,16 +84,14 @@ def get_base_power_levels( levels.events_default = overrides.get( "events_default", 50 - if portal.peer_type == "channel" and not entity.megagroup or dbr.send_messages + if portal.peer_type == "channel" and not portal.megagroup or dbr.send_messages else 0, ) for evt_type, value in overrides.get("events", {}).items(): levels.events[EventType.find(evt_type)] = value userlevel_overrides = overrides.get("users", {}) - bot_level = levels.get_user_level(portal.main_intent.mxid) - for user, user_level in levels.users.items(): - if user_level < bot_level: - levels.users[user] = userlevel_overrides.get(user, 0) + if is_initial: + levels.users.update(userlevel_overrides) if portal.main_intent.mxid not in levels.users: levels.users[portal.main_intent.mxid] = 100 return levels