use super::*;
fn entry(identity: &Identity, name: &str) -> Entry {
Entry {
machine_id: identity.machine_id,
pin: identity.pin,
name: name.into(),
spki_der: Some(identity::spki_of(&identity.cert_der).unwrap()),
hw_addr: None,
screen_mm: None,
}
}
#[test]
fn merge_desk_containing_own_member_stores_only_peer_pins() {
let a_dir = tempfile::tempdir().unwrap();
let b_dir = tempfile::tempdir().unwrap();
let c_dir = tempfile::tempdir().unwrap();
let a = identity::load_or_create(a_dir.path()).unwrap();
let b = identity::load_or_create(b_dir.path()).unwrap();
let c = identity::load_or_create(c_dir.path()).unwrap();
let mut a_pins = PinStore::load(&a_dir.path().join("pins.toml")).unwrap();
let mut b_pins = PinStore::load(&b_dir.path().join("pins.toml")).unwrap();
b_pins.add(entry(&a, "a"));
let mut a_desk =
DeskStore::load(&a_dir.path().join("desk.pb"), a.machine_id, &mut a_pins).unwrap();
let path = b_dir.path().join("desk.pb");
let mut b_desk = DeskStore::load(&path, b.machine_id, &mut b_pins).unwrap();
a_desk.admit(&a, &mut a_pins, &entry(&b, "b"), 1).unwrap();
a_desk.admit(&a, &mut a_pins, &entry(&c, "c"), 2).unwrap();
let outcome = b_desk.merge(&b, &mut b_pins, &a_desk.to_desk()).unwrap();
assert_eq!(outcome.admitted.len(), 2);
assert!(b_pins.get(&b.machine_id).is_none());
assert_eq!(b_pins.get(&a.machine_id), Some(&entry(&a, "a")));
assert_eq!(b_pins.get(&c.machine_id).unwrap().pin, c.pin);
}
#[test]
fn merge_admission_then_revocation_survives_reload_and_stale_desk() {
let a_dir = tempfile::tempdir().unwrap();
let b_dir = tempfile::tempdir().unwrap();
let c_dir = tempfile::tempdir().unwrap();
let a = identity::load_or_create(a_dir.path()).unwrap();
let b = identity::load_or_create(b_dir.path()).unwrap();
let c = identity::load_or_create(c_dir.path()).unwrap();
let mut a_pins = PinStore::load(&a_dir.path().join("pins.toml")).unwrap();
let mut c_pins = PinStore::load(&c_dir.path().join("pins.toml")).unwrap();
c_pins.add(entry(&a, "a"));
c_pins.save().unwrap();
let mut a_desk =
DeskStore::load(&a_dir.path().join("desk.pb"), a.machine_id, &mut a_pins).unwrap();
let path = c_dir.path().join("desk.pb");
let mut c_desk = DeskStore::load(&path, c.machine_id, &mut c_pins).unwrap();
a_desk.admit(&a, &mut a_pins, &entry(&b, "b"), 1).unwrap();
let old_desk = a_desk.to_desk();
let admitted = c_desk.merge(&c, &mut c_pins, &old_desk).unwrap();
let accepted_b = c_pins.get(&b.machine_id).cloned();
let stale_pins = std::fs::read(c_dir.path().join("pins.toml")).unwrap();
a_desk.revoke(&a, &mut a_pins, b.machine_id, 2).unwrap();
let revoked = c_desk.merge(&c, &mut c_pins, &a_desk.to_desk()).unwrap();
std::fs::write(c_dir.path().join("pins.toml"), stale_pins).unwrap();
let mut c_pins = PinStore::load(&c_dir.path().join("pins.toml")).unwrap();
let mut reloaded = DeskStore::load(&path, c.machine_id, &mut c_pins).unwrap();
let stale = reloaded.merge(&c, &mut c_pins, &old_desk).unwrap();
assert_eq!(admitted.admitted.len(), 1);
assert_eq!(accepted_b.unwrap().pin, b.pin);
assert_eq!(revoked.revoked, vec![b.machine_id]);
assert!(a_pins.get(&b.machine_id).is_none());
assert!(c_pins.get(&b.machine_id).is_none());
assert_eq!(stale.admitted.len(), 0);
assert_eq!(reloaded.to_desk(), a_desk.to_desk());
}