ruma_common/identifiers/
signatures.rs

1use std::{
2    collections::BTreeMap,
3    ops::{Deref, DerefMut},
4};
5
6use serde::{Deserialize, Serialize};
7
8use super::{
9    Base64PublicKeyOrDeviceId, DeviceId, KeyName, OwnedServerName, OwnedSigningKeyId, OwnedUserId,
10    ServerSigningKeyVersion,
11};
12
13/// Map of key identifier to signature values.
14pub type EntitySignatures<K> = BTreeMap<OwnedSigningKeyId<K>, String>;
15
16/// Map of all signatures, grouped by entity.
17///
18/// ```
19/// # use ruma_common::{server_name, server_signing_key_version, ServerSigningKeyId, Signatures, SigningKeyAlgorithm};
20/// let key_identifier = ServerSigningKeyId::from_parts(
21///     SigningKeyAlgorithm::Ed25519,
22///     server_signing_key_version!("1")
23/// );
24/// let mut signatures = Signatures::new();
25/// let server_name = server_name!("example.org");
26/// let signature =
27///     "YbJva03ihSj5mPk+CHMJKUKlCXCPFXjXOK6VqBnN9nA2evksQcTGn6hwQfrgRHIDDXO2le49x7jnWJHMJrJoBQ";
28/// signatures.insert_signature(server_name, key_identifier, signature.into());
29/// ```
30#[derive(Debug, Serialize, Deserialize)]
31#[serde(
32    transparent,
33    bound(serialize = "E: Serialize", deserialize = "E: serde::de::DeserializeOwned")
34)]
35pub struct Signatures<E: Ord, K: KeyName + ?Sized>(BTreeMap<E, EntitySignatures<K>>);
36
37impl<E: Ord, K: KeyName + ?Sized> Signatures<E, K> {
38    /// Creates an empty signature map.
39    pub fn new() -> Self {
40        Self::default()
41    }
42
43    /// Add a signature for the given entity and key identifier.
44    ///
45    /// If there was already one, it is returned.
46    pub fn insert_signature(
47        &mut self,
48        entity: E,
49        key_identifier: OwnedSigningKeyId<K>,
50        value: String,
51    ) -> Option<String> {
52        self.0.entry(entity).or_default().insert(key_identifier, value)
53    }
54}
55
56/// Map of server signatures, grouped by server.
57pub type ServerSignatures = Signatures<OwnedServerName, ServerSigningKeyVersion>;
58
59/// Map of device signatures, grouped by user.
60pub type DeviceSignatures = Signatures<OwnedUserId, DeviceId>;
61
62/// Map of cross-signing or device signatures, grouped by user.
63pub type CrossSigningOrDeviceSignatures = Signatures<OwnedUserId, Base64PublicKeyOrDeviceId>;
64
65impl<E, K> Clone for Signatures<E, K>
66where
67    E: Ord + Clone,
68    K: KeyName + ?Sized,
69{
70    fn clone(&self) -> Self {
71        Self(self.0.clone())
72    }
73}
74
75impl<E: Ord, K: KeyName + ?Sized> Default for Signatures<E, K> {
76    fn default() -> Self {
77        Self(Default::default())
78    }
79}
80
81impl<E: Ord, K: KeyName + ?Sized> Deref for Signatures<E, K> {
82    type Target = BTreeMap<E, EntitySignatures<K>>;
83
84    fn deref(&self) -> &Self::Target {
85        &self.0
86    }
87}
88
89impl<E: Ord, K: KeyName + ?Sized> DerefMut for Signatures<E, K> {
90    fn deref_mut(&mut self) -> &mut Self::Target {
91        &mut self.0
92    }
93}
94
95impl<E: Ord, K: KeyName + ?Sized, const N: usize> From<[(E, OwnedSigningKeyId<K>, String); N]>
96    for Signatures<E, K>
97{
98    fn from(value: [(E, OwnedSigningKeyId<K>, String); N]) -> Self {
99        value.into_iter().collect()
100    }
101}
102
103impl<E: Ord, K: KeyName + ?Sized> FromIterator<(E, OwnedSigningKeyId<K>, String)>
104    for Signatures<E, K>
105{
106    fn from_iter<T: IntoIterator<Item = (E, OwnedSigningKeyId<K>, String)>>(iter: T) -> Self {
107        iter.into_iter().fold(Self::new(), |mut acc, (entity, key_identifier, value)| {
108            acc.insert_signature(entity, key_identifier, value);
109            acc
110        })
111    }
112}
113
114impl<E: Ord, K: KeyName + ?Sized> Extend<(E, OwnedSigningKeyId<K>, String)> for Signatures<E, K> {
115    fn extend<T: IntoIterator<Item = (E, OwnedSigningKeyId<K>, String)>>(&mut self, iter: T) {
116        for (entity, key_identifier, value) in iter {
117            self.insert_signature(entity, key_identifier, value);
118        }
119    }
120}
121
122impl<E: Ord + Clone, K: KeyName + ?Sized> IntoIterator for Signatures<E, K> {
123    type Item = (E, OwnedSigningKeyId<K>, String);
124    type IntoIter = IntoIter<E, K>;
125
126    fn into_iter(self) -> Self::IntoIter {
127        IntoIter { outer: self.0.into_iter(), inner: None, entity: None }
128    }
129}
130
131pub struct IntoIter<E: Clone, K: KeyName + ?Sized> {
132    outer: std::collections::btree_map::IntoIter<E, BTreeMap<OwnedSigningKeyId<K>, String>>,
133    inner: Option<std::collections::btree_map::IntoIter<OwnedSigningKeyId<K>, String>>,
134    entity: Option<E>,
135}
136
137impl<E: Clone, K: KeyName + ?Sized> Iterator for IntoIter<E, K> {
138    type Item = (E, OwnedSigningKeyId<K>, String);
139
140    fn next(&mut self) -> Option<Self::Item> {
141        loop {
142            if let Some(inner) = &mut self.inner {
143                if let Some((k, v)) = inner.next() {
144                    if let Some(entity) = self.entity.clone() {
145                        return Some((entity, k, v));
146                    }
147                }
148            }
149
150            if let Some((e, map)) = self.outer.next() {
151                self.inner = Some(map.into_iter());
152                self.entity = Some(e);
153            } else {
154                return None;
155            }
156        }
157    }
158}
159
160#[cfg(test)]
161mod tests {
162    #[test]
163    fn signatures_into_iter() {
164        use ruma_common::{
165            owned_server_name, server_signing_key_version, ServerSigningKeyId, Signatures,
166            SigningKeyAlgorithm,
167        };
168        let key_identifier = ServerSigningKeyId::from_parts(
169            SigningKeyAlgorithm::Ed25519,
170            server_signing_key_version!("1"),
171        );
172        let mut signatures = Signatures::new();
173        let server_name = owned_server_name!("example.org");
174        let signature =
175     "YbJva03ihSj5mPk+CHMJKUKlCXCPFXjXOK6VqBnN9nA2evksQcTGn6hwQfrgRHIDDXO2le49x7jnWJHMJrJoBQ";
176        signatures.insert_signature(server_name, key_identifier, signature.into());
177
178        let mut more_signatures = Signatures::new();
179        more_signatures.extend(signatures.clone());
180
181        assert_eq!(more_signatures.0, signatures.0);
182
183        let mut iter = more_signatures.into_iter();
184        assert!(iter.next().is_some());
185        assert!(iter.next().is_none());
186    }
187}