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