#![allow(dead_code)]
use std::sync::Arc;
use gunnar_core::{AuthTable, ControlStore, HashKind, NewRepo, RepoCatalog, RepoRef, Visibility};
pub const KAT_ED25519: &str =
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMW4aqVr75w+3DWorOCbfwl5XCDCq1yCQ6puzU4qzol2 gunnar-kat";
pub const KAT_ED25519_FINGERPRINT: &str = "SHA256:mRq7xzwk8TswSflB9kTXW/SLFDtAsgf5ksW8h6skax4";
pub const KAT_RSA: &str = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCk+UFkETJzTQaKJojczwNtCTGEE6TVWu7bkJLTY4v+ssDRZ8OadsXZDjAa+nDeHBH39ELZw0lA0XpjljxCYsg2Ta9x4qN8MX9MSJjl10FrUmn6UuO4hRi6OC60fBOvMM1G2U7UnYFbt2Mojo+JIw1IsnwrlITPpx7lmse2lqidO1yGIJW5BQyJutIQsKux1pQkc+tpGbhUwI1/8Vihuy88DJGrWdMp3mS8r1LW9fvOcQ8vYy78318/uV2vfzb71IvaslwC40zyP5tIsmwWlvYEsZwMhk/pNzcgmLkn4fzeUVF37N6FP5V6RRT4GM4EK2Uq4H1OHgsgicqsYTrnqErn gunnar-kat-rsa";
pub const KAT_RSA_FINGERPRINT: &str = "SHA256:WORS4jaxEY/2QuUpJOlfRD03Lz7CCSeXMdD0FjNacJg";
pub const OTHER_ED25519: &str =
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICoNhstm/zoeaAvHBeLWH192X+HjvMcX7NLMGq98FL0B other";
pub const OTHER_ED25519_FINGERPRINT: &str = "SHA256:BT8pCbOuAqBeX1M+Ep3hZMawlY3h74H9/91esEqk3fw";
pub struct Fixture {
pub catalog: RepoCatalog,
pub auth: AuthTable,
pub store: Arc<dyn ControlStore>,
}
impl Fixture {
pub fn new() -> Self {
let store = gunnar_core::memory_control_store().expect("control store");
Fixture {
catalog: RepoCatalog::new(Arc::clone(&store)).expect("catalog"),
auth: AuthTable::new(Arc::clone(&store)).expect("auth table"),
store,
}
}
pub fn repo(&self, ns: &str, name: &str) -> gunnar_core::Repo {
self.repo_with(ns, name, HashKind::Sha256, Visibility::Private)
}
pub fn repo_with(
&self,
ns: &str,
name: &str,
hash_kind: HashKind,
visibility: Visibility,
) -> gunnar_core::Repo {
if self.catalog.namespace(ns).expect("read").is_none() {
self.catalog.create_namespace(ns).expect("create namespace");
}
let path = RepoRef::new(ns, name).expect("legal path");
self.catalog
.create(
NewRepo::new(path)
.hash_kind(hash_kind)
.visibility(visibility),
)
.expect("create repo")
}
pub fn dump_auth_document(&self) -> String {
let width = gunnar_core::BLOB_ID_LEN * 2;
let root = self
.store
.read_doc(gunnar_core::AUTH_REF)
.expect("read the auth document")
.expect("the auth table has a version; something was stored");
let mut seen = std::collections::BTreeSet::new();
let mut queue = vec![root];
let mut out = String::new();
while let Some(id) = queue.pop() {
if !seen.insert(id) {
continue;
}
let Ok(Some(bytes)) = self.store.get_blob(&id) else {
continue;
};
let text = String::from_utf8_lossy(&bytes).into_owned();
for word in text.split(|c: char| !c.is_ascii_hexdigit()) {
if word.len() == width {
if let Some(child) = gunnar_core::BlobId::from_hex(word) {
queue.push(child);
}
}
}
out.push_str(&text);
out.push('\n');
}
assert!(
seen.len() > 1,
"the auth document has no shards, so this walk read one blob and \
proves nothing about where a secret could hide"
);
out
}
}