core: improve error handling on ASGI level (cherry-pick #10547) (#10552)

core: improve error handling on ASGI level (#10547)

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens L. <jens@goauthentik.io>
This commit is contained in:
gcp-cherry-pick-bot[bot]
2024-07-19 17:19:29 +02:00
committed by GitHub
parent 9075270b01
commit 6426a1d177
6 changed files with 10 additions and 8 deletions

View File

@ -5,7 +5,6 @@ from channels.sessions import CookieMiddleware
from django.urls import path from django.urls import path
from django.views.decorators.csrf import ensure_csrf_cookie from django.views.decorators.csrf import ensure_csrf_cookie
from authentik.core.channels import TokenOutpostMiddleware
from authentik.enterprise.providers.rac.api.connection_tokens import ConnectionTokenViewSet from authentik.enterprise.providers.rac.api.connection_tokens import ConnectionTokenViewSet
from authentik.enterprise.providers.rac.api.endpoints import EndpointViewSet from authentik.enterprise.providers.rac.api.endpoints import EndpointViewSet
from authentik.enterprise.providers.rac.api.property_mappings import RACPropertyMappingViewSet from authentik.enterprise.providers.rac.api.property_mappings import RACPropertyMappingViewSet
@ -13,6 +12,7 @@ from authentik.enterprise.providers.rac.api.providers import RACProviderViewSet
from authentik.enterprise.providers.rac.consumer_client import RACClientConsumer from authentik.enterprise.providers.rac.consumer_client import RACClientConsumer
from authentik.enterprise.providers.rac.consumer_outpost import RACOutpostConsumer from authentik.enterprise.providers.rac.consumer_outpost import RACOutpostConsumer
from authentik.enterprise.providers.rac.views import RACInterface, RACStartView from authentik.enterprise.providers.rac.views import RACInterface, RACStartView
from authentik.outposts.channels import TokenOutpostMiddleware
from authentik.root.asgi_middleware import SessionMiddleware from authentik.root.asgi_middleware import SessionMiddleware
from authentik.root.middleware import ChannelsLoggingMiddleware from authentik.root.middleware import ChannelsLoggingMiddleware

View File

@ -2,7 +2,6 @@
from dataclasses import asdict from dataclasses import asdict
from channels.exceptions import DenyConnection
from channels.routing import URLRouter from channels.routing import URLRouter
from channels.testing import WebsocketCommunicator from channels.testing import WebsocketCommunicator
from django.test import TransactionTestCase from django.test import TransactionTestCase
@ -37,9 +36,8 @@ class TestOutpostWS(TransactionTestCase):
communicator = WebsocketCommunicator( communicator = WebsocketCommunicator(
URLRouter(websocket.websocket_urlpatterns), f"/ws/outpost/{self.outpost.pk}/" URLRouter(websocket.websocket_urlpatterns), f"/ws/outpost/{self.outpost.pk}/"
) )
with self.assertRaises(DenyConnection): connected, _ = await communicator.connect()
connected, _ = await communicator.connect() self.assertFalse(connected)
self.assertFalse(connected)
async def test_auth_valid(self): async def test_auth_valid(self):
"""Test auth with token""" """Test auth with token"""

View File

@ -2,13 +2,13 @@
from django.urls import path from django.urls import path
from authentik.core.channels import TokenOutpostMiddleware
from authentik.outposts.api.outposts import OutpostViewSet from authentik.outposts.api.outposts import OutpostViewSet
from authentik.outposts.api.service_connections import ( from authentik.outposts.api.service_connections import (
DockerServiceConnectionViewSet, DockerServiceConnectionViewSet,
KubernetesServiceConnectionViewSet, KubernetesServiceConnectionViewSet,
ServiceConnectionViewSet, ServiceConnectionViewSet,
) )
from authentik.outposts.channels import TokenOutpostMiddleware
from authentik.outposts.consumer import OutpostConsumer from authentik.outposts.consumer import OutpostConsumer
from authentik.root.middleware import ChannelsLoggingMiddleware from authentik.root.middleware import ChannelsLoggingMiddleware

View File

@ -274,9 +274,13 @@ class ChannelsLoggingMiddleware:
self.log(scope) self.log(scope)
try: try:
return await self.inner(scope, receive, send) return await self.inner(scope, receive, send)
except DenyConnection:
return await send({"type": "websocket.close"})
except Exception as exc: except Exception as exc:
if settings.DEBUG:
raise exc
LOGGER.warning("Exception in ASGI application", exc=exc) LOGGER.warning("Exception in ASGI application", exc=exc)
raise DenyConnection() from None return await send({"type": "websocket.close"})
def log(self, scope: dict, **kwargs): def log(self, scope: dict, **kwargs):
"""Log request""" """Log request"""

View File

@ -144,7 +144,7 @@ class Migration(migrations.Migration):
default=None, default=None,
help_text=( help_text=(
"When set, shows a password field, instead of showing the password field as" "When set, shows a password field, instead of showing the password field as"
" seaprate step." " separate step."
), ),
null=True, null=True,
on_delete=django.db.models.deletion.SET_NULL, on_delete=django.db.models.deletion.SET_NULL,