core: bump channels-redis from 4.0.0 to 4.1.0 (#5115)

* core: bump channels-redis from 4.0.0 to 4.1.0

Bumps [channels-redis](https://github.com/django/channels_redis) from 4.0.0 to 4.1.0.
- [Release notes](https://github.com/django/channels_redis/releases)
- [Changelog](https://github.com/django/channels_redis/blob/main/CHANGELOG.txt)
- [Commits](https://github.com/django/channels_redis/compare/4.0.0...4.1.0)

---
updated-dependencies:
- dependency-name: channels-redis
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* remove channels <4.1 workaround

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
dependabot[bot] 2023-03-30 00:08:07 +02:00 committed by GitHub
parent 2e5a33f0c2
commit 73bf6fd530
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 20 additions and 26 deletions

View File

@ -7,6 +7,7 @@ from urllib.parse import urlparse
import yaml import yaml
from asgiref.sync import async_to_sync from asgiref.sync import async_to_sync
from channels.layers import get_channel_layer
from django.core.cache import cache from django.core.cache import cache
from django.db import DatabaseError, InternalError, ProgrammingError from django.db import DatabaseError, InternalError, ProgrammingError
from django.db.models.base import Model from django.db.models.base import Model
@ -42,7 +43,6 @@ from authentik.providers.ldap.controllers.kubernetes import LDAPKubernetesContro
from authentik.providers.proxy.controllers.docker import ProxyDockerController from authentik.providers.proxy.controllers.docker import ProxyDockerController
from authentik.providers.proxy.controllers.kubernetes import ProxyKubernetesController from authentik.providers.proxy.controllers.kubernetes import ProxyKubernetesController
from authentik.root.celery import CELERY_APP from authentik.root.celery import CELERY_APP
from authentik.root.messages.storage import closing_send
LOGGER = get_logger() LOGGER = get_logger()
CACHE_KEY_OUTPOST_DOWN = "outpost_teardown_%s" CACHE_KEY_OUTPOST_DOWN = "outpost_teardown_%s"
@ -214,26 +214,29 @@ def outpost_post_save(model_class: str, model_pk: Any):
outpost_send_update(reverse) outpost_send_update(reverse)
def outpost_send_update(model_instace: Model): def outpost_send_update(model_instance: Model):
"""Send outpost update to all registered outposts, regardless to which authentik """Send outpost update to all registered outposts, regardless to which authentik
instance they are connected""" instance they are connected"""
if isinstance(model_instace, OutpostModel): channel_layer = get_channel_layer()
for outpost in model_instace.outpost_set.all(): if isinstance(model_instance, OutpostModel):
_outpost_single_update(outpost) for outpost in model_instance.outpost_set.all():
elif isinstance(model_instace, Outpost): _outpost_single_update(outpost, channel_layer)
_outpost_single_update(model_instace) elif isinstance(model_instance, Outpost):
_outpost_single_update(model_instance, channel_layer)
def _outpost_single_update(outpost: Outpost): def _outpost_single_update(outpost: Outpost, layer=None):
"""Update outpost instances connected to a single outpost""" """Update outpost instances connected to a single outpost"""
# Ensure token again, because this function is called when anything related to an # Ensure token again, because this function is called when anything related to an
# OutpostModel is saved, so we can be sure permissions are right # OutpostModel is saved, so we can be sure permissions are right
_ = outpost.token _ = outpost.token
outpost.build_user_permissions(outpost.user) outpost.build_user_permissions(outpost.user)
if not layer: # pragma: no cover
layer = get_channel_layer()
for state in OutpostState.for_outpost(outpost): for state in OutpostState.for_outpost(outpost):
for channel in state.channel_ids: for channel in state.channel_ids:
LOGGER.debug("sending update", channel=channel, instance=state.uid, outpost=outpost) LOGGER.debug("sending update", channel=channel, instance=state.uid, outpost=outpost)
async_to_sync(closing_send)(channel, {"type": "event.update"}) async_to_sync(layer.send)(channel, {"type": "event.update"})
@CELERY_APP.task( @CELERY_APP.task(

View File

@ -1,7 +1,6 @@
"""Channels Messages storage""" """Channels Messages storage"""
from asgiref.sync import async_to_sync from asgiref.sync import async_to_sync
from channels import DEFAULT_CHANNEL_LAYER from channels.layers import get_channel_layer
from channels.layers import channel_layers
from django.contrib.messages.storage.base import Message from django.contrib.messages.storage.base import Message
from django.contrib.messages.storage.session import SessionStorage from django.contrib.messages.storage.session import SessionStorage
from django.core.cache import cache from django.core.cache import cache
@ -11,21 +10,13 @@ SESSION_KEY = "_messages"
CACHE_PREFIX = "goauthentik.io/root/messages_" CACHE_PREFIX = "goauthentik.io/root/messages_"
async def closing_send(channel, message):
"""Wrapper around layer send that closes the connection"""
# See https://github.com/django/channels_redis/issues/332
# TODO: Remove this after channels_redis 4.1 is released
channel_layer = channel_layers.make_backend(DEFAULT_CHANNEL_LAYER)
await channel_layer.send(channel, message)
await channel_layer.close_pools()
class ChannelsStorage(SessionStorage): class ChannelsStorage(SessionStorage):
"""Send contrib.messages over websocket""" """Send contrib.messages over websocket"""
def __init__(self, request: HttpRequest) -> None: def __init__(self, request: HttpRequest) -> None:
# pyright: reportGeneralTypeIssues=false # pyright: reportGeneralTypeIssues=false
super().__init__(request) super().__init__(request)
self.channel = get_channel_layer()
def _store(self, messages: list[Message], response, *args, **kwargs): def _store(self, messages: list[Message], response, *args, **kwargs):
prefix = f"{CACHE_PREFIX}{self.request.session.session_key}_messages_" prefix = f"{CACHE_PREFIX}{self.request.session.session_key}_messages_"
@ -37,7 +28,7 @@ class ChannelsStorage(SessionStorage):
for key in keys: for key in keys:
uid = key.replace(prefix, "") uid = key.replace(prefix, "")
for message in messages: for message in messages:
async_to_sync(closing_send)( async_to_sync(self.channel.send)(
uid, uid,
{ {
"type": "event.update", "type": "event.update",

10
poetry.lock generated
View File

@ -661,25 +661,25 @@ tests = ["async-timeout", "coverage (>=4.5,<5.0)", "pytest", "pytest-asyncio", "
[[package]] [[package]]
name = "channels-redis" name = "channels-redis"
version = "4.0.0" version = "4.1.0"
description = "Redis-backed ASGI channel layer implementation" description = "Redis-backed ASGI channel layer implementation"
category = "main" category = "main"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "channels_redis-4.0.0-py3-none-any.whl", hash = "sha256:81b59d68f53313e1aa891f23591841b684abb936b42e4d1a966d9e4dc63a95ec"}, {file = "channels_redis-4.1.0-py3-none-any.whl", hash = "sha256:3696f5b9fe367ea495d402ba83d7c3c99e8ca0e1354ff8d913535976ed0abf73"},
{file = "channels_redis-4.0.0.tar.gz", hash = "sha256:122414f29f525f7b9e0c9d59cdcfc4dc1b0eecba16fbb6a1c23f1d9b58f49dcb"}, {file = "channels_redis-4.1.0.tar.gz", hash = "sha256:6bd4f75f4ab4a7db17cee495593ace886d7e914c66f8214a1f247ff6659c073a"},
] ]
[package.dependencies] [package.dependencies]
asgiref = ">=3.2.10,<4" asgiref = ">=3.2.10,<4"
channels = "*" channels = "*"
msgpack = ">=1.0,<2.0" msgpack = ">=1.0,<2.0"
redis = ">=4.2.0" redis = ">=4.5.3"
[package.extras] [package.extras]
cryptography = ["cryptography (>=1.3.0)"] cryptography = ["cryptography (>=1.3.0)"]
tests = ["async-timeout", "cryptography (>=1.3.0)", "pytest", "pytest-asyncio"] tests = ["async-timeout", "cryptography (>=1.3.0)", "pytest", "pytest-asyncio", "pytest-timeout"]
[[package]] [[package]]
name = "charset-normalizer" name = "charset-normalizer"