use crate::database::universal_types::UniversalUuid;
pub mod events {
pub const PACKAGE_LOAD_SUCCESS: &str = "package.load.success";
pub const PACKAGE_LOAD_FAILURE: &str = "package.load.failure";
pub const PACKAGE_SIGNED: &str = "package.signed";
pub const PACKAGE_SIGN_FAILURE: &str = "package.sign.failure";
pub const KEY_SIGNING_CREATED: &str = "key.signing.created";
pub const KEY_SIGNING_CREATE_FAILED: &str = "key.signing.create_failed";
pub const KEY_SIGNING_REVOKED: &str = "key.signing.revoked";
pub const KEY_EXPORTED: &str = "key.exported";
pub const KEY_TRUSTED_ADDED: &str = "key.trusted.added";
pub const KEY_TRUSTED_REVOKED: &str = "key.trusted.revoked";
pub const KEY_TRUST_ACL_GRANTED: &str = "key.trust_acl.granted";
pub const KEY_TRUST_ACL_REVOKED: &str = "key.trust_acl.revoked";
pub const VERIFICATION_SUCCESS: &str = "verification.success";
pub const VERIFICATION_FAILURE: &str = "verification.failure";
}
pub fn log_signing_key_created(
org_id: UniversalUuid,
key_id: UniversalUuid,
key_fingerprint: &str,
key_name: &str,
) {
tracing::info!(
event_type = events::KEY_SIGNING_CREATED,
org_id = %org_id,
key_id = %key_id,
key_fingerprint = %key_fingerprint,
key_name = %key_name,
"Signing key created"
);
}
pub fn log_signing_key_create_failed(org_id: UniversalUuid, key_name: &str, error: &str) {
tracing::error!(
event_type = events::KEY_SIGNING_CREATE_FAILED,
org_id = %org_id,
key_name = %key_name,
error = %error,
"Failed to create signing key"
);
}
pub fn log_signing_key_revoked(
org_id: UniversalUuid,
key_id: UniversalUuid,
key_fingerprint: &str,
key_name: Option<&str>,
) {
tracing::warn!(
event_type = events::KEY_SIGNING_REVOKED,
org_id = %org_id,
key_id = %key_id,
key_fingerprint = %key_fingerprint,
key_name = key_name.unwrap_or("<unknown>"),
"Signing key revoked"
);
}
pub fn log_key_exported(key_id: UniversalUuid, key_fingerprint: &str) {
tracing::info!(
event_type = events::KEY_EXPORTED,
key_id = %key_id,
key_fingerprint = %key_fingerprint,
"Public key exported"
);
}
pub fn log_trusted_key_added(
org_id: UniversalUuid,
key_id: UniversalUuid,
key_fingerprint: &str,
key_name: Option<&str>,
) {
tracing::warn!(
event_type = events::KEY_TRUSTED_ADDED,
org_id = %org_id,
key_id = %key_id,
key_fingerprint = %key_fingerprint,
key_name = key_name.unwrap_or("<unnamed>"),
"Trusted key added"
);
}
pub fn log_trusted_key_revoked(key_id: UniversalUuid) {
tracing::warn!(
event_type = events::KEY_TRUSTED_REVOKED,
key_id = %key_id,
"Trusted key revoked"
);
}
pub fn log_trust_acl_granted(parent_org: UniversalUuid, child_org: UniversalUuid) {
tracing::warn!(
event_type = events::KEY_TRUST_ACL_GRANTED,
parent_org_id = %parent_org,
child_org_id = %child_org,
"Trust ACL granted"
);
}
pub fn log_trust_acl_revoked(parent_org: UniversalUuid, child_org: UniversalUuid) {
tracing::warn!(
event_type = events::KEY_TRUST_ACL_REVOKED,
parent_org_id = %parent_org,
child_org_id = %child_org,
"Trust ACL revoked"
);
}
pub fn log_package_signed(package_path: &str, package_hash: &str, key_fingerprint: &str) {
tracing::info!(
event_type = events::PACKAGE_SIGNED,
package_path = %package_path,
package_hash = %package_hash,
key_fingerprint = %key_fingerprint,
"Package signed"
);
}
pub fn log_package_sign_failed(package_path: &str, error: &str) {
tracing::error!(
event_type = events::PACKAGE_SIGN_FAILURE,
package_path = %package_path,
error = %error,
"Package signing failed"
);
}
pub fn log_package_load_success(
org_id: UniversalUuid,
package_path: &str,
package_hash: &str,
signer_fingerprint: Option<&str>,
signature_verified: bool,
) {
tracing::info!(
event_type = events::PACKAGE_LOAD_SUCCESS,
org_id = %org_id,
package_path = %package_path,
package_hash = %package_hash,
signer_fingerprint = signer_fingerprint.unwrap_or("<none>"),
signature_verified = signature_verified,
"Package loaded successfully"
);
}
pub fn log_package_load_failure(
org_id: UniversalUuid,
package_path: &str,
error: &str,
failure_reason: &str,
) {
tracing::warn!(
event_type = events::PACKAGE_LOAD_FAILURE,
org_id = %org_id,
package_path = %package_path,
error = %error,
failure_reason = %failure_reason,
"Package load failed"
);
}
pub fn log_verification_success(
org_id: UniversalUuid,
package_hash: &str,
signer_fingerprint: &str,
signer_name: Option<&str>,
) {
tracing::info!(
event_type = events::VERIFICATION_SUCCESS,
org_id = %org_id,
package_hash = %package_hash,
signer_fingerprint = %signer_fingerprint,
signer_name = signer_name.unwrap_or("<unknown>"),
"Package signature verified successfully"
);
}
pub fn log_verification_failure(
org_id: UniversalUuid,
package_hash: &str,
failure_reason: &str,
signer_fingerprint: Option<&str>,
) {
tracing::warn!(
event_type = events::VERIFICATION_FAILURE,
org_id = %org_id,
package_hash = %package_hash,
failure_reason = %failure_reason,
signer_fingerprint = signer_fingerprint.unwrap_or("<unknown>"),
"Package signature verification failed"
);
}
#[cfg(test)]
mod tests {
use super::*;
use std::sync::{Arc, Mutex};
use tracing_subscriber::fmt::MakeWriter;
#[derive(Clone)]
struct StringWriter(Arc<Mutex<Vec<u8>>>);
impl std::io::Write for StringWriter {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
self.0.lock().unwrap().extend_from_slice(buf);
Ok(buf.len())
}
fn flush(&mut self) -> std::io::Result<()> {
Ok(())
}
}
impl<'a> MakeWriter<'a> for StringWriter {
type Writer = StringWriter;
fn make_writer(&'a self) -> Self::Writer {
self.clone()
}
}
fn with_captured_logs<F>(f: F) -> String
where
F: FnOnce(),
{
let buffer = Arc::new(Mutex::new(Vec::new()));
let writer = StringWriter(buffer.clone());
let subscriber = tracing_subscriber::fmt()
.with_writer(writer)
.with_ansi(false)
.finish();
tracing::subscriber::with_default(subscriber, f);
let result = String::from_utf8(buffer.lock().unwrap().clone()).unwrap();
result
}
#[test]
fn test_log_signing_key_created() {
let output = with_captured_logs(|| {
log_signing_key_created(
UniversalUuid::new_v4(),
UniversalUuid::new_v4(),
"abc123",
"test-key",
);
});
assert!(output.contains(events::KEY_SIGNING_CREATED));
assert!(output.contains("test-key"));
assert!(output.contains("abc123"));
}
#[test]
fn test_log_verification_failure() {
let output = with_captured_logs(|| {
log_verification_failure(
UniversalUuid::new_v4(),
"package_hash_123",
"untrusted_signer",
Some("fingerprint_abc"),
);
});
assert!(output.contains(events::VERIFICATION_FAILURE));
assert!(output.contains("untrusted_signer"));
assert!(output.contains("fingerprint_abc"));
}
#[test]
fn test_log_package_load_success() {
let output = with_captured_logs(|| {
log_package_load_success(
UniversalUuid::new_v4(),
"/path/to/package.so",
"hash_123",
Some("fingerprint_456"),
true,
);
});
assert!(output.contains(events::PACKAGE_LOAD_SUCCESS));
assert!(output.contains("/path/to/package.so"));
assert!(output.contains("signature_verified"));
}
#[test]
fn test_log_trust_acl_granted() {
let output = with_captured_logs(|| {
log_trust_acl_granted(UniversalUuid::new_v4(), UniversalUuid::new_v4());
});
assert!(output.contains(events::KEY_TRUST_ACL_GRANTED));
assert!(output.contains("parent_org_id"));
assert!(output.contains("child_org_id"));
}
#[test]
fn test_event_type_constants() {
assert!(events::PACKAGE_LOAD_SUCCESS.starts_with("package."));
assert!(events::KEY_SIGNING_CREATED.starts_with("key."));
assert!(events::VERIFICATION_SUCCESS.starts_with("verification."));
}
#[test]
fn test_log_signing_key_create_failed() {
let output = with_captured_logs(|| {
log_signing_key_create_failed(UniversalUuid::new_v4(), "bad-key", "encryption error");
});
assert!(output.contains(events::KEY_SIGNING_CREATE_FAILED));
assert!(output.contains("bad-key"));
assert!(output.contains("encryption error"));
}
#[test]
fn test_log_signing_key_revoked() {
let output = with_captured_logs(|| {
log_signing_key_revoked(
UniversalUuid::new_v4(),
UniversalUuid::new_v4(),
"fp_abc",
Some("my-key"),
);
});
assert!(output.contains(events::KEY_SIGNING_REVOKED));
assert!(output.contains("fp_abc"));
assert!(output.contains("my-key"));
}
#[test]
fn test_log_signing_key_revoked_no_name() {
let output = with_captured_logs(|| {
log_signing_key_revoked(
UniversalUuid::new_v4(),
UniversalUuid::new_v4(),
"fp_xyz",
None,
);
});
assert!(output.contains(events::KEY_SIGNING_REVOKED));
assert!(output.contains("<unknown>"));
}
#[test]
fn test_log_key_exported() {
let output = with_captured_logs(|| {
log_key_exported(UniversalUuid::new_v4(), "fp_export_123");
});
assert!(output.contains(events::KEY_EXPORTED));
assert!(output.contains("fp_export_123"));
}
#[test]
fn test_log_trusted_key_added() {
let output = with_captured_logs(|| {
log_trusted_key_added(
UniversalUuid::new_v4(),
UniversalUuid::new_v4(),
"trusted_fp",
Some("vendor-key"),
);
});
assert!(output.contains(events::KEY_TRUSTED_ADDED));
assert!(output.contains("trusted_fp"));
assert!(output.contains("vendor-key"));
}
#[test]
fn test_log_trusted_key_added_no_name() {
let output = with_captured_logs(|| {
log_trusted_key_added(
UniversalUuid::new_v4(),
UniversalUuid::new_v4(),
"trusted_fp2",
None,
);
});
assert!(output.contains(events::KEY_TRUSTED_ADDED));
assert!(output.contains("<unnamed>"));
}
#[test]
fn test_log_trusted_key_revoked() {
let output = with_captured_logs(|| {
log_trusted_key_revoked(UniversalUuid::new_v4());
});
assert!(output.contains(events::KEY_TRUSTED_REVOKED));
}
#[test]
fn test_log_trust_acl_revoked() {
let output = with_captured_logs(|| {
log_trust_acl_revoked(UniversalUuid::new_v4(), UniversalUuid::new_v4());
});
assert!(output.contains(events::KEY_TRUST_ACL_REVOKED));
assert!(output.contains("parent_org_id"));
assert!(output.contains("child_org_id"));
}
#[test]
fn test_log_package_signed() {
let output = with_captured_logs(|| {
log_package_signed("/tmp/pkg.tar.gz", "hash_abc", "fp_signer");
});
assert!(output.contains(events::PACKAGE_SIGNED));
assert!(output.contains("/tmp/pkg.tar.gz"));
assert!(output.contains("hash_abc"));
assert!(output.contains("fp_signer"));
}
#[test]
fn test_log_package_sign_failed() {
let output = with_captured_logs(|| {
log_package_sign_failed("/tmp/bad.tar.gz", "key not found");
});
assert!(output.contains(events::PACKAGE_SIGN_FAILURE));
assert!(output.contains("/tmp/bad.tar.gz"));
assert!(output.contains("key not found"));
}
#[test]
fn test_log_package_load_failure() {
let output = with_captured_logs(|| {
log_package_load_failure(
UniversalUuid::new_v4(),
"/path/to/bad.so",
"hash mismatch",
"tampered",
);
});
assert!(output.contains(events::PACKAGE_LOAD_FAILURE));
assert!(output.contains("/path/to/bad.so"));
assert!(output.contains("hash mismatch"));
assert!(output.contains("tampered"));
}
#[test]
fn test_log_verification_success() {
let output = with_captured_logs(|| {
log_verification_success(
UniversalUuid::new_v4(),
"pkg_hash_ok",
"signer_fp_ok",
Some("trusted-vendor"),
);
});
assert!(output.contains(events::VERIFICATION_SUCCESS));
assert!(output.contains("pkg_hash_ok"));
assert!(output.contains("signer_fp_ok"));
assert!(output.contains("trusted-vendor"));
}
#[test]
fn test_log_verification_success_no_name() {
let output = with_captured_logs(|| {
log_verification_success(UniversalUuid::new_v4(), "pkg_hash", "signer_fp", None);
});
assert!(output.contains(events::VERIFICATION_SUCCESS));
assert!(output.contains("<unknown>"));
}
#[test]
fn test_log_verification_failure_no_fingerprint() {
let output = with_captured_logs(|| {
log_verification_failure(UniversalUuid::new_v4(), "pkg_hash", "no matching key", None);
});
assert!(output.contains(events::VERIFICATION_FAILURE));
assert!(output.contains("<unknown>"));
}
}