diff --git a/crates/fs-mistrust/src/lib.rs b/crates/fs-mistrust/src/lib.rs index b3488a421..da3a5897b 100644 --- a/crates/fs-mistrust/src/lib.rs +++ b/crates/fs-mistrust/src/lib.rs @@ -815,7 +815,7 @@ impl<'a> Verifier<'a> { mod test { #![allow(clippy::unwrap_used)] use super::*; - use testing::Dir; + use testing::{mistrust_build, Dir, MistrustOp}; #[cfg(target_family = "unix")] use testing::LinkType; @@ -833,20 +833,10 @@ mod test { d.chmod("e/f", 0o777); d.link_rel(LinkType::Dir, "a/b/c", "d"); - let mut b = Mistrust::builder(); - let m = b - .ignore_prefix(d.canonical_root()); - - #[cfg(all( - target_family = "unix", - not(target_os = "ios"), - not(target_os = "android") - ))] - let m = m.trust_no_group_id(); - - let m = m - .build() - .unwrap(); + let m = mistrust_build(&[ + MistrustOp::IgnorePrefix(d.canonical_root()), + MistrustOp::TrustNoGroupId(), + ]); // /a/b/c should be fine... m.check_directory(d.path("a/b/c")).unwrap(); @@ -874,18 +864,14 @@ mod test { } // With normal settings should be okay... - let m = Mistrust::builder() - .ignore_prefix(d.canonical_root()) - .build() - .unwrap(); + let m = mistrust_build(&[MistrustOp::IgnorePrefix(d.canonical_root())]); m.check_directory(d.path("a/b")).unwrap(); // With admin_only, it'll fail. - let m = Mistrust::builder() - .ignore_prefix(d.canonical_root()) - .trust_admin_only() - .build() - .unwrap(); + let m = mistrust_build(&[ + MistrustOp::IgnorePrefix(d.canonical_root()), + MistrustOp::TrustAdminOnly(), + ]); let err = m.check_directory(d.path("a/b")).unwrap_err(); assert!(matches!(err, Error::BadOwner(_, _))); @@ -900,20 +886,10 @@ mod test { d.chmod("a", 0o700); d.chmod("b", 0o600); - let mut b = Mistrust::builder(); - let m = b - .ignore_prefix(d.canonical_root()); - - #[cfg(all( - target_family = "unix", - not(target_os = "ios"), - not(target_os = "android") - ))] - let m = m.trust_no_group_id(); - - let m = m - .build() - .unwrap(); + let m = mistrust_build(&[ + MistrustOp::IgnorePrefix(d.canonical_root()), + MistrustOp::TrustNoGroupId(), + ]); // If we insist stuff is its own type, it works fine. m.verifier().require_directory().check(d.path("a")).unwrap(); @@ -944,20 +920,10 @@ mod test { d.chmod("a/b", 0o750); d.chmod("a/b/c", 0o640); - let mut b = Mistrust::builder(); - let m = b - .ignore_prefix(d.canonical_root()); - - #[cfg(all( - target_family = "unix", - not(target_os = "ios"), - not(target_os = "android") - ))] - let m = m.trust_no_group_id(); - - let m = m - .build() - .unwrap(); + let m = mistrust_build(&[ + MistrustOp::IgnorePrefix(d.canonical_root()), + MistrustOp::TrustNoGroupId(), + ]); // These will fail, since the file or directory is readable. let e = m.verifier().check(d.path("a/b")).unwrap_err(); @@ -982,20 +948,10 @@ mod test { d.chmod("a", 0o700); d.chmod("a/b", 0o700); - let mut b = Mistrust::builder(); - let m = b - .ignore_prefix(d.canonical_root()); - - #[cfg(all( - target_family = "unix", - not(target_os = "ios"), - not(target_os = "android") - ))] - let m = m.trust_no_group_id(); - - let m = m - .build() - .unwrap(); + let m = mistrust_build(&[ + MistrustOp::IgnorePrefix(d.canonical_root()), + MistrustOp::TrustNoGroupId(), + ]); // Only one error occurs, so we get that error. let e = m @@ -1029,10 +985,7 @@ mod test { d.chmod("a/b", 0o755); d.chmod("a/b/c", 0o700); - let m = Mistrust::builder() - .ignore_prefix(d.canonical_root()) - .build() - .unwrap(); + let m = mistrust_build(&[MistrustOp::IgnorePrefix(d.canonical_root())]); // `a` is world-writable, so the first check will fail. m.check_directory(d.path("a/b/c")).unwrap_err(); @@ -1058,11 +1011,10 @@ mod test { d.chmod("a", 0o770); d.chmod("a/b", 0o770); - let m = Mistrust::builder() - .ignore_prefix(d.canonical_root()) - .trust_no_group_id() - .build() - .unwrap(); + let m = mistrust_build(&[ + MistrustOp::IgnorePrefix(d.canonical_root()), + MistrustOp::TrustNoGroupId(), + ]); // By default, we shouldn't be accept this directory, since it is // group-writable. @@ -1072,20 +1024,19 @@ mod test { // But we can make the group trusted, which will make it okay for the // directory to be group-writable. let gid = d.path("a/b").metadata().unwrap().gid(); - let m = Mistrust::builder() - .ignore_prefix(d.canonical_root()) - .trust_group(gid) - .build() - .unwrap(); + + let m = mistrust_build(&[ + MistrustOp::IgnorePrefix(d.canonical_root()), + MistrustOp::TrustGroup(gid), + ]); m.check_directory(d.path("a/b")).unwrap(); // OTOH, if we made a _different_ group trusted, it'll fail. - let m = Mistrust::builder() - .ignore_prefix(d.canonical_root()) - .trust_group(gid ^ 1) - .build() - .unwrap(); + let m = mistrust_build(&[ + MistrustOp::IgnorePrefix(d.canonical_root()), + MistrustOp::TrustGroup(gid ^ 1), + ]); let e = m.check_directory(d.path("a/b")).unwrap_err(); assert!(matches!(e, Error::BadPermission(..))); @@ -1096,10 +1047,7 @@ mod test { let d = Dir::new(); d.dir("a/b"); - let m = Mistrust::builder() - .ignore_prefix(d.canonical_root()) - .build() - .unwrap(); + let m = mistrust_build(&[MistrustOp::IgnorePrefix(d.canonical_root())]); #[cfg(target_family = "unix")] { @@ -1133,10 +1081,7 @@ mod test { d.chmod("a/b/c", 0o755); d.chmod("a/b/c/d", 0o666); - let m = Mistrust::builder() - .ignore_prefix(d.canonical_root()) - .build() - .unwrap(); + let m = mistrust_build(&[MistrustOp::IgnorePrefix(d.canonical_root())]); // A check should work... m.check_directory(d.path("a/b")).unwrap(); @@ -1165,10 +1110,7 @@ mod test { d.chmod("a/b/c", 0o777); d.chmod("a/b/c/d", 0o666); - let m = Mistrust::builder() - .dangerously_trust_everyone() - .build() - .unwrap(); + let m = mistrust_build(&[MistrustOp::DangerouslyTrustEveryone()]); // This is fine. m.check_directory(d.path("a/b/c")).unwrap(); diff --git a/crates/fs-mistrust/src/testing.rs b/crates/fs-mistrust/src/testing.rs index 627efe091..0cfa00064 100644 --- a/crates/fs-mistrust/src/testing.rs +++ b/crates/fs-mistrust/src/testing.rs @@ -12,6 +12,8 @@ use std::{ #[cfg(target_family = "unix")] use std::os::unix::{self, fs::PermissionsExt}; +use crate::Mistrust; + /// A temporary directory with convenience functions to build items inside it. #[derive(Debug)] pub(crate) struct Dir { @@ -143,3 +145,55 @@ impl Dir { } } } + +/// A utility type to represent the different operations available for a MistrustBuilder. +#[derive(Debug)] +pub(crate) enum MistrustOp<'a> { + IgnorePrefix(&'a Path), + DangerouslyTrustEveryone(), + TrustNoGroupId(), + + #[cfg(target_family = "unix")] + TrustAdminOnly(), + + #[cfg(target_family = "unix")] + TrustGroup(u32), +} + +/// A convenience function to construct a Mistrust type using a set of given operations. +pub(crate) fn mistrust_build(ops: &[MistrustOp]) -> Mistrust { + ops.iter() + .fold(&mut Mistrust::builder(), |m, op| { + match op { + MistrustOp::IgnorePrefix(prefix) => m.ignore_prefix(prefix), + + MistrustOp::DangerouslyTrustEveryone() => m.dangerously_trust_everyone(), + + MistrustOp::TrustNoGroupId() => { + // We call `m.trust_no_group_id()` on platforms where it is available. + // Otherwise, we simply return `m` unmodified here. + #[cfg(all( + target_family = "unix", + not(target_os = "ios"), + not(target_os = "android") + ))] + return m.trust_no_group_id(); + + #[cfg(not(all( + target_family = "unix", + not(target_os = "ios"), + not(target_os = "android") + )))] + return m; + } + + #[cfg(target_family = "unix")] + MistrustOp::TrustAdminOnly() => m.trust_admin_only(), + + #[cfg(target_family = "unix")] + MistrustOp::TrustGroup(gid) => m.trust_group(*gid), + } + }) + .build() + .unwrap() +}