diff --git a/Cargo.toml b/Cargo.toml index 033788e..df5b4f1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ color-eyre = { version = "0.6.2" } ldap3 = { version = "0.11.3", default-features = false, features = ["tls-rustls"] } secrecy = { version = "0.8.0", features = ["serde"] } serde = { version = "1.0.196", features = ["derive"] } -sqlx = { version = "0.7.3", features = ["runtime-tokio", "tls-rustls"] } +sqlx = { version = "0.7.3", features = ["runtime-tokio", "tls-rustls", "sqlite"] } tokio = { version = "1.36.0", features = ["macros", "rt-multi-thread"] } tracing = "0.1.40" tracing-error = "0.2.0" diff --git a/src/auth.rs b/src/auth.rs index 7f5c4e9..da3fac3 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -1,7 +1,11 @@ use secrecy::SecretString; use serde::Deserialize; +use std::sync::Arc; + +use tokio::sync::Mutex; use tracing::instrument; +use crate::db::SqliteDatabase; #[derive(Debug, Clone, Deserialize)] pub struct Password(pub SecretString); @@ -10,21 +14,21 @@ pub struct UserToken(pub SecretString); #[derive(Debug)] pub struct Authenticator { - // TODO + db: Arc>, } impl Authenticator { - pub fn new(/* database credentials ? */) -> Self { - Self {} + pub fn new(db: Arc>) -> Self { + Self { db } } #[instrument] - pub fn create_user_token(&mut self, username: &str, password: &Password) -> UserToken { + pub async fn create_user_token(&mut self, username: &str, password: &Password) -> UserToken { todo!() } #[instrument] - pub fn verify_user_token(&self, token: &UserToken) -> bool { + pub async fn verify_user_token(&self, token: &UserToken) -> bool { todo!() } } diff --git a/src/db.rs b/src/db.rs new file mode 100644 index 0000000..14c3750 --- /dev/null +++ b/src/db.rs @@ -0,0 +1,55 @@ +use sqlx::{query, Connection, SqliteConnection}; + +use crate::auth::UserToken; + +// TODO: allow configuring this via envar +const DB_URI_DEFAULT: &str = "sqlite://sqlite.db"; + +pub trait Database { + async fn get_token(&self, username: &str) -> UserToken; +} + +#[derive(Debug)] +pub struct SqliteDatabase { + conn: SqliteConnection, +} + +impl SqliteDatabase { + pub async fn open() -> Self { + let mut db = Self { + conn: SqliteConnection::connect(DB_URI_DEFAULT) + .await + .expect("Failed to open SQLite database"), + }; + + db.init().await; + + db + } + + pub async fn init(&mut self) { + query( + "CREATE TABLE IF NOT EXISTS user_tokens ( + id INTEGER PRIMARY KEY NOT NULL, + username VARCHAR(255), + token NCHAR(30), + created DATETIME, + valid BOOLEAN, + );", + ) + .execute(&mut self.conn) + .await + .expect("Failed to initialize table user_tokens"); + } +} + +impl Database for SqliteDatabase { + async fn get_token(&self, username: &str) -> UserToken { + todo!() + // query( + // " + // SELECT token, created, valid + // ", + // ) + } +} diff --git a/src/main.rs b/src/main.rs index 8efef20..ca00b12 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,6 +20,7 @@ #![forbid(unsafe_code)] mod auth; +mod db; mod server; use color_eyre::Result;