use std::sync::Arc; use super::Environment; use super::AllocAdapter; use super::DB; use super::raw::RawDB; use super::{DatabaseFlags, WriteFlags}; use crate::db::Result; use super::Transaction; use argon2; type Adapter = AllocAdapter; #[derive(Clone)] pub struct PassDB { env: Arc, db: DB, } impl PassDB { pub unsafe fn new(env: Arc, db: RawDB) -> Self { let db = DB::new_unchecked(db); Self { env, db } } pub unsafe fn open(env: Arc) -> Result { let db = RawDB::open(&env, Some("pass"))?; Ok(Self::new(env, db)) } pub unsafe fn create(env: Arc) -> Result { let flags = DatabaseFlags::empty(); let db = RawDB::create(&env, Some("pass"), flags)?; Ok(Self::new(env, db)) } pub fn check_pw>(&self, uid: &str, inpass: P) -> Result> { let txn = self.env.begin_ro_txn()?; if let Some(pass) = self.db.get(&txn, &uid.as_bytes())? { Ok(argon2::verify_encoded(pass.as_str(), inpass.as_ref()) .ok()) } else { Ok(None) } } pub fn set_password>(&self, uid: &str, password: P) -> Result<()> { let cfg = argon2::Config::default(); let salt: [u8; 10] = rand::random(); let enc = argon2::hash_encoded(password.as_ref(), &salt, &cfg) .expect("Hashing password failed for static valid config"); let flags = WriteFlags::empty(); let mut txn = self.env.begin_rw_txn()?; self.db.put(&mut txn, &uid.as_bytes(), &enc, flags)?; txn.commit()?; Ok(()) } }