use actix_web::HttpRequest;
use myc_core::domain::dtos::service::Service;
use myc_http_tools::responses::GatewayError;
use mycelium_base::dtos::Parent;
use wildmatch::WildMatch;
#[tracing::instrument(name = "check_the_source_reliability", skip_all)]
pub(super) async fn check_source_reliability<T>(
req: HttpRequest,
parent_service: &Parent<Service, T>,
) -> Result<(), GatewayError> {
let service = if let Parent::Record(ref service) = parent_service {
service
} else {
tracing::error!("Service not found");
return Err(GatewayError::InternalServerError(String::from(
"Service not found",
)));
};
if let Some(allowed_sources) = service.allowed_sources.clone() {
let host = req.headers().get("Host");
if host.is_none() {
tracing::warn!(
"The host is not present in the request when it is required to check the source reliability"
);
return Err(GatewayError::Unauthorized(String::from(
"The source is not allowed to access this service",
)));
}
let host = host.unwrap().to_str().map_err(|_| {
tracing::error!(
"The host is present in the request but it is not a string when it is required to check the source reliability"
);
GatewayError::Unauthorized(String::from(
"The source is not allowed to access this service",
))
})?;
for allowed_source in allowed_sources {
if WildMatch::new(allowed_source.as_str()).matches(host) {
return Ok(());
}
}
tracing::warn!(
"The host is not allowed to access the service {}",
service.name
);
return Err(GatewayError::Unauthorized(String::from(
"The source is not allowed to access this service",
)));
}
return Ok(());
}