db: implement simple logging
This commit is contained in:
parent
1a319fc2b9
commit
c624f2a5cf
|
@ -670,6 +670,7 @@ name = "hagrid-database"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"chrono 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
|
@ -21,6 +21,7 @@ pathdiff = "0.1"
|
|||
idna = "0.1"
|
||||
fs2 = "0.4"
|
||||
walkdir = "2.2"
|
||||
chrono = "0.4"
|
||||
|
||||
[lib]
|
||||
name = "hagrid_database"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::collections::HashMap;
|
||||
use std::convert::TryFrom;
|
||||
use std::fs::{create_dir_all, read_link, remove_file, rename, set_permissions, Permissions};
|
||||
use std::fs::{OpenOptions, File, create_dir_all, read_link, remove_file, rename, set_permissions, Permissions};
|
||||
use std::io::Write;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
|
@ -28,6 +28,7 @@ pub struct Filesystem {
|
|||
keys_dir_full: PathBuf,
|
||||
keys_dir_quarantined: PathBuf,
|
||||
keys_dir_published: PathBuf,
|
||||
keys_dir_log: PathBuf,
|
||||
|
||||
links_dir_by_fingerprint: PathBuf,
|
||||
links_dir_by_keyid: PathBuf,
|
||||
|
@ -78,10 +79,12 @@ impl Filesystem {
|
|||
let keys_external_dir: PathBuf = keys_external_dir.into();
|
||||
let keys_dir_full = keys_internal_dir.join("full");
|
||||
let keys_dir_quarantined = keys_internal_dir.join("quarantined");
|
||||
let keys_dir_log = keys_internal_dir.join("log");
|
||||
let keys_dir_published = keys_external_dir.join("pub");
|
||||
create_dir_all(&keys_dir_full)?;
|
||||
create_dir_all(&keys_dir_quarantined)?;
|
||||
create_dir_all(&keys_dir_published)?;
|
||||
create_dir_all(&keys_dir_log)?;
|
||||
|
||||
let links_dir = keys_external_dir.join("links");
|
||||
let links_dir_by_keyid = links_dir.join("by-keyid");
|
||||
|
@ -103,6 +106,7 @@ impl Filesystem {
|
|||
keys_dir_full,
|
||||
keys_dir_published,
|
||||
keys_dir_quarantined,
|
||||
keys_dir_log,
|
||||
|
||||
links_dir_by_keyid,
|
||||
links_dir_by_fingerprint,
|
||||
|
@ -199,6 +203,14 @@ impl Filesystem {
|
|||
}
|
||||
}
|
||||
|
||||
fn open_logfile(&self, file_name: &str) -> Result<File> {
|
||||
let file_path = self.keys_dir_log.join(file_name);
|
||||
Ok(OpenOptions::new()
|
||||
.create(true)
|
||||
.append(true)
|
||||
.open(file_path)?)
|
||||
}
|
||||
|
||||
fn perform_checks(
|
||||
&self,
|
||||
checks_dir: &Path,
|
||||
|
@ -278,6 +290,15 @@ impl Database for Filesystem {
|
|||
Ok(tempfile)
|
||||
}
|
||||
|
||||
fn write_log_append(&self, filename: &str, fpr_primary: &Fingerprint) -> Result<()> {
|
||||
let fingerprint_line = format!("{}\n", fpr_primary.to_string());
|
||||
|
||||
self.open_logfile(filename)?
|
||||
.write_all(fingerprint_line.as_bytes())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn move_tmp_to_full(&self, file: NamedTempFile, fpr: &Fingerprint) -> Result<()> {
|
||||
if self.dry_run {
|
||||
return Ok(());
|
||||
|
@ -628,10 +649,17 @@ mod tests {
|
|||
let _ = Filesystem::new_from_base(tmpdir.path()).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn new() {
|
||||
fn open_db() -> (TempDir, Filesystem, PathBuf) {
|
||||
let tmpdir = TempDir::new().unwrap();
|
||||
let db = Filesystem::new_from_base(tmpdir.path()).unwrap();
|
||||
let log_path = db.keys_dir_log.join(db.get_current_log_filename());
|
||||
|
||||
(tmpdir, db, log_path)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn new() {
|
||||
let (_tmp_dir, db, _log_path) = open_db();
|
||||
let k1 = TPKBuilder::new().add_userid("a@invalid.example.org")
|
||||
.generate().unwrap().0;
|
||||
let k2 = TPKBuilder::new().add_userid("b@invalid.example.org")
|
||||
|
@ -649,125 +677,99 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn uid_verification() {
|
||||
let tmpdir = TempDir::new().unwrap();
|
||||
let mut db = Filesystem::new_from_base(tmpdir.path()).unwrap();
|
||||
|
||||
test::test_uid_verification(&mut db);
|
||||
let (_tmp_dir, mut db, log_path) = open_db();
|
||||
test::test_uid_verification(&mut db, &log_path);
|
||||
db.check_consistency().expect("inconsistent database");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn uid_deletion() {
|
||||
let tmpdir = TempDir::new().unwrap();
|
||||
let mut db = Filesystem::new_from_base(tmpdir.path()).unwrap();
|
||||
|
||||
test::test_uid_deletion(&mut db);
|
||||
let (_tmp_dir, mut db, log_path) = open_db();
|
||||
test::test_uid_deletion(&mut db, &log_path);
|
||||
db.check_consistency().expect("inconsistent database");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn subkey_lookup() {
|
||||
let tmpdir = TempDir::new().unwrap();
|
||||
let mut db = Filesystem::new_from_base(tmpdir.path()).unwrap();
|
||||
|
||||
test::test_subkey_lookup(&mut db);
|
||||
let (_tmp_dir, mut db, log_path) = open_db();
|
||||
test::test_subkey_lookup(&mut db, &log_path);
|
||||
db.check_consistency().expect("inconsistent database");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn kid_lookup() {
|
||||
let tmpdir = TempDir::new().unwrap();
|
||||
let mut db = Filesystem::new_from_base(tmpdir.path()).unwrap();
|
||||
|
||||
test::test_kid_lookup(&mut db);
|
||||
let (_tmp_dir, mut db, log_path) = open_db();
|
||||
test::test_kid_lookup(&mut db, &log_path);
|
||||
db.check_consistency().expect("inconsistent database");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn upload_revoked_tpk() {
|
||||
let tmpdir = TempDir::new().unwrap();
|
||||
let mut db = Filesystem::new_from_base(tmpdir.path()).unwrap();
|
||||
test::test_upload_revoked_tpk(&mut db);
|
||||
let (_tmp_dir, mut db, log_path) = open_db();
|
||||
test::test_upload_revoked_tpk(&mut db, &log_path);
|
||||
db.check_consistency().expect("inconsistent database");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn uid_revocation() {
|
||||
let tmpdir = TempDir::new().unwrap();
|
||||
let mut db = Filesystem::new_from_base(tmpdir.path()).unwrap();
|
||||
|
||||
test::test_uid_revocation(&mut db);
|
||||
let (_tmp_dir, mut db, log_path) = open_db();
|
||||
test::test_uid_revocation(&mut db, &log_path);
|
||||
db.check_consistency().expect("inconsistent database");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn regenerate() {
|
||||
let tmpdir = TempDir::new().unwrap();
|
||||
let mut db = Filesystem::new_from_base(tmpdir.path()).unwrap();
|
||||
|
||||
test::test_regenerate(&mut db);
|
||||
let (_tmp_dir, mut db, log_path) = open_db();
|
||||
test::test_regenerate(&mut db, &log_path);
|
||||
db.check_consistency().expect("inconsistent database");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn key_reupload() {
|
||||
let tmpdir = TempDir::new().unwrap();
|
||||
let mut db = Filesystem::new_from_base(tmpdir.path()).unwrap();
|
||||
|
||||
test::test_reupload(&mut db);
|
||||
let (_tmp_dir, mut db, log_path) = open_db();
|
||||
test::test_reupload(&mut db, &log_path);
|
||||
db.check_consistency().expect("inconsistent database");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn uid_replacement() {
|
||||
let tmpdir = TempDir::new().unwrap();
|
||||
let mut db = Filesystem::new_from_base(tmpdir.path()).unwrap();
|
||||
|
||||
test::test_uid_replacement(&mut db);
|
||||
let (_tmp_dir, mut db, log_path) = open_db();
|
||||
test::test_uid_replacement(&mut db, &log_path);
|
||||
db.check_consistency().expect("inconsistent database");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn uid_unlinking() {
|
||||
let tmpdir = TempDir::new().unwrap();
|
||||
let mut db = Filesystem::new_from_base(tmpdir.path()).unwrap();
|
||||
test::test_unlink_uid(&mut db);
|
||||
let (_tmp_dir, mut db, log_path) = open_db();
|
||||
test::test_unlink_uid(&mut db, &log_path);
|
||||
db.check_consistency().expect("inconsistent database");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn same_email_1() {
|
||||
let tmpdir = TempDir::new().unwrap();
|
||||
let mut db = Filesystem::new_from_base(tmpdir.path()).unwrap();
|
||||
|
||||
test::test_same_email_1(&mut db);
|
||||
let (_tmp_dir, mut db, log_path) = open_db();
|
||||
test::test_same_email_1(&mut db, &log_path);
|
||||
db.check_consistency().expect("inconsistent database");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn same_email_2() {
|
||||
let tmpdir = TempDir::new().unwrap();
|
||||
let mut db = Filesystem::new_from_base(tmpdir.path()).unwrap();
|
||||
|
||||
test::test_same_email_2(&mut db);
|
||||
let (_tmp_dir, mut db, log_path) = open_db();
|
||||
test::test_same_email_2(&mut db, &log_path);
|
||||
db.check_consistency().expect("inconsistent database");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_selfsig() {
|
||||
let tmpdir = TempDir::new().unwrap();
|
||||
let mut db = Filesystem::new_from_base(tmpdir.path()).unwrap();
|
||||
|
||||
test::test_no_selfsig(&mut db);
|
||||
let (_tmp_dir, mut db, log_path) = open_db();
|
||||
test::test_no_selfsig(&mut db, &log_path);
|
||||
db.check_consistency().expect("inconsistent database");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bad_uids() {
|
||||
let tmpdir = TempDir::new().unwrap();
|
||||
let mut db = Filesystem::new_from_base(tmpdir.path()).unwrap();
|
||||
|
||||
test::test_bad_uids(&mut db);
|
||||
let (_tmp_dir, mut db, log_path) = open_db();
|
||||
test::test_bad_uids(&mut db, &log_path);
|
||||
db.check_consistency().expect("inconsistent database");
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,8 @@ use std::convert::TryFrom;
|
|||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
|
||||
use chrono::prelude::Utc;
|
||||
|
||||
extern crate failure;
|
||||
use failure::Error;
|
||||
use failure::Fallible as Result;
|
||||
|
@ -20,6 +22,7 @@ extern crate time;
|
|||
extern crate url;
|
||||
extern crate hex;
|
||||
extern crate walkdir;
|
||||
extern crate chrono;
|
||||
|
||||
use tempfile::NamedTempFile;
|
||||
|
||||
|
@ -214,9 +217,11 @@ pub trait Database: Sync + Send {
|
|||
return Err(failure::err_msg("Not a well-formed key!"));
|
||||
}
|
||||
|
||||
let published_uids: Vec<UserID> = self
|
||||
let published_tpk_old = self
|
||||
.by_fpr(&fpr_primary)
|
||||
.and_then(|bytes| TPK::from_bytes(bytes.as_ref()).ok())
|
||||
.and_then(|bytes| TPK::from_bytes(bytes.as_ref()).ok());
|
||||
let published_uids: Vec<UserID> = published_tpk_old
|
||||
.as_ref()
|
||||
.map(|tpk| tpk.userids()
|
||||
.map(|binding| binding.userid().clone())
|
||||
.collect()
|
||||
|
@ -308,6 +313,13 @@ pub trait Database: Sync + Send {
|
|||
self.move_tmp_to_full(full_tpk_tmp, &fpr_primary)?;
|
||||
self.move_tmp_to_published(published_tpk_tmp, &fpr_primary)?;
|
||||
|
||||
let published_tpk_changed = published_tpk_old
|
||||
.map(|tpk| tpk != published_tpk_clean)
|
||||
.unwrap_or(true);
|
||||
if published_tpk_changed {
|
||||
self.update_write_log(&fpr_primary);
|
||||
}
|
||||
|
||||
for fpr in fpr_not_linked {
|
||||
if let Err(e) = self.link_fpr(&fpr, &fpr_primary) {
|
||||
info!("Error ensuring symlink! {} {} {:?}",
|
||||
|
@ -329,6 +341,18 @@ pub trait Database: Sync + Send {
|
|||
}
|
||||
}
|
||||
|
||||
fn update_write_log(&self, fpr_primary: &Fingerprint) {
|
||||
let log_name = self.get_current_log_filename();
|
||||
println!("{}", log_name);
|
||||
if let Err(e) = self.write_log_append(&log_name, fpr_primary) {
|
||||
error!("Error writing to log! {} {} {}", &log_name, &fpr_primary, e);
|
||||
}
|
||||
}
|
||||
|
||||
fn get_current_log_filename(&self) -> String {
|
||||
Utc::now().format("%Y-%m-%d").to_string()
|
||||
}
|
||||
|
||||
fn get_tpk_status(&self, fpr_primary: &Fingerprint, known_addresses: &[Email]) -> Result<TpkStatus> {
|
||||
let tpk_full = self.by_fpr_full(&fpr_primary)
|
||||
.ok_or_else(|| failure::err_msg("Key not in database!"))
|
||||
|
@ -433,6 +457,7 @@ pub trait Database: Sync + Send {
|
|||
let published_tpk_tmp = self.write_to_temp(&tpk_to_string(&published_tpk_clean)?)?;
|
||||
|
||||
self.move_tmp_to_published(published_tpk_tmp, &fpr_primary)?;
|
||||
self.update_write_log(&fpr_primary);
|
||||
|
||||
if let Err(e) = self.link_email(&email_new, &fpr_primary) {
|
||||
info!("Error ensuring email symlink! {} -> {} {:?}",
|
||||
|
@ -516,6 +541,7 @@ pub trait Database: Sync + Send {
|
|||
let published_tpk_tmp = self.write_to_temp(&tpk_to_string(&published_tpk_clean)?)?;
|
||||
|
||||
self.move_tmp_to_published(published_tpk_tmp, &fpr_primary)?;
|
||||
self.update_write_log(&fpr_primary);
|
||||
|
||||
for unpublished_email in unpublished_emails {
|
||||
if let Err(e) = self.unlink_email(&unpublished_email, &fpr_primary) {
|
||||
|
@ -600,6 +626,7 @@ pub trait Database: Sync + Send {
|
|||
fn move_tmp_to_full(&self, content: NamedTempFile, fpr: &Fingerprint) -> Result<()>;
|
||||
fn move_tmp_to_published(&self, content: NamedTempFile, fpr: &Fingerprint) -> Result<()>;
|
||||
fn write_to_quarantine(&self, fpr: &Fingerprint, content: &[u8]) -> Result<()>;
|
||||
fn write_log_append(&self, filename: &str, fpr_primary: &Fingerprint) -> Result<()>;
|
||||
|
||||
fn check_consistency(&self) -> Result<()>;
|
||||
}
|
||||
|
|
|
@ -26,11 +26,13 @@ use openpgp::{
|
|||
packet::KeyFlags
|
||||
};
|
||||
use types::{Email, Fingerprint, KeyID};
|
||||
use std::path::Path;
|
||||
use std::fs;
|
||||
|
||||
use TpkStatus;
|
||||
use EmailAddressStatus;
|
||||
|
||||
pub fn test_uid_verification<D: Database>(db: &mut D) {
|
||||
pub fn test_uid_verification(db: &mut impl Database, log_path: &Path) {
|
||||
let str_uid1 = "Test A <test_a@example.com>";
|
||||
let str_uid2 = "Test B <test_b@example.com>";
|
||||
let tpk = TPKBuilder::new()
|
||||
|
@ -43,10 +45,11 @@ pub fn test_uid_verification<D: Database>(db: &mut D) {
|
|||
let uid2 = UserID::from(str_uid2);
|
||||
let email1 = Email::from_str(str_uid1).unwrap();
|
||||
let email2 = Email::from_str(str_uid2).unwrap();
|
||||
let fpr = Fingerprint::try_from(tpk.fingerprint()).unwrap();
|
||||
|
||||
// upload key
|
||||
let tpk_status = db.merge(tpk.clone()).unwrap().into_tpk_status();
|
||||
let fpr = Fingerprint::try_from(tpk.fingerprint()).unwrap();
|
||||
check_log_entry(log_path, &fpr);
|
||||
|
||||
assert_eq!(TpkStatus {
|
||||
is_revoked: false,
|
||||
|
@ -153,6 +156,7 @@ pub fn test_uid_verification<D: Database>(db: &mut D) {
|
|||
}
|
||||
|
||||
let tpk_status = db.merge(tpk.clone()).unwrap().into_tpk_status();
|
||||
check_log_entry(log_path, &fpr);
|
||||
assert_eq!(TpkStatus {
|
||||
is_revoked: false,
|
||||
email_status: vec!(
|
||||
|
@ -262,7 +266,7 @@ pub fn test_uid_verification<D: Database>(db: &mut D) {
|
|||
}*/
|
||||
}
|
||||
|
||||
pub fn test_regenerate<D: Database>(db: &mut D) {
|
||||
pub fn test_regenerate(db: &mut impl Database, log_path: &Path) {
|
||||
let str_uid1 = "Test A <test_a@example.com>";
|
||||
let tpk = TPKBuilder::new()
|
||||
.add_userid(str_uid1)
|
||||
|
@ -284,6 +288,7 @@ pub fn test_regenerate<D: Database>(db: &mut D) {
|
|||
|
||||
// upload key
|
||||
db.merge(tpk).unwrap().into_tpk_status();
|
||||
check_log_entry(log_path, &fpr);
|
||||
|
||||
db.regenerate_links(&fpr).unwrap();
|
||||
assert!(db.by_email(&email1).is_none());
|
||||
|
@ -309,7 +314,7 @@ pub fn test_regenerate<D: Database>(db: &mut D) {
|
|||
assert!(db.check_consistency().is_ok());
|
||||
}
|
||||
|
||||
pub fn test_reupload<D: Database>(db: &mut D) {
|
||||
pub fn test_reupload(db: &mut impl Database, log_path: &Path) {
|
||||
let str_uid1 = "Test A <test_a@example.com>";
|
||||
let str_uid2 = "Test B <test_b@example.com>";
|
||||
let tpk = TPKBuilder::new()
|
||||
|
@ -324,6 +329,7 @@ pub fn test_reupload<D: Database>(db: &mut D) {
|
|||
|
||||
// upload key
|
||||
db.merge(tpk.clone()).unwrap().into_tpk_status();
|
||||
check_log_entry(log_path, &fpr);
|
||||
|
||||
// verify 1st uid
|
||||
db.set_email_published(&fpr, &email1).unwrap();
|
||||
|
@ -343,7 +349,7 @@ pub fn test_reupload<D: Database>(db: &mut D) {
|
|||
assert!(db.by_email(&email2).is_none() ^ db.by_email(&email1).is_none());
|
||||
}
|
||||
|
||||
pub fn test_uid_replacement<D: Database>(db: &mut D) {
|
||||
pub fn test_uid_replacement(db: &mut impl Database, log_path: &Path) {
|
||||
let str_uid1 = "Test A <test_a@example.com>";
|
||||
let tpk1 = TPKBuilder::new().add_userid(str_uid1).generate().unwrap().0;
|
||||
let fpr1 = Fingerprint::try_from(tpk1.fingerprint()).unwrap();
|
||||
|
@ -358,7 +364,9 @@ pub fn test_uid_replacement<D: Database>(db: &mut D) {
|
|||
|
||||
// upload both keys
|
||||
db.merge(tpk1).unwrap().into_tpk_status();
|
||||
check_log_entry(log_path, &fpr1);
|
||||
db.merge(tpk2).unwrap().into_tpk_status();
|
||||
check_log_entry(log_path, &fpr2);
|
||||
|
||||
// verify 1st uid
|
||||
db.set_email_published(&fpr1, &email1).unwrap();
|
||||
|
@ -383,7 +391,7 @@ pub fn test_uid_replacement<D: Database>(db: &mut D) {
|
|||
.userids().len(), 1);
|
||||
}
|
||||
|
||||
pub fn test_uid_deletion<D: Database>(db: &mut D) {
|
||||
pub fn test_uid_deletion(db: &mut impl Database, log_path: &Path) {
|
||||
let str_uid1 = "Test A <test_a@example.com>";
|
||||
let str_uid2 = "Test B <test_b@example.com>";
|
||||
let tpk = TPKBuilder::new()
|
||||
|
@ -401,6 +409,7 @@ pub fn test_uid_deletion<D: Database>(db: &mut D) {
|
|||
|
||||
// upload key and verify uids
|
||||
let tpk_status = db.merge(tpk).unwrap().into_tpk_status();
|
||||
check_log_entry(log_path, &fpr);
|
||||
assert_eq!(TpkStatus {
|
||||
is_revoked: false,
|
||||
email_status: vec!(
|
||||
|
@ -442,7 +451,7 @@ pub fn test_uid_deletion<D: Database>(db: &mut D) {
|
|||
assert_eq!(tpk.subkeys().count(), n_subkeys);
|
||||
}
|
||||
|
||||
pub fn test_subkey_lookup<D: Database>(db: &mut D) {
|
||||
pub fn test_subkey_lookup(db: &mut impl Database, _log_path: &Path) {
|
||||
let tpk = TPKBuilder::new()
|
||||
.add_userid("Testy <test@example.com>")
|
||||
.add_signing_subkey()
|
||||
|
@ -454,8 +463,6 @@ pub fn test_subkey_lookup<D: Database>(db: &mut D) {
|
|||
// upload key
|
||||
let _ = db.merge(tpk.clone()).unwrap().into_tpk_status();
|
||||
|
||||
// upload key
|
||||
let _ = db.merge(tpk.clone()).unwrap().into_tpk_status();
|
||||
let fpr_primray = Fingerprint::try_from(tpk.fingerprint()).unwrap();
|
||||
let fpr_sign: Fingerprint = tpk.keys_all()
|
||||
.signing_capable()
|
||||
|
@ -474,7 +481,7 @@ pub fn test_subkey_lookup<D: Database>(db: &mut D) {
|
|||
assert_eq!(raw1, raw2);
|
||||
}
|
||||
|
||||
pub fn test_kid_lookup<D: Database>(db: &mut D) {
|
||||
pub fn test_kid_lookup(db: &mut impl Database, _log_path: &Path) {
|
||||
let tpk = TPKBuilder::new()
|
||||
.add_userid("Testy <test@example.com>")
|
||||
.add_signing_subkey()
|
||||
|
@ -503,7 +510,7 @@ pub fn test_kid_lookup<D: Database>(db: &mut D) {
|
|||
assert_eq!(raw1, raw2);
|
||||
}
|
||||
|
||||
pub fn test_upload_revoked_tpk<D: Database>(db: &mut D) {
|
||||
pub fn test_upload_revoked_tpk(db: &mut impl Database, log_path: &Path) {
|
||||
let str_uid1 = "Test A <test_a@example.com>";
|
||||
let str_uid2 = "Test B <test_b@example.com>";
|
||||
let (mut tpk, revocation) = TPKBuilder::new()
|
||||
|
@ -513,6 +520,7 @@ pub fn test_upload_revoked_tpk<D: Database>(db: &mut D) {
|
|||
.unwrap();
|
||||
let email1 = Email::from_str(str_uid1).unwrap();
|
||||
let email2 = Email::from_str(str_uid2).unwrap();
|
||||
let fpr = Fingerprint::try_from(tpk.fingerprint()).unwrap();
|
||||
|
||||
tpk = tpk.merge_packets(vec![revocation.into()]).unwrap();
|
||||
match tpk.revocation_status() {
|
||||
|
@ -522,6 +530,7 @@ pub fn test_upload_revoked_tpk<D: Database>(db: &mut D) {
|
|||
|
||||
// upload key
|
||||
let tpk_status = db.merge(tpk).unwrap().into_tpk_status();
|
||||
check_log_entry(log_path, &fpr);
|
||||
assert_eq!(TpkStatus {
|
||||
is_revoked: true,
|
||||
email_status: vec!(
|
||||
|
@ -532,7 +541,7 @@ pub fn test_upload_revoked_tpk<D: Database>(db: &mut D) {
|
|||
}, tpk_status);
|
||||
}
|
||||
|
||||
pub fn test_uid_revocation<D: Database>(db: &mut D) {
|
||||
pub fn test_uid_revocation(db: &mut impl Database, log_path: &Path) {
|
||||
use std::{thread, time};
|
||||
|
||||
let str_uid1 = "Test A <test_a@example.com>";
|
||||
|
@ -550,6 +559,7 @@ pub fn test_uid_revocation<D: Database>(db: &mut D) {
|
|||
|
||||
// upload key
|
||||
let tpk_status = db.merge(tpk.clone()).unwrap().into_tpk_status();
|
||||
check_log_entry(log_path, &fpr);
|
||||
assert_eq!(TpkStatus {
|
||||
is_revoked: false,
|
||||
email_status: vec!(
|
||||
|
@ -603,7 +613,7 @@ pub fn test_uid_revocation<D: Database>(db: &mut D) {
|
|||
}
|
||||
|
||||
/* FIXME I couldn't get this to work.
|
||||
pub fn test_uid_revocation_fake<D: Database>(db: &mut D) {
|
||||
pub fn test_uid_revocation_fake(db: &mut D) {
|
||||
use std::{thread, time};
|
||||
|
||||
let str_uid = "Test A <test_a@example.com>";
|
||||
|
@ -682,7 +692,7 @@ pub fn test_uid_revocation_fake<D: Database>(db: &mut D) {
|
|||
}
|
||||
*/
|
||||
|
||||
pub fn test_unlink_uid<D: Database>(db: &mut D) {
|
||||
pub fn test_unlink_uid(db: &mut impl Database, log_path: &Path) {
|
||||
let uid = "Test A <test_a@example.com>";
|
||||
let email = Email::from_str(uid).unwrap();
|
||||
|
||||
|
@ -696,6 +706,7 @@ pub fn test_unlink_uid<D: Database>(db: &mut D) {
|
|||
|
||||
// Create a 2nd key with same uid, and revoke the uid.
|
||||
let tpk_evil = TPKBuilder::new().add_userid(uid).generate().unwrap().0;
|
||||
let fpr_evil = Fingerprint::try_from(tpk_evil.fingerprint()).unwrap();
|
||||
let sig = {
|
||||
let uid = tpk_evil.userids()
|
||||
.find(|b| b.userid().value() == uid.as_bytes()).unwrap();
|
||||
|
@ -715,6 +726,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().into_tpk_status();
|
||||
check_log_entry(log_path, &fpr_evil);
|
||||
assert_eq!(TpkStatus {
|
||||
is_revoked: false,
|
||||
email_status: vec!(
|
||||
|
@ -737,7 +749,7 @@ pub fn get_userids(armored: &str) -> Vec<UserID> {
|
|||
|
||||
// If multiple keys have the same email address, make sure things work
|
||||
// as expected.
|
||||
pub fn test_same_email_1<D: Database>(db: &mut D) {
|
||||
pub fn test_same_email_1(db: &mut impl Database, log_path: &Path) {
|
||||
let str_uid1 = "A <test@example.com>";
|
||||
let tpk1 = TPKBuilder::new()
|
||||
.add_userid(str_uid1)
|
||||
|
@ -760,6 +772,7 @@ pub fn test_same_email_1<D: Database>(db: &mut D) {
|
|||
|
||||
// upload keys.
|
||||
let tpk_status1 = db.merge(tpk1).unwrap().into_tpk_status();
|
||||
check_log_entry(log_path, &fpr1);
|
||||
assert_eq!(TpkStatus {
|
||||
is_revoked: false,
|
||||
email_status: vec!(
|
||||
|
@ -768,6 +781,7 @@ pub fn test_same_email_1<D: Database>(db: &mut D) {
|
|||
unparsed_uids: 0,
|
||||
}, tpk_status1);
|
||||
let tpk_status2 = db.merge(tpk2.clone()).unwrap().into_tpk_status();
|
||||
check_log_entry(log_path, &fpr2);
|
||||
assert_eq!(TpkStatus {
|
||||
is_revoked: false,
|
||||
email_status: vec!(
|
||||
|
@ -814,6 +828,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().into_tpk_status();
|
||||
check_log_entry(log_path, &fpr2);
|
||||
assert_eq!(TpkStatus {
|
||||
is_revoked: false,
|
||||
email_status: vec!(
|
||||
|
@ -829,7 +844,7 @@ pub fn test_same_email_1<D: Database>(db: &mut D) {
|
|||
|
||||
// If a key has multiple user ids with the same email address, make
|
||||
// sure things still work.
|
||||
pub fn test_same_email_2<D: Database>(db: &mut D) {
|
||||
pub fn test_same_email_2(db: &mut impl Database, log_path: &Path) {
|
||||
use std::{thread, time};
|
||||
|
||||
let str_uid1 = "A <test@example.com>";
|
||||
|
@ -847,6 +862,7 @@ pub fn test_same_email_2<D: Database>(db: &mut D) {
|
|||
|
||||
// upload key
|
||||
let tpk_status = db.merge(tpk.clone()).unwrap().into_tpk_status();
|
||||
check_log_entry(log_path, &fpr);
|
||||
|
||||
// verify uid1
|
||||
assert_eq!(TpkStatus {
|
||||
|
@ -883,6 +899,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().into_tpk_status();
|
||||
check_log_entry(log_path, &fpr);
|
||||
assert_eq!(TpkStatus {
|
||||
is_revoked: false,
|
||||
email_status: vec!(
|
||||
|
@ -899,7 +916,7 @@ pub fn test_same_email_2<D: Database>(db: &mut D) {
|
|||
vec![ uid1.clone() ]);
|
||||
}
|
||||
|
||||
pub fn test_bad_uids<D: Database>(db: &mut D) {
|
||||
pub fn test_bad_uids(db: &mut impl Database, log_path: &Path) {
|
||||
let str_uid1 = "foo@bar.example <foo@bar.example>";
|
||||
let str_uid2 = "A <test@example.com>";
|
||||
let str_uid3 = "lalalalaaaaa";
|
||||
|
@ -915,6 +932,7 @@ pub fn test_bad_uids<D: Database>(db: &mut D) {
|
|||
let email2 = Email::from_str(str_uid2).unwrap();
|
||||
|
||||
let tpk_status = db.merge(tpk).unwrap().into_tpk_status();
|
||||
check_log_entry(log_path, &fpr);
|
||||
assert_eq!(TpkStatus {
|
||||
is_revoked: false,
|
||||
email_status: vec!(
|
||||
|
@ -938,10 +956,11 @@ pub fn test_bad_uids<D: Database>(db: &mut D) {
|
|||
}, tpk_status);
|
||||
}
|
||||
|
||||
pub fn test_no_selfsig<D: Database>(db: &mut D) {
|
||||
pub fn test_no_selfsig(db: &mut impl Database, log_path: &Path) {
|
||||
let (mut tpk, revocation) = TPKBuilder::new()
|
||||
.generate()
|
||||
.unwrap();
|
||||
let fpr = Fingerprint::try_from(tpk.fingerprint()).unwrap();
|
||||
|
||||
// don't allow upload of naked key
|
||||
assert!(db.merge(tpk.clone()).is_err());
|
||||
|
@ -949,9 +968,20 @@ pub fn test_no_selfsig<D: Database>(db: &mut D) {
|
|||
// with revocation, it's ok
|
||||
tpk = tpk.merge_packets(vec![revocation.into()]).unwrap();
|
||||
let tpk_status = db.merge(tpk).unwrap().into_tpk_status();
|
||||
check_log_entry(log_path, &fpr);
|
||||
assert_eq!(TpkStatus {
|
||||
is_revoked: true,
|
||||
email_status: vec!(),
|
||||
unparsed_uids: 0,
|
||||
}, tpk_status);
|
||||
}
|
||||
|
||||
fn check_log_entry(log_path: &Path, fpr: &Fingerprint) {
|
||||
let log_data = fs::read_to_string(log_path).unwrap();
|
||||
let last_entry = log_data
|
||||
.lines()
|
||||
.last()
|
||||
.unwrap();
|
||||
assert_eq!(last_entry, fpr.to_string());
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue