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