scufflecloud_core/middleware/
ip_address.rs

1use std::net::{IpAddr, SocketAddr};
2
3use axum::extract::{ConnectInfo, Request};
4use axum::middleware::Next;
5use axum::response::Response;
6use reqwest::StatusCode;
7
8use crate::CoreConfig;
9use crate::http_ext::RequestExt;
10
11#[derive(Debug, Clone, Copy)]
12pub(crate) struct IpAddressInfo {
13    pub ip_address: IpAddr,
14    // maxminddb...
15}
16
17impl IpAddressInfo {
18    pub(crate) fn to_network(self) -> ipnetwork::IpNetwork {
19        self.ip_address.into()
20    }
21}
22
23pub(crate) async fn ip_address<G: CoreConfig>(mut req: Request, next: Next) -> Result<Response, StatusCode> {
24    let _global = req.global::<G>().map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
25
26    // Get the IP address from the request
27    // TODO: IP from headers if behind a proxy
28    let info: ConnectInfo<SocketAddr> = axum::RequestExt::extract_parts(&mut req).await.map_err(|e| {
29        tracing::error!(err = %e, "failed to extract ConnectInfo");
30        StatusCode::INTERNAL_SERVER_ERROR
31    })?;
32
33    // TODO: Get location from MaxMindDB
34
35    req.extensions_mut().insert(IpAddressInfo { ip_address: info.ip() });
36
37    Ok(next.run(req).await)
38}