cc_toolgate/commands/
simple.rs1use crate::commands::CommandSpec;
4use crate::eval::{CommandContext, Decision, RuleMatch};
5
6pub struct SimpleCommandSpec {
12 decision: Decision,
14}
15
16impl SimpleCommandSpec {
17 pub fn new(decision: Decision) -> Self {
19 Self { decision }
20 }
21}
22
23impl CommandSpec for SimpleCommandSpec {
24 fn evaluate(&self, ctx: &CommandContext) -> RuleMatch {
25 match self.decision {
26 Decision::Allow => {
27 if ctx.words.len() <= 3 && ctx.has_flag("--version") {
29 return RuleMatch {
30 decision: Decision::Allow,
31 reason: format!("{} --version", ctx.base_command),
32 };
33 }
34 if let Some(ref r) = ctx.redirection {
36 return RuleMatch {
37 decision: Decision::Ask,
38 reason: format!("{} with {}", ctx.base_command, r.description),
39 };
40 }
41 RuleMatch {
42 decision: Decision::Allow,
43 reason: format!("allowed: {}", ctx.base_command),
44 }
45 }
46 Decision::Ask => RuleMatch {
47 decision: Decision::Ask,
48 reason: format!("{} requires confirmation", ctx.base_command),
49 },
50 Decision::Deny => RuleMatch {
51 decision: Decision::Deny,
52 reason: format!("blocked command: {}", ctx.base_command),
53 },
54 }
55 }
56}
57
58#[cfg(test)]
59mod tests {
60 use super::*;
61
62 #[test]
63 fn allow_simple() {
64 let spec = SimpleCommandSpec::new(Decision::Allow);
65 let ctx = CommandContext::from_command("ls -la");
66 assert_eq!(spec.evaluate(&ctx).decision, Decision::Allow);
67 }
68
69 #[test]
70 fn allow_with_redir() {
71 let spec = SimpleCommandSpec::new(Decision::Allow);
72 let ctx = CommandContext::from_command("ls > file.txt");
73 assert_eq!(spec.evaluate(&ctx).decision, Decision::Ask);
74 }
75
76 #[test]
77 fn ask_simple() {
78 let spec = SimpleCommandSpec::new(Decision::Ask);
79 let ctx = CommandContext::from_command("rm -rf /tmp");
80 assert_eq!(spec.evaluate(&ctx).decision, Decision::Ask);
81 }
82
83 #[test]
84 fn deny_simple() {
85 let spec = SimpleCommandSpec::new(Decision::Deny);
86 let ctx = CommandContext::from_command("shred /dev/sda");
87 assert_eq!(spec.evaluate(&ctx).decision, Decision::Deny);
88 }
89}