Draft 0.5: identity/registry spec; Phase A signed MA registry, mailbox challenge auth, key rotation, skew rejection
This commit is contained in:
+141
@@ -183,6 +183,147 @@ fn cli_init_refuses_overwrite_without_force() {
|
||||
run_ok(&forced);
|
||||
}
|
||||
|
||||
fn http_get(port: u16, path: &str) -> String {
|
||||
use std::io::{Read, Write};
|
||||
let mut stream = std::net::TcpStream::connect(("127.0.0.1", port)).unwrap();
|
||||
stream
|
||||
.write_all(format!("GET {path} HTTP/1.0\r\nHost: 127.0.0.1\r\n\r\n").as_bytes())
|
||||
.unwrap();
|
||||
let mut out = String::new();
|
||||
stream.read_to_string(&mut out).unwrap();
|
||||
out
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cli_registry_lifecycle() {
|
||||
let root = tempfile::tempdir().unwrap();
|
||||
let dir = root.path().join("reg");
|
||||
let dir_arg = dir.display().to_string();
|
||||
|
||||
let stdout = run_ok(&[
|
||||
"registry".to_string(),
|
||||
"--dir".to_string(),
|
||||
dir_arg.clone(),
|
||||
"init".to_string(),
|
||||
]);
|
||||
assert!(stdout.contains("MA key"), "{stdout}");
|
||||
assert!(dir.join("registry.json").exists());
|
||||
#[cfg(unix)]
|
||||
{
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
let mode = fs::metadata(dir.join("ma-key.hex"))
|
||||
.unwrap()
|
||||
.permissions()
|
||||
.mode()
|
||||
& 0o777;
|
||||
assert_eq!(mode, 0o600);
|
||||
}
|
||||
|
||||
let stdout = run_ok(&[
|
||||
"registry".to_string(),
|
||||
"--dir".to_string(),
|
||||
dir_arg.clone(),
|
||||
"show".to_string(),
|
||||
]);
|
||||
assert!(stdout.contains("version 1"));
|
||||
|
||||
let stdout = run_ok(&[
|
||||
"registry".to_string(),
|
||||
"--dir".to_string(),
|
||||
dir_arg.clone(),
|
||||
"add".to_string(),
|
||||
"alice.frx.example".to_string(),
|
||||
"ab".repeat(32),
|
||||
]);
|
||||
assert!(stdout.contains("added alice.frx.example"));
|
||||
|
||||
let stdout = run_ok(&[
|
||||
"registry".to_string(),
|
||||
"--dir".to_string(),
|
||||
dir_arg.clone(),
|
||||
"add-key".to_string(),
|
||||
"alice.frx.example".to_string(),
|
||||
"cd".repeat(32),
|
||||
]);
|
||||
assert!(stdout.contains("added key"));
|
||||
let stdout = run_ok(&[
|
||||
"registry".to_string(),
|
||||
"--dir".to_string(),
|
||||
dir_arg.clone(),
|
||||
"list".to_string(),
|
||||
]);
|
||||
assert!(stdout.contains("alice.frx.example [source] (2 key(s))"));
|
||||
|
||||
let stdout = run_ok(&[
|
||||
"registry".to_string(),
|
||||
"--dir".to_string(),
|
||||
dir_arg.clone(),
|
||||
"revoke-key".to_string(),
|
||||
"alice.frx.example".to_string(),
|
||||
"ab".repeat(32),
|
||||
]);
|
||||
assert!(stdout.contains("revoked key"));
|
||||
let stdout = run_ok(&[
|
||||
"registry".to_string(),
|
||||
"--dir".to_string(),
|
||||
dir_arg.clone(),
|
||||
"list".to_string(),
|
||||
]);
|
||||
assert!(stdout.contains("(1 key(s))"));
|
||||
|
||||
let port = common::free_port();
|
||||
let _service = spawn_service(
|
||||
&[
|
||||
"registry".to_string(),
|
||||
"--dir".to_string(),
|
||||
dir_arg,
|
||||
"serve".to_string(),
|
||||
"--listen".to_string(),
|
||||
format!("127.0.0.1:{port}"),
|
||||
],
|
||||
"registry serving",
|
||||
);
|
||||
let body = http_get(port, "/registry.json");
|
||||
assert!(body.contains("\"members\""), "{body}");
|
||||
assert!(body.contains("alice.frx.example"), "{body}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cli_key_rotation() {
|
||||
let root = tempfile::tempdir().unwrap();
|
||||
let config = root.path().join("frxd.toml");
|
||||
let data = root.path().join("data");
|
||||
let config_arg = config.display().to_string();
|
||||
run_ok(&init_args(&config, "alice", 0, 1, &data));
|
||||
|
||||
let first = run_ok(&[
|
||||
"--config".to_string(),
|
||||
config_arg.clone(),
|
||||
"key".to_string(),
|
||||
"show".to_string(),
|
||||
]);
|
||||
let first = first.trim().to_string();
|
||||
assert_eq!(first.len(), 64);
|
||||
|
||||
let stdout = run_ok(&[
|
||||
"--config".to_string(),
|
||||
config_arg.clone(),
|
||||
"key".to_string(),
|
||||
"rotate".to_string(),
|
||||
]);
|
||||
assert!(stdout.contains("old pubkey"), "{stdout}");
|
||||
assert!(stdout.contains("new pubkey"), "{stdout}");
|
||||
|
||||
let second = run_ok(&[
|
||||
"--config".to_string(),
|
||||
config_arg,
|
||||
"key".to_string(),
|
||||
"show".to_string(),
|
||||
]);
|
||||
assert_ne!(first, second.trim(), "key did not change");
|
||||
assert!(data.join("key.hex.bak").exists());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cli_full_network_pipeline() {
|
||||
let root = tempfile::tempdir().unwrap();
|
||||
|
||||
Reference in New Issue
Block a user