1
#![cfg_attr(docsrs, feature(doc_cfg))]
2
#![deny(rustdoc::broken_intra_doc_links)]
3
#![doc = include_str!("../README.md")]
4
#![deny(unsafe_code)]
5
#[cfg(all(all(feature = "tokio", feature = "async-std"), not(doc)))]
6
compile_error!("You can't enable both async-std & tokio features at once");
7
#[cfg(all(not(feature = "tokio"), not(feature = "async-std"), not(doc)))]
8
compile_error!("You have to enable either tokio or async-std feature");
9
#[cfg(all(all(feature = "native_crypto", feature = "openssl_crypto"), not(doc)))]
10
compile_error!("You can't enable both openssl_crypto & native_crypto features at once");
11
#[cfg(all(
12
    not(feature = "native_crypto"),
13
    not(feature = "openssl_crypto"),
14
    not(doc)
15
))]
16
compile_error!("You have to enable either openssl_crypto or native_crypto feature");
17

            
18
use std::collections::HashMap;
19

            
20
mod error;
21
mod key;
22
mod mac;
23
mod migration;
24

            
25
pub use key::Key;
26
pub use mac::Mac;
27

            
28
#[cfg(not(feature = "unstable"))]
29
mod crypto;
30
#[cfg(feature = "unstable")]
31
#[cfg_attr(docsrs, doc(cfg(feature = "unstable")))]
32
pub mod crypto;
33
pub mod dbus;
34
pub mod file;
35

            
36
mod keyring;
37
mod secret;
38

            
39
pub use ashpd;
40
#[cfg(feature = "schema")]
41
#[cfg_attr(docsrs, doc(cfg(feature = "schema")))]
42
pub use error::SchemaError;
43
pub use error::{Error, Result};
44
pub use keyring::{Item, Keyring};
45
pub use migration::migrate;
46
#[cfg(feature = "schema")]
47
#[cfg_attr(docsrs, doc(cfg(feature = "schema")))]
48
pub use oo7_macros::SecretSchema;
49
pub use secret::{ContentType, Secret};
50
pub use zbus;
51

            
52
/// A schema attribute.
53
///
54
/// Currently the key, is not really used but would allow
55
/// to map a Rust struct of simple types to an item attributes with type check.
56
pub const XDG_SCHEMA_ATTRIBUTE: &str = "xdg:schema";
57

            
58
/// A content type attribute.
59
///
60
/// Defines the type of the secret stored in the item.
61
pub const CONTENT_TYPE_ATTRIBUTE: &str = "xdg:content-type";
62

            
63
/// An item/collection attributes.
64
pub trait AsAttributes {
65
    fn as_attributes(&self) -> HashMap<String, String>;
66

            
67
12
    fn as_search_attributes(&self) -> HashMap<String, String> {
68
12
        let mut attributes = self.as_attributes();
69
24
        attributes.remove(CONTENT_TYPE_ATTRIBUTE);
70
12
        attributes
71
    }
72

            
73
62
    fn search_attributes(&self) -> HashMap<String, String> {
74
62
        self.as_attributes()
75
    }
76

            
77
34
    fn hash(&self, key: &Key) -> Vec<(String, std::result::Result<Mac, crate::crypto::Error>)> {
78
35
        self.search_attributes()
79
            .into_iter()
80
105
            .map(|(k, v)| (k, crypto::compute_mac(v.as_bytes(), key)))
81
            .collect()
82
    }
83
}
84

            
85
macro_rules! impl_as_attributes {
86
    ($rust_type:ty) => {
87
        impl<K, V> AsAttributes for $rust_type
88
        where
89
            K: AsRef<str>,
90
            V: AsRef<str>,
91
        {
92
40
            fn as_attributes(&self) -> std::collections::HashMap<String, String> {
93
40
                self.iter()
94
115
                    .map(|(k, v)| (k.as_ref().to_string(), v.as_ref().to_string()))
95
41
                    .collect()
96
            }
97
        }
98

            
99
        impl<K, V> AsAttributes for &$rust_type
100
        where
101
            K: AsRef<str>,
102
            V: AsRef<str>,
103
        {
104
2
            fn as_attributes(&self) -> std::collections::HashMap<String, String> {
105
2
                self.iter()
106
6
                    .map(|(k, v)| (k.as_ref().to_string(), v.as_ref().to_string()))
107
2
                    .collect()
108
            }
109
        }
110
    };
111
}
112

            
113
impl_as_attributes!([(K, V)]);
114
impl_as_attributes!(HashMap<K, V>);
115
impl_as_attributes!(std::collections::BTreeMap<K, V>);
116
impl_as_attributes!(Vec<(K, V)>);
117

            
118
impl<K, V, const N: usize> AsAttributes for [(K, V); N]
119
where
120
    K: AsRef<str>,
121
    V: AsRef<str>,
122
{
123
48
    fn as_attributes(&self) -> HashMap<String, String> {
124
49
        self.iter()
125
148
            .map(|(k, v)| (k.as_ref().to_string(), v.as_ref().to_string()))
126
            .collect()
127
    }
128
}
129

            
130
// Implementation for references to arrays
131
impl<K, V, const N: usize> AsAttributes for &[(K, V); N]
132
where
133
    K: AsRef<str>,
134
    V: AsRef<str>,
135
{
136
4
    fn as_attributes(&self) -> HashMap<String, String> {
137
4
        self.iter()
138
12
            .map(|(k, v)| (k.as_ref().to_string(), v.as_ref().to_string()))
139
            .collect()
140
    }
141
}