-
Notifications
You must be signed in to change notification settings - Fork 22
/
Copy pathbackends.py
63 lines (50 loc) · 2.03 KB
/
backends.py
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
from rest_framework import exceptions
from rest_framework.authentication import TokenAuthentication
from rest_framework_digestauth.models import DigestAuthCounter
class AbstractDigestBackend(object):
def __init__(self, user):
self.user = user # This user is *unauthenticated*, beware.
def get_password(self):
"""
This should return a plain text password, or something that can be used
in it's place, such as a token. Exactly what is used and how it's
generated much be pre-negotiated with all clients.
"""
raise NotImplementedError
def get_counter(self, server_nonce, client_nonce):
"""
This should return an integer, which should be equal to the last call
to `set_counter` or None was not previously a counter set.
"""
raise NotImplementedError
def set_counter(self, server_nonce, client_nonce, counter):
"""
This method should store the counter, to be returned at a later date
when `get_counter` is called.
"""
raise NotImplementedError
class DatabaseBackend(AbstractDigestBackend):
def get_password(self):
Token = TokenAuthentication.model
try:
token = Token.objects.get(user=self.user)
except (Token.DoesNotExist,
Token.MultipleObjectsReturned):
raise exceptions.AuthenticationFailed
return token.key
def get_counter(self, server_nonce, client_nonce):
try:
auth_counter = DigestAuthCounter.objects.get(
server_nonce=server_nonce,
client_nonce=client_nonce,
)
except DigestAuthCounter.DoesNotExist:
return None
return auth_counter.client_counter
def set_counter(self, server_nonce, client_nonce, counter):
auth_counter, __ = DigestAuthCounter.objects.get_or_create(
server_nonce=server_nonce,
client_nonce=client_nonce,
)
auth_counter.client_counter = counter
auth_counter.save()