Merge remote-tracking branch 'origin/master' into i18n-updates-1

This commit is contained in:
Vincent Breitmoser 2019-11-19 12:36:57 +01:00
commit 6b311dfa8b
No known key found for this signature in database
GPG Key ID: 7BD18320DEADFA11
12 changed files with 176 additions and 85 deletions

1
Cargo.lock generated
View File

@ -663,6 +663,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.6 (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)",

View File

@ -21,6 +21,7 @@ pathdiff = "0.1"
idna = "0.1"
fs2 = "0.4"
walkdir = "2.2"
chrono = "0.4"
[lib]
name = "hagrid_database"

View File

@ -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;
@ -8,6 +8,7 @@ use std::os::unix::fs::PermissionsExt;
use tempfile;
use url;
use pathdiff::diff_paths;
use std::time::SystemTime;
//use sequoia_openpgp::armor::{Writer, Kind};
@ -28,6 +29,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 +80,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 +107,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 +204,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 +291,19 @@ impl Database for Filesystem {
Ok(tempfile)
}
fn write_log_append(&self, filename: &str, fpr_primary: &Fingerprint) -> Result<()> {
let timestamp = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
.as_secs();
let fingerprint_line = format!("{:010} {}\n", timestamp, 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 +654,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 +682,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");
}

View File

@ -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<()>;
}

View File

@ -98,6 +98,6 @@ mod tests {
#[test]
fn flock_nonexistent() {
FlockMutexGuard::lock("nonexistent").is_err();
assert!(FlockMutexGuard::lock("nonexistent").is_err());
}
}

View File

@ -19,18 +19,20 @@ use std::str::FromStr;
use Database;
use Query;
use openpgp::tpk::{TPKBuilder, UserIDBinding};
use openpgp::tpk::TPKBuilder;
use openpgp::{
constants::ReasonForRevocation, constants::SignatureType, packet::UserID,
parse::Parse, Packet, PacketPile, RevocationStatus, TPK,
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,21 @@ 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()
.split(" ")
.last().unwrap();
assert_eq!(last_entry, fpr.to_string());
}

18
dist/assets/img/atom.svg vendored Normal file
View File

@ -0,0 +1,18 @@
<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="128px" height="128px" id="RSSicon" viewBox="0 0 256 256">
<defs>
<linearGradient x1="0.085" y1="0.085" x2="0.915" y2="0.915" id="RSSg">
<stop offset="0.0" stop-color="#E3702D"/><stop offset="0.1071" stop-color="#EA7D31"/>
<stop offset="0.3503" stop-color="#F69537"/><stop offset="0.5" stop-color="#FB9E3A"/>
<stop offset="0.7016" stop-color="#EA7C31"/><stop offset="0.8866" stop-color="#DE642B"/>
<stop offset="1.0" stop-color="#D95B29"/>
</linearGradient>
</defs>
<rect width="256" height="256" rx="55" ry="55" x="0" y="0" fill="#CC5D15"/>
<rect width="246" height="246" rx="50" ry="50" x="5" y="5" fill="#F49C52"/>
<rect width="236" height="236" rx="47" ry="47" x="10" y="10" fill="url(#RSSg)"/>
<circle cx="68" cy="189" r="24" fill="#FFF"/>
<path d="M160 213h-34a82 82 0 0 0 -82 -82v-34a116 116 0 0 1 116 116z" fill="#FFF"/>
<path d="M184 213A140 140 0 0 0 44 73 V 38a175 175 0 0 1 175 175z" fill="#FFF"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -9,10 +9,10 @@
</p>
<p>
<center><img src="/about/stats/week.png" /></center>
<center><img src="/about/stats/month.png" /></center>
</p>
<p>
<center><img src="/about/stats/month.png" /></center>
<center><img src="/about/stats/year.png" /></center>
</p>
<h3>Load Average</h3>

View File

@ -3,7 +3,13 @@
<title>keys.openpgp.org</title>
<link href="{{ base_uri }}/atom.xml" rel="self"/>
<id>urn:uuid:8e783366-73b1-460e-83d3-42f01046646d</id>
<updated>2019-09-12T12:00:00Z</updated>
<updated>2019-11-12T12:00:00Z</updated>
<entry>
<title>Celebrating 100.000 verified addresses! 📈</title>
<link href="{{ base_uri }}/about/news#2019-11-12-celebrating-100k" />
<updated>2019-11-12T12:00:00Z</updated>
<id>urn:uuid:5b69781f-5aa4-4276-8d9e-6a71c896cb65</id>
</entry>
<entry>
<title>Launching a new keyserver! 🚀</title>
<link href="{{ base_uri }}/about/news#2019-06-12-launch" />

View File

@ -25,7 +25,7 @@
<hr />
<p>
<strong>{{ text "News:" }}</strong> {{ text "<a href=\"/about/news#2019-09-12-three-months-later\">Three months after launch ✨</a> (2019-09-12)" }}
<strong>{{ text "News:" }}</strong> {{ text "<a href=\"/about/news#2019-11-12-celebrating-100k\">Celebrating 100.000 verified addresses! 📈</a> (2019-11-12)" }}
</p>
{{/with}}
{{/layout}}

View File

@ -8,10 +8,10 @@
</p>
<p>
<center><img src="/about/stats/week.png" /></center>
<center><img src="/about/stats/month.png" /></center>
</p>
<p>
<center><img src="/about/stats/month.png" /></center>
<center><img src="/about/stats/year.png" /></center>
</p>
<h3>Load Average</h3>