python3-Flask-Login: patch for Flask and Werzeug 3
This commit is contained in:
parent
66462c6e00
commit
c784c6937d
|
@ -0,0 +1,46 @@
|
|||
From 7b170bf4e5e0240fe084166c9ca6ec4fba258dcd Mon Sep 17 00:00:00 2001
|
||||
From: Hiromasa Ihara <iharahiromasa@gmail.com>
|
||||
Date: Mon, 2 Oct 2023 20:14:40 +0900
|
||||
Subject: [PATCH] fix: avoid DeprecationWarning 'werkzeug.urls.url_decode' is
|
||||
deprecated (#746)
|
||||
|
||||
---
|
||||
src/flask_login/utils.py | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/flask_login/utils.py b/src/flask_login/utils.py
|
||||
index c3c46846..45a7e279 100644
|
||||
--- a/src/flask_login/utils.py
|
||||
+++ b/src/flask_login/utils.py
|
||||
@@ -3,6 +3,8 @@
|
||||
from hashlib import sha512
|
||||
from urllib.parse import urlparse
|
||||
from urllib.parse import urlunparse
|
||||
+from urllib.parse import parse_qs
|
||||
+from urllib.parse import urlencode
|
||||
|
||||
from flask import current_app
|
||||
from flask import g
|
||||
@@ -11,8 +13,6 @@
|
||||
from flask import session
|
||||
from flask import url_for
|
||||
from werkzeug.local import LocalProxy
|
||||
-from werkzeug.urls import url_decode
|
||||
-from werkzeug.urls import url_encode
|
||||
|
||||
from .config import COOKIE_NAME
|
||||
from .config import EXEMPT_METHODS
|
||||
@@ -123,11 +123,11 @@ def login_url(login_view, next_url=None, next_field="next"):
|
||||
return base
|
||||
|
||||
parsed_result = urlparse(base)
|
||||
- md = url_decode(parsed_result.query)
|
||||
+ md = parse_qs(parsed_result.query)
|
||||
md[next_field] = make_next_param(base, next_url)
|
||||
netloc = current_app.config.get("FORCE_HOST_FOR_REDIRECTS") or parsed_result.netloc
|
||||
parsed_result = parsed_result._replace(
|
||||
- netloc=netloc, query=url_encode(md, sort=True)
|
||||
+ netloc=netloc, query=urlencode(md, doseq=True)
|
||||
)
|
||||
return urlunparse(parsed_result)
|
||||
|
|
@ -0,0 +1,317 @@
|
|||
From 7d98a49bc38d0849367b348bfe37a2b689323419 Mon Sep 17 00:00:00 2001
|
||||
From: Sha <wangsha@users.noreply.github.com>
|
||||
Date: Mon, 2 Oct 2023 07:00:12 -0500
|
||||
Subject: [PATCH] flask 3.0 compatibility (#778)
|
||||
|
||||
* Werkzeug 3.0 compatible
|
||||
|
||||
* python3.7 compatibility
|
||||
|
||||
* troubleshooting version compatibility
|
||||
|
||||
* update constrain
|
||||
|
||||
* package version troubleshooting
|
||||
|
||||
* troubleshooting package version
|
||||
|
||||
* troubleshoot package version
|
||||
|
||||
* package tuning
|
||||
|
||||
* troubleshoot package version
|
||||
|
||||
* troubleshooting package version
|
||||
|
||||
* troubleshoot test cases
|
||||
|
||||
* troubleshoot python package version
|
||||
|
||||
* Update tox.ini
|
||||
|
||||
* version troubleshoot
|
||||
|
||||
* version fix
|
||||
|
||||
* package version
|
||||
|
||||
* package version
|
||||
|
||||
* Update setup.py
|
||||
|
||||
* Update setup.py
|
||||
|
||||
* package version
|
||||
|
||||
* package version
|
||||
|
||||
* package version
|
||||
|
||||
* Update setup.cfg
|
||||
|
||||
* version fix
|
||||
|
||||
* package version
|
||||
|
||||
* package version
|
||||
|
||||
* package version
|
||||
|
||||
* package version
|
||||
|
||||
* deprecate python3.7
|
||||
|
||||
* package version
|
||||
|
||||
* merge conflicts
|
||||
|
||||
* pylint fix
|
||||
---
|
||||
.github/workflows/tests.yaml | 4 +-
|
||||
requirements/ci-release.txt | 83 +++++++++------------
|
||||
requirements/ci-tests.in | 5 +-
|
||||
requirements/ci-tests.txt | 61 +++++++++-------
|
||||
requirements/dev.txt | 138 ++++++-----------------------------
|
||||
requirements/docs.txt | 50 +++++++------
|
||||
requirements/style.txt | 25 +++----
|
||||
requirements/tests-min.in | 8 +-
|
||||
requirements/tests-min.txt | 34 ++++-----
|
||||
requirements/tests.in | 6 +-
|
||||
requirements/tests.txt | 28 +++----
|
||||
setup.cfg | 2 +-
|
||||
setup.py | 5 +-
|
||||
src/flask_login/utils.py | 4 +-
|
||||
tests/test_login.py | 26 ++++---
|
||||
tox.ini | 2 +-
|
||||
16 files changed, 198 insertions(+), 283 deletions(-)
|
||||
|
||||
diff --git a/src/flask_login/utils.py b/src/flask_login/utils.py
|
||||
index 45a7e279..0fde23f4 100644
|
||||
--- a/src/flask_login/utils.py
|
||||
+++ b/src/flask_login/utils.py
|
||||
@@ -1,10 +1,10 @@
|
||||
import hmac
|
||||
from functools import wraps
|
||||
from hashlib import sha512
|
||||
-from urllib.parse import urlparse
|
||||
-from urllib.parse import urlunparse
|
||||
from urllib.parse import parse_qs
|
||||
from urllib.parse import urlencode
|
||||
+from urllib.parse import urlparse
|
||||
+from urllib.parse import urlunparse
|
||||
|
||||
from flask import current_app
|
||||
from flask import g
|
||||
diff --git a/tests/test_login.py b/tests/test_login.py
|
||||
--- a/tests/test_login.py
|
||||
+++ b/tests/test_login.py
|
||||
@@ -328,7 +328,7 @@
|
||||
def empty_session():
|
||||
return f"modified={session.modified}"
|
||||
|
||||
- # This will help us with the possibility of typoes in the tests. Now
|
||||
+ # This will help us with the possibility of typos in the tests. Now
|
||||
# we shouldn't have to check each response to help us set up state
|
||||
# (such as login pages) to make sure it worked: we will always
|
||||
# get an exception raised (rather than return a 404 response)
|
||||
@@ -669,24 +669,17 @@
|
||||
name = self.app.config["REMEMBER_COOKIE_NAME"] = "myname"
|
||||
duration = self.app.config["REMEMBER_COOKIE_DURATION"] = timedelta(days=2)
|
||||
path = self.app.config["REMEMBER_COOKIE_PATH"] = "/mypath"
|
||||
- domain = self.app.config["REMEMBER_COOKIE_DOMAIN"] = ".localhost.local"
|
||||
+ domain = self.app.config["REMEMBER_COOKIE_DOMAIN"] = "localhost.local"
|
||||
|
||||
with self.app.test_client() as c:
|
||||
c.get("/login-notch-remember")
|
||||
|
||||
- # TODO: Is there a better way to test this?
|
||||
- self.assertIn(
|
||||
- domain,
|
||||
- c.cookie_jar._cookies,
|
||||
- "Custom domain not found as cookie domain",
|
||||
+ cookie = c.get_cookie(key=name, domain=domain, path=path)
|
||||
+ self.assertIsNotNone(
|
||||
+ cookie, "Custom domain, path and name not found in cookies"
|
||||
)
|
||||
- domain_cookie = c.cookie_jar._cookies[domain]
|
||||
- self.assertIn(path, domain_cookie, "Custom path not found as cookie path")
|
||||
- path_cookie = domain_cookie[path]
|
||||
- self.assertIn(name, path_cookie, "Custom name not found as cookie name")
|
||||
- cookie = path_cookie[name]
|
||||
|
||||
- expiration_date = datetime.utcfromtimestamp(cookie.expires)
|
||||
+ expiration_date = datetime.utcfromtimestamp(cookie.expires.timestamp())
|
||||
expected_date = datetime.utcnow() + duration
|
||||
difference = expected_date - expiration_date
|
||||
|
||||
@@ -702,24 +695,17 @@
|
||||
self.app.config["REMEMBER_COOKIE_DURATION"] = 172800
|
||||
duration = timedelta(hours=7)
|
||||
path = self.app.config["REMEMBER_COOKIE_PATH"] = "/mypath"
|
||||
- domain = self.app.config["REMEMBER_COOKIE_DOMAIN"] = ".localhost.local"
|
||||
+ domain = self.app.config["REMEMBER_COOKIE_DOMAIN"] = "localhost.local"
|
||||
|
||||
with self.app.test_client() as c:
|
||||
c.get("/login-notch-remember-custom")
|
||||
|
||||
- # TODO: Is there a better way to test this?
|
||||
- self.assertIn(
|
||||
- domain,
|
||||
- c.cookie_jar._cookies,
|
||||
- "Custom domain not found as cookie domain",
|
||||
+ cookie = c.get_cookie(key=name, domain=domain, path=path)
|
||||
+ self.assertIsNotNone(
|
||||
+ cookie, "Custom domain, path and name not found in cookies"
|
||||
)
|
||||
- domain_cookie = c.cookie_jar._cookies[domain]
|
||||
- self.assertIn(path, domain_cookie, "Custom path not found as cookie path")
|
||||
- path_cookie = domain_cookie[path]
|
||||
- self.assertIn(name, path_cookie, "Custom name not found as cookie name")
|
||||
- cookie = path_cookie[name]
|
||||
|
||||
- expiration_date = datetime.utcfromtimestamp(cookie.expires)
|
||||
+ expiration_date = datetime.utcfromtimestamp(cookie.expires.timestamp())
|
||||
expected_date = datetime.utcnow() + duration
|
||||
difference = expected_date - expiration_date
|
||||
|
||||
@@ -734,15 +720,15 @@
|
||||
self.app.config["REMEMBER_COOKIE_DURATION"] = 172800
|
||||
duration = timedelta(seconds=172800)
|
||||
name = self.app.config["REMEMBER_COOKIE_NAME"] = "myname"
|
||||
- domain = self.app.config["REMEMBER_COOKIE_DOMAIN"] = ".localhost.local"
|
||||
+ domain = self.app.config["REMEMBER_COOKIE_DOMAIN"] = "localhost.local"
|
||||
|
||||
with self.app.test_client() as c:
|
||||
result = c.get("/login-notch-remember")
|
||||
self.assertEqual(result.status_code, 200)
|
||||
|
||||
- cookie = c.cookie_jar._cookies[domain]["/"][name]
|
||||
+ cookie = c.get_cookie(key=name, domain=domain, path="/")
|
||||
|
||||
- expiration_date = datetime.utcfromtimestamp(cookie.expires)
|
||||
+ expiration_date = datetime.utcfromtimestamp(cookie.expires.timestamp())
|
||||
expected_date = datetime.utcnow() + duration
|
||||
difference = expected_date - expiration_date
|
||||
|
||||
@@ -794,25 +780,22 @@
|
||||
self.assertIn(expected_exception_message, str(cm.exception))
|
||||
|
||||
def test_remember_me_refresh_every_request(self):
|
||||
- domain = self.app.config["REMEMBER_COOKIE_DOMAIN"] = ".localhost.local"
|
||||
+ domain = self.app.config["REMEMBER_COOKIE_DOMAIN"] = "localhost.local"
|
||||
path = self.app.config["REMEMBER_COOKIE_PATH"] = "/"
|
||||
|
||||
# No refresh
|
||||
self.app.config["REMEMBER_COOKIE_REFRESH_EACH_REQUEST"] = False
|
||||
with self.app.test_client() as c:
|
||||
c.get("/login-notch-remember")
|
||||
- self.assertIn("remember", c.cookie_jar._cookies[domain][path])
|
||||
- expiration_date_1 = datetime.utcfromtimestamp(
|
||||
- c.cookie_jar._cookies[domain][path]["remember"].expires
|
||||
- )
|
||||
-
|
||||
- self._delete_session(c)
|
||||
+ cookie = c.get_cookie(key="remember", domain=domain, path=path)
|
||||
+ self.assertIsNotNone(cookie)
|
||||
+ expiration_date_1 = datetime.utcfromtimestamp(cookie.expires.timestamp())
|
||||
|
||||
+ # self._delete_session(c)
|
||||
c.get("/username")
|
||||
- self.assertIn("remember", c.cookie_jar._cookies[domain][path])
|
||||
- expiration_date_2 = datetime.utcfromtimestamp(
|
||||
- c.cookie_jar._cookies[domain][path]["remember"].expires
|
||||
- )
|
||||
+ cookie = c.get_cookie(key="remember", domain=domain, path=path)
|
||||
+ self.assertIsNotNone(cookie)
|
||||
+ expiration_date_2 = datetime.utcfromtimestamp(cookie.expires.timestamp())
|
||||
self.assertEqual(expiration_date_1, expiration_date_2)
|
||||
|
||||
# With refresh (mock datetime's `utcnow`)
|
||||
@@ -820,22 +803,24 @@
|
||||
self.app.config["REMEMBER_COOKIE_REFRESH_EACH_REQUEST"] = True
|
||||
now = datetime.utcnow()
|
||||
mock_dt.utcnow = Mock(return_value=now)
|
||||
-
|
||||
+ mock_utcnow1 = mock_dt.utcnow
|
||||
with self.app.test_client() as c:
|
||||
c.get("/login-notch-remember")
|
||||
- self.assertIn("remember", c.cookie_jar._cookies[domain][path])
|
||||
+ cookie = c.get_cookie(key="remember", domain=domain, path=path)
|
||||
expiration_date_1 = datetime.utcfromtimestamp(
|
||||
- c.cookie_jar._cookies[domain][path]["remember"].expires
|
||||
+ cookie.expires.timestamp()
|
||||
)
|
||||
self.assertIsNotNone(expiration_date_1)
|
||||
|
||||
- self._delete_session(c)
|
||||
+ # self._delete_session(c)
|
||||
|
||||
mock_dt.utcnow = Mock(return_value=now + timedelta(seconds=1))
|
||||
+ mock_utcnow2 = mock_dt.utcnow
|
||||
+ self.assertNotEqual(mock_utcnow1, mock_utcnow2)
|
||||
c.get("/username")
|
||||
- self.assertIn("remember", c.cookie_jar._cookies[domain][path])
|
||||
+ cookie = c.get_cookie(key="remember", domain=domain, path=path)
|
||||
expiration_date_2 = datetime.utcfromtimestamp(
|
||||
- c.cookie_jar._cookies[domain][path]["remember"].expires
|
||||
+ cookie.expires.timestamp()
|
||||
)
|
||||
self.assertIsNotNone(expiration_date_2)
|
||||
self.assertNotEqual(expiration_date_1, expiration_date_2)
|
||||
@@ -1016,7 +1001,7 @@
|
||||
c.get("/login-notch-remember")
|
||||
with c.session_transaction() as sess:
|
||||
sess["_user_id"] = None
|
||||
- c.set_cookie(domain, self.remember_cookie_name, "foo")
|
||||
+ c.set_cookie(self.remember_cookie_name, "foo", domain=domain)
|
||||
result = c.get("/username")
|
||||
self.assertEqual("Anonymous", result.data.decode("utf-8"))
|
||||
|
||||
@@ -1315,7 +1300,7 @@
|
||||
pass
|
||||
return USERS.get(user_id)
|
||||
|
||||
- # This will help us with the possibility of typoes in the tests. Now
|
||||
+ # This will help us with the possibility of typos in the tests. Now
|
||||
# we shouldn't have to check each response to help us set up state
|
||||
# (such as login pages) to make sure it worked: we will always
|
||||
# get an exception raised (rather than return a 404 response)
|
||||
@@ -1426,9 +1411,10 @@
|
||||
result = login_url("https://auth.localhost/login", PROTECTED)
|
||||
self.assertEqual(expected, result)
|
||||
|
||||
+ url = login_url("/login?affil=cgnu", PROTECTED)
|
||||
self.assertEqual(
|
||||
"/login?affil=cgnu&next=%2Fprotected",
|
||||
- login_url("/login?affil=cgnu", PROTECTED),
|
||||
+ url,
|
||||
)
|
||||
|
||||
def test_login_url_generation_with_view(self):
|
||||
@@ -1590,7 +1576,7 @@
|
||||
def load_user(user_id):
|
||||
return USERS[str(user_id)]
|
||||
|
||||
- # This will help us with the possibility of typoes in the tests. Now
|
||||
+ # This will help us with the possibility of typos in the tests. Now
|
||||
# we shouldn't have to check each response to help us set up state
|
||||
# (such as login pages) to make sure it worked: we will always
|
||||
# get an exception raised (rather than return a 404 response)
|
||||
@@ -1646,7 +1632,7 @@
|
||||
def load_user(user_id):
|
||||
return USERS[str(user_id)]
|
||||
|
||||
- # This will help us with the possibility of typoes in the tests. Now
|
||||
+ # This will help us with the possibility of typos in the tests. Now
|
||||
# we shouldn't have to check each response to help us set up state
|
||||
# (such as login pages) to make sure it worked: we will always
|
||||
# get an exception raised (rather than return a 404 response)
|
||||
@@ -1742,7 +1728,7 @@
|
||||
def load_user(user_id):
|
||||
return USERS[int(user_id)]
|
||||
|
||||
- # This will help us with the possibility of typoes in the tests. Now
|
||||
+ # This will help us with the possibility of typos in the tests. Now
|
||||
# we shouldn't have to check each response to help us set up state
|
||||
# (such as login pages) to make sure it worked: we will always
|
||||
# get an exception raised (rather than return a 404 response)
|
|
@ -1,11 +1,12 @@
|
|||
# Template file for 'python3-Flask-Login'
|
||||
pkgname=python3-Flask-Login
|
||||
version=0.6.2
|
||||
revision=3
|
||||
revision=4
|
||||
build_style=python3-module
|
||||
make_check_args="-p no:warnings"
|
||||
hostmakedepends="python3-setuptools"
|
||||
depends="python3-Flask"
|
||||
checkdepends="python3-Werkzeug python3-Flask"
|
||||
checkdepends="python3-semanticversion python3-pytest python3-asgiref $depends"
|
||||
short_desc="User session management for Flask (Python3)"
|
||||
maintainer="pulux <pulux@pf4sh.de>"
|
||||
license="MIT"
|
||||
|
|
Loading…
Reference in New Issue