libsftpman/
auth_type.rs

1use serde::de::Error as DeError;
2use serde::{Deserialize, Deserializer, Serialize, Serializer};
3
4#[cfg(feature = "cli")]
5use clap::builder::{PossibleValue, Str};
6
7#[cfg(feature = "cli")]
8use clap::ValueEnum;
9
10#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq)]
11pub enum AuthType {
12    #[default]
13    PublicKey,
14
15    /// AuthenticationAgent is a placeholder authentication type.
16    /// It's not recognized by the `ssh` command (as a valid `PreferredAuthentications` choice),
17    /// but instructs us to avoid specifying a preferred authentication and SSH key (`ssh -i ..`),
18    /// thus delegating to an SSH agent, if available.
19    AuthenticationAgent,
20
21    Password,
22
23    KeyboardInteractive,
24
25    HostBased,
26
27    GSSAPIWithMic,
28}
29
30impl AuthType {
31    pub const ALL: [AuthType; 6] = [
32        Self::PublicKey,
33        Self::AuthenticationAgent,
34        Self::Password,
35        Self::KeyboardInteractive,
36        Self::HostBased,
37        Self::GSSAPIWithMic,
38    ];
39
40    pub fn to_static_str(&self) -> &'static str {
41        match &self {
42            Self::PublicKey => "publickey",
43            Self::AuthenticationAgent => "authentication-agent",
44            Self::Password => "password",
45            Self::KeyboardInteractive => "keyboard-interactive",
46            Self::HostBased => "hostbased",
47            Self::GSSAPIWithMic => "gssapi-with-mic",
48        }
49    }
50
51    pub fn from_string(s: &str) -> Result<Self, &'static str> {
52        match s {
53            "publickey" => Ok(Self::PublicKey),
54            "authentication-agent" => Ok(Self::AuthenticationAgent),
55            "password" => Ok(Self::Password),
56            "keyboard-interactive" => Ok(Self::KeyboardInteractive),
57            "hostbased" => Ok(Self::HostBased),
58            "gssapi-with-mic" => Ok(Self::GSSAPIWithMic),
59            _ => Err("Unexpected string value"),
60        }
61    }
62}
63
64impl std::fmt::Display for AuthType {
65    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
66        write!(f, "{0}", self.to_static_str())
67    }
68}
69
70#[cfg(feature = "cli")]
71impl ValueEnum for AuthType {
72    fn value_variants<'a>() -> &'a [Self] {
73        &AuthType::ALL
74    }
75
76    #[cfg(feature = "cli")]
77    fn to_possible_value(&self) -> Option<PossibleValue> {
78        Some(PossibleValue::new(Str::from(self.to_static_str())))
79    }
80}
81
82// Custom serialization for AuthType
83pub fn serialize_auth_type_to_string<S>(value: &AuthType, serializer: S) -> Result<S::Ok, S::Error>
84where
85    S: Serializer,
86{
87    serializer.serialize_str(value.to_static_str())
88}
89
90// Custom deserialization for AuthType
91pub fn deserialize_auth_type_from_string<'de, D>(deserializer: D) -> Result<AuthType, D::Error>
92where
93    D: Deserializer<'de>,
94{
95    let s = String::deserialize(deserializer)?;
96    AuthType::from_string(&s).map_err(DeError::custom)
97}