use super::{Plan, check_apply};
use std::cell::Cell;
use std::fs;
use std::os::unix::fs::PermissionsExt;
thread_local! {
pub(super) static EFFECTIVE_UID: Cell<u32> = Cell::new(rustix::process::geteuid().as_raw());
}
#[test]
fn round2_sticky_folder_refuses_replacing_another_users_configuration()
-> Result<(), Box<dyn std::error::Error>> {
let folder = tempfile::Builder::new()
.prefix("door-sticky-")
.tempdir_in("/tmp")?;
let path = folder.path().join("door.json");
fs::write(&path, b"{}")?;
fs::set_permissions(&path, fs::Permissions::from_mode(0o666))?;
fs::set_permissions(folder.path(), fs::Permissions::from_mode(0o1777))?;
let plan = Plan {
bytes: b"{}".to_vec(),
names: vec!["fixture".to_owned()],
};
let user = rustix::process::geteuid().as_raw();
EFFECTIVE_UID.with(|uid| uid.set(user ^ 1));
let result = check_apply(&path, &plan);
EFFECTIVE_UID.with(|uid| uid.set(user));
assert!(
result.is_err(),
"sticky folder accepted a foreign replacement"
);
let refusal = result.err().ok_or("upgrade refusal missing")?;
assert!(
refusal.starts_with("door_config_upgrade_failed:"),
"{refusal}"
);
assert!(refusal.contains("sticky"), "{refusal}");
assert_eq!(fs::read(&path)?, b"{}");
assert_eq!(fs::read_dir(folder.path())?.count(), 1);
check_apply(&path, &plan)?;
fs::set_permissions(folder.path(), fs::Permissions::from_mode(0o777))?;
EFFECTIVE_UID.with(|uid| uid.set(user ^ 1));
let nonsticky = check_apply(&path, &plan);
EFFECTIVE_UID.with(|uid| uid.set(user));
nonsticky?;
Ok(())
}