use blindplane_access::{
AccessError, AccessIssuer, AccessValidationPolicy, Principal, PrincipalKeypair, PrincipalKind,
};
#[test]
fn principal_encoding_is_canonical_and_bounded() {
let keys = PrincipalKeypair::from_secret_bytes(
"acme",
"alice",
PrincipalKind::User,
1,
[7; 32],
[9; 32],
)
.unwrap();
let encoded = keys.principal().encode();
assert_eq!(
Principal::decode(&encoded, &AccessValidationPolicy::default()).unwrap(),
*keys.principal()
);
let with_trailing_byte = [encoded, vec![0]].concat();
assert_eq!(
Principal::decode(&with_trailing_byte, &AccessValidationPolicy::default()),
Err(AccessError::TrailingBytes)
);
}
#[test]
fn principals_reject_invalid_identity_and_key_epochs() {
assert_eq!(
PrincipalKeypair::from_secret_bytes("", "alice", PrincipalKind::User, 1, [7; 32], [9; 32],)
.unwrap_err(),
AccessError::InvalidIdentifier
);
assert_eq!(
PrincipalKeypair::from_secret_bytes(
"acme",
"alice",
PrincipalKind::User,
0,
[7; 32],
[9; 32],
)
.unwrap_err(),
AccessError::InvalidEpoch
);
}
#[test]
fn issuer_identity_is_derived_from_the_signing_key() {
let issuer = AccessIssuer::from_seed("tenant-admin", [11; 32]).unwrap();
let trusted = issuer.trusted();
assert_eq!(trusted.issuer_id(), "tenant-admin");
assert_ne!(trusted.key_id(), [0; 32]);
assert_eq!(trusted.public_key(), issuer.public_key());
}
#[test]
fn every_truncated_principal_encoding_is_rejected() {
let keys = PrincipalKeypair::from_secret_bytes(
"acme",
"alice",
PrincipalKind::User,
1,
[7; 32],
[9; 32],
)
.unwrap();
let encoded = keys.principal().encode();
for end in 0..encoded.len() {
assert!(
Principal::decode(&encoded[..end], &AccessValidationPolicy::default()).is_err(),
"accepted truncation at byte {end}"
);
}
}