openvpn_mgmt_codec/
auth.rs1use std::str::FromStr;
2
3#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
5#[error("unrecognized auth type: {0:?}")]
6pub struct ParseAuthTypeError(pub String);
7
8#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
10#[error("unrecognized auth retry mode: {0:?}")]
11pub struct ParseAuthRetryModeError(pub String);
12
13#[derive(Debug, Clone, PartialEq, Eq, strum::Display)]
17pub enum AuthType {
18 Auth,
20
21 #[strum(to_string = "Private Key")]
23 PrivateKey,
24
25 #[strum(to_string = "HTTP Proxy")]
27 HttpProxy,
28
29 #[strum(to_string = "SOCKS Proxy")]
31 SocksProxy,
32
33 #[strum(default)]
35 Unknown(String),
36}
37
38impl FromStr for AuthType {
39 type Err = ParseAuthTypeError;
40
41 fn from_str(s: &str) -> Result<Self, Self::Err> {
48 match s {
49 "Auth" => Ok(Self::Auth),
50 "PrivateKey" | "Private Key" => Ok(Self::PrivateKey),
51 "HTTPProxy" | "HTTP Proxy" => Ok(Self::HttpProxy),
52 "SOCKSProxy" | "SOCKS Proxy" => Ok(Self::SocksProxy),
53 other => Err(ParseAuthTypeError(other.to_string())),
54 }
55 }
56}
57
58#[derive(Debug, Clone, Copy, PartialEq, Eq, strum::Display)]
60#[strum(serialize_all = "lowercase")]
61pub enum AuthRetryMode {
62 None,
64
65 Interact,
67
68 #[strum(to_string = "nointeract")]
70 NoInteract,
71}
72
73impl FromStr for AuthRetryMode {
74 type Err = ParseAuthRetryModeError;
75
76 fn from_str(s: &str) -> Result<Self, Self::Err> {
78 match s {
79 "none" => Ok(Self::None),
80 "interact" => Ok(Self::Interact),
81 "nointeract" => Ok(Self::NoInteract),
82 other => Err(ParseAuthRetryModeError(other.to_string())),
83 }
84 }
85}
86
87#[cfg(test)]
88mod tests {
89 use super::*;
90
91 #[test]
92 fn auth_type_roundtrip() {
93 for at in [
94 AuthType::Auth,
95 AuthType::PrivateKey,
96 AuthType::HttpProxy,
97 AuthType::SocksProxy,
98 ] {
99 let s = at.to_string();
100 assert_eq!(s.parse::<AuthType>().unwrap(), at);
101 }
102 }
103
104 #[test]
105 fn auth_type_aliases() {
106 assert_eq!(
107 "PrivateKey".parse::<AuthType>().unwrap(),
108 AuthType::PrivateKey
109 );
110 assert_eq!(
111 "Private Key".parse::<AuthType>().unwrap(),
112 AuthType::PrivateKey
113 );
114 assert_eq!(
115 "HTTPProxy".parse::<AuthType>().unwrap(),
116 AuthType::HttpProxy
117 );
118 assert_eq!(
119 "SOCKSProxy".parse::<AuthType>().unwrap(),
120 AuthType::SocksProxy
121 );
122 }
123
124 #[test]
125 fn auth_type_unknown_is_err() {
126 assert!("MyPlugin".parse::<AuthType>().is_err());
127 }
128
129 #[test]
130 fn auth_type_unknown_falls_back() {
131 let s = "MyPlugin";
132 let at: AuthType = s
133 .parse()
134 .unwrap_or_else(|_| AuthType::Unknown(s.to_string()));
135 assert_eq!(at, AuthType::Unknown("MyPlugin".to_string()));
136 }
137
138 #[test]
139 fn auth_retry_roundtrip() {
140 for mode in [
141 AuthRetryMode::None,
142 AuthRetryMode::Interact,
143 AuthRetryMode::NoInteract,
144 ] {
145 let s = mode.to_string();
146 assert_eq!(s.parse::<AuthRetryMode>().unwrap(), mode);
147 }
148 }
149
150 #[test]
151 fn auth_retry_invalid() {
152 assert!("bogus".parse::<AuthRetryMode>().is_err());
153 }
154}