arc_web/http/middlewares/
auth_middleware.rs1use crate::helpers::session::is_authenticated;
2use actix_session::SessionExt;
3use actix_web::body::EitherBody;
4use actix_web::{
5 dev::{forward_ready, Service, ServiceRequest, ServiceResponse, Transform},
6 Error, HttpResponse,
7};
8use futures_util::future::LocalBoxFuture;
9use std::future::{ready, Ready};
10
11pub struct AuthMiddleware;
14
15impl<S, B> Transform<S, ServiceRequest> for AuthMiddleware
16where
17 S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
18 S::Future: 'static,
19 B: 'static,
20{
21 type Response = ServiceResponse<EitherBody<B>>;
22 type Error = Error;
23 type InitError = ();
24 type Transform = AuthCheck<S>;
25 type Future = Ready<Result<Self::Transform, Self::InitError>>;
26
27 fn new_transform(&self, service: S) -> Self::Future {
28 ready(Ok(AuthCheck { service }))
29 }
30}
31
32pub struct AuthCheck<S> {
34 service: S,
35}
36
37impl<S, B> Service<ServiceRequest> for AuthCheck<S>
38where
39 S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
40 S::Future: 'static,
41 B: 'static,
42{
43 type Response = ServiceResponse<EitherBody<B>>;
44 type Error = Error;
45 type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;
46
47 forward_ready!(service);
48
49 fn call(&self, req: ServiceRequest) -> Self::Future {
50 let session = req.get_session();
51
52 if !is_authenticated(&session) {
54 return Box::pin(async move {
55 Ok(req.into_response(
56 HttpResponse::Found()
57 .insert_header(("Location", "/signin"))
58 .finish()
59 .map_into_right_body(),
60 ))
61 });
62 }
63
64 let res: <S as Service<ServiceRequest>>::Future = self.service.call(req);
65 Box::pin(async move { res.await.map(ServiceResponse::map_into_left_body) })
66 }
67}