-
Notifications
You must be signed in to change notification settings - Fork 149
/
models.py
123 lines (98 loc) · 3.66 KB
/
models.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
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
from django.conf import settings
from django.db import models
from django.utils.translation import gettext_lazy as _
from django.contrib.auth import get_user_model
from django_rest_passwordreset.tokens import get_token_generator
# Prior to Django 1.5, the AUTH_USER_MODEL setting does not exist.
# Note that we don't perform this code in the compat module due to
# bug report #1297
# See: https://github.com/tomchristie/django-rest-framework/issues/1297
AUTH_USER_MODEL = getattr(settings, 'AUTH_USER_MODEL', 'auth.User')
# get the token generator class
TOKEN_GENERATOR_CLASS = get_token_generator()
__all__ = [
'ResetPasswordToken',
'get_password_reset_token_expiry_time',
'get_password_reset_lookup_field',
'clear_expired',
]
class ResetPasswordToken(models.Model):
class Meta:
verbose_name = _("Password Reset Token")
verbose_name_plural = _("Password Reset Tokens")
@staticmethod
def generate_key():
""" generates a pseudo random code using os.urandom and binascii.hexlify """
return TOKEN_GENERATOR_CLASS.generate_token()
id = models.AutoField(
primary_key=True
)
user = models.ForeignKey(
AUTH_USER_MODEL,
related_name='password_reset_tokens',
on_delete=models.CASCADE,
verbose_name=_("The User which is associated to this password reset token")
)
created_at = models.DateTimeField(
auto_now_add=True,
verbose_name=_("When was this token generated")
)
# Key field, though it is not the primary key of the model
key = models.CharField(
_("Key"),
max_length=64,
db_index=True,
unique=True
)
ip_address = models.GenericIPAddressField(
_("The IP address of this session"),
default="",
blank=True,
null=True,
)
user_agent = models.CharField(
max_length=512,
verbose_name=_("HTTP User Agent"),
default="",
blank=True,
)
def save(self, *args, **kwargs):
if not self.key:
self.key = self.generate_key()
return super(ResetPasswordToken, self).save(*args, **kwargs)
def __str__(self):
return "Password reset token for user {user}".format(user=self.user)
def get_password_reset_token_expiry_time():
"""
Returns the password reset token expirty time in hours (default: 24)
Set Django SETTINGS.DJANGO_REST_MULTITOKENAUTH_RESET_TOKEN_EXPIRY_TIME to overwrite this time
:return: expiry time
"""
# get token validation time
return getattr(settings, 'DJANGO_REST_MULTITOKENAUTH_RESET_TOKEN_EXPIRY_TIME', 24)
def get_password_reset_lookup_field():
"""
Returns the password reset lookup field (default: email)
Set Django SETTINGS.DJANGO_REST_LOOKUP_FIELD to overwrite this time
:return: lookup field
"""
return getattr(settings, 'DJANGO_REST_LOOKUP_FIELD', 'email')
def clear_expired(expiry_time):
"""
Remove all expired tokens
:param expiry_time: Token expiration time
"""
ResetPasswordToken.objects.filter(created_at__lte=expiry_time).delete()
def eligible_for_reset(self):
if not self.is_active:
# if the user is active we dont bother checking
return False
if getattr(settings, 'DJANGO_REST_MULTITOKENAUTH_REQUIRE_USABLE_PASSWORD', True):
# if we require a usable password then return the result of has_usable_password()
return self.has_usable_password()
else:
# otherwise return True because we dont care about the result of has_usable_password()
return True
# add eligible_for_reset to the user class
UserModel = get_user_model()
UserModel.add_to_class("eligible_for_reset", eligible_for_reset)