summaryrefslogtreecommitdiffstats
path: root/src/admin/user_creation.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/admin/user_creation.rs')
-rw-r--r--src/admin/user_creation.rs87
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(())
+ }
+}