87 lines
2.4 KiB
Rust
87 lines
2.4 KiB
Rust
use std::future::Future;
|
|
use std::ops::Deref;
|
|
use std::pin::Pin;
|
|
|
|
use actix::Addr;
|
|
use actix_identity::Identity;
|
|
use actix_web::dev::Payload;
|
|
use actix_web::error::ErrorInternalServerError;
|
|
use actix_web::{web, Error, FromRequest, HttpRequest};
|
|
|
|
use crate::actors::users_actor;
|
|
use crate::actors::users_actor::UsersActor;
|
|
use crate::constants::SECOND_FACTOR_EXPIRATION_FOR_CRITICAL_OPERATIONS;
|
|
use crate::data::session_identity::SessionIdentity;
|
|
use crate::data::user::User;
|
|
use crate::utils::time::time;
|
|
|
|
pub struct CurrentUser {
|
|
user: User,
|
|
pub auth_time: u64,
|
|
pub last_2fa_auth: Option<u64>,
|
|
}
|
|
|
|
impl CurrentUser {
|
|
pub fn should_request_2fa_for_critical_functions(&self) -> bool {
|
|
self.user.has_two_factor()
|
|
&& self
|
|
.last_2fa_auth
|
|
.map(|t| t + SECOND_FACTOR_EXPIRATION_FOR_CRITICAL_OPERATIONS < time())
|
|
.unwrap_or(true)
|
|
}
|
|
}
|
|
|
|
impl From<CurrentUser> for User {
|
|
fn from(user: CurrentUser) -> Self {
|
|
user.user
|
|
}
|
|
}
|
|
|
|
impl Deref for CurrentUser {
|
|
type Target = User;
|
|
|
|
fn deref(&self) -> &Self::Target {
|
|
&self.user
|
|
}
|
|
}
|
|
|
|
impl FromRequest for CurrentUser {
|
|
type Error = Error;
|
|
type Future = Pin<Box<dyn Future<Output = Result<Self, Self::Error>>>>;
|
|
|
|
fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
|
|
let user_actor: &web::Data<Addr<UsersActor>> =
|
|
req.app_data().expect("UserActor undefined!");
|
|
let user_actor: Addr<UsersActor> = user_actor.as_ref().clone();
|
|
let identity: Identity = Identity::from_request(req, payload)
|
|
.into_inner()
|
|
.expect("Failed to get identity!");
|
|
let id = SessionIdentity(Some(&identity));
|
|
let user_id = id.user_id();
|
|
let last_2fa_auth = id.last_2fa_auth();
|
|
let auth_time = id.auth_time();
|
|
|
|
Box::pin(async move {
|
|
let user = match user_actor
|
|
.send(users_actor::GetUserRequest(user_id))
|
|
.await
|
|
.unwrap()
|
|
.0
|
|
{
|
|
Some(u) => u,
|
|
None => {
|
|
return Err(ErrorInternalServerError(
|
|
"Could not extract user information!",
|
|
));
|
|
}
|
|
};
|
|
|
|
Ok(CurrentUser {
|
|
user,
|
|
auth_time,
|
|
last_2fa_auth,
|
|
})
|
|
})
|
|
}
|
|
}
|