From e6468b012d5b33dd16992652da57f11dd5a6e82f Mon Sep 17 00:00:00 2001 From: Jokler Date: Sun, 21 Jun 2020 06:37:46 +0200 Subject: Initial commit --- src/user/login.rs | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 src/user/login.rs (limited to 'src/user/login.rs') diff --git a/src/user/login.rs b/src/user/login.rs new file mode 100644 index 0000000..67d4c24 --- /dev/null +++ b/src/user/login.rs @@ -0,0 +1,77 @@ +use actix::{Actor, Handler, Message, SyncContext}; +use argonautica::{input::SecretKey, Verifier}; +use diesel::MysqlConnection; +use diesel::{ExpressionMethods, QueryDsl, RunQueryDsl}; + +use crate::error::ServiceError; +use crate::model::DbExecutor; +use crate::model::User; +use crate::schema::passwords::{columns as password_columns, dsl::passwords}; +use crate::schema::users::{columns as user_columns, dsl::users}; + +pub struct HashVerifyExecutor(pub Verifier<'static>); + +impl Actor for HashVerifyExecutor { + type Context = SyncContext; +} + +pub struct HashVerifyRequest { + hash: String, + password: String, + secret: String, +} + +impl HashVerifyRequest { + pub fn new(hash: String, password: String, secret: String) -> Self { + Self { + hash, + password, + secret, + } + } +} + +impl Message for HashVerifyRequest { + type Result = Result; +} + +impl Handler for HashVerifyExecutor { + type Result = Result; + + fn handle(&mut self, req: HashVerifyRequest, _: &mut Self::Context) -> Self::Result { + let secret = SecretKey::from_base64_encoded(req.secret)?; + Ok(self + .0 + .with_hash(req.hash) + .with_password(req.password) + .with_secret_key(secret) + .verify()?) + } +} + +pub struct LoginRequest(pub String); + +impl Message for LoginRequest { + type Result = Result<(User, String), ServiceError>; +} + +impl Handler for DbExecutor { + type Result = Result<(User, String), ServiceError>; + + fn handle(&mut self, login: LoginRequest, _: &mut Self::Context) -> Self::Result { + let conn: &MysqlConnection = &self.0.get().unwrap(); + + let user = users + .filter(user_columns::name.eq(login.0)) + .first::(conn) + .map_err(|_| ServiceError::NotFound)?; + + let hash = passwords + .filter(password_columns::id.eq(user.id)) + .select(password_columns::hash) + .first::(conn) + .map_err(|_| ServiceError::NotFound)?; + + Ok((user, hash)) + } +} -- cgit v1.2.3-70-g09d2