whyno-core 0.5.0

Permission check pipeline, fix engine, and state types
Documentation
use super::*;

#[test]
fn posix_acl_new_and_entries_api() {
    // Verifies the public constructor and read-only slice accessor.
    // `PosixAcl::new` must accept a Vec<AclEntry> and `entries` must
    // return a `&[AclEntry]` with the same contents.
    let entry = AclEntry {
        tag: AclTag::UserObj,
        qualifier: None,
        perms: AclPerms {
            read: true,
            write: false,
            execute: true,
        },
    };
    let acl = PosixAcl::new(vec![entry.clone()]);
    let slice = acl.entries();
    assert_eq!(slice.len(), 1);
    assert_eq!(slice[0], entry);
}

#[test]
fn posix_acl_entries_returns_empty_slice_for_empty_acl() {
    let acl = PosixAcl::new(vec![]);
    assert!(acl.entries().is_empty());
}

fn mask_entry(r: bool, w: bool, x: bool) -> AclEntry {
    AclEntry {
        tag: AclTag::Mask,
        qualifier: None,
        perms: AclPerms {
            read: r,
            write: w,
            execute: x,
        },
    }
}

fn named_user_entry(uid: u32, r: bool, w: bool, x: bool) -> AclEntry {
    AclEntry {
        tag: AclTag::User,
        qualifier: Some(uid),
        perms: AclPerms {
            read: r,
            write: w,
            execute: x,
        },
    }
}

fn named_group_entry(gid: u32, r: bool, w: bool, x: bool) -> AclEntry {
    AclEntry {
        tag: AclTag::Group,
        qualifier: Some(gid),
        perms: AclPerms {
            read: r,
            write: w,
            execute: x,
        },
    }
}

#[test]
fn mask_returns_some_when_present() {
    let acl = PosixAcl(vec![mask_entry(true, false, true)]);
    let mask = acl.mask();
    assert_eq!(
        mask,
        Some(&AclPerms {
            read: true,
            write: false,
            execute: true,
        })
    );
}

#[test]
fn mask_returns_none_when_absent() {
    let acl = PosixAcl(vec![named_user_entry(33, true, true, true)]);
    assert!(acl.mask().is_none());
}

#[test]
fn named_user_finds_matching_entry() {
    let acl = PosixAcl(vec![
        named_user_entry(33, true, false, false),
        named_user_entry(99, false, true, false),
    ]);
    let entry = acl.named_user(33);
    assert_eq!(entry.map(|e| e.qualifier), Some(Some(33)));
}

#[test]
fn named_user_returns_none_for_missing_uid() {
    let acl = PosixAcl(vec![named_user_entry(33, true, false, false)]);
    assert!(acl.named_user(999).is_none());
}

#[test]
fn named_group_finds_matching_entry() {
    let acl = PosixAcl(vec![named_group_entry(44, false, true, false)]);
    let entry = acl.named_group(44);
    assert_eq!(entry.map(|e| e.qualifier), Some(Some(44)));
}

#[test]
fn named_group_returns_none_for_missing_gid() {
    let acl = PosixAcl(vec![named_group_entry(44, false, true, false)]);
    assert!(acl.named_group(999).is_none());
}

#[test]
fn effective_perms_with_mask_ands_named_user() {
    let acl = PosixAcl(vec![
        named_user_entry(33, true, true, true),
        mask_entry(true, false, true),
    ]);
    let entry = acl.named_user(33).expect("entry exists");
    let effective = acl.effective_perms(entry);
    assert_eq!(
        effective,
        AclPerms {
            read: true,
            write: false,
            execute: true,
        }
    );
}

#[test]
fn effective_perms_with_mask_ands_named_group() {
    let acl = PosixAcl(vec![
        named_group_entry(44, true, true, false),
        mask_entry(false, true, false),
    ]);
    let entry = acl.named_group(44).expect("entry exists");
    let effective = acl.effective_perms(entry);
    assert_eq!(
        effective,
        AclPerms {
            read: false,
            write: true,
            execute: false,
        }
    );
}

#[test]
fn effective_perms_with_mask_ands_group_obj() {
    let group_obj = AclEntry {
        tag: AclTag::GroupObj,
        qualifier: None,
        perms: AclPerms {
            read: true,
            write: true,
            execute: true,
        },
    };
    let acl = PosixAcl(vec![group_obj.clone(), mask_entry(true, false, false)]);
    let effective = acl.effective_perms(&group_obj);
    assert_eq!(
        effective,
        AclPerms {
            read: true,
            write: false,
            execute: false,
        }
    );
}

#[test]
fn effective_perms_without_mask_returns_entry_unchanged() {
    let acl = PosixAcl(vec![named_user_entry(33, true, true, true)]);
    let entry = acl.named_user(33).expect("entry exists");
    let effective = acl.effective_perms(entry);
    assert_eq!(
        effective,
        AclPerms {
            read: true,
            write: true,
            execute: true,
        }
    );
}

#[test]
fn effective_perms_user_obj_not_affected_by_mask() {
    let user_obj = AclEntry {
        tag: AclTag::UserObj,
        qualifier: None,
        perms: AclPerms {
            read: true,
            write: true,
            execute: true,
        },
    };
    let acl = PosixAcl(vec![user_obj.clone(), mask_entry(false, false, false)]);
    let effective = acl.effective_perms(&user_obj);
    assert_eq!(
        effective,
        AclPerms {
            read: true,
            write: true,
            execute: true,
        }
    );
}

#[test]
fn effective_perms_other_not_affected_by_mask() {
    let other = AclEntry {
        tag: AclTag::Other,
        qualifier: None,
        perms: AclPerms {
            read: true,
            write: false,
            execute: false,
        },
    };
    let acl = PosixAcl(vec![other.clone(), mask_entry(false, false, false)]);
    let effective = acl.effective_perms(&other);
    assert_eq!(
        effective,
        AclPerms {
            read: true,
            write: false,
            execute: false,
        }
    );
}