use actix_web::{dev::Payload, FromRequest, HttpRequest};
use futures::Future;
use myc_http_tools::{
responses::GatewayError, settings::DEFAULT_TENANT_ID_KEY,
};
use serde::Deserialize;
use std::{pin::Pin, str::FromStr};
use uuid::Uuid;
#[derive(Clone, Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct TenantData(Uuid);
impl TenantData {
pub fn tenant_id(&self) -> &Uuid {
&self.0
}
}
impl FromRequest for TenantData {
type Error = GatewayError;
type Future =
Pin<Box<dyn Future<Output = Result<TenantData, Self::Error>>>>;
fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
let req_clone = req.clone();
Box::pin(async move {
let tenant_id = req_clone
.headers()
.get(DEFAULT_TENANT_ID_KEY)
.ok_or_else(|| {
GatewayError::BadRequest(format!(
"Missing tenant id in request. Expected header: {}",
DEFAULT_TENANT_ID_KEY
))
})?
.to_str()
.map_err(|_| {
GatewayError::BadRequest(
"Invalid tenant id in request".to_string(),
)
})?;
Ok(TenantData(Uuid::from_str(tenant_id).map_err(|_| {
GatewayError::BadRequest(
"Invalid tenant id in request".to_string(),
)
})?))
})
}
}