diff --git a/community/bot.py b/community/bot.py index d4b48b2..9d8feec 100644 --- a/community/bot.py +++ b/community/bot.py @@ -2374,3 +2374,233 @@ class CommunityBot(Plugin): error_msg = f"Failed to initialize community: {e}" self.log.error(error_msg) await evt.respond(error_msg, edits=msg) + + @community.subcommand( + "doctor", + help="review bot permissions across the space and all rooms to identify potential issues" + ) + async def doctor_check(self, evt: MessageEvent) -> None: + if not await self.check_parent_room(evt): + return + if not await self.user_permitted(evt.sender): + await evt.reply("You don't have permission to use this command") + return + + msg = await evt.respond("Running diagnostic check...") + + try: + report = { + "space": {}, + "rooms": {}, + "issues": [], + "warnings": [] + } + + # Check parent space permissions + try: + space_power_levels = await self.client.get_state_event( + self.config["parent_room"], EventType.ROOM_POWER_LEVELS + ) + bot_level = space_power_levels.get_user_level(self.client.mxid) + + report["space"] = { + "room_id": self.config["parent_room"], + "bot_power_level": bot_level, + "has_admin": bot_level >= 100, + "users_higher_or_equal": [], + "users_equal": [], + "users_higher": [] + } + + # Check for users with equal or higher power level + for user, level in space_power_levels.users.items(): + if user != self.client.mxid and level >= bot_level: + if level == bot_level: + report["space"]["users_equal"].append({ + "user": user, + "level": level + }) + else: + report["space"]["users_higher"].append({ + "user": user, + "level": level + }) + report["space"]["users_higher_or_equal"].append({ + "user": user, + "level": level + }) + + if bot_level < 100: + report["issues"].append(f"Bot lacks administrative privileges in parent space (level: {bot_level})") + + if report["space"]["users_higher"]: + report["warnings"].append(f"Users with higher power level in parent space: {', '.join([f'{u['user']} ({u['level']})' for u in report['space']['users_higher']])}") + + if report["space"]["users_equal"]: + report["warnings"].append(f"Users with equal power level in parent space: {', '.join([f'{u['user']} ({u['level']})' for u in report['space']['users_equal']])}") + + except Exception as e: + report["space"] = { + "room_id": self.config["parent_room"], + "error": str(e) + } + report["issues"].append(f"Failed to check parent space permissions: {e}") + + # Check all rooms in the space + space_rooms = await self.get_space_roomlist() + + for room_id in space_rooms: + try: + # First check if bot is in the room + try: + await self.client.get_state_event(room_id, EventType.ROOM_MEMBER, self.client.mxid) + bot_in_room = True + except Exception: + bot_in_room = False + report["issues"].append(f"Bot is not a member of room '{room_id}' that is part of the space") + report["rooms"][room_id] = { + "room_id": room_id, + "error": "Bot not in room" + } + continue + + room_power_levels = await self.client.get_state_event( + room_id, EventType.ROOM_POWER_LEVELS + ) + bot_level = room_power_levels.get_user_level(self.client.mxid) + + # Get room name if available + room_name = room_id + try: + room_name_event = await self.client.get_state_event(room_id, EventType.ROOM_NAME) + room_name = room_name_event.name + except: + pass + + room_report = { + "room_id": room_id, + "room_name": room_name, + "bot_power_level": bot_level, + "has_admin": bot_level >= 100, + "users_higher_or_equal": [], + "users_equal": [], + "users_higher": [] + } + + # Check for users with equal or higher power level + for user, level in room_power_levels.users.items(): + if user != self.client.mxid and level >= bot_level: + if level == bot_level: + room_report["users_equal"].append({ + "user": user, + "level": level + }) + else: + room_report["users_higher"].append({ + "user": user, + "level": level + }) + room_report["users_higher_or_equal"].append({ + "user": user, + "level": level + }) + + if bot_level < 100: + report["issues"].append(f"Bot lacks administrative privileges in room '{room_name}' ({room_id}) - level: {bot_level}") + + if room_report["users_higher"]: + report["warnings"].append(f"Users with higher power level in room '{room_name}': {', '.join([f'{u['user']} ({u['level']})' for u in room_report['users_higher']])}") + + if room_report["users_equal"]: + report["warnings"].append(f"Users with equal power level in room '{room_name}': {', '.join([f'{u['user']} ({u['level']})' for u in room_report['users_equal']])}") + + report["rooms"][room_id] = room_report + + except Exception as e: + report["rooms"][room_id] = { + "room_id": room_id, + "error": str(e) + } + report["issues"].append(f"Failed to check room {room_id}: {e}") + + # Generate response + response = "