fapolicy_rules/parser/
decision.rs

1/*
2 * Copyright Concurrent Technologies Corporation 2021
3 *
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 */
8
9use nom::branch::alt;
10use nom::bytes::complete::tag;
11
12use nom::character::complete::alpha1;
13use nom::character::complete::alphanumeric1;
14
15use nom::combinator::{map, opt, recognize};
16
17use nom::multi::many0_count;
18use nom::sequence::pair;
19
20use crate::parser::error::RuleParseError::*;
21
22use crate::Decision;
23use nom::IResult;
24
25use crate::parser::parse::{NomTraceError, StrTrace, TraceError, TraceResult};
26
27pub(crate) fn parse(i: StrTrace) -> TraceResult<Decision> {
28    let (ii, r) = recognize(pair(
29        alt((alpha1, tag("_"))),
30        many0_count(alt((alphanumeric1, tag("_")))),
31    ))(i)
32    .map_err(|_: nom::Err<TraceError>| nom::Err::Error(ExpectedDecision(i)))?;
33
34    let x: IResult<StrTrace, Option<Decision>, NomTraceError> = opt(alt((
35        map(tag("allow_audit"), |_| Decision::AllowAudit),
36        map(tag("allow_syslog"), |_| Decision::AllowSyslog),
37        map(tag("allow_log"), |_| Decision::AllowLog),
38        map(tag("allow"), |_| Decision::Allow),
39        map(tag("deny_audit"), |_| Decision::DenyAudit),
40        map(tag("deny_syslog"), |_| Decision::DenySyslog),
41        map(tag("deny_log"), |_| Decision::DenyLog),
42        map(tag("deny"), |_| Decision::Deny),
43    )))(r);
44
45    match x {
46        Ok((r, Some(_))) if !r.is_empty() => Err(nom::Err::Error(ExpectedDecision(i))),
47        Ok((_, Some(dec))) => Ok((ii, dec)),
48        Ok((r, None)) => Err(nom::Err::Error(UnknownDecision(i, r))),
49        Err(_) => Err(nom::Err::Error(ExpectedDecision(i))),
50    }
51}
52
53#[cfg(test)]
54mod tests {
55    use super::*;
56
57    #[test]
58    fn parse_dec() {
59        assert_eq!(Decision::Allow, parse("allow".into()).ok().unwrap().1);
60        assert_eq!(Decision::Deny, parse("deny".into()).ok().unwrap().1);
61        assert_eq!(
62            Decision::AllowLog,
63            parse("allow_log".into()).ok().unwrap().1
64        );
65        assert_eq!(Decision::DenyLog, parse("deny_log".into()).ok().unwrap().1);
66        assert_eq!(
67            Decision::DenyAudit,
68            parse("deny_audit".into()).ok().unwrap().1
69        );
70        assert_eq!(
71            Decision::AllowAudit,
72            parse("allow_audit".into()).ok().unwrap().1
73        );
74    }
75}