feat: resolve upstream auth at runtime
This commit is contained in:
+33
-17
@@ -6,6 +6,7 @@ mod session;
|
||||
use std::{env, net::SocketAddr, time::Duration};
|
||||
|
||||
use crank_registry::PostgresRegistry;
|
||||
use crank_runtime::SecretCrypto;
|
||||
use tokio::net::TcpListener;
|
||||
use tracing::info;
|
||||
|
||||
@@ -30,7 +31,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
.unwrap_or_else(|| Duration::from_secs(5));
|
||||
let socket_addr: SocketAddr = bind_addr.parse()?;
|
||||
let registry = PostgresRegistry::connect(&database_url).await?;
|
||||
let app = build_app(registry, refresh_interval, public_base_url);
|
||||
let secret_crypto = SecretCrypto::new(&env::var("CRANK_MASTER_KEY")?)?;
|
||||
let app = build_app(registry, refresh_interval, public_base_url, secret_crypto);
|
||||
let listener = TcpListener::bind(socket_addr).await?;
|
||||
|
||||
info!("mcp-server listening on {}", socket_addr);
|
||||
@@ -68,6 +70,7 @@ mod tests {
|
||||
CreateAgentRequest, CreatePlatformApiKeyRequest, ListInvocationLogsQuery, PostgresRegistry,
|
||||
PublishAgentRequest, PublishRequest,
|
||||
};
|
||||
use crank_runtime::SecretCrypto;
|
||||
use crank_schema::{Schema, SchemaKind};
|
||||
use futures_util::stream;
|
||||
use serde_json::{Value, json};
|
||||
@@ -86,6 +89,19 @@ mod tests {
|
||||
"default"
|
||||
}
|
||||
|
||||
fn build_test_app(
|
||||
registry: PostgresRegistry,
|
||||
refresh_interval: Duration,
|
||||
public_base_url: Option<String>,
|
||||
) -> axum::Router {
|
||||
build_app(
|
||||
registry,
|
||||
refresh_interval,
|
||||
public_base_url,
|
||||
SecretCrypto::new("test-master-key").unwrap(),
|
||||
)
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn initializes_lists_and_calls_published_tool_via_mcp() {
|
||||
let registry = test_registry().await;
|
||||
@@ -114,7 +130,7 @@ mod tests {
|
||||
)
|
||||
.await;
|
||||
|
||||
let base_url = spawn_mcp_server(build_app(
|
||||
let base_url = spawn_mcp_server(build_test_app(
|
||||
registry.clone(),
|
||||
Duration::from_millis(0),
|
||||
Some("https://crank.example.com".to_owned()),
|
||||
@@ -220,7 +236,7 @@ mod tests {
|
||||
)
|
||||
.await;
|
||||
|
||||
let base_url = spawn_mcp_server(build_app(
|
||||
let base_url = spawn_mcp_server(build_test_app(
|
||||
registry,
|
||||
Duration::from_millis(0),
|
||||
Some("https://crank.example.com".to_owned()),
|
||||
@@ -284,7 +300,7 @@ mod tests {
|
||||
)
|
||||
.await;
|
||||
|
||||
let base_url = spawn_mcp_server(build_app(
|
||||
let base_url = spawn_mcp_server(build_test_app(
|
||||
registry,
|
||||
Duration::from_millis(0),
|
||||
Some("https://crank.example.com".to_owned()),
|
||||
@@ -326,7 +342,7 @@ mod tests {
|
||||
publish_agent_with_bindings(®istry, "sales-init", vec![]).await;
|
||||
let api_key =
|
||||
create_platform_api_key(®istry, "mcp-init", &[PlatformApiKeyScope::Read]).await;
|
||||
let base_url = spawn_mcp_server(build_app(
|
||||
let base_url = spawn_mcp_server(build_test_app(
|
||||
registry,
|
||||
Duration::from_millis(0),
|
||||
Some("https://crank.example.com".to_owned()),
|
||||
@@ -388,7 +404,7 @@ mod tests {
|
||||
&[PlatformApiKeyScope::Read, PlatformApiKeyScope::Write],
|
||||
)
|
||||
.await;
|
||||
let base_url = spawn_mcp_server(build_app(
|
||||
let base_url = spawn_mcp_server(build_test_app(
|
||||
registry,
|
||||
Duration::from_millis(0),
|
||||
Some("https://crank.example.com".to_owned()),
|
||||
@@ -438,7 +454,7 @@ mod tests {
|
||||
&[PlatformApiKeyScope::Read, PlatformApiKeyScope::Write],
|
||||
)
|
||||
.await;
|
||||
let base_url = spawn_mcp_server(build_app(
|
||||
let base_url = spawn_mcp_server(build_test_app(
|
||||
registry,
|
||||
Duration::from_millis(0),
|
||||
Some("https://crank.example.com".to_owned()),
|
||||
@@ -489,7 +505,7 @@ mod tests {
|
||||
&[PlatformApiKeyScope::Read],
|
||||
)
|
||||
.await;
|
||||
let base_url = spawn_mcp_server(build_app(
|
||||
let base_url = spawn_mcp_server(build_test_app(
|
||||
registry,
|
||||
Duration::from_millis(0),
|
||||
Some("https://crank.example.com".to_owned()),
|
||||
@@ -518,7 +534,7 @@ mod tests {
|
||||
&[PlatformApiKeyScope::Read],
|
||||
)
|
||||
.await;
|
||||
let base_url = spawn_mcp_server(build_app(
|
||||
let base_url = spawn_mcp_server(build_test_app(
|
||||
registry,
|
||||
Duration::from_millis(0),
|
||||
Some("https://crank.example.com".to_owned()),
|
||||
@@ -562,7 +578,7 @@ mod tests {
|
||||
&[PlatformApiKeyScope::Read],
|
||||
)
|
||||
.await;
|
||||
let base_url = spawn_mcp_server(build_app(
|
||||
let base_url = spawn_mcp_server(build_test_app(
|
||||
registry,
|
||||
Duration::from_millis(0),
|
||||
Some("https://crank.example.com".to_owned()),
|
||||
@@ -589,7 +605,7 @@ mod tests {
|
||||
async fn refreshes_published_tools_without_restart() {
|
||||
let registry = test_registry().await;
|
||||
let upstream_base_url = spawn_upstream_server().await;
|
||||
let base_url = spawn_mcp_server(build_app(
|
||||
let base_url = spawn_mcp_server(build_test_app(
|
||||
registry.clone(),
|
||||
Duration::from_millis(0),
|
||||
Some("https://crank.example.com".to_owned()),
|
||||
@@ -700,7 +716,7 @@ mod tests {
|
||||
)
|
||||
.await;
|
||||
|
||||
let base_url = spawn_mcp_server(build_app(
|
||||
let base_url = spawn_mcp_server(build_test_app(
|
||||
registry,
|
||||
Duration::from_millis(0),
|
||||
Some("https://crank.example.com".to_owned()),
|
||||
@@ -747,7 +763,7 @@ mod tests {
|
||||
async fn rejects_initialize_without_platform_api_key() {
|
||||
let registry = test_registry().await;
|
||||
publish_agent_with_bindings(®istry, "sales-auth", vec![]).await;
|
||||
let base_url = spawn_mcp_server(build_app(
|
||||
let base_url = spawn_mcp_server(build_test_app(
|
||||
registry,
|
||||
Duration::from_millis(0),
|
||||
Some("https://crank.example.com".to_owned()),
|
||||
@@ -796,7 +812,7 @@ mod tests {
|
||||
let api_key =
|
||||
create_platform_api_key(®istry, "mcp-read", &[PlatformApiKeyScope::Read]).await;
|
||||
|
||||
let base_url = spawn_mcp_server(build_app(
|
||||
let base_url = spawn_mcp_server(build_test_app(
|
||||
registry,
|
||||
Duration::from_millis(0),
|
||||
Some("https://crank.example.com".to_owned()),
|
||||
@@ -857,7 +873,7 @@ mod tests {
|
||||
)
|
||||
.await;
|
||||
|
||||
let base_url = spawn_mcp_server(build_app(
|
||||
let base_url = spawn_mcp_server(build_test_app(
|
||||
registry.clone(),
|
||||
Duration::from_millis(0),
|
||||
Some("https://crank.example.com".to_owned()),
|
||||
@@ -1001,7 +1017,7 @@ mod tests {
|
||||
)
|
||||
.await;
|
||||
|
||||
let base_url = spawn_mcp_server(build_app(
|
||||
let base_url = spawn_mcp_server(build_test_app(
|
||||
registry.clone(),
|
||||
Duration::from_millis(0),
|
||||
Some("https://crank.example.com".to_owned()),
|
||||
@@ -1148,7 +1164,7 @@ mod tests {
|
||||
)
|
||||
.await;
|
||||
|
||||
let base_url = spawn_mcp_server(build_app(
|
||||
let base_url = spawn_mcp_server(build_test_app(
|
||||
registry,
|
||||
Duration::from_millis(0),
|
||||
Some("https://crank.example.com".to_owned()),
|
||||
|
||||
Reference in New Issue
Block a user