use ci_group::group;
use std::time::Duration;
use tenuo::{constraints::ConstraintSet, crypto::SigningKey, warrant::Warrant, Error};
#[test]
fn test_delegation_semantics_issuer_equals_parent_holder() {
let (parent, child) = group!("Setup warrants", {
let parent_kp = SigningKey::generate();
let child_kp = SigningKey::generate();
let parent = Warrant::builder()
.capability("read", ConstraintSet::new())
.ttl(Duration::from_secs(3600))
.holder(parent_kp.public_key())
.build(&parent_kp)
.unwrap();
let child = parent
.attenuate()
.inherit_all()
.holder(child_kp.public_key())
.build(&parent_kp)
.unwrap();
(parent, child)
});
group!("Verify delegation semantics", {
assert_eq!(
child.issuer(),
parent.authorized_holder(),
"Child's issuer must equal parent's holder (delegation authority)"
);
assert_ne!(
child.issuer(),
child.authorized_holder(),
"Child's issuer should not equal child's holder (except for root warrants)"
);
println!("✅ Delegation semantics correct:");
println!(
" Parent holder: {}",
parent.authorized_holder().fingerprint()
);
println!(" Child issuer: {}", child.issuer().fingerprint());
println!(
" Child holder: {}",
child.authorized_holder().fingerprint()
);
println!(
" Audit trail: '{}' delegated to '{}'",
parent.authorized_holder().fingerprint(),
child.authorized_holder().fingerprint()
);
});
}
#[test]
fn test_delegation_authority_enforcement() {
let (parent, wrong_kp, result) = group!("Setup and attempt unauthorized delegation", {
let parent_kp = SigningKey::generate();
let child_kp = SigningKey::generate();
let wrong_kp = SigningKey::generate();
let parent = Warrant::builder()
.capability("read", ConstraintSet::new())
.ttl(Duration::from_secs(3600))
.holder(parent_kp.public_key())
.build(&parent_kp)
.unwrap();
let result = parent
.attenuate()
.inherit_all()
.holder(child_kp.public_key())
.build(&wrong_kp);
(parent, wrong_kp, result)
});
group!("Verify delegation rejected", {
match result {
Err(Error::DelegationAuthorityError { expected, actual }) => {
println!("✅ Delegation authority enforced:");
println!(" Expected signer: {}", expected);
println!(" Actual signer: {}", actual);
assert_eq!(expected, parent.authorized_holder().fingerprint());
assert_eq!(actual, wrong_kp.public_key().fingerprint());
}
Ok(_) => panic!("Should have rejected delegation from non-holder"),
Err(e) => panic!("Wrong error type: {:?}", e),
}
});
}
#[test]
fn test_multi_level_delegation_chain_semantics() {
let (root, middle, leaf) = group!("Build 3-level delegation chain", {
let root_kp = SigningKey::generate();
let middle_kp = SigningKey::generate();
let leaf_kp = SigningKey::generate();
let root = Warrant::builder()
.capability("read", ConstraintSet::new())
.ttl(Duration::from_secs(3600))
.holder(root_kp.public_key())
.build(&root_kp)
.unwrap();
let middle = root
.attenuate()
.inherit_all()
.holder(middle_kp.public_key())
.build(&root_kp)
.unwrap();
let leaf = middle
.attenuate()
.inherit_all()
.holder(leaf_kp.public_key())
.build(&middle_kp)
.unwrap();
(root, middle, leaf)
});
group!("Verify chain semantics", {
assert_eq!(
middle.issuer(),
root.authorized_holder(),
"Middle's issuer should be root's holder"
);
assert_eq!(
leaf.issuer(),
middle.authorized_holder(),
"Leaf's issuer should be middle's holder"
);
println!("✅ Multi-level delegation chain correct:");
println!(
" Root: holder={}",
root.authorized_holder().fingerprint()
);
println!(
" Middle: issuer={}, holder={}",
middle.issuer().fingerprint(),
middle.authorized_holder().fingerprint()
);
println!(
" Leaf: issuer={}, holder={}",
leaf.issuer().fingerprint(),
leaf.authorized_holder().fingerprint()
);
println!(" Chain: Root → Middle → Leaf");
});
}