use super::passport::Passport;
use crate::Ticket;
use anyhow::anyhow;
use log::debug;
use std::collections::HashMap;
pub trait PassportRegister {
fn passport(&self, passport_id: &str) -> anyhow::Result<Option<Passport>>;
fn set_passport(&mut self, passport: Passport) -> anyhow::Result<String>;
fn verify_credentials(
&self,
ticket: &Ticket,
) -> anyhow::Result<Option<Passport>>;
}
pub struct MemoryPassportRegister {
passports: HashMap<String, Passport>,
}
impl From<Vec<Passport>> for MemoryPassportRegister {
fn from(value: Vec<Passport>) -> Self {
let mut passports = HashMap::new();
for val in value {
passports.insert(val.id.clone(), val);
}
Self { passports }
}
}
impl PassportRegister for MemoryPassportRegister {
fn passport(&self, passport_id: &str) -> anyhow::Result<Option<Passport>> {
Ok(self.passports.get(passport_id).map(|p| p.to_owned()))
}
fn set_passport(&mut self, passport: Passport) -> anyhow::Result<String> {
let id = passport.id.clone();
self.passports.insert(id.clone(), passport);
Ok(id)
}
fn verify_credentials(
&self,
ticket: &Ticket,
) -> anyhow::Result<Option<Passport>> {
let Some(passport) = self.passport(&ticket.id)? else {
debug!("User with id {} not found.", ticket.id);
return Ok(None);
};
if passport.verify_password(&ticket.secret)? {
Ok(Some(passport))
} else {
Err(anyhow!("Invalid credentials."))
}
}
}