database: added totp codes migrations, get/add/use token

This commit is contained in:
Philippe Loctaux 2023-05-01 11:57:41 +02:00
parent f891d2f940
commit 8658966b41
10 changed files with 229 additions and 0 deletions

View file

@ -1,6 +1,7 @@
mod database;
mod error;
pub mod password_reset;
pub mod totp_login_request;
use chrono::{DateTime, Utc};
use id::UserID;

View 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?)
}
}