totp auth work pt2
This commit is contained in:
parent
19332e519b
commit
2a5a2bb910
|
@ -1,7 +1,10 @@
|
|||
CREATE TABLE totp_authenticators
|
||||
(
|
||||
id VARCHAR NOT NULL PRIMARY KEY,
|
||||
user_id VARCHAR NOT NULL REFERENCES users(id),
|
||||
secret VARCHAR NOT NULL,
|
||||
verified BOOLEAN NOT NULL
|
||||
id VARCHAR NOT NULL PRIMARY KEY,
|
||||
user_id VARCHAR NOT NULL REFERENCES users (id) ON DELETE CASCADE,
|
||||
secret VARCHAR NOT NULL,
|
||||
verified BOOLEAN NOT NULL,
|
||||
name VARCHAR NOT NULL,
|
||||
created_at TIMESTAMP NOT NULL,
|
||||
last_seen_at TIMESTAMP NOT NULL
|
||||
);
|
|
@ -44,6 +44,9 @@ pub struct TotpAuthenticator {
|
|||
pub user_id: String,
|
||||
pub secret: String,
|
||||
pub verified: bool,
|
||||
pub name: String,
|
||||
pub created_at: SystemTime,
|
||||
pub last_seen_at: SystemTime
|
||||
}
|
||||
|
||||
#[derive(
|
||||
|
|
|
@ -8,7 +8,7 @@ use crate::response::JsonAPIResponse;
|
|||
use diesel::{QueryDsl, ExpressionMethods, SelectableHelper, BelongingToDsl};
|
||||
use diesel_async::RunQueryDsl;
|
||||
use totp_rs::{Algorithm, Secret, TOTP};
|
||||
use crate::schema::{auth_tokens, users};
|
||||
use crate::schema::{auth_tokens, users, totp_authenticators};
|
||||
use crate::models::{AuthToken, TotpAuthenticator, User};
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
|
@ -42,19 +42,22 @@ pub async fn totp_req(req: Json<TotpAuthReq>, state: Data<AppState>, req_info: H
|
|||
let authenticators: Vec<TotpAuthenticator> = handle_error!(TotpAuthenticator::belonging_to(&user).load::<TotpAuthenticator>(&mut conn).await);
|
||||
|
||||
let mut found_valid_code = false;
|
||||
let mut chosen_auther = None;
|
||||
|
||||
for totp_auther in authenticators {
|
||||
if totp_auther.verified {
|
||||
let secret = Secret::Encoded(totp_auther.secret);
|
||||
let secret = Secret::Encoded(totp_auther.secret.clone());
|
||||
let totp_machine = handle_error!(TOTP::new(Algorithm::SHA1, 6, 1, 30, handle_error!(secret.to_bytes()), Some("Trifid".to_string()), user.email.clone()));
|
||||
let is_valid = handle_error!(totp_machine.check_current(&req.code));
|
||||
if is_valid { found_valid_code = true; break; }
|
||||
if is_valid { found_valid_code = true; chosen_auther = Some(totp_auther); break; }
|
||||
}
|
||||
}
|
||||
if !found_valid_code {
|
||||
err!(StatusCode::UNAUTHORIZED, make_err!("ERR_UNAUTHORIZED", "unauthorized"));
|
||||
}
|
||||
|
||||
handle_error!(diesel::update(&(chosen_auther.unwrap())).set(totp_authenticators::dsl::last_seen_at.eq(SystemTime::now())).execute(&mut conn).await);
|
||||
|
||||
// issue auth token
|
||||
|
||||
let new_token = AuthToken {
|
||||
|
|
|
@ -12,6 +12,7 @@ use totp_rs::{Algorithm, Secret, TOTP};
|
|||
use crate::schema::totp_authenticators;
|
||||
use crate::schema::users;
|
||||
use crate::models::User;
|
||||
use std::time::SystemTime;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct TotpAuthenticatorReq {}
|
||||
|
@ -54,7 +55,10 @@ pub async fn create_totp_auth_req(
|
|||
id: randid!(id "totp"),
|
||||
user_id: session_token.user_id,
|
||||
secret: secret.to_encoded().to_string(),
|
||||
verified: false
|
||||
verified: false,
|
||||
name: "".to_string(),
|
||||
created_at: SystemTime::now(),
|
||||
last_seen_at: SystemTime::now()
|
||||
};
|
||||
|
||||
handle_error!(
|
||||
|
|
|
@ -74,7 +74,7 @@ pub async fn verify_totp_req(req: Json<VerifyTotpAuthReq>, state: Data<AppState>
|
|||
err!(StatusCode::UNAUTHORIZED, make_err!("ERR_UNAUTHORIZED", "unauthorized"));
|
||||
}
|
||||
|
||||
handle_error!(diesel::update(&authenticator).set(totp_authenticators::dsl::verified.eq(true)).execute(&mut conn).await);
|
||||
handle_error!(diesel::update(&authenticator).set((totp_authenticators::dsl::verified.eq(true), totp_authenticators::dsl::last_seen_at.eq(SystemTime::now()))).execute(&mut conn).await);
|
||||
|
||||
// issue auth token
|
||||
|
||||
|
|
|
@ -30,6 +30,9 @@ diesel::table! {
|
|||
user_id -> Varchar,
|
||||
secret -> Varchar,
|
||||
verified -> Bool,
|
||||
name -> Varchar,
|
||||
created_at -> Timestamp,
|
||||
last_seen_at -> Timestamp,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue