use crate::dat::DatPayload;
use crate::dat_key::{DatKey, Kid};
use crate::error::DatError;
use itertools::Itertools;
use std::sync::RwLock;
use crate::dat_records::DatRecords;
use crate::signature_key::SignatureKeyOutOption;
use crate::util::now_unix_timestamp;
pub struct DatBank<T: Kid> {
issue_key: RwLock<Option<DatKey<T>>>,
verify_keys: RwLock<Vec<DatKey<T>>>,
}
impl <T: Kid> DatBank<T> {
pub fn new() -> Self {
DatBank {
issue_key: RwLock::new(None),
verify_keys: RwLock::new(vec![]),
}
}
pub fn to_dat(&self, plain: &str, secure: &str) -> Result<String, DatError> {
if let Some(key) = self.issue_key.read().unwrap().as_ref() {
key.to_dat(plain, secure)
} else {
Err(DatError::NoAvailableKey)
}
}
pub fn to_payload(&self, dat: String) -> Result<DatPayload, DatError> {
let dat_records: DatRecords<T> = DatRecords::from(dat)?;
let kid = dat_records.kid();
if let Some(key) = self.verify_keys.read().unwrap().iter().find(|e| &e.kid == kid) {
key.to_payload(&dat_records)
} else {
Err(DatError::KidNotFound)
}
}
pub fn to_payload_without_verify(&self, dat: String) -> Result<DatPayload, DatError> {
let dat_records: DatRecords<T> = DatRecords::from(dat)?;
let kid = dat_records.kid();
if let Some(key) = self.verify_keys.read().unwrap().iter().find(|e| &e.kid == kid) {
key.to_payload_without_verify(&dat_records)
} else {
Err(DatError::KidNotFound)
}
}
pub fn export_kids(&self) -> Vec<T> {
self.verify_keys.read().unwrap().iter().map(|key| key.kid.clone()).collect()
}
pub fn export_keys_format(&self, signature_key_out_option: SignatureKeyOutOption) -> String {
self.verify_keys.read().unwrap().iter().map(|key| key.format(signature_key_out_option).unwrap()).join("\n")
}
pub fn export_keys(&self) -> Vec<DatKey<T>> {
self.verify_keys.read().unwrap().clone()
}
pub fn import_keys_format(&self, format: &str, clear: bool) -> Result<(), DatError> {
let new_keys = format.lines()
.filter(|e| !e.is_empty())
.map(|e| e.parse::<DatKey<T>>())
.collect::<Result<Vec<DatKey<T>>, DatError>>()?;
self.import_keys(new_keys, clear)
}
pub fn import_keys(&self, new_keys: Vec<DatKey<T>>, clear: bool) -> Result<(), DatError> {
let now = now_unix_timestamp();
let mut keys = if clear {
vec![]
} else {
self.verify_keys.read().unwrap().clone()
};
for key in new_keys {
if !keys.contains(&key) {
keys.push(key);
}
}
let keys = keys.into_iter()
.filter(|key| key.key_expire() >= now)
.sorted_by(|a, b| a.issue_begin.cmp(&b.issue_begin))
.collect::<Vec<DatKey<T>>>();
let issue_key_set: Option<DatKey<T>> = keys.iter()
.rev()
.find(|e| e.issue_begin() <= now && e.issue_end() > now)
.cloned();
*self.issue_key.write().unwrap() = issue_key_set;
*self.verify_keys.write().unwrap() = keys;
Ok(())
}
}