diff options
Diffstat (limited to 'src/admin')
| -rw-r--r-- | src/admin/user_creation.rs | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/src/admin/user_creation.rs b/src/admin/user_creation.rs new file mode 100644 index 0000000..563b660 --- /dev/null +++ b/src/admin/user_creation.rs @@ -0,0 +1,87 @@ +use actix::{Actor, Handler, Message, SyncContext}; +use argonautica::{input::SecretKey, Hasher}; +use diesel::MysqlConnection; +use diesel::{ + dsl::sql, + types::{Bigint, Unsigned}, + RunQueryDsl, +}; + +use crate::error::ServiceError; +use crate::model::{DbExecutor, NewPassword, NewUser}; +use crate::schema::passwords::dsl::passwords; +use crate::schema::users::dsl::users; + +static LAST_ID_SQL: &'static str = "SELECT LAST_INSERT_ID()"; + +pub struct PassHashExecutor(pub Hasher<'static>); + +impl Actor for PassHashExecutor { + type Context = SyncContext<Self>; +} + +pub struct PassHashRequest { + password: String, + secret: String, +} + +impl PassHashRequest { + pub fn new(password: String, secret: String) -> Self { + Self { password, secret } + } +} + +impl Message for PassHashRequest { + type Result = Result<String, ServiceError>; +} + +impl Handler<PassHashRequest> for PassHashExecutor { + type Result = Result<String, ServiceError>; + + fn handle(&mut self, req: PassHashRequest, _: &mut Self::Context) -> Self::Result { + let secret = SecretKey::from_base64_encoded(req.secret)?; + Ok(self + .0 + .with_password(req.password) + .with_secret_key(secret) + .hash()?) + } +} + +pub struct SaveUserRequest { + user: NewUser, + pass_hash: String, +} + +impl SaveUserRequest { + pub fn new(user: NewUser, pass_hash: String) -> Self { + Self { user, pass_hash } + } +} + +impl Message for SaveUserRequest { + type Result = Result<(), ServiceError>; +} + +impl Handler<SaveUserRequest> for DbExecutor { + type Result = Result<(), ServiceError>; + + fn handle(&mut self, msg: SaveUserRequest, _: &mut Self::Context) -> Self::Result { + let conn: &MysqlConnection = &self.0.get().unwrap(); + + diesel::insert_into(users).values(&msg.user).execute(conn)?; + + let id = sql::<Unsigned<Bigint>>(LAST_ID_SQL).get_result(conn)?; + + let new_pass = NewPassword { + id: id, + hash: &msg.pass_hash, + }; + + diesel::insert_into(passwords) + .values(&new_pass) + .execute(conn)?; + + Ok(()) + } +} |
