pub mod v1 {
use ruma_common::{
OwnedServerName, ServerName, ServerSignatures as ServerSignaturesMap,
ServerSigningKeyVersion, SigningKeyId,
api::{request, response},
metadata,
};
use serde_json::value::RawValue as RawJsonValue;
use crate::authentication::ServerSignatures as ServerSignaturesAuth;
metadata! {
method: POST,
rate_limited: true,
authentication: ServerSignaturesAuth,
path: "/_matrix/policy/v1/sign",
}
#[request]
pub struct Request {
#[ruma_api(body)]
pub pdu: Box<RawJsonValue>,
}
#[response]
pub struct Response {
#[ruma_api(body)]
pub signatures: ServerSignaturesMap,
}
impl Request {
pub fn new(pdu: Box<RawJsonValue>) -> Self {
Self { pdu }
}
}
impl Response {
pub const POLICY_SERVER_ED25519_SIGNING_KEY_ID: &str = "ed25519:policy_server";
pub fn new(server_name: OwnedServerName, ed25519_signature: String) -> Self {
Self {
signatures: ServerSignaturesMap::from_iter(std::iter::once((
server_name,
SigningKeyId::parse(Self::POLICY_SERVER_ED25519_SIGNING_KEY_ID)
.expect("Policy Server default ed25519 signing key ID should be valid"),
ed25519_signature,
))),
}
}
pub fn ed25519_signature(&self, server_name: &ServerName) -> Option<&str> {
self.signatures
.get(server_name)?
.get(
<&SigningKeyId<ServerSigningKeyVersion>>::try_from(
Self::POLICY_SERVER_ED25519_SIGNING_KEY_ID,
)
.expect("Policy Server default ed25519 signing key ID should be valid"),
)
.map(String::as_str)
}
}
}
#[cfg(test)]
mod tests {
use super::v1::Response;
#[cfg(feature = "server")]
#[test]
fn construct_and_serialize_response() {
use ruma_common::{api::OutgoingResponse, owned_server_name};
use serde_json::{Value as JsonValue, from_slice as from_json_slice, json};
let response = Response::new(owned_server_name!("policy.example.org"), "zLFxllD0pbBuBpfHh8NuHNaICpReF/PAOpUQTsw+bFGKiGfDNAsnhcP7pbrmhhpfbOAxIdLraQLeeiXBryLmBw".to_owned());
let http_response = response.try_into_http_response::<Vec<u8>>().unwrap();
assert_eq!(
from_json_slice::<JsonValue>(http_response.body()).unwrap(),
json!({
"policy.example.org": {
"ed25519:policy_server": "zLFxllD0pbBuBpfHh8NuHNaICpReF/PAOpUQTsw+bFGKiGfDNAsnhcP7pbrmhhpfbOAxIdLraQLeeiXBryLmBw",
},
})
);
}
#[cfg(feature = "client")]
#[test]
fn deserialize_response() {
use ruma_common::{api::IncomingResponse, server_name};
use serde_json::{json, to_vec as to_json_vec};
let http_response = http::Response::new(to_json_vec(&json!({
"policy.example.org": {
"ed25519:policy_server": "zLFxllD0pbBuBpfHh8NuHNaICpReF/PAOpUQTsw+bFGKiGfDNAsnhcP7pbrmhhpfbOAxIdLraQLeeiXBryLmBw",
},
})).unwrap());
let response = Response::try_from_http_response(http_response).unwrap();
assert_eq!(
response.ed25519_signature(server_name!("policy.example.org")),
Some(
"zLFxllD0pbBuBpfHh8NuHNaICpReF/PAOpUQTsw+bFGKiGfDNAsnhcP7pbrmhhpfbOAxIdLraQLeeiXBryLmBw"
)
);
}
}