-
Notifications
You must be signed in to change notification settings - Fork 163
Expand file tree
/
Copy pathconfirmable.py
More file actions
107 lines (83 loc) · 2.78 KB
/
confirmable.py
File metadata and controls
107 lines (83 loc) · 2.78 KB
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
"""
flask_security.confirmable
~~~~~~~~~~~~~~~~~~~~~~~~~~
Flask-Security confirmable module
:copyright: (c) 2012 by Matt Wright.
:copyright: (c) 2017 by CERN.
:copyright: (c) 2021-2023 by J. Christopher Wagner (jwag).
:license: MIT, see LICENSE for more details.
"""
from flask import current_app
from .proxies import _security, _datastore
from .signals import confirm_instructions_sent, user_confirmed
from .utils import (
config_value as cv,
get_token_status,
hash_data,
send_mail,
url_for_security,
verify_hash,
)
def generate_confirmation_link(user):
token = generate_confirmation_token(user)
return url_for_security("confirm_email", token=token, _external=True), token
def send_confirmation_instructions(user):
"""Sends the confirmation instructions email for the specified user.
:param user: The user to send the instructions to
"""
confirmation_link, token = generate_confirmation_link(user)
send_mail(
cv("EMAIL_SUBJECT_CONFIRM"),
user.email,
"confirmation_instructions",
user=user,
confirmation_link=confirmation_link,
confirmation_token=token,
)
confirm_instructions_sent.send(
current_app._get_current_object(),
_async_wrapper=current_app.ensure_sync,
user=user,
token=token,
confirmation_token=token,
)
def generate_confirmation_token(user):
"""Generates a unique confirmation token for the specified user.
:param user: The user to work with
"""
data = [str(user.fs_uniquifier), hash_data(user.email)]
return _security.confirm_serializer.dumps(data)
def requires_confirmation(user):
"""Returns `True` if the user requires confirmation."""
return (
_security.confirmable
and not cv("LOGIN_WITHOUT_CONFIRMATION")
and user.confirmed_at is None
)
def confirm_email_token_status(token):
"""Returns the expired status, invalid status, and user of a confirmation
token. For example::
expired, invalid, user = confirm_email_token_status('...')
:param token: The confirmation token
"""
expired, invalid, user, token_data = get_token_status(
token, "confirm", "CONFIRM_EMAIL", return_data=True
)
if not invalid and user:
user_id, token_email_hash = token_data
invalid = not verify_hash(token_email_hash, user.email)
return expired, invalid, user
def confirm_user(user):
"""Confirms the specified user
:param user: The user to confirm
"""
if user.confirmed_at is not None:
return False
user.confirmed_at = _security.datetime_factory()
_datastore.put(user)
user_confirmed.send(
current_app._get_current_object(),
_async_wrapper=current_app.ensure_sync,
user=user,
)
return True