Skip to content

Commit 5327d44

Browse files
authored
Merge branch 'main' into dependabot/github_actions/github-actions-484570b1b1
2 parents 51dd2c6 + e880c74 commit 5327d44

23 files changed

Lines changed: 199 additions & 126 deletions

CHANGES.rst

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,11 @@ Features & Improvements
1313
- (:issue:`1206`) Add support for refresh tokens. See :ref:`token_topic`
1414
- (:pr:`1233`) Change :py:data:`SECURITY_TOKEN_MAX_AGE` from an int to a timedelta.
1515
Also - change default from ``never expire`` to 15 minutes.
16-
- (:pr:`1235`) Change default LOGOUT_METHODS to be just ``"POST"``
16+
- (:pr:`1235`) Change default :py:data:`SECURITY_LOGOUT_METHODS` to be just ``"POST"``
1717
- (:issue:`1228`) Change default ``csrf`` and ``tf_validity`` cookie config to ``secure=True``
1818
- (:issue:`1228`) The ``tf_validity`` cookie name is now configurable via :py:data:`SECURITY_TWO_FACTOR_VALIDITY_COOKIE_NAME`
1919
- (:issue:`1237`) Add support for CSRF on logout
20+
- (:pr:`xx`) Convert all _WITHIN configuration variable to use timedelta.
2021

2122
Fixes
2223
+++++
@@ -27,7 +28,7 @@ Fixes
2728
Docs and Chores
2829
+++++++++++++++
2930
- (:issue:`1208`) Remove support for Pony ORM
30-
- (:pr:`xxx`) Remove deprecated get_token_status() and converted over to check_and_get_token_status()
31+
- (:pr:`1240`) Remove deprecated get_token_status() and converted over to check_and_get_token_status()
3132

3233
Backwards Compatibility Concerns
3334
+++++++++++++++++++++++++++++++++
@@ -43,6 +44,9 @@ Backwards Compatibility Concerns
4344
has been change to ``secure=True``.
4445
- The default configuration for :py:data:`SECURITY_CSRF_COOKIE` has been
4546
changed to ``secure=True``
47+
- All _WITHIN configuration variables now take a timedelta instead of the
48+
home-grown <#> <period>. The old form is still accepted, with a deprecation
49+
warning, and converted at flask-security app init time into a timedelta.
4650

4751
Notes
4852
+++++

docs/configuration.rst

Lines changed: 47 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -844,6 +844,9 @@ Login/Logout
844844

845845
Default: ``["POST"]``.
846846

847+
.. versionchanged:: 5.9.0
848+
Default changed to just allowing ``"POST"``.
849+
847850

848851
.. py:data:: SECURITY_POST_LOGIN_VIEW
849852
@@ -1055,10 +1058,12 @@ Confirmable
10551058
Default: ``False``.
10561059
.. py:data:: SECURITY_CONFIRM_EMAIL_WITHIN
10571060
1058-
Specifies the amount of time a user has before their confirmation
1059-
link expires. Always pluralize the time unit for this value.
1061+
Specifies how long until the confirmation link expires.
1062+
1063+
Default: ``timedelta(days=2)``.
10601064

1061-
Default: ``"5 days"``.
1065+
.. versionchanged:: 5.9.0
1066+
Accepted value changed to a timedelta
10621067
.. py:data:: SECURITY_CONFIRM_URL
10631068
10641069
Specifies the email confirmation URL.
@@ -1221,10 +1226,12 @@ Recoverable
12211226

12221227
.. py:data:: SECURITY_RESET_PASSWORD_WITHIN
12231228
1224-
Specifies the amount of time a user has before their password reset link expires.
1225-
Always pluralize the time unit for this value.
1229+
Specifies how long until the reset link expires.
1230+
1231+
Default: ``timedelta(days=1)``.
12261232

1227-
Default: ``"1 days"``.
1233+
.. versionchanged:: 5.9.0
1234+
Accepted value changed to a timedelta
12281235

12291236
.. py:data:: SECURITY_SEND_PASSWORD_RESET_EMAIL
12301237
@@ -1273,10 +1280,12 @@ Change-Email
12731280
Default: ``"security/change_email.html"``.
12741281
.. py:data:: SECURITY_CHANGE_EMAIL_WITHIN
12751282
1276-
Specifies the amount of time a user has before their change email
1277-
token expires. Always pluralize the time unit for this value.
1283+
Specifies how long until the change email token expires.
1284+
1285+
Default: ``timedelta(hours=2)``.
12781286

1279-
Default: ``"2 hours"``
1287+
.. versionchanged:: 5.9.0
1288+
Accepted value changed to a timedelta
12801289
.. py:data:: SECURITY_POST_CHANGE_EMAIL_VIEW
12811290
12821291
Specifies the view to redirect to after a user successfully confirms their new email address.
@@ -1357,10 +1366,12 @@ Configuration related to the two-factor authentication feature.
13571366
Default: ``120``.
13581367
.. py:data:: SECURITY_TWO_FACTOR_SETUP_WITHIN
13591368
1360-
Specifies the amount of time a user has before their two-factor setup
1361-
token expires. Always pluralize the time unit for this value.
1369+
Specifies how long until the setup token expires.
13621370

1363-
Default: ``"30 minutes"``
1371+
Default: ``timedelta(minutes=30)``.
1372+
1373+
.. versionchanged:: 5.9.0
1374+
Accepted value changed to a timedelta
13641375

13651376
.. versionadded:: 5.5.0
13661377
.. py:data:: SECURITY_TWO_FACTOR_RESCUE_MAIL
@@ -1458,7 +1469,10 @@ Configuration related to the two-factor authentication feature.
14581469
14591470
Specifies the expiration of the two-factor validity cookie and verification of the token.
14601471

1461-
Default: ``"30 Days"``.
1472+
Default: ``timedelta(days=30)``.
1473+
1474+
.. versionchanged:: 5.9.0
1475+
Accepted value changed to a timedelta
14621476

14631477

14641478
.. py:data:: SECURITY_TWO_FACTOR_VALIDITY_COOKIE_NAME
@@ -1612,10 +1626,12 @@ Unified Signin
16121626

16131627
.. py:data:: SECURITY_US_SETUP_WITHIN
16141628
1615-
Specifies the amount of time a user has before their setup
1616-
token expires. Always pluralize the time unit for this value.
1629+
Specifies how long until the setup token expires.
16171630

1618-
Default: ``"30 minutes"``
1631+
Default: ``timedelta(minutes=30)``.
1632+
1633+
.. versionchanged:: 5.9.0
1634+
Accepted value changed to a timedelta
16191635

16201636
.. py:data:: SECURITY_US_SIGNIN_REPLACES_LOGIN
16211637
@@ -1755,10 +1771,12 @@ This feature is DEPRECATED as of 5.0.0. Please use unified signin feature instea
17551771

17561772
.. py:data:: SECURITY_LOGIN_WITHIN
17571773
1758-
Specifies the amount of time a user has before a login link expires.
1759-
Always pluralize the time unit for this value.
1774+
Specifies how long until the login link expires.
1775+
1776+
Default: ``timedelta(days=1)``.
17601777

1761-
Default: ``"1 days"``.
1778+
.. versionchanged:: 5.9.0
1779+
Accepted value changed to a timedelta
17621780

17631781
.. py:data:: SECURITY_LOGIN_ERROR_VIEW
17641782
@@ -1849,10 +1867,12 @@ WebAuthn
18491867

18501868
.. py:data:: SECURITY_WAN_REGISTER_WITHIN
18511869
1852-
Specifies the amount of time a user has before their register
1853-
token expires. Always pluralize the time unit for this value.
1870+
Specifies how long until the passkey registration token expires.
1871+
1872+
Default: ``timedelta(minutes=30)``.
18541873

1855-
Default: ``"30 minutes"``
1874+
.. versionchanged:: 5.9.0
1875+
Accepted value changed to a timedelta
18561876

18571877
.. py:data:: SECURITY_WAN_REGISTER_TIMEOUT
18581878
@@ -1863,10 +1883,12 @@ WebAuthn
18631883

18641884
.. py:data:: SECURITY_WAN_SIGNIN_WITHIN
18651885
1866-
Specifies the amount of time a user has before their signin
1867-
token expires. Always pluralize the time unit for this value.
1886+
Specifies how long until the passkey signin token expires.
18681887

1869-
Default: ``"1 minutes"``
1888+
Default: ``timedelta(minutes=1)``.
1889+
1890+
.. versionchanged:: 5.9.0
1891+
Accepted value changed to a timedelta
18701892

18711893
.. py:data:: SECURITY_WAN_SIGNIN_TIMEOUT
18721894

flask_security/change_email.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,12 @@
4141
do_flash,
4242
get_message,
4343
get_url,
44-
get_within_delta,
4544
hash_data,
4645
send_mail,
4746
url_for_security,
4847
verify_hash,
4948
view_commit,
49+
td_format,
5050
)
5151

5252
if t.TYPE_CHECKING: # pragma: no cover
@@ -129,7 +129,7 @@ def change_email_confirm(token):
129129
if expired:
130130
m, c = get_message(
131131
"CHANGE_EMAIL_EXPIRED",
132-
within=cv("CHANGE_EMAIL_WITHIN"),
132+
within=td_format(cv("CHANGE_EMAIL_WITHIN")),
133133
)
134134
else:
135135
m, c = get_message("API_ERROR")
@@ -187,6 +187,7 @@ def _send_instructions(user, new_email):
187187
user=user,
188188
link=link,
189189
token=token,
190+
within=td_format(cv("CHANGE_EMAIL_WITHIN")),
190191
)
191192

192193
change_email_instructions_sent.send(
@@ -204,7 +205,7 @@ def _verify_token_status(token):
204205
new_email is still available (and if not return 'invalid').
205206
"""
206207
expired, invalid, state = check_and_get_token_status(
207-
token, "change_email", get_within_delta("CHANGE_EMAIL_WITHIN")
208+
token, "change_email", cv("CHANGE_EMAIL_WITHIN")
208209
)
209210
if invalid or expired:
210211
return expired, invalid, None, None

flask_security/confirmable.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
send_mail,
2121
url_for_security,
2222
check_and_get_token_status,
23-
get_within_delta,
2423
verify_hash,
2524
)
2625

@@ -84,7 +83,7 @@ def confirm_email_token_status(token):
8483
:param token: The confirmation token
8584
"""
8685
expired, invalid, data = check_and_get_token_status(
87-
token, "confirm", get_within_delta("CONFIRM_EMAIL_WITHIN")
86+
token, "confirm", cv("CONFIRM_EMAIL_WITHIN")
8887
)
8988
if invalid or expired or not data:
9089
return expired, invalid, None

flask_security/core.py

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -241,10 +241,10 @@
241241
"SEND_PASSWORD_CHANGE_EMAIL": True,
242242
"SEND_PASSWORD_RESET_EMAIL": True,
243243
"SEND_PASSWORD_RESET_NOTICE_EMAIL": True,
244-
"LOGIN_WITHIN": "1 days",
244+
"LOGIN_WITHIN": timedelta(days=1),
245245
"CHANGE_EMAIL": False,
246246
"CHANGE_EMAIL_TEMPLATE": "security/change_email.html",
247-
"CHANGE_EMAIL_WITHIN": "2 hours",
247+
"CHANGE_EMAIL_WITHIN": timedelta(hours=2),
248248
"CHANGE_EMAIL_URL": "/change-email",
249249
"CHANGE_EMAIL_CONFIRM_URL": "/change-email-confirm",
250250
"CHANGE_EMAIL_ERROR_VIEW": None, # spa
@@ -260,7 +260,7 @@
260260
"TWO_FACTOR_MAIL_VALIDITY": 300,
261261
"TWO_FACTOR_SMS_VALIDITY": 120,
262262
"TWO_FACTOR_ALWAYS_VALIDATE": True,
263-
"TWO_FACTOR_LOGIN_VALIDITY": "30 days",
263+
"TWO_FACTOR_LOGIN_VALIDITY": timedelta(days=30),
264264
"TWO_FACTOR_VALIDITY_SALT": "tf-validity-salt",
265265
"TWO_FACTOR_VALIDITY_COOKIE_NAME": "tf_validity",
266266
"TWO_FACTOR_VALIDITY_COOKIE": {
@@ -269,7 +269,7 @@
269269
"samesite": "Strict",
270270
},
271271
"TWO_FACTOR_SETUP_SALT": "tf-setup-salt",
272-
"TWO_FACTOR_SETUP_WITHIN": "30 minutes",
272+
"TWO_FACTOR_SETUP_WITHIN": timedelta(minutes=30),
273273
"TWO_FACTOR_RESCUE_EMAIL": True,
274274
"MULTI_FACTOR_RECOVERY_CODES": False,
275275
"MULTI_FACTOR_RECOVERY_CODES_N": 5,
@@ -285,8 +285,8 @@
285285
"OAUTH_RESPONSE_URL": "/login/oauthresponse",
286286
"OAUTH_VERIFY_START_URL": "/login/oauth-verify-start",
287287
"OAUTH_VERIFY_RESPONSE_URL": "/login/oauth-verify-response",
288-
"CONFIRM_EMAIL_WITHIN": "5 days",
289-
"RESET_PASSWORD_WITHIN": "1 days",
288+
"CONFIRM_EMAIL_WITHIN": timedelta(days=2),
289+
"RESET_PASSWORD_WITHIN": timedelta(days=1),
290290
"LOGIN_WITHOUT_CONFIRMATION": False,
291291
"AUTO_LOGIN_AFTER_CONFIRM": False,
292292
"AUTO_LOGIN_AFTER_RESET": False,
@@ -372,7 +372,7 @@
372372
"US_MFA_REQUIRED": ["password", "email"],
373373
"US_TOKEN_VALIDITY": 120,
374374
"US_EMAIL_SUBJECT": _("Verification Code"),
375-
"US_SETUP_WITHIN": "30 minutes",
375+
"US_SETUP_WITHIN": timedelta(minutes=30),
376376
"US_SIGNIN_REPLACES_LOGIN": False,
377377
"CACHE_CONTROL": {"private": True, "no-store": True},
378378
"CSRF_PROTECT_MECHANISMS": AUTHN_MECHANISMS,
@@ -400,11 +400,11 @@
400400
"WAN_REGISTER_TIMEOUT": 60000, # milliseconds
401401
"WAN_REGISTER_TEMPLATE": "security/wan_register.html",
402402
"WAN_REGISTER_URL": "/wan-register",
403-
"WAN_REGISTER_WITHIN": "30 minutes",
403+
"WAN_REGISTER_WITHIN": timedelta(minutes=30),
404404
"WAN_SIGNIN_TIMEOUT": 60000, # milliseconds
405405
"WAN_SIGNIN_TEMPLATE": "security/wan_signin.html",
406406
"WAN_SIGNIN_URL": "/wan-signin",
407-
"WAN_SIGNIN_WITHIN": "1 minutes",
407+
"WAN_SIGNIN_WITHIN": timedelta(minutes=1),
408408
"WAN_DELETE_URL": "/wan-delete",
409409
"WAN_VERIFY_URL": "/wan-verify",
410410
"WAN_VERIFY_TEMPLATE": "security/wan_verify.html",
@@ -1769,6 +1769,29 @@ def init_app(
17691769
seconds=cv("TOKEN_MAX_AGE", app=app)
17701770
)
17711771

1772+
within_conversion = [
1773+
"LOGIN_WITHIN",
1774+
"CHANGE_EMAIL_WITHIN",
1775+
"CONFIRM_EMAIL_WITHIN",
1776+
"RESET_PASSWORD_WITHIN",
1777+
"TWO_FACTOR_SETUP_WITHIN",
1778+
"US_SETUP_WITHIN",
1779+
"WAN_REGISTER_WITHIN",
1780+
"WAN_SIGNIN_WITHIN",
1781+
"TWO_FACTOR_LOGIN_VALIDITY",
1782+
]
1783+
for key in within_conversion:
1784+
within_value = cv(key, app=app)
1785+
if not isinstance(within_value, timedelta):
1786+
values = within_value.split()
1787+
app.config[f"SECURITY_{key}"] = timedelta(**{values[1]: int(values[0])})
1788+
warnings.warn(
1789+
f"Non timedelta values for SECURITY_{key} are"
1790+
f"deprecated as of 5.9",
1791+
DeprecationWarning,
1792+
stacklevel=2,
1793+
)
1794+
17721795
self.login_manager = _get_login_manager(app, self)
17731796
self._phone_util = self._phone_util_cls(app)
17741797
self._mail_util = self._mail_util_cls(app)

flask_security/passwordless.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,10 @@
1414
from .proxies import _security, _datastore
1515
from .signals import login_instructions_sent
1616
from .utils import (
17-
config_value,
17+
config_value as cv,
1818
send_mail,
1919
url_for_security,
2020
check_and_get_token_status,
21-
get_within_delta,
2221
)
2322

2423

@@ -31,7 +30,7 @@ def send_login_instructions(user):
3130
login_link = url_for_security("token_login", token=token, _external=True)
3231

3332
send_mail(
34-
config_value("EMAIL_SUBJECT_PASSWORDLESS"),
33+
cv("EMAIL_SUBJECT_PASSWORDLESS"),
3534
user.email,
3635
"login_instructions",
3736
user=user,
@@ -64,7 +63,7 @@ def login_token_status(token):
6463
:param token: The login token
6564
"""
6665
expired, invalid, data = check_and_get_token_status(
67-
token, "login", get_within_delta("LOGIN_WITHIN")
66+
token, "login", cv("LOGIN_WITHIN")
6867
)
6968
if invalid or not data:
7069
return expired, invalid, None

0 commit comments

Comments
 (0)