make db only return tokens, not validate

This commit is contained in:
deneb 2024-02-10 14:02:41 +01:00
parent 3079bc40a7
commit 2bac280f3b
4 changed files with 29 additions and 14 deletions

5
Cargo.lock generated
View file

@ -1803,6 +1803,7 @@ dependencies = [
"smallvec", "smallvec",
"sqlformat", "sqlformat",
"thiserror", "thiserror",
"time",
"tokio", "tokio",
"tokio-stream", "tokio-stream",
"tracing", "tracing",
@ -1842,6 +1843,7 @@ dependencies = [
"sha2", "sha2",
"sqlx-core", "sqlx-core",
"sqlx-mysql", "sqlx-mysql",
"sqlx-postgres",
"sqlx-sqlite", "sqlx-sqlite",
"syn 1.0.109", "syn 1.0.109",
"tempfile", "tempfile",
@ -1887,6 +1889,7 @@ dependencies = [
"sqlx-core", "sqlx-core",
"stringprep", "stringprep",
"thiserror", "thiserror",
"time",
"tracing", "tracing",
"whoami", "whoami",
] ]
@ -1926,6 +1929,7 @@ dependencies = [
"sqlx-core", "sqlx-core",
"stringprep", "stringprep",
"thiserror", "thiserror",
"time",
"tracing", "tracing",
"whoami", "whoami",
] ]
@ -1948,6 +1952,7 @@ dependencies = [
"percent-encoding", "percent-encoding",
"serde", "serde",
"sqlx-core", "sqlx-core",
"time",
"tracing", "tracing",
"url", "url",
"urlencoding", "urlencoding",

View file

@ -23,7 +23,7 @@ md-5 = "0.10.6"
rand = "0.8.5" rand = "0.8.5"
secrecy = { version = "0.8.0", features = ["serde"] } secrecy = { version = "0.8.0", features = ["serde"] }
serde = { version = "1.0.196", features = ["derive"] } serde = { version = "1.0.196", features = ["derive"] }
sqlx = { version = "0.7.3", features = ["runtime-tokio", "tls-rustls", "sqlite"] } sqlx = { version = "0.7.3", features = ["runtime-tokio", "tls-rustls", "sqlite", "time"] }
thiserror = "1.0.56" thiserror = "1.0.56"
time = { version = "0.3.34", features = ["formatting", "macros"] } time = { version = "0.3.34", features = ["formatting", "macros"] }
tokio = { version = "1.36.0", features = ["macros", "rt-multi-thread"] } tokio = { version = "1.36.0", features = ["macros", "rt-multi-thread"] }

View file

@ -14,7 +14,7 @@ use tokio::sync::Mutex;
use tracing::{event, instrument, Level}; use tracing::{event, instrument, Level};
use crate::{ use crate::{
db::{/* Database, */ Database, SqliteDatabase}, db::{/* Database, */ Database, SqliteDatabase, UserTokenEntry},
secrets::{ secrets::{
PadlockGenerationSecret, Password, ServerHash, ServerPadlock, UserServerKey, UserToken, PadlockGenerationSecret, Password, ServerHash, ServerPadlock, UserServerKey, UserToken,
}, },
@ -69,8 +69,8 @@ impl UserAuthenticator {
) -> Result<(), AuthenticationError> { ) -> Result<(), AuthenticationError> {
let mut db = self.db.lock().await; let mut db = self.db.lock().await;
if let Some(user_token) = db.get_token(username).await? { if let Some(UserTokenEntry::Valid(user_token, ..)) = &db.get_token(username).await? {
if token == &user_token { if token == user_token {
return Ok(()); return Ok(());
} }
} }

View file

@ -11,8 +11,13 @@ const DB_URI_DEFAULT: &str = "sqlite://sqlite.db";
const TABLE_USER_TOKENS: &str = "user_tokens"; const TABLE_USER_TOKENS: &str = "user_tokens";
pub enum UserTokenEntry {
Valid(UserToken, time::Time, time::Time),
Invalid(UserToken, time::Time, time::Time),
}
pub trait Database { pub trait Database {
async fn get_token(&mut self, username: &str) -> Result<Option<UserToken>, sqlx::Error>; async fn get_token(&mut self, username: &str) -> Result<Option<UserTokenEntry>, sqlx::Error>;
async fn save_token(&mut self, username: &str, token: &UserToken) -> Result<(), sqlx::Error>; async fn save_token(&mut self, username: &str, token: &UserToken) -> Result<(), sqlx::Error>;
} }
@ -60,21 +65,26 @@ impl SqliteDatabase {
impl Database for SqliteDatabase { impl Database for SqliteDatabase {
#[instrument] #[instrument]
async fn get_token(&mut self, username: &str) -> Result<Option<UserToken>, sqlx::Error> { async fn get_token(&mut self, username: &str) -> Result<Option<UserTokenEntry>, sqlx::Error> {
let row: Option<(String,)> = query_as( let row: Option<(String, bool, time::Time, time::Time)> = query_as(
"SELECT token "SELECT token, valid, created, last_used
FROM user_tokens FROM user_tokens
WHERE WHERE username = ?
username = ? ORDER BY created DESC",
AND valid = TRUE
ORDER BY
created DESC",
) )
.bind(username) .bind(username)
.fetch_optional(&mut self.conn) .fetch_optional(&mut self.conn)
.await?; .await?;
Ok(row.map(|(token_str, ..)| UserToken::from(token_str))) Ok(row.map(|row| match row {
(token_str, true, created, last_used) => {
UserTokenEntry::Valid(UserToken::from(token_str), created, last_used)
}
(token_str, false, created, last_used) => {
UserTokenEntry::Invalid(UserToken::from(token_str), created, last_used)
}
}))
} }
#[instrument] #[instrument]