(&self, server_name: &str)
| 308 | } |
| 309 | |
| 310 | pub async fn start_oauth(&self, server_name: &str) -> Result<McpOAuthState, McpOAuthError> { |
| 311 | let managed = self.managed_server(server_name).await?; |
| 312 | let remote = match managed.config { |
| 313 | McpRuntimeConfig::Remote(remote) => remote, |
| 314 | McpRuntimeConfig::Local(_) => { |
| 315 | return Err(McpOAuthError::OAuthNotSupported(server_name.to_string())); |
| 316 | } |
| 317 | }; |
| 318 | |
| 319 | if !remote.oauth_enabled { |
| 320 | return Err(McpOAuthError::OAuthNotSupported(server_name.to_string())); |
| 321 | } |
| 322 | |
| 323 | if self |
| 324 | .oauth_states |
| 325 | .read() |
| 326 | .await |
| 327 | .get(server_name) |
| 328 | .is_some_and(|state| state.status == McpOAuthStatus::Pending) |
| 329 | { |
| 330 | return Err(McpOAuthError::OAuthInProgress); |
| 331 | } |
| 332 | |
| 333 | let authorization_url = remote |
| 334 | .authorization_url |
| 335 | .unwrap_or_else(|| format!("{}/oauth/authorize", remote.url.trim_end_matches('/'))); |
| 336 | |
| 337 | let state = McpOAuthState { |
| 338 | server_name: server_name.to_string(), |
| 339 | authorization_url, |
| 340 | client_id: remote |
| 341 | .client_id |
| 342 | .or_else(|| Some(format!("mcp_client_{}", server_name))), |
| 343 | status: McpOAuthStatus::Pending, |
| 344 | }; |
| 345 | |
| 346 | self.oauth_states |
| 347 | .write() |
| 348 | .await |
| 349 | .insert(server_name.to_string(), state.clone()); |
| 350 | self.log_event(server_name, "info", "OAuth flow started") |
| 351 | .await; |
| 352 | |
| 353 | let mut statuses = self.statuses.write().await; |
| 354 | let info = statuses |
| 355 | .entry(server_name.to_string()) |
| 356 | .or_insert_with(|| McpServerInfo { |
| 357 | name: server_name.to_string(), |
| 358 | status: "needs_auth".to_string(), |
| 359 | tools: 0, |
| 360 | resources: 0, |
| 361 | error: None, |
| 362 | oauth_required: true, |
| 363 | oauth_status: Some(McpOAuthStatus::Pending), |
| 364 | }); |
| 365 | info.status = "needs_auth".to_string(); |
| 366 | info.error = None; |
| 367 | info.oauth_required = true; |
no test coverage detected