don't reject websocket requests that don't have an Origin header

This commit is contained in:
Gwendolyn 2024-03-29 12:24:45 +01:00
parent ba47de5bb4
commit 24ef0f81de

View file

@ -3,7 +3,7 @@ from contextlib import suppress
from channels.auth import AuthMiddlewareStack from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter from channels.routing import ProtocolTypeRouter, URLRouter
from channels.security.websocket import AllowedHostsOriginValidator from channels.security.websocket import OriginValidator
from django.core.asgi import get_asgi_application from django.core.asgi import get_asgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "c3nav.settings") os.environ.setdefault("DJANGO_SETTINGS_MODULE", "c3nav.settings")
@ -13,9 +13,37 @@ django_asgi = get_asgi_application()
from c3nav.control.middleware import UserPermissionsChannelMiddleware # noqa from c3nav.control.middleware import UserPermissionsChannelMiddleware # noqa
from c3nav.urls import websocket_urlpatterns # noqa from c3nav.urls import websocket_urlpatterns # noqa
class OriginValidatorWithAllowNone(OriginValidator):
def valid_origin(self, parsed_origin):
"""
Checks parsed origin is None.
We want to allow None because browsers always send the Origin header and non-browser clients do not need CORS
Pass control to the validate_origin function.
Returns ``True`` if validation function was successful, ``False`` otherwise.
"""
# None is not allowed unless all hosts are allowed
if parsed_origin is None:
return True
return self.validate_origin(parsed_origin)
def AllowedHostsOriginValidatorWithAllowNone(app):
"""
Factory function which returns an OriginValidatorWithAllowNone configured to use
settings.ALLOWED_HOSTS.
"""
allowed_hosts = settings.ALLOWED_HOSTS
if settings.DEBUG and not allowed_hosts:
allowed_hosts = ["localhost", "127.0.0.1", "[::1]"]
return OriginValidatorWithAllowNone(app, allowed_hosts)
application = ProtocolTypeRouter({ application = ProtocolTypeRouter({
"http": django_asgi, "http": django_asgi,
"websocket": AllowedHostsOriginValidator( "websocket": AllowedHostsOriginValidatorWithAllowNone(
AuthMiddlewareStack( AuthMiddlewareStack(
UserPermissionsChannelMiddleware( UserPermissionsChannelMiddleware(
URLRouter(websocket_urlpatterns), URLRouter(websocket_urlpatterns),