1
0
mirror of https://github.com/actix/examples synced 2025-02-13 14:02:19 +01:00
examples/simple-auth-server/src/auth_handler.rs

61 lines
1.8 KiB
Rust
Raw Normal View History

use actix::{Handler, Message};
2019-03-29 13:43:03 -07:00
use actix_web::{dev::ServiceFromRequest, Error};
use actix_web::{middleware::identity::Identity, FromRequest, HttpRequest};
2019-03-09 18:03:09 -08:00
use bcrypt::verify;
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;
#[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};
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)?;
if let Some(user) = items.pop() {
match verify(&msg.password, &user.password) {
2019-03-09 18:03:09 -08:00
Ok(matching) => {
if matching {
return Ok(user.into());
2019-03-09 18:03:09 -08:00
}
}
Err(_) => (),
}
}
2019-03-09 18:03:09 -08:00
Err(ServiceError::BadRequest(
"Username and Password don't match".into(),
))
}
}
// we need the same data
// simple aliasing makes the intentions clear and its more readable
pub type LoggedUser = SlimUser;
2019-03-29 13:43:03 -07:00
impl<P> FromRequest<P> for LoggedUser {
type Error = Error;
type Future = Result<LoggedUser, Error>;
fn from_request(req: &mut ServiceFromRequest<P>) -> Self::Future {
if let Some(identity) = Identity::from_request(req)?.identity() {
let user: SlimUser = decode_token(&identity)?;
return Ok(user as LoggedUser);
}
2019-03-29 13:43:03 -07:00
Err(ServiceError::Unauthorized.into())
}
}