Block requests for groups the user is already a part of

This commit is contained in:
Astra Logical 2026-07-22 18:29:35 -04:00
parent 65d219c1b7
commit bf2eeb9bf7

View file

@ -48,6 +48,29 @@ def get_keycloak_client() -> KeycloakAdmin:
)
def check_group_membership(username: str, group_name: str) -> tuple[bool, str]:
"""Checks if a user is already a member of a specified Keycloak group."""
try:
kc = get_keycloak_client()
users = kc.get_users(query={"username": username, "exact": True})
if not users:
return False, f"⚠️ Keycloak user `{username}` not found."
user_id = users[0]["id"]
user_groups = kc.get_user_groups(user_id=user_id)
user_group_names = {g["name"].lower() for g in user_groups}
if group_name.lower() in user_group_names:
return True, f" You are already a member of the `{group_name}` group."
return False, ""
except KeycloakError as e:
return False, f"⚠️ Keycloak API error: {str(e)}"
except Exception as e:
return False, f"⚠️ Unexpected error: {str(e)}"
def add_user_to_kc_group(username: str, group_name: str) -> tuple[bool, str]:
"""Adds a Keycloak user to a target group."""
try:
@ -100,7 +123,6 @@ def get_requestable_groups(username: str) -> tuple[bool, str]:
group_lines.append(f"* `{name}`")
group_list = "\n".join(group_lines)
# Added extra \n before {group_list} to satisfy Markdown list block rules
return True, f"**Available Groups:**\n\n{group_list}"
except KeycloakError as e:
@ -132,7 +154,6 @@ async def send_markdown_message(
msgtype: str = "m.text",
relates_to: dict = None,
):
# Added "nl2br" extension to preserve single line breaks in chat messages
html_body = markdown.markdown(md_text, extensions=["extra", "sane_lists", "nl2br"])
content = {
@ -213,6 +234,17 @@ async def on_message(client: AsyncClient, room: MatrixRoom, event: RoomMessageTe
)
return
# Check if the user is already in the requested group before asking for approval
already_member, membership_msg = check_group_membership(kc_username, requested_group)
if already_member or membership_msg:
await send_markdown_message(
client,
room_id=room.room_id,
md_text=membership_msg,
msgtype="m.notice",
)
return
admin_msg_body = (
f"📋 **Access Request**\n\n"
f"**User:** `{matrix_user}` (KC: `{kc_username}`)\n"