Skip to main content

haloforge_plugin_api/
permissions.rs

1/// Fine-grained permissions a plugin must declare in its manifest.
2/// The host checks these at install time (user approval) and at runtime (sandbox enforcement).
3#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
4#[serde(tag = "type", content = "value", rename_all = "snake_case")]
5pub enum Permission {
6    /// Read any host table.
7    DatabaseReadAll,
8    /// Read a specific host table (e.g. "launch_profiles").
9    DatabaseRead(String),
10    /// Write to a specific host table. Restricted tier.
11    DatabaseWrite(String),
12    /// Create tables in the plugin's own namespace.
13    DatabaseCreateTables,
14
15    /// Read any filesystem path (prompts user on first use).
16    FilesystemRead,
17    /// Read within the HaloForge app-data directory only.
18    FilesystemReadAppData,
19    /// Write any filesystem path (prompts user on first use).
20    FilesystemWrite,
21    /// Write within the HaloForge app-data directory only.
22    FilesystemWriteAppData,
23
24    /// Make outbound HTTP requests to any URL.
25    NetworkHttp,
26    /// Make outbound HTTP requests to a specific domain only.
27    NetworkHttpDomain(String),
28
29    /// Register new Tauri IPC commands.
30    IpcRegister,
31
32    /// Emit events on the app event bus.
33    EventsEmit,
34    /// Listen to app lifecycle events.
35    EventsListen,
36
37    /// Inject into UI slots (implied by capability_levels 1/2).
38    UiInject,
39
40    /// Spawn any child process (high risk — Restricted tier).
41    ProcessSpawn,
42    /// Spawn only executables from a declared whitelist.
43    ProcessSpawnWhitelist(Vec<String>),
44
45    /// Show desktop toast notifications.
46    Notifications,
47
48    /// Read the clipboard.
49    ClipboardRead,
50    /// Write to the clipboard.
51    ClipboardWrite,
52
53    /// Read app config (theme, language).
54    AppConfigRead,
55}
56
57impl Permission {
58    /// Approval tier for this permission.
59    pub fn tier(&self) -> PermissionTier {
60        match self {
61            Self::UiInject
62            | Self::EventsListen
63            | Self::DatabaseCreateTables
64            | Self::AppConfigRead
65            | Self::Notifications => PermissionTier::Transparent,
66
67            Self::DatabaseReadAll
68            | Self::DatabaseRead(_)
69            | Self::IpcRegister
70            | Self::EventsEmit
71            | Self::NetworkHttpDomain(_) => PermissionTier::Standard,
72
73            Self::FilesystemRead
74            | Self::FilesystemWrite
75            | Self::FilesystemReadAppData
76            | Self::FilesystemWriteAppData
77            | Self::NetworkHttp
78            | Self::ProcessSpawnWhitelist(_)
79            | Self::ClipboardRead
80            | Self::ClipboardWrite => PermissionTier::Sensitive,
81
82            Self::DatabaseWrite(_)
83            | Self::ProcessSpawn => PermissionTier::Restricted,
84        }
85    }
86
87    /// Human-readable description shown in the permission prompt.
88    pub fn description(&self) -> String {
89        match self {
90            Self::DatabaseReadAll           => "Read all app data".into(),
91            Self::DatabaseRead(t)           => format!("Read table: {t}"),
92            Self::DatabaseWrite(t)          => format!("Write to table: {t}"),
93            Self::DatabaseCreateTables      => "Create plugin-owned database tables".into(),
94            Self::FilesystemRead            => "Read files from your filesystem".into(),
95            Self::FilesystemReadAppData     => "Read files in the app data directory".into(),
96            Self::FilesystemWrite           => "Write files to your filesystem".into(),
97            Self::FilesystemWriteAppData    => "Write files in the app data directory".into(),
98            Self::NetworkHttp               => "Make outbound HTTP requests".into(),
99            Self::NetworkHttpDomain(d)      => format!("Make HTTP requests to: {d}"),
100            Self::IpcRegister               => "Register new app commands".into(),
101            Self::EventsEmit                => "Emit app events".into(),
102            Self::EventsListen              => "Listen to app lifecycle events".into(),
103            Self::UiInject                  => "Inject UI components".into(),
104            Self::ProcessSpawn              => "Spawn arbitrary child processes".into(),
105            Self::ProcessSpawnWhitelist(v)  => format!("Spawn processes: {}", v.join(", ")),
106            Self::Notifications             => "Show desktop notifications".into(),
107            Self::ClipboardRead             => "Read the clipboard".into(),
108            Self::ClipboardWrite            => "Write to the clipboard".into(),
109            Self::AppConfigRead             => "Read app configuration".into(),
110        }
111    }
112}
113
114#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
115pub enum PermissionTier {
116    /// Auto-granted at install time with no user prompt.
117    Transparent = 0,
118    /// Shown once at install time; user approves/denies.
119    Standard = 1,
120    /// Shown at install + confirmation on first actual use.
121    Sensitive = 2,
122    /// Disabled by default; user must manually enable in Plugin Manager.
123    Restricted = 3,
124}