Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-Authlib for openSUSE:Factory 
checked in at 2026-01-12 11:50:08
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-Authlib (Old)
 and      /work/SRC/openSUSE:Factory/.python-Authlib.new.1928 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-Authlib"

Mon Jan 12 11:50:08 2026 rev:27 rq:1326736 version:1.6.6

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-Authlib/python-Authlib.changes    
2025-10-13 15:37:36.854961288 +0200
+++ /work/SRC/openSUSE:Factory/.python-Authlib.new.1928/python-Authlib.changes  
2026-01-12 11:50:28.066509416 +0100
@@ -1,0 +2,10 @@
+Fri Jan  9 08:29:28 UTC 2026 - John Paul Adrian Glaubitz 
<[email protected]>
+
+- Update to 1.6.6 (bsc#1256414, CVE-2025-68158)
+  * ``get_jwt_config`` takes a ``client`` parameter, #844.
+  * Fix incorrect signature when ``Content-Type`` is x-www-form-urlencoded
+    for OAuth 1.0 Client, #778.
+  * Use ``expires_in`` in ``OAuth2Token`` when ``expires_at`` is unparsable, 
#842.
+  * Always track ``state`` in session for OAuth client integrations.
+
+-------------------------------------------------------------------

Old:
----
  authlib-1.6.5.tar.gz

New:
----
  authlib-1.6.6.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-Authlib.spec ++++++
--- /var/tmp/diff_new_pack.qgOH7e/_old  2026-01-12 11:50:29.046550790 +0100
+++ /var/tmp/diff_new_pack.qgOH7e/_new  2026-01-12 11:50:29.050550959 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-Authlib
 #
-# Copyright (c) 2025 SUSE LLC and contributors
+# Copyright (c) 2026 SUSE LLC and contributors
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -19,7 +19,7 @@
 %define modname authlib
 %{?sle15_python_module_pythons}
 Name:           python-Authlib
-Version:        1.6.5
+Version:        1.6.6
 Release:        0
 Summary:        Python library for building OAuth and OpenID Connect servers
 License:        BSD-3-Clause

++++++ authlib-1.6.5.tar.gz -> authlib-1.6.6.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/authlib-1.6.5/authlib/__init__.py 
new/authlib-1.6.6/authlib/__init__.py
--- old/authlib-1.6.5/authlib/__init__.py       2025-10-02 15:31:28.000000000 
+0200
+++ new/authlib-1.6.6/authlib/__init__.py       2025-12-12 08:59:43.000000000 
+0100
@@ -1,4 +1,5 @@
-"""authlib.
+"""
+authlib
 ~~~~~~~
 
 The ultimate Python library in building OAuth 1.0, OAuth 2.0 and OpenID
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/authlib-1.6.5/authlib/consts.py 
new/authlib-1.6.6/authlib/consts.py
--- old/authlib-1.6.5/authlib/consts.py 2025-10-02 15:31:28.000000000 +0200
+++ new/authlib-1.6.6/authlib/consts.py 2025-12-12 08:59:43.000000000 +0100
@@ -1,5 +1,5 @@
 name = "Authlib"
-version = "1.6.5"
+version = "1.6.6"
 author = "Hsiaoming Yang <[email protected]>"
 homepage = "https://authlib.org";
 default_user_agent = f"{name}/{version} (+{homepage})"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/authlib-1.6.5/authlib/integrations/base_client/framework_integration.py 
new/authlib-1.6.6/authlib/integrations/base_client/framework_integration.py
--- old/authlib-1.6.5/authlib/integrations/base_client/framework_integration.py 
2025-10-02 15:31:28.000000000 +0200
+++ new/authlib-1.6.6/authlib/integrations/base_client/framework_integration.py 
2025-12-12 08:59:43.000000000 +0100
@@ -20,11 +20,9 @@
 
     def _clear_session_state(self, session):
         now = time.time()
+        prefix = f"_state_{self.name}"
         for key in dict(session):
-            if "_authlib_" in key:
-                # TODO: remove in future
-                session.pop(key)
-            elif key.startswith("_state_"):
+            if key.startswith(prefix):
                 value = session[key]
                 exp = value.get("exp")
                 if not exp or exp < now:
@@ -32,29 +30,32 @@
 
     def get_state_data(self, session, state):
         key = f"_state_{self.name}_{state}"
+        session_data = session.get(key)
+        if not session_data:
+            return None
         if self.cache:
-            value = self._get_cache_data(key)
+            cached_value = self._get_cache_data(key)
         else:
-            value = session.get(key)
-        if value:
-            return value.get("data")
+            cached_value = session_data
+        if cached_value:
+            return cached_value.get("data")
         return None
 
     def set_state_data(self, session, state, data):
         key = f"_state_{self.name}_{state}"
+        now = time.time()
         if self.cache:
             self.cache.set(key, json.dumps({"data": data}), self.expires_in)
+            session[key] = {"exp": now + self.expires_in}
         else:
-            now = time.time()
             session[key] = {"data": data, "exp": now + self.expires_in}
 
     def clear_state_data(self, session, state):
         key = f"_state_{self.name}_{state}"
         if self.cache:
             self.cache.delete(key)
-        else:
-            session.pop(key, None)
-            self._clear_session_state(session)
+        session.pop(key, None)
+        self._clear_session_state(session)
 
     def update_token(self, token, refresh_token=None, access_token=None):
         raise NotImplementedError()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/authlib-1.6.5/authlib/oauth1/rfc5849/client_auth.py 
new/authlib-1.6.6/authlib/oauth1/rfc5849/client_auth.py
--- old/authlib-1.6.5/authlib/oauth1/rfc5849/client_auth.py     2025-10-02 
15:31:28.000000000 +0200
+++ new/authlib-1.6.6/authlib/oauth1/rfc5849/client_auth.py     2025-12-12 
08:59:43.000000000 +0100
@@ -172,6 +172,8 @@
 
         if CONTENT_TYPE_FORM_URLENCODED in content_type:
             headers["Content-Type"] = CONTENT_TYPE_FORM_URLENCODED
+            if isinstance(body, bytes):
+                body = body.decode()
             uri, headers, body = self.sign(method, uri, headers, body)
         elif self.force_include_body:
             # To allow custom clients to work on non form encoded bodies.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/authlib-1.6.5/authlib/oauth2/rfc6749/wrappers.py 
new/authlib-1.6.6/authlib/oauth2/rfc6749/wrappers.py
--- old/authlib-1.6.5/authlib/oauth2/rfc6749/wrappers.py        2025-10-02 
15:31:28.000000000 +0200
+++ new/authlib-1.6.6/authlib/oauth2/rfc6749/wrappers.py        2025-12-12 
08:59:43.000000000 +0100
@@ -4,15 +4,26 @@
 class OAuth2Token(dict):
     def __init__(self, params):
         if params.get("expires_at"):
-            params["expires_at"] = int(params["expires_at"])
+            try:
+                params["expires_at"] = int(params["expires_at"])
+            except ValueError:
+                # If expires_at is not parseable, fall back to expires_in if 
available
+                # Otherwise leave expires_at untouched
+                if params.get("expires_in"):
+                    params["expires_at"] = int(time.time()) + 
int(params["expires_in"])
+
         elif params.get("expires_in"):
             params["expires_at"] = int(time.time()) + int(params["expires_in"])
+
         super().__init__(params)
 
     def is_expired(self, leeway=60):
         expires_at = self.get("expires_at")
         if not expires_at:
             return None
+        # Only check expiration if expires_at is an integer
+        if not isinstance(expires_at, int):
+            return None
         # small timedelta to consider token as expired before it actually 
expires
         expiration_threshold = expires_at - leeway
         return expiration_threshold < time.time()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/authlib-1.6.5/authlib/oidc/core/grants/code.py 
new/authlib-1.6.6/authlib/oidc/core/grants/code.py
--- old/authlib-1.6.5/authlib/oidc/core/grants/code.py  2025-10-02 
15:31:28.000000000 +0200
+++ new/authlib-1.6.6/authlib/oidc/core/grants/code.py  2025-12-12 
08:59:43.000000000 +0100
@@ -8,6 +8,7 @@
 """
 
 import logging
+import warnings
 
 from authlib.oauth2.rfc6749 import OAuth2Request
 
@@ -20,7 +21,7 @@
 
 
 class OpenIDToken:
-    def get_jwt_config(self, grant):  # pragma: no cover
+    def get_jwt_config(self, grant, client):  # pragma: no cover
         """Get the JWT configuration for OpenIDCode extension. The JWT
         configuration will be used to generate ``id_token``.
         If ``alg`` is undefined, the ``id_token_signed_response_alg`` client
@@ -29,15 +30,16 @@
         will be used.
         Developers MUST implement this method in subclass, e.g.::
 
-            def get_jwt_config(self, grant):
+            def get_jwt_config(self, grant, client):
                 return {
                     "key": read_private_key_file(key_path),
-                    "alg": "RS256",
+                    "alg": client.id_token_signed_response_alg or "RS256",
                     "iss": "issuer-identity",
                     "exp": 3600,
                 }
 
         :param grant: AuthorizationCodeGrant instance
+        :param client: OAuth2 client instance
         :return: dict
         """
         raise NotImplementedError()
@@ -78,7 +80,17 @@
         request: OAuth2Request = grant.request
         authorization_code = request.authorization_code
 
-        config = self.get_jwt_config(grant)
+        try:
+            config = self.get_jwt_config(grant, request.client)
+        except TypeError:
+            warnings.warn(
+                "get_jwt_config(self, grant) is deprecated and will be removed 
in version 1.8. "
+                "Use get_jwt_config(self, grant, client) instead.",
+                DeprecationWarning,
+                stacklevel=2,
+            )
+            config = self.get_jwt_config(grant)
+
         config["aud"] = self.get_audiences(request)
 
         # Per OpenID Connect Registration 1.0 Section 2:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/authlib-1.6.5/authlib/oidc/core/grants/implicit.py 
new/authlib-1.6.6/authlib/oidc/core/grants/implicit.py
--- old/authlib-1.6.5/authlib/oidc/core/grants/implicit.py      2025-10-02 
15:31:28.000000000 +0200
+++ new/authlib-1.6.6/authlib/oidc/core/grants/implicit.py      2025-12-12 
08:59:43.000000000 +0100
@@ -1,4 +1,5 @@
 import logging
+import warnings
 
 from authlib.oauth2.rfc6749 import AccessDeniedError
 from authlib.oauth2.rfc6749 import ImplicitGrant
@@ -36,19 +37,20 @@
         """
         raise NotImplementedError()
 
-    def get_jwt_config(self):
+    def get_jwt_config(self, client):
         """Get the JWT configuration for OpenIDImplicitGrant. The JWT
         configuration will be used to generate ``id_token``. Developers
         MUST implement this method in subclass, e.g.::
 
-            def get_jwt_config(self):
+            def get_jwt_config(self, client):
                 return {
                     "key": read_private_key_file(key_path),
-                    "alg": "RS256",
+                    "alg": client.id_token_signed_response_alg or "RS256",
                     "iss": "issuer-identity",
                     "exp": 3600,
                 }
 
+        :param client: OAuth2 client instance
         :return: dict
         """
         raise NotImplementedError()
@@ -143,7 +145,17 @@
         return params
 
     def process_implicit_token(self, token, code=None):
-        config = self.get_jwt_config()
+        try:
+            config = self.get_jwt_config(self.request.client)
+        except TypeError:
+            warnings.warn(
+                "get_jwt_config(self) is deprecated and will be removed in 
version 1.8. "
+                "Use get_jwt_config(self, client) instead.",
+                DeprecationWarning,
+                stacklevel=2,
+            )
+            config = self.get_jwt_config()
+
         config["aud"] = self.get_audiences(self.request)
         config["nonce"] = self.request.payload.data.get("nonce")
         if code is not None:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/authlib-1.6.5/docs/changelog.rst 
new/authlib-1.6.6/docs/changelog.rst
--- old/authlib-1.6.5/docs/changelog.rst        2025-10-02 15:31:28.000000000 
+0200
+++ new/authlib-1.6.6/docs/changelog.rst        2025-12-12 08:59:43.000000000 
+0100
@@ -6,6 +6,16 @@
 
 Here you can see the full list of changes between each Authlib release.
 
+Version 1.6.6
+-------------
+
+**Released on Dec 12, 2025**
+
+- ``get_jwt_config`` takes a ``client`` parameter, :pr:`844`.
+- Fix incorrect signature when ``Content-Type`` is x-www-form-urlencoded for 
OAuth 1.0 Client, :pr:`778`.
+- Use ``expires_in`` in ``OAuth2Token`` when ``expires_at`` is unparsable, 
:pr:`842`.
+- Always track ``state`` in session for OAuth client integrations.
+
 Version 1.6.5
 -------------
 
@@ -57,12 +67,16 @@
 
 - Fix issue when :rfc:`RFC9207 <9207>` is enabled and the authorization 
endpoint response is not a redirection. :pr:`733`
 - Fix missing ``state`` parameter in authorization error responses. 
:issue:`525`
-- Support for ``acr`` and ``amr`` claims in ``id_token``. :issue:`734`
 - Support for the ``none`` JWS algorithm.
 - Fix ``response_types`` strict order during dynamic client registration. 
:issue:`760`
 - Implement :rfc:`RFC9101 The OAuth 2.0 Authorization Framework: JWT-Secured 
Authorization Request (JAR) <9101>`. :issue:`723`
 - OIDC :class:`UserInfo endpoint 
<authlib.oidc.core.userinfo.UserInfoEndpoint>` support. :issue:`459`
 
+**Breaking changes**:
+
+- Support for ``acr`` and ``amr`` claims in ``id_token``. :issue:`734`
+  The ``OAuth2AuthorizationCodeMixin`` must have a migration to support the 
new fields.
+
 Version 1.5.2
 -------------
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/authlib-1.6.5/docs/client/requests.rst 
new/authlib-1.6.6/docs/client/requests.rst
--- old/authlib-1.6.5/docs/client/requests.rst  2025-10-02 15:31:28.000000000 
+0200
+++ new/authlib-1.6.6/docs/client/requests.rst  2025-12-12 08:59:43.000000000 
+0100
@@ -159,24 +159,13 @@
 Self-signed certificate mutual-TLS method internet standard is defined in
 `RFC8705 Section 2.2`_ .
 
-For specifics development purposes only, you may need to
-**disable SSL verification**.
+You can use the environment variables CURL_CA_BUNDLE and REQUESTS_CA_BUNDLE
+to specify a CA certificate file for validating your self-signed certificate.
 
-You can force all requests to disable SSL verification by setting
-your environment variable ``CURL_CA_BUNDLE=""``.
+.. code-block:: bash
 
-This solutions works because Python requests (and most of the packages)
-overwrites the default value for ssl verifications from environment
-variables ``CURL_CA_BUNDLE`` and ``REQUESTS_CA_BUNDLE``.
-
-This hack will **only work** with ``CURL_CA_BUNDLE``, as you can see
-in `requests/sessions.py`_ ::
-
-    verify = (os.environ.get('REQUESTS_CA_BUNDLE')
-    or os.environ.get('CURL_CA_BUNDLE'))
+    REQUESTS_CA_BUNDLE=/path/to/ca-cert.pem
 
 Please remember to set the env variable only in you development environment.
 
-
 .. _RFC8705 Section 2.2: https://tools.ietf.org/html/rfc8705#section-2.2
-.. _requests/sessions.py: 
https://github.com/requests/requests/blob/master/requests/sessions.py#L706
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/authlib-1.6.5/tests/clients/test_flask/test_oauth_client.py 
new/authlib-1.6.6/tests/clients/test_flask/test_oauth_client.py
--- old/authlib-1.6.5/tests/clients/test_flask/test_oauth_client.py     
2025-10-02 15:31:28.000000000 +0200
+++ new/authlib-1.6.6/tests/clients/test_flask/test_oauth_client.py     
2025-12-12 08:59:43.000000000 +0100
@@ -150,9 +150,13 @@
             assert resp.status_code == 302
             url = resp.headers.get("Location")
             assert "oauth_token=foo" in url
+            session_data = session["_state_dev_foo"]
+            assert "exp" in session_data
+            assert "data" not in session_data
 
     with app.test_request_context("/?oauth_token=foo"):
         with mock.patch("requests.sessions.Session.send") as send:
+            session["_state_dev_foo"] = session_data
             send.return_value = 
mock_send_value("oauth_token=a&oauth_token_secret=b")
             token = client.authorize_access_token()
             assert token["oauth_token"] == "a"
@@ -207,7 +211,44 @@
     assert session.update_token is not None
 
 
-def test_oauth2_authorize():
+def test_oauth2_authorize_cache():
+    app = Flask(__name__)
+    app.secret_key = "!"
+    cache = SimpleCache()
+    oauth = OAuth(app, cache=cache)
+    client = oauth.register(
+        "dev",
+        client_id="dev",
+        client_secret="dev",
+        api_base_url="https://resource.test/api";,
+        access_token_url="https://provider.test/token";,
+        authorize_url="https://provider.test/authorize";,
+    )
+    with app.test_request_context():
+        resp = client.authorize_redirect("https://client.test/callback";)
+        assert resp.status_code == 302
+        url = resp.headers.get("Location")
+        assert "state=" in url
+        state = dict(url_decode(urlparse.urlparse(url).query))["state"]
+        assert state is not None
+        session_data = session[f"_state_dev_{state}"]
+        assert "exp" in session_data
+        assert "data" not in session_data
+
+    with app.test_request_context(path=f"/?code=a&state={state}"):
+        # session is cleared in tests
+        session[f"_state_dev_{state}"] = session_data
+
+        with mock.patch("requests.sessions.Session.send") as send:
+            send.return_value = mock_send_value(get_bearer_token())
+            token = client.authorize_access_token()
+            assert token["access_token"] == "a"
+
+    with app.test_request_context():
+        assert client.token is None
+
+
+def test_oauth2_authorize_session():
     app = Flask(__name__)
     app.secret_key = "!"
     oauth = OAuth(app)
@@ -227,11 +268,13 @@
         assert "state=" in url
         state = dict(url_decode(urlparse.urlparse(url).query))["state"]
         assert state is not None
-        data = session[f"_state_dev_{state}"]
+        session_data = session[f"_state_dev_{state}"]
+        assert "exp" in session_data
+        assert "data" in session_data
 
     with app.test_request_context(path=f"/?code=a&state={state}"):
         # session is cleared in tests
-        session[f"_state_dev_{state}"] = data
+        session[f"_state_dev_{state}"] = session_data
 
         with mock.patch("requests.sessions.Session.send") as send:
             send.return_value = mock_send_value(get_bearer_token())
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/authlib-1.6.5/tests/clients/test_requests/test_oauth2_session.py 
new/authlib-1.6.6/tests/clients/test_requests/test_oauth2_session.py
--- old/authlib-1.6.5/tests/clients/test_requests/test_oauth2_session.py        
2025-10-02 15:31:28.000000000 +0200
+++ new/authlib-1.6.6/tests/clients/test_requests/test_oauth2_session.py        
2025-12-12 08:59:43.000000000 +0100
@@ -323,6 +323,42 @@
     assert not sess.token.is_expired(sess.leeway)
 
 
+def test_expires_in_used_when_expires_at_unparseable():
+    """Test that expires_in is used as fallback when expires_at is 
unparsable."""
+    token = dict(
+        access_token="a",
+        token_type="bearer",
+        expires_in=3600,  # 1 hour from now
+        expires_at="2024-01-01T00:00:00Z",  # Unparsable - should fall back to 
expires_in
+    )
+    sess = OAuth2Session("foo", token=token)
+
+    # The token should use expires_in since expires_at is unparsable
+    # So it should be considered expired with leeway > 3600
+    assert sess.token.is_expired(leeway=3700) is True
+    # And not expired with leeway < 3600
+    assert sess.token.is_expired(leeway=0) is False
+    # expires_at should be calculated from expires_in
+    assert isinstance(sess.token["expires_at"], int)
+
+
+def test_unparseable_expires_at_returns_none():
+    """Test that is_expired returns None when expires_at is unparsable and no 
expires_in."""
+    token = dict(
+        access_token="a",
+        token_type="bearer",
+        expires_at="2024-01-01T00:00:00Z",  # Unparsable date string
+    )
+    sess = OAuth2Session("foo", token=token)
+
+    # Should return None since we can't determine expiration
+    assert sess.token.is_expired() is None
+    # The unparsable expires_at should be preserved in the token
+    assert sess.token["expires_at"] == "2024-01-01T00:00:00Z"
+    # No expires_in should be calculated
+    assert "expires_in" not in sess.token
+
+
 def test_token_expired():
     token = dict(access_token="a", token_type="bearer", expires_at=100)
     sess = OAuth2Session("foo", token=token)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/authlib-1.6.5/tests/django/test_oauth2/conftest.py 
new/authlib-1.6.6/tests/django/test_oauth2/conftest.py
--- old/authlib-1.6.5/tests/django/test_oauth2/conftest.py      2025-10-02 
15:31:28.000000000 +0200
+++ new/authlib-1.6.6/tests/django/test_oauth2/conftest.py      2025-12-12 
08:59:43.000000000 +0100
@@ -31,3 +31,19 @@
     user.save()
     yield user
     user.delete()
+
+
[email protected]
+def token(user):
+    token = OAuth2Token(
+        user_id=user.pk,
+        client_id="client-id",
+        token_type="bearer",
+        access_token="a1",
+        refresh_token="r1",
+        scope="profile",
+        expires_in=3600,
+    )
+    token.save()
+    yield token
+    token.delete()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/authlib-1.6.5/tests/django/test_oauth2/test_refresh_token.py 
new/authlib-1.6.6/tests/django/test_oauth2/test_refresh_token.py
--- old/authlib-1.6.5/tests/django/test_oauth2/test_refresh_token.py    
2025-10-02 15:31:28.000000000 +0200
+++ new/authlib-1.6.6/tests/django/test_oauth2/test_refresh_token.py    
2025-12-12 08:59:43.000000000 +0100
@@ -51,22 +51,6 @@
     client.delete()
 
 
[email protected]
-def token(user):
-    token = OAuth2Token(
-        user_id=user.pk,
-        client_id="client-id",
-        token_type="bearer",
-        access_token="a1",
-        refresh_token="r1",
-        scope="profile",
-        expires_in=3600,
-    )
-    token.save()
-    yield token
-    token.delete()
-
-
 def test_invalid_client(factory, server):
     request = factory.post(
         "/oauth/token",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/authlib-1.6.5/tests/django/test_oauth2/test_resource_protector.py 
new/authlib-1.6.6/tests/django/test_oauth2/test_resource_protector.py
--- old/authlib-1.6.5/tests/django/test_oauth2/test_resource_protector.py       
2025-10-02 15:31:28.000000000 +0200
+++ new/authlib-1.6.6/tests/django/test_oauth2/test_resource_protector.py       
2025-12-12 08:59:43.000000000 +0100
@@ -26,21 +26,6 @@
     client.delete()
 
 
[email protected]
-def token(user, client):
-    token = OAuth2Token(
-        user_id=user.pk,
-        client_id=client.client_id,
-        token_type="bearer",
-        access_token="a1",
-        scope="profile",
-        expires_in=3600,
-    )
-    token.save()
-    yield token
-    token.delete()
-
-
 def test_invalid_token(factory):
     @require_oauth("profile")
     def get_user_profile(request):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/authlib-1.6.5/tests/django/test_oauth2/test_revocation_endpoint.py 
new/authlib-1.6.6/tests/django/test_oauth2/test_revocation_endpoint.py
--- old/authlib-1.6.5/tests/django/test_oauth2/test_revocation_endpoint.py      
2025-10-02 15:31:28.000000000 +0200
+++ new/authlib-1.6.6/tests/django/test_oauth2/test_revocation_endpoint.py      
2025-12-12 08:59:43.000000000 +0100
@@ -5,7 +5,6 @@
 from authlib.integrations.django_oauth2 import RevocationEndpoint
 
 from .models import Client
-from .models import OAuth2Token
 from .oauth2_server import create_basic_auth
 
 ENDPOINT_NAME = RevocationEndpoint.ENDPOINT_NAME
@@ -31,22 +30,6 @@
     client.delete()
 
 
[email protected]
-def token(user, client):
-    token = OAuth2Token(
-        user_id=user.pk,
-        client_id="client-id",
-        token_type="bearer",
-        access_token="a1",
-        refresh_token="r1",
-        scope="profile",
-        expires_in=3600,
-    )
-    token.save()
-    yield token
-    token.delete()
-
-
 def test_invalid_client(factory, server):
     request = factory.post("/oauth/revoke")
     resp = server.create_endpoint_response(ENDPOINT_NAME, request)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/authlib-1.6.5/tests/flask/test_oauth2/conftest.py 
new/authlib-1.6.6/tests/flask/test_oauth2/conftest.py
--- old/authlib-1.6.5/tests/flask/test_oauth2/conftest.py       2025-10-02 
15:31:28.000000000 +0200
+++ new/authlib-1.6.6/tests/flask/test_oauth2/conftest.py       2025-12-12 
08:59:43.000000000 +0100
@@ -6,6 +6,7 @@
 from tests.flask.test_oauth2.oauth2_server import create_authorization_server
 
 from .models import Client
+from .models import Token
 from .models import User
 
 
@@ -83,3 +84,20 @@
 @pytest.fixture
 def server(app):
     return create_authorization_server(app)
+
+
[email protected]
+def token(db):
+    token = Token(
+        user_id=1,
+        client_id="client-id",
+        token_type="bearer",
+        access_token="a1",
+        refresh_token="r1",
+        scope="profile",
+        expires_in=3600,
+    )
+    db.session.add(token)
+    db.session.commit()
+    yield token
+    db.session.delete(token)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/authlib-1.6.5/tests/flask/test_oauth2/test_client_configuration_endpoint.py 
new/authlib-1.6.6/tests/flask/test_oauth2/test_client_configuration_endpoint.py
--- 
old/authlib-1.6.5/tests/flask/test_oauth2/test_client_configuration_endpoint.py 
    2025-10-02 15:31:28.000000000 +0200
+++ 
new/authlib-1.6.6/tests/flask/test_oauth2/test_client_configuration_endpoint.py 
    2025-12-12 08:59:43.000000000 +0100
@@ -83,23 +83,6 @@
     return client
 
 
[email protected](autouse=True)
-def token(db, user, client):
-    token = Token(
-        user_id=user.id,
-        client_id=client.id,
-        token_type="bearer",
-        access_token="a1",
-        refresh_token="r1",
-        scope="openid profile",
-        expires_in=3600,
-    )
-    db.session.add(token)
-    db.session.commit()
-    yield token
-    db.session.delete(token)
-
-
 def test_read_client(test_client, client, token):
     assert client.client_name == "Authlib"
     headers = {"Authorization": f"bearer {token.access_token}"}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/authlib-1.6.5/tests/flask/test_oauth2/test_introspection_endpoint.py 
new/authlib-1.6.6/tests/flask/test_oauth2/test_introspection_endpoint.py
--- old/authlib-1.6.5/tests/flask/test_oauth2/test_introspection_endpoint.py    
2025-10-02 15:31:28.000000000 +0200
+++ new/authlib-1.6.6/tests/flask/test_oauth2/test_introspection_endpoint.py    
2025-12-12 08:59:43.000000000 +0100
@@ -58,23 +58,6 @@
     return client
 
 
[email protected]
-def token(db):
-    token = Token(
-        user_id=1,
-        client_id="client-id",
-        token_type="bearer",
-        access_token="a1",
-        refresh_token="r1",
-        scope="profile",
-        expires_in=3600,
-    )
-    db.session.add(token)
-    db.session.commit()
-    yield db
-    db.session.delete(token)
-
-
 def test_invalid_client(test_client):
     rv = test_client.post("/oauth/introspect")
     resp = json.loads(rv.data)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/authlib-1.6.5/tests/flask/test_oauth2/test_oauth2_server.py 
new/authlib-1.6.6/tests/flask/test_oauth2/test_oauth2_server.py
--- old/authlib-1.6.5/tests/flask/test_oauth2/test_oauth2_server.py     
2025-10-02 15:31:28.000000000 +0200
+++ new/authlib-1.6.6/tests/flask/test_oauth2/test_oauth2_server.py     
2025-12-12 08:59:43.000000000 +0100
@@ -85,23 +85,7 @@
     assert data["error"] == "unsupported_grant_type"
 
 
[email protected](autouse=True)
-def token(db):
-    token = Token(
-        user_id=1,
-        client_id="client-id",
-        token_type="bearer",
-        access_token="a1",
-        scope="profile",
-        expires_in=3600,
-    )
-    db.session.add(token)
-    db.session.commit()
-    yield token
-    db.session.delete(token)
-
-
-def test_invalid_token(test_client):
+def test_invalid_token(test_client, token):
     rv = test_client.get("/user")
     assert rv.status_code == 401
     resp = json.loads(rv.data)
@@ -136,7 +120,7 @@
     assert rv.status_code == 401
 
 
-def test_insufficient_token(test_client):
+def test_insufficient_token(test_client, token):
     headers = create_bearer_header("a1")
     rv = test_client.get("/user/email", headers=headers)
     assert rv.status_code == 403
@@ -144,7 +128,7 @@
     assert resp["error"] == "insufficient_scope"
 
 
-def test_access_resource(test_client):
+def test_access_resource(test_client, token):
     headers = create_bearer_header("a1")
 
     rv = test_client.get("/user", headers=headers)
@@ -160,7 +144,7 @@
     assert resp["status"] == "ok"
 
 
-def test_scope_operator(test_client):
+def test_scope_operator(test_client, token):
     headers = create_bearer_header("a1")
     rv = test_client.get("/operator-and", headers=headers)
     assert rv.status_code == 403
@@ -171,7 +155,7 @@
     assert rv.status_code == 200
 
 
-def test_optional_token(test_client):
+def test_optional_token(test_client, token):
     rv = test_client.get("/optional")
     assert rv.status_code == 200
     resp = json.loads(rv.data)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/authlib-1.6.5/tests/flask/test_oauth2/test_openid_code_grant.py 
new/authlib-1.6.6/tests/flask/test_oauth2/test_openid_code_grant.py
--- old/authlib-1.6.5/tests/flask/test_oauth2/test_openid_code_grant.py 
2025-10-02 15:31:28.000000000 +0200
+++ new/authlib-1.6.6/tests/flask/test_oauth2/test_openid_code_grant.py 
2025-12-12 08:59:43.000000000 +0100
@@ -15,6 +15,7 @@
 from authlib.oidc.core.grants import OpenIDCode as _OpenIDCode
 from tests.util import read_file_path
 
+from .models import Client
 from .models import CodeGrantMixin
 from .models import exists_nonce
 from .models import save_authorization_code
@@ -54,7 +55,7 @@
             return save_authorization_code(code, request)
 
     class OpenIDCode(_OpenIDCode):
-        def get_jwt_config(self, grant):
+        def get_jwt_config(self, grant, client):
             key = current_app.config.get("OAUTH2_JWT_KEY")
             alg = current_app.config.get("OAUTH2_JWT_ALG")
             iss = current_app.config.get("OAUTH2_JWT_ISS")
@@ -419,3 +420,64 @@
         claims_options={"iss": {"value": "Authlib"}},
     )
     claims.validate()
+
+
+def test_deprecated_get_jwt_config_signature(test_client, server, db, user):
+    """Using the old get_jwt_config(self, grant) signature should emit a 
DeprecationWarning."""
+
+    class DeprecatedOpenIDCode(_OpenIDCode):
+        def get_jwt_config(self, grant):
+            return {"key": "secret", "alg": "HS256", "iss": "Authlib", "exp": 
3600}
+
+        def exists_nonce(self, nonce, request):
+            return exists_nonce(nonce, request)
+
+        def generate_user_info(self, user, scopes):
+            return user.generate_user_info(scopes)
+
+    class AuthorizationCodeGrant(CodeGrantMixin, _AuthorizationCodeGrant):
+        def save_authorization_code(self, code, request):
+            return save_authorization_code(code, request)
+
+    server.register_grant(AuthorizationCodeGrant, [DeprecatedOpenIDCode()])
+
+    client = Client(
+        user_id=user.id,
+        client_id="deprecated-client",
+        client_secret="secret",
+    )
+    client.set_client_metadata(
+        {
+            "redirect_uris": ["https://client.test";],
+            "scope": "openid profile",
+            "response_types": ["code"],
+            "grant_types": ["authorization_code"],
+        }
+    )
+    db.session.add(client)
+    db.session.commit()
+
+    rv = test_client.post(
+        "/oauth/authorize",
+        data={
+            "response_type": "code",
+            "client_id": "deprecated-client",
+            "state": "bar",
+            "scope": "openid profile",
+            "redirect_uri": "https://client.test";,
+            "user_id": "1",
+        },
+    )
+    params = dict(url_decode(urlparse.urlparse(rv.location).query))
+    code = params["code"]
+
+    with pytest.warns(DeprecationWarning, match="get_jwt_config.*version 1.8"):
+        test_client.post(
+            "/oauth/token",
+            data={
+                "grant_type": "authorization_code",
+                "redirect_uri": "https://client.test";,
+                "code": code,
+            },
+            headers=create_basic_header("deprecated-client", "secret"),
+        )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/authlib-1.6.5/tests/flask/test_oauth2/test_openid_hybrid_grant.py 
new/authlib-1.6.6/tests/flask/test_oauth2/test_openid_hybrid_grant.py
--- old/authlib-1.6.5/tests/flask/test_oauth2/test_openid_hybrid_grant.py       
2025-10-02 15:31:28.000000000 +0200
+++ new/authlib-1.6.6/tests/flask/test_oauth2/test_openid_hybrid_grant.py       
2025-12-12 08:59:43.000000000 +0100
@@ -26,7 +26,7 @@
             return save_authorization_code(code, request)
 
     class OpenIDCode(_OpenIDCode):
-        def get_jwt_config(self, grant):
+        def get_jwt_config(self, grant, client):
             return dict(JWT_CONFIG)
 
         def exists_nonce(self, nonce, request):
@@ -39,7 +39,7 @@
         def save_authorization_code(self, code, request):
             return save_authorization_code(code, request)
 
-        def get_jwt_config(self):
+        def get_jwt_config(self, client):
             return dict(JWT_CONFIG)
 
         def exists_nonce(self, nonce, request):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/authlib-1.6.5/tests/flask/test_oauth2/test_openid_implict_grant.py 
new/authlib-1.6.6/tests/flask/test_oauth2/test_openid_implict_grant.py
--- old/authlib-1.6.5/tests/flask/test_oauth2/test_openid_implict_grant.py      
2025-10-02 15:31:28.000000000 +0200
+++ new/authlib-1.6.6/tests/flask/test_oauth2/test_openid_implict_grant.py      
2025-12-12 08:59:43.000000000 +0100
@@ -5,9 +5,12 @@
 from authlib.common.urls import url_decode
 from authlib.common.urls import urlparse
 from authlib.jose import JsonWebToken
+from authlib.oauth2.rfc6749.requests import BasicOAuth2Payload
+from authlib.oauth2.rfc6749.requests import OAuth2Request
 from authlib.oidc.core import ImplicitIDToken
 from authlib.oidc.core.grants import OpenIDImplicitGrant as 
_OpenIDImplicitGrant
 
+from .models import Client
 from .models import exists_nonce
 
 authorize_url = "/oauth/authorize?response_type=token&client_id=client-id"
@@ -16,7 +19,7 @@
 @pytest.fixture(autouse=True)
 def server(server):
     class OpenIDImplicitGrant(_OpenIDImplicitGrant):
-        def get_jwt_config(self):
+        def get_jwt_config(self, client):
             alg = current_app.config.get("OAUTH2_JWT_ALG", "HS256")
             return dict(key="secret", alg=alg, iss="Authlib", exp=3600)
 
@@ -259,3 +262,42 @@
     )
     params = dict(url_decode(urlparse.urlparse(rv.location).fragment))
     assert params["error"] == "invalid_request"
+
+
+def test_deprecated_get_jwt_config_signature(user):
+    """Using the old get_jwt_config(self) signature should emit a 
DeprecationWarning."""
+
+    class DeprecatedImplicitGrant(_OpenIDImplicitGrant):
+        def get_jwt_config(self):
+            return {"key": "secret", "alg": "HS256", "iss": "Authlib", "exp": 
3600}
+
+        def generate_user_info(self, user, scopes):
+            return user.generate_user_info(scopes)
+
+        def exists_nonce(self, nonce, request):
+            return exists_nonce(nonce, request)
+
+    client = Client(
+        user_id=user.id,
+        client_id="deprecated-client",
+        client_secret="secret",
+    )
+    client.set_client_metadata(
+        {
+            "redirect_uris": ["https://client.test/callback";],
+            "scope": "openid profile",
+            "token_endpoint_auth_method": "none",
+            "response_types": ["id_token"],
+        }
+    )
+
+    request = OAuth2Request("POST", "https://server.test/authorize";)
+    request.payload = BasicOAuth2Payload({"nonce": "test-nonce"})
+    request.client = client
+    request.user = user
+
+    grant = DeprecatedImplicitGrant(request, client)
+    token = {"scope": "openid", "expires_in": 3600}
+
+    with pytest.warns(DeprecationWarning, match="get_jwt_config.*version 1.8"):
+        grant.process_implicit_token(token)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/authlib-1.6.5/tests/flask/test_oauth2/test_password_grant.py 
new/authlib-1.6.6/tests/flask/test_oauth2/test_password_grant.py
--- old/authlib-1.6.5/tests/flask/test_oauth2/test_password_grant.py    
2025-10-02 15:31:28.000000000 +0200
+++ new/authlib-1.6.6/tests/flask/test_oauth2/test_password_grant.py    
2025-12-12 08:59:43.000000000 +0100
@@ -26,7 +26,7 @@
 
 
 class IDToken(OpenIDToken):
-    def get_jwt_config(self, grant):
+    def get_jwt_config(self, grant, client):
         return {
             "iss": "Authlib",
             "key": "secret",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/authlib-1.6.5/tests/flask/test_oauth2/test_refresh_token.py 
new/authlib-1.6.6/tests/flask/test_oauth2/test_refresh_token.py
--- old/authlib-1.6.5/tests/flask/test_oauth2/test_refresh_token.py     
2025-10-02 15:31:28.000000000 +0200
+++ new/authlib-1.6.6/tests/flask/test_oauth2/test_refresh_token.py     
2025-12-12 08:59:43.000000000 +0100
@@ -47,23 +47,6 @@
     return client
 
 
[email protected]
-def token(db):
-    token = Token(
-        user_id=1,
-        client_id="client-id",
-        token_type="bearer",
-        access_token="a1",
-        refresh_token="r1",
-        scope="profile",
-        expires_in=3600,
-    )
-    db.session.add(token)
-    db.session.commit()
-    yield token
-    db.session.delete(token)
-
-
 def test_invalid_client(test_client):
     rv = test_client.post(
         "/oauth/token",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/authlib-1.6.5/tests/flask/test_oauth2/test_revocation_endpoint.py 
new/authlib-1.6.6/tests/flask/test_oauth2/test_revocation_endpoint.py
--- old/authlib-1.6.5/tests/flask/test_oauth2/test_revocation_endpoint.py       
2025-10-02 15:31:28.000000000 +0200
+++ new/authlib-1.6.6/tests/flask/test_oauth2/test_revocation_endpoint.py       
2025-12-12 08:59:43.000000000 +0100
@@ -34,23 +34,6 @@
     return client
 
 
[email protected]
-def token(db, user):
-    token = Token(
-        user_id=1,
-        client_id="client-id",
-        token_type="bearer",
-        access_token="a1",
-        refresh_token="r1",
-        scope="profile",
-        expires_in=3600,
-    )
-    db.session.add(token)
-    db.session.commit()
-    yield token
-    db.session.delete(token)
-
-
 def test_invalid_client(test_client):
     rv = test_client.post("/oauth/revoke")
     resp = json.loads(rv.data)

Reply via email to