Skip to main content

oo7/dbus/
algorithm.rs

1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, zvariant::Type, PartialEq, Eq, Copy, Clone)]
4#[zvariant(signature = "s")]
5/// Algorithm used to start a new session.
6///
7/// The communication between the Secret Service and the application can either
8/// be encrypted or the items can be sent in plain text.
9pub enum Algorithm {
10    /// Plain text, per <https://specifications.freedesktop.org/secret-service-spec/latest/ch07s02.html>.
11    Plain,
12    /// Encrypted, per <https://specifications.freedesktop.org/secret-service-spec/latest/ch07s03.html>.
13    Encrypted,
14}
15
16const PLAIN_ALGORITHM: &str = "plain";
17const ENCRYPTED_ALGORITHM: &str = "dh-ietf1024-sha256-aes128-cbc-pkcs7";
18
19impl Serialize for Algorithm {
20    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
21    where
22        S: serde::Serializer,
23    {
24        match self {
25            Self::Plain => str::serialize(PLAIN_ALGORITHM, serializer),
26            Self::Encrypted => str::serialize(ENCRYPTED_ALGORITHM, serializer),
27        }
28    }
29}
30
31impl<'de> Deserialize<'de> for Algorithm {
32    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
33    where
34        D: serde::Deserializer<'de>,
35    {
36        match String::deserialize(deserializer)?.as_str() {
37            PLAIN_ALGORITHM => Ok(Self::Plain),
38            ENCRYPTED_ALGORITHM => Ok(Self::Encrypted),
39            e => Err(serde::de::Error::custom(format!("Invalid algorithm {e}"))),
40        }
41    }
42}
43
44#[cfg(test)]
45mod tests {
46    use zvariant::{Endian, serialized::Context, to_bytes};
47
48    use super::*;
49
50    #[test]
51    fn serialization() {
52        let ctxt = Context::new_dbus(Endian::Little, 0);
53
54        // Test serializing Plain
55        let encoded = to_bytes(ctxt, &Algorithm::Plain).unwrap();
56        let value: String = encoded.deserialize().unwrap().0;
57        assert_eq!(value, "plain");
58
59        // Test serializing Encrypted
60        let encoded = to_bytes(ctxt, &Algorithm::Encrypted).unwrap();
61        let value: String = encoded.deserialize().unwrap().0;
62        assert_eq!(value, "dh-ietf1024-sha256-aes128-cbc-pkcs7");
63
64        // Test deserializing plain
65        let encoded = to_bytes(ctxt, &PLAIN_ALGORITHM).unwrap();
66        let algo: Algorithm = encoded.deserialize().unwrap().0;
67        assert_eq!(algo, Algorithm::Plain);
68
69        // Test deserializing encrypted
70        let encoded = to_bytes(ctxt, &ENCRYPTED_ALGORITHM).unwrap();
71        let algo: Algorithm = encoded.deserialize().unwrap().0;
72        assert_eq!(algo, Algorithm::Encrypted);
73
74        // Test deserializing invalid algorithm
75        let encoded = to_bytes(ctxt, &"invalid-algorithm").unwrap();
76        let result: Result<(Algorithm, _), _> = encoded.deserialize();
77        assert!(result.is_err());
78        assert!(
79            result
80                .unwrap_err()
81                .to_string()
82                .contains("Invalid algorithm")
83        );
84
85        // Test roundtrip for Plain
86        let original = Algorithm::Plain;
87        let encoded = to_bytes(ctxt, &original).unwrap();
88        let decoded: Algorithm = encoded.deserialize().unwrap().0;
89        assert_eq!(original, decoded);
90
91        // Test roundtrip for Encrypted
92        let original = Algorithm::Encrypted;
93        let encoded = to_bytes(ctxt, &original).unwrap();
94        let decoded: Algorithm = encoded.deserialize().unwrap().0;
95        assert_eq!(original, decoded);
96    }
97}