1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
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(())
}
}
|