From 595348fbd617dad978a2dcd18181999eaa7c789a Mon Sep 17 00:00:00 2001 From: Astra Logical Date: Wed, 22 Jul 2026 18:13:55 -0400 Subject: [PATCH] Groups now tells user if they are in group --- matrix_keycloak_bot.py | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/matrix_keycloak_bot.py b/matrix_keycloak_bot.py index 3cdb639..4460150 100644 --- a/matrix_keycloak_bot.py +++ b/matrix_keycloak_bot.py @@ -49,10 +49,22 @@ def get_keycloak_client() -> KeycloakAdmin: verify=True, ) -def get_requestable_groups() -> tuple[bool, str]: - """Fetches available Keycloak groups, filtering out the 'admin' group.""" +def get_requestable_groups(username: str) -> tuple[bool, str]: + """Fetches available Keycloak groups, filtering out the 'admin' group, and checks user membership.""" try: kc = get_keycloak_client() + + # 1. Fetch User UUID to get their current groups + users = kc.get_users(query={"username": username, "exact": True}) + if not users: + # If the user doesn't exist in Keycloak, we just show groups normally + user_group_names = set() + else: + user_id = users[0]["id"] + user_groups = kc.get_user_groups(user_id=user_id) + user_group_names = {g["name"] for g in user_groups} + + # 2. Fetch all groups groups = kc.get_groups() # Filter out 'admin' (case-insensitive) @@ -61,7 +73,15 @@ def get_requestable_groups() -> tuple[bool, str]: if not valid_groups: return True, "No groups are currently available to request." - group_list = "\n".join([f"• `{name}`" for name in valid_groups]) + # 3. Format the output list with membership status + group_lines = [] + for name in valid_groups: + if name in user_group_names: + group_lines.append(f"• `{name}` *(Already a member)*") + else: + group_lines.append(f"• `{name}`") + + group_list = "\n".join(group_lines) return True, f"**Available Groups:**\n{group_list}" except KeycloakError as e: @@ -126,9 +146,13 @@ async def on_message(client: AsyncClient, room: MatrixRoom, event: RoomMessageTe body = event.body.strip() + # Extract username early so both commands can utilize it + matrix_user = event.sender + kc_username = matrix_user.split(":")[0].lstrip("@") + # --- COMMAND: !groups --- if body.startswith("!groups"): - success, msg = get_requestable_groups() + success, msg = get_requestable_groups(kc_username) await send_message_safe( client, room_id=room.room_id,