Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-google-auth-oauthlib for 
openSUSE:Factory checked in at 2026-03-04 21:10:30
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-google-auth-oauthlib (Old)
 and      /work/SRC/openSUSE:Factory/.python-google-auth-oauthlib.new.561 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-google-auth-oauthlib"

Wed Mar  4 21:10:30 2026 rev:22 rq:1336386 version:1.3.0

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-google-auth-oauthlib/python-google-auth-oauthlib.changes
  2026-01-19 18:42:43.909544679 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-google-auth-oauthlib.new.561/python-google-auth-oauthlib.changes
 2026-03-04 21:11:01.814854641 +0100
@@ -1,0 +2,7 @@
+Wed Mar  4 10:00:47 UTC 2026 - John Paul Adrian Glaubitz 
<[email protected]>
+
+- Update to 1.3.0
+  * Log the flow.run_local_server redirect URL (#362)
+  * Raise meaningful exception when oauth callback times out (#363)
+
+-------------------------------------------------------------------

Old:
----
  google_auth_oauthlib-1.2.4.tar.gz

New:
----
  google_auth_oauthlib-1.3.0.tar.gz

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

Other differences:
------------------
++++++ python-google-auth-oauthlib.spec ++++++
--- /var/tmp/diff_new_pack.JQwnSc/_old  2026-03-04 21:11:02.470881551 +0100
+++ /var/tmp/diff_new_pack.JQwnSc/_new  2026-03-04 21:11:02.470881551 +0100
@@ -18,7 +18,7 @@
 
 %{?sle15_python_module_pythons}
 Name:           python-google-auth-oauthlib
-Version:        1.2.4
+Version:        1.3.0
 Release:        0
 Summary:        Google authentication library
 License:        Apache-2.0

++++++ google_auth_oauthlib-1.2.4.tar.gz -> google_auth_oauthlib-1.3.0.tar.gz 
++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/google_auth_oauthlib-1.2.4/PKG-INFO 
new/google_auth_oauthlib-1.3.0/PKG-INFO
--- old/google_auth_oauthlib-1.2.4/PKG-INFO     2026-01-15 22:59:23.335595100 
+0100
+++ new/google_auth_oauthlib-1.3.0/PKG-INFO     2026-02-26 19:44:14.592100000 
+0100
@@ -1,8 +1,8 @@
 Metadata-Version: 2.4
 Name: google-auth-oauthlib
-Version: 1.2.4
+Version: 1.3.0
 Summary: Google Authentication Library
-Home-page: 
https://github.com/GoogleCloudPlatform/google-auth-library-python-oauthlib
+Home-page: 
https://github.com/googleapis/google-cloud-python/tree/main/packages/google-auth-oauthlib
 Author: Google Cloud Platform
 Author-email: [email protected]
 License: Apache 2.0
@@ -50,8 +50,6 @@
 
 This library provides `oauthlib`_ integration with `google-auth`_.
 
-.. |build| image:: 
https://travis-ci.org/googleapis/google-auth-library-python-oauthlib.svg?branch=main
-   :target: 
https://googleapis.dev/python/google-auth-oauthlib/latest/index.html
 .. |pypi| image:: https://img.shields.io/pypi/v/google-auth-oauthlib.svg
    :target: https://pypi.python.org/pypi/google-auth-oauthlib
 
@@ -95,4 +93,4 @@
 
 Apache 2.0 - See `the LICENSE`_ for more information.
 
-.. _the LICENSE: 
https://github.com/googleapis/google-auth-library-python-oauthlib/blob/main/LICENSE
+.. _the LICENSE: 
https://github.com/googleapis/google-cloud-python/blob/main/LICENSE
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/google_auth_oauthlib-1.2.4/README.rst 
new/google_auth_oauthlib-1.3.0/README.rst
--- old/google_auth_oauthlib-1.2.4/README.rst   2026-01-15 22:59:03.000000000 
+0100
+++ new/google_auth_oauthlib-1.3.0/README.rst   2026-02-26 19:42:51.000000000 
+0100
@@ -5,8 +5,6 @@
 
 This library provides `oauthlib`_ integration with `google-auth`_.
 
-.. |build| image:: 
https://travis-ci.org/googleapis/google-auth-library-python-oauthlib.svg?branch=main
-   :target: 
https://googleapis.dev/python/google-auth-oauthlib/latest/index.html
 .. |pypi| image:: https://img.shields.io/pypi/v/google-auth-oauthlib.svg
    :target: https://pypi.python.org/pypi/google-auth-oauthlib
 
@@ -50,4 +48,4 @@
 
 Apache 2.0 - See `the LICENSE`_ for more information.
 
-.. _the LICENSE: 
https://github.com/googleapis/google-auth-library-python-oauthlib/blob/main/LICENSE
+.. _the LICENSE: 
https://github.com/googleapis/google-cloud-python/blob/main/LICENSE
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google_auth_oauthlib-1.2.4/google_auth_oauthlib/flow.py 
new/google_auth_oauthlib-1.3.0/google_auth_oauthlib/flow.py
--- old/google_auth_oauthlib-1.2.4/google_auth_oauthlib/flow.py 2026-01-15 
22:59:03.000000000 +0100
+++ new/google_auth_oauthlib-1.3.0/google_auth_oauthlib/flow.py 2026-02-26 
19:42:51.000000000 +0100
@@ -160,7 +160,7 @@
 
         # these args cannot be passed to requests_oauthlib.OAuth2Session
         code_verifier = kwargs.pop("code_verifier", None)
-        autogenerate_code_verifier = kwargs.pop("autogenerate_code_verifier", 
None)
+        autogenerate_code_verifier = kwargs.pop("autogenerate_code_verifier", 
True)
 
         (
             session,
@@ -237,7 +237,7 @@
                 specify the ``state`` when constructing the :class:`Flow`.
         """
         kwargs.setdefault("access_type", "offline")
-        if self.autogenerate_code_verifier:
+        if self.code_verifier is None and self.autogenerate_code_verifier:
             chars = ascii_letters + digits + "-._~"
             rnd = SystemRandom()
             random_verifier = [rnd.choice(chars) for _ in range(0, 128)]
@@ -410,8 +410,9 @@
                 in the user's browser.
             redirect_uri_trailing_slash (bool): whether or not to add trailing
                 slash when constructing the redirect_uri. Default value is 
True.
-            timeout_seconds (int): It will raise an error after the timeout 
timing
-                if there are no credentials response. The value is in seconds.
+            timeout_seconds (int): It will raise a WSGITimeoutError exception 
after the
+                timeout timing if there are no credentials response. The value 
is in
+                seconds.
                 When set to None there is no timeout.
                 Default value is None.
             token_audience (str): Passed along with the request for an access
@@ -425,6 +426,10 @@
         Returns:
             google.oauth2.credentials.Credentials: The OAuth 2.0 credentials
                 for the user.
+
+        Raises:
+            WSGITimeoutError: If there is a timeout when waiting for the 
response from the
+                authorization server.
         """
         wsgi_app = _RedirectWSGIApp(success_message)
         # Fail fast if the address is occupied
@@ -447,6 +452,7 @@
                 webbrowser.get(browser).open(auth_url, new=1, autoraise=True)
 
             if authorization_prompt_message:
+                _LOGGER.info(authorization_prompt_message.format(url=auth_url))
                 print(authorization_prompt_message.format(url=auth_url))
 
             local_server.timeout = timeout_seconds
@@ -454,7 +460,15 @@
 
             # Note: using https here because oauthlib is very picky that
             # OAuth 2.0 should only occur over https.
-            authorization_response = wsgi_app.last_request_uri.replace("http", 
"https")
+            try:
+                authorization_response = wsgi_app.last_request_uri.replace(
+                    "http", "https"
+                )
+            except AttributeError as e:
+                raise WSGITimeoutError(
+                    "Timed out waiting for response from authorization server"
+                ) from e
+
             self.fetch_token(
                 authorization_response=authorization_response, 
audience=token_audience
             )
@@ -505,3 +519,7 @@
         start_response("200 OK", [("Content-type", "text/plain; 
charset=utf-8")])
         self.last_request_uri = wsgiref.util.request_uri(environ)
         return [self._success_message.encode("utf-8")]
+
+
+class WSGITimeoutError(AttributeError):
+    """Raised when the WSGI server times out waiting for a response."""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google_auth_oauthlib-1.2.4/google_auth_oauthlib.egg-info/PKG-INFO 
new/google_auth_oauthlib-1.3.0/google_auth_oauthlib.egg-info/PKG-INFO
--- old/google_auth_oauthlib-1.2.4/google_auth_oauthlib.egg-info/PKG-INFO       
2026-01-15 22:59:23.000000000 +0100
+++ new/google_auth_oauthlib-1.3.0/google_auth_oauthlib.egg-info/PKG-INFO       
2026-02-26 19:44:14.000000000 +0100
@@ -1,8 +1,8 @@
 Metadata-Version: 2.4
 Name: google-auth-oauthlib
-Version: 1.2.4
+Version: 1.3.0
 Summary: Google Authentication Library
-Home-page: 
https://github.com/GoogleCloudPlatform/google-auth-library-python-oauthlib
+Home-page: 
https://github.com/googleapis/google-cloud-python/tree/main/packages/google-auth-oauthlib
 Author: Google Cloud Platform
 Author-email: [email protected]
 License: Apache 2.0
@@ -50,8 +50,6 @@
 
 This library provides `oauthlib`_ integration with `google-auth`_.
 
-.. |build| image:: 
https://travis-ci.org/googleapis/google-auth-library-python-oauthlib.svg?branch=main
-   :target: 
https://googleapis.dev/python/google-auth-oauthlib/latest/index.html
 .. |pypi| image:: https://img.shields.io/pypi/v/google-auth-oauthlib.svg
    :target: https://pypi.python.org/pypi/google-auth-oauthlib
 
@@ -95,4 +93,4 @@
 
 Apache 2.0 - See `the LICENSE`_ for more information.
 
-.. _the LICENSE: 
https://github.com/googleapis/google-auth-library-python-oauthlib/blob/main/LICENSE
+.. _the LICENSE: 
https://github.com/googleapis/google-cloud-python/blob/main/LICENSE
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/google_auth_oauthlib-1.2.4/setup.py 
new/google_auth_oauthlib-1.3.0/setup.py
--- old/google_auth_oauthlib-1.2.4/setup.py     2026-01-15 22:59:03.000000000 
+0100
+++ new/google_auth_oauthlib-1.3.0/setup.py     2026-02-26 19:42:50.000000000 
+0100
@@ -32,7 +32,7 @@
     long_description = fh.read()
 
 
-version = "1.2.4"
+version = "1.3.0"
 
 setup(
     name="google-auth-oauthlib",
@@ -41,7 +41,7 @@
     author_email="[email protected]",
     description="Google Authentication Library",
     long_description=long_description,
-    
url="https://github.com/GoogleCloudPlatform/google-auth-library-python-oauthlib";,
+    
url="https://github.com/googleapis/google-cloud-python/tree/main/packages/google-auth-oauthlib";,
     packages=find_namespace_packages(
         exclude=(
             "docs*",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/google_auth_oauthlib-1.2.4/tests/unit/test_flow.py 
new/google_auth_oauthlib-1.3.0/tests/unit/test_flow.py
--- old/google_auth_oauthlib-1.2.4/tests/unit/test_flow.py      2026-01-15 
22:59:03.000000000 +0100
+++ new/google_auth_oauthlib-1.3.0/tests/unit/test_flow.py      2026-02-26 
19:42:50.000000000 +0100
@@ -16,6 +16,7 @@
 import datetime
 from functools import partial
 import json
+import logging
 import os
 import re
 import socket
@@ -34,6 +35,9 @@
 with open(CLIENT_SECRETS_FILE, "r") as fh:
     CLIENT_SECRETS_INFO = json.load(fh)
 
+VALID_PKCE_VERIFIER_REGEX = r"^[A-Za-z0-9-._~]{128}$"
+VALID_CODE_CHALLENGE_REGEX = r"^[A-Za-z0-9-_]{43}$"
+
 
 class TestFlow(object):
     def test_from_client_secrets_file(self):
@@ -114,10 +118,14 @@
 
             assert CLIENT_SECRETS_INFO["web"]["auth_uri"] in url
             assert scope in url
+            assert "code_challenge=" in url
+            assert "code_challenge_method=S256" in url
             authorization_url_spy.assert_called_with(
                 CLIENT_SECRETS_INFO["web"]["auth_uri"],
                 access_type="offline",
                 prompt="consent",
+                code_challenge=mock.ANY,
+                code_challenge_method="S256",
             )
 
     def test_authorization_url_code_verifier(self, instance):
@@ -183,10 +191,8 @@
             assert kwargs["code_challenge_method"] == "S256"
             assert len(instance.code_verifier) == 128
             assert len(kwargs["code_challenge"]) == 43
-            valid_verifier = r"^[A-Za-z0-9-._~]*$"
-            valid_challenge = r"^[A-Za-z0-9-_]*$"
-            assert re.match(valid_verifier, instance.code_verifier)
-            assert re.match(valid_challenge, kwargs["code_challenge"])
+            assert re.fullmatch(VALID_PKCE_VERIFIER_REGEX, 
instance.code_verifier)
+            assert re.fullmatch(VALID_CODE_CHALLENGE_REGEX, 
kwargs["code_challenge"])
 
     def test_fetch_token(self, instance):
         instance.code_verifier = "amanaplanacanalpanama"
@@ -263,6 +269,7 @@
     @pytest.fixture
     def socket(self, port):
         s = socket.socket()
+        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)  # Enable 
SO_REUSEADDR
         s.bind(("localhost", port))
         yield s
         s.close()
@@ -307,13 +314,13 @@
         assert credentials.id_token == mock.sentinel.id_token
         assert webbrowser_mock.get().open.called
         assert instance.redirect_uri == f"http://localhost:{port}/";
-
+        assert re.fullmatch(VALID_PKCE_VERIFIER_REGEX, instance.code_verifier)
         expected_auth_response = auth_redirect_url.replace("http", "https")
         mock_fetch_token.assert_called_with(
             CLIENT_SECRETS_INFO["web"]["token_uri"],
             client_secret=CLIENT_SECRETS_INFO["web"]["client_secret"],
             authorization_response=expected_auth_response,
-            code_verifier=None,
+            code_verifier=mock.ANY,
             audience=None,
         )
 
@@ -352,7 +359,7 @@
             CLIENT_SECRETS_INFO["web"]["token_uri"],
             client_secret=CLIENT_SECRETS_INFO["web"]["client_secret"],
             authorization_response=expected_auth_response,
-            code_verifier=None,
+            code_verifier=mock.ANY,
             audience=self.AUDIENCE,
         )
 
@@ -455,3 +462,55 @@
             instance.run_local_server()
 
         server_mock.server_close.assert_called_once()
+
+    @mock.patch("builtins.print")
+    @mock.patch("google_auth_oauthlib.flow.webbrowser", autospec=True)
+    def test_run_local_server_logs_and_prints_url(
+        self, webbrowser_mock, print_mock, instance, mock_fetch_token, port, 
caplog
+    ):
+        auth_redirect_url = urllib.parse.urljoin(
+            f"http://localhost:{port}";, self.REDIRECT_REQUEST_PATH
+        )
+
+        # Configure caplog to capture INFO logs
+        caplog.set_level(logging.INFO, logger="google_auth_oauthlib.flow")
+
+        with concurrent.futures.ThreadPoolExecutor(max_workers=1) as pool:
+            future = pool.submit(partial(instance.run_local_server, port=port))
+
+            while not future.done():
+                try:
+                    requests.get(auth_redirect_url)
+                except requests.ConnectionError:
+                    pass
+
+            future.result()
+
+        # Verify log message
+        assert "Please visit this URL" in caplog.text
+        assert urllib.parse.quote(instance.redirect_uri, safe="") in 
caplog.text
+
+        # Verify print message
+        print_mock.assert_called_once()
+        assert "Please visit this URL" in print_mock.call_args[0][0]
+        assert (
+            urllib.parse.quote(instance.redirect_uri, safe="")
+            in print_mock.call_args[0][0]
+        )
+
+    @mock.patch("google_auth_oauthlib.flow.webbrowser", autospec=True)
+    @mock.patch("wsgiref.simple_server.make_server", autospec=True)
+    def test_run_local_server_timeout(
+        self, make_server_mock, webbrowser_mock, instance, mock_fetch_token
+    ):
+        mock_server = mock.Mock()
+        make_server_mock.return_value = mock_server
+
+        # handle_request does nothing (simulating timeout), so 
last_request_uri remains None
+        mock_server.handle_request.return_value = None
+
+        with pytest.raises(flow.WSGITimeoutError):
+            instance.run_local_server(timeout_seconds=1)
+
+        webbrowser_mock.get.assert_called_with(None)
+        webbrowser_mock.get.return_value.open.assert_called_once()

Reply via email to