use std::path::PathBuf;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum SandboxPermissions {
#[default]
UseDefault,
RequireEscalated,
WithAdditionalPermissions,
BypassSandbox,
}
impl SandboxPermissions {
pub fn requires_approval(&self) -> bool {
matches!(
self,
Self::RequireEscalated | Self::WithAdditionalPermissions | Self::BypassSandbox
)
}
pub fn requires_escalated_permissions(&self) -> bool {
matches!(self, Self::RequireEscalated | Self::BypassSandbox)
}
pub fn requires_additional_permissions(&self) -> bool {
!matches!(self, Self::UseDefault)
}
pub fn uses_additional_permissions(&self) -> bool {
matches!(self, Self::WithAdditionalPermissions)
}
pub fn bypasses_sandbox(&self) -> bool {
matches!(self, Self::BypassSandbox)
}
pub fn merge(&self, other: &Self) -> Self {
use SandboxPermissions::*;
match (self, other) {
(BypassSandbox, _) | (_, BypassSandbox) => BypassSandbox,
(RequireEscalated, _) | (_, RequireEscalated) => RequireEscalated,
(WithAdditionalPermissions, _) | (_, WithAdditionalPermissions) => {
WithAdditionalPermissions
}
(UseDefault, UseDefault) => UseDefault,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
pub struct AdditionalPermissions {
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub fs_read: Vec<PathBuf>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub fs_write: Vec<PathBuf>,
}
impl AdditionalPermissions {
pub fn is_empty(&self) -> bool {
self.fs_read.is_empty() && self.fs_write.is_empty()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_permissions() {
let perm = SandboxPermissions::default();
assert!(!perm.requires_approval());
assert!(!perm.bypasses_sandbox());
}
#[test]
fn test_escalated_permissions() {
let perm = SandboxPermissions::RequireEscalated;
assert!(perm.requires_approval());
assert!(!perm.bypasses_sandbox());
assert!(perm.requires_escalated_permissions());
}
#[test]
fn test_bypass_permissions() {
let perm = SandboxPermissions::BypassSandbox;
assert!(perm.requires_approval());
assert!(perm.bypasses_sandbox());
assert!(perm.requires_escalated_permissions());
}
#[test]
fn test_with_additional_permissions() {
let perm = SandboxPermissions::WithAdditionalPermissions;
assert!(perm.requires_approval());
assert!(perm.requires_additional_permissions());
assert!(perm.uses_additional_permissions());
assert!(!perm.requires_escalated_permissions());
assert!(!perm.bypasses_sandbox());
}
#[test]
fn test_merge_permissions() {
use SandboxPermissions::*;
assert_eq!(UseDefault.merge(&UseDefault), UseDefault);
assert_eq!(
UseDefault.merge(&WithAdditionalPermissions),
WithAdditionalPermissions
);
assert_eq!(UseDefault.merge(&RequireEscalated), RequireEscalated);
assert_eq!(RequireEscalated.merge(&BypassSandbox), BypassSandbox);
}
}