mirror of
https://github.com/outbackdingo/optimclaw.git
synced 2026-08-25 14:53:34 +00:00
* fix: Google Sheets returns 403 PERMISSION_DENIED after completing OAuth * fix: linter * fix: linter * fix: ci * fix * fix * fix * fix
111 lines
4.5 KiB
Python
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
|