Pour tout problème contactez-nous par mail : support@froggit.fr | La FAQ :grey_question: | Rejoignez-nous sur le Chat :speech_balloon:

Skip to content
Snippets Groups Projects
authentication.rs 2.21 KiB
Newer Older
  • Learn to ignore specific revisions
  • use actix_web::{
        dev::{forward_ready, Service, ServiceRequest, ServiceResponse, Transform},
        Error,
    };
    use futures::prelude::future::LocalBoxFuture;
    use std::future::{ready, Ready};
    
    pub struct AuthData;
    
    impl<S, B> Transform<S, ServiceRequest> for AuthData
    where
        S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
        S::Future: 'static,
        B: 'static,
    {
        type Response = ServiceResponse<B>;
        type Error = Error;
        type InitError = ();
        type Transform = AuthenticatedMiddleware<S>;
        type Future = Ready<Result<Self::Transform, Self::InitError>>;
    
        fn new_transform(&self, service: S) -> Self::Future {
            ready(Ok(AuthenticatedMiddleware { service }))
        }
    }
    
    pub struct AuthenticatedMiddleware<S> {
        service: S,
    }
    
    
    Pierre Jarriges's avatar
    Pierre Jarriges committed
    #[derive(serde::Deserialize)]
    struct Credentials {
        id: String,
        password: String,
    }
    
    async fn auth(req: &mut ServiceRequest) -> Result<(), Box<dyn actix_web::ResponseError>> {
        let cookie = req.cookie("auth");
        match cookie {
            Some(cookie) => Ok(()),
            None => match req.extract::<actix_web::web::Form<Credentials>>().await {
                Ok(credentials) => Ok(()),
                Err(_) => Err(Box::new(actix_web::ResponseError::status_code(
                    actix_web::http::StatusCode::UNAUTHORIZED,
                ))),
            },
        }
    }
    
    
    impl<S, B> Service<ServiceRequest> for AuthenticatedMiddleware<S>
    where
        S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
        S::Future: 'static,
        B: 'static,
    {
    
    Pierre Jarriges's avatar
    Pierre Jarriges committed
        type Response = ServiceResponse<actix_web::body::EitherBody<B>>;
    
        type Error = Error;
        type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;
    
        forward_ready!(service);
    
        fn call(&self, req: ServiceRequest) -> Self::Future {
            Box::pin(async move {
    
    Pierre Jarriges's avatar
    Pierre Jarriges committed
                let credentials = req.extract::<actix_web::web::Form<Credentials>>().await;
                let authenticated = auth(&mut req).await;
    
                if let Err(msg) = authenticated {
                    return Ok(req.error_response(Error::from(msg)).map_into_right_body());
                }
    
                self.service
                    .call(req)
                    .await
                    .map(|res| res.map_into_left_body())