Accepting request 1177931 from home:alarrosa:branches:devel:languages:python:flask
- Update to 5.4.3: + Fixes * Regression - some templates no longer getting correct config * CSRF not properly ignored for application forms using :py SECURITY_CSRF_PROTECT_MECHANISMS. * Improve jp translations * Regression - datetime_factory should still be an attribute * :py SECURITY_RETURN_GENERIC_RESPONSES hide email validation/syntax errors. - Update to 5.4.2: + Fixes * OpenAPI spec missing. * Doc fixes * Update ES/IT translations - Update to 5.4.0 & 5.4.1: + Features and improvements: * Work with Flask[async]. view decorators and signals support async handlers. * CI support for python 3.12 * Work with py_webauthn 2.0 (and only 2.0+) * Improve (and simplify) Two-Factor setup. See below for backwards compatability issues and new functionality. * Improve oauth debugging support. Handle next propagation in a more general way. * Make AnonymousUser (Flask-Login) optional and deprecated. * Remove undocumented and untested looking in session for possible 'next' redirect location. * No longer rely on Flask-Login.unauthorized callback. See below for implications. * Changes to default unauthorized handler - remove use of OBS-URL: https://build.opensuse.org/request/show/1177931 OBS-URL: https://build.opensuse.org/package/show/devel:languages:python:flask/python-Flask-Security-Too?expand=0&rev=45
This commit is contained in:
parent
e13f1e343f
commit
1fc62f52ba
@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:c1ed93aae536f2a3ff8abe1e13aec9d0d95fb7ff082fcc3b372df2a5213970d9
|
||||
size 616595
|
3
Flask-Security-Too-5.4.3.tar.gz
Normal file
3
Flask-Security-Too-5.4.3.tar.gz
Normal file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:62b19397e8d71a8d4cb8dc0d4409cc7a1497982549030396960aee518755e583
|
||||
size 652228
|
@ -1,3 +1,78 @@
|
||||
-------------------------------------------------------------------
|
||||
Fri May 31 12:12:17 UTC 2024 - Antonio Larrosa <alarrosa@suse.com>
|
||||
|
||||
- Update to 5.4.3:
|
||||
+ Fixes
|
||||
* Regression - some templates no longer getting correct config
|
||||
* CSRF not properly ignored for application forms using
|
||||
:py SECURITY_CSRF_PROTECT_MECHANISMS.
|
||||
* Improve jp translations
|
||||
* Regression - datetime_factory should still be an attribute
|
||||
* :py SECURITY_RETURN_GENERIC_RESPONSES hide email
|
||||
validation/syntax errors.
|
||||
|
||||
- Update to 5.4.2:
|
||||
+ Fixes
|
||||
* OpenAPI spec missing.
|
||||
* Doc fixes
|
||||
* Update ES/IT translations
|
||||
|
||||
- Update to 5.4.0 & 5.4.1:
|
||||
+ Features and improvements:
|
||||
* Work with Flask[async]. view decorators and signals support
|
||||
async handlers.
|
||||
* CI support for python 3.12
|
||||
* Work with py_webauthn 2.0 (and only 2.0+)
|
||||
* Improve (and simplify) Two-Factor setup. See below for
|
||||
backwards compatability issues and new functionality.
|
||||
* Improve oauth debugging support. Handle next propagation in a
|
||||
more general way.
|
||||
* Make AnonymousUser (Flask-Login) optional and deprecated.
|
||||
* Remove undocumented and untested looking in session for
|
||||
possible 'next' redirect location.
|
||||
* No longer rely on Flask-Login.unauthorized callback. See
|
||||
below for implications.
|
||||
* Changes to default unauthorized handler - remove use of
|
||||
referrer header (see below) and document precise behavior.
|
||||
* The authentication_token format has changed - adding
|
||||
per-token expiry time and future session ID. Old tokens are
|
||||
still accepted.
|
||||
+ Docs and Chores
|
||||
* Improve method translations for unified signin and two
|
||||
factor. Remove support for Flask-Babelex.
|
||||
* Chore - stop setting all config as attributes.
|
||||
init_app(**kwargs) can only set forms, flags, and utility
|
||||
classes (see below for compatibility concerns).
|
||||
* Update Spanish and Italian translations.
|
||||
* Improve translations for two-factor method selection.
|
||||
* Improve German translations.
|
||||
* Remove deprecation of AUTO_LOGIN_AFTER_CONFIRM - it has a
|
||||
reasonable use case.
|
||||
* Update message extraction - note that the
|
||||
CONFIRM_REGISTRATION message was changed to improve
|
||||
readability.
|
||||
+ Fixes
|
||||
* us-signin magic link should use fs_uniquifier (not email).
|
||||
* Improve open-redirect vulnerability mitigation. (see below)
|
||||
* user_datastore.create_user has side effects on mutable
|
||||
inputs. (NoRePercussions)
|
||||
* The long deprecated _unauthorized_callback/handler has been
|
||||
removed.
|
||||
* Oauth re-used POST_LOGIN_VIEW which caused confusion. See
|
||||
below for the new configuration and implications.
|
||||
* Improve CSRF documentation and testing. Fix bug where a CSRF
|
||||
failure could return an HTML page even if the request was
|
||||
JSON.
|
||||
* Register with JSON and authentication token failed CSRF.
|
||||
* Fix 2 issues with CSRF configuration.
|
||||
* It was possible that if SECURITY_EMAIL_VALIDATOR_ARGS were
|
||||
set that deliverability would be checked even for login.
|
||||
+ Backwards Compatibility Concerns
|
||||
Please read the full changelog at
|
||||
https://github.com/Flask-Middleware/flask-security/blob/master/CHANGES.rst#version-540--541
|
||||
- Drop patch that's already included by upstream:
|
||||
* support-python-312.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Mon Feb 12 04:11:51 UTC 2024 - Steve Kowalik <steven.kowalik@suse.com>
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
%{?sle15_python_module_pythons}
|
||||
Name: python-Flask-Security-Too
|
||||
Version: 5.3.3
|
||||
Version: 5.4.3
|
||||
Release: 0
|
||||
Summary: Security for Flask apps
|
||||
License: MIT
|
||||
@ -27,8 +27,6 @@ Source: https://files.pythonhosted.org/packages/source/F/Flask-Security-
|
||||
Patch0: no-mongodb.patch
|
||||
# PATCH-FIX-OPENSUSE Use pyqrcodeng, we do not ship qrcode in OpenSUSE.
|
||||
Patch1: use-pyqrcodeng.patch
|
||||
# PATCH-FIX-UPSTREAM Based on gh#Flask-Middleware/flask-security#900
|
||||
Patch2: support-python-312.patch
|
||||
BuildRequires: %{python_module Authlib}
|
||||
BuildRequires: %{python_module Babel >= 2.10.0}
|
||||
BuildRequires: %{python_module Flask >= 2.3.2}
|
||||
@ -37,7 +35,7 @@ BuildRequires: %{python_module Flask-Login >= 0.6.2}
|
||||
BuildRequires: %{python_module Flask-Mailman >= 0.3.0}
|
||||
BuildRequires: %{python_module Flask-Principal >= 0.4.0}
|
||||
BuildRequires: %{python_module Flask-SQLAlchemy >= 3.0.3}
|
||||
BuildRequires: %{python_module Flask-WTF >= 1.1.1}
|
||||
BuildRequires: %{python_module Flask-WTF >= 1.1.2}
|
||||
BuildRequires: %{python_module MarkupSafe >= 2.1.0}
|
||||
BuildRequires: %{python_module PyQRCode >= 1.2}
|
||||
BuildRequires: %{python_module SQLAlchemy}
|
||||
@ -49,8 +47,8 @@ BuildRequires: %{python_module bcrypt >= 4.0.1}
|
||||
BuildRequires: %{python_module bleach >= 6.0.0}
|
||||
BuildRequires: %{python_module cachetools >= 3.1.0}
|
||||
BuildRequires: %{python_module cryptography >= 40.0.2}
|
||||
BuildRequires: %{python_module dateutil}
|
||||
BuildRequires: %{python_module email-validator >= 2.0}
|
||||
BuildRequires: %{python_module freezegun}
|
||||
BuildRequires: %{python_module importlib_resources >= 5.10.0}
|
||||
BuildRequires: %{python_module itsdangerous >= 1.1.0}
|
||||
BuildRequires: %{python_module passlib >= 1.7.4}
|
||||
@ -61,6 +59,7 @@ BuildRequires: %{python_module pony if %python-base < 3.11}
|
||||
BuildRequires: %{python_module pytest >= 6.2.5}
|
||||
BuildRequires: %{python_module requests}
|
||||
BuildRequires: %{python_module setuptools}
|
||||
BuildRequires: %{python_module webauthn >= 2.0.0}
|
||||
BuildRequires: %{python_module wheel}
|
||||
BuildRequires: %{python_module zxcvbn >= 4.4.28}
|
||||
BuildRequires: fdupes
|
||||
@ -69,7 +68,7 @@ Requires: python-Flask >= 2.3.2
|
||||
Requires: python-Flask-Babel >= 3.1.0
|
||||
Requires: python-Flask-Login >= 0.6.2
|
||||
Requires: python-Flask-Principal >= 0.4.0
|
||||
Requires: python-Flask-WTF >= 1.1.1
|
||||
Requires: python-Flask-WTF >= 1.1.2
|
||||
Requires: python-MarkupSafe >= 2.1.0
|
||||
Requires: python-WTForms >= 3.0.0
|
||||
Requires: python-Werkzeug >= 2.3.3
|
||||
@ -80,6 +79,7 @@ Requires: python-email-validator >= 2.0
|
||||
Requires: python-importlib_resources >= 5.10.0
|
||||
Requires: python-itsdangerous >= 1.1.0
|
||||
Requires: python-passlib >= 1.7.4
|
||||
Requires: python-webauthn >= 2.0.0
|
||||
Recommends: python-PyQRCode >= 1.2
|
||||
Recommends: python-SQLAlchemy
|
||||
Recommends: python-zxcvbn >= 4.4.28
|
||||
|
@ -1,792 +0,0 @@
|
||||
From f7733559de7c8cd8a5bd683b2c53b523b6fb639b Mon Sep 17 00:00:00 2001
|
||||
From: Chris Wagner <jwag.wagner@gmail.com>
|
||||
Date: Sun, 7 Jan 2024 15:38:43 -0800
|
||||
Subject: [PATCH] Updates for python 3.12
|
||||
|
||||
- add CI support
|
||||
- utcnow is deprecated - create our own so DB is still naive UTC timestamps
|
||||
- remove use of dateutil (it was just used for tests)
|
||||
- many places didn't use DATETIME_FACTORY - now they do
|
||||
- update translations
|
||||
- many copyright dates
|
||||
- remove JSON compatibility code for Flask pre 2.x
|
||||
---
|
||||
.github/workflows/tests.yml | 12 +-
|
||||
.pre-commit-config.yaml | 2 +-
|
||||
CHANGES.rst | 1 +
|
||||
LICENSE | 2 +-
|
||||
README.rst | 2 +-
|
||||
docs/conf.py | 4 +-
|
||||
docs/configuration.rst | 5 +-
|
||||
examples/unified_signin/server/api.py | 6 +-
|
||||
flask_security/__init__.py | 7 +-
|
||||
flask_security/core.py | 6 +-
|
||||
flask_security/datastore.py | 30 +-
|
||||
flask_security/json.py | 40 +--
|
||||
flask_security/models/fsqla.py | 9 +-
|
||||
flask_security/password_util.py | 2 +-
|
||||
.../af_ZA/LC_MESSAGES/flask_security.po | 284 +++++++++--------
|
||||
.../ca_ES/LC_MESSAGES/flask_security.po | 275 ++++++++--------
|
||||
.../da_DK/LC_MESSAGES/flask_security.po | 275 ++++++++--------
|
||||
.../de_DE/LC_MESSAGES/flask_security.po | 294 +++++++++---------
|
||||
.../es_ES/LC_MESSAGES/flask_security.po | 292 ++++++++---------
|
||||
.../eu_ES/LC_MESSAGES/flask_security.po | 281 +++++++++--------
|
||||
.../translations/flask_security.pot | 267 ++++++++--------
|
||||
.../fr_FR/LC_MESSAGES/flask_security.po | 282 +++++++++--------
|
||||
.../hu_HU/LC_MESSAGES/flask_security.po | 285 +++++++++--------
|
||||
.../hy_AM/LC_MESSAGES/flask_security.po | 289 ++++++++---------
|
||||
.../is_IS/LC_MESSAGES/flask_security.po | 275 ++++++++--------
|
||||
.../it_IT/LC_MESSAGES/flask_security.po | 285 +++++++++--------
|
||||
.../ja_JP/LC_MESSAGES/flask_security.po | 275 ++++++++--------
|
||||
.../nl_NL/LC_MESSAGES/flask_security.po | 287 +++++++++--------
|
||||
.../pl_PL/LC_MESSAGES/flask_security.po | 287 +++++++++--------
|
||||
.../pt_BR/LC_MESSAGES/flask_security.po | 275 ++++++++--------
|
||||
.../pt_PT/LC_MESSAGES/flask_security.po | 275 ++++++++--------
|
||||
.../ru_RU/LC_MESSAGES/flask_security.po | 287 +++++++++--------
|
||||
.../tr_TR/LC_MESSAGES/flask_security.po | 275 ++++++++--------
|
||||
.../zh_Hans_CN/LC_MESSAGES/flask_security.po | 277 +++++++++--------
|
||||
flask_security/utils.py | 35 ++-
|
||||
flask_security/webauthn.py | 7 +-
|
||||
pyproject.toml | 4 +-
|
||||
pytest.ini | 2 +
|
||||
requirements/tests.txt | 5 +-
|
||||
tests/conftest.py | 7 +-
|
||||
tests/test_datastore.py | 16 +-
|
||||
tests/test_webauthn.py | 7 +-
|
||||
tests/view_scaffold.py | 17 +-
|
||||
tox.ini | 6 +-
|
||||
44 files changed, 3028 insertions(+), 2828 deletions(-)
|
||||
|
||||
Index: Flask-Security-Too-5.3.3/LICENSE
|
||||
===================================================================
|
||||
--- Flask-Security-Too-5.3.3.orig/LICENSE
|
||||
+++ Flask-Security-Too-5.3.3/LICENSE
|
||||
@@ -1,7 +1,7 @@
|
||||
MIT License
|
||||
|
||||
Copyright (C) 2012-2021 by Matthew Wright
|
||||
-Copyright (C) 2019-2021 by Chris Wagner
|
||||
+Copyright (C) 2019-2024 by Chris Wagner
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
Index: Flask-Security-Too-5.3.3/docs/configuration.rst
|
||||
===================================================================
|
||||
--- Flask-Security-Too-5.3.3.orig/docs/configuration.rst
|
||||
+++ Flask-Security-Too-5.3.3/docs/configuration.rst
|
||||
@@ -578,9 +578,10 @@ Core - rarely need changing
|
||||
|
||||
.. py:data:: SECURITY_DATETIME_FACTORY
|
||||
|
||||
- Specifies the default datetime factory.
|
||||
+ Specifies the default datetime factory. The default is naive-UTC which
|
||||
+ corresponds to many DB's DateTime type.
|
||||
|
||||
- Default:``datetime.datetime.utcnow``.
|
||||
+ Default:``flask_security.naive_utcnow``.
|
||||
|
||||
.. py:data:: SECURITY_CONFIRM_SALT
|
||||
|
||||
Index: Flask-Security-Too-5.3.3/examples/unified_signin/server/api.py
|
||||
===================================================================
|
||||
--- Flask-Security-Too-5.3.3.orig/examples/unified_signin/server/api.py
|
||||
+++ Flask-Security-Too-5.3.3/examples/unified_signin/server/api.py
|
||||
@@ -1,10 +1,10 @@
|
||||
"""
|
||||
-Copyright 2020 by J. Christopher Wagner (jwag). All rights reserved.
|
||||
+Copyright 2020-2024 by J. Christopher Wagner (jwag). All rights reserved.
|
||||
:license: MIT, see LICENSE for more details.
|
||||
|
||||
"""
|
||||
|
||||
-from datetime import datetime
|
||||
+from datetime import datetime, timezone
|
||||
|
||||
from flask import Blueprint, abort, current_app, jsonify
|
||||
from flask_security import auth_required
|
||||
@@ -17,7 +17,7 @@ api = Blueprint("api", __name__)
|
||||
@api.route("/health", methods=["GET"])
|
||||
@auth_required("session")
|
||||
def health():
|
||||
- return jsonify(secret="lush oranges", date=datetime.utcnow())
|
||||
+ return jsonify(secret="lush oranges", date=datetime.now(timezone.utc))
|
||||
|
||||
|
||||
@api.route("/popmail", methods=["GET"])
|
||||
Index: Flask-Security-Too-5.3.3/flask_security/__init__.py
|
||||
===================================================================
|
||||
--- Flask-Security-Too-5.3.3.orig/flask_security/__init__.py
|
||||
+++ Flask-Security-Too-5.3.3/flask_security/__init__.py
|
||||
@@ -2,11 +2,11 @@
|
||||
flask_security
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
- Flask-Security is a Flask extension that aims to add quick and simple
|
||||
- security via Flask-Login, Flask-Principal, Flask-WTF, and passlib.
|
||||
+ Flask-Security is a Flask extension that aims to add comprehensive security
|
||||
+ to Flask applications.
|
||||
|
||||
:copyright: (c) 2012-2019 by Matt Wright.
|
||||
- :copyright: (c) 2019-2023 by J. Christopher Wagner.
|
||||
+ :copyright: (c) 2019-2024 by J. Christopher Wagner.
|
||||
:license: MIT, see LICENSE for more details.
|
||||
"""
|
||||
|
||||
@@ -111,6 +111,7 @@ from .utils import (
|
||||
login_user,
|
||||
logout_user,
|
||||
lookup_identity,
|
||||
+ naive_utcnow,
|
||||
password_breached_validator,
|
||||
password_complexity_validator,
|
||||
password_length_validator,
|
||||
Index: Flask-Security-Too-5.3.3/flask_security/core.py
|
||||
===================================================================
|
||||
--- Flask-Security-Too-5.3.3.orig/flask_security/core.py
|
||||
+++ Flask-Security-Too-5.3.3/flask_security/core.py
|
||||
@@ -7,7 +7,7 @@
|
||||
:copyright: (c) 2012 by Matt Wright.
|
||||
:copyright: (c) 2017 by CERN.
|
||||
:copyright: (c) 2017 by ETH Zurich, Swiss Data Science Center.
|
||||
- :copyright: (c) 2019-2023 by J. Christopher Wagner (jwag).
|
||||
+ :copyright: (c) 2019-2024 by J. Christopher Wagner (jwag).
|
||||
:license: MIT, see LICENSE for more details.
|
||||
"""
|
||||
|
||||
@@ -95,6 +95,7 @@ from .utils import (
|
||||
get_identity_attributes,
|
||||
get_message,
|
||||
get_request_attr,
|
||||
+ naive_utcnow,
|
||||
localize_callback,
|
||||
set_request_attr,
|
||||
uia_email_mapper,
|
||||
@@ -283,7 +284,7 @@ _default_config: t.Dict[str, t.Any] = {
|
||||
"API_ENABLED_METHODS": ["session", "token"],
|
||||
"HASHING_SCHEMES": ["sha256_crypt", "hex_md5"],
|
||||
"DEPRECATED_HASHING_SCHEMES": ["hex_md5"],
|
||||
- "DATETIME_FACTORY": datetime.utcnow,
|
||||
+ "DATETIME_FACTORY": naive_utcnow,
|
||||
"TOTP_SECRETS": None,
|
||||
"TOTP_ISSUER": None,
|
||||
"SMS_SERVICE": "Dummy",
|
||||
@@ -1255,6 +1256,7 @@ class Security:
|
||||
self.register_blueprint: bool
|
||||
self.two_factor_plugins: TfPlugin
|
||||
self.oauthglue: t.Optional[OAuthGlue] = None
|
||||
+ self.datetime_factory: t.Callable[[], datetime]
|
||||
|
||||
self.login_manager: "flask_login.LoginManager"
|
||||
self._mail_util: MailUtil
|
||||
Index: Flask-Security-Too-5.3.3/flask_security/datastore.py
|
||||
===================================================================
|
||||
--- Flask-Security-Too-5.3.3.orig/flask_security/datastore.py
|
||||
+++ Flask-Security-Too-5.3.3/flask_security/datastore.py
|
||||
@@ -5,10 +5,10 @@
|
||||
This module contains an user datastore classes.
|
||||
|
||||
:copyright: (c) 2012 by Matt Wright.
|
||||
- :copyright: (c) 2019-2023 by J. Christopher Wagner (jwag).
|
||||
+ :copyright: (c) 2019-2024 by J. Christopher Wagner (jwag).
|
||||
:license: MIT, see LICENSE for more details.
|
||||
"""
|
||||
-import datetime
|
||||
+from datetime import datetime
|
||||
import json
|
||||
import typing as t
|
||||
import uuid
|
||||
@@ -817,6 +817,8 @@ class SQLAlchemyUserDatastore(SQLAlchemy
|
||||
extensions: t.Optional[str] = None,
|
||||
**kwargs: t.Any,
|
||||
) -> None:
|
||||
+ from .proxies import _security
|
||||
+
|
||||
if not hasattr(self, "webauthn_model") or not self.webauthn_model:
|
||||
raise NotImplementedError
|
||||
|
||||
@@ -830,7 +832,7 @@ class SQLAlchemyUserDatastore(SQLAlchemy
|
||||
backup_state=backup_state,
|
||||
transports=transports,
|
||||
extensions=extensions,
|
||||
- lastuse_datetime=datetime.datetime.utcnow(),
|
||||
+ lastuse_datetime=_security.datetime_factory(),
|
||||
**kwargs,
|
||||
)
|
||||
user.webauthn.append(webauthn)
|
||||
@@ -944,6 +946,8 @@ class MongoEngineUserDatastore(MongoEngi
|
||||
extensions: t.Optional[str] = None,
|
||||
**kwargs: t.Any,
|
||||
) -> None:
|
||||
+ from .proxies import _security
|
||||
+
|
||||
if not hasattr(self, "webauthn_model") or not self.webauthn_model:
|
||||
raise NotImplementedError
|
||||
webauthn = self.webauthn_model(
|
||||
@@ -957,7 +961,7 @@ class MongoEngineUserDatastore(MongoEngi
|
||||
backup_state=backup_state,
|
||||
transports=transports,
|
||||
extensions=extensions,
|
||||
- lastuse_datetime=datetime.datetime.utcnow(),
|
||||
+ lastuse_datetime=_security.datetime_factory(),
|
||||
**kwargs,
|
||||
)
|
||||
user.webauthn.append(webauthn)
|
||||
@@ -1079,6 +1083,8 @@ class PeeweeUserDatastore(PeeweeDatastor
|
||||
extensions: t.Optional[str] = None,
|
||||
**kwargs: t.Any,
|
||||
) -> None:
|
||||
+ from .proxies import _security
|
||||
+
|
||||
if not hasattr(self, "webauthn_model") or not self.webauthn_model:
|
||||
raise NotImplementedError
|
||||
webauthn = self.webauthn_model(
|
||||
@@ -1092,7 +1098,7 @@ class PeeweeUserDatastore(PeeweeDatastor
|
||||
backup_state=backup_state,
|
||||
transports=transports,
|
||||
extensions=extensions,
|
||||
- lastuse_datetime=datetime.datetime.utcnow(),
|
||||
+ lastuse_datetime=_security.datetime_factory(),
|
||||
**kwargs,
|
||||
)
|
||||
self.put(webauthn) # type: ignore
|
||||
@@ -1164,9 +1170,9 @@ if t.TYPE_CHECKING: # pragma: no cover
|
||||
fs_uniquifier: str
|
||||
fs_token_uniquifier: str
|
||||
fs_webauthn_user_handle: str
|
||||
- confirmed_at: t.Optional[datetime.datetime]
|
||||
- last_login_at: datetime.datetime
|
||||
- current_login_at: datetime.datetime
|
||||
+ confirmed_at: t.Optional[datetime]
|
||||
+ last_login_at: datetime
|
||||
+ current_login_at: datetime
|
||||
last_login_ip: t.Optional[str]
|
||||
current_login_ip: t.Optional[str]
|
||||
login_count: int
|
||||
@@ -1176,8 +1182,8 @@ if t.TYPE_CHECKING: # pragma: no cover
|
||||
mf_recovery_codes: t.Optional[t.List[str]]
|
||||
us_phone_number: t.Optional[str]
|
||||
us_totp_secrets: t.Optional[t.Union[str, bytes]]
|
||||
- create_datetime: datetime.datetime
|
||||
- update_datetime: datetime.datetime
|
||||
+ create_datetime: datetime
|
||||
+ update_datetime: datetime
|
||||
roles: t.List["Role"]
|
||||
webauthn: t.List["WebAuthn"]
|
||||
|
||||
@@ -1189,7 +1195,7 @@ if t.TYPE_CHECKING: # pragma: no cover
|
||||
name: str
|
||||
description: t.Optional[str]
|
||||
permissions: t.Optional[t.List[str]]
|
||||
- update_datetime: datetime.datetime
|
||||
+ update_datetime: datetime
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
...
|
||||
@@ -1204,7 +1210,7 @@ if t.TYPE_CHECKING: # pragma: no cover
|
||||
backup_state: bool
|
||||
device_type: str
|
||||
extensions: t.Optional[str]
|
||||
- lastuse_datetime: datetime.datetime
|
||||
+ lastuse_datetime: datetime
|
||||
user_id: int
|
||||
usage: str
|
||||
|
||||
Index: Flask-Security-Too-5.3.3/flask_security/json.py
|
||||
===================================================================
|
||||
--- Flask-Security-Too-5.3.3.orig/flask_security/json.py
|
||||
+++ Flask-Security-Too-5.3.3/flask_security/json.py
|
||||
@@ -1,32 +1,13 @@
|
||||
"""
|
||||
Flask-Security JSON extensions.
|
||||
|
||||
- :copyright: (c) 2022-2023 by J. Christopher Wagner (jwag).
|
||||
+ :copyright: (c) 2022-2024 by J. Christopher Wagner (jwag).
|
||||
:license: MIT, see LICENSE for more details.
|
||||
|
||||
Pieces of this code liberally copied from flask-mongoengine.
|
||||
"""
|
||||
|
||||
|
||||
-def _use_encoder(superclass): # pragma: no cover
|
||||
- """Flask < 2.2"""
|
||||
-
|
||||
- class FsJsonEncoder(superclass):
|
||||
- """Flask-Security JSON encoder.
|
||||
- Extends Flask's JSONencoder to handle lazy-text.
|
||||
- """
|
||||
-
|
||||
- def default(self, obj):
|
||||
- from .babel import is_lazy_string
|
||||
-
|
||||
- if is_lazy_string(obj):
|
||||
- return str(obj)
|
||||
- else:
|
||||
- return super().default(obj)
|
||||
-
|
||||
- return FsJsonEncoder
|
||||
-
|
||||
-
|
||||
def _use_provider(superclass):
|
||||
"""Flask 2.2 onwards - customize JSONProvider"""
|
||||
|
||||
@@ -44,19 +25,6 @@ def _use_provider(superclass):
|
||||
|
||||
def setup_json(app, bp=None):
|
||||
# Called at init_app time.
|
||||
- if hasattr(app, "json_provider_class"):
|
||||
- # Flask >= 2.2
|
||||
- app.json_provider_class = _use_provider(app.json_provider_class)
|
||||
- app.json = app.json_provider_class(app)
|
||||
- # a bit if a hack - if a package (e.g. flask-mongoengine) hasn't
|
||||
- # converted yet - they might use json_encoder. This ONLY applies
|
||||
- # to this specific version of Flask that happens to use _json_encoder to
|
||||
- # signal if any app/extension has registered an old style encoder.
|
||||
- # (app.json_encoder is always set)
|
||||
- # (If they do, then Flask 2.2.x won't use json_provider at all)
|
||||
- # Of course if they do this AFTER we're initialized all bets are off.
|
||||
- if getattr(app, "_json_encoder", None):
|
||||
- app.json_encoder = _use_encoder(app.json_encoder)
|
||||
-
|
||||
- elif bp: # pragma: no cover
|
||||
- bp.json_encoder = _use_encoder(app.json_encoder)
|
||||
+ # Flask >= 2.2
|
||||
+ app.json_provider_class = _use_provider(app.json_provider_class)
|
||||
+ app.json = app.json_provider_class(app)
|
||||
Index: Flask-Security-Too-5.3.3/flask_security/models/fsqla.py
|
||||
===================================================================
|
||||
--- Flask-Security-Too-5.3.3.orig/flask_security/models/fsqla.py
|
||||
+++ Flask-Security-Too-5.3.3/flask_security/models/fsqla.py
|
||||
@@ -1,5 +1,5 @@
|
||||
"""
|
||||
-Copyright 2019-2021 by J. Christopher Wagner (jwag). All rights reserved.
|
||||
+Copyright 2019-2024 by J. Christopher Wagner (jwag). All rights reserved.
|
||||
:license: MIT, see LICENSE for more details.
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ BE AWARE: Once any version of this is sh
|
||||
a new version needs to be created.
|
||||
"""
|
||||
|
||||
-import datetime
|
||||
from typing import cast
|
||||
from sqlalchemy import (
|
||||
Boolean,
|
||||
@@ -25,7 +24,7 @@ from sqlalchemy.ext.declarative import d
|
||||
from sqlalchemy.ext.mutable import MutableList
|
||||
from sqlalchemy.sql import func
|
||||
|
||||
-from flask_security import AsaList, RoleMixin, UserMixin
|
||||
+from flask_security import AsaList, RoleMixin, UserMixin, naive_utcnow
|
||||
|
||||
|
||||
class FsModels:
|
||||
@@ -77,7 +76,7 @@ class FsRoleMixin(RoleMixin):
|
||||
type_=DateTime,
|
||||
nullable=False,
|
||||
server_default=func.now(),
|
||||
- onupdate=datetime.datetime.utcnow,
|
||||
+ onupdate=naive_utcnow,
|
||||
)
|
||||
|
||||
|
||||
@@ -126,5 +125,5 @@ class FsUserMixin(UserMixin):
|
||||
type_=DateTime,
|
||||
nullable=False,
|
||||
server_default=func.now(),
|
||||
- onupdate=datetime.datetime.utcnow,
|
||||
+ onupdate=naive_utcnow,
|
||||
)
|
||||
Index: Flask-Security-Too-5.3.3/flask_security/password_util.py
|
||||
===================================================================
|
||||
--- Flask-Security-Too-5.3.3.orig/flask_security/password_util.py
|
||||
+++ Flask-Security-Too-5.3.3/flask_security/password_util.py
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
Utility class providing methods for validating and normalizing passwords.
|
||||
|
||||
- :copyright: (c) 2020-2021 by J. Christopher Wagner (jwag).
|
||||
+ :copyright: (c) 2020-2024 by J. Christopher Wagner (jwag).
|
||||
:license: MIT, see LICENSE for more details.
|
||||
|
||||
"""
|
||||
Index: Flask-Security-Too-5.3.3/flask_security/utils.py
|
||||
===================================================================
|
||||
--- Flask-Security-Too-5.3.3.orig/flask_security/utils.py
|
||||
+++ Flask-Security-Too-5.3.3/flask_security/utils.py
|
||||
@@ -5,12 +5,12 @@
|
||||
Flask-Security utils module
|
||||
|
||||
:copyright: (c) 2012-2019 by Matt Wright.
|
||||
- :copyright: (c) 2019-2023 by J. Christopher Wagner (jwag).
|
||||
+ :copyright: (c) 2019-2024 by J. Christopher Wagner (jwag).
|
||||
:license: MIT, see LICENSE for more details.
|
||||
"""
|
||||
import abc
|
||||
import base64
|
||||
-import datetime
|
||||
+from datetime import datetime, timedelta, timezone
|
||||
from functools import partial
|
||||
import hashlib
|
||||
import hmac
|
||||
@@ -104,6 +104,25 @@ else:
|
||||
return response
|
||||
|
||||
|
||||
+# From a miguel grinberg blog around dealing with 3.12.
|
||||
+# Our default SQLAlchemy Datetime is naive.
|
||||
+# Note that most code should call _security.datetime_factory()
|
||||
+def aware_utcnow():
|
||||
+ return datetime.now(timezone.utc)
|
||||
+
|
||||
+
|
||||
+def aware_utcfromtimestamp(timestamp):
|
||||
+ return datetime.fromtimestamp(timestamp, timezone.utc)
|
||||
+
|
||||
+
|
||||
+def naive_utcnow():
|
||||
+ return aware_utcnow().replace(tzinfo=None)
|
||||
+
|
||||
+
|
||||
+def naive_utcfromtimestamp(timestamp):
|
||||
+ return aware_utcfromtimestamp(timestamp).replace(tzinfo=None)
|
||||
+
|
||||
+
|
||||
def find_csrf_field_name():
|
||||
"""
|
||||
We need to clear it on logout (since that isn't being done by Flask-WTF).
|
||||
@@ -207,8 +226,8 @@ def logout_user() -> None:
|
||||
|
||||
|
||||
def check_and_update_authn_fresh(
|
||||
- within: datetime.timedelta,
|
||||
- grace: datetime.timedelta,
|
||||
+ within: timedelta,
|
||||
+ grace: timedelta,
|
||||
method: t.Optional[str] = None,
|
||||
) -> bool:
|
||||
"""Check if user authenticated within specified time and update grace period.
|
||||
@@ -255,7 +274,7 @@ def check_and_update_authn_fresh(
|
||||
# No session, you can't play.
|
||||
return False
|
||||
|
||||
- now = datetime.datetime.utcnow()
|
||||
+ now = naive_utcnow()
|
||||
new_exp = now + grace
|
||||
grace_ts = int(new_exp.timestamp())
|
||||
|
||||
@@ -271,7 +290,7 @@ def check_and_update_authn_fresh(
|
||||
session["fs_gexp"] = grace_ts
|
||||
return False
|
||||
|
||||
- authn_time = datetime.datetime.utcfromtimestamp(session["fs_paa"])
|
||||
+ authn_time = naive_utcfromtimestamp(session["fs_paa"])
|
||||
# allow for some time drift where it's possible authn_time is in the future
|
||||
# but let's be cautious and not allow arbitrary future times
|
||||
delta = now - authn_time
|
||||
@@ -673,7 +692,7 @@ def get_within_delta(key, app=None):
|
||||
"""
|
||||
txt = config_value(key, app=app)
|
||||
values = txt.split()
|
||||
- return datetime.timedelta(**{values[1]: int(values[0])})
|
||||
+ return timedelta(**{values[1]: int(values[0])})
|
||||
|
||||
|
||||
def send_mail(subject, recipient, template, **context):
|
||||
@@ -758,7 +777,7 @@ def get_token_status(token, serializer,
|
||||
|
||||
|
||||
def check_and_get_token_status(
|
||||
- token: str, serializer_name: str, within: datetime.timedelta
|
||||
+ token: str, serializer_name: str, within: timedelta
|
||||
) -> t.Tuple[bool, bool, t.Any]:
|
||||
"""Get the status of a token and return data.
|
||||
|
||||
Index: Flask-Security-Too-5.3.3/flask_security/webauthn.py
|
||||
===================================================================
|
||||
--- Flask-Security-Too-5.3.3.orig/flask_security/webauthn.py
|
||||
+++ Flask-Security-Too-5.3.3/flask_security/webauthn.py
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
Flask-Security WebAuthn module
|
||||
|
||||
- :copyright: (c) 2021-2023 by J. Christopher Wagner (jwag).
|
||||
+ :copyright: (c) 2021-2024 by J. Christopher Wagner (jwag).
|
||||
:license: MIT, see LICENSE for more details.
|
||||
|
||||
This implements support for webauthn/FIDO2 Level 2 using the py_webauthn package.
|
||||
@@ -36,7 +36,6 @@
|
||||
|
||||
"""
|
||||
|
||||
-import datetime
|
||||
import json
|
||||
import time
|
||||
import typing as t
|
||||
@@ -677,7 +676,7 @@ def webauthn_signin_response(token: str)
|
||||
after_this_request(view_commit)
|
||||
assert form.cred
|
||||
assert form.user
|
||||
- form.cred.lastuse_datetime = datetime.datetime.utcnow()
|
||||
+ form.cred.lastuse_datetime = _security.datetime_factory()
|
||||
form.cred.sign_count = form.authentication_verification.new_sign_count
|
||||
form.cred.backup_state = getattr(
|
||||
form.authentication_verification, "credential_backed_up", False
|
||||
@@ -833,7 +832,7 @@ def webauthn_verify_response(token: str)
|
||||
# update last use and sign count
|
||||
after_this_request(view_commit)
|
||||
assert form.cred
|
||||
- form.cred.lastuse_datetime = datetime.datetime.utcnow()
|
||||
+ form.cred.lastuse_datetime = _security.datetime_factory()
|
||||
form.cred.sign_count = form.authentication_verification.new_sign_count
|
||||
_datastore.put(form.cred)
|
||||
|
||||
Index: Flask-Security-Too-5.3.3/pyproject.toml
|
||||
===================================================================
|
||||
--- Flask-Security-Too-5.3.3.orig/pyproject.toml
|
||||
+++ Flask-Security-Too-5.3.3/pyproject.toml
|
||||
@@ -31,6 +31,7 @@ classifiers=[
|
||||
"Programming Language :: Python :: 3.9",
|
||||
"Programming Language :: Python :: 3.10",
|
||||
"Programming Language :: Python :: 3.11",
|
||||
+ "Programming Language :: Python :: 3.12",
|
||||
"Programming Language :: Python :: Implementation :: CPython",
|
||||
"Programming Language :: Python :: Implementation :: PyPy",
|
||||
"Development Status :: 5 - Production/Stable",
|
||||
@@ -70,7 +71,6 @@ low = [
|
||||
"babel==2.12.1",
|
||||
"bcrypt==4.0.1",
|
||||
"bleach==6.0.0",
|
||||
- "python-dateutil==2.8.2",
|
||||
"jinja2==3.1.2",
|
||||
"itsdangerous==2.1.2",
|
||||
"markupsafe==2.1.2",
|
||||
@@ -82,6 +82,8 @@ low = [
|
||||
"qrcode==7.4.2",
|
||||
# authlib requires requests
|
||||
"requests",
|
||||
+ # passlib required setuptools
|
||||
+ "setuptools",
|
||||
"sqlalchemy==2.0.12",
|
||||
"sqlalchemy-utils==0.41.1",
|
||||
"webauthn==1.11.0",
|
||||
Index: Flask-Security-Too-5.3.3/pytest.ini
|
||||
===================================================================
|
||||
--- Flask-Security-Too-5.3.3.orig/pytest.ini
|
||||
+++ Flask-Security-Too-5.3.3/pytest.ini
|
||||
@@ -20,6 +20,8 @@ filterwarnings =
|
||||
ignore::DeprecationWarning:mongoengine:
|
||||
ignore::DeprecationWarning:flask_login:0
|
||||
ignore::DeprecationWarning:pydantic_core:0
|
||||
+ # next for py 3.12
|
||||
+ ignore::DeprecationWarning:pkg_resources:0
|
||||
ignore::UserWarning:cbor2:0
|
||||
ignore:.*passwordless feature.*:DeprecationWarning:flask_security:0
|
||||
ignore::DeprecationWarning:passlib:0
|
||||
Index: Flask-Security-Too-5.3.3/requirements/tests.txt
|
||||
===================================================================
|
||||
--- Flask-Security-Too-5.3.3.orig/requirements/tests.txt
|
||||
+++ Flask-Security-Too-5.3.3/requirements/tests.txt
|
||||
@@ -3,7 +3,7 @@ Babel
|
||||
Flask-Login@git+https://github.com/maxcountryman/flask-login@main
|
||||
Flask-Mailman
|
||||
Flask-Principal
|
||||
-peewee
|
||||
+peewee; python_version < '3.12'
|
||||
Flask-SQLAlchemy
|
||||
argon2_cffi
|
||||
authlib
|
||||
@@ -13,7 +13,6 @@ check-manifest
|
||||
coverage
|
||||
cryptography
|
||||
djlint
|
||||
-python-dateutil
|
||||
mongoengine
|
||||
mongomock
|
||||
msgcheck
|
||||
@@ -27,6 +26,8 @@ pytest
|
||||
qrcode
|
||||
# authlib requires requests
|
||||
requests
|
||||
+# passlib requires setuptools which is deprecated
|
||||
+setuptools
|
||||
sqlalchemy
|
||||
sqlalchemy-utils
|
||||
webauthn
|
||||
Index: Flask-Security-Too-5.3.3/tests/conftest.py
|
||||
===================================================================
|
||||
--- Flask-Security-Too-5.3.3.orig/tests/conftest.py
|
||||
+++ Flask-Security-Too-5.3.3/tests/conftest.py
|
||||
@@ -5,7 +5,7 @@
|
||||
Test fixtures and what not
|
||||
|
||||
:copyright: (c) 2017 by CERN.
|
||||
- :copyright: (c) 2019-2022 by J. Christopher Wagner (jwag).
|
||||
+ :copyright: (c) 2019-2024 by J. Christopher Wagner (jwag).
|
||||
:license: MIT, see LICENSE for more details.
|
||||
"""
|
||||
|
||||
@@ -37,6 +37,7 @@ from flask_security import (
|
||||
auth_token_required,
|
||||
http_auth_required,
|
||||
get_request_attr,
|
||||
+ naive_utcnow,
|
||||
login_required,
|
||||
roles_accepted,
|
||||
roles_required,
|
||||
@@ -563,7 +564,7 @@ def sqlalchemy_session_setup(request, ap
|
||||
DateTime,
|
||||
nullable=False,
|
||||
server_default=func.now(),
|
||||
- onupdate=datetime.utcnow,
|
||||
+ onupdate=naive_utcnow,
|
||||
)
|
||||
|
||||
class User(Base, UserMixin):
|
||||
@@ -597,7 +598,7 @@ def sqlalchemy_session_setup(request, ap
|
||||
DateTime,
|
||||
nullable=False,
|
||||
server_default=func.now(),
|
||||
- onupdate=datetime.utcnow,
|
||||
+ onupdate=naive_utcnow,
|
||||
)
|
||||
|
||||
@declared_attr
|
||||
Index: Flask-Security-Too-5.3.3/tests/test_datastore.py
|
||||
===================================================================
|
||||
--- Flask-Security-Too-5.3.3.orig/tests/test_datastore.py
|
||||
+++ Flask-Security-Too-5.3.3/tests/test_datastore.py
|
||||
@@ -5,15 +5,21 @@
|
||||
Datastore tests
|
||||
|
||||
:copyright: (c) 2012 by Matt Wright.
|
||||
- :copyright: (c) 2019-2022 by J. Christopher Wagner (jwag).
|
||||
+ :copyright: (c) 2019-2024 by J. Christopher Wagner (jwag).
|
||||
:license: MIT, see LICENSE for more details.
|
||||
"""
|
||||
|
||||
-import datetime
|
||||
from pytest import raises, skip, importorskip
|
||||
from tests.test_utils import init_app_with_options, get_num_queries, is_sqlalchemy
|
||||
|
||||
-from flask_security import RoleMixin, Security, UserMixin, LoginForm, RegisterForm
|
||||
+from flask_security import (
|
||||
+ RoleMixin,
|
||||
+ Security,
|
||||
+ UserMixin,
|
||||
+ LoginForm,
|
||||
+ RegisterForm,
|
||||
+ naive_utcnow,
|
||||
+)
|
||||
from flask_security.datastore import Datastore, UserDatastore
|
||||
|
||||
|
||||
@@ -294,7 +300,7 @@ def test_modify_permissions(app, datasto
|
||||
assert perms == t1.get_permissions()
|
||||
if hasattr(t1, "update_datetime"):
|
||||
orig_update_time = t1.update_datetime
|
||||
- assert t1.update_datetime <= datetime.datetime.utcnow()
|
||||
+ assert t1.update_datetime <= naive_utcnow()
|
||||
|
||||
ds.add_permissions_to_role(t1, "execute")
|
||||
ds.commit()
|
||||
@@ -414,7 +420,7 @@ def test_uuid(app, request, tmpdir, real
|
||||
username = Column(String(255), unique=True, nullable=True)
|
||||
password = Column(String(255))
|
||||
active = Column(Boolean())
|
||||
- created_at = Column(DateTime, default=datetime.datetime.utcnow)
|
||||
+ created_at = Column(DateTime, default=naive_utcnow())
|
||||
confirmed_at = Column(DateTime())
|
||||
roles = relationship(
|
||||
"Role", secondary="roles_users", backref=backref("users", lazy="dynamic")
|
||||
Index: Flask-Security-Too-5.3.3/tests/test_webauthn.py
|
||||
===================================================================
|
||||
--- Flask-Security-Too-5.3.3.orig/tests/test_webauthn.py
|
||||
+++ Flask-Security-Too-5.3.3/tests/test_webauthn.py
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
WebAuthn tests
|
||||
|
||||
- :copyright: (c) 2021-2023 by J. Christopher Wagner (jwag).
|
||||
+ :copyright: (c) 2021-2024 by J. Christopher Wagner (jwag).
|
||||
:license: MIT, see LICENSE for more details.
|
||||
|
||||
"""
|
||||
@@ -12,7 +12,6 @@
|
||||
from base64 import urlsafe_b64encode
|
||||
import copy
|
||||
import datetime
|
||||
-from dateutil import parser
|
||||
import json
|
||||
import re
|
||||
import typing as t
|
||||
@@ -383,7 +382,7 @@ def test_basic_json(app, clients, get_me
|
||||
response = clients.get("/wan-register", headers=headers)
|
||||
active_creds = response.json["response"]["registered_credentials"]
|
||||
assert active_creds[0]["name"] == "testr1"
|
||||
- assert parser.parse(active_creds[0]["lastuse"]) == fake_dt
|
||||
+ assert datetime.datetime.fromisoformat(active_creds[0]["lastuse"]) == fake_dt
|
||||
|
||||
# sign in - simple case use identity so we get back allowCredentials
|
||||
logout(clients)
|
||||
@@ -409,7 +408,7 @@ def test_basic_json(app, clients, get_me
|
||||
# fetch credentials and verify lastuse was updated
|
||||
response = clients.get("/wan-register", headers=headers)
|
||||
active_creds = response.json["response"]["registered_credentials"]
|
||||
- assert parser.parse(active_creds[0]["lastuse"]) != fake_dt
|
||||
+ assert datetime.datetime.fromisoformat(active_creds[0]["lastuse"]) != fake_dt
|
||||
assert active_creds[0]["transports"] == ["usb"]
|
||||
assert active_creds[0]["usage"] == "first"
|
||||
|
||||
Index: Flask-Security-Too-5.3.3/tests/view_scaffold.py
|
||||
===================================================================
|
||||
--- Flask-Security-Too-5.3.3.orig/tests/view_scaffold.py
|
||||
+++ Flask-Security-Too-5.3.3/tests/view_scaffold.py
|
||||
@@ -1,4 +1,4 @@
|
||||
-# :copyright: (c) 2019-2023 by J. Christopher Wagner (jwag).
|
||||
+# :copyright: (c) 2019-2024 by J. Christopher Wagner (jwag).
|
||||
# :license: MIT, see LICENSE for more details.
|
||||
|
||||
"""
|
||||
@@ -21,7 +21,7 @@ data and a mail sender that flashes what
|
||||
|
||||
"""
|
||||
|
||||
-import datetime
|
||||
+from datetime import timedelta
|
||||
import os
|
||||
import typing as t
|
||||
|
||||
@@ -46,7 +46,12 @@ from flask_security.signals import (
|
||||
user_not_registered,
|
||||
user_registered,
|
||||
)
|
||||
-from flask_security.utils import hash_password, uia_email_mapper, uia_phone_mapper
|
||||
+from flask_security.utils import (
|
||||
+ hash_password,
|
||||
+ naive_utcnow,
|
||||
+ uia_email_mapper,
|
||||
+ uia_phone_mapper,
|
||||
+)
|
||||
|
||||
|
||||
def _find_bool(v):
|
||||
@@ -101,8 +106,8 @@ def create_app():
|
||||
app.config["SECURITY_TOTP_SECRETS"] = {
|
||||
"1": "TjQ9Qa31VOrfEzuPy4VHQWPCTmRzCnFzMKLxXYiZu9B"
|
||||
}
|
||||
- app.config["SECURITY_FRESHNESS"] = datetime.timedelta(minutes=1)
|
||||
- app.config["SECURITY_FRESHNESS_GRACE_PERIOD"] = datetime.timedelta(minutes=2)
|
||||
+ app.config["SECURITY_FRESHNESS"] = timedelta(minutes=1)
|
||||
+ app.config["SECURITY_FRESHNESS_GRACE_PERIOD"] = timedelta(minutes=2)
|
||||
app.config["SECURITY_USERNAME_ENABLE"] = True
|
||||
app.config["SECURITY_USERNAME_REQUIRED"] = True
|
||||
app.config["SECURITY_PASSWORD_REQUIRED"] = True
|
||||
@@ -286,7 +291,7 @@ def add_user(ds, email, password, roles)
|
||||
roles = [ds.find_or_create_role(rn) for rn in roles]
|
||||
ds.commit()
|
||||
user = ds.create_user(
|
||||
- email=email, password=pw, active=True, confirmed_at=datetime.datetime.utcnow()
|
||||
+ email=email, password=pw, active=True, confirmed_at=naive_utcnow()
|
||||
)
|
||||
ds.commit()
|
||||
for role in roles:
|
Loading…
x
Reference in New Issue
Block a user