Fix message edit on approval. Add groups command. Prevent requesting admin group
This commit is contained in:
parent
d9c38ff119
commit
1fc97b6256
1 changed files with 65 additions and 10 deletions
|
|
@ -49,6 +49,25 @@ def get_keycloak_client() -> KeycloakAdmin:
|
||||||
verify=True,
|
verify=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def get_requestable_groups() -> tuple[bool, str]:
|
||||||
|
"""Fetches available Keycloak groups, filtering out the 'admin' group."""
|
||||||
|
try:
|
||||||
|
kc = get_keycloak_client()
|
||||||
|
groups = kc.get_groups()
|
||||||
|
|
||||||
|
# Filter out 'admin' (case-insensitive)
|
||||||
|
valid_groups = [g["name"] for g in groups if g["name"].lower() != "admin"]
|
||||||
|
|
||||||
|
if not valid_groups:
|
||||||
|
return True, "No groups are currently available to request."
|
||||||
|
|
||||||
|
group_list = "\n".join([f"• `{name}`" for name in valid_groups])
|
||||||
|
return True, f"**Available Groups:**\n{group_list}"
|
||||||
|
|
||||||
|
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]:
|
def add_user_to_kc_group(username: str, group_name: str) -> tuple[bool, str]:
|
||||||
"""Queries Keycloak for the user and group UUIDs and adds the user to the group."""
|
"""Queries Keycloak for the user and group UUIDs and adds the user to the group."""
|
||||||
|
|
@ -100,12 +119,29 @@ async def on_invite(client: AsyncClient, room: MatrixRoom, event: InviteMemberEv
|
||||||
|
|
||||||
|
|
||||||
async def on_message(client: AsyncClient, room: MatrixRoom, event: RoomMessageText):
|
async def on_message(client: AsyncClient, room: MatrixRoom, event: RoomMessageText):
|
||||||
"""Listens for `!request <group_name>` commands."""
|
"""Listens for commands."""
|
||||||
# Ignore messages sent by the bot itself
|
# Ignore messages sent by the bot itself
|
||||||
if event.sender == client.user_id:
|
if event.sender == client.user_id:
|
||||||
return
|
return
|
||||||
|
|
||||||
body = event.body.strip()
|
body = event.body.strip()
|
||||||
|
|
||||||
|
# --- COMMAND: !groups ---
|
||||||
|
if body.startswith("!groups"):
|
||||||
|
success, msg = get_requestable_groups()
|
||||||
|
await send_message_safe(
|
||||||
|
client,
|
||||||
|
room_id=room.room_id,
|
||||||
|
content={
|
||||||
|
"msgtype": "m.notice" if not success else "m.text",
|
||||||
|
"body": msg,
|
||||||
|
"format": "org.matrix.custom.html",
|
||||||
|
"formatted_body": msg.replace("\n", "<br>")
|
||||||
|
},
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
# --- COMMAND: !request ---
|
||||||
if not body.startswith("!request"):
|
if not body.startswith("!request"):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
@ -114,17 +150,27 @@ async def on_message(client: AsyncClient, room: MatrixRoom, event: RoomMessageTe
|
||||||
await send_message_safe(
|
await send_message_safe(
|
||||||
client,
|
client,
|
||||||
room_id=room.room_id,
|
room_id=room.room_id,
|
||||||
message_type="m.room.message",
|
content={"msgtype": "m.notice", "body": "Usage: !request <group_name> or !groups"},
|
||||||
content={"msgtype": "m.notice", "body": "Usage: !request <group_name>"},
|
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
requested_group = parts[1].strip()
|
requested_group = parts[1].strip()
|
||||||
|
|
||||||
|
# Block 'admin' requests immediately
|
||||||
|
if requested_group.lower() == "admin":
|
||||||
|
await send_message_safe(
|
||||||
|
client,
|
||||||
|
room_id=room.room_id,
|
||||||
|
content={
|
||||||
|
"msgtype": "m.notice",
|
||||||
|
"body": "❌ Requests for the 'admin' group are not permitted."
|
||||||
|
},
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
matrix_user = event.sender
|
matrix_user = event.sender
|
||||||
# Extract username (e.g., "@alice:nest.local" -> "alice")
|
|
||||||
kc_username = matrix_user.split(":")[0].lstrip("@")
|
kc_username = matrix_user.split(":")[0].lstrip("@")
|
||||||
|
|
||||||
# Send notification message to the private Admin Room
|
|
||||||
admin_msg_body = (
|
admin_msg_body = (
|
||||||
f"📋 **Access Request**\n"
|
f"📋 **Access Request**\n"
|
||||||
f"**User:** `{matrix_user}` (KC Username: `{kc_username}`)\n"
|
f"**User:** `{matrix_user}` (KC Username: `{kc_username}`)\n"
|
||||||
|
|
@ -144,7 +190,6 @@ async def on_message(client: AsyncClient, room: MatrixRoom, event: RoomMessageTe
|
||||||
)
|
)
|
||||||
|
|
||||||
if isinstance(res, RoomSendResponse):
|
if isinstance(res, RoomSendResponse):
|
||||||
# Store pending request keyed by the admin message event_id
|
|
||||||
pending_requests[res.event_id] = {
|
pending_requests[res.event_id] = {
|
||||||
"matrix_user": matrix_user,
|
"matrix_user": matrix_user,
|
||||||
"kc_username": kc_username,
|
"kc_username": kc_username,
|
||||||
|
|
@ -152,7 +197,6 @@ async def on_message(client: AsyncClient, room: MatrixRoom, event: RoomMessageTe
|
||||||
"origin_room_id": room.room_id,
|
"origin_room_id": room.room_id,
|
||||||
}
|
}
|
||||||
|
|
||||||
# Confirm request receipt to the user
|
|
||||||
await send_message_safe(
|
await send_message_safe(
|
||||||
client,
|
client,
|
||||||
room_id=room.room_id,
|
room_id=room.room_id,
|
||||||
|
|
@ -245,15 +289,26 @@ async def on_reaction(client: AsyncClient, room: MatrixRoom, event: ReactionEven
|
||||||
return # Ignore other reactions
|
return # Ignore other reactions
|
||||||
|
|
||||||
# Update the original admin room message to reflect resolution status
|
# Update the original admin room message to reflect resolution status
|
||||||
|
fallback_text = f"* {status_text}"
|
||||||
|
|
||||||
await send_message_safe(
|
await send_message_safe(
|
||||||
client,
|
client,
|
||||||
room_id=ADMIN_ROOM_ID,
|
room_id=ADMIN_ROOM_ID,
|
||||||
content={
|
content={
|
||||||
|
"msgtype": "m.text",
|
||||||
|
"body": fallback_text,
|
||||||
|
"format": "org.matrix.custom.html",
|
||||||
|
"formatted_body": fallback_text.replace("\n", "<br>"),
|
||||||
|
"m.new_content": {
|
||||||
"msgtype": "m.text",
|
"msgtype": "m.text",
|
||||||
"body": status_text,
|
"body": status_text,
|
||||||
"format": "org.matrix.custom.html",
|
"format": "org.matrix.custom.html",
|
||||||
"formatted_body": status_text.replace("\n", "<br>"),
|
"formatted_body": status_text.replace("\n", "<br>"),
|
||||||
"m.relates_to": {"rel_type": "m.replace", "event_id": target_event_id},
|
},
|
||||||
|
"m.relates_to": {
|
||||||
|
"rel_type": "m.replace",
|
||||||
|
"event_id": target_event_id
|
||||||
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue