From 3c3d82a9d9d7856dfae7ff83541dde2ba5655cf2 Mon Sep 17 00:00:00 2001 From: Kos Perun Date: Tue, 11 Jun 2024 16:59:57 -0400 Subject: [PATCH 1/6] Fix: Ensure autogenerate_code_verifier defaults to True in from_client_config --- google_auth_oauthlib/flow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/google_auth_oauthlib/flow.py b/google_auth_oauthlib/flow.py index e564ca4..143c80f 100644 --- a/google_auth_oauthlib/flow.py +++ b/google_auth_oauthlib/flow.py @@ -160,7 +160,7 @@ def from_client_config(cls, client_config, scopes, **kwargs): # 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, From 8e8ef2736abaacc8dfef9639d27e0ddbe43f0911 Mon Sep 17 00:00:00 2001 From: Kos Perun Date: Tue, 11 Jun 2024 17:51:32 -0400 Subject: [PATCH 2/6] Fix: Ensure autogenerate_code_verifier defaults to True in from_client_config --- google_auth_oauthlib/flow.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/google_auth_oauthlib/flow.py b/google_auth_oauthlib/flow.py index 143c80f..7714524 100644 --- a/google_auth_oauthlib/flow.py +++ b/google_auth_oauthlib/flow.py @@ -160,7 +160,9 @@ def from_client_config(cls, client_config, scopes, **kwargs): # these args cannot be passed to requests_oauthlib.OAuth2Session code_verifier = kwargs.pop("code_verifier", None) - autogenerate_code_verifier = kwargs.pop("autogenerate_code_verifier", True) + autogenerate_code_verifier = kwargs.pop("autogenerate_code_verifier", None) + if not code_verifier and autogenerate_code_verifier is None: + autogenerate_code_verifier = True ( session, From 0883284633e7e8adde34ef83d569bdfb5f00e513 Mon Sep 17 00:00:00 2001 From: Kostiantyn Perun Date: Fri, 28 Jun 2024 20:01:03 -0400 Subject: [PATCH 3/6] Move checks for code_verifier --- google_auth_oauthlib/flow.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/google_auth_oauthlib/flow.py b/google_auth_oauthlib/flow.py index e564ca4..76a8780 100644 --- a/google_auth_oauthlib/flow.py +++ b/google_auth_oauthlib/flow.py @@ -160,7 +160,7 @@ def from_client_config(cls, client_config, scopes, **kwargs): # 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 @@ def authorization_url(self, **kwargs): 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)] From c8f36cdd3dace8eca379a2270d316f277954b268 Mon Sep 17 00:00:00 2001 From: Kostiantyn Perun Date: Fri, 28 Jun 2024 20:12:03 -0400 Subject: [PATCH 4/6] Move checks for code_verifier --- google_auth_oauthlib/flow.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/google_auth_oauthlib/flow.py b/google_auth_oauthlib/flow.py index 7714524..76a8780 100644 --- a/google_auth_oauthlib/flow.py +++ b/google_auth_oauthlib/flow.py @@ -160,9 +160,7 @@ def from_client_config(cls, client_config, scopes, **kwargs): # 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) - if not code_verifier and autogenerate_code_verifier is None: - autogenerate_code_verifier = True + autogenerate_code_verifier = kwargs.pop("autogenerate_code_verifier", True) ( session, @@ -239,7 +237,7 @@ def authorization_url(self, **kwargs): 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)] From ec7fddcb349bdf9631e817b5422e84f5d6ef5f27 Mon Sep 17 00:00:00 2001 From: Kostiantyn Perun Date: Sun, 13 Oct 2024 19:42:12 -0400 Subject: [PATCH 5/6] Fix tests to account for code auto-generation --- tests/unit/test_flow.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/tests/unit/test_flow.py b/tests/unit/test_flow.py index a3314d1..63fa9c5 100644 --- a/tests/unit/test_flow.py +++ b/tests/unit/test_flow.py @@ -115,10 +115,14 @@ def test_authorization_url(self, instance): 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): @@ -184,10 +188,10 @@ def test_authorization_url_generated_verifier(self): 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"]) + valid_verifier = r"^[A-Za-z0-9-._~]{128}$" + valid_challenge = r"^[A-Za-z0-9-._~]{43}$" + assert re.fullmatch(valid_verifier, instance.code_verifier) + assert re.fullmatch(valid_challenge, kwargs["code_challenge"]) def test_fetch_token(self, instance): instance.code_verifier = "amanaplanacanalpanama" @@ -307,13 +311,15 @@ def test_run_local_server(self, webbrowser_mock, instance, mock_fetch_token, por assert credentials.id_token == mock.sentinel.id_token assert webbrowser_mock.get().open.called assert instance.redirect_uri == f"http://localhost:{port}/" + valid_verifier = r"^[A-Za-z0-9-._~]{128}$" + assert re.fullmatch(valid_verifier, 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 +358,7 @@ def test_run_local_server_audience( 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, ) From da532f46352c9fbc9451808e89eb9595a19a6d77 Mon Sep 17 00:00:00 2001 From: Kostiantyn Perun Date: Sun, 13 Oct 2024 20:08:44 -0400 Subject: [PATCH 6/6] Remove invalid chars from regex --- tests/unit/test_flow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/test_flow.py b/tests/unit/test_flow.py index 63fa9c5..c305b6e 100644 --- a/tests/unit/test_flow.py +++ b/tests/unit/test_flow.py @@ -189,7 +189,7 @@ def test_authorization_url_generated_verifier(self): assert len(instance.code_verifier) == 128 assert len(kwargs["code_challenge"]) == 43 valid_verifier = r"^[A-Za-z0-9-._~]{128}$" - valid_challenge = r"^[A-Za-z0-9-._~]{43}$" + valid_challenge = r"^[A-Za-z0-9-_]{43}$" assert re.fullmatch(valid_verifier, instance.code_verifier) assert re.fullmatch(valid_challenge, kwargs["code_challenge"])