Files
optimclaw/tests/e2e/scenarios/test_oauth_credential_fallback.py
T
Nick PismenkovandGitHub 1770663279 fix: Google Sheets returns 403 PERMISSION_DENIED after completing OAuth (#1164)
* fix: Google Sheets returns 403 PERMISSION_DENIED after completing OAuth

* fix: linter

* fix: linter

* fix: ci

* fix

* fix

* fix

* fix
2026-03-14 12:01:47 -07:00

111 lines
4.5 KiB
Python

"""OAuth credential fallback e2e tests.
Tests that OAuth tokens stored globally under 'default' user are properly
injected when WASM tools make HTTP requests. This validates the fix for:
https://github.com/nearai/ironclaw/issues/999
Note: Full routine execution testing is limited because routines are disabled
in the e2e test environment (ROUTINES_ENABLED=false in conftest.py). This test
validates the OAuth + credential injection flow at the REST API level.
Unit tests in src/tools/wasm/wrapper.rs provide additional coverage of the
fallback mechanism itself.
"""
from helpers import api_post, api_get
import pytest
async def test_oauth_credential_injection_after_gmail_auth(ironclaw_server):
"""Verify that after OAuth, tool HTTP requests include credentials.
This is an indirect test: we verify that gmail shows as authenticated
and that its tools are registered. A full e2e test would require:
1. Enabling ROUTINES_ENABLED=true in conftest.py
2. Creating a routine that calls a WASM tool with OAuth
3. Triggering the routine and verifying the request succeeded
The unit tests in src/tools/wasm/wrapper.rs validate the credential
fallback mechanism (trying 'default' user when user-specific lookup fails).
"""
# First, ensure gmail is installed and authenticated
# (Reuse from test_extension_oauth.py if running in sequence)
r = await api_get(ironclaw_server, "/api/extensions")
extensions = r.json().get("extensions", [])
gmail = next((ext for ext in extensions if ext["name"] == "gmail"), None)
if gmail is None:
# Install gmail
r = await api_post(
ironclaw_server,
"/api/extensions/install",
json={"name": "gmail"},
timeout=180,
)
assert r.status_code == 200, f"Failed to install gmail: {r.text}"
# Verify gmail is authenticated (it should be if oauth flow completed)
r = await api_get(ironclaw_server, "/api/extensions")
extensions = r.json().get("extensions", [])
gmail = next((ext for ext in extensions if ext["name"] == "gmail"), None)
assert gmail is not None, "gmail not found in extensions"
# Authenticated tools should have credentials available for injection
if gmail.get("authenticated"):
tools = gmail.get("tools", [])
assert (
len(tools) > 0
), f"Authenticated gmail should have tools registered: {gmail}"
# Tools should be callable (which requires credential injection)
# In a full e2e with routines enabled, we would:
# 1. Call a gmail tool from a routine
# 2. Verify the HTTP request included the OAuth token
# 3. Verify no 403 "unregistered callers" error
async def test_tool_registry_lists_authenticated_extensions(ironclaw_server):
"""Verify authenticated extensions' tools are registered in tool registry.
Tools from authenticated extensions should have credentials pre-injected
before HTTP requests are made. This validates the end of the injection
pipeline (credential resolution -> WASM execution -> HTTP request).
"""
# Get extensions list
r = await api_get(ironclaw_server, "/api/extensions")
extensions = r.json().get("extensions", [])
# Authenticated extensions should appear
authenticated = [ext for ext in extensions if ext.get("authenticated")]
# At minimum, verify the endpoint works and structure is correct
for ext in authenticated:
assert "name" in ext
assert "tools" in ext
assert isinstance(ext["tools"], list)
async def test_credential_fallback_documented_in_code(ironclaw_server):
"""Verify the credential fallback fix is present.
This is a documentation test that the bug fix for issue #999 is
actually in the code. The real validation happens in unit tests:
- test_resolve_host_credentials_fallback_to_default_user
- test_resolve_host_credentials_prefers_user_specific_over_default
- test_resolve_host_credentials_no_fallback_when_already_default
If these unit tests pass, the fix is working correctly.
"""
# This test serves as a reminder that:
# 1. OAuth tokens are stored globally under user_id="default"
# 2. When routines execute, they use routine.user_id (not "default")
# 3. The fix adds credential fallback: try user_id first, then "default"
# 4. This allows global OAuth tokens to be used in routine contexts
# No specific assertion needed — presence of this test file documents
# the fix. Actual validation is in unit tests.
assert True