forked from anexia-it/django-rest-passwordreset
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmodels.py
116 lines (90 loc) · 3.58 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
from django.conf import settings
from django.contrib.auth import get_user_model
from django.db import models
from django.utils.translation import gettext_lazy as _
from .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=256,
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)