Add unstable backup and keys/upload_signing/signature endpoints
Co-authored-by: Timo Kosters <timo@koesters.xyz>
This commit is contained in:
parent
7cfec8631a
commit
24b0068213
@ -31,3 +31,6 @@ strum = { version = "0.18.0", features = ["derive"] }
|
||||
[dev-dependencies]
|
||||
maplit = "1.0.2"
|
||||
matches = "0.1.8"
|
||||
|
||||
[features]
|
||||
unstable-pre-spec = []
|
||||
|
@ -3,6 +3,8 @@
|
||||
pub mod account;
|
||||
pub mod alias;
|
||||
pub mod appservice;
|
||||
#[cfg(feature = "unstable-pre-spec")]
|
||||
pub mod backup;
|
||||
pub mod capabilities;
|
||||
pub mod config;
|
||||
pub mod contact;
|
||||
|
53
ruma-client-api/src/r0/backup.rs
Normal file
53
ruma-client-api/src/r0/backup.rs
Normal file
@ -0,0 +1,53 @@
|
||||
//! Endpoints for server-side key backups.
|
||||
|
||||
pub mod add_backup_keys;
|
||||
pub mod create_backup;
|
||||
pub mod get_backup;
|
||||
pub mod get_backup_keys;
|
||||
pub mod get_latest_backup;
|
||||
pub mod update_backup;
|
||||
|
||||
use js_int::UInt;
|
||||
use ruma_identifiers::UserId;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use crate::r0::keys::AlgorithmAndDeviceId;
|
||||
|
||||
/// The algorithm used for storing backups.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[serde(tag = "algorithm", content = "auth_data")]
|
||||
pub enum BackupAlgorithm {
|
||||
/// `m.megolm_backup.v1.curve25519-aes-sha2` backup algorithm.
|
||||
#[serde(rename = "m.megolm_backup.v1.curve25519-aes-sha2")]
|
||||
MegolmBackupV1Curve25519AesSha2 {
|
||||
/// The curve25519 public key used to encrypt the backups, encoded in unpadded base64.
|
||||
public_key: String,
|
||||
/// Signatures of the auth_data as Signed JSON.
|
||||
signatures: BTreeMap<UserId, BTreeMap<AlgorithmAndDeviceId, String>>,
|
||||
},
|
||||
}
|
||||
|
||||
/// The key data.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct KeyData {
|
||||
/// The index of the first message in the session that the key can decrypt.
|
||||
first_message_index: UInt,
|
||||
/// The number of times this key has been forwarded via key-sharing between devices.
|
||||
forwarded_count: UInt,
|
||||
/// Whether the device backing up the key verified the device that the key is from.
|
||||
is_verified: bool,
|
||||
/// Data about the session.
|
||||
session_data: SessionData,
|
||||
}
|
||||
|
||||
/// The algorithm used for storing backups.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct SessionData {
|
||||
/// Unpadded base64-encoded public half of the ephemeral key.
|
||||
ephemeral: String,
|
||||
/// Ciphertext, encrypted using AES-CBC-256 with PKCS#7 padding, encoded in base64.
|
||||
ciphertext: String,
|
||||
/// First 8 bytes of MAC key, encoded in base64.
|
||||
mac: String,
|
||||
}
|
52
ruma-client-api/src/r0/backup/add_backup_keys.rs
Normal file
52
ruma-client-api/src/r0/backup/add_backup_keys.rs
Normal file
@ -0,0 +1,52 @@
|
||||
//! [PUT /_matrix/client/r0/room_keys/keys](https://matrix.org/docs/spec/client_server/unstable#put-matrix-client-r0-room-keys-keys)
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use js_int::UInt;
|
||||
use ruma_api::ruma_api;
|
||||
use ruma_identifiers::RoomId;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::KeyData;
|
||||
|
||||
ruma_api! {
|
||||
metadata: {
|
||||
description: "Store several keys in the backup.",
|
||||
method: PUT,
|
||||
name: "add_backup_keys",
|
||||
path: "/_matrix/client/r0/room_keys/keys",
|
||||
rate_limited: true,
|
||||
requires_authentication: true,
|
||||
}
|
||||
|
||||
request: {
|
||||
/// The backup version. Must be the current backup.
|
||||
#[ruma_api(query)]
|
||||
pub version: String,
|
||||
|
||||
/// A map from room IDs to session IDs to key data.
|
||||
///
|
||||
/// Note: synapse has the `sessions: {}` wrapper, the Matrix spec does not.
|
||||
pub rooms: BTreeMap<RoomId, Sessions>,
|
||||
}
|
||||
|
||||
response: {
|
||||
/// An opaque string representing stored keys in the backup. Clients can compare it with
|
||||
/// the etag value they received in the request of their last key storage request.
|
||||
pub etag: String,
|
||||
|
||||
/// The number of keys stored in the backup.
|
||||
pub count: UInt,
|
||||
}
|
||||
|
||||
error: crate::Error
|
||||
}
|
||||
|
||||
// TODO: remove
|
||||
/// A wrapper around a mapping of session IDs to key data.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct Sessions {
|
||||
// TODO: remove
|
||||
/// A map of session IDs to key data.
|
||||
pub sessions: BTreeMap<String, KeyData>,
|
||||
}
|
27
ruma-client-api/src/r0/backup/create_backup.rs
Normal file
27
ruma-client-api/src/r0/backup/create_backup.rs
Normal file
@ -0,0 +1,27 @@
|
||||
//! [POST /_matrix/client/r0/room_keys/version](https://matrix.org/docs/spec/client_server/unstable#post-matrix-client-r0-room-keys-version)
|
||||
|
||||
use ruma_api::ruma_api;
|
||||
|
||||
ruma_api! {
|
||||
metadata: {
|
||||
description: "Creates a new backup.",
|
||||
method: POST,
|
||||
name: "create_backup",
|
||||
path: "/_matrix/client/r0/room_keys/version",
|
||||
rate_limited: true,
|
||||
requires_authentication: true,
|
||||
}
|
||||
|
||||
request: {
|
||||
/// The algorithm used for storing backups.
|
||||
#[serde(flatten)]
|
||||
pub algorithm: super::BackupAlgorithm,
|
||||
}
|
||||
|
||||
response: {
|
||||
/// The backup version. This is an opaque string.
|
||||
pub version: String,
|
||||
}
|
||||
|
||||
error: crate::Error
|
||||
}
|
39
ruma-client-api/src/r0/backup/get_backup.rs
Normal file
39
ruma-client-api/src/r0/backup/get_backup.rs
Normal file
@ -0,0 +1,39 @@
|
||||
//! [GET /_matrix/client/r0/room_keys/version](https://matrix.org/docs/spec/client_server/unstable#post-matrix-client-r0-room-keys-version)
|
||||
|
||||
use js_int::UInt;
|
||||
use ruma_api::ruma_api;
|
||||
|
||||
ruma_api! {
|
||||
metadata: {
|
||||
description: "Get information about an existing backup.",
|
||||
method: GET,
|
||||
name: "get_backup",
|
||||
path: "/_matrix/client/r0/room_keys/version/:version",
|
||||
rate_limited: true,
|
||||
requires_authentication: true,
|
||||
}
|
||||
|
||||
request: {
|
||||
/// The backup version.
|
||||
#[ruma_api(path)]
|
||||
pub version: String,
|
||||
}
|
||||
|
||||
response: {
|
||||
/// The algorithm used for storing backups.
|
||||
#[serde(flatten)]
|
||||
pub algorithm: super::BackupAlgorithm,
|
||||
|
||||
/// The number of keys stored in the backup.
|
||||
pub count: UInt,
|
||||
|
||||
/// An opaque string representing stored keys in the backup. Clients can compare it with
|
||||
/// the etag value they received in the request of their last key storage request.
|
||||
pub etag: String,
|
||||
|
||||
/// The backup version. This is an opaque string.
|
||||
pub version: String,
|
||||
}
|
||||
|
||||
error: crate::Error
|
||||
}
|
44
ruma-client-api/src/r0/backup/get_backup_keys.rs
Normal file
44
ruma-client-api/src/r0/backup/get_backup_keys.rs
Normal file
@ -0,0 +1,44 @@
|
||||
//! [GET /_matrix/client/r0/room_keys/keys](https://matrix.org/docs/spec/client_server/unstable#get-matrix-client-r0-room-keys-keys)
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use ruma_api::ruma_api;
|
||||
use ruma_identifiers::RoomId;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::KeyData;
|
||||
|
||||
ruma_api! {
|
||||
metadata: {
|
||||
description: "Retrieve all keys from a backup.",
|
||||
method: GET,
|
||||
name: "get_backup_keys",
|
||||
path: "/_matrix/client/r0/room_keys/keys",
|
||||
rate_limited: true,
|
||||
requires_authentication: true,
|
||||
}
|
||||
|
||||
request: {
|
||||
/// The backup version. Must be the current backup.
|
||||
#[ruma_api(query)]
|
||||
pub version: String,
|
||||
}
|
||||
|
||||
response: {
|
||||
/// A map from room IDs to session IDs to key data.
|
||||
///
|
||||
/// Note: synapse has the `sessions: {}` wrapper, the Matrix spec does not.
|
||||
pub rooms: BTreeMap<RoomId, Sessions>,
|
||||
}
|
||||
|
||||
error: crate::Error
|
||||
}
|
||||
|
||||
// TODO: remove
|
||||
/// A wrapper around a mapping of session IDs to key data.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct Sessions {
|
||||
// TODO: remove
|
||||
/// A map of session IDs to key data.
|
||||
pub sessions: BTreeMap<String, KeyData>,
|
||||
}
|
35
ruma-client-api/src/r0/backup/get_latest_backup.rs
Normal file
35
ruma-client-api/src/r0/backup/get_latest_backup.rs
Normal file
@ -0,0 +1,35 @@
|
||||
//! [GET /_matrix/client/r0/room_keys/version](https://matrix.org/docs/spec/client_server/unstable#post-matrix-client-r0-room-keys-version)
|
||||
|
||||
use js_int::UInt;
|
||||
use ruma_api::ruma_api;
|
||||
|
||||
ruma_api! {
|
||||
metadata: {
|
||||
description: "Get information about the latest backup.",
|
||||
method: GET,
|
||||
name: "get_latest_backup",
|
||||
path: "/_matrix/client/r0/room_keys/version",
|
||||
rate_limited: true,
|
||||
requires_authentication: true,
|
||||
}
|
||||
|
||||
request: {}
|
||||
|
||||
response: {
|
||||
/// The algorithm used for storing backups.
|
||||
#[serde(flatten)]
|
||||
pub algorithm: super::BackupAlgorithm,
|
||||
|
||||
/// The number of keys stored in the backup.
|
||||
pub count: UInt,
|
||||
|
||||
/// An opaque string represetning stored keys in the backup. Clients can compare it with
|
||||
/// the etag value they received in the request of their last key storage request.
|
||||
pub etag: String,
|
||||
|
||||
/// The backup version. This is an opaque string.
|
||||
pub version: String,
|
||||
}
|
||||
|
||||
error: crate::Error
|
||||
}
|
28
ruma-client-api/src/r0/backup/update_backup.rs
Normal file
28
ruma-client-api/src/r0/backup/update_backup.rs
Normal file
@ -0,0 +1,28 @@
|
||||
//! [POST /_matrix/client/r0/room_keys/version](https://matrix.org/docs/spec/client_server/unstable#post-matrix-client-r0-room-keys-version)
|
||||
|
||||
use ruma_api::ruma_api;
|
||||
|
||||
ruma_api! {
|
||||
metadata: {
|
||||
description: "Update information about an existing backup.",
|
||||
method: POST,
|
||||
name: "update_backup",
|
||||
path: "/_matrix/client/r0/room_keys/version/:version",
|
||||
rate_limited: true,
|
||||
requires_authentication: true,
|
||||
}
|
||||
|
||||
request: {
|
||||
/// The backup version.
|
||||
#[ruma_api(path)]
|
||||
pub version: String,
|
||||
|
||||
/// The algorithm used for storing backups.
|
||||
#[serde(flatten)]
|
||||
pub algorithm: super::BackupAlgorithm,
|
||||
}
|
||||
|
||||
response: {}
|
||||
|
||||
error: crate::Error
|
||||
}
|
@ -18,6 +18,11 @@ pub mod get_key_changes;
|
||||
pub mod get_keys;
|
||||
pub mod upload_keys;
|
||||
|
||||
#[cfg(feature = "unstable-pre-spec")]
|
||||
pub mod upload_signatures;
|
||||
#[cfg(feature = "unstable-pre-spec")]
|
||||
pub mod upload_signing_keys;
|
||||
|
||||
/// The basic key algorithms in the specification
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||
pub enum KeyAlgorithm {
|
||||
@ -161,3 +166,29 @@ pub enum OneTimeKey {
|
||||
/// A string-valued key, for the Ed25519 and Curve25519 algorithms.
|
||||
Key(String),
|
||||
}
|
||||
|
||||
/// A cross signing key.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct CrossSigningKey {
|
||||
/// The ID of the user the key belongs to.
|
||||
pub user_id: UserId,
|
||||
/// What the key is used for.
|
||||
pub usage: Vec<KeyUsage>,
|
||||
/// The public key. The object must have exactly one property.
|
||||
pub keys: BTreeMap<String, String>,
|
||||
/// Signatures of the key. Only optional for master key.
|
||||
#[serde(skip_serializing_if = "BTreeMap::is_empty")]
|
||||
pub signatures: BTreeMap<UserId, BTreeMap<String, String>>,
|
||||
}
|
||||
|
||||
/// The usage of a cross signing key.
|
||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum KeyUsage {
|
||||
/// Master key.
|
||||
Master,
|
||||
/// Self-signing key.
|
||||
SelfSigning,
|
||||
/// User-signing key.
|
||||
UserSigning,
|
||||
}
|
||||
|
27
ruma-client-api/src/r0/keys/upload_signatures.rs
Normal file
27
ruma-client-api/src/r0/keys/upload_signatures.rs
Normal file
@ -0,0 +1,27 @@
|
||||
//! [POST /_matrix/client/r0/keys/signatures/upload](https://13301-24998719-gh.circle-artifacts.com/0/scripts/gen/client_server/unstable.html#post-matrix-client-r0-keys-signatures-upload)
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use ruma_api::ruma_api;
|
||||
use ruma_identifiers::UserId;
|
||||
|
||||
ruma_api! {
|
||||
metadata: {
|
||||
description: "Publishes cross-signing signatures for the user.",
|
||||
method: POST,
|
||||
name: "upload_signatures",
|
||||
path: "/_matrix/client/r0/keys/signatures/upload",
|
||||
rate_limited: false,
|
||||
requires_authentication: true,
|
||||
}
|
||||
|
||||
request: {
|
||||
/// Signed keys.
|
||||
#[ruma_api(body)]
|
||||
pub signed_keys: BTreeMap<UserId, BTreeMap<String, serde_json::Value>>,
|
||||
}
|
||||
|
||||
response: {}
|
||||
|
||||
error: crate::Error
|
||||
}
|
41
ruma-client-api/src/r0/keys/upload_signing_keys.rs
Normal file
41
ruma-client-api/src/r0/keys/upload_signing_keys.rs
Normal file
@ -0,0 +1,41 @@
|
||||
//! [POST /_matrix/client/r0/keys/device_signing/upload](https://13301-24998719-gh.circle-artifacts.com/0/scripts/gen/client_server/unstable.html#post-matrix-client-r0-keys-device-signing-upload)
|
||||
|
||||
use ruma_api::ruma_api;
|
||||
|
||||
use super::CrossSigningKey;
|
||||
use crate::r0::uiaa::AuthData;
|
||||
|
||||
ruma_api! {
|
||||
metadata: {
|
||||
description: "Publishes cross signing keys for the user.",
|
||||
method: POST,
|
||||
name: "upload_signing_keys",
|
||||
path: "/_matrix/client/r0/keys/device_signing/upload",
|
||||
rate_limited: false,
|
||||
requires_authentication: true,
|
||||
}
|
||||
|
||||
request: {
|
||||
/// Additional authentication information for the user-interactive authentication API.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub auth: Option<AuthData>,
|
||||
|
||||
/// The user's master key.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub master_key: Option<CrossSigningKey>,
|
||||
|
||||
/// The user's self-signing key. Must be signed with the accompanied master, or by the
|
||||
/// user's most recently uploaded master key if no master key is included in the request.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub self_signing_key: Option<CrossSigningKey>,
|
||||
|
||||
/// The user's user-signing key. Must be signed with the accompanied master, or by the
|
||||
/// user's most recently uploaded master key if no master key is included in the request.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub user_signing_key: Option<CrossSigningKey>,
|
||||
}
|
||||
|
||||
response: {}
|
||||
|
||||
error: crate::Error
|
||||
}
|
@ -15,6 +15,7 @@ edition = "2018"
|
||||
[features]
|
||||
either = ["ruma-identifiers/either"]
|
||||
rand = ["ruma-identifiers/rand"]
|
||||
unstable-pre-spec = ["ruma-client-api/unstable-pre-spec"]
|
||||
|
||||
appservice-api = ["ruma-api", "ruma-appservice-api", "ruma-events"]
|
||||
client-api = ["ruma-api", "ruma-client-api", "ruma-events"]
|
||||
|
Loading…
x
Reference in New Issue
Block a user