cred: reject the reserved host and migrate durable fixtures

This commit is contained in:
2026-11-06 22:44:17 +00:00
parent 86c5d8a4e4
commit e332e76807
3 changed files with 35 additions and 6 deletions
+2 -1
View File
@@ -184,7 +184,8 @@ pub(crate) fn validate(item: &Item) -> Result<()> {
})
|| r.hosts.iter().any(|p| {
let h = p.strip_prefix("*.").unwrap_or(p);
h.is_empty()
p.eq_ignore_ascii_case("host.sausage")
|| h.is_empty()
|| h.starts_with('.')
|| h.ends_with('.')
|| h.contains("..")
+17
View File
@@ -25,6 +25,23 @@ fn parts(uri: &str) -> http::request::Parts {
http::Request::get(uri).body(()).unwrap().into_parts().0
}
#[test]
fn reserved_host_is_rejected_in_every_case() {
let dir = tempfile::tempdir().unwrap();
let c = Cred::open(dir.path()).unwrap();
let caller = Caller::default();
for host in [
"host.sausage",
"HOST.SAUSAGE",
"Host.Sausage",
"hOsT.sAuSaGe",
] {
assert!(
c.create_item(config(host, None), &caller, c.unlocked().unwrap())
.is_err()
);
}
}
#[test]
fn ports_before_and_after_transform() {
let dir = tempfile::tempdir().unwrap();
let c = Cred::open(dir.path()).unwrap();
+16 -5
View File
@@ -5,6 +5,7 @@ use sausage::{
requests::{GrantRequest, Overrides},
store::Cred,
types::Caller,
webauthn::Decision,
},
harness::{run_module, run_module_with_credentials},
world::World,
@@ -55,7 +56,7 @@ fn sigkill_preserves_request_wait() -> anyhow::Result<()> {
fields: vec![],
},
&admin,
"test",
cred.unlocked()?,
)?;
let mut child = Command::new(std::env::current_exe()?)
.args(["--exact", "restart_child", "--nocapture"])
@@ -108,7 +109,12 @@ fn sigkill_preserves_request_wait() -> anyhow::Result<()> {
}
child.kill()?;
child.wait()?;
cred.approve(&id, "yes", Overrides::default(), Some("test"))?;
cred.approve(
&id,
Decision::Approve,
Overrides::default(),
cred.unlocked()?,
)?;
for _ in 0..2 {
let mut resumed = Command::new(std::env::current_exe()?)
.args(["--exact", "restart_child", "--nocapture"])
@@ -239,7 +245,7 @@ async fn decisions_wake_idle_conversation() -> anyhow::Result<()> {
fields: vec![],
},
&admin,
"test",
cred.unlocked()?,
)?;
cred.file_request(
&admin,
@@ -291,8 +297,13 @@ async fn decisions_wake_idle_conversation() -> anyhow::Result<()> {
tokio::task::yield_now().await;
}
match state {
"approved" => cred.approve(&id, "yes", Overrides::default(), Some("test"))?,
"denied" => cred.deny(&id, "no", Some("test"))?,
"approved" => cred.approve(
&id,
Decision::Approve,
Overrides::default(),
cred.unlocked()?,
)?,
"denied" => cred.deny(&id, Decision::Deny, cred.unlocked()?)?,
_ => {
let db = rusqlite::Connection::open(dir.join("host/cred.sqlite"))?;
db.execute("UPDATE requests SET expires=0 WHERE id=?", [&id])?;