Verify all userids with the same address with one token.

- See #75.
This commit is contained in:
Justus Winter 2019-03-11 11:06:56 +01:00
parent 9e9ff04b72
commit 102c71afc5
No known key found for this signature in database
GPG Key ID: 686F55B4AB2B3386
2 changed files with 35 additions and 18 deletions

View File

@ -98,6 +98,19 @@ impl Verify {
email: Email::try_from(uidb.userid())?,
})
}
/// Extends the verification token by this userid binding.
fn extend(&mut self, uidb: &UserIDBinding) -> Result<()> {
use openpgp::serialize::Serialize;
uidb.userid().serialize(&mut self.packets)?;
// Serialize selfsigs and certifications, revocations are
// never stripped from the TPKs in the first place.
for s in uidb.selfsigs() { s.serialize(&mut self.packets)? }
for s in uidb.certifications() { s.serialize(&mut self.packets)? }
Ok(())
}
}
#[derive(Serialize, Deserialize, Clone, Debug)]
@ -312,11 +325,12 @@ pub trait Database: Sync + Send {
}
fn merge_or_publish(&self, mut tpk: TPK) -> Result<Vec<(Email, String)>> {
use std::collections::HashMap;
use openpgp::RevocationStatus;
let fpr = Fingerprint::try_from(tpk.primary().fingerprint())?;
let mut all_uids = Vec::default();
let mut active_uids = Vec::default();
let mut unverified_uids: HashMap<Email, Verify> = HashMap::new();
let mut verified_uids = Vec::default();
let _ = self.lock();
@ -358,12 +372,20 @@ pub trait Database: Sync + Send {
if add_to_verified {
verified_uids.push(email.clone());
} else {
let payload = Verify::new(uid, fpr.clone())?;
// Hackaround mutable borrow in else.
let updated =
if let Some(token) = unverified_uids.get_mut(&email)
{
token.extend(uid)?;
true
} else {
false
};
active_uids.push((
email.clone(),
self.new_verify_token(payload)?,
));
if ! updated {
unverified_uids.insert(
email.clone(), Verify::new(uid, fpr.clone())?);
}
}
}
}
@ -390,7 +412,11 @@ pub trait Database: Sync + Send {
self.link_email(&email, &fpr)?;
}
Ok(active_uids)
let mut tokens = Vec::new();
for (fp, verify) in unverified_uids.into_iter() {
tokens.push((fp, self.new_verify_token(verify)?));
}
Ok(tokens)
}
// if (uid, fpr) = pop-token(tok) {

View File

@ -676,19 +676,10 @@ pub fn test_same_email_2<D: Database>(db: &mut D) {
let tokens = db.merge_or_publish(tpk.clone()).unwrap();
// verify uid1
assert_eq!(tokens.len(), 2);
assert_eq!(tokens.len(), 1);
assert!(db.verify_token(&tokens[0].1).unwrap().is_some());
// fetch by both user ids. Even though we didn't verify uid2, the
// email is the same, and both should return exactly uid1.
assert_eq!(get_userids(&db.by_email(&email1).unwrap()[..]),
vec![ uid1.clone() ]);
assert_eq!(get_userids(&db.by_email(&email2).unwrap()[..]),
vec![ uid1.clone() ]);
assert!(db.verify_token(&tokens[1].1).unwrap().is_some());
// fetch by both user ids. We've now verified uid2.
// fetch by both user ids.
assert_eq!(get_userids(&db.by_email(&email1).unwrap()[..]),
vec![ uid1.clone(), uid2.clone() ]);
assert_eq!(get_userids(&db.by_email(&email2).unwrap()[..]),