summaryrefslogtreecommitdiffstats
path: root/src/user/login.rs
diff options
context:
space:
mode:
authorJokler <jokler@protonmail.com>2020-06-21 06:37:46 +0200
committerJokler <jokler@protonmail.com>2020-06-21 06:37:46 +0200
commite6468b012d5b33dd16992652da57f11dd5a6e82f (patch)
treee89add440df79d4036b9b44d8c77ee6d69e67201 /src/user/login.rs
downloadjoklerpoints-e6468b012d5b33dd16992652da57f11dd5a6e82f.tar.gz
joklerpoints-e6468b012d5b33dd16992652da57f11dd5a6e82f.zip
Initial commitHEADmaster
Diffstat (limited to 'src/user/login.rs')
-rw-r--r--src/user/login.rs77
1 files changed, 77 insertions, 0 deletions
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<Self>;
+}
+
+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<bool, ServiceError>;
+}
+
+impl Handler<HashVerifyRequest> for HashVerifyExecutor {
+ type Result = Result<bool, ServiceError>;
+
+ 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<LoginRequest> 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::<User>(conn)
+ .map_err(|_| ServiceError::NotFound)?;
+
+ let hash = passwords
+ .filter(password_columns::id.eq(user.id))
+ .select(password_columns::hash)
+ .first::<String>(conn)
+ .map_err(|_| ServiceError::NotFound)?;
+
+ Ok((user, hash))
+ }
+}