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]
|
[dev-dependencies]
|
||||||
maplit = "1.0.2"
|
maplit = "1.0.2"
|
||||||
matches = "0.1.8"
|
matches = "0.1.8"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
unstable-pre-spec = []
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
pub mod account;
|
pub mod account;
|
||||||
pub mod alias;
|
pub mod alias;
|
||||||
pub mod appservice;
|
pub mod appservice;
|
||||||
|
#[cfg(feature = "unstable-pre-spec")]
|
||||||
|
pub mod backup;
|
||||||
pub mod capabilities;
|
pub mod capabilities;
|
||||||
pub mod config;
|
pub mod config;
|
||||||
pub mod contact;
|
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 get_keys;
|
||||||
pub mod upload_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
|
/// The basic key algorithms in the specification
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
pub enum KeyAlgorithm {
|
pub enum KeyAlgorithm {
|
||||||
@ -161,3 +166,29 @@ pub enum OneTimeKey {
|
|||||||
/// A string-valued key, for the Ed25519 and Curve25519 algorithms.
|
/// A string-valued key, for the Ed25519 and Curve25519 algorithms.
|
||||||
Key(String),
|
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]
|
[features]
|
||||||
either = ["ruma-identifiers/either"]
|
either = ["ruma-identifiers/either"]
|
||||||
rand = ["ruma-identifiers/rand"]
|
rand = ["ruma-identifiers/rand"]
|
||||||
|
unstable-pre-spec = ["ruma-client-api/unstable-pre-spec"]
|
||||||
|
|
||||||
appservice-api = ["ruma-api", "ruma-appservice-api", "ruma-events"]
|
appservice-api = ["ruma-api", "ruma-appservice-api", "ruma-events"]
|
||||||
client-api = ["ruma-api", "ruma-client-api", "ruma-events"]
|
client-api = ["ruma-api", "ruma-client-api", "ruma-events"]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user