/usr/lib/python3/dist-packages/channels/auth.py is in python3-django-channels 1.1.8.1-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | import functools
from django.contrib import auth
from .sessions import channel_and_http_session, channel_session, http_session
def transfer_user(from_session, to_session):
"""
Transfers user from HTTP session to channel session.
"""
if auth.BACKEND_SESSION_KEY in from_session and \
auth.SESSION_KEY in from_session and \
auth.HASH_SESSION_KEY in from_session:
to_session[auth.BACKEND_SESSION_KEY] = from_session[auth.BACKEND_SESSION_KEY]
to_session[auth.SESSION_KEY] = from_session[auth.SESSION_KEY]
to_session[auth.HASH_SESSION_KEY] = from_session[auth.HASH_SESSION_KEY]
def channel_session_user(func):
"""
Presents a message.user attribute obtained from a user ID in the channel
session, rather than in the http_session. Turns on channel session implicitly.
"""
@channel_session
@functools.wraps(func)
def inner(message, *args, **kwargs):
# If we didn't get a session, then we don't get a user
if not hasattr(message, "channel_session"):
raise ValueError("Did not see a channel session to get auth from")
if message.channel_session is None:
# Inner import to avoid reaching into models before load complete
from django.contrib.auth.models import AnonymousUser
message.user = AnonymousUser()
# Otherwise, be a bit naughty and make a fake Request with just
# a "session" attribute (later on, perhaps refactor contrib.auth to
# pass around session rather than request)
else:
fake_request = type("FakeRequest", (object, ), {"session": message.channel_session})
message.user = auth.get_user(fake_request)
# Run the consumer
return func(message, *args, **kwargs)
return inner
def http_session_user(func):
"""
Wraps a HTTP or WebSocket consumer (or any consumer of messages
that provides a "COOKIES" attribute) to provide both a "session"
attribute and a "user" attibute, like AuthMiddleware does.
This runs http_session() to get a session to hook auth off of.
If the user does not have a session cookie set, both "session"
and "user" will be None.
"""
@http_session
@functools.wraps(func)
def inner(message, *args, **kwargs):
# If we didn't get a session, then we don't get a user
if not hasattr(message, "http_session"):
raise ValueError("Did not see a http session to get auth from")
if message.http_session is None:
# Inner import to avoid reaching into models before load complete
from django.contrib.auth.models import AnonymousUser
message.user = AnonymousUser()
# Otherwise, be a bit naughty and make a fake Request with just
# a "session" attribute (later on, perhaps refactor contrib.auth to
# pass around session rather than request)
else:
fake_request = type("FakeRequest", (object, ), {"session": message.http_session})
message.user = auth.get_user(fake_request)
# Run the consumer
return func(message, *args, **kwargs)
return inner
def channel_session_user_from_http(func):
"""
Decorator that automatically transfers the user from HTTP sessions to
channel-based sessions, and returns the user as message.user as well.
Useful for things that consume e.g. websocket.connect
"""
@http_session_user
@channel_session
@functools.wraps(func)
def inner(message, *args, **kwargs):
if message.http_session is not None:
transfer_user(message.http_session, message.channel_session)
return func(message, *args, **kwargs)
return inner
def channel_and_http_session_user_from_http(func):
"""
Decorator that automatically transfers the user from HTTP sessions to
channel-based sessions, rehydrates the HTTP session, and returns the
user as message.user as well.
"""
@http_session_user
@channel_and_http_session
@functools.wraps(func)
def inner(message, *args, **kwargs):
if message.http_session is not None:
transfer_user(message.http_session, message.channel_session)
return func(message, *args, **kwargs)
return inner
|