micromegas/servers/
tonic_auth_interceptor.rs1use micromegas_auth::client_ip::resolve_client_ip;
2use micromegas_auth::types::{AuthProvider, GrpcRequestParts, ProviderUnavailable, RequestParts};
3use micromegas_tracing::prelude::*;
4use std::sync::Arc;
5use tonic::{Request, Status};
6
7pub async fn check_auth(
12 req: Request<()>,
13 auth_provider: &Arc<dyn AuthProvider>,
14) -> Result<Request<()>, Status> {
15 let metadata = req.metadata();
16 let client_ip = resolve_client_ip(metadata.as_ref(), req.extensions());
18
19 let parts = GrpcRequestParts {
20 metadata: metadata.clone(),
21 client_ip,
22 };
23
24 let auth_ctx = auth_provider
25 .validate_request(&parts as &dyn RequestParts)
26 .await
27 .map_err(|e| {
28 if e.downcast_ref::<ProviderUnavailable>().is_some() {
29 debug!("authentication failed: {e}");
30 Status::unavailable("auth provider unavailable")
31 } else {
32 warn!("authentication failed: {e}");
33 Status::unauthenticated("invalid token")
34 }
35 })?;
36
37 info!(
38 "authenticated: subject={} email={:?} issuer={} admin={}",
39 auth_ctx.subject,
40 auth_ctx.email,
41 auth_ctx.issuer,
42 auth_ctx.is_admin()
43 );
44
45 let mut req = req;
46 req.extensions_mut().insert(auth_ctx);
47 Ok(req)
48}