Skip to main content

sim_table_core/
capabilities.rs

1//! Canonical host-effect capability names shared by table-like backends.
2//!
3//! Filesystem, search, edit, process, and HTTP host effects use these names as
4//! their canonical tokens. The alias helpers accept compatibility spellings for
5//! host grant files.
6
7use sim_kernel::{CapabilityName, Cx, Error, Result};
8
9/// The capability gating read-only filesystem and directory access.
10pub fn fs_read() -> CapabilityName {
11    CapabilityName::new("fs/read")
12}
13
14/// The capability gating filesystem and directory mutation.
15pub fn fs_write() -> CapabilityName {
16    CapabilityName::new("fs/write")
17}
18
19/// The capability gating directory search operations.
20pub fn find() -> CapabilityName {
21    CapabilityName::new("find")
22}
23
24/// The capability gating in-place edit operations.
25pub fn edit() -> CapabilityName {
26    CapabilityName::new("edit")
27}
28
29/// The capability gating bounded host-process execution.
30pub fn exec() -> CapabilityName {
31    CapabilityName::new("exec")
32}
33
34/// The capability gating effectful HTTP access.
35pub fn net_http() -> CapabilityName {
36    CapabilityName::new("net/http")
37}
38
39/// Compatibility filesystem-read aliases accepted by call sites.
40pub fn fs_read_aliases() -> &'static [&'static str] {
41    &["table.fs.read", "stream.file.read", "file-read"]
42}
43
44/// Compatibility filesystem-write aliases accepted by call sites.
45pub fn fs_write_aliases() -> &'static [&'static str] {
46    &[
47        "table.fs.write",
48        "table.fs.mkdir",
49        "table.fs.rmdir",
50        "stream.file.write",
51        "file-write",
52    ]
53}
54
55/// Compatibility host-process aliases accepted by call sites.
56pub fn exec_aliases() -> &'static [&'static str] {
57    &["host.process"]
58}
59
60/// Compatibility HTTP/network aliases accepted by call sites.
61pub fn net_http_aliases() -> &'static [&'static str] {
62    &["net.http", "net-connect", "network"]
63}
64
65/// Return the granted canonical capability or one of its accepted aliases.
66///
67/// This is useful for effect records, which carry a flat required-capability
68/// list and therefore cannot express "canonical or alias" directly.
69pub fn granted_capability_or_alias(
70    cx: &Cx,
71    canonical: CapabilityName,
72    aliases: &[&'static str],
73) -> Result<CapabilityName> {
74    if cx.capabilities().contains(&canonical) {
75        return Ok(canonical);
76    }
77    for alias in aliases {
78        let alias = CapabilityName::new(*alias);
79        if cx.capabilities().contains(&alias) {
80            return Ok(alias);
81        }
82    }
83    Err(Error::CapabilityDenied {
84        capability: canonical,
85    })
86}
87
88/// Require a canonical capability, accepting compatibility aliases.
89pub fn require_with_aliases(
90    cx: &Cx,
91    canonical: CapabilityName,
92    aliases: &[&'static str],
93) -> Result<()> {
94    granted_capability_or_alias(cx, canonical, aliases).map(|_| ())
95}