db: treat emails correctly during publication
This commit is contained in:
parent
c3d4b448a5
commit
30bb4b2993
|
@ -53,7 +53,7 @@ mod stateful_tokens;
|
|||
pub use stateful_tokens::StatefulTokens;
|
||||
|
||||
mod openpgp_utils;
|
||||
use openpgp_utils::{tpk_filter_userids, tpk_to_string, tpk_clean, is_status_revoked, POLICY};
|
||||
use openpgp_utils::{tpk_filter_userids, tpk_filter_alive_emails, tpk_to_string, tpk_clean, is_status_revoked, POLICY};
|
||||
|
||||
#[cfg(test)]
|
||||
mod test;
|
||||
|
@ -270,36 +270,11 @@ pub trait Database: Sync + Send {
|
|||
return Ok(ImportResult::Unchanged(TpkStatus { is_revoked, email_status, unparsed_uids }));
|
||||
}
|
||||
|
||||
// If the key is revoked, consider all uids revoked
|
||||
let newly_revoked_uids: Vec<&UserID> = if is_revoked {
|
||||
full_tpk_new.userids().bundles().map(|binding| binding.userid()).collect()
|
||||
let published_tpk_new = if is_revoked {
|
||||
tpk_filter_alive_emails(&full_tpk_new, &[])
|
||||
} else {
|
||||
let revoked_uids: Vec<UserID> = full_tpk_new
|
||||
.userids()
|
||||
.bundles()
|
||||
.filter(|binding| is_status_revoked(binding.revoked(&*POLICY, None)))
|
||||
.map(|binding| binding.userid().clone())
|
||||
.collect();
|
||||
|
||||
published_tpk_old
|
||||
.as_ref()
|
||||
.map(|tpk| tpk
|
||||
.userids()
|
||||
.bundles()
|
||||
.map(|binding| binding.userid())
|
||||
.filter(|uid| revoked_uids.contains(uid))
|
||||
.collect()
|
||||
).unwrap_or_default()
|
||||
};
|
||||
|
||||
let published_tpk_new = tpk_filter_userids(
|
||||
&full_tpk_new, |uid| {
|
||||
if let Ok(email) = Email::try_from(uid) {
|
||||
published_emails.contains(&email) && !newly_revoked_uids.contains(&uid)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})?;
|
||||
tpk_filter_alive_emails(&full_tpk_new, &published_emails)
|
||||
}?;
|
||||
|
||||
let newly_revoked_emails: Vec<&Email> = published_emails
|
||||
.iter()
|
||||
|
@ -470,12 +445,10 @@ pub trait Database: Sync + Send {
|
|||
return Ok(());
|
||||
}
|
||||
|
||||
let published_tpk_new = {
|
||||
tpk_filter_userids(&full_tpk, |uid| {
|
||||
Email::try_from(uid).map(|email| email == *email_new)
|
||||
.unwrap_or(false) || published_uids_old.contains(uid)
|
||||
})?
|
||||
};
|
||||
let mut published_emails = published_emails_old.clone();
|
||||
published_emails.push(email_new.clone());
|
||||
|
||||
let published_tpk_new = tpk_filter_alive_emails(&full_tpk, &published_emails)?;
|
||||
|
||||
if !published_tpk_new
|
||||
.userids()
|
||||
|
@ -556,7 +529,7 @@ pub trait Database: Sync + Send {
|
|||
.collect();
|
||||
|
||||
let published_tpk_new = {
|
||||
tpk_filter_userids(&published_tpk_old, |uid| email_remove(uid))?
|
||||
tpk_filter_userids(&published_tpk_old, |uid| email_remove(uid.userid()))?
|
||||
};
|
||||
|
||||
let published_emails_new: Vec<Email> = published_tpk_new
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
use failure::Fallible as Result;
|
||||
use std::convert::TryFrom;
|
||||
|
||||
use openpgp::{
|
||||
Cert,
|
||||
cert::components::ComponentBundle,
|
||||
RevocationStatus,
|
||||
armor::{Writer, Kind},
|
||||
packet::UserID,
|
||||
|
@ -9,6 +11,8 @@ use openpgp::{
|
|||
policy::StandardPolicy,
|
||||
};
|
||||
|
||||
use Email;
|
||||
|
||||
lazy_static! {
|
||||
pub static ref POLICY: StandardPolicy = StandardPolicy::new();
|
||||
}
|
||||
|
@ -62,10 +66,23 @@ pub fn tpk_clean(tpk: &Cert) -> Result<Cert> {
|
|||
Cert::from_packet_pile(acc.into())
|
||||
}
|
||||
|
||||
/// Filters the Cert, keeping only UserIDs that aren't revoked, and whose emails match the given list
|
||||
pub fn tpk_filter_alive_emails(tpk: &Cert, emails: &[Email]) -> Result<Cert> {
|
||||
tpk_filter_userids(tpk, |uid| {
|
||||
if is_status_revoked(uid.revoked(&*POLICY, None)) {
|
||||
false
|
||||
} else if let Ok(email) = Email::try_from(uid.userid()) {
|
||||
emails.contains(&email)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Filters the Cert, keeping only those UserIDs that fulfill the
|
||||
/// predicate `filter`.
|
||||
pub fn tpk_filter_userids<F>(tpk: &Cert, filter: F) -> Result<Cert>
|
||||
where F: Fn(&UserID) -> bool
|
||||
where F: Fn(&ComponentBundle<UserID>) -> bool
|
||||
{
|
||||
// Iterate over the Cert, pushing packets we want to merge
|
||||
// into the accumulator.
|
||||
|
@ -91,7 +108,7 @@ pub fn tpk_filter_userids<F>(tpk: &Cert, filter: F) -> Result<Cert>
|
|||
// Updates for UserIDs fulfilling `filter`.
|
||||
for uidb in tpk.userids().bundles() {
|
||||
// Only include userids matching filter
|
||||
if filter(uidb.userid()) {
|
||||
if filter(uidb) {
|
||||
acc.push(uidb.userid().clone().into());
|
||||
for s in uidb.self_signatures() { acc.push(s.clone().into()) }
|
||||
for s in uidb.certifications() { acc.push(s.clone().into()) }
|
||||
|
|
Loading…
Reference in New Issue