2018-12-09 15:55:36 +00:00
|
|
|
use actix::{Handler, Message};
|
2019-06-17 12:48:03 +06:00
|
|
|
use actix_web::{dev::Payload, Error, HttpRequest, FromRequest};
|
|
|
|
use actix_identity::Identity;
|
2019-03-09 18:03:09 -08:00
|
|
|
use bcrypt::verify;
|
2018-12-09 15:55:36 +00:00
|
|
|
use diesel::prelude::*;
|
2019-03-29 13:43:03 -07:00
|
|
|
|
|
|
|
use crate::errors::ServiceError;
|
|
|
|
use crate::models::{DbExecutor, SlimUser, User};
|
|
|
|
use crate::utils::decode_token;
|
2018-12-09 15:55:36 +00:00
|
|
|
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct AuthData {
|
|
|
|
pub email: String,
|
|
|
|
pub password: String,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Message for AuthData {
|
|
|
|
type Result = Result<SlimUser, ServiceError>;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Handler<AuthData> for DbExecutor {
|
|
|
|
type Result = Result<SlimUser, ServiceError>;
|
|
|
|
fn handle(&mut self, msg: AuthData, _: &mut Self::Context) -> Self::Result {
|
2019-03-29 13:43:03 -07:00
|
|
|
use crate::schema::users::dsl::{email, users};
|
2018-12-09 15:55:36 +00:00
|
|
|
let conn: &PgConnection = &self.0.get().unwrap();
|
|
|
|
|
2019-03-09 18:03:09 -08:00
|
|
|
let mut items = users.filter(email.eq(&msg.email)).load::<User>(conn)?;
|
2018-12-09 15:55:36 +00:00
|
|
|
|
|
|
|
if let Some(user) = items.pop() {
|
|
|
|
match verify(&msg.password, &user.password) {
|
2019-03-09 18:03:09 -08:00
|
|
|
Ok(matching) => {
|
|
|
|
if matching {
|
2018-12-09 15:55:36 +00:00
|
|
|
return Ok(user.into());
|
2019-03-09 18:03:09 -08:00
|
|
|
}
|
|
|
|
}
|
2018-12-09 15:55:36 +00:00
|
|
|
Err(_) => (),
|
|
|
|
}
|
|
|
|
}
|
2019-03-09 18:03:09 -08:00
|
|
|
Err(ServiceError::BadRequest(
|
|
|
|
"Username and Password don't match".into(),
|
|
|
|
))
|
2018-12-09 15:55:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// we need the same data
|
|
|
|
// simple aliasing makes the intentions clear and its more readable
|
|
|
|
pub type LoggedUser = SlimUser;
|
|
|
|
|
2019-04-14 10:34:41 -07:00
|
|
|
impl FromRequest for LoggedUser {
|
|
|
|
type Config = ();
|
2019-03-29 13:43:03 -07:00
|
|
|
type Error = Error;
|
|
|
|
type Future = Result<LoggedUser, Error>;
|
|
|
|
|
2019-04-14 10:34:41 -07:00
|
|
|
fn from_request(req: &HttpRequest, pl: &mut Payload) -> Self::Future {
|
2019-04-07 23:39:45 -07:00
|
|
|
if let Some(identity) = Identity::from_request(req, pl)?.identity() {
|
2018-12-09 15:55:36 +00:00
|
|
|
let user: SlimUser = decode_token(&identity)?;
|
|
|
|
return Ok(user as LoggedUser);
|
|
|
|
}
|
2019-03-29 13:43:03 -07:00
|
|
|
Err(ServiceError::Unauthorized.into())
|
2018-12-09 15:55:36 +00:00
|
|
|
}
|
|
|
|
}
|