forked from rust-lang/crates.io
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathci.rs
60 lines (51 loc) · 1.51 KB
/
ci.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
use crate::middleware::real_ip::RealIp;
use async_trait::async_trait;
use axum::extract::FromRequestParts;
use http::request::Parts;
use ipnetwork::IpNetwork;
use once_cell::sync::Lazy;
use std::fmt::Display;
use std::net::IpAddr;
#[derive(Copy, Clone, Debug)]
pub enum CiService {
GitHubActions,
}
impl Display for CiService {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
CiService::GitHubActions => write!(f, "GitHub Actions"),
}
}
}
#[async_trait]
impl<S> FromRequestParts<S> for CiService {
type Rejection = ();
async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result<Self, Self::Rejection> {
let real_ip = parts.extensions.get::<RealIp>().ok_or(())?;
if is_github_actions_ip(real_ip) {
return Ok(CiService::GitHubActions);
}
Err(())
}
}
fn is_github_actions_ip(ip: &IpAddr) -> bool {
static GITHUB_ACTIONS_CIDRS: Lazy<Vec<IpNetwork>> = Lazy::new(|| {
github_meta::META
.actions
.iter()
.filter_map(|cidr| parse_cidr(cidr, "GitHub Actions"))
.collect()
});
GITHUB_ACTIONS_CIDRS
.iter()
.any(|trusted_proxy| trusted_proxy.contains(*ip))
}
fn parse_cidr(cidr: &str, service: &'static str) -> Option<IpNetwork> {
match cidr.parse() {
Ok(ip_network) => Some(ip_network),
Err(error) => {
warn!(%cidr, %error, "Failed to parse {service} CIDR");
None
}
}
}