authentik.root.ws.storage
Channels Messages storage
1"""Channels Messages storage""" 2 3from asgiref.sync import async_to_sync 4from channels.layers import get_channel_layer 5from django.contrib.messages.storage.base import Message 6from django.contrib.messages.storage.session import SessionStorage 7from django.core.cache import cache 8from django.http.request import HttpRequest 9 10SESSION_KEY = "_messages" 11CACHE_PREFIX = "goauthentik.io/root/messages_" 12 13 14class ChannelsStorage(SessionStorage): 15 """Send contrib.messages over websocket""" 16 17 def __init__(self, request: HttpRequest) -> None: 18 super().__init__(request) 19 self.channel = get_channel_layer() 20 21 def _store(self, messages: list[Message], response, *args, **kwargs): 22 prefix = f"{CACHE_PREFIX}{self.request.session.session_key}_messages_" 23 keys = cache.keys(f"{prefix}*") 24 # if no active connections are open, fallback to storing messages in the 25 # session, so they can always be retrieved 26 if len(keys) < 1: 27 return super()._store(messages, response, *args, **kwargs) 28 for key in keys: 29 uid = key.replace(prefix, "") 30 for message in messages: 31 async_to_sync(self.channel.send)( 32 uid, 33 { 34 "type": "event.message", 35 "message_type": "message", 36 "level": message.level_tag, 37 "tags": message.tags, 38 "message": message.message, 39 }, 40 ) 41 return []
SESSION_KEY =
'_messages'
CACHE_PREFIX =
'goauthentik.io/root/messages_'
class
ChannelsStorage(django.contrib.messages.storage.session.SessionStorage):
15class ChannelsStorage(SessionStorage): 16 """Send contrib.messages over websocket""" 17 18 def __init__(self, request: HttpRequest) -> None: 19 super().__init__(request) 20 self.channel = get_channel_layer() 21 22 def _store(self, messages: list[Message], response, *args, **kwargs): 23 prefix = f"{CACHE_PREFIX}{self.request.session.session_key}_messages_" 24 keys = cache.keys(f"{prefix}*") 25 # if no active connections are open, fallback to storing messages in the 26 # session, so they can always be retrieved 27 if len(keys) < 1: 28 return super()._store(messages, response, *args, **kwargs) 29 for key in keys: 30 uid = key.replace(prefix, "") 31 for message in messages: 32 async_to_sync(self.channel.send)( 33 uid, 34 { 35 "type": "event.message", 36 "message_type": "message", 37 "level": message.level_tag, 38 "tags": message.tags, 39 "message": message.message, 40 }, 41 ) 42 return []
Send contrib.messages over websocket