haproxy_config/config/
userlist.rs1use std::collections::HashMap;
2
3use super::{error::Error, Name};
4use crate::section::{PasswordRef, borrowed::Section};
5use crate::line::borrowed::Line;
6
7#[derive(Debug, Clone, Hash, PartialEq, Eq)]
8pub struct Group {
9 pub name: String,
10 pub users: Vec<String>,
11}
12
13#[derive(Debug, Clone, Hash, PartialEq, Eq)]
15pub enum Password {
16 Secure(String),
17 Insecure(String),
18}
19
20impl From<&PasswordRef<'_>> for Password {
21 fn from(value: &PasswordRef) -> Self {
22 match value {
23 PasswordRef::Secure(p) => Self::Secure((*p).to_string()),
24 PasswordRef::Insecure(p) => Self::Insecure((*p).to_string()),
25 }
26 }
27}
28
29#[derive(Debug, Clone, Hash, PartialEq, Eq)]
30pub struct User {
31 pub name: String,
32 pub password: Password,
33}
34
35#[derive(Debug, Clone, Hash, PartialEq, Eq)]
36pub struct Userlist {
37 pub name: String,
38 pub groups: Vec<Group>,
39 pub users: Vec<User>,
40}
41
42type Pair = (Name, Userlist);
43impl<'a> TryFrom<&'a Section<'a>> for Pair {
44 type Error = Error;
45
46 fn try_from(entry: &'a Section<'a>) -> Result<Pair, Self::Error> {
47 let Section::Userlist{name, lines, ..} = entry else {
48 unreachable!()
49 };
50
51 let mut users = Vec::new();
52 let mut groups = Vec::new();
53 let mut other = Vec::new();
54
55 for line in lines
56 .iter()
57 .filter(|l| !matches!(l, Line::Blank | Line::Comment(_)))
58 {
59 match line {
60 Line::User { name, password, .. } => users.push(User {
61 name: (*name).to_string(),
62 password: Password::from(password),
63 }),
64 Line::Group { name, users, .. } => groups.push(Group {
65 name: (*name).to_string(),
66 users: users.iter().map(ToString::to_string).collect(),
67 }),
68 wrong => other.push(wrong),
69 }
70 }
71
72 if !other.is_empty() {
73 return Err(Error::wrong_userlist_lines(other));
74 }
75
76 Ok((
77 (*name).to_string(),
78 Userlist {
79 name: (*name).to_string(),
80 users,
81 groups,
82 },
83 ))
84 }
85}
86
87impl<'a> Userlist {
88 pub(crate) fn parse_multiple(entries: &'a [Section<'a>]) -> Result<HashMap<Name, Self>, Error> {
89 entries
90 .iter()
91 .filter(|e| matches!(e, Section::Userlist { .. }))
92 .map(Pair::try_from)
93 .collect()
94 }
95}