1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
//! `POST /_matrix/key/*/query`
//!
//! Query for keys from multiple servers in a batch format. The receiving (notary) server must sign
//! the keys returned by the queried servers.

pub mod v2 {
    //! `/v2/` ([spec])
    //!
    //! [spec]: https://spec.matrix.org/latest/server-server-api/#post_matrixkeyv2query

    use std::collections::BTreeMap;

    use ruma_common::{
        api::{request, response, Metadata},
        metadata,
        serde::Raw,
        MilliSecondsSinceUnixEpoch, OwnedServerName, OwnedServerSigningKeyId,
    };
    use serde::{Deserialize, Serialize};

    use crate::discovery::ServerSigningKeys;

    const METADATA: Metadata = metadata! {
        method: POST,
        rate_limited: false,
        authentication: None,
        history: {
            1.0 => "/_matrix/key/v2/query",
        }
    };

    /// Request type for the `get_remote_server_keys_batch` endpoint.
    #[request]
    pub struct Request {
        /// The query criteria.
        ///
        /// The outer string key on the object is the server name (eg: matrix.org). The inner
        /// string key is the Key ID to query for the particular server. If no key IDs are given to
        /// be queried, the notary server should query for all keys. If no servers are given, the
        /// notary server must return an empty server_keys array in the response.
        ///
        /// The notary server may return multiple keys regardless of the Key IDs given.
        pub server_keys:
            BTreeMap<OwnedServerName, BTreeMap<OwnedServerSigningKeyId, QueryCriteria>>,
    }

    /// Response type for the `get_remote_server_keys_batch` endpoint.
    #[response]
    pub struct Response {
        /// The queried server's keys, signed by the notary server.
        pub server_keys: Vec<Raw<ServerSigningKeys>>,
    }

    impl Request {
        /// Creates a new `Request` with the given query criteria.
        pub fn new(
            server_keys: BTreeMap<
                OwnedServerName,
                BTreeMap<OwnedServerSigningKeyId, QueryCriteria>,
            >,
        ) -> Self {
            Self { server_keys }
        }
    }

    impl Response {
        /// Creates a new `Response` with the given keys.
        pub fn new(server_keys: Vec<Raw<ServerSigningKeys>>) -> Self {
            Self { server_keys }
        }
    }

    /// The query criteria.
    #[derive(Clone, Debug, Default, Deserialize, Serialize)]
    #[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
    pub struct QueryCriteria {
        /// A millisecond POSIX timestamp in milliseconds indicating when the
        /// returned certificates will need to be valid until to be useful to the
        /// requesting server.
        ///
        /// If not supplied, the current time as determined by the notary server is
        /// used.
        // This doesn't use `serde(default)` because the default would then be
        // determined by the client rather than the server (and it would take more
        // bandwidth because `skip_serializing_if` couldn't be used).
        #[serde(skip_serializing_if = "Option::is_none")]
        pub minimum_valid_until_ts: Option<MilliSecondsSinceUnixEpoch>,
    }

    impl QueryCriteria {
        /// Creates empty `QueryCriteria`.
        pub fn new() -> Self {
            Default::default()
        }
    }
}