feat(multi-tenant): resolve per-caller credentials in every tool
All 20 tools now drop the athlete_id/api_key parameters and instead resolve the authenticated caller's stored, enabled credentials via credentials.resolve_caller_credentials() (get_access_token().subject -> store). Security: there is no tool parameter a caller can pass to supply a key, so a disabled/unapproved user cannot bypass the admin-approval gate — each tool returns a helpful "not approved / set up your credentials" message instead. Gear resolution now uses the caller's athlete id rather than an env var. Tests: conftest autouse fixture runs tool tests as an enabled user; a parametrized test asserts every tool refuses when unauthorized; existing tool tests updated (no more athlete_id/api_key kwargs). 221 passing at 91.5%. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
"""Shared test fixtures."""
|
||||
|
||||
import pytest
|
||||
|
||||
from intervals_mcp_server import credentials
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def _default_caller_credentials(monkeypatch):
|
||||
"""Run tool tests as an enabled user with fixed credentials.
|
||||
|
||||
Tools resolve the caller via ``credentials.resolve_caller_credentials()``;
|
||||
patching the module attribute covers every tool at once. A test can override
|
||||
this (e.g. patch it to raise ``CredentialError``) to exercise the not-approved
|
||||
path. Tests that exercise the resolver itself import the function directly and
|
||||
are unaffected.
|
||||
"""
|
||||
|
||||
async def _creds():
|
||||
return ("i1", "testkey")
|
||||
|
||||
monkeypatch.setattr(credentials, "resolve_caller_credentials", _creds)
|
||||
Reference in New Issue
Block a user