crates/gunnar-cli/tests/account_push_door.rs
#![cfg(feature = "server")]
//! **The first push names a repository too** (the owner's enterprise list,
//! 2026-10-05): a customer creates repositories in their own account with
//! `git push` as well as with `Repos.Create`, so the name filter stands at
//! the push door, and the creation is in the account's audit log. Stock
//! `git`, a real SSH connection, the account's own key.
mod common;
use common::{local_repo, tools_present, Harness};
use gunnar_core::account_audit::AuditQuery;
use gunnar_core::{HashKind, Principal, PrincipalKind};
/// `acme`, a person with an account, and an ssh command that signs as acme.
fn acme(harness: &Harness) -> String {
harness
.stores
.auth()
.add_principal(Principal::new("acme", "acme", PrincipalKind::User).expect("a person"))
.expect("acme");
harness
.stores
.catalog()
.create_namespace("acme")
.expect("acme's account namespace");
let private = gunnar_core::mint_ed25519().expect("a key");
let parsed = gunnar_core::ssh_key::PrivateKey::from_openssh(&private).expect("parses");
let public = parsed.public_key().to_openssh().expect("openssh");
harness
.stores
.auth()
.register_key("acme", &public, None)
.expect("acme's key");
let path = harness.dir.path().join("acme_ed25519");
std::fs::write(&path, &private).expect("write acme's key");
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt as _;
std::fs::set_permissions(&path, std::fs::Permissions::from_mode(0o600)).expect("0600");
}
format!(
"ssh -i {} -o IdentitiesOnly=yes -o IdentityAgent=none -o StrictHostKeyChecking=no \
-o UserKnownHostsFile=/dev/null -o BatchMode=yes -o LogLevel=ERROR",
path.display()
)
}
#[test]
fn a_first_push_meets_the_name_filter_and_its_creation_is_in_the_accounts_log() {
assert!(
tools_present(),
"this test requires `git` and `ssh` on PATH"
);
let harness = Harness::start_appliance_bootstrap();
let as_acme = acme(&harness);
let work = harness.dir.path().join("work");
local_repo(&harness, &work, HashKind::Sha1, "acme's first bytes\n");
// An offensive name: refused with gunnar's sentence, nothing made.
let refused = harness.git_with_ssh(
&work,
&as_acme,
&[
"push",
&harness.url("acme", "fuck-this"),
"HEAD:refs/heads/main",
],
);
assert!(
!refused.ok,
"the push of an offensive name went through: {}",
refused.stdout
);
assert!(
refused.stderr.contains("is refused") && refused.stderr.contains("Choose another name"),
"the pusher is not told why: {}",
refused.stderr
);
assert!(
harness
.stores
.catalog()
.open(&gunnar_core::RepoRef::new("acme", "fuck-this").unwrap())
.is_err(),
"a repository was made under the refused name"
);
// A clean name: made, and in acme's log as acme's own act.
harness
.git_with_ssh(
&work,
&as_acme,
&["push", &harness.url("acme", "site"), "HEAD:refs/heads/main"],
)
.expect_ok("acme's first push of a clean name");
let log = harness
.stores
.account_audit()
.query(
"acme",
&AuditQuery {
limit: 50,
..AuditQuery::default()
},
)
.expect("acme's log");
let seen: Vec<String> = log
.entries
.iter()
.map(|e| format!("{}:{}:{}:{}", e.kind, e.actor, e.actor_role, e.target))
.collect();
assert_eq!(
seen,
vec![
"repo.created:acme:admin:acme/site",
"name.refused:acme:admin:fuck-this"
],
"{seen:#?}"
);
let queue = harness
.stores
.names()
.reviews("acme")
.expect("acme's queue");
assert_eq!(
queue.len(),
1,
"the refusal is noted for acme's admin: {queue:?}"
);
}