pulseengine_mcp_server/
middleware.rs1use crate::context::RequestContext;
4use pulseengine_mcp_auth::AuthenticationManager;
5use pulseengine_mcp_monitoring::MetricsCollector;
6use pulseengine_mcp_protocol::*;
7use pulseengine_mcp_security::SecurityMiddleware;
8
9use async_trait::async_trait;
10use std::sync::Arc;
11use tracing::debug;
12
13#[async_trait]
15pub trait Middleware: Send + Sync {
16 async fn process_request(
18 &self,
19 request: Request,
20 context: &RequestContext,
21 ) -> std::result::Result<Request, Error>;
22
23 async fn process_response(
25 &self,
26 response: Response,
27 context: &RequestContext,
28 ) -> std::result::Result<Response, Error>;
29}
30
31#[derive(Clone)]
33pub struct MiddlewareStack {
34 security: Option<SecurityMiddleware>,
35 auth: Option<Arc<AuthenticationManager>>,
36 monitoring: Option<Arc<MetricsCollector>>,
37}
38
39impl MiddlewareStack {
40 pub fn new() -> Self {
42 Self {
43 security: None,
44 auth: None,
45 monitoring: None,
46 }
47 }
48
49 pub fn with_security(mut self, security: SecurityMiddleware) -> Self {
51 self.security = Some(security);
52 self
53 }
54
55 pub fn with_auth(mut self, auth: Arc<AuthenticationManager>) -> Self {
57 self.auth = Some(auth);
58 self
59 }
60
61 pub fn with_monitoring(mut self, monitoring: Arc<MetricsCollector>) -> Self {
63 self.monitoring = Some(monitoring);
64 self
65 }
66
67 pub async fn process_request(
69 &self,
70 mut request: Request,
71 context: &RequestContext,
72 ) -> std::result::Result<Request, crate::handler::HandlerError> {
73 debug!("Processing request through middleware stack");
74
75 if let Some(security) = &self.security {
77 let sec_context = pulseengine_mcp_security::middleware::RequestContext {
78 request_id: context.request_id,
79 };
80 request = security.process_request(request, &sec_context)?;
81 }
82
83 if let Some(auth) = &self.auth {
85 let auth_context = pulseengine_mcp_auth::manager::RequestContext {
86 user_id: context.authenticated_user.clone(),
87 roles: context
88 .roles
89 .iter()
90 .map(|r| match r.as_str() {
91 "admin" => pulseengine_mcp_auth::models::Role::Admin,
92 "operator" => pulseengine_mcp_auth::models::Role::Operator,
93 "monitor" => pulseengine_mcp_auth::models::Role::Monitor,
94 _ => pulseengine_mcp_auth::models::Role::Monitor, })
96 .collect(),
97 };
98
99 request = auth
100 .process_request(request, &auth_context)
101 .await
102 .map_err(|e| crate::handler::HandlerError::Authentication(e.to_string()))?;
103 }
104
105 if let Some(monitoring) = &self.monitoring {
107 let mon_context = pulseengine_mcp_monitoring::collector::RequestContext {
108 request_id: context.request_id,
109 };
110 request = monitoring.process_request(request, &mon_context)?;
111 }
112
113 Ok(request)
114 }
115
116 pub async fn process_response(
118 &self,
119 mut response: Response,
120 context: &RequestContext,
121 ) -> std::result::Result<Response, crate::handler::HandlerError> {
122 debug!("Processing response through middleware stack");
123
124 if let Some(monitoring) = &self.monitoring {
126 let mon_context = pulseengine_mcp_monitoring::collector::RequestContext {
127 request_id: context.request_id,
128 };
129 response = monitoring.process_response(response, &mon_context)?;
130 }
131
132 if let Some(auth) = &self.auth {
134 let auth_context = pulseengine_mcp_auth::manager::RequestContext {
135 user_id: context.authenticated_user.clone(),
136 roles: context
137 .roles
138 .iter()
139 .map(|r| match r.as_str() {
140 "admin" => pulseengine_mcp_auth::models::Role::Admin,
141 "operator" => pulseengine_mcp_auth::models::Role::Operator,
142 "monitor" => pulseengine_mcp_auth::models::Role::Monitor,
143 _ => pulseengine_mcp_auth::models::Role::Monitor, })
145 .collect(),
146 };
147 response = auth
148 .process_response(response, &auth_context)
149 .await
150 .map_err(|e| crate::handler::HandlerError::Authentication(e.to_string()))?;
151 }
152
153 if let Some(security) = &self.security {
155 let sec_context = pulseengine_mcp_security::middleware::RequestContext {
156 request_id: context.request_id,
157 };
158 response = security.process_response(response, &sec_context)?;
159 }
160
161 Ok(response)
162 }
163}
164
165impl Default for MiddlewareStack {
166 fn default() -> Self {
167 Self::new()
168 }
169}