use tokio::sync::RwLock; use std::sync::Arc; use crate::db::error::BoxedError; use crate::db::{DatabaseInterface, UserRef}; #[derive(Clone, Debug)] pub struct Database { pub inner: Arc>, } impl Database { pub fn new(db: D) -> Self { Self { inner: Arc::new(RwLock::new(db)), } } } impl Database { /// Return false if the user doesn't exist, or the password is wrong. /// /// TODO: should we return something else when the account doesn't exist? /// or is it a feature to behave in the same way? /// /// TODO: we may want to make sure the method runs in constant time /// to avoid leaking information about existing users... /// or maybe we do not care. pub async fn check_password(&self, user: &UserRef, password: &str) -> Result { let Some(user) = self.get_user(user).await? else { tracing::debug!("check_password: User not found {user}"); return Ok(false); }; tracing::debug!("Comparing {} and {}", user.password, password); Ok(user.password == password) } }