matrix_sdk_test/test_json/
keys_query.rs

1// Copyright 2024 The Matrix.org Foundation C.I.C.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Templates for simulating responses to
16//! `POST /_matrix/client/v3/keys/query`
17//! requests.
18
19use std::{collections::HashMap, iter};
20
21use ruma::{
22    api::client::keys::get_keys::v3::Response as KeyQueryResponse, device_id, user_id, DeviceId,
23    UserId,
24};
25use serde_json::json;
26
27use crate::ruma_response_from_json;
28
29pub struct KeysQueryUser {
30    pub user_id: &'static UserId,
31    pub device_id: &'static DeviceId,
32    device_key_curve25519: &'static str,
33    device_key_ed22519: &'static str,
34    device_signature: &'static str,
35    device_signature_2_name: Option<&'static str>,
36    device_signature_2_signature: Option<&'static str>,
37    master_key_name: Option<&'static str>,
38    master_key_signature: Option<&'static str>,
39    master_key_device_signature: Option<&'static str>,
40    self_signing_key_name: Option<&'static str>,
41    self_signing_key_signature: Option<&'static str>,
42}
43
44impl KeysQueryUser {
45    pub(crate) fn bob_a() -> Self {
46        Self {
47            user_id: user_id!("@bob:localhost"),
48            device_id: device_id!("GYKSNAWLVK"),
49            device_key_curve25519: "dBcZBzQaiQYWf6rBPh2QypIOB/dxSoTeyaFaxNNbeHs",
50            device_key_ed22519: "6melQNnhoI9sT2b4VzNPAwa8aB179ym45fON8Yo7kVk",
51            device_signature: "Fk45zHAbrd+1j9wZXLjL2Y/+DU/Mnz9yuvlfYBOOT7qExN2Jdud+5BAuNs8nZ/caS4wTF39Kg3zQpzaGERoCBg",
52            device_signature_2_name: Some("dO4gmBNW7WC0bXBK81j8uh4me6085fP+keoOm0pH3gw"),
53            device_signature_2_signature: Some("md0Pa1MYlneFb1fp6KCsvZpi2ySb6/G+ULoCbQDWBeDxNEcoNMzf7PEKY04UToCZKUU4LifvRWmiWFDanOlkCQ"),
54            master_key_name: Some("/mULSzYNTdHJOBWnBmsvDHhqdHQcWnXRHHmqwzwC7DY"),
55            master_key_signature: Some("6vGDbPO5XzlcwbU3aV+kcck+iHHEBtX85ow2gW5U05/DZdtda/JNVa5Nn7B9lQHNnnrMqt1sX00y/JrIkSS1Aw"),
56            master_key_device_signature: Some("jLxmUPr0Ny2Ai9+NGKGhed9BAuKikOc7r6gr7MQVawePYS95w8NJ8Tzaq9zFFOmIiojACNdQ/ksy3QAdwD6vBQ"),
57            self_signing_key_name: Some("dO4gmBNW7WC0bXBK81j8uh4me6085fP+keoOm0pH3gw"),
58            self_signing_key_signature: Some("7md6mwjUK8zjintmffJ0+kImC59/Y8PdySy99EZz5Neu+VMX3LT7txhKO2gC/hmDduRw+JGfGXIiDxR7GmQqDw"),
59        }
60    }
61
62    pub(crate) fn bob_b() -> Self {
63        Self {
64            user_id: user_id!("@bob:localhost"),
65            device_id:  device_id!("ATWKQFSFRN"),
66            device_key_curve25519:  "CY0TWVK1/Kj3ZADuBcGe3UKvpT+IKAPMUsMeJhSDqno",
67            device_key_ed22519:  "TyTQqd6j2JlWZh97r+kTYuCbvqnPoNwO6EGovYsjY00",
68            device_signature:  "BQ9Gp0p+6srF+c8OyruqKKd9R4yaub3THYAyyBB/7X/rG8BwcAqFynzl1aGyFYun4Q+087a5OSiglCXI+/kQAA",
69            device_signature_2_name: Some("At1ai1VUZrCncCI7V7fEAJmBShfpqZ30xRzqcEjTjdc"),
70            device_signature_2_signature:  Some("TWmDPaG7t0rZ6luauonELD3dmBDTIRryqXhgsIQRiGint2rJdic8RVyZ6a61bgu6mtBjfvU3prqMNp6sVi16Cg"),
71            master_key_name:  Some("NmI78hY54kE7OZsIjbRE/iCox59t4nzScCNEO6fvtY4"),
72            master_key_signature:  Some("xqLhC3sIUci1W2CNVW7HZWXreQApgjv2RDwB0WPiMd1P4vbZ/qJM0KWqK2piGPWliPi8YVREMrg216KXM3IhCA"),
73            master_key_device_signature:  Some("MBOzCKYPQLQMpBY2lFZJ4c8451xJfQCdhPBb1AHlTUSxKFiWi6V+k1oRRnhQein/PjkIY7ZO+HoOrIeOtbRMAw"),
74            self_signing_key_name: Some("At1ai1VUZrCncCI7V7fEAJmBShfpqZ30xRzqcEjTjdc"),
75            self_signing_key_signature:  Some("Ls6CeoA4LoPCHuSwG96kbhd1dEV09TgdMROIZi6vFz/MT9Wtik6joQi/tQ3zCwIZCSR53ksLO4jG1DD31AiBAA"),
76        }
77    }
78
79    pub(crate) fn bob_c() -> Self {
80        Self {
81            user_id: user_id!("@bob:localhost"),
82            device_id: device_id!("OPABMDDXGX"),
83            device_key_curve25519: "O6bwa9Op0E+PQPCrbTOfdYwU+j95RRPhXIHuNpe94ns",
84            device_key_ed22519: "DvjkSNOM9XrR1gWrr2YSDvTnwnLIgKDMRr5v8HgMKak",
85            device_signature: "o+BBnw/SIJWxSf799Adq6jEl9X3lwCg5MJkS8GlfId+pW3ReEETK0l+9bhCAgBsNSKRtB/fmZQBhjMx4FJr+BA",
86            device_signature_2_name: None,
87            device_signature_2_signature: None,
88            master_key_name: None,
89            master_key_signature: None,
90            master_key_device_signature: None,
91            self_signing_key_name: None,
92            self_signing_key_signature: None,
93        }
94    }
95}
96
97pub fn keys_query(user: &KeysQueryUser, signed_device_users: &[KeysQueryUser]) -> KeyQueryResponse {
98    let device_keys = iter::once((user.user_id, device_keys(user, signed_device_users)));
99
100    let data = json!({
101        "device_keys": to_object(device_keys),
102        "failures": {},
103        "master_keys": master_keys(user),
104        "self_signing_keys": self_signing_keys(user),
105        "user_signing_keys": {}
106    });
107    ruma_response_from_json(&data)
108}
109
110pub fn self_signing_keys(user: &KeysQueryUser) -> serde_json::Value {
111    if let (Some(self_signing_key_name), Some(self_signing_key_signature)) =
112        (user.self_signing_key_name, user.self_signing_key_signature)
113    {
114        let master_key_name = user
115            .master_key_name
116            .expect("Missing master key name when we have self_signing_key_name");
117
118        json!({
119            user.user_id: {
120                "keys": {
121                    &format!("ed25519:{}", self_signing_key_name): self_signing_key_name
122                },
123                "signatures": {
124                    "@bob:localhost": {
125                        &format!("ed25519:{}", master_key_name): self_signing_key_signature,
126                    }
127                },
128                "usage": [ "self_signing" ],
129                "user_id": "@bob:localhost"
130            }
131        })
132    } else {
133        json!({})
134    }
135}
136
137pub fn master_keys(user: &KeysQueryUser) -> serde_json::Value {
138    if let (Some(master_key_name), Some(master_key_signature), Some(master_key_device_signature)) =
139        (user.master_key_name, user.master_key_signature, user.master_key_device_signature)
140    {
141        json!({
142            user.user_id: {
143                "keys": { &format!("ed25519:{}", master_key_name): master_key_name },
144                "signatures": {
145                    user.user_id: {
146                        &format!("ed25519:{}", master_key_name): master_key_signature,
147                        &format!("ed25519:{}", user.device_id): master_key_device_signature
148                    }
149                },
150                "usage": [ "master" ],
151                "user_id": user.user_id
152            }
153        })
154    } else {
155        json!({})
156    }
157}
158
159pub fn device_keys_payload(user: &KeysQueryUser) -> serde_json::Value {
160    let mut signatures = HashMap::new();
161    signatures.insert(format!("ed25519:{}", user.device_id), user.device_signature);
162
163    if let (Some(device_signature_2_name), Some(device_signature_2_signature)) =
164        (user.device_signature_2_name, user.device_signature_2_signature)
165    {
166        signatures
167            .insert(format!("ed25519:{}", device_signature_2_name), device_signature_2_signature);
168    }
169
170    json!({
171        "algorithms": [
172            "m.olm.v1.curve25519-aes-sha2",
173            "m.megolm.v1.aes-sha2"
174        ],
175        "device_id": user.device_id,
176        "keys": {
177            &format!("curve25519:{}", user.device_id): user.device_key_curve25519,
178            &format!("ed25519:{}", user.device_id): user.device_key_ed22519,
179        },
180        "signatures": {
181            user.user_id: signatures
182        },
183        "user_id": user.user_id,
184    })
185}
186
187fn device_keys(user: &KeysQueryUser, signed_device_users: &[KeysQueryUser]) -> serde_json::Value {
188    let mut ret = HashMap::new();
189
190    ret.insert(user.device_id, device_keys_payload(user));
191
192    for other in signed_device_users {
193        ret.insert(other.device_id, device_keys_payload(other));
194    }
195
196    json!(ret)
197}
198
199fn to_object(
200    items: impl Iterator<Item = (&'static UserId, serde_json::Value)>,
201) -> serde_json::Value {
202    let mp: HashMap<&'static UserId, serde_json::Value> = items.collect();
203    serde_json::to_value(mp).unwrap()
204}