use std::collections::BTreeSet;
mod common;
use common::Environment;
use common::Result;
fn create_environment() -> Result<(Environment, String)> {
Environment::scooby_gang_bootstrap(None)
}
const SIGN_COMMIT: &str = "sign_commit";
const SIGN_TAG: &str = "sign_tag";
const SIGN_ARCHIVE: &str = "sign_archive";
const ADD_USER: &str = "add_user";
const RETIRE_USER: &str = "retire_user";
const AUDIT: &str = "audit";
const CAPS: &[&str] = &[
SIGN_COMMIT,
SIGN_TAG,
SIGN_ARCHIVE,
ADD_USER,
RETIRE_USER,
AUDIT
];
fn check(e: &Environment, args: &[&str], expected_caps: &[&str])
{
let petname = e.buffy.petname;
let fpr = e.buffy.fingerprint.to_string();
let openpgp_policy_toml = e.git_state().join("openpgp-policy.toml");
if let Err(err) = std::fs::remove_file(&openpgp_policy_toml) {
if std::io::ErrorKind::NotFound != err.kind() {
panic!("Removing {}", openpgp_policy_toml.display());
}
}
let mut sq_git: Vec<&str> = [
"policy",
"authorize",
&petname,
&fpr,
].to_vec();
sq_git.extend(args);
eprintln!("Running: sq-git {}", sq_git.join(" "));
e.sq_git(&sq_git).unwrap();
let output = e.sq_git(&[
"policy",
"describe",
"--output-format", "json"
]).unwrap();
eprintln!("Output:\n{}", String::from_utf8_lossy(&output.stdout));
let status: serde_json::Value = serde_json::from_slice(&output.stdout)
.expect("\"sq policy describe\" emits valid json output");
let auths = &status["authorization"];
let user = &auths[petname];
eprintln!("JSON[\"authorization\"][\"{}\"]:\n{:?}", petname, user);
let caps = BTreeSet::from_iter(CAPS.iter());
let expected_caps_present = BTreeSet::from_iter(expected_caps.iter());
for cap in expected_caps_present.iter() {
eprintln!("Checking that {} is true", cap);
match &user[cap] {
serde_json::Value::Bool(true) => (),
v => {
panic!("expected {} to be true, but it is: {:?}",
cap, v);
}
}
}
let expected_caps_missing = caps.difference(&expected_caps_present);
for cap in expected_caps_missing {
eprintln!("Checking that {} is not set or false", cap);
match &user[cap] {
serde_json::Value::Null => (),
serde_json::Value::Bool(false) => (),
v => {
panic!("expected {} to be false, but it is: {:?}",
cap, v);
}
}
}
}
#[test]
fn check_flags() -> anyhow::Result<()> {
let (e, _root) = create_environment()?;
check(&e,
&["--sign-commit"],
&[ SIGN_COMMIT ]);
check(&e,
&["--sign-archive"],
&[ SIGN_ARCHIVE ]);
check(&e,
&["--sign-tag"],
&[ SIGN_TAG ]);
check(&e,
&["--add-user"],
&[ ADD_USER ]);
check(&e,
&["--retire-user"],
&[ RETIRE_USER ]);
check(&e,
&["--audit"],
&[ AUDIT ]);
check(&e,
&["--sign-commit", "--sign-archive"],
&[ SIGN_COMMIT, SIGN_ARCHIVE ]);
check(&e,
&["--sign-tag", "--add-user", "--retire-user"],
&[ SIGN_TAG, ADD_USER, RETIRE_USER ]);
check(&e,
&["--no-sign-commit", "--sign-archive"],
&[ SIGN_ARCHIVE ]);
check(&e,
&["--sign-commit", "--no-sign-commit", "--sign-archive"],
&[ SIGN_ARCHIVE ]);
check(&e,
&["--no-sign-commit", "--sign-commit", "--sign-archive"],
&[ SIGN_COMMIT, SIGN_ARCHIVE ]);
check(&e,
&["--committer"],
&[ SIGN_COMMIT ]);
check(&e,
&["--release-manager"],
&[ SIGN_COMMIT, SIGN_TAG, SIGN_ARCHIVE ]);
check(&e,
&["--project-maintainer"],
&[ SIGN_COMMIT, SIGN_TAG, SIGN_ARCHIVE, ADD_USER, RETIRE_USER,
AUDIT ]);
check(&e,
&["--project-maintainer", "--committer"],
&[ SIGN_COMMIT, SIGN_TAG, SIGN_ARCHIVE, ADD_USER, RETIRE_USER,
AUDIT ]);
check(&e,
&["--project-maintainer", "--no-sign-archive"],
&[ SIGN_COMMIT, SIGN_TAG, ADD_USER, RETIRE_USER, AUDIT ]);
check(&e,
&["--no-sign-archive", "--project-maintainer"],
&[ SIGN_COMMIT, SIGN_TAG, ADD_USER, RETIRE_USER, AUDIT ]);
Ok(())
}