v2.17.0 (#822)
Co-authored-by: Clément Sirieix <clement.sirieix@mistral.ai> Co-authored-by: Guillaume LE GOFF <guillaume.lgf@gmail.com> Co-authored-by: Hdandria <henri.dandria@mistral.ai> Co-authored-by: Ivana Dunisijevic <ivana.dunisijevic@mistral.ai> Co-authored-by: Jean Burellier <sheplu@users.noreply.github.com> Co-authored-by: Mathias Gesbert <mathias.gesbert@mistral.ai> Co-authored-by: Mert Unsal <mert.unsal@mistral.ai> Co-authored-by: Michel Thomazo <51709227+michelTho@users.noreply.github.com> Co-authored-by: Paul VEZIA <166131032+le-codeur-rapide@users.noreply.github.com> Co-authored-by: Pierre Rossinès <pierre.rossines@mistral.ai> Co-authored-by: Val <102326092+vdeva@users.noreply.github.com> Co-authored-by: Vincent G <10739306+VinceOPS@users.noreply.github.com> Co-authored-by: renovate-mistral[bot] <253709520+renovate-mistral[bot]@users.noreply.github.com> Co-authored-by: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
parent
564a14365e
commit
6bedf271ce
223 changed files with 10533 additions and 6947 deletions
|
|
@ -4,6 +4,8 @@ import asyncio
|
|||
from collections.abc import Callable, Iterator
|
||||
from contextlib import suppress
|
||||
import socket
|
||||
from types import TracebackType
|
||||
from unittest.mock import patch
|
||||
import urllib.parse
|
||||
|
||||
import httpx
|
||||
|
|
@ -11,6 +13,7 @@ import keyring
|
|||
from keyring.backend import KeyringBackend
|
||||
import keyring.backends.fail
|
||||
import keyring.errors
|
||||
from mcp.client.auth import OAuthFlowError
|
||||
from mcp.shared.auth import OAuthClientInformationFull, OAuthToken
|
||||
import pytest
|
||||
import respx
|
||||
|
|
@ -21,6 +24,7 @@ from vibe.core.auth.mcp_oauth import (
|
|||
LoopbackCallbackHandler,
|
||||
MCPOAuthError,
|
||||
MCPOAuthHeadlessError,
|
||||
MCPOAuthLoginFailed,
|
||||
MCPOAuthPortInUse,
|
||||
build_oauth_provider,
|
||||
perform_oauth_login,
|
||||
|
|
@ -366,6 +370,26 @@ class TestBuildOAuthProvider:
|
|||
)
|
||||
assert provider.context.client_metadata_url == "https://vibe.example/cm.json"
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_client_id_is_exposed_as_fallback_client_info(
|
||||
self, memory_keyring: _MemoryKeyring
|
||||
) -> None:
|
||||
srv = _oauth_server(client_id="pre-registered-client")
|
||||
|
||||
async def on_url(_url: str) -> None:
|
||||
return None
|
||||
|
||||
async def cb() -> tuple[str, str | None]:
|
||||
return "code", None
|
||||
|
||||
provider = build_oauth_provider(
|
||||
srv, redirect_handler=on_url, callback_handler=cb
|
||||
)
|
||||
client_info = await provider.context.storage.get_client_info()
|
||||
|
||||
assert client_info is not None
|
||||
assert client_info.client_id == "pre-registered-client"
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_rejects_static_auth(self, memory_keyring: _MemoryKeyring) -> None:
|
||||
from vibe.core.config import MCPStaticAuth
|
||||
|
|
@ -388,6 +412,39 @@ class TestBuildOAuthProvider:
|
|||
|
||||
|
||||
class TestPerformOAuthLogin:
|
||||
@pytest.mark.asyncio
|
||||
async def test_oauth_flow_error_becomes_login_failed(
|
||||
self, memory_keyring: _MemoryKeyring
|
||||
) -> None:
|
||||
srv = _oauth_server(name="demo")
|
||||
|
||||
class OAuthFlowFailingClient:
|
||||
def __init__(self, *args: object, **kwargs: object) -> None:
|
||||
pass
|
||||
|
||||
async def __aenter__(self) -> OAuthFlowFailingClient:
|
||||
return self
|
||||
|
||||
async def __aexit__(
|
||||
self,
|
||||
exc_type: type[BaseException] | None,
|
||||
exc: BaseException | None,
|
||||
traceback: TracebackType | None,
|
||||
) -> None:
|
||||
pass
|
||||
|
||||
async def get(self, _url: str) -> None:
|
||||
raise OAuthFlowError("cancelled")
|
||||
|
||||
async def on_url(_url: str) -> None:
|
||||
pass
|
||||
|
||||
with patch(
|
||||
"vibe.core.auth.mcp_oauth.httpx.AsyncClient", new=OAuthFlowFailingClient
|
||||
):
|
||||
with pytest.raises(MCPOAuthLoginFailed, match="cancelled"):
|
||||
await perform_oauth_login(srv, on_url=on_url)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_full_flow_persists_tokens_and_fingerprint(
|
||||
self, memory_keyring: _MemoryKeyring
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue