use anyhow::Result;
use super::Key;
use crate::crypto::{self, prelude::*, util};
#[derive(Clone, PartialEq)]
pub struct Recipients {
keys: Vec<Key>,
}
impl Recipients {
pub fn from(keys: Vec<Key>) -> Self {
assert!(keys_same_proto(&keys), "recipient keys must use same proto");
Self { keys }
}
pub fn keys(&self) -> &[Key] {
&self.keys
}
pub fn add(&mut self, key: Key) {
self.keys.push(key);
assert!(
keys_same_proto(&self.keys),
"added recipient key uses different proto"
);
}
pub fn remove(&mut self, key: &Key) {
self.keys.retain(|k| k != key);
}
pub fn remove_all(&mut self, keys: &[Key]) {
self.keys.retain(|k| !keys.contains(k));
}
pub fn has_fingerprint(&self, fingerprint: &str) -> bool {
self.keys
.iter()
.any(|k| util::fingerprints_equal(k.fingerprint(false), fingerprint))
}
}
pub fn contains_own_secret_key(recipients: &Recipients) -> Result<bool> {
let secrets = Recipients::from(crypto::context(crypto::PROTO)?.keys_private()?);
Ok(recipients
.keys()
.iter()
.any(|k| secrets.has_fingerprint(&k.fingerprint(false))))
}
fn keys_same_proto(keys: &[Key]) -> bool {
if keys.len() < 2 {
true
} else {
let proto = keys[0].proto();
keys[1..].iter().all(|k| k.proto() == proto)
}
}