fix(auth): address PR #758 round-2 review
- oauth_login_callback's integrated-mode token-exchange branch now reuses the shared discovery cache via get_oidc_discovery (round-2 finding 1). - AS proxy flow now generates an OIDC nonce in oauth_authorize, stores it on ASProxySession, forwards it to the IdP, and passes it as expected_nonce to verify_id_token in _oauth_callback_as_proxy (round-2 finding 2). - Consolidate the two parallel discovery caches: oauth_routes' local _discovery_cache and _get_cached_discovery are removed; all callers now go through token_utils.get_oidc_discovery, which acquires the follow_redirects=True knob it needs for Nextcloud installs without pretty URLs (round-2 finding 3). - Demote per-user INFO logs in oauth_tools.py (check_logged_in, get_provisioning_status) to DEBUG; the elicitation auth URL is no longer logged because it contains a sensitive state token (round-2 finding 4). Also pin nonce binding behaviour with a new unit test that asserts _oauth_callback_as_proxy forwards session.nonce to verify_id_token, and update test mocks to track the cache consolidation. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
4c84d82984
commit
c33d52ea91
@@ -15,6 +15,7 @@ import httpx
|
||||
import pytest
|
||||
from cryptography.fernet import Fernet
|
||||
|
||||
from nextcloud_mcp_server.auth import token_utils
|
||||
from nextcloud_mcp_server.auth.browser_oauth_routes import oauth_login_callback
|
||||
from nextcloud_mcp_server.auth.storage import RefreshTokenStorage
|
||||
|
||||
@@ -24,6 +25,14 @@ pytestmark = pytest.mark.unit
|
||||
XSS_PAYLOAD = "<script>alert(1)</script>"
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def _clear_oidc_discovery_cache():
|
||||
"""Reset the shared discovery cache between tests."""
|
||||
token_utils._discovery_cache.clear()
|
||||
yield
|
||||
token_utils._discovery_cache.clear()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
async def storage():
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
@@ -109,9 +118,18 @@ async def test_callback_escapes_idp_http_error_body(storage):
|
||||
},
|
||||
)
|
||||
|
||||
with patch(
|
||||
"nextcloud_mcp_server.auth.browser_oauth_routes.nextcloud_httpx_client",
|
||||
side_effect=fake_client,
|
||||
# Discovery now goes through token_utils.get_oidc_discovery (PR #758
|
||||
# round-2 nit 3); token-exchange POST still uses browser_oauth_routes'
|
||||
# httpx client.
|
||||
with (
|
||||
patch(
|
||||
"nextcloud_mcp_server.auth.browser_oauth_routes.nextcloud_httpx_client",
|
||||
side_effect=fake_client,
|
||||
),
|
||||
patch(
|
||||
"nextcloud_mcp_server.auth.token_utils.nextcloud_httpx_client",
|
||||
side_effect=fake_client,
|
||||
),
|
||||
):
|
||||
response = await oauth_login_callback(request)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user