From 9a76ea1a8b7ce495ae558c296448175422a344ee Mon Sep 17 00:00:00 2001 From: Eddy de Vink Date: Tue, 1 Sep 2026 23:40:34 +0200 Subject: [PATCH] Recognize creator as owner (MSC4289 room v12+); v2.0.1 --- maubot.yaml | 2 +- roomsoverview.mbp | Bin 4674 -> 4783 bytes roomsoverview.py | 29 +++++++++++++++++++++++------ 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/maubot.yaml b/maubot.yaml index 554abd6..27c40f7 100644 --- a/maubot.yaml +++ b/maubot.yaml @@ -1,6 +1,6 @@ maubot: 0.1.0 id: nl.roomsoverview -version: 2.0.0 +version: 2.0.1 license: MIT modules: - roomsoverview diff --git a/roomsoverview.mbp b/roomsoverview.mbp index 518c4ce0df2652c02c1dcbfe892c2c39b8b261ea..29dff1983c765910906e519ad2cb9b7513cef783 100644 GIT binary patch delta 4075 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 delta 3965 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 XiLWNG4gdflH bool: - """Moderator (power level >= 50) in de gegeven room.""" + """Moderator (power level >= 50) in de gegeven room. + + Let op room v12+ (MSC4289): de creator heeft impliciet de maximale macht + en mag/hoeft niet in de users-map voor te komen. Die telt daarom mee. + """ + base = self._base_url() + h = self._headers() + rid = quote(room_id, safe="") try: async with self.http.get( - f"{self._base_url()}/_matrix/client/v3/rooms/{quote(room_id, safe='')}/state/m.room.power_levels", - headers=self._headers(), + f"{base}/_matrix/client/v3/rooms/{rid}/state/m.room.power_levels", + headers=h, timeout=_REQUEST_TIMEOUT, ) as r: if r.status != 200: return False d = await r.json() + async with self.http.get( + f"{base}/_matrix/client/v3/rooms/{rid}/state/m.room.create", + headers=h, + timeout=_REQUEST_TIMEOUT, + ) as r: + creator = (await r.json()).get("creator") if r.status == 200 else None except Exception: return False + if user_id == creator: + return True # MSC4289: creator heeft impliciet maximale macht users = d.get("users", {}) or {} default = int(d.get("users_default", 0) or 0) pl = int(users.get(user_id, default) or 0) @@ -368,7 +382,10 @@ class RoomsOverviewPlugin(Plugin): @handle_rooms.subcommand(name="refresh", help="Valideer de index nu (moderator+)") async def refresh_index(self, evt: MessageEvent) -> None: if not await self._is_mod(evt.room_id, evt.sender): - await evt.reply("Geen permissie: moderator of hoger.") + await evt.reply("Geen permissie: moderator of hoger vereist.") return removed, total = await self._validate_all() - await evt.reply(f"Index gecontroleerd: {total - removed} rooms over, {removed} verwijderd (bestonden niet meer).") \ No newline at end of file + await evt.reply( + f"Index gecontroleerd: {total - removed} rooms over, " + f"{removed} verwijderd (bestonden niet meer)." + ) \ No newline at end of file