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
 97
 98
 99
100
101
102
103
104
105
106
/*
* Copyright (C) 2021  Aravinth Manivannan <realaravinth@batsense.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program.  If not, see <https://www.gnu.org/licenses/>.
*/

#![allow(clippy::type_complexity)]
//use std::task::{Context, Poll};

use actix_http::body::AnyBody;
use actix_identity::Identity;
use actix_service::{Service, Transform};
use actix_web::dev::{ServiceRequest, ServiceResponse};
use actix_web::{http, Error, FromRequest, HttpResponse};

use futures::future::{ok, Either, Ready};

use crate::PAGES;

pub struct CheckLogin;

impl<S> Transform<S, ServiceRequest> for CheckLogin
where
    S: Service<ServiceRequest, Response = ServiceResponse<AnyBody>, Error = Error>,
    S::Future: 'static,
{
    type Response = ServiceResponse<AnyBody>;
    type Error = Error;
    type Transform = CheckLoginMiddleware<S>;
    type InitError = ();
    type Future = Ready<Result<Self::Transform, Self::InitError>>;

    fn new_transform(&self, service: S) -> Self::Future {
        ok(CheckLoginMiddleware { service })
    }
}
pub struct CheckLoginMiddleware<S> {
    service: S,
}

impl<S> Service<ServiceRequest> for CheckLoginMiddleware<S>
where
    S: Service<ServiceRequest, Response = ServiceResponse<AnyBody>, Error = Error>,
    S::Future: 'static,
{
    type Response = ServiceResponse<AnyBody>;
    type Error = Error;
    type Future = Either<S::Future, Ready<Result<Self::Response, Self::Error>>>;

    //    fn poll_ready(&mut self, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
    //        self.service.poll_ready(cx)
    //    }
    //
    actix_service::forward_ready!(service);

    fn call(&self, req: ServiceRequest) -> Self::Future {
        //    let (r, mut pl) = req.into_parts();

        //    // TODO investigate when the bellow statement will
        //    // return error
        //    if let Ok(Some(_)) = Identity::from_request(&r, &mut pl)
        //        .into_inner()
        //        .map(|x| x.identity())
        //    {
        //        let req = ServiceRequest::from_parts(r, pl);
        //        Either::Left(self.service.call(req))
        //    } else {
        //        let resp = actix_http::ResponseBuilder::new(http::StatusCode::FOUND)
        //            .insert_header((http::header::LOCATION, PAGES.auth.login))
        //            .finish();

        //        let req = ServiceRequest::from_parts(r, pl);
        //        Either::Right(ok(req.into_response(resp)))
        //    }

        let (r, mut pl) = req.into_parts();

        // TODO investigate when the bellow statement will
        // return error
        if let Ok(Some(_)) = Identity::from_request(&r, &mut pl)
            .into_inner()
            .map(|x| x.identity())
        {
            let req = ServiceRequest::from_parts(r, pl);
            Either::Left(self.service.call(req))
        } else {
            let req = ServiceRequest::from_parts(r, pl); //.ok().unwrap();
            Either::Right(ok(req.into_response(
                HttpResponse::Found()
                    .insert_header((http::header::LOCATION, PAGES.auth.login))
                    .finish(),
            )))
        }
    }
}