Skip to content

Commit ac99770

Browse files
RaghunandanKumarGWeale
authored andcommitted
fix(auth): allow configuring OAuth prompt parameter
Merge #5818 Closes #3046 ## Summary `AuthHandler.generate_auth_uri()` currently hardcodes `prompt=consent` when building OAuth authorization URLs. That makes app-level OAuth configuration less flexible than the underlying providers allow. Flows that need `prompt=none` (or another prompt mode) cannot express that through `OAuth2Auth`, even though the rest of the OAuth request metadata is already configurable. This change adds an optional `prompt` field to `OAuth2Auth`, preserves `consent` as the default, and uses the configured value when generating the authorization URL. ## Changes - `src/google/adk/auth/auth_credential.py` - Add optional `prompt` field to `OAuth2Auth`. - `src/google/adk/auth/auth_handler.py` - Use `auth_credential.oauth2.prompt or "consent"` when populating OAuth authorization params. - `tests/unittests/auth/test_auth_handler.py` - Extend the OAuth session test double to surface `prompt` in generated auth URIs. - Assert the default OAuth flow still includes `prompt=consent`. - Add coverage for a custom `prompt="none"` override. ## Test plan - [x] `python3.12 -m py_compile src/google/adk/auth/auth_credential.py src/google/adk/auth/auth_handler.py tests/unittests/auth/test_auth_handler.py` - [ ] `PYTHONPATH=src .venv/bin/python -m pytest tests/unittests/auth/test_auth_handler.py -q` - Blocked locally while bootstrapping a minimal ad hoc venv: importing `google.adk` for this test path pulls additional runtime dependencies (`google.genai`, `opentelemetry.semconv`, and friends). I stopped after confirming the touched files compile cleanly rather than trying to recreate the repo's full `uv sync --all-extras` environment by hand. - [ ] Reviewer / CI confirmation that the existing auth handler unit suite passes in the standard repo environment. Co-authored-by: George Weale <gweale@google.com> COPYBARA_INTEGRATE_REVIEW=#5818 from RaghunandanKumar:fix/oauth-prompt-configurable 727e2e5 PiperOrigin-RevId: 943553106
1 parent a721c1e commit ac99770

3 files changed

Lines changed: 24 additions & 2 deletions

File tree

src/google/adk/auth/auth_credential.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ class OAuth2Auth(BaseModelWithConfig):
8787
expires_at: int | None = None
8888
expires_in: int | None = None
8989
audience: str | None = None
90+
prompt: str | None = None
9091
code_verifier: str | None = None
9192
code_challenge_method: str | None = None
9293
token_endpoint_auth_method: (

src/google/adk/auth/auth_handler.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ def generate_auth_uri(
211211
)
212212
params = {
213213
"access_type": "offline",
214-
"prompt": "consent",
214+
"prompt": auth_credential.oauth2.prompt or "consent",
215215
}
216216
if auth_credential.oauth2.audience:
217217
params["audience"] = auth_credential.oauth2.audience

tests/unittests/auth/test_auth_handler.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ def create_authorization_url(self, url, **kwargs):
6767
params = f"client_id={self.client_id}&scope={self.scope}"
6868
if kwargs.get("audience"):
6969
params += f"&audience={kwargs.get('audience')}"
70+
if kwargs.get("prompt"):
71+
params += f"&prompt={kwargs.get('prompt')}"
7072
return f"{url}?{params}", "mock_state"
7173

7274
def fetch_token(
@@ -251,6 +253,25 @@ def test_generate_auth_uri_with_audience_and_prompt(
251253
result = handler.generate_auth_uri()
252254

253255
assert "audience=test_audience" in result.oauth2.auth_uri
256+
assert "prompt=consent" in result.oauth2.auth_uri
257+
258+
@patch("google.adk.auth.auth_handler.OAuth2Session", MockOAuth2Session)
259+
def test_generate_auth_uri_with_custom_prompt(
260+
self, openid_auth_scheme, oauth2_credentials
261+
):
262+
"""Test generating an auth URI with a custom prompt override."""
263+
oauth2_credentials.oauth2.prompt = "none"
264+
exchanged = oauth2_credentials.model_copy(deep=True)
265+
266+
config = AuthConfig(
267+
auth_scheme=openid_auth_scheme,
268+
raw_auth_credential=oauth2_credentials,
269+
exchanged_auth_credential=exchanged,
270+
)
271+
handler = AuthHandler(config)
272+
result = handler.generate_auth_uri()
273+
274+
assert "prompt=none" in result.oauth2.auth_uri
254275

255276
@patch("google.adk.auth.auth_handler.OAuth2Session", MockOAuth2Session)
256277
def test_generate_auth_uri_openid(
@@ -299,7 +320,7 @@ def test_generate_auth_uri_client_credentials_with_missing_scopes(
299320

300321
assert (
301322
result.oauth2.auth_uri
302-
== "https://example.com/oauth2/token?client_id=mock_client_id&scope="
323+
== "https://example.com/oauth2/token?client_id=mock_client_id&scope=&prompt=consent"
303324
)
304325
assert result.oauth2.state == "mock_state"
305326

0 commit comments

Comments
 (0)