feat(mcp): câble le garde /_mcp + exemption CSRF dans l'app (scope B #111)
This commit is contained in:
+13
@@ -124,6 +124,19 @@ if _mcp_enabled:
|
|||||||
)
|
)
|
||||||
import src.mcp.tools # noqa: E402,F401 # l'import enregistre les @mcp_enabled
|
import src.mcp.tools # noqa: E402,F401 # l'import enregistre les @mcp_enabled
|
||||||
|
|
||||||
|
# Les routes /_mcp existent maintenant : exempter du CSRF (POST JSON-RPC
|
||||||
|
# externe sans jeton) puis brancher le garde d'abonnement.
|
||||||
|
from src.mcp.auth import init_mcp_auth # noqa: E402
|
||||||
|
|
||||||
|
if _auth_csrf is not None:
|
||||||
|
for _rule in app.server.url_map.iter_rules():
|
||||||
|
if _rule.rule.startswith("/_mcp"):
|
||||||
|
_vf = app.server.view_functions.get(_rule.endpoint)
|
||||||
|
if _vf is not None:
|
||||||
|
_auth_csrf.exempt(_vf)
|
||||||
|
|
||||||
|
init_mcp_auth(app.server)
|
||||||
|
|
||||||
from src.subscriptions.setup import init_subscriptions # noqa: E402
|
from src.subscriptions.setup import init_subscriptions # noqa: E402
|
||||||
|
|
||||||
init_subscriptions(app.server)
|
init_subscriptions(app.server)
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import importlib
|
||||||
|
|
||||||
|
|
||||||
|
def test_mcp_endpoint_guarded_and_csrf_exempt(monkeypatch, tmp_path):
|
||||||
|
# DB éphémère + secrets requis par init_auth/init_subscriptions.
|
||||||
|
monkeypatch.setenv("USERS_DB_PATH", str(tmp_path / "users.test.sqlite"))
|
||||||
|
monkeypatch.setenv("SECRET_KEY", "test-secret-key")
|
||||||
|
monkeypatch.setenv("APP_BASE_URL", "http://localhost:8050")
|
||||||
|
monkeypatch.setenv("DASH_MCP_ENABLED", "true")
|
||||||
|
|
||||||
|
from src.auth import db as auth_db
|
||||||
|
|
||||||
|
auth_db.reset_conn_for_tests()
|
||||||
|
|
||||||
|
import src.app as app_module
|
||||||
|
|
||||||
|
app_module = importlib.reload(app_module)
|
||||||
|
client = app_module.app.server.test_client()
|
||||||
|
|
||||||
|
# Pas de jeton : le garde renvoie 401 (et NON une erreur CSRF 400/403),
|
||||||
|
# ce qui prouve exemption CSRF + garde câblés sur /_mcp.
|
||||||
|
resp = client.post("/_mcp", json={"jsonrpc": "2.0", "method": "ping", "id": 1})
|
||||||
|
assert resp.status_code == 401
|
||||||
|
assert resp.headers.get("WWW-Authenticate") == 'Bearer realm="colibre-mcp"'
|
||||||
|
|
||||||
|
auth_db.reset_conn_for_tests()
|
||||||
Reference in New Issue
Block a user