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}