Permissions¶
The package uses two layers of permission checking: decorator-level guards on
consumer methods, and django-guardian object-level permissions on room
instances.
Permission Decorators¶
Every consumer event handler that requires authorisation is wrapped with a
decorator from realtime_chat_messaging.permissions.decorators. Each decorator
calls the configured PERMISSION_HANDLER_CLASS and injects the resolved
room object into the handler method.
Decorator |
What it checks |
|---|---|
|
User is a member of the room (participant or subscriber) |
|
User can send to the room (see rules below). Injects |
|
User is a member of the room containing the message(s) |
|
User is the sender of the message(s). All messages must be in the same room. Injects |
|
User has |
|
User has |
|
For |
Send Message Permission Rules¶
The rules vary by room type:
OneToOneChat — user must be a participant.
GroupChat (unlocked) — user must be a participant.
GroupChat (locked, i.e. group_locked=True) — user must be a participant AND (be the creator OR be an admin).
Channel — user must be a subscriber AND (be the creator OR be a moderator OR have the
can_send_messagesobject-level permission).
Note that even the creator of a group or channel must be a member (participant / subscriber) to send messages, add/remove members, delete the room etc. Leaving a room as a creator of that room from the members list removes your privileges as a creator.
Object-Level Permissions¶
django-guardian manages per-room permissions. Permissions are assigned and
revoked automatically via Django signals — you rarely need to manage them
manually.
GroupChat permissions:
Permission codename |
Automatically granted to |
|---|---|
|
Creator on room creation; any user added to |
|
Creator on room creation; any user added to |
Channel permissions:
Permission codename |
Automatically granted to |
|---|---|
|
Creator on room creation; any user added to |
|
Creator on room creation; any user added to |
|
Creator on room creation; any user added to |
Managing Permissions via WebSocket¶
Grant or revoke object-level permissions for specific users via room.modify:
Grant:
{
"event_type": "room.modify",
"data": {
"room_id": "<uuid>",
"action": "add_permission",
"data": {
"users": [3, 7],
"permission": ["can_send_messages"]
}
}
}
Revoke:
{
"event_type": "room.modify",
"data": {
"room_id": "<uuid>",
"action": "remove_permission",
"data": {
"users": [3],
"permission": ["can_send_messages"]
}
}
}
Valid permissions for GroupChat: can_add_new_participants,
can_remove_participants.
Valid permissions for Channel: can_add_new_subscribers,
can_remove_subscribers, can_send_messages.
The room creator can never have their permissions removed by another admin —
room.creator.id is silently excluded from any permission removal operation.
Managing Admins and Moderators¶
Add admin to GroupChat:
{
"event_type": "room.modify",
"data": {
"room_id": "<uuid>",
"action": "add_admin",
"data": {
"users": [5, 6]
}
}
}
Remove admin from GroupChat:
{
"event_type": "room.modify",
"data": {
"room_id": "<uuid>",
"action": "remove_admin",
"data": {
"users": [5]
}
}
}
Add moderator to Channel:
{
"event_type": "room.modify",
"data": {
"room_id": "<uuid>",
"action": "add_moderator",
"data": {
"users": [8]
}
}
}
When a user is added to admins or moderators the signal
add_permissions_to_admin_and_moderators automatically grants the appropriate
permissions. When they are removed, all permissions are revoked.
Only users who are already room members can be made admins or moderators. Users not in the member list are silently skipped.
Customising Permissions¶
To replace the entire permission logic, implement a custom PermissionHandler
and configure it in settings:
REALTIME_CHAT_MESSAGING = {
"PERMISSION_HANDLER_CLASS": "myapp.permissions.MyPermissionHandler"
}
Your class must expose the same async interface:
from realtime_chat_messaging.permissions.handlers import PermissionHandler
class MyPermissionHandler(PermissionHandler):
async def have_send_message_permission(self, user, data):
# Custom logic — return (is_permitted: bool, room: Room)
...
To override only specific checks, subclass PermissionHandler and override
the relevant async method. Each method must return (bool, Room) except
have_message_permission which returns bool only.
For finer-grained customisation, subclass PermissionHelperMixin (the
synchronous layer) and override the _have_* methods. Wrap your DB calls
with sqlite_safe_db_sync_to_async. See Custom Permissions for full
examples.
The default_admin_names Parameter¶
Several permission helper methods accept a default_admin_names keyword
argument:
default_admin_names = {"group": "admins", "channel": "moderators"}
This maps to the M2M field names used for admins (GroupChat) and moderators
(Channel). If you create a custom GroupChat or Channel model that renames
these fields (e.g. admins → managers), you must pass the updated mapping
when calling these methods or override the helpers to use your field names.