Complete private authentication, server integrations and activity reporting
Add Fabric/Forge version builds and Paper integration, preserve permanent player identities across renames, harden session authorization, and surface privacy-conscious launcher/server activity in the panel.
This commit is contained in:
commit
a1f19e86c6
74 files changed
+2108
-95
No files matched your search
+19
-7
@@ -42,16 +42,28 @@ pub fn host_of(url: &str) -> String {
|
||||
host.split(':').next().unwrap_or(host).to_string()
|
||||
}
|
||||
|
||||
/// Client IP: the first `X-Forwarded-For` hop, `X-Real-IP`, or the socket.
|
||||
/// Forwarded addresses are accepted only from explicitly trusted proxies.
|
||||
pub struct ClientIp(pub Option<String>);
|
||||
|
||||
impl<S: Send + Sync> FromRequestParts<S> for ClientIp {
|
||||
impl FromRequestParts<AppState> for ClientIp {
|
||||
type Rejection = AppError;
|
||||
async fn from_request_parts(parts: &mut Parts, _: &S) -> Result<Self, Self::Rejection> {
|
||||
let forwarded = header(&parts.headers, "x-forwarded-for").and_then(|v| v.split(',').next()).map(|v| v.trim().to_string());
|
||||
let real = header(&parts.headers, "x-real-ip").map(String::from);
|
||||
let socket = parts.extensions.get::<ConnectInfo<SocketAddr>>().map(|c| c.0.ip().to_string());
|
||||
Ok(ClientIp(forwarded.or(real).or(socket)))
|
||||
async fn from_request_parts(parts: &mut Parts, state: &AppState) -> Result<Self, Self::Rejection> {
|
||||
let peer = parts.extensions.get::<ConnectInfo<SocketAddr>>().map(|c| c.0.ip());
|
||||
if peer.is_some_and(|ip| state.cfg.trusted_proxies.contains(&ip)) {
|
||||
// Walk right-to-left so a client-supplied prefix cannot spoof its IP.
|
||||
if let Some(chain) = header(&parts.headers, "x-forwarded-for") {
|
||||
for hop in chain.rsplit(',') {
|
||||
let Ok(ip) = hop.trim().parse::<std::net::IpAddr>() else { return Ok(ClientIp(None)) };
|
||||
if !state.cfg.trusted_proxies.contains(&ip) {
|
||||
return Ok(ClientIp(Some(ip.to_string())));
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(ip) = header(&parts.headers, "x-real-ip").and_then(|v| v.parse::<std::net::IpAddr>().ok()) {
|
||||
return Ok(ClientIp(Some(ip.to_string())));
|
||||
}
|
||||
}
|
||||
Ok(ClientIp(peer.map(|ip| ip.to_string())))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user