use std::time::{Duration, Instant};
use futures::executor::block_on;
use ikigai_core::{ArgRef, Capability, Error, Iri, Request, Verb};
fn eval(src: &str) -> Request {
Request::new(
Verb::Source,
Iri::parse("urn:lisp:eval").expect("valid IRI"),
)
.with_arg("in", ArgRef::Inline(src.as_bytes().to_vec()))
}
#[test]
#[allow(clippy::disallowed_methods)]
fn the_served_eval_is_governed_clamped_and_absent_without_optin() {
ikigai_embedded::set_eval_timeout_secs(2);
let workspace = std::env::temp_dir().join("ikigai-wire-eval-workspace");
let _ = std::fs::remove_dir_all(&workspace);
std::fs::create_dir_all(&workspace).expect("workspace root");
ikigai_embedded::set_file_root(workspace);
let dir = std::env::temp_dir().join("ikigai-code-signers-test");
let _ = std::fs::remove_dir_all(&dir);
std::fs::create_dir_all(&dir).expect("signers dir");
std::fs::write(dir.join("k1.pub"), K1_PUB).expect("write pub key");
ikigai_embedded::set_code_signers_dir(dir.clone());
ikigai_embedded::set_code_signers(vec!["urn:codekey:k1.pub".to_string()]);
let warm = ikigai_core::Kernel::new(std::sync::Arc::new(ikigai_lisp::space()));
block_on(warm.issue(eval("(+ 1 1)"), &Capability::root())).expect("warm-up eval");
let kernel = ikigai_embedded::calendar_server_kernel_with_eval();
let ceiling = Capability::root().attenuate([
"urn:cap:lisp".to_string(),
"urn:cap:personal:calendar:read:freebusy".to_string(),
]);
let out = block_on(kernel.issue(eval("(+ 20 22)"), &ceiling)).expect("a granted eval runs");
assert_eq!(out.bytes, b"42");
let started = Instant::now();
let err =
block_on(kernel.issue(eval("(let loop ((i 0)) (loop (+ i 1)))"), &ceiling)).unwrap_err();
assert!(
matches!(err, Error::Timeout(_)),
"the governor bounds a served runaway: {err:?}"
);
assert!(
started.elapsed() < Duration::from_secs(10),
"released at the budget: {:?}",
started.elapsed()
);
let no_lisp =
Capability::root().attenuate(["urn:cap:personal:calendar:read:freebusy".to_string()]);
let err = block_on(kernel.issue(eval("(+ 1 1)"), &no_lisp)).unwrap_err();
assert!(matches!(err, Error::Denied(_)), "got {err:?}");
let plain = ikigai_embedded::calendar_server_kernel();
let err = block_on(plain.issue(eval("(+ 1 1)"), &Capability::root())).unwrap_err();
assert!(
matches!(err, Error::Unresolved(_)),
"eval is not even nameable without the opt-in: {err:?}"
);
signed_run_door(&kernel);
demo_wakes_on_the_served_surface();
}
fn demo_wakes_on_the_served_surface() {
let kernel = ikigai_embedded::trusted_kernel_for("Remote (IPC)");
let cap = Capability::root();
let err = block_on(kernel.issue(
Request::new(
Verb::Source,
Iri::parse("urn:demo:jury").expect("valid IRI"),
),
&cap,
))
.unwrap_err();
assert!(matches!(err, Error::Unresolved(_)), "got {err:?}");
let out = block_on(
kernel.issue(
Request::new(Verb::Sink, Iri::parse("urn:host:demo").expect("valid IRI"))
.with_arg("content", ArgRef::Inline(b"on".to_vec())),
&cap,
),
)
.expect("the demo toggle is served");
assert_eq!(out.bytes, b"demo on\n");
block_on(kernel.issue(
Request::new(
Verb::Source,
Iri::parse("urn:demo:jury").expect("valid IRI"),
),
&cap,
))
.expect("the demo endpoint woke on the served surface");
}
const K1_PRIV: &str = "-----BEGIN PRIVATE KEY-----\n\
MC4CAQAwBQYDK2VwBCIEIEIW/m80W4IrD82k3Mos0l4aeyfOkZMMZXqEYt6jpawc\n\
-----END PRIVATE KEY-----\n";
const K1_PUB: &str = "-----BEGIN PUBLIC KEY-----\n\
MCowBQYDK2VwAyEAa9JuLzyLESJBF9LPZZ4RJk13iu5OhgKvLRQ3q0oQ4pE=\n\
-----END PUBLIC KEY-----\n";
fn signed_run_door(_governed_2s: &ikigai_core::Kernel) {
ikigai_embedded::set_eval_timeout_secs(60);
let kernel = &ikigai_embedded::calendar_server_kernel_with_eval();
let author = ikigai_core::Kernel::new(std::sync::Arc::new(ikigai_sign::space().bind(
ikigai_core::Exact::new("urn:author:key"),
StaticKey(K1_PRIV),
)));
let program = "(+ 40 2)";
let sig = {
let out = block_on(
author.issue(
Request::new(
Verb::Source,
Iri::parse("urn:sign:sign").expect("valid IRI"),
)
.with_arg("in", ArgRef::Inline(program.as_bytes().to_vec()))
.with_arg("key", ArgRef::Inline(b"urn:author:key".to_vec())),
&Capability::root().attenuate(["urn:cap:sign".to_string()]),
),
)
.expect("author signs");
String::from_utf8(out.bytes).expect("sig graph utf-8")
};
let run = |sig: &str| {
Request::new(Verb::Source, Iri::parse("urn:lisp:run").expect("valid IRI"))
.with_arg("in", ArgRef::Inline(program.as_bytes().to_vec()))
.with_arg("sig", ArgRef::Inline(sig.as_bytes().to_vec()))
.with_arg("key", ArgRef::Inline(b"urn:codekey:k1.pub".to_vec()))
};
let ceiling = Capability::root().attenuate([
"urn:cap:lisp:run".to_string(),
"urn:cap:personal:calendar:read:freebusy".to_string(),
]);
let out = block_on(kernel.issue(run(&sig), &ceiling)).expect("the signed program runs");
assert_eq!(out.bytes, b"42");
let err = block_on(kernel.issue(eval("(+ 1 1)"), &ceiling)).unwrap_err();
assert!(
matches!(err, Error::Denied(_)),
"signed-only means signed-only: {err:?}"
);
}
struct StaticKey(&'static str);
#[async_trait::async_trait]
impl ikigai_core::Endpoint for StaticKey {
async fn invoke(
&self,
_inv: &ikigai_core::Invocation<'_>,
) -> ikigai_core::Result<ikigai_core::Representation> {
Ok(ikigai_core::Representation::new(
ikigai_core::ReprType::new("application/x-pem-file"),
self.0.as_bytes().to_vec(),
))
}
}