1 3
import functools
2

3 3
from channels.handler import AsgiRequest
4 3
from rest_framework.exceptions import AuthenticationFailed
5 3
from rest_framework.settings import api_settings
6 3
from django.conf import settings
7

8
#print(api_settings.DEFAULT_AUTHENTICATION_CLASSES)
9
#authenticators = [auth() for auth in api_settings.DEFAULT_AUTHENTICATION_CLASSES]
10

11

12 3
def rest_auth(func):
13
    """
14
    Wraps a HTTP or WebSocket connect consumer (or any consumer of messages
15
    that provides a "cookies" or "get" attribute) to provide a "http_session"
16
    attribute that behaves like request.session; that is, it's hung off of
17
    a per-user session key that is saved in a cookie or passed as the
18
    "session_key" GET parameter.
19

20
    It won't automatically create and set a session cookie for users who
21
    don't have one - that's what SessionMiddleware is for, this is a simpler
22
    read-only version for more low-level code.
23

24
    If a message does not have a session we can inflate, the "session" attribute
25
    will be None, rather than an empty session you can write to.
26

27
    Does not allow a new session to be set; that must be done via a view. This
28
    is only an accessor for any existing session.
29
    """
30 3
    @functools.wraps(func)
31
    def inner(message, *args, **kwargs):
32
        # Make sure there's NOT a http_session already
33 0
        try:
34
            # We want to parse the WebSocket (or similar HTTP-lite) message
35
            # to get cookies and GET, but we need to add in a few things that
36
            # might not have been there.
37 0
            if "method" not in message.content:
38 0
                message.content['method'] = "FAKE"
39 0
            request = AsgiRequest(message)
40

41 0
        except Exception as e:
42 0
            raise ValueError("Cannot parse HTTP message - are you sure this is a HTTP consumer? %s" % e)
43
        # Make sure there's a session key
44 0
        user = None
45 0
        auth = None
46 0
        auth_token = request.GET.get("token", None)
47 0
        print('NEW TOKEN : {}'.format(auth_token))
48 0
        if auth_token:
49
            # comptatibility with rest framework
50 0
            request._request = {}
51 0
            request.META["HTTP_AUTHORIZATION"] = "Bearer {}".format(auth_token)
52 0
            authenticators = [auth() for auth in api_settings.DEFAULT_AUTHENTICATION_CLASSES]
53 0
            print('Try Auth with {}'.format(request.META['HTTP_AUTHORIZATION']))
54 0
            for authenticator in authenticators:
55 0
                try:
56 0
                    user_auth_tuple = authenticator.authenticate(request)
57 0
                except AuthenticationFailed:
58 0
                    pass
59

60 0
                if user_auth_tuple is not None:
61 0
                    message._authenticator = authenticator
62 0
                    user, auth = user_auth_tuple
63 0
                    break
64 0
        message.user, message.auth = user, auth
65
        # Make sure there's a session key
66
        # Run the consumer
67 0
        result = func(message, *args, **kwargs)
68 0
        return result
69 3
    return inner
70

71

72 3
def rest_token_user(func):
73
    """
74
saf    Wraps a HTTP or WebSocket consumer (or any consumer of messages
75
    that provides a "COOKIES" attribute) to provide both a "session"
76
    attribute and a "user" attibute, like AuthMiddleware does.
77

78
    This runs http_session() to get a session to hook auth off of.
79
    If the user does not have a session cookie set, both "session"
80
    and "user" will be None.
81
    """
82 0
    @rest_auth
83 0
    @functools.wraps(func)
84
    def inner(message, *args, **kwargs):
85
        # If we didn't get a session, then we don't get a user
86 0
        if not hasattr(message, "auth"):
87 0
            raise ValueError("Did not see a http session to get auth from")
88 0
        return func(message, *args, **kwargs)
89 0
    return inner
90

91

92 3
class RestTokenConsumerMixin(object):
93 3
    rest_user = False
94

95 3
    def get_handler(self, message, **kwargs):
96 0
        handler = super(RestTokenConsumerMixin, self).get_handler(message, **kwargs)
97 0
        if self.rest_user:
98 0
            handler = rest_token_user(handler)
99 0
        return handler
100

101 3
    def connect(self, message, **kwargs):
102 0
        if self.rest_user and not self.message.user:
103 0
            self.close()
104 0
        return message

Read our documentation on viewing source code .

Loading