fabaccess-bffh/bffhd/db/pass.rs

73 lines
2.2 KiB
Rust
Raw Normal View History

2020-11-24 15:57:23 +01:00
use std::sync::Arc;
2021-10-20 18:37:50 +02:00
use super::Environment;
use super::AllocAdapter;
use super::DB;
use super::raw::RawDB;
use super::{DatabaseFlags, WriteFlags};
use crate::db::Result;
use super::Transaction;
2020-11-24 15:57:23 +01:00
use argon2;
2021-10-20 18:37:50 +02:00
type Adapter = AllocAdapter<String>;
2021-10-28 01:10:35 +02:00
#[derive(Clone, Debug)]
2020-11-24 15:57:23 +01:00
pub struct PassDB {
env: Arc<Environment>,
2021-10-20 18:37:50 +02:00
db: DB<Adapter>,
2020-11-24 15:57:23 +01:00
}
impl PassDB {
2021-10-20 18:37:50 +02:00
pub unsafe fn new(env: Arc<Environment>, db: RawDB) -> Self {
let db = DB::new_unchecked(db);
Self { env, db }
2020-11-24 15:57:23 +01:00
}
2021-10-20 18:37:50 +02:00
pub unsafe fn open(env: Arc<Environment>) -> Result<Self> {
let db = RawDB::open(&env, Some("pass"))?;
Ok(Self::new(env, db))
2020-11-30 07:23:47 +01:00
}
2021-10-20 18:37:50 +02:00
pub unsafe fn create(env: Arc<Environment>) -> Result<Self> {
let flags = DatabaseFlags::empty();
let db = RawDB::create(&env, Some("pass"), flags)?;
Ok(Self::new(env, db))
2020-11-24 15:57:23 +01:00
}
2021-10-20 18:37:50 +02:00
pub fn check_pw<P: AsRef<[u8]>>(&self, uid: &str, inpass: P) -> Result<Option<bool>> {
2020-11-30 07:23:47 +01:00
let txn = self.env.begin_ro_txn()?;
2021-10-20 18:37:50 +02:00
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)
}
2020-11-30 07:23:47 +01:00
}
2020-11-24 15:57:23 +01:00
2021-10-20 18:37:50 +02:00
pub fn set_password<P: AsRef<[u8]>>(&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");
2020-12-16 14:25:03 +01:00
2021-10-20 18:37:50 +02:00
let flags = WriteFlags::empty();
2020-12-16 14:25:03 +01:00
let mut txn = self.env.begin_rw_txn()?;
2021-10-20 18:37:50 +02:00
self.db.put(&mut txn, &uid.as_bytes(), &enc, flags)?;
2020-12-16 14:25:03 +01:00
txn.commit()?;
Ok(())
}
2021-10-20 20:56:47 +02:00
pub fn get_all(&self) -> Result<Vec<(String, String)>> {
let txn = self.env.begin_ro_txn()?;
let mut cursor = self.db.open_ro_cursor(&txn)?;
let iter = cursor.iter_start();
let mut out = Vec::new();
for pass in iter {
let (uid, pass) = pass?;
let uid = unsafe { std::str::from_utf8_unchecked(uid).to_string() };
2021-10-27 17:53:00 +02:00
let pass = pass.as_str().to_string();
2021-10-20 20:56:47 +02:00
out.push((uid, pass));
}
Ok(out)
}
2021-10-20 18:37:50 +02:00
}