From e64468e4db96ef14f00a44e379c85bdee10e624f Mon Sep 17 00:00:00 2001 From: peterrabbit <pierre.jarriges@tutanota.com> Date: Sun, 11 Sep 2022 18:38:04 +0200 Subject: [PATCH] wip auth middleware --- src/middleware/authentication.rs | 64 +++++++++++++++++++------------- 1 file changed, 38 insertions(+), 26 deletions(-) diff --git a/src/middleware/authentication.rs b/src/middleware/authentication.rs index 278eb2c..6fb4c4e 100644 --- a/src/middleware/authentication.rs +++ b/src/middleware/authentication.rs @@ -1,31 +1,40 @@ use actix_web::{ + body::{EitherBody, MessageBody}, dev::{forward_ready, Service, ServiceRequest, ServiceResponse, Transform}, Error, }; use futures::prelude::future::LocalBoxFuture; use std::future::{ready, Ready}; -pub struct AuthData; +#[derive(Clone)] +pub struct AuthData { + id: String, + password: String, + _token: Option<String>, +} impl<S, B> Transform<S, ServiceRequest> for AuthData where - S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>, - S::Future: 'static, - B: 'static, + S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error> + 'static, + B: MessageBody + 'static, { - type Response = ServiceResponse<B>; + type Response = ServiceResponse<EitherBody<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 })) + ready(Ok(AuthenticatedMiddleware { + service: std::rc::Rc::new(service), + auth_data: self.clone(), + })) } } pub struct AuthenticatedMiddleware<S> { - service: S, + service: std::rc::Rc<S>, + auth_data: AuthData, } #[derive(serde::Deserialize)] @@ -34,44 +43,47 @@ struct Credentials { password: String, } -async fn auth(req: &mut ServiceRequest) -> Result<(), Box<dyn actix_web::ResponseError>> { +async fn authenticate(req: &mut ServiceRequest, auth_data: &AuthData) -> bool { let cookie = req.cookie("auth"); match cookie { - Some(cookie) => Ok(()), + Some(_) => true, 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, - ))), + Ok(credentials) => { + if credentials.id == auth_data.id && credentials.password == auth_data.password { + return true; + } + return false; + } + Err(_) => false, }, } } impl<S, B> Service<ServiceRequest> for AuthenticatedMiddleware<S> where - S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>, - S::Future: 'static, - B: 'static, + S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error> + 'static, + B: MessageBody + 'static, { - type Response = ServiceResponse<actix_web::body::EitherBody<B>>; + 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 { + let service = self.service.clone(); + let auth_data = self.auth_data.clone(); Box::pin(async move { - 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()); + let mut req = req; + if let false = authenticate(&mut req, &auth_data).await { + return Ok(req.into_response( + actix_web::HttpResponse::Unauthorized() + .finish() + .map_into_right_body(), + )); } - self.service - .call(req) - .await - .map(|res| res.map_into_left_body()) + Ok(service.call(req).await?.map_into_left_body()) }) } } -- GitLab