db: return more detailed result info

This commit is contained in:
Vincent Breitmoser 2019-05-27 11:28:29 +02:00
parent 19d4eb00cd
commit dc3454facb
4 changed files with 54 additions and 34 deletions

View File

@ -395,7 +395,7 @@ impl Database for Filesystem {
if !link_keyid_target.ends_with(&path_published) {
info!("KeyID points to different key for {} (expected {:?} to be suffix of {:?})",
fpr, &path_published, &link_keyid_target);
Err(failure::err_msg("Collision with a different key!"))?;
Err(failure::err_msg(format!("KeyID collision for key {}", fpr)))?;
}
}
@ -403,7 +403,7 @@ impl Database for Filesystem {
if !link_fpr_target.ends_with(&path_published) {
info!("Fingerprint points to different key for {} (expected {:?} to be suffix of {:?})",
fpr, &path_published, &link_fpr_target);
Err(failure::err_msg("Collision with a different key!"))?;
Err(failure::err_msg(format!("Fingerprint collision for key {}", fpr)))?;
}
}
@ -599,12 +599,12 @@ mod tests {
let k3 = TPKBuilder::default().add_userid("c@invalid.example.org")
.generate().unwrap().0;
assert!(db.merge(k1).unwrap().email_status.len() > 0);
assert!(db.merge(k2.clone()).unwrap().email_status.len() > 0);
assert!(!db.merge(k2).unwrap().email_status.len() > 0);
assert!(db.merge(k3.clone()).unwrap().email_status.len() > 0);
assert!(!db.merge(k3.clone()).unwrap().email_status.len() > 0);
assert!(!db.merge(k3).unwrap().email_status.len() > 0);
assert!(db.merge(k1).unwrap().into_tpk_status().email_status.len() > 0);
assert!(db.merge(k2.clone()).unwrap().into_tpk_status().email_status.len() > 0);
assert!(!db.merge(k2).unwrap().into_tpk_status().email_status.len() > 0);
assert!(db.merge(k3.clone()).unwrap().into_tpk_status().email_status.len() > 0);
assert!(!db.merge(k3.clone()).unwrap().into_tpk_status().email_status.len() > 0);
assert!(!db.merge(k3).unwrap().into_tpk_status().email_status.len() > 0);
}
#[test]

View File

@ -82,6 +82,22 @@ pub enum EmailAddressStatus {
Published,
}
pub enum ImportResult {
New(TpkStatus),
Updated(TpkStatus),
Unchanged(TpkStatus),
}
impl ImportResult {
pub fn into_tpk_status(self) -> TpkStatus {
match self {
ImportResult::New(status) => status,
ImportResult::Updated(status) => status,
ImportResult::Unchanged(status) => status,
}
}
}
#[derive(Debug,PartialEq)]
pub struct TpkStatus {
pub is_revoked: bool,
@ -145,7 +161,7 @@ pub trait Database: Sync + Send {
/// - abort if any problems come up!
/// 5. Move full and published temporary TPK to their location
/// 6. Update all symlinks
fn merge(&self, new_tpk: TPK) -> Result<TpkStatus> {
fn merge(&self, new_tpk: TPK) -> Result<ImportResult> {
let fpr_primary = Fingerprint::try_from(new_tpk.primary().fingerprint())?;
let _lock = self.lock()?;
@ -157,6 +173,7 @@ pub trait Database: Sync + Send {
let full_tpk_old = self.by_fpr_full(&fpr_primary)
.and_then(|bytes| TPK::from_bytes(bytes.as_ref()).ok());
let is_update = full_tpk_old.is_some();
let (full_tpk_new, full_tpk_unchanged) = if let Some(full_tpk_old) = full_tpk_old {
let full_tpk_new = new_tpk.merge(full_tpk_old.clone())?;
let full_tpk_unchanged = full_tpk_new == full_tpk_old;
@ -198,8 +215,7 @@ pub trait Database: Sync + Send {
// Abort if no changes were made
if full_tpk_unchanged {
println!("tpk unchanged!");
return Ok(TpkStatus { is_revoked, email_status });
return Ok(ImportResult::Unchanged(TpkStatus { is_revoked, email_status }));
}
let revoked_uids: Vec<UserID> = full_tpk_new
@ -268,7 +284,11 @@ pub trait Database: Sync + Send {
}
}
Ok(TpkStatus { is_revoked, email_status })
if is_update {
Ok(ImportResult::Updated(TpkStatus { is_revoked, email_status }))
} else {
Ok(ImportResult::New(TpkStatus { is_revoked, email_status }))
}
}
fn get_tpk_status(&self, fpr_primary: &Fingerprint, known_addresses: &[Email]) -> Result<TpkStatus> {

View File

@ -44,7 +44,7 @@ pub fn test_uid_verification<D: Database>(db: &mut D) {
let email2 = Email::from_str(str_uid2).unwrap();
// upload key
let tpk_status = db.merge(tpk.clone()).unwrap();
let tpk_status = db.merge(tpk.clone()).unwrap().into_tpk_status();
let fpr = Fingerprint::try_from(tpk.fingerprint()).unwrap();
assert_eq!(TpkStatus {
@ -150,7 +150,7 @@ pub fn test_uid_verification<D: Database>(db: &mut D) {
);
}
let tpk_status = db.merge(tpk.clone()).unwrap();
let tpk_status = db.merge(tpk.clone()).unwrap().into_tpk_status();
assert_eq!(TpkStatus {
is_revoked: false,
email_status: vec!(
@ -171,7 +171,7 @@ pub fn test_uid_verification<D: Database>(db: &mut D) {
let pile : PacketPile = packets.collect::<Vec<Packet>>().into();
let short_tpk = TPK::from_packet_pile(pile).unwrap();
let tpk_status = db.merge(short_tpk).unwrap();
let tpk_status = db.merge(short_tpk).unwrap().into_tpk_status();
assert_eq!(TpkStatus {
is_revoked: false,
email_status: vec!(
@ -225,7 +225,7 @@ pub fn test_uid_verification<D: Database>(db: &mut D) {
let pile : PacketPile = packets.into();
let ext_tpk = TPK::from_packet_pile(pile).unwrap();
let tpk_status = db.merge(ext_tpk).unwrap();
let tpk_status = db.merge(ext_tpk).unwrap().into_tpk_status();
assert_eq!(TpkStatus {
is_revoked: false,
@ -270,14 +270,14 @@ pub fn test_reupload<D: Database>(db: &mut D) {
let email2 = Email::from_str(str_uid2).unwrap();
// upload key
db.merge(tpk.clone()).unwrap();
db.merge(tpk.clone()).unwrap().into_tpk_status();
// verify 1st uid
db.set_email_published(&fpr, &email1).unwrap();
assert!(db.by_email(&email2).is_none() ^ db.by_email(&email1).is_none());
// reupload
let tpk_status = db.merge(tpk).unwrap();
let tpk_status = db.merge(tpk).unwrap().into_tpk_status();
assert_eq!(TpkStatus {
is_revoked: false,
@ -303,14 +303,14 @@ pub fn test_uid_replacement<D: Database>(db: &mut D) {
let email1 = Email::from_str(str_uid1).unwrap();
// upload key
db.merge(tpk1).unwrap();
db.merge(tpk1).unwrap().into_tpk_status();
// verify 1st uid
db.set_email_published(&fpr1, &email1).unwrap();
assert_eq!(TPK::from_bytes(db.by_email(&email1).unwrap().as_bytes()).unwrap().fingerprint(), pgp_fpr1);
// replace
db.merge(tpk2).unwrap();
db.merge(tpk2).unwrap().into_tpk_status();
// Before tpk_status are verified, the first binding is still valid.
assert!(db.by_email(&email1).is_some());
@ -338,7 +338,7 @@ pub fn test_uid_deletion<D: Database>(db: &mut D) {
let email2 = Email::from_str(str_uid2).unwrap();
// upload key and verify uids
let tpk_status = db.merge(tpk).unwrap();
let tpk_status = db.merge(tpk).unwrap().into_tpk_status();
assert_eq!(TpkStatus {
is_revoked: false,
email_status: vec!(
@ -389,7 +389,7 @@ pub fn test_subkey_lookup<D: Database>(db: &mut D) {
.0;
// upload key
let _ = db.merge(tpk.clone()).unwrap();
let _ = db.merge(tpk.clone()).unwrap().into_tpk_status();
let primary_fpr = Fingerprint::try_from(tpk.fingerprint()).unwrap();
let sub1_fpr = Fingerprint::try_from(
tpk.subkeys().next().map(|x| x.subkey().fingerprint()).unwrap(),
@ -418,7 +418,7 @@ pub fn test_kid_lookup<D: Database>(db: &mut D) {
.0;
// upload key
let _ = db.merge(tpk.clone()).unwrap();
let _ = db.merge(tpk.clone()).unwrap().into_tpk_status();
let primary_kid = KeyID::try_from(tpk.fingerprint()).unwrap();
let sub1_kid = KeyID::try_from(
tpk.subkeys().next().map(|x| x.subkey().fingerprint()).unwrap(),
@ -455,7 +455,7 @@ pub fn test_upload_revoked_tpk<D: Database>(db: &mut D) {
}
// upload key
let tpk_status = db.merge(tpk).unwrap();
let tpk_status = db.merge(tpk).unwrap().into_tpk_status();
assert_eq!(TpkStatus {
is_revoked: true,
email_status: vec!(
@ -482,7 +482,7 @@ pub fn test_uid_revocation<D: Database>(db: &mut D) {
let fpr = Fingerprint::try_from(tpk.fingerprint()).unwrap();
// upload key
let tpk_status = db.merge(tpk.clone()).unwrap();
let tpk_status = db.merge(tpk.clone()).unwrap().into_tpk_status();
assert_eq!(TpkStatus {
is_revoked: false,
email_status: vec!(
@ -516,7 +516,7 @@ pub fn test_uid_revocation<D: Database>(db: &mut D) {
};
assert_eq!(sig.sigtype(), SignatureType::CertificateRevocation);
let tpk = tpk.merge_packets(vec![sig.into()]).unwrap();
let tpk_status = db.merge(tpk).unwrap();
let tpk_status = db.merge(tpk).unwrap().into_tpk_status();
assert_eq!(TpkStatus {
is_revoked: false,
email_status: vec!(
@ -538,7 +538,7 @@ pub fn test_unlink_uid<D: Database>(db: &mut D) {
let tpk = TPKBuilder::default().add_userid(uid).generate().unwrap().0;
let fpr = Fingerprint::try_from(tpk.fingerprint()).unwrap();
db.merge(tpk.clone()).unwrap();
db.merge(tpk.clone()).unwrap().into_tpk_status();
db.set_email_published(&fpr, &email).unwrap();
assert!(db.by_email(&email).is_some());
@ -559,7 +559,7 @@ pub fn test_unlink_uid<D: Database>(db: &mut D) {
};
assert_eq!(sig.sigtype(), SignatureType::CertificateRevocation);
let tpk_evil = tpk_evil.merge_packets(vec![sig.into()]).unwrap();
let tpk_status = db.merge(tpk_evil).unwrap();
let tpk_status = db.merge(tpk_evil).unwrap().into_tpk_status();
assert_eq!(TpkStatus {
is_revoked: false,
email_status: vec!(
@ -603,14 +603,14 @@ pub fn test_same_email_1<D: Database>(db: &mut D) {
let email2 = Email::from_str(str_uid2).unwrap();
// upload keys.
let tpk_status1 = db.merge(tpk1).unwrap();
let tpk_status1 = db.merge(tpk1).unwrap().into_tpk_status();
assert_eq!(TpkStatus {
is_revoked: false,
email_status: vec!(
(email1.clone(), EmailAddressStatus::NotPublished),
)
}, tpk_status1);
let tpk_status2 = db.merge(tpk2.clone()).unwrap();
let tpk_status2 = db.merge(tpk2.clone()).unwrap().into_tpk_status();
assert_eq!(TpkStatus {
is_revoked: false,
email_status: vec!(
@ -652,7 +652,7 @@ pub fn test_same_email_1<D: Database>(db: &mut D) {
};
assert_eq!(sig.sigtype(), SignatureType::CertificateRevocation);
let tpk2 = tpk2.merge_packets(vec![sig.into()]).unwrap();
let tpk_status2 = db.merge(tpk2).unwrap();
let tpk_status2 = db.merge(tpk2).unwrap().into_tpk_status();
assert_eq!(TpkStatus {
is_revoked: false,
email_status: vec!(
@ -684,7 +684,7 @@ pub fn test_same_email_2<D: Database>(db: &mut D) {
let fpr = Fingerprint::try_from(tpk.fingerprint()).unwrap();
// upload key
let tpk_status = db.merge(tpk.clone()).unwrap();
let tpk_status = db.merge(tpk.clone()).unwrap().into_tpk_status();
// verify uid1
assert_eq!(TpkStatus {
@ -716,7 +716,7 @@ pub fn test_same_email_2<D: Database>(db: &mut D) {
};
assert_eq!(sig.sigtype(), SignatureType::CertificateRevocation);
let tpk = tpk.merge_packets(vec![sig.into()]).unwrap();
let tpk_status = db.merge(tpk).unwrap();
let tpk_status = db.merge(tpk).unwrap().into_tpk_status();
assert_eq!(TpkStatus {
is_revoked: false,
email_status: vec!(

View File

@ -138,7 +138,7 @@ fn process_key_single(
let fp = Fingerprint::try_from(tpk.fingerprint()).unwrap();
let tpk_status = match db.merge(tpk) {
Ok(tpk_status) => tpk_status,
Ok(import_result) => import_result.into_tpk_status(),
Err(_) => return UploadResponse::err("internal error"),
};