database: added totp codes migrations, get/add/use token
This commit is contained in:
parent
f891d2f940
commit
8658966b41
10 changed files with 229 additions and 0 deletions
|
|
@ -1,6 +1,7 @@
|
|||
mod database;
|
||||
mod error;
|
||||
pub mod password_reset;
|
||||
pub mod totp_login_request;
|
||||
|
||||
use chrono::{DateTime, Utc};
|
||||
use id::UserID;
|
||||
|
|
|
|||
73
crates/users/src/totp_login_request.rs
Normal file
73
crates/users/src/totp_login_request.rs
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
use crate::Error;
|
||||
use chrono::{DateTime, Duration, Utc};
|
||||
use database::sqlx::SqliteExecutor;
|
||||
use database::TotpLoginRequests as DatabaseTotpLoginRequests;
|
||||
use id::UserID;
|
||||
|
||||
pub const TOTP_REQUEST_COOKIE_NAME: &str = "totp_request";
|
||||
pub const TOTP_REQUEST_LEN: usize = 25;
|
||||
|
||||
pub struct TotpLoginRequest {
|
||||
// Info
|
||||
token: String,
|
||||
user: UserID,
|
||||
|
||||
// Timings
|
||||
created_at: DateTime<Utc>,
|
||||
expires_at: DateTime<Utc>,
|
||||
used_at: Option<DateTime<Utc>>,
|
||||
}
|
||||
|
||||
impl TotpLoginRequest {
|
||||
pub fn token(&self) -> &str {
|
||||
&self.token
|
||||
}
|
||||
pub fn user(&self) -> &UserID {
|
||||
&self.user
|
||||
}
|
||||
pub fn has_expired(&self) -> bool {
|
||||
self.expires_at < Utc::now()
|
||||
}
|
||||
pub fn used_at(&self) -> Option<DateTime<Utc>> {
|
||||
self.used_at
|
||||
}
|
||||
}
|
||||
|
||||
impl From<DatabaseTotpLoginRequests> for TotpLoginRequest {
|
||||
fn from(db: DatabaseTotpLoginRequests) -> Self {
|
||||
Self {
|
||||
token: db.token,
|
||||
user: UserID(db.user),
|
||||
created_at: db.created_at,
|
||||
expires_at: db.expires_at,
|
||||
used_at: db.used_at,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TotpLoginRequest {
|
||||
pub async fn insert(
|
||||
conn: impl SqliteExecutor<'_>,
|
||||
token: &str,
|
||||
user: &UserID,
|
||||
validity_minutes: i64,
|
||||
) -> Result<Option<()>, Error> {
|
||||
let expires_at = Utc::now() + Duration::minutes(validity_minutes);
|
||||
|
||||
Ok(DatabaseTotpLoginRequests::insert(conn, token, &user.0, expires_at.timestamp()).await?)
|
||||
}
|
||||
|
||||
pub async fn get_one(
|
||||
conn: impl SqliteExecutor<'_>,
|
||||
token: &str,
|
||||
) -> Result<Option<Self>, Error> {
|
||||
Ok(DatabaseTotpLoginRequests::get_one(conn, token)
|
||||
.await?
|
||||
.map(Self::from))
|
||||
}
|
||||
|
||||
/// Consume and mark as used
|
||||
pub async fn use_code(self, conn: impl SqliteExecutor<'_>) -> Result<Option<()>, Error> {
|
||||
Ok(DatabaseTotpLoginRequests::use_token(conn, &self.token).await?)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue