mirror of
https://github.com/ansible/awx.git
synced 2026-05-06 08:57:35 -02:30
Support websocket per-endpoint auth
* Channels doesn't really give you an interface to support per-endpoint auth ... so this adds one. * The web browser and node <--> node communication have different auth needs.
This commit is contained in:
@@ -27,14 +27,50 @@ class AWXProtocolTypeRouter(ProtocolTypeRouter):
|
|||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class MultipleURLRouterAdapter:
|
||||||
|
"""
|
||||||
|
Django channels doesn't nicely support Auth_1(urls_1), Auth_2(urls_2), ..., Auth_n(urls_n)
|
||||||
|
This class allows assocating a websocket url with an auth
|
||||||
|
Ordering matters. The first matching url will be used.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, *auths):
|
||||||
|
self._auths = [a for a in auths]
|
||||||
|
|
||||||
|
async def __call__(self, scope, receive, send):
|
||||||
|
"""
|
||||||
|
Loop through the list of passed in URLRouter's (they may or may not be wrapped by auth).
|
||||||
|
We know we have exhausted the list of URLRouter patterns when we get a
|
||||||
|
ValueError('No route found for path %s'). When that happens, move onto the next
|
||||||
|
URLRouter.
|
||||||
|
If the final URLRouter raises an error, re-raise it in the end.
|
||||||
|
|
||||||
|
We know that we found a match when no error is raised, end the loop.
|
||||||
|
"""
|
||||||
|
last_index = len(self._auths) - 1
|
||||||
|
for i, auth in enumerate(self._auths):
|
||||||
|
try:
|
||||||
|
return await auth.__call__(scope, receive, send)
|
||||||
|
except ValueError as e:
|
||||||
|
if str(e).startswith('No route found for path'):
|
||||||
|
# Only surface the error if on the last URLRouter
|
||||||
|
if i == last_index:
|
||||||
|
raise
|
||||||
|
|
||||||
|
|
||||||
websocket_urlpatterns = [
|
websocket_urlpatterns = [
|
||||||
re_path(r'api/websocket/$', consumers.EventConsumer.as_asgi()),
|
re_path(r'api/websocket/$', consumers.EventConsumer.as_asgi()),
|
||||||
re_path(r'websocket/$', consumers.EventConsumer.as_asgi()),
|
re_path(r'websocket/$', consumers.EventConsumer.as_asgi()),
|
||||||
|
]
|
||||||
|
websocket_relay_urlpatterns = [
|
||||||
re_path(r'websocket/relay/$', consumers.RelayConsumer.as_asgi()),
|
re_path(r'websocket/relay/$', consumers.RelayConsumer.as_asgi()),
|
||||||
]
|
]
|
||||||
|
|
||||||
application = AWXProtocolTypeRouter(
|
application = AWXProtocolTypeRouter(
|
||||||
{
|
{
|
||||||
'websocket': DrfAuthMiddlewareStack(URLRouter(websocket_urlpatterns)),
|
'websocket': MultipleURLRouterAdapter(
|
||||||
|
URLRouter(websocket_relay_urlpatterns),
|
||||||
|
DrfAuthMiddlewareStack(URLRouter(websocket_urlpatterns)),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user