diff --git a/virtweb_backend/src/extractors/api_auth_extractor.rs b/virtweb_backend/src/extractors/api_auth_extractor.rs index 0f22043..19d5dff 100644 --- a/virtweb_backend/src/extractors/api_auth_extractor.rs +++ b/virtweb_backend/src/extractors/api_auth_extractor.rs @@ -3,6 +3,7 @@ use crate::api_tokens::{Token, TokenID, TokenVerb}; use crate::api_tokens; use crate::utils::jwt_utils; use crate::utils::time_utils::time; +use actix_remote_ip::RemoteIP; use actix_web::dev::Payload; use actix_web::error::{ErrorBadRequest, ErrorUnauthorized}; use actix_web::{Error, FromRequest, HttpRequest}; @@ -28,9 +29,14 @@ impl FromRequest for ApiAuthExtractor { type Error = Error; type Future = Pin>>>; - fn from_request(req: &HttpRequest, _payload: &mut Payload) -> Self::Future { + fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future { let req = req.clone(); + let remote_ip = match RemoteIP::from_request(&req, payload).into_inner() { + Ok(ip) => ip, + Err(e) => return Box::pin(async { Err(e) }), + }; + Box::pin(async move { let (token_id, token_jwt) = match ( req.headers().get("x-token-id"), @@ -118,9 +124,15 @@ impl FromRequest for ApiAuthExtractor { )); } - // TODO : check for ip restriction - - // TODO : manually validate all checks + if let Some(ip) = token.ip_restriction { + if !ip.contains(remote_ip.0) { + log::error!( + "Attempt to use a token for an unauthorized IP! {remote_ip:?} token_id={}", + token.id.0 + ); + return Err(ErrorUnauthorized("Token cannot be used from this IP!")); + } + } if token.should_update_last_activity() { if let Err(e) = api_tokens::refresh_last_used(token.id).await {