bucketwarden-server 0.1.0

BucketWarden storage server runtime.
Documentation
use bucketwarden_lock::{ObjectLock, RetentionMode};
use bucketwarden_s3::{ObjectMetadata, PutObjectRequest};
use bucketwarden_server::{BucketWarden, RuntimeConfig, RuntimeError};

#[test]
fn certified_runtime_slice_exercises_public_crate_surface() {
    let mut runtime = BucketWarden::new(RuntimeConfig::development()).expect("runtime");
    runtime.allow("operator", "s3:*", "*");
    runtime
        .create_bucket("operator", "archive-001")
        .expect("bucket");

    let put = runtime
        .put_object(
            "operator",
            PutObjectRequest {
                bucket: "archive-001".to_string(),
                key: "records/report.json".to_string(),
                body: br#"{"ok":true}"#.to_vec(),
                metadata: ObjectMetadata::default(),
            },
            ObjectLock::none(),
        )
        .expect("put object");

    let got = runtime
        .get_object("operator", "archive-001", "records/report.json")
        .expect("get object");

    runtime
        .set_retention(
            "operator",
            "archive-001",
            "records/report.json",
            RetentionMode::Governance,
            3600,
            false,
        )
        .expect("retention");
    let denied = runtime
        .delete_object("operator", "archive-001", "records/report.json", false)
        .expect_err("retention denies delete");
    let deleted = runtime
        .delete_object("operator", "archive-001", "records/report.json", true)
        .expect("governance bypass delete");

    assert_eq!(put.version_id, "v1");
    assert_eq!(got.body, br#"{"ok":true}"#);
    assert!(matches!(
        denied,
        RuntimeError::ObjectLocked(bucketwarden_lock::LockError::GovernanceRetentionActive { .. })
    ));
    assert_eq!(deleted.delete_marker_version_id, "v2");
    assert_eq!(runtime.replication_records().len(), 2);
    assert!(runtime.audit_events().iter().any(|event| {
        event.outcome == bucketwarden_audit::AuditOutcome::Denied
            && event.action == "s3:DeleteObject"
    }));
}

#[test]
fn certified_runtime_slice_enforces_explicit_deny() {
    let mut runtime = BucketWarden::new(RuntimeConfig::development()).expect("runtime");
    runtime.allow("operator", "s3:*", "*");
    runtime.deny("operator", "s3:DeleteObject", "archive-001/private/*");
    runtime
        .create_bucket("operator", "archive-001")
        .expect("bucket");
    runtime
        .put_object(
            "operator",
            PutObjectRequest {
                bucket: "archive-001".to_string(),
                key: "private/report.json".to_string(),
                body: b"private".to_vec(),
                metadata: ObjectMetadata::default(),
            },
            ObjectLock::none(),
        )
        .expect("put");

    let denied = runtime
        .delete_object("operator", "archive-001", "private/report.json", true)
        .expect_err("explicit deny");

    assert!(matches!(
        denied,
        RuntimeError::AccessDenied {
            explicit_deny: true,
            ..
        }
    ));
}