summaryrefslogtreecommitdiff
path: root/src/web/extract.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/web/extract.rs')
-rw-r--r--src/web/extract.rs139
1 files changed, 0 insertions, 139 deletions
diff --git a/src/web/extract.rs b/src/web/extract.rs
deleted file mode 100644
index 4b6cd7c..0000000
--- a/src/web/extract.rs
+++ /dev/null
@@ -1,139 +0,0 @@
-use std::{
- io::Read,
- net::{IpAddr, SocketAddr},
-};
-
-use axum::{
- async_trait,
- body::HttpBody,
- extract::{ConnectInfo, FromRequest, FromRequestParts},
- http::{request::Parts, Request},
- response::Response,
- BoxError,
-};
-use bytes::Bytes;
-use moka::future::Cache;
-use tower_cookies::Cookies;
-
-use super::http::text;
-
-pub struct Authorized;
-
-#[async_trait]
-impl<S> FromRequestParts<S> for Authorized
-where
- S: Send + Sync,
-{
- type Rejection = Response;
-
- async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {
- let Ok(Some(cookies)) = Option::<Cookies>::from_request_parts(parts, state).await else {
- return Err(text(403, "No cookies provided"))
- };
-
- let Some(token) = cookies.get("auth") else {
- return Err(text(403, "No auth token provided"))
- };
-
- let auth_ip: IpAddr;
- {
- let Some(cache) = parts.extensions.get::<Cache<String, IpAddr>>() else {
- return Err(text(500, "Failed to load auth store"))
- };
-
- let Some(ip) = cache.get(token.value()) else {
- return Err(text(401, "Unauthorized"))
- };
-
- auth_ip = ip
- }
-
- let Ok(Some(RequestIp(ip))) = Option::<RequestIp>::from_request_parts(parts, state).await else {
- return Err(text(403, "You have no ip"))
- };
-
- if auth_ip != ip {
- return Err(text(403, "Auth token does not match current ip"));
- }
-
- Ok(Self)
- }
-}
-
-pub struct RequestIp(pub IpAddr);
-
-#[async_trait]
-impl<S> FromRequestParts<S> for RequestIp
-where
- S: Send + Sync,
-{
- type Rejection = Response;
-
- async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result<Self, Self::Rejection> {
- let headers = &parts.headers;
-
- let forwardedfor = headers
- .get("x-forwarded-for")
- .and_then(|h| h.to_str().ok())
- .and_then(|h| {
- h.split(',')
- .rev()
- .find_map(|s| s.trim().parse::<IpAddr>().ok())
- });
-
- if let Some(forwardedfor) = forwardedfor {
- return Ok(Self(forwardedfor));
- }
-
- let realip = headers
- .get("x-real-ip")
- .and_then(|hv| hv.to_str().ok())
- .and_then(|s| s.parse::<IpAddr>().ok());
-
- if let Some(realip) = realip {
- return Ok(Self(realip));
- }
-
- let realip = headers
- .get("x-real-ip")
- .and_then(|hv| hv.to_str().ok())
- .and_then(|s| s.parse::<IpAddr>().ok());
-
- if let Some(realip) = realip {
- return Ok(Self(realip));
- }
-
- let info = parts.extensions.get::<ConnectInfo<SocketAddr>>();
-
- if let Some(info) = info {
- return Ok(Self(info.0.ip()));
- }
-
- Err(text(403, "You have no ip"))
- }
-}
-
-pub struct Body(pub String);
-
-#[async_trait]
-impl<S, B> FromRequest<S, B> for Body
-where
- B: HttpBody + Sync + Send + 'static,
- B::Data: Send,
- B::Error: Into<BoxError>,
- S: Send + Sync,
-{
- type Rejection = Response;
-
- async fn from_request(req: Request<B>, state: &S) -> Result<Self, Self::Rejection> {
- let Ok(bytes) = Bytes::from_request(req, state).await else {
- return Err(text(413, "Payload too large"));
- };
-
- let Ok(body) = String::from_utf8(bytes.bytes().flatten().collect()) else {
- return Err(text(400, "Invalid utf8 body"))
- };
-
- Ok(Self(body))
- }
-}