1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
| use actix_web::{ body::EitherBody, dev::{forward_ready, Service, ServiceRequest, ServiceResponse, Transform}, Error, HttpResponse, }; use futures::future::{ok, LocalBoxFuture, Ready}; use serde_json::json;
pub struct Authentication; impl<S, B> Transform<S, ServiceRequest> for Authentication where S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>, S::Future: 'static, B: 'static, { type Response = ServiceResponse<EitherBody<B>>; type Error = Error; type InitError = (); type Transform = AuthenticationMiddleware<S>; type Future = Ready<Result<Self::Transform, Self::InitError>>;
fn new_transform(&self, service: S) -> Self::Future { ok(AuthenticationMiddleware { service }) } } pub struct AuthenticationMiddleware<S> { service: S, }
impl<S, B> Service<ServiceRequest> for AuthenticationMiddleware<S> where S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>, S::Future: 'static, B: 'static, { type Response = ServiceResponse<EitherBody<B>>; type Error = Error; type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;
forward_ready!(service);
fn call(&self, req: ServiceRequest) -> Self::Future { println!("Hi from start. You requested: {}", req.path());
let path = req.path().to_string();
let whitelist: Vec<String> = std::env::var("WL_LIST") .unwrap_or_default() .split(',') .map(|s| s.trim().to_string()) .filter(|s| !s.is_empty()) .collect();
let token = req .headers() .get("api-key") .and_then(|v| v.to_str().ok()) .unwrap_or("");
let authenticate_passbool; if whitelist.iter().any(|p| path.starts_with(p)) { authenticate_passbool = true; } else { if token == "08a31351f3324664a4e982310e76583b" { authenticate_passbool = true; } else { authenticate_passbool = false; } }
if authenticate_passbool { let res = self.service.call(req); return Box::pin(async move { res.await.map(ServiceResponse::map_into_left_body) }); } else { let (request, _pl) = req.into_parts(); let response: HttpResponse<actix_web::body::EitherBody<_>> = HttpResponse::Unauthorized() .json(json!({ "code": 401, "message": "Unauthorized", "data": null })) .map_into_right_body(); return Box::pin(async { Ok(ServiceResponse::new(request, response)) }); } } }
|