ruma_federation_api/policy/
sign_event.rs1pub mod v1 {
16 use ruma_common::{
21 OwnedServerName, ServerName, ServerSignatures as ServerSignaturesMap,
22 ServerSigningKeyVersion, SigningKeyId,
23 api::{request, response},
24 metadata,
25 };
26 use serde_json::value::RawValue as RawJsonValue;
27
28 use crate::authentication::ServerSignatures as ServerSignaturesAuth;
29
30 metadata! {
31 method: POST,
32 rate_limited: true,
33 authentication: ServerSignaturesAuth,
34 path: "/_matrix/policy/v1/sign",
35 }
36
37 #[request]
39 pub struct Request {
40 #[ruma_api(body)]
42 pub pdu: Box<RawJsonValue>,
43 }
44
45 #[response]
47 pub struct Response {
48 #[ruma_api(body)]
55 pub signatures: ServerSignaturesMap,
56 }
57
58 impl Request {
59 pub fn new(pdu: Box<RawJsonValue>) -> Self {
61 Self { pdu }
62 }
63 }
64
65 impl Response {
66 pub const POLICY_SERVER_ED25519_SIGNING_KEY_ID: &str = "ed25519:policy_server";
68
69 pub fn new(server_name: OwnedServerName, ed25519_signature: String) -> Self {
71 Self {
72 signatures: ServerSignaturesMap::from_iter(std::iter::once((
73 server_name,
74 SigningKeyId::parse(Self::POLICY_SERVER_ED25519_SIGNING_KEY_ID)
75 .expect("Policy Server default ed25519 signing key ID should be valid"),
76 ed25519_signature,
77 ))),
78 }
79 }
80
81 pub fn ed25519_signature(&self, server_name: &ServerName) -> Option<&str> {
83 self.signatures
84 .get(server_name)?
85 .get(
86 <&SigningKeyId<ServerSigningKeyVersion>>::try_from(
87 Self::POLICY_SERVER_ED25519_SIGNING_KEY_ID,
88 )
89 .expect("Policy Server default ed25519 signing key ID should be valid"),
90 )
91 .map(String::as_str)
92 }
93 }
94}
95
96#[cfg(test)]
97mod tests {
98 use super::v1::Response;
99
100 #[cfg(feature = "server")]
101 #[test]
102 fn construct_and_serialize_response() {
103 use ruma_common::{api::OutgoingResponse, owned_server_name};
104 use serde_json::{Value as JsonValue, from_slice as from_json_slice, json};
105
106 let response = Response::new(owned_server_name!("policy.example.org"), "zLFxllD0pbBuBpfHh8NuHNaICpReF/PAOpUQTsw+bFGKiGfDNAsnhcP7pbrmhhpfbOAxIdLraQLeeiXBryLmBw".to_owned());
107
108 let http_response = response.try_into_http_response::<Vec<u8>>().unwrap();
109
110 assert_eq!(
111 from_json_slice::<JsonValue>(http_response.body()).unwrap(),
112 json!({
113 "policy.example.org": {
114 "ed25519:policy_server": "zLFxllD0pbBuBpfHh8NuHNaICpReF/PAOpUQTsw+bFGKiGfDNAsnhcP7pbrmhhpfbOAxIdLraQLeeiXBryLmBw",
115 },
116 })
117 );
118 }
119
120 #[cfg(feature = "client")]
121 #[test]
122 fn deserialize_response() {
123 use ruma_common::{api::IncomingResponse, server_name};
124 use serde_json::{json, to_vec as to_json_vec};
125
126 let http_response = http::Response::new(to_json_vec(&json!({
127 "policy.example.org": {
128 "ed25519:policy_server": "zLFxllD0pbBuBpfHh8NuHNaICpReF/PAOpUQTsw+bFGKiGfDNAsnhcP7pbrmhhpfbOAxIdLraQLeeiXBryLmBw",
129 },
130 })).unwrap());
131
132 let response = Response::try_from_http_response(http_response).unwrap();
133
134 assert_eq!(
135 response.ed25519_signature(server_name!("policy.example.org")),
136 Some(
137 "zLFxllD0pbBuBpfHh8NuHNaICpReF/PAOpUQTsw+bFGKiGfDNAsnhcP7pbrmhhpfbOAxIdLraQLeeiXBryLmBw"
138 )
139 );
140 }
141}