├── .gitignore ├── src ├── r0 │ ├── context.rs │ ├── receipt.rs │ ├── redact.rs │ ├── search.rs │ ├── server.rs │ ├── voip.rs │ ├── read_marker.rs │ ├── typing.rs │ ├── user_directory.rs │ ├── sync.rs │ ├── presence.rs │ ├── capabilities.rs │ ├── tag.rs │ ├── alias.rs │ ├── appservice.rs │ ├── message.rs │ ├── contact.rs │ ├── session.rs │ ├── profile.rs │ ├── config.rs │ ├── media.rs │ ├── state.rs │ ├── session │ │ ├── logout.rs │ │ ├── logout_all.rs │ │ ├── sso_login.rs │ │ ├── get_login_types.rs │ │ ├── login │ │ │ └── user_serde.rs │ │ └── login.rs │ ├── room.rs │ ├── device │ │ ├── get_devices.rs │ │ ├── get_device.rs │ │ ├── delete_devices.rs │ │ ├── update_device.rs │ │ └── delete_device.rs │ ├── account │ │ ├── whoami.rs │ │ ├── change_password.rs │ │ ├── get_username_availability.rs │ │ ├── bind_3pid.rs │ │ ├── unbind_3pid.rs │ │ ├── delete_3pid.rs │ │ ├── deactivate.rs │ │ ├── request_openid_token.rs │ │ ├── request_password_change_token_via_msisdn.rs │ │ ├── request_registration_token_via_email.rs │ │ ├── request_3pid_management_token_via_email.rs │ │ ├── request_password_change_token_via_email.rs │ │ ├── request_registration_token_via_msisdn.rs │ │ ├── request_3pid_management_token_via_msisdn.rs │ │ └── register.rs │ ├── membership │ │ ├── leave_room.rs │ │ ├── forget_room.rs │ │ ├── joined_rooms.rs │ │ ├── unban_user.rs │ │ ├── ban_user.rs │ │ ├── kick_user.rs │ │ ├── join_room_by_id.rs │ │ ├── join_room_by_id_or_alias.rs │ │ ├── joined_members.rs │ │ ├── get_member_events.rs │ │ └── invite_user.rs │ ├── media │ │ ├── get_media_config.rs │ │ ├── create_content.rs │ │ ├── get_media_preview.rs │ │ ├── get_content.rs │ │ ├── get_content_as_filename.rs │ │ └── get_content_thumbnail.rs │ ├── push │ │ ├── get_pushers.rs │ │ ├── get_pushrules_all.rs │ │ ├── get_pushrules_global_scope.rs │ │ ├── set_pusher.rs │ │ ├── delete_pushrule.rs │ │ ├── get_pushrule.rs │ │ ├── get_pushrule_enabled.rs │ │ ├── get_pushrule_actions.rs │ │ ├── set_pushrule_enabled.rs │ │ ├── set_pushrule_actions.rs │ │ ├── set_pushrule.rs │ │ └── get_notifications.rs │ ├── device.rs │ ├── alias │ │ ├── delete_alias.rs │ │ ├── create_alias.rs │ │ └── get_alias.rs │ ├── profile │ │ ├── set_avatar_url.rs │ │ ├── get_avatar_url.rs │ │ ├── set_display_name.rs │ │ ├── get_display_name.rs │ │ └── get_profile.rs │ ├── thirdparty │ │ ├── get_protocols.rs │ │ ├── get_user_for_user_id.rs │ │ ├── get_protocol.rs │ │ ├── get_location_for_room_alias.rs │ │ ├── get_user_for_protocol.rs │ │ └── get_location_for_protocol.rs │ ├── room │ │ ├── upgrade_room.rs │ │ ├── report_content.rs │ │ ├── get_room_event.rs │ │ └── create_room.rs │ ├── tag │ │ ├── delete_tag.rs │ │ ├── get_tags.rs │ │ └── create_tag.rs │ ├── voip │ │ └── get_turn_server_info.rs │ ├── filter │ │ ├── get_filter.rs │ │ └── create_filter.rs │ ├── presence │ │ ├── set_presence.rs │ │ └── get_presence.rs │ ├── state │ │ ├── get_state_events_for_empty_key.rs │ │ ├── get_state_events.rs │ │ ├── create_state_event_for_empty_key.rs │ │ ├── get_state_events_for_key.rs │ │ └── create_state_event_for_key.rs │ ├── config │ │ ├── get_global_account_data.rs │ │ ├── set_global_account_data.rs │ │ ├── get_room_account_data.rs │ │ └── set_room_account_data.rs │ ├── contact │ │ ├── get_contacts.rs │ │ └── request_contact_verification_token.rs │ ├── appservice │ │ └── set_room_visibility.rs │ ├── typing │ │ └── create_typing_event.rs │ ├── keys │ │ ├── upload_keys.rs │ │ ├── get_key_changes.rs │ │ ├── claim_keys.rs │ │ └── get_keys.rs │ ├── read_marker │ │ └── set_read_marker.rs │ ├── client_exchange │ │ └── send_event_to_device.rs │ ├── redact │ │ └── redact_event.rs │ ├── receipt │ │ └── create_receipt.rs │ ├── directory.rs │ ├── message │ │ ├── create_message_event.rs │ │ └── get_message_events.rs │ ├── membership.rs │ ├── user_directory │ │ └── search_users.rs │ ├── directory │ │ ├── get_public_rooms.rs │ │ └── get_public_rooms_filtered.rs │ ├── server │ │ └── get_user_info.rs │ ├── account.rs │ ├── client_exchange.rs │ ├── context │ │ └── get_context.rs │ ├── capabilities │ │ └── get_capabilities.rs │ ├── thirdparty.rs │ └── keys.rs ├── serde │ ├── duration.rs │ └── duration │ │ ├── secs.rs │ │ └── opt_ms.rs ├── unversioned.rs ├── serde.rs ├── lib.rs ├── r0.rs ├── unversioned │ ├── get_supported_versions.rs │ └── discover_homeserver.rs └── error.rs ├── README.md ├── .travis.yml ├── Cargo.toml ├── LICENSE ├── CHANGELOG.md └── CONTRIBUTING.md /.gitignore: -------------------------------------------------------------------------------- 1 | Cargo.lock 2 | target 3 | -------------------------------------------------------------------------------- /src/r0/context.rs: -------------------------------------------------------------------------------- 1 | //! Endpoints for event context. 2 | 3 | pub mod get_context; 4 | -------------------------------------------------------------------------------- /src/r0/receipt.rs: -------------------------------------------------------------------------------- 1 | //! Endpoints for event receipts. 2 | 3 | pub mod create_receipt; 4 | -------------------------------------------------------------------------------- /src/r0/redact.rs: -------------------------------------------------------------------------------- 1 | //! Endpoints for event redaction. 2 | 3 | pub mod redact_event; 4 | -------------------------------------------------------------------------------- /src/r0/search.rs: -------------------------------------------------------------------------------- 1 | //! Endpoints for event searches. 2 | 3 | pub mod search_events; 4 | -------------------------------------------------------------------------------- /src/r0/server.rs: -------------------------------------------------------------------------------- 1 | //! Endpoints for server administration. 2 | 3 | pub mod get_user_info; 4 | -------------------------------------------------------------------------------- /src/r0/voip.rs: -------------------------------------------------------------------------------- 1 | //! Endpoints for Voice over IP. 2 | 3 | pub mod get_turn_server_info; 4 | -------------------------------------------------------------------------------- /src/r0/read_marker.rs: -------------------------------------------------------------------------------- 1 | //! Endpoints for "fully read markers" 2 | 3 | pub mod set_read_marker; 4 | -------------------------------------------------------------------------------- /src/r0/typing.rs: -------------------------------------------------------------------------------- 1 | //! Endpoints for typing notifications. 2 | 3 | pub mod create_typing_event; 4 | -------------------------------------------------------------------------------- /src/r0/user_directory.rs: -------------------------------------------------------------------------------- 1 | //! Endpoints for the user directory. 2 | 3 | pub mod search_users; 4 | -------------------------------------------------------------------------------- /src/r0/sync.rs: -------------------------------------------------------------------------------- 1 | //! Endpoints for getting and synchronizing events. 2 | 3 | pub mod sync_events; 4 | -------------------------------------------------------------------------------- /src/r0/presence.rs: -------------------------------------------------------------------------------- 1 | //! Endpoints for user presence. 2 | 3 | pub mod get_presence; 4 | pub mod set_presence; 5 | -------------------------------------------------------------------------------- /src/r0/capabilities.rs: -------------------------------------------------------------------------------- 1 | //! Endpoints for querying the server's supported feature set 2 | 3 | pub mod get_capabilities; 4 | -------------------------------------------------------------------------------- /src/r0/tag.rs: -------------------------------------------------------------------------------- 1 | //! Endpoints for tagging rooms. 2 | 3 | pub mod create_tag; 4 | pub mod delete_tag; 5 | pub mod get_tags; 6 | -------------------------------------------------------------------------------- /src/r0/alias.rs: -------------------------------------------------------------------------------- 1 | //! Endpoints for room aliases. 2 | 3 | pub mod create_alias; 4 | pub mod delete_alias; 5 | pub mod get_alias; 6 | -------------------------------------------------------------------------------- /src/serde/duration.rs: -------------------------------------------------------------------------------- 1 | //! De-/serialization functions for `std::time::Duration` objects 2 | 3 | pub mod opt_ms; 4 | pub mod secs; 5 | -------------------------------------------------------------------------------- /src/r0/appservice.rs: -------------------------------------------------------------------------------- 1 | //! Endpoints part of the application service extension of the client-server API 2 | 3 | pub mod set_room_visibility; 4 | -------------------------------------------------------------------------------- /src/r0/message.rs: -------------------------------------------------------------------------------- 1 | //! Enpoints for sending and receiving messages 2 | 3 | pub mod create_message_event; 4 | pub mod get_message_events; 5 | -------------------------------------------------------------------------------- /src/r0/contact.rs: -------------------------------------------------------------------------------- 1 | //! Endpoints for account contact information. 2 | 3 | pub mod get_contacts; 4 | pub mod request_contact_verification_token; 5 | -------------------------------------------------------------------------------- /src/unversioned.rs: -------------------------------------------------------------------------------- 1 | //! Endpoints that cannot change with new versions of the Matrix specification. 2 | 3 | pub mod discover_homeserver; 4 | pub mod get_supported_versions; 5 | -------------------------------------------------------------------------------- /src/r0/session.rs: -------------------------------------------------------------------------------- 1 | //! Endpoints for user session management. 2 | 3 | pub mod get_login_types; 4 | pub mod login; 5 | pub mod logout; 6 | pub mod logout_all; 7 | pub mod sso_login; 8 | -------------------------------------------------------------------------------- /src/r0/profile.rs: -------------------------------------------------------------------------------- 1 | //! Endpoints for user profiles. 2 | 3 | pub mod get_avatar_url; 4 | pub mod get_display_name; 5 | pub mod get_profile; 6 | pub mod set_avatar_url; 7 | pub mod set_display_name; 8 | -------------------------------------------------------------------------------- /src/r0/config.rs: -------------------------------------------------------------------------------- 1 | //! Endpoints for client configuration. 2 | 3 | pub mod get_global_account_data; 4 | pub mod get_room_account_data; 5 | pub mod set_global_account_data; 6 | pub mod set_room_account_data; 7 | -------------------------------------------------------------------------------- /src/serde.rs: -------------------------------------------------------------------------------- 1 | //! Modules to hold functions for de-/serializing remote types 2 | 3 | pub mod duration; 4 | 5 | pub fn is_default(val: &T) -> bool { 6 | val == &T::default() 7 | } 8 | -------------------------------------------------------------------------------- /src/r0/media.rs: -------------------------------------------------------------------------------- 1 | //! Endpoints for the media repository. 2 | 3 | pub mod create_content; 4 | pub mod get_content; 5 | pub mod get_content_as_filename; 6 | pub mod get_content_thumbnail; 7 | pub mod get_media_config; 8 | -------------------------------------------------------------------------------- /src/r0/state.rs: -------------------------------------------------------------------------------- 1 | //! Endpoints for managing room state 2 | 3 | pub mod create_state_event_for_empty_key; 4 | pub mod create_state_event_for_key; 5 | pub mod get_state_events; 6 | pub mod get_state_events_for_empty_key; 7 | pub mod get_state_events_for_key; 8 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Crate ruma_client_api contains serializable types for the requests and responses for each 2 | //! endpoint in the [Matrix](https://matrix.org/) client API specification. These types can be 3 | //! shared by client and server code. 4 | 5 | #![deny( 6 | missing_copy_implementations, 7 | missing_debug_implementations, 8 | missing_docs 9 | )] 10 | 11 | pub mod error; 12 | pub mod r0; 13 | pub mod unversioned; 14 | 15 | mod serde; 16 | 17 | pub use error::Error; 18 | -------------------------------------------------------------------------------- /src/r0/session/logout.rs: -------------------------------------------------------------------------------- 1 | //! [POST /_matrix/client/r0/logout](https://matrix.org/docs/spec/client_server/r0.4.0.html#post-matrix-client-r0-logout) 2 | 3 | use ruma_api::ruma_api; 4 | 5 | ruma_api! { 6 | metadata { 7 | description: "Log out of the homeserver.", 8 | method: POST, 9 | name: "logout", 10 | path: "/_matrix/client/r0/logout", 11 | rate_limited: false, 12 | requires_authentication: true, 13 | } 14 | 15 | request {} 16 | 17 | response {} 18 | 19 | error: crate::Error 20 | } 21 | -------------------------------------------------------------------------------- /src/r0/room.rs: -------------------------------------------------------------------------------- 1 | //! Endpoints for room management. 2 | 3 | pub mod create_room; 4 | pub mod get_room_event; 5 | pub mod report_content; 6 | pub mod upgrade_room; 7 | 8 | use serde::{Deserialize, Serialize}; 9 | 10 | /// Whether or not a newly created room will be listed in the room directory. 11 | #[derive(Clone, Copy, Debug, Deserialize, Serialize)] 12 | #[serde(rename_all = "snake_case")] 13 | pub enum Visibility { 14 | /// Indicates that the room will be shown in the published room list. 15 | Public, 16 | /// Indicates that the room will not be shown in the published room list. 17 | Private, 18 | } 19 | -------------------------------------------------------------------------------- /src/r0/session/logout_all.rs: -------------------------------------------------------------------------------- 1 | //! [POST /_matrix/client/r0/logout/all](https://matrix.org/docs/spec/client_server/r0.4.0.html#post-matrix-client-r0-logout-all) 2 | 3 | use ruma_api::ruma_api; 4 | 5 | ruma_api! { 6 | metadata { 7 | description: "Invalidates all access tokens for a user, so that they can no longer be used for authorization.", 8 | method: POST, 9 | name: "logout_all", 10 | path: "/_matrix/client/r0/logout/all", 11 | rate_limited: false, 12 | requires_authentication: true, 13 | } 14 | 15 | request {} 16 | 17 | response {} 18 | 19 | error: crate::Error 20 | } 21 | -------------------------------------------------------------------------------- /src/r0/device/get_devices.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/client/r0/devices](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-devices) 2 | 3 | use super::Device; 4 | use ruma_api::ruma_api; 5 | 6 | ruma_api! { 7 | metadata { 8 | description: "Get registered devices for authenticated user.", 9 | method: GET, 10 | name: "get_devices", 11 | path: "/_matrix/client/r0/devices", 12 | rate_limited: false, 13 | requires_authentication: true, 14 | } 15 | 16 | request {} 17 | 18 | response { 19 | devices: Vec, 20 | } 21 | 22 | error: crate::Error 23 | } 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ruma-client-api 2 | 3 | [![Build Status](https://travis-ci.org/ruma/ruma-client-api.svg?branch=master)](https://travis-ci.org/ruma/ruma-client-api) 4 | 5 | **ruma-client-api** contains serializable types for the requests and responses for each endpoint in the [Matrix](https://matrix.org/) client API specification. 6 | These types can be shared by client and server code. 7 | 8 | ## Minimum Rust version 9 | 10 | ruma-client-api requires Rust 1.39.0 or later. 11 | 12 | ## Status 13 | 14 | This project is currently experimental and is very likely to change drastically. 15 | 16 | ## License 17 | 18 | [MIT](http://opensource.org/licenses/MIT) 19 | -------------------------------------------------------------------------------- /src/r0/account/whoami.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/client/r0/account/whoami](https://matrix.org/docs/spec/client_server/r0.4.0.html#get-matrix-client-r0-account-whoami) 2 | 3 | use ruma_api::ruma_api; 4 | 5 | ruma_api! { 6 | metadata { 7 | description: "Get information about the owner of a given access token.", 8 | method: GET, 9 | name: "whoami", 10 | path: "/_matrix/client/r0/account/whoami", 11 | rate_limited: true, 12 | requires_authentication: true, 13 | } 14 | 15 | request {} 16 | 17 | response { 18 | /// The id of the user that owns the access token. 19 | pub user_id: String, 20 | } 21 | 22 | error: crate::Error 23 | } 24 | -------------------------------------------------------------------------------- /src/r0/membership/leave_room.rs: -------------------------------------------------------------------------------- 1 | //! [POST /_matrix/client/r0/rooms/{roomId}/leave](https://matrix.org/docs/spec/client_server/r0.4.0.html#post-matrix-client-r0-rooms-roomid-leave) 2 | 3 | use ruma_api::ruma_api; 4 | use ruma_identifiers::RoomId; 5 | 6 | ruma_api! { 7 | metadata { 8 | description: "Leave a room.", 9 | method: POST, 10 | name: "leave_room", 11 | path: "/_matrix/client/r0/rooms/:room_id/leave", 12 | rate_limited: true, 13 | requires_authentication: true, 14 | } 15 | 16 | request { 17 | /// The room to leave. 18 | #[ruma_api(path)] 19 | pub room_id: RoomId, 20 | } 21 | 22 | response {} 23 | 24 | error: crate::Error 25 | } 26 | -------------------------------------------------------------------------------- /src/r0/media/get_media_config.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/media/r0/config](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-media-r0-config) 2 | 3 | use js_int::UInt; 4 | use ruma_api::ruma_api; 5 | 6 | ruma_api! { 7 | metadata { 8 | description: "Gets the config for the media repository.", 9 | method: GET, 10 | path: "/_matrix/media/r0/config", 11 | name: "get_media_config", 12 | rate_limited: true, 13 | requires_authentication: true, 14 | } 15 | 16 | request {} 17 | 18 | response { 19 | /// Maximum size of upload in bytes. 20 | #[serde(rename = "m.upload.size")] 21 | pub upload_size: UInt, 22 | } 23 | 24 | error: crate::Error 25 | } 26 | -------------------------------------------------------------------------------- /src/r0/push/get_pushers.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/client/r0/pushers](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-pushers) 2 | 3 | use ruma_api::ruma_api; 4 | 5 | use super::Pusher; 6 | 7 | ruma_api! { 8 | metadata { 9 | description: "Gets all currently active pushers for the authenticated user.", 10 | method: GET, 11 | name: "get_pushers", 12 | path: "/_matrix/client/r0/pushers", 13 | rate_limited: false, 14 | requires_authentication: true, 15 | } 16 | 17 | request {} 18 | 19 | response { 20 | /// An array containing the current pushers for the user. 21 | pub pushers: Vec 22 | } 23 | 24 | error: crate::Error 25 | } 26 | -------------------------------------------------------------------------------- /src/r0/membership/forget_room.rs: -------------------------------------------------------------------------------- 1 | //! [POST /_matrix/client/r0/rooms/{roomId}/forget](https://matrix.org/docs/spec/client_server/r0.4.0.html#post-matrix-client-r0-rooms-roomid-forget) 2 | 3 | use ruma_api::ruma_api; 4 | use ruma_identifiers::RoomId; 5 | 6 | ruma_api! { 7 | metadata { 8 | description: "Forget a room.", 9 | method: POST, 10 | name: "forget_room", 11 | path: "/_matrix/client/r0/rooms/:room_id/forget", 12 | rate_limited: true, 13 | requires_authentication: true, 14 | } 15 | 16 | request { 17 | /// The room to forget. 18 | #[ruma_api(path)] 19 | pub room_id: RoomId, 20 | } 21 | 22 | response {} 23 | 24 | error: crate::Error 25 | } 26 | -------------------------------------------------------------------------------- /src/r0.rs: -------------------------------------------------------------------------------- 1 | //! Endpoints for the r0.x.x versions of the client API specification. 2 | 3 | pub mod account; 4 | pub mod alias; 5 | pub mod appservice; 6 | pub mod capabilities; 7 | pub mod client_exchange; 8 | pub mod config; 9 | pub mod contact; 10 | pub mod context; 11 | pub mod device; 12 | pub mod directory; 13 | pub mod filter; 14 | pub mod keys; 15 | pub mod media; 16 | pub mod membership; 17 | pub mod message; 18 | pub mod presence; 19 | pub mod profile; 20 | pub mod push; 21 | pub mod read_marker; 22 | pub mod receipt; 23 | pub mod redact; 24 | pub mod room; 25 | pub mod search; 26 | pub mod server; 27 | pub mod session; 28 | pub mod state; 29 | pub mod sync; 30 | pub mod tag; 31 | pub mod thirdparty; 32 | pub mod typing; 33 | pub mod user_directory; 34 | pub mod voip; 35 | -------------------------------------------------------------------------------- /src/r0/push/get_pushrules_all.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/client/r0/pushrules/](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-pushrules) 2 | 3 | use std::collections::HashMap; 4 | 5 | use ruma_api::ruma_api; 6 | 7 | use super::{PushRule, RuleKind}; 8 | 9 | ruma_api! { 10 | metadata { 11 | description: "Retrieve all push rulesets for this user.", 12 | method: GET, 13 | name: "get_pushrules_all", 14 | path: "/_matrix/client/r0/pushrules/", 15 | rate_limited: false, 16 | requires_authentication: true, 17 | } 18 | 19 | request {} 20 | 21 | response { 22 | /// The global ruleset 23 | pub global: HashMap> 24 | } 25 | 26 | error: crate::Error 27 | } 28 | -------------------------------------------------------------------------------- /src/r0/device.rs: -------------------------------------------------------------------------------- 1 | //! Endpoints for managing devices. 2 | 3 | use js_int::UInt; 4 | use ruma_identifiers::DeviceId; 5 | use serde::{Deserialize, Serialize}; 6 | 7 | pub mod delete_device; 8 | pub mod delete_devices; 9 | pub mod get_device; 10 | pub mod get_devices; 11 | pub mod update_device; 12 | 13 | /// Information about a registered device. 14 | #[derive(Clone, Debug, Deserialize, Hash, PartialEq, Serialize)] 15 | pub struct Device { 16 | /// Device ID 17 | pub device_id: DeviceId, 18 | /// Public display name of the device. 19 | pub display_name: Option, 20 | /// Most recently seen IP address of the session. 21 | pub ip: Option, 22 | /// Unix timestamp that the session was last active. 23 | pub last_seen: Option, 24 | } 25 | -------------------------------------------------------------------------------- /src/r0/alias/delete_alias.rs: -------------------------------------------------------------------------------- 1 | //! [DELETE /_matrix/client/r0/directory/room/{roomAlias}](https://matrix.org/docs/spec/client_server/r0.4.0.html#delete-matrix-client-r0-directory-room-roomalias) 2 | 3 | use ruma_api::ruma_api; 4 | use ruma_identifiers::RoomAliasId; 5 | 6 | ruma_api! { 7 | metadata { 8 | description: "Remove an alias from a room.", 9 | method: DELETE, 10 | name: "delete_alias", 11 | path: "/_matrix/client/r0/directory/room/:room_alias", 12 | rate_limited: false, 13 | requires_authentication: true, 14 | } 15 | 16 | request { 17 | /// The room alias to remove. 18 | #[ruma_api(path)] 19 | pub room_alias: RoomAliasId, 20 | } 21 | 22 | response {} 23 | 24 | error: crate::Error 25 | } 26 | -------------------------------------------------------------------------------- /src/r0/membership/joined_rooms.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/client/r0/joined_rooms](https://matrix.org/docs/spec/client_server/r0.4.0.html#get-matrix-client-r0-joined-rooms) 2 | 3 | use ruma_api::ruma_api; 4 | use ruma_identifiers::RoomId; 5 | 6 | ruma_api! { 7 | metadata { 8 | description: "Get a list of the user's current rooms.", 9 | method: GET, 10 | name: "joined_rooms", 11 | path: "/_matrix/client/r0/joined_rooms", 12 | rate_limited: false, 13 | requires_authentication: true, 14 | } 15 | 16 | request {} 17 | 18 | response { 19 | /// A list of the rooms the user is in, i.e. 20 | /// the ID of each room in which the user has joined membership. 21 | pub joined_rooms: Vec, 22 | } 23 | 24 | error: crate::Error 25 | } 26 | -------------------------------------------------------------------------------- /src/r0/membership/unban_user.rs: -------------------------------------------------------------------------------- 1 | //! [POST /_matrix/client/r0/rooms/{roomId}/unban](https://matrix.org/docs/spec/client_server/r0.4.0.html#post-matrix-client-r0-rooms-roomid-unban) 2 | 3 | use ruma_api::ruma_api; 4 | use ruma_identifiers::{RoomId, UserId}; 5 | 6 | ruma_api! { 7 | metadata { 8 | description: "Unban a user from a room.", 9 | method: POST, 10 | name: "unban_user", 11 | path: "/_matrix/client/r0/rooms/:room_id/unban", 12 | rate_limited: false, 13 | requires_authentication: true, 14 | } 15 | 16 | request { 17 | /// The room to unban the user from. 18 | #[ruma_api(path)] 19 | pub room_id: RoomId, 20 | /// The user to unban. 21 | pub user_id: UserId, 22 | } 23 | 24 | response {} 25 | 26 | error: crate::Error 27 | } 28 | -------------------------------------------------------------------------------- /src/r0/alias/create_alias.rs: -------------------------------------------------------------------------------- 1 | //! [PUT /_matrix/client/r0/directory/room/{roomAlias}](https://matrix.org/docs/spec/client_server/r0.6.0#put-matrix-client-r0-directory-room-roomalias) 2 | 3 | use ruma_api::ruma_api; 4 | use ruma_identifiers::{RoomAliasId, RoomId}; 5 | 6 | ruma_api! { 7 | metadata { 8 | description: "Add an alias to a room.", 9 | method: PUT, 10 | name: "create_alias", 11 | path: "/_matrix/client/r0/directory/room/:room_alias", 12 | rate_limited: false, 13 | requires_authentication: true, 14 | } 15 | 16 | request { 17 | /// The room alias to set. 18 | #[ruma_api(path)] 19 | pub room_alias: RoomAliasId, 20 | /// The room ID to set. 21 | pub room_id: RoomId, 22 | } 23 | 24 | response {} 25 | 26 | error: crate::Error 27 | } 28 | -------------------------------------------------------------------------------- /src/r0/push/get_pushrules_global_scope.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/client/r0/pushrules/global/](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-pushrules) 2 | 3 | use std::collections::HashMap; 4 | 5 | use ruma_api::ruma_api; 6 | 7 | use super::{PushRule, RuleKind}; 8 | 9 | ruma_api! { 10 | metadata { 11 | description: "Retrieve all push rulesets in the global scope for this user.", 12 | method: GET, 13 | name: "get_pushrules_global_scope", 14 | path: "/_matrix/client/r0/pushrules/global/", 15 | rate_limited: false, 16 | requires_authentication: true, 17 | } 18 | 19 | request {} 20 | 21 | response { 22 | /// The global ruleset. 23 | #[ruma_api(body)] 24 | pub global: HashMap>, 25 | } 26 | 27 | error: crate::Error 28 | } 29 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: "rust" 2 | cache: "cargo" 3 | rust: 4 | - 1.40.0 5 | - stable 6 | - beta 7 | - nightly 8 | jobs: 9 | allow_failures: 10 | - rust: nightly 11 | fast_finish: true 12 | 13 | before_script: 14 | - rustup component add rustfmt 15 | - rustup component add clippy 16 | - | 17 | if [ "$TRAVIS_RUST_VERSION" == "stable" ]; then 18 | cargo install --force cargo-audit 19 | fi 20 | - cargo generate-lockfile 21 | script: 22 | - | 23 | if [ "$TRAVIS_RUST_VERSION" == "stable" ]; then 24 | cargo audit 25 | fi 26 | - cargo fmt -- --check 27 | - | 28 | if [ "$TRAVIS_RUST_VERSION" != "1.39.0" ]; then 29 | cargo clippy --all-targets --all-features -- -D warnings 30 | fi 31 | - cargo build --verbose 32 | - cargo test --verbose 33 | if: "type != push OR (tag IS blank AND branch = master)" 34 | -------------------------------------------------------------------------------- /src/r0/profile/set_avatar_url.rs: -------------------------------------------------------------------------------- 1 | //! [PUT /_matrix/client/r0/profile/{userId}/avatar_url](https://matrix.org/docs/spec/client_server/r0.4.0.html#put-matrix-client-r0-profile-userid-avatar-url) 2 | 3 | use ruma_api::ruma_api; 4 | use ruma_identifiers::UserId; 5 | 6 | ruma_api! { 7 | metadata { 8 | description: "Set the avatar URL of the user.", 9 | method: PUT, 10 | name: "set_avatar_url", 11 | path: "/_matrix/client/r0/profile/:user_id/avatar_url", 12 | rate_limited: true, 13 | requires_authentication: true, 14 | } 15 | 16 | request { 17 | /// The new avatar URL for the user. 18 | pub avatar_url: String, 19 | /// The user whose avatar URL will be set. 20 | #[ruma_api(path)] 21 | pub user_id: UserId 22 | } 23 | 24 | response {} 25 | 26 | error: crate::Error 27 | } 28 | -------------------------------------------------------------------------------- /src/r0/thirdparty/get_protocols.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/client/r0/thirdparty/protocols](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-thirdparty-protocols) 2 | 3 | use std::collections::HashMap; 4 | 5 | use ruma_api::ruma_api; 6 | 7 | use super::Protocol; 8 | 9 | ruma_api! { 10 | metadata { 11 | description: "Fetches the overall metadata about protocols supported by the homeserver.", 12 | method: GET, 13 | name: "get_protocols", 14 | path: "/_matrix/client/r0/thirdparty/protocols", 15 | rate_limited: false, 16 | requires_authentication: true, 17 | } 18 | 19 | request {} 20 | 21 | response { 22 | /// Metadata about protocols supported by the homeserver. 23 | #[ruma_api(body)] 24 | pub protocols: HashMap, 25 | } 26 | 27 | error: crate::Error 28 | } 29 | -------------------------------------------------------------------------------- /src/r0/device/get_device.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/client/r0/devices/{deviceId}](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-devices-deviceid) 2 | 3 | use super::Device; 4 | use ruma_api::ruma_api; 5 | use ruma_identifiers::DeviceId; 6 | 7 | ruma_api! { 8 | metadata { 9 | description: "Get a device for authenticated user.", 10 | method: GET, 11 | name: "get_device", 12 | path: "/_matrix/client/r0/devices/:device_id", 13 | rate_limited: false, 14 | requires_authentication: true, 15 | } 16 | 17 | request { 18 | /// The device to retrieve. 19 | #[ruma_api(path)] 20 | pub device_id: DeviceId, 21 | } 22 | 23 | response { 24 | /// Information about the device. 25 | #[ruma_api(body)] 26 | pub device: Device, 27 | } 28 | 29 | error: crate::Error 30 | } 31 | -------------------------------------------------------------------------------- /src/r0/account/change_password.rs: -------------------------------------------------------------------------------- 1 | //! [POST /_matrix/client/r0/account/password](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-account-password) 2 | 3 | use ruma_api::ruma_api; 4 | 5 | use super::AuthenticationData; 6 | 7 | ruma_api! { 8 | metadata { 9 | description: "Change the password of the current user's account.", 10 | method: POST, 11 | name: "change_password", 12 | path: "/_matrix/client/r0/account/password", 13 | rate_limited: true, 14 | requires_authentication: true, 15 | } 16 | 17 | request { 18 | /// The new password for the account. 19 | pub new_password: String, 20 | /// Additional authentication information for the user-interactive authentication API. 21 | pub auth: Option, 22 | } 23 | 24 | response {} 25 | 26 | error: crate::Error 27 | } 28 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | authors = ["Jimmy Cuadra "] 3 | categories = ["api-bindings", "web-programming"] 4 | description = "Types for the endpoints in the Matrix client-server API." 5 | documentation = "https://docs.rs/ruma-client-api" 6 | homepage = "https://github.com/ruma/ruma-client-api" 7 | keywords = ["matrix", "chat", "messaging", "ruma"] 8 | license = "MIT" 9 | name = "ruma-client-api" 10 | readme = "README.md" 11 | repository = "https://github.com/ruma/ruma-client-api" 12 | version = "0.7.1" 13 | edition = "2018" 14 | 15 | [dependencies] 16 | http = "0.2.1" 17 | js_int = { version = "0.1.4", features = ["serde"] } 18 | ruma-api = "0.15.0" 19 | ruma-events = "0.18.0" 20 | ruma-identifiers = "0.14.1" 21 | serde = { version = "1.0.105", features = ["derive"] } 22 | serde_json = "1.0.50" 23 | strum = { version = "0.18.0", features = ["derive"] } 24 | url = { version = "2.1.1", features = ["serde"] } 25 | -------------------------------------------------------------------------------- /src/r0/room/upgrade_room.rs: -------------------------------------------------------------------------------- 1 | //! [POST /_matrix/client/r0/rooms/{roomId}/upgrade](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-rooms-roomid-upgrade) 2 | 3 | use ruma_api::ruma_api; 4 | use ruma_identifiers::RoomId; 5 | 6 | ruma_api! { 7 | metadata { 8 | description: "Upgrades a room to a particular version.", 9 | method: POST, 10 | name: "upgrade_room", 11 | path: "/_matrix/client/r0/rooms/:room_id/upgrade", 12 | rate_limited: false, 13 | requires_authentication: true, 14 | } 15 | 16 | request { 17 | /// ID of the room to be upgraded. 18 | #[ruma_api(path)] 19 | pub room_id: RoomId, 20 | /// New version for the room. 21 | pub new_version: String, 22 | } 23 | 24 | response { 25 | /// ID of the new room. 26 | pub replacement_room: RoomId, 27 | } 28 | 29 | error: crate::Error 30 | } 31 | -------------------------------------------------------------------------------- /src/r0/session/sso_login.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/client/r0/login/sso/redirect](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-login-sso-redirect) 2 | 3 | use ruma_api::ruma_api; 4 | 5 | ruma_api! { 6 | metadata { 7 | description: "", 8 | method: GET, 9 | name: "sso_login", 10 | path: "/_matrix/client/r0/login/sso/redirect", 11 | rate_limited: false, 12 | requires_authentication: false, 13 | 14 | } 15 | 16 | request { 17 | /// URL to which the homeserver should return the user after completing 18 | /// authentication with the SSO identity provider. 19 | #[ruma_api(query)] 20 | pub redirect_url: String, 21 | } 22 | 23 | response { 24 | /// Redirect URL to the SSO identity provider. 25 | #[ruma_api(header = LOCATION)] 26 | pub location: String, 27 | } 28 | 29 | error: crate::Error 30 | } 31 | -------------------------------------------------------------------------------- /src/r0/thirdparty/get_user_for_user_id.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/client/r0/thirdparty/user](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-thirdparty-user) 2 | 3 | use ruma_api::ruma_api; 4 | use ruma_identifiers::UserId; 5 | 6 | use super::User; 7 | 8 | ruma_api! { 9 | metadata { 10 | description: "Retrieve an array of third party users from a Matrix User ID.", 11 | method: GET, 12 | name: "get_user_for_user_id", 13 | path: "/_matrix/client/r0/thirdparty/user", 14 | rate_limited: false, 15 | requires_authentication: true, 16 | } 17 | 18 | request { 19 | /// The Matrix User ID to look up. 20 | #[ruma_api(query)] 21 | pub userid: UserId, 22 | } 23 | 24 | response { 25 | /// List of matched third party users. 26 | #[ruma_api(body)] 27 | pub users: Vec, 28 | } 29 | 30 | error: crate::Error 31 | } 32 | -------------------------------------------------------------------------------- /src/r0/thirdparty/get_protocol.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/client/r0/thirdparty/protocol/{protocol}](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-thirdparty-protocol-protocol) 2 | 3 | use ruma_api::ruma_api; 4 | 5 | use super::Protocol; 6 | 7 | ruma_api! { 8 | metadata { 9 | description: "Fetches the metadata from the homeserver about a particular third party protocol.", 10 | method: GET, 11 | name: "get_protocol", 12 | path: "/_matrix/client/r0/thirdparty/protocol/:protocol", 13 | rate_limited: false, 14 | requires_authentication: true, 15 | } 16 | 17 | request { 18 | /// The name of the protocol. 19 | #[ruma_api(path)] 20 | pub protocol: String, 21 | } 22 | 23 | response { 24 | /// Metadata about the protocol. 25 | #[ruma_api(body)] 26 | pub protocol: Protocol, 27 | } 28 | 29 | error: crate::Error 30 | } 31 | -------------------------------------------------------------------------------- /src/r0/profile/get_avatar_url.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/client/r0/profile/{userId}/avatar_url](https://matrix.org/docs/spec/client_server/r0.4.0.html#get-matrix-client-r0-profile-userid-avatar-url) 2 | 3 | use ruma_api::ruma_api; 4 | use ruma_identifiers::UserId; 5 | 6 | ruma_api! { 7 | metadata { 8 | description: "Get the avatar URL of a user.", 9 | method: GET, 10 | name: "get_avatar_url", 11 | path: "/_matrix/client/r0/profile/:user_id/avatar_url", 12 | rate_limited: false, 13 | requires_authentication: false, 14 | } 15 | 16 | request { 17 | /// The user whose avatar URL will be retrieved. 18 | #[ruma_api(path)] 19 | pub user_id: UserId 20 | } 21 | 22 | response { 23 | /// The user's avatar URL, if set. 24 | #[serde(skip_serializing_if = "Option::is_none")] 25 | pub avatar_url: Option 26 | } 27 | 28 | error: crate::Error 29 | } 30 | -------------------------------------------------------------------------------- /src/r0/profile/set_display_name.rs: -------------------------------------------------------------------------------- 1 | //! [PUT /_matrix/client/r0/profile/{userId}/displayname](https://matrix.org/docs/spec/client_server/r0.4.0.html#put-matrix-client-r0-profile-userid-displayname) 2 | 3 | use ruma_api::ruma_api; 4 | use ruma_identifiers::UserId; 5 | 6 | ruma_api! { 7 | metadata { 8 | description: "Set the display name of the user.", 9 | method: PUT, 10 | name: "set_display_name", 11 | path: "/_matrix/client/r0/profile/:user_id/displayname", 12 | rate_limited: true, 13 | requires_authentication: true, 14 | } 15 | 16 | request { 17 | /// The new display name for the user. 18 | #[serde(skip_serializing_if = "Option::is_none")] 19 | pub displayname: Option, 20 | /// The user whose display name will be set. 21 | #[ruma_api(path)] 22 | pub user_id: UserId, 23 | } 24 | 25 | response {} 26 | 27 | error: crate::Error 28 | } 29 | -------------------------------------------------------------------------------- /src/r0/membership/ban_user.rs: -------------------------------------------------------------------------------- 1 | //! [POST /_matrix/client/r0/rooms/{roomId}/ban](https://matrix.org/docs/spec/client_server/r0.4.0.html#post-matrix-client-r0-rooms-roomid-ban) 2 | 3 | use ruma_api::ruma_api; 4 | use ruma_identifiers::{RoomId, UserId}; 5 | 6 | ruma_api! { 7 | metadata { 8 | description: "Ban a user from a room.", 9 | method: POST, 10 | name: "ban_user", 11 | path: "/_matrix/client/r0/rooms/:room_id/ban", 12 | rate_limited: false, 13 | requires_authentication: true, 14 | } 15 | 16 | request { 17 | /// The reason for banning the user. 18 | #[serde(skip_serializing_if = "Option::is_none")] 19 | pub reason: Option, 20 | /// The room to kick the user from. 21 | #[ruma_api(path)] 22 | pub room_id: RoomId, 23 | /// The user to ban. 24 | pub user_id: UserId, 25 | } 26 | 27 | response {} 28 | 29 | error: crate::Error 30 | } 31 | -------------------------------------------------------------------------------- /src/r0/profile/get_display_name.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/client/r0/profile/{userId}/displayname](https://matrix.org/docs/spec/client_server/r0.4.0.html#get-matrix-client-r0-profile-userid-displayname) 2 | 3 | use ruma_api::ruma_api; 4 | use ruma_identifiers::UserId; 5 | 6 | ruma_api! { 7 | metadata { 8 | description: "Get the display name of a user.", 9 | method: GET, 10 | name: "get_display_name", 11 | path: "/_matrix/client/r0/profile/:user_id/displayname", 12 | rate_limited: false, 13 | requires_authentication: false, 14 | } 15 | 16 | request { 17 | /// The user whose display name will be retrieved. 18 | #[ruma_api(path)] 19 | pub user_id: UserId 20 | } 21 | 22 | response { 23 | /// The user's display name, if set. 24 | #[serde(skip_serializing_if = "Option::is_none")] 25 | pub displayname: Option 26 | } 27 | 28 | error: crate::Error 29 | } 30 | -------------------------------------------------------------------------------- /src/r0/alias/get_alias.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/client/r0/directory/room/{roomAlias}](https://matrix.org/docs/spec/client_server/r0.4.0.html#get-matrix-client-r0-directory-room-roomalias) 2 | 3 | use ruma_api::ruma_api; 4 | use ruma_identifiers::{RoomAliasId, RoomId}; 5 | 6 | ruma_api! { 7 | metadata { 8 | description: "Resolve a room alias to a room ID.", 9 | method: GET, 10 | name: "get_alias", 11 | path: "/_matrix/client/r0/directory/room/:room_alias", 12 | rate_limited: false, 13 | requires_authentication: true, 14 | } 15 | 16 | request { 17 | /// The room alias. 18 | #[ruma_api(path)] 19 | pub room_alias: RoomAliasId, 20 | } 21 | 22 | response { 23 | /// The room ID for this room alias. 24 | pub room_id: RoomId, 25 | /// A list of servers that are aware of this room ID. 26 | pub servers: Vec, 27 | } 28 | 29 | error: crate::Error 30 | } 31 | -------------------------------------------------------------------------------- /src/r0/device/delete_devices.rs: -------------------------------------------------------------------------------- 1 | //! [POST /_matrix/client/r0/delete_devices](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-delete-devices) 2 | 3 | use crate::r0::account::AuthenticationData; 4 | use ruma_api::ruma_api; 5 | use ruma_identifiers::DeviceId; 6 | 7 | ruma_api! { 8 | metadata { 9 | description: "Delete specified devices.", 10 | method: POST, 11 | path: "/_matrix/client/r0/delete_devices", 12 | name: "delete_devices", 13 | rate_limited: false, 14 | requires_authentication: true, 15 | } 16 | 17 | request { 18 | /// List of devices to delete. 19 | pub devices: Vec, 20 | 21 | /// Additional authentication information for the user-interactive authentication API. 22 | #[serde(skip_serializing_if = "Option::is_none")] 23 | pub auth: Option, 24 | } 25 | 26 | response {} 27 | 28 | error: crate::Error 29 | } 30 | -------------------------------------------------------------------------------- /src/r0/device/update_device.rs: -------------------------------------------------------------------------------- 1 | //! [PUT /_matrix/client/r0/devices/{deviceId}](https://matrix.org/docs/spec/client_server/r0.6.0#put-matrix-client-r0-devices-deviceid) 2 | 3 | use ruma_api::ruma_api; 4 | use ruma_identifiers::DeviceId; 5 | 6 | ruma_api! { 7 | metadata { 8 | description: "Update metadata for a device.", 9 | method: PUT, 10 | name: "update_device", 11 | path: "/_matrix/client/r0/devices/:device_id", 12 | rate_limited: false, 13 | requires_authentication: true, 14 | } 15 | 16 | request { 17 | /// The device to update. 18 | #[ruma_api(path)] 19 | pub device_id: DeviceId, 20 | /// The new display name for this device. If this is `None`, the display name won't be 21 | /// changed. 22 | #[serde(skip_serializing_if = "Option::is_none")] 23 | pub display_name: Option, 24 | } 25 | 26 | response {} 27 | 28 | error: crate::Error 29 | } 30 | -------------------------------------------------------------------------------- /src/r0/push/set_pusher.rs: -------------------------------------------------------------------------------- 1 | //! [POST /_matrix/client/r0/pushers/set](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-pushers-set) 2 | 3 | use ruma_api::ruma_api; 4 | 5 | use super::Pusher; 6 | 7 | ruma_api! { 8 | metadata { 9 | description: "This endpoint allows the creation, modification and deletion of pushers for this user ID.", 10 | method: POST, 11 | name: "set_pusher", 12 | path: "/_matrix/client/r0/pushers/set", 13 | rate_limited: true, 14 | requires_authentication: true, 15 | } 16 | 17 | request { 18 | /// The pusher to configure 19 | #[serde(flatten)] 20 | pub pusher: Pusher, 21 | 22 | /// Controls if another pusher with the same pushkey and app id should be created. 23 | /// See the spec for details. 24 | #[serde(default)] 25 | pub append: bool 26 | 27 | } 28 | 29 | response {} 30 | 31 | error: crate::Error 32 | } 33 | -------------------------------------------------------------------------------- /src/r0/account/get_username_availability.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/client/r0/register/available](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-register-available) 2 | 3 | use ruma_api::ruma_api; 4 | 5 | ruma_api! { 6 | metadata { 7 | description: "Checks to see if a username is available, and valid, for the server.", 8 | method: GET, 9 | name: "get_username_availability", 10 | path: "/_matrix/client/r0/register/available", 11 | rate_limited: true, 12 | requires_authentication: false, 13 | } 14 | 15 | request { 16 | /// The username to check the availability of. 17 | #[ruma_api(query)] 18 | pub username: String, 19 | } 20 | 21 | response { 22 | /// A flag to indicate that the username is available. 23 | /// This should always be true when the server replies with 200 OK. 24 | pub available: bool 25 | } 26 | 27 | error: crate::Error 28 | } 29 | -------------------------------------------------------------------------------- /src/r0/membership/kick_user.rs: -------------------------------------------------------------------------------- 1 | //! [POST /_matrix/client/r0/rooms/{roomId}/kick](https://matrix.org/docs/spec/client_server/r0.4.0.html#post-matrix-client-r0-rooms-roomid-kick) 2 | 3 | use ruma_api::ruma_api; 4 | use ruma_identifiers::{RoomId, UserId}; 5 | 6 | ruma_api! { 7 | metadata { 8 | description: "Kick a user from a room.", 9 | method: POST, 10 | name: "kick_user", 11 | path: "/_matrix/client/r0/rooms/:room_id/kick", 12 | rate_limited: false, 13 | requires_authentication: true, 14 | } 15 | 16 | request { 17 | /// The reason for kicking the user. 18 | #[serde(skip_serializing_if = "Option::is_none")] 19 | pub reason: Option, 20 | /// The room to kick the user from. 21 | #[ruma_api(path)] 22 | pub room_id: RoomId, 23 | /// The user to kick. 24 | pub user_id: UserId, 25 | } 26 | 27 | response {} 28 | 29 | error: crate::Error 30 | } 31 | -------------------------------------------------------------------------------- /src/unversioned/get_supported_versions.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/client/versions](https://matrix.org/docs/spec/client_server/r0.6.0.html#get-matrix-client-versions) 2 | 3 | use std::collections::HashMap; 4 | 5 | use ruma_api::ruma_api; 6 | 7 | ruma_api! { 8 | metadata { 9 | description: "Get the versions of the client-server API supported by this homeserver.", 10 | method: GET, 11 | name: "api_versions", 12 | path: "/_matrix/client/versions", 13 | rate_limited: false, 14 | requires_authentication: false, 15 | } 16 | 17 | request {} 18 | 19 | response { 20 | /// A list of Matrix client API protocol versions supported by the homeserver. 21 | pub versions: Vec, 22 | /// Experimental features supported by the server. 23 | #[serde(default, skip_serializing_if = "HashMap::is_empty")] 24 | pub unstable_features: HashMap 25 | } 26 | 27 | error: crate::Error 28 | } 29 | -------------------------------------------------------------------------------- /src/r0/thirdparty/get_location_for_room_alias.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/client/r0/thirdparty/location](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-thirdparty-location) 2 | 3 | use ruma_api::ruma_api; 4 | use ruma_identifiers::RoomAliasId; 5 | 6 | use super::Location; 7 | 8 | ruma_api! { 9 | metadata { 10 | description: "Retrieve an array of third party network locations from a Matrix room alias.", 11 | method: GET, 12 | name: "get_location_for_room_alias", 13 | path: "/_matrix/client/r0/thirdparty/location", 14 | rate_limited: false, 15 | requires_authentication: true, 16 | } 17 | 18 | request { 19 | /// The Matrix room alias to look up. 20 | #[ruma_api(query)] 21 | pub alias: RoomAliasId, 22 | } 23 | 24 | response { 25 | /// List of matched third party locations. 26 | #[ruma_api(body)] 27 | pub locations: Vec, 28 | } 29 | 30 | error: crate::Error 31 | } 32 | -------------------------------------------------------------------------------- /src/r0/device/delete_device.rs: -------------------------------------------------------------------------------- 1 | //! [DELETE /_matrix/client/r0/devices/{deviceId}](https://matrix.org/docs/spec/client_server/r0.6.0#delete-matrix-client-r0-devices-deviceid) 2 | 3 | use crate::r0::account::AuthenticationData; 4 | use ruma_api::ruma_api; 5 | use ruma_identifiers::DeviceId; 6 | 7 | ruma_api! { 8 | metadata { 9 | description: "Delete a device for authenticated user.", 10 | method: DELETE, 11 | name: "delete_device", 12 | path: "/_matrix/client/r0/devices/:device_id", 13 | rate_limited: false, 14 | requires_authentication: true, 15 | } 16 | 17 | request { 18 | /// The device to delete. 19 | #[ruma_api(path)] 20 | pub device_id: DeviceId, 21 | /// Additional authentication information for the user-interactive authentication API. 22 | #[serde(skip_serializing_if = "Option::is_none")] 23 | pub auth: Option, 24 | } 25 | 26 | response {} 27 | 28 | error: crate::Error 29 | } 30 | -------------------------------------------------------------------------------- /src/r0/tag/delete_tag.rs: -------------------------------------------------------------------------------- 1 | //! [DELETE /_matrix/client/r0/user/{userId}/rooms/{roomId}/tags/{tag}](https://matrix.org/docs/spec/client_server/r0.4.0.html#delete-matrix-client-r0-user-userid-rooms-roomid-tags-tag) 2 | 3 | use ruma_api::ruma_api; 4 | use ruma_identifiers::{RoomId, UserId}; 5 | 6 | ruma_api! { 7 | metadata { 8 | description: "Remove a tag from a room.", 9 | method: DELETE, 10 | name: "delete_tag", 11 | path: "/_matrix/client/r0/user/:user_id/rooms/:room_id/tags/:tag", 12 | rate_limited: false, 13 | requires_authentication: true, 14 | } 15 | 16 | request { 17 | /// The tagged room. 18 | #[ruma_api(path)] 19 | pub room_id: RoomId, 20 | /// The name of the tag to delete. 21 | #[ruma_api(path)] 22 | pub tag: String, 23 | /// The user whose tag will be deleted. 24 | #[ruma_api(path)] 25 | pub user_id: UserId, 26 | } 27 | 28 | response {} 29 | 30 | error: crate::Error 31 | } 32 | -------------------------------------------------------------------------------- /src/r0/voip/get_turn_server_info.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/client/r0/voip/turnServer](https://matrix.org/docs/spec/client_server/r0.4.0.html#get-matrix-client-r0-voip-turnserver) 2 | 3 | use std::time::Duration; 4 | 5 | use ruma_api::ruma_api; 6 | 7 | ruma_api! { 8 | metadata { 9 | description: "Get credentials for the client to use when initiating VoIP calls.", 10 | method: GET, 11 | name: "turn_server_info", 12 | path: "_matrix/client/r0/voip/turnServer", 13 | rate_limited: true, 14 | requires_authentication: true, 15 | } 16 | 17 | request {} 18 | 19 | response { 20 | /// The password to use. 21 | pub password: String, 22 | /// The time-to-live in seconds. 23 | #[serde(with = "crate::serde::duration::secs")] 24 | pub ttl: Duration, 25 | /// A list of TURN URIs. 26 | pub uris: Vec, 27 | /// The username to use. 28 | pub username: String, 29 | } 30 | 31 | error: crate::Error 32 | } 33 | -------------------------------------------------------------------------------- /src/r0/push/delete_pushrule.rs: -------------------------------------------------------------------------------- 1 | //! [DELETE /_matrix/client/r0/pushrules/{scope}/{kind}/{ruleId}](https://matrix.org/docs/spec/client_server/r0.6.0#delete-matrix-client-r0-pushrules-scope-kind-ruleid) 2 | 3 | use ruma_api::ruma_api; 4 | 5 | use super::RuleKind; 6 | 7 | ruma_api! { 8 | metadata { 9 | description: "This endpoint removes the push rule defined in the path.", 10 | method: DELETE, 11 | name: "delete_pushrule", 12 | path: "/_matrix/client/r0/pushrules/:scope/:kind/:rule_id", 13 | rate_limited: false, 14 | requires_authentication: true, 15 | } 16 | 17 | request { 18 | /// The scope to delete from. 'global' to specify global rules. 19 | #[ruma_api(path)] 20 | pub scope: String, 21 | 22 | /// The kind of rule 23 | #[ruma_api(path)] 24 | pub kind: RuleKind, 25 | 26 | /// The identifier for the rule. 27 | #[ruma_api(path)] 28 | pub rule_id: String, 29 | } 30 | 31 | response {} 32 | 33 | error: crate::Error 34 | } 35 | -------------------------------------------------------------------------------- /src/r0/filter/get_filter.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/client/r0/user/{userId}/filter/{filterId}](https://matrix.org/docs/spec/client_server/r0.4.0.html#get-matrix-client-r0-user-userid-filter-filterid) 2 | 3 | use ruma_api::ruma_api; 4 | use ruma_identifiers::UserId; 5 | 6 | use super::FilterDefinition; 7 | 8 | ruma_api! { 9 | metadata { 10 | description: "Retrieve a previously created filter.", 11 | method: GET, 12 | name: "get_filter", 13 | path: "/_matrix/client/r0/user/:user_id/filter/:filter_id", 14 | rate_limited: false, 15 | requires_authentication: true, 16 | } 17 | 18 | request { 19 | /// The ID of the filter to download. 20 | #[ruma_api(path)] 21 | pub filter_id: String, 22 | /// The user ID to download a filter for. 23 | #[ruma_api(path)] 24 | pub user_id: UserId, 25 | } 26 | 27 | response { 28 | /// The filter definition. 29 | #[ruma_api(body)] 30 | pub filter: FilterDefinition, 31 | } 32 | 33 | error: crate::Error 34 | } 35 | -------------------------------------------------------------------------------- /src/r0/presence/set_presence.rs: -------------------------------------------------------------------------------- 1 | //! [PUT /_matrix/client/r0/presence/{userId}/status](https://matrix.org/docs/spec/client_server/r0.4.0.html#put-matrix-client-r0-presence-userid-status) 2 | 3 | use ruma_api::ruma_api; 4 | use ruma_events::presence::PresenceState; 5 | use ruma_identifiers::UserId; 6 | 7 | ruma_api! { 8 | metadata { 9 | description: "Set presence status for this user.", 10 | method: PUT, 11 | name: "set_presence", 12 | path: "/_matrix/client/r0/presence/:user_id/status", 13 | rate_limited: true, 14 | requires_authentication: true, 15 | } 16 | 17 | request { 18 | /// The new presence state. 19 | pub presence: PresenceState, 20 | /// The status message to attach to this state. 21 | #[serde(skip_serializing_if = "Option::is_none")] 22 | pub status_msg: Option, 23 | /// The user whose presence state will be updated. 24 | #[ruma_api(path)] 25 | pub user_id: UserId, 26 | } 27 | 28 | response {} 29 | 30 | error: crate::Error 31 | } 32 | -------------------------------------------------------------------------------- /src/r0/profile/get_profile.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/client/r0/profile/{userId}](https://matrix.org/docs/spec/client_server/r0.4.0.html#get-matrix-client-r0-profile-userid) 2 | 3 | use ruma_api::ruma_api; 4 | use ruma_identifiers::UserId; 5 | 6 | ruma_api! { 7 | metadata { 8 | description: "Get all profile information of an user.", 9 | method: GET, 10 | name: "get_profile", 11 | path: "/_matrix/client/r0/profile/:user_id", 12 | rate_limited: false, 13 | requires_authentication: false, 14 | } 15 | 16 | request { 17 | /// The user whose profile will be retrieved. 18 | #[ruma_api(path)] 19 | pub user_id: UserId, 20 | } 21 | 22 | response { 23 | /// The user's avatar URL, if set. 24 | #[serde(skip_serializing_if = "Option::is_none")] 25 | pub avatar_url: Option, 26 | /// The user's display name, if set. 27 | #[serde(skip_serializing_if = "Option::is_none")] 28 | pub displayname: Option, 29 | } 30 | 31 | error: crate::Error 32 | } 33 | -------------------------------------------------------------------------------- /src/r0/room/report_content.rs: -------------------------------------------------------------------------------- 1 | //! [POST /_matrix/client/r0/rooms/{roomId}/report/{eventId}](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-rooms-roomid-report-eventid) 2 | 3 | use js_int::Int; 4 | use ruma_api::ruma_api; 5 | use ruma_identifiers::{EventId, RoomId}; 6 | 7 | ruma_api! { 8 | metadata { 9 | description: "Report content as inappropriate.", 10 | method: POST, 11 | name: "report_content", 12 | path: "/rooms/:room_id/report/:event_id", 13 | rate_limited: false, 14 | requires_authentication: true, 15 | } 16 | 17 | request { 18 | /// Room in which the event to be reported is located. 19 | #[ruma_api(path)] 20 | pub room_id: RoomId, 21 | /// Event to report. 22 | #[ruma_api(path)] 23 | pub event_id: EventId, 24 | /// Integer between -100 and 0 rating offensivness. 25 | pub score: Int, 26 | /// Reason to report content. May be blank. 27 | pub reason: String, 28 | } 29 | 30 | response {} 31 | 32 | error: crate::Error 33 | } 34 | -------------------------------------------------------------------------------- /src/r0/account/bind_3pid.rs: -------------------------------------------------------------------------------- 1 | //! [POST /_matrix/client/r0/account/3pid/bind](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-account-3pid-bind) 2 | 3 | use ruma_api::ruma_api; 4 | 5 | use super::IdentityServerInfo; 6 | 7 | ruma_api! { 8 | metadata { 9 | description: "Bind a 3PID to a user's account on an identity server", 10 | method: POST, 11 | name: "bind_3pid", 12 | path: "/_matrix/client/r0/account/3pid/bind", 13 | rate_limited: true, 14 | requires_authentication: true, 15 | } 16 | 17 | request { 18 | /// Client-generated secret string used to protect this session. 19 | pub client_secret: String, 20 | /// The ID server to send the onward request to as a hostname with an 21 | /// appended colon and port number if the port is not the default. 22 | #[serde(flatten)] 23 | pub identity_server_info: IdentityServerInfo, 24 | /// The session identifier given by the identity server. 25 | pub sid: String, 26 | } 27 | 28 | response {} 29 | 30 | error: crate::Error 31 | } 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 Jimmy Cuadra 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /src/r0/media/create_content.rs: -------------------------------------------------------------------------------- 1 | //! [POST /_matrix/media/r0/upload](https://matrix.org/docs/spec/client_server/r0.4.0.html#post-matrix-media-r0-upload) 2 | 3 | use ruma_api::ruma_api; 4 | 5 | ruma_api! { 6 | metadata { 7 | description: "Upload content to the media store.", 8 | method: POST, 9 | name: "create_media_content", 10 | path: "/_matrix/media/r0/upload", 11 | rate_limited: true, 12 | requires_authentication: true, 13 | } 14 | 15 | request { 16 | /// The name of the file being uploaded. 17 | #[serde(skip_serializing_if = "Option::is_none")] 18 | #[ruma_api(query)] 19 | pub filename: Option, 20 | /// The content type of the file being uploaded. 21 | #[ruma_api(header = CONTENT_TYPE)] 22 | pub content_type: String, 23 | /// The file contents to upload. 24 | #[ruma_api(raw_body)] 25 | pub file: Vec, 26 | } 27 | 28 | response { 29 | /// The MXC URI for the uploaded content. 30 | pub content_uri: String, 31 | } 32 | 33 | error: crate::Error 34 | } 35 | -------------------------------------------------------------------------------- /src/r0/tag/get_tags.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/client/r0/user/{userId}/rooms/{roomId}/tags](https://matrix.org/docs/spec/client_server/r0.4.0.html#get-matrix-client-r0-user-userid-rooms-roomid-tags) 2 | 3 | use ruma_api::ruma_api; 4 | use ruma_events::{tag::TagEventContent, EventResult}; 5 | use ruma_identifiers::{RoomId, UserId}; 6 | 7 | ruma_api! { 8 | metadata { 9 | description: "Get the tags associated with a room.", 10 | method: GET, 11 | name: "get_tags", 12 | path: "/_matrix/client/r0/user/:user_id/rooms/:room_id/tags", 13 | rate_limited: false, 14 | requires_authentication: true, 15 | } 16 | 17 | request { 18 | /// The room from which tags will be retrieved. 19 | #[ruma_api(path)] 20 | pub room_id: RoomId, 21 | /// The user whose tags will be retrieved. 22 | #[ruma_api(path)] 23 | pub user_id: UserId, 24 | } 25 | 26 | response { 27 | /// The user's tags for the room. 28 | #[wrap_incoming(with EventResult)] 29 | pub tags: TagEventContent, 30 | } 31 | 32 | error: crate::Error 33 | } 34 | -------------------------------------------------------------------------------- /src/r0/filter/create_filter.rs: -------------------------------------------------------------------------------- 1 | //! [POST /_matrix/client/r0/user/{userId}/filter](https://matrix.org/docs/spec/client_server/r0.4.0.html#post-matrix-client-r0-user-userid-filter) 2 | 3 | use ruma_api::ruma_api; 4 | use ruma_identifiers::UserId; 5 | 6 | use super::FilterDefinition; 7 | 8 | ruma_api! { 9 | metadata { 10 | description: "Create a new filter for event retrieval.", 11 | method: POST, 12 | name: "create_filter", 13 | path: "/_matrix/client/r0/user/:user_id/filter", 14 | rate_limited: false, 15 | requires_authentication: true, 16 | } 17 | 18 | request { 19 | /// The filter definition. 20 | #[ruma_api(body)] 21 | pub filter: FilterDefinition, 22 | /// The ID of the user uploading the filter. 23 | /// 24 | /// The access token must be authorized to make requests for this user ID. 25 | #[ruma_api(path)] 26 | pub user_id: UserId, 27 | } 28 | 29 | response { 30 | /// The ID of the filter that was created. 31 | pub filter_id: String, 32 | } 33 | 34 | error: crate::Error 35 | } 36 | -------------------------------------------------------------------------------- /src/r0/room/get_room_event.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/client/r0/rooms/{roomId}/event/{eventId}](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-rooms-roomid-event-eventid) 2 | 3 | use ruma_api::ruma_api; 4 | use ruma_events::{collections::all, EventResult}; 5 | use ruma_identifiers::{EventId, RoomId}; 6 | 7 | ruma_api! { 8 | metadata { 9 | description: "Get a single event based on roomId/eventId", 10 | method: GET, 11 | name: "get_room_event", 12 | path: "/_matrix/client/r0/rooms/:room_id/event/:event_id", 13 | rate_limited: false, 14 | requires_authentication: true, 15 | } 16 | 17 | request { 18 | /// The ID of the room the event is in. 19 | #[ruma_api(path)] 20 | pub room_id: RoomId, 21 | /// The ID of the event. 22 | #[ruma_api(path)] 23 | pub event_id: EventId, 24 | } 25 | 26 | response { 27 | /// Arbitrary JSON of the event body. Returns both room and state events. 28 | #[wrap_incoming(with EventResult)] 29 | pub event: all::RoomEvent, 30 | } 31 | 32 | error: crate::Error 33 | } 34 | -------------------------------------------------------------------------------- /src/r0/tag/create_tag.rs: -------------------------------------------------------------------------------- 1 | //! [PUT /_matrix/client/r0/user/{userId}/rooms/{roomId}/tags/{tag}](https://matrix.org/docs/spec/client_server/r0.4.0.html#put-matrix-client-r0-user-userid-rooms-roomid-tags-tag) 2 | 3 | use ruma_api::ruma_api; 4 | use ruma_events::tag::TagInfo; 5 | use ruma_identifiers::{RoomId, UserId}; 6 | 7 | ruma_api! { 8 | metadata { 9 | description: "Add a new tag to a room.", 10 | method: PUT, 11 | name: "create_tag", 12 | path: "/_matrix/client/r0/user/:user_id/rooms/:room_id/tags/:tag", 13 | rate_limited: false, 14 | requires_authentication: true, 15 | } 16 | 17 | request { 18 | /// The room to tag. 19 | #[ruma_api(path)] 20 | pub room_id: RoomId, 21 | /// The name of the tag to create. 22 | #[ruma_api(path)] 23 | pub tag: String, 24 | /// Info about the tag. 25 | #[ruma_api(body)] 26 | pub tag_info: TagInfo, 27 | /// The ID of the user creating the tag. 28 | #[ruma_api(path)] 29 | pub user_id: UserId, 30 | } 31 | 32 | response {} 33 | 34 | error: crate::Error 35 | } 36 | -------------------------------------------------------------------------------- /src/r0/state/get_state_events_for_empty_key.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/client/r0/rooms/{roomId}/state/{eventType}](https://matrix.org/docs/spec/client_server/r0.4.0.html#get-matrix-client-r0-rooms-roomid-state-eventtype) 2 | 3 | use ruma_api::ruma_api; 4 | use ruma_events::EventType; 5 | use ruma_identifiers::RoomId; 6 | use serde_json::Value; 7 | 8 | ruma_api! { 9 | metadata { 10 | description: "Get state events of a given type associated with the empty key.", 11 | method: GET, 12 | name: "get_state_events_for_empty_key", 13 | path: "/_matrix/client/r0/rooms/:room_id/state/:event_type", 14 | rate_limited: false, 15 | requires_authentication: true, 16 | } 17 | 18 | request { 19 | /// The room to look up the state for. 20 | #[ruma_api(path)] 21 | pub room_id: RoomId, 22 | /// The type of state to look up. 23 | #[ruma_api(path)] 24 | pub event_type: EventType, 25 | } 26 | 27 | response { 28 | /// The content of the state event. 29 | #[ruma_api(body)] 30 | pub content: Value, 31 | } 32 | 33 | error: crate::Error 34 | } 35 | -------------------------------------------------------------------------------- /src/r0/push/get_pushrule.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/client/r0/pushrules/{scope}/{kind}/{ruleId}](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-pushrules-scope-kind-ruleid) 2 | 3 | use ruma_api::ruma_api; 4 | 5 | use super::{PushRule, RuleKind}; 6 | 7 | ruma_api! { 8 | metadata { 9 | description: "Retrieve a single specified push rule.", 10 | method: GET, 11 | name: "get_pushrule", 12 | path: "/_matrix/client/r0/pushrules/:scope/:kind/:rule_id", 13 | rate_limited: false, 14 | requires_authentication: true, 15 | } 16 | 17 | request { 18 | /// The scope to fetch rules from. 'global' to specify global rules. 19 | #[ruma_api(path)] 20 | pub scope: String, 21 | 22 | /// The kind of rule 23 | #[ruma_api(path)] 24 | pub kind: RuleKind, 25 | 26 | /// The identifier for the rule. 27 | #[ruma_api(path)] 28 | pub rule_id: String, 29 | } 30 | 31 | response { 32 | /// The specific push rule. 33 | #[ruma_api(body)] 34 | pub rule: PushRule 35 | } 36 | 37 | error: crate::Error 38 | } 39 | -------------------------------------------------------------------------------- /src/r0/account/unbind_3pid.rs: -------------------------------------------------------------------------------- 1 | //! [POST /_matrix/client/r0/account/3pid/unbind](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-account-3pid-unbind) 2 | 3 | use ruma_api::ruma_api; 4 | 5 | use super::ThirdPartyIdRemovalStatus; 6 | use crate::r0::thirdparty::Medium; 7 | 8 | ruma_api! { 9 | metadata { 10 | description: "Unbind a 3PID from a user's account on an identity server.", 11 | method: POST, 12 | name: "unbind_3pid", 13 | path: "/_matrix/client/r0/account/3pid/unbind", 14 | rate_limited: false, 15 | requires_authentication: true, 16 | } 17 | 18 | request { 19 | /// Identity server to unbind from. 20 | #[serde(skip_serializing_if = "Option::is_none")] 21 | pub id_server: Option, 22 | /// Medium of the 3PID to be removed. 23 | pub medium: Medium, 24 | /// Third-party address being removed. 25 | pub address: String, 26 | } 27 | 28 | response { 29 | /// Result of unbind operation. 30 | pub id_server_unbind_result: ThirdPartyIdRemovalStatus, 31 | } 32 | 33 | error: crate::Error 34 | } 35 | -------------------------------------------------------------------------------- /src/r0/account/delete_3pid.rs: -------------------------------------------------------------------------------- 1 | //! [POST /_matrix/client/r0/account/3pid/delete](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-account-3pid-delete) 2 | 3 | use ruma_api::ruma_api; 4 | 5 | use super::ThirdPartyIdRemovalStatus; 6 | use crate::r0::thirdparty::Medium; 7 | 8 | ruma_api! { 9 | metadata { 10 | description: "Delete a 3PID from a user's account on an identity server.", 11 | method: POST, 12 | name: "delete_3pid", 13 | path: "/_matrix/client/r0/account/3pid/delete", 14 | rate_limited: false, 15 | requires_authentication: true, 16 | } 17 | 18 | request { 19 | /// Identity server to delete from. 20 | #[serde(skip_serializing_if = "Option::is_none")] 21 | pub id_server: Option, 22 | /// Medium of the 3PID to be removed. 23 | pub medium: Medium, 24 | /// Third-party address being removed. 25 | pub address: String, 26 | } 27 | 28 | response { 29 | /// Result of unbind operation. 30 | pub id_server_unbind_result: ThirdPartyIdRemovalStatus, 31 | } 32 | 33 | error: crate::Error 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/r0/config/get_global_account_data.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/client/r0/user/{userId}/account_data/{type}](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-user-userid-account-data-type) 2 | 3 | use ruma_api::ruma_api; 4 | use ruma_events::{collections::only, EventResult}; 5 | use ruma_identifiers::UserId; 6 | 7 | ruma_api! { 8 | metadata { 9 | description: "Gets global account data for a user.", 10 | name: "get_global_account_data", 11 | method: GET, 12 | path: "/_matrix/client/r0/user/:user_id/account_data/:event_type", 13 | rate_limited: false, 14 | requires_authentication: true, 15 | } 16 | 17 | request { 18 | /// User ID of user for whom to retrieve data. 19 | #[ruma_api(path)] 20 | pub user_id: UserId, 21 | /// Type of data to retrieve. 22 | #[ruma_api(path)] 23 | pub event_type: String, 24 | } 25 | 26 | response { 27 | /// Account data content for the given type. 28 | #[ruma_api(body)] 29 | #[wrap_incoming(with EventResult)] 30 | pub account_data: only::Event, 31 | } 32 | 33 | error: crate::Error 34 | } 35 | -------------------------------------------------------------------------------- /src/r0/contact/get_contacts.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/client/r0/account/3pid](https://matrix.org/docs/spec/client_server/r0.4.0.html#get-matrix-client-r0-account-3pid) 2 | 3 | use crate::r0::thirdparty::Medium; 4 | use ruma_api::ruma_api; 5 | use serde::{Deserialize, Serialize}; 6 | 7 | ruma_api! { 8 | metadata { 9 | description: "Get a list of 3rd party contacts associated with the user's account.", 10 | method: GET, 11 | name: "get_contacts", 12 | path: "/_matrix/client/r0/account/3pid", 13 | rate_limited: false, 14 | requires_authentication: true, 15 | } 16 | 17 | request {} 18 | 19 | response { 20 | /// A list of third party identifiers the homeserver has associated with the user's 21 | /// account. 22 | pub threepids: Vec, 23 | } 24 | 25 | error: crate::Error 26 | } 27 | 28 | /// An identifier external to Matrix. 29 | #[derive(Clone, Debug, Deserialize, Serialize)] 30 | pub struct ThirdPartyIdentifier { 31 | /// The third party identifier address. 32 | pub address: String, 33 | /// The medium of third party identifier. 34 | pub medium: Medium, 35 | } 36 | -------------------------------------------------------------------------------- /src/r0/membership/join_room_by_id.rs: -------------------------------------------------------------------------------- 1 | //! [POST /_matrix/client/r0/rooms/{roomId}/join](https://matrix.org/docs/spec/client_server/r0.4.0.html#post-matrix-client-r0-rooms-roomid-join) 2 | 3 | use ruma_api::ruma_api; 4 | use ruma_identifiers::RoomId; 5 | 6 | use super::ThirdPartySigned; 7 | 8 | ruma_api! { 9 | metadata { 10 | description: "Join a room using its ID.", 11 | method: POST, 12 | name: "join_room_by_id", 13 | path: "/_matrix/client/r0/rooms/:room_id/join", 14 | rate_limited: true, 15 | requires_authentication: true, 16 | } 17 | 18 | request { 19 | /// The room where the user should be invited. 20 | #[ruma_api(path)] 21 | pub room_id: RoomId, 22 | /// The signature of a `m.third_party_invite` token to prove that this user owns a third 23 | /// party identity which has been invited to the room. 24 | #[serde(skip_serializing_if = "Option::is_none")] 25 | pub third_party_signed: Option, 26 | } 27 | 28 | response { 29 | /// The room that the user joined. 30 | pub room_id: RoomId, 31 | } 32 | 33 | error: crate::Error 34 | } 35 | -------------------------------------------------------------------------------- /src/r0/push/get_pushrule_enabled.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/client/r0/pushrules/{scope}/{kind}/{ruleId}/enabled](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-pushrules-scope-kind-ruleid-enabled) 2 | 3 | use ruma_api::ruma_api; 4 | 5 | use super::RuleKind; 6 | 7 | ruma_api! { 8 | metadata { 9 | description: "This endpoint gets whether the specified push rule is enabled.", 10 | method: GET, 11 | name: "get_pushrule_enabled", 12 | path: "/_matrix/client/r0/pushrules/:scope/:kind/:rule_id/enabled", 13 | rate_limited: false, 14 | requires_authentication: true, 15 | } 16 | 17 | request { 18 | /// The scope to fetch a rule from. 'global' to specify global rules. 19 | #[ruma_api(path)] 20 | pub scope: String, 21 | 22 | /// The kind of rule 23 | #[ruma_api(path)] 24 | pub kind: RuleKind, 25 | 26 | /// The identifier for the rule. 27 | #[ruma_api(path)] 28 | pub rule_id: String, 29 | } 30 | 31 | response { 32 | /// Whether the push rule is enabled or not. 33 | pub enabled: bool 34 | } 35 | 36 | error: crate::Error 37 | } 38 | -------------------------------------------------------------------------------- /src/r0/media/get_media_preview.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/media/r0/preview_url](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-media-r0-preview-url) 2 | 3 | use js_int::UInt; 4 | use ruma_api::ruma_api; 5 | use serde_json::Value; 6 | 7 | ruma_api! { 8 | metadata { 9 | description: "Get a preview for a URL.", 10 | name: "get_media_preview", 11 | method: GET, 12 | path: "/_matrix/media/r0/preview_url", 13 | rate_limited: true, 14 | requires_authentication: true, 15 | } 16 | 17 | request { 18 | /// URL to get a preview of. 19 | #[ruma_api(query)] 20 | pub url: String, 21 | /// Preferred point in time (in milliseconds) to return a preview for. 22 | #[ruma_api(query)] 23 | pub ts: UInt, 24 | } 25 | 26 | response { 27 | /// OpenGraph-like data for the URL. 28 | /// 29 | /// Differences from OpenGraph: the image size in bytes is added to the `matrix:image:size` 30 | /// field, and `og:image` returns the MXC URI to the image, if any. 31 | #[ruma_api(body)] 32 | pub data: Option, 33 | } 34 | 35 | error: crate::Error 36 | } 37 | -------------------------------------------------------------------------------- /src/r0/push/get_pushrule_actions.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/client/r0/pushrules/{scope}/{kind}/{ruleId}/actions](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-pushrules-scope-kind-ruleid-actions) 2 | 3 | use ruma_api::ruma_api; 4 | 5 | use super::{Action, RuleKind}; 6 | 7 | ruma_api! { 8 | metadata { 9 | description: "This endpoint get the actions for the specified push rule.", 10 | method: GET, 11 | name: "get_pushrule_actions", 12 | path: "/_matrix/client/r0/pushrules/:scope/:kind/:rule_id/actions", 13 | rate_limited: false, 14 | requires_authentication: true, 15 | } 16 | 17 | request { 18 | /// The scope to fetch a rule from. 'global' to specify global rules. 19 | #[ruma_api(path)] 20 | pub scope: String, 21 | 22 | /// The kind of rule 23 | #[ruma_api(path)] 24 | pub kind: RuleKind, 25 | 26 | /// The identifier for the rule. 27 | #[ruma_api(path)] 28 | pub rule_id: String, 29 | } 30 | 31 | response { 32 | /// The actions to perform for this rule. 33 | pub actions: Vec 34 | } 35 | 36 | error: crate::Error 37 | } 38 | -------------------------------------------------------------------------------- /src/r0/push/set_pushrule_enabled.rs: -------------------------------------------------------------------------------- 1 | //! [PUT /_matrix/client/r0/pushrules/{scope}/{kind}/{ruleId}/enabled](https://matrix.org/docs/spec/client_server/r0.6.0#put-matrix-client-r0-pushrules-scope-kind-ruleid-enabled) 2 | 3 | use ruma_api::ruma_api; 4 | 5 | use super::RuleKind; 6 | 7 | ruma_api! { 8 | metadata { 9 | description: "This endpoint allows clients to enable or disable the specified push rule.", 10 | method: PUT, 11 | name: "set_pushrule_enabled", 12 | path: "/_matrix/client/r0/pushrules/:scope/:kind/:rule_id/enabled", 13 | rate_limited: false, 14 | requires_authentication: true, 15 | } 16 | 17 | request { 18 | /// The scope to fetch a rule from. 'global' to specify global rules. 19 | #[ruma_api(path)] 20 | pub scope: String, 21 | 22 | /// The kind of rule 23 | #[ruma_api(path)] 24 | pub kind: RuleKind, 25 | 26 | /// The identifier for the rule. 27 | #[ruma_api(path)] 28 | pub rule_id: String, 29 | 30 | /// Whether the push rule is enabled or not. 31 | pub enabled: bool 32 | } 33 | 34 | response {} 35 | 36 | error: crate::Error 37 | } 38 | -------------------------------------------------------------------------------- /src/r0/account/deactivate.rs: -------------------------------------------------------------------------------- 1 | //! [POST /_matrix/client/r0/account/deactivate](https://matrix.org/docs/spec/client_server/r0.6.0.html#post-matrix-client-r0-account-deactivate) 2 | 3 | use ruma_api::ruma_api; 4 | 5 | use super::{AuthenticationData, ThirdPartyIdRemovalStatus}; 6 | 7 | ruma_api! { 8 | metadata { 9 | description: "Deactivate the current user's account.", 10 | method: POST, 11 | name: "deactivate", 12 | path: "/_matrix/client/r0/account/deactivate", 13 | rate_limited: true, 14 | requires_authentication: true, 15 | } 16 | 17 | request { 18 | /// Additional authentication information for the user-interactive authentication API. 19 | #[serde(skip_serializing_if = "Option::is_none")] 20 | pub auth: Option, 21 | /// Identity server from which to unbind the user's third party 22 | /// identifier. 23 | #[serde(skip_serializing_if = "Option::is_none")] 24 | pub id_server: Option, 25 | } 26 | 27 | response { 28 | /// Result of unbind operation. 29 | pub id_server_unbind_result: ThirdPartyIdRemovalStatus, 30 | } 31 | 32 | error: crate::Error 33 | } 34 | -------------------------------------------------------------------------------- /src/r0/appservice/set_room_visibility.rs: -------------------------------------------------------------------------------- 1 | //! [PUT /_matrix/client/r0/directory/list/appservice/{networkId}/{roomId}](https://matrix.org/docs/spec/application_service/r0.1.2#put-matrix-client-r0-directory-list-appservice-networkid-roomid) 2 | 3 | use ruma_api::ruma_api; 4 | use ruma_identifiers::RoomId; 5 | 6 | use crate::r0::room::Visibility; 7 | 8 | ruma_api! { 9 | metadata { 10 | description: "Updates the visibility of a given room on the application service's room directory.", 11 | method: PUT, 12 | name: "set_room_visibility", 13 | path: "/_matrix/client/r0/directory/list/appservice/:network_id/:room_id", 14 | rate_limited: false, 15 | requires_authentication: true, 16 | } 17 | 18 | request { 19 | /// The protocol (network) ID to update the room list for. 20 | #[ruma_api(path)] 21 | pub network_id: String, 22 | /// The room ID to add to the directory. 23 | #[ruma_api(path)] 24 | pub room_id: RoomId, 25 | /// Whether the room should be visible (public) in the directory or not (private). 26 | pub visibility: Visibility, 27 | } 28 | 29 | response {} 30 | 31 | error: crate::Error 32 | } 33 | -------------------------------------------------------------------------------- /src/r0/state/get_state_events.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/client/r0/rooms/{roomId}/state](https://matrix.org/docs/spec/client_server/r0.4.0.html#get-matrix-client-r0-rooms-roomid-state) 2 | 3 | use ruma_api::ruma_api; 4 | use ruma_events::{collections::all::StateEvent, EventResult}; 5 | use ruma_identifiers::RoomId; 6 | 7 | ruma_api! { 8 | metadata { 9 | description: "Get state events for a room.", 10 | method: GET, 11 | name: "get_state_events", 12 | path: "/_matrix/client/r0/rooms/:room_id/state", 13 | rate_limited: false, 14 | requires_authentication: true, 15 | } 16 | 17 | request { 18 | /// The room to look up the state for. 19 | #[ruma_api(path)] 20 | pub room_id: RoomId, 21 | } 22 | 23 | response { 24 | /// If the user is a member of the room this will be the current state of the room as a 25 | /// list of events. If the user has left the room then this will be the state of the 26 | /// room when they left as a list of events. 27 | #[ruma_api(body)] 28 | #[wrap_incoming(StateEvent with EventResult)] 29 | pub room_state: Vec, 30 | } 31 | 32 | error: crate::Error 33 | } 34 | -------------------------------------------------------------------------------- /src/r0/state/create_state_event_for_empty_key.rs: -------------------------------------------------------------------------------- 1 | //! [PUT /_matrix/client/r0/rooms/{roomId}/state/{eventType}](https://matrix.org/docs/spec/client_server/r0.4.0.html#put-matrix-client-r0-rooms-roomid-state-eventtype) 2 | 3 | use ruma_api::ruma_api; 4 | use ruma_events::EventType; 5 | use ruma_identifiers::{EventId, RoomId}; 6 | use serde_json::Value; 7 | 8 | ruma_api! { 9 | metadata { 10 | description: "Send a state event to a room associated with the empty state key.", 11 | method: PUT, 12 | name: "create_state_event_for_empty_key", 13 | path: "/_matrix/client/r0/rooms/:room_id/state/:event_type", 14 | rate_limited: false, 15 | requires_authentication: true, 16 | } 17 | 18 | request { 19 | /// The room to set the state in. 20 | #[ruma_api(path)] 21 | pub room_id: RoomId, 22 | /// The type of event to send. 23 | #[ruma_api(path)] 24 | pub event_type: EventType, 25 | /// The event's content. 26 | #[ruma_api(body)] 27 | pub data: Value, 28 | } 29 | 30 | response { 31 | /// A unique identifier for the event. 32 | pub event_id: EventId, 33 | } 34 | 35 | error: crate::Error 36 | } 37 | -------------------------------------------------------------------------------- /src/r0/push/set_pushrule_actions.rs: -------------------------------------------------------------------------------- 1 | //! [PUT /_matrix/client/r0/pushrules/{scope}/{kind}/{ruleId}/actions](https://matrix.org/docs/spec/client_server/r0.6.0#put-matrix-client-r0-pushrules-scope-kind-ruleid-actions) 2 | 3 | use ruma_api::ruma_api; 4 | 5 | use super::{Action, RuleKind}; 6 | 7 | ruma_api! { 8 | metadata { 9 | description: "This endpoint allows clients to change the actions of a push rule. This can be used to change the actions of builtin rules.", 10 | method: PUT, 11 | name: "set_pushrule_actions", 12 | path: "/_matrix/client/r0/pushrules/:scope/:kind/:rule_id/actions", 13 | rate_limited: false, 14 | requires_authentication: true, 15 | } 16 | 17 | request { 18 | /// The scope to fetch a rule from. 'global' to specify global rules. 19 | #[ruma_api(path)] 20 | pub scope: String, 21 | 22 | /// The kind of rule 23 | #[ruma_api(path)] 24 | pub kind: RuleKind, 25 | 26 | /// The identifier for the rule. 27 | #[ruma_api(path)] 28 | pub rule_id: String, 29 | 30 | /// The actions to perform for this rule 31 | pub actions: Vec 32 | } 33 | 34 | response {} 35 | 36 | error: crate::Error 37 | } 38 | -------------------------------------------------------------------------------- /src/r0/thirdparty/get_user_for_protocol.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/client/r0/thirdparty/user/{protocol}](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-thirdparty-user-protocol) 2 | 3 | use std::collections::HashMap; 4 | 5 | use ruma_api::ruma_api; 6 | 7 | use super::User; 8 | 9 | ruma_api! { 10 | metadata { 11 | description: "Fetches third party users for a protocol.", 12 | method: GET, 13 | name: "get_user_for_protocol", 14 | path: "/_matrix/client/r0/thirdparty/user/:protocol", 15 | rate_limited: false, 16 | requires_authentication: true, 17 | } 18 | 19 | request { 20 | /// The protocol used to communicate to the third party network. 21 | #[ruma_api(path)] 22 | pub protocol: String, 23 | /// One or more custom fields that are passed to the AS to help identify the user. 24 | // The specification is incorrect for this parameter. See matrix-org/matrix-doc#2352. 25 | #[ruma_api(query_map)] 26 | pub fields: HashMap, 27 | } 28 | 29 | response { 30 | /// List of matched third party users. 31 | #[ruma_api(body)] 32 | pub users: Vec, 33 | } 34 | 35 | error: crate::Error 36 | } 37 | -------------------------------------------------------------------------------- /src/r0/membership/join_room_by_id_or_alias.rs: -------------------------------------------------------------------------------- 1 | //! [POST /_matrix/client/r0/join/{roomIdOrAlias}](https://matrix.org/docs/spec/client_server/r0.4.0.html#post-matrix-client-r0-join-roomidoralias) 2 | 3 | use ruma_api::ruma_api; 4 | use ruma_identifiers::{RoomId, RoomIdOrAliasId}; 5 | 6 | use super::ThirdPartySigned; 7 | 8 | ruma_api! { 9 | metadata { 10 | description: "Join a room using its ID or one of its aliases.", 11 | method: POST, 12 | name: "join_room_by_id_or_alias", 13 | path: "/_matrix/client/r0/join/:room_id_or_alias", 14 | rate_limited: true, 15 | requires_authentication: true, 16 | } 17 | 18 | request { 19 | /// The room where the user should be invited. 20 | #[ruma_api(path)] 21 | pub room_id_or_alias: RoomIdOrAliasId, 22 | /// The signature of a `m.third_party_invite` token to prove that this user owns a third 23 | /// party identity which has been invited to the room. 24 | #[serde(skip_serializing_if = "Option::is_none")] 25 | pub third_party_signed: Option, 26 | } 27 | 28 | response { 29 | /// The room that the user joined. 30 | pub room_id: RoomId, 31 | } 32 | 33 | error: crate::Error 34 | } 35 | -------------------------------------------------------------------------------- /src/r0/state/get_state_events_for_key.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/client/r0/rooms/{roomId}/state/{eventType}/{stateKey}](https://matrix.org/docs/spec/client_server/r0.4.0.html#get-matrix-client-r0-rooms-roomid-state-eventtype-state-key) 2 | 3 | use ruma_api::ruma_api; 4 | use ruma_events::EventType; 5 | use ruma_identifiers::RoomId; 6 | use serde_json::Value; 7 | 8 | ruma_api! { 9 | metadata { 10 | description: "Get state events associated with a given key.", 11 | method: GET, 12 | name: "get_state_events_for_key", 13 | path: "/_matrix/client/r0/rooms/:room_id/state/:event_type/:state_key", 14 | rate_limited: false, 15 | requires_authentication: true, 16 | } 17 | 18 | request { 19 | /// The room to look up the state for. 20 | #[ruma_api(path)] 21 | pub room_id: RoomId, 22 | /// The type of state to look up. 23 | #[ruma_api(path)] 24 | pub event_type: EventType, 25 | /// The key of the state to look up. 26 | #[ruma_api(path)] 27 | pub state_key: String, 28 | } 29 | 30 | response { 31 | /// The content of the state event. 32 | #[ruma_api(body)] 33 | pub content: Value, 34 | } 35 | 36 | error: crate::Error 37 | } 38 | -------------------------------------------------------------------------------- /src/r0/config/set_global_account_data.rs: -------------------------------------------------------------------------------- 1 | //! [PUT /_matrix/client/r0/user/{userId}/account_data/{type}](https://matrix.org/docs/spec/client_server/r0.4.0.html#put-matrix-client-r0-user-userid-account-data-type) 2 | 3 | use ruma_api::ruma_api; 4 | use ruma_identifiers::UserId; 5 | use serde_json::Value; 6 | 7 | ruma_api! { 8 | metadata { 9 | description: "Sets global account data.", 10 | method: PUT, 11 | name: "set_global_account_data", 12 | path: "/_matrix/client/r0/user/:user_id/account_data/:event_type", 13 | rate_limited: false, 14 | requires_authentication: true, 15 | } 16 | 17 | request { 18 | /// Arbitrary JSON to store as config data. 19 | #[ruma_api(body)] 20 | pub data: Value, 21 | /// The event type of the account_data to set. 22 | /// 23 | /// Custom types should be namespaced to avoid clashes. 24 | #[ruma_api(path)] 25 | pub event_type: String, 26 | /// The ID of the user to set account_data for. 27 | /// 28 | /// The access token must be authorized to make requests for this user ID. 29 | #[ruma_api(path)] 30 | pub user_id: UserId, 31 | } 32 | 33 | response {} 34 | 35 | error: crate::Error 36 | } 37 | -------------------------------------------------------------------------------- /src/r0/thirdparty/get_location_for_protocol.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/client/r0/thirdparty/location/{protocol}](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-thirdparty-location-protocol) 2 | 3 | use std::collections::HashMap; 4 | 5 | use ruma_api::ruma_api; 6 | 7 | use super::Location; 8 | 9 | ruma_api! { 10 | metadata { 11 | description: "Fetches third party locations for a protocol.", 12 | method: GET, 13 | name: "get_location_for_protocol", 14 | path: "/_matrix/client/r0/thirdparty/location/:protocol", 15 | rate_limited: false, 16 | requires_authentication: true, 17 | } 18 | 19 | request { 20 | /// The protocol used to communicate to the third party network. 21 | #[ruma_api(path)] 22 | pub protocol: String, 23 | /// One or more custom fields to help identify the third party location. 24 | // The specification is incorrect for this parameter. See matrix-org/matrix-doc#2352. 25 | #[ruma_api(query_map)] 26 | pub fields: HashMap, 27 | } 28 | 29 | response { 30 | /// List of matched third party locations. 31 | #[ruma_api(body)] 32 | pub locations: Vec, 33 | } 34 | 35 | error: crate::Error 36 | } 37 | -------------------------------------------------------------------------------- /src/r0/contact/request_contact_verification_token.rs: -------------------------------------------------------------------------------- 1 | //! [POST /_matrix/client/r0/account/3pid/email/requestToken](https://matrix.org/docs/spec/client_server/r0.4.0.html#post-matrix-client-r0-account-3pid-email-requesttoken) 2 | 3 | use js_int::UInt; 4 | use ruma_api::ruma_api; 5 | 6 | ruma_api! { 7 | metadata { 8 | description: "Ask for a verification token for a given 3rd party ID.", 9 | method: POST, 10 | name: "request_contact_verification_token", 11 | path: "/_matrix/client/r0/account/3pid/email/requestToken", 12 | rate_limited: false, 13 | requires_authentication: false, 14 | } 15 | 16 | request { 17 | /// Client-generated secret string used to protect this session. 18 | pub client_secret: String, 19 | /// The email address. 20 | pub email: String, 21 | /// The ID server to send the onward request to as a hostname with an appended colon and port number if the port is not the default. 22 | #[serde(skip_serializing_if = "Option::is_none")] 23 | pub id_server: Option, 24 | /// Used to distinguish protocol level retries from requests to re-send the email. 25 | pub send_attempt: UInt, 26 | } 27 | 28 | response {} 29 | 30 | error: crate::Error 31 | } 32 | -------------------------------------------------------------------------------- /src/r0/config/get_room_account_data.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/client/r0/user/{userId}/rooms/{roomId}/account_data/{type}](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-user-userid-rooms-roomid-account-data-type) 2 | 3 | use ruma_api::ruma_api; 4 | use ruma_events::{collections::only, EventResult}; 5 | use ruma_identifiers::{RoomId, UserId}; 6 | 7 | ruma_api! { 8 | metadata { 9 | description: "Gets account data room for a user for a given room", 10 | name: "get_room_account_data", 11 | method: GET, 12 | path: "/_matrix/client/r0/user/:user_id/rooms/:room_id/account_data/:event_type", 13 | rate_limited: false, 14 | requires_authentication: true, 15 | } 16 | 17 | request { 18 | /// User ID of user for whom to retrieve data. 19 | #[ruma_api(path)] 20 | pub user_id: UserId, 21 | /// Room ID for which to retrieve data. 22 | #[ruma_api(path)] 23 | pub room_id: RoomId, 24 | /// Type of data to retrieve. 25 | #[ruma_api(path)] 26 | pub event_type: String, 27 | } 28 | 29 | response { 30 | /// Account data content for the given type. 31 | #[ruma_api(body)] 32 | #[wrap_incoming(with EventResult)] 33 | pub account_data: only::Event, 34 | } 35 | 36 | error: crate::Error 37 | } 38 | -------------------------------------------------------------------------------- /src/r0/typing/create_typing_event.rs: -------------------------------------------------------------------------------- 1 | //! [PUT /_matrix/client/r0/rooms/{roomId}/typing/{userId}](https://matrix.org/docs/spec/client_server/r0.4.0.html#put-matrix-client-r0-rooms-roomid-typing-userid) 2 | 3 | use std::time::Duration; 4 | 5 | use ruma_api::ruma_api; 6 | use ruma_identifiers::{RoomId, UserId}; 7 | 8 | ruma_api! { 9 | metadata { 10 | method: PUT, 11 | path: "/_matrix/client/r0/rooms/:room_id/typing/:user_id", 12 | name: "create_typing_event", 13 | description: "Send a typing event to a room.", 14 | requires_authentication: true, 15 | rate_limited: true, 16 | } 17 | 18 | request { 19 | /// The room in which the user is typing. 20 | #[ruma_api(path)] 21 | pub room_id: RoomId, 22 | /// The length of time in milliseconds to mark this user as typing. 23 | #[serde( 24 | with = "crate::serde::duration::opt_ms", 25 | default, 26 | skip_serializing_if = "Option::is_none", 27 | )] 28 | pub timeout: Option, 29 | /// Whether the user is typing or not. If `false`, the `timeout` key can be omitted. 30 | pub typing: bool, 31 | /// The user who has started to type. 32 | #[ruma_api(path)] 33 | pub user_id: UserId, 34 | } 35 | 36 | response {} 37 | 38 | error: crate::Error 39 | } 40 | -------------------------------------------------------------------------------- /src/r0/keys/upload_keys.rs: -------------------------------------------------------------------------------- 1 | //! [POST /_matrix/client/r0/keys/upload](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-keys-upload) 2 | 3 | use std::collections::HashMap; 4 | 5 | use js_int::UInt; 6 | use ruma_api::ruma_api; 7 | 8 | use super::{AlgorithmAndDeviceId, DeviceKeys, KeyAlgorithm, OneTimeKey}; 9 | 10 | ruma_api! { 11 | metadata { 12 | description: "Publishes end-to-end encryption keys for the device.", 13 | method: POST, 14 | name: "upload_keys", 15 | path: "/_matrix/client/r0/keys/upload", 16 | rate_limited: false, 17 | requires_authentication: true, 18 | } 19 | 20 | request { 21 | /// Identity keys for the device. May be absent if no new identity keys are required. 22 | #[serde(skip_serializing_if = "Option::is_none")] 23 | pub device_keys: Option, 24 | 25 | /// One-time public keys for "pre-key" messages. 26 | #[serde(skip_serializing_if = "Option::is_none")] 27 | pub one_time_keys: Option>, 28 | } 29 | 30 | response { 31 | /// For each key algorithm, the number of unclaimed one-time keys of that 32 | /// type currently held on the server for this device. 33 | pub one_time_key_counts: HashMap 34 | } 35 | 36 | error: crate::Error 37 | } 38 | -------------------------------------------------------------------------------- /src/r0/state/create_state_event_for_key.rs: -------------------------------------------------------------------------------- 1 | //! [PUT /_matrix/client/r0/rooms/{roomId}/state/{eventType}/{stateKey}](https://matrix.org/docs/spec/client_server/r0.4.0.html#put-matrix-client-r0-rooms-roomid-state-eventtype-statekey) 2 | 3 | use ruma_api::ruma_api; 4 | use ruma_events::EventType; 5 | use ruma_identifiers::{EventId, RoomId}; 6 | use serde_json::Value; 7 | 8 | ruma_api! { 9 | metadata { 10 | description: "Send a state event to a room associated with a given state key.", 11 | method: PUT, 12 | name: "create_state_event_for_key", 13 | path: "/_matrix/client/r0/rooms/:room_id/state/:event_type/:state_key", 14 | rate_limited: false, 15 | requires_authentication: true, 16 | } 17 | 18 | request { 19 | /// The room to set the state in. 20 | #[ruma_api(path)] 21 | pub room_id: RoomId, 22 | /// The type of event to send. 23 | #[ruma_api(path)] 24 | pub event_type: EventType, 25 | /// The state_key for the state to send. Defaults to the empty string. 26 | #[ruma_api(path)] 27 | pub state_key: String, 28 | /// The event's content. 29 | #[ruma_api(body)] 30 | pub data: Value, 31 | } 32 | 33 | response { 34 | /// A unique identifier for the event. 35 | pub event_id: EventId, 36 | } 37 | 38 | error: crate::Error 39 | } 40 | -------------------------------------------------------------------------------- /src/r0/read_marker/set_read_marker.rs: -------------------------------------------------------------------------------- 1 | //! [POST /_matrix/client/r0/rooms/{roomId}/read_markers](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-rooms-roomid-read-markers) 2 | 3 | use ruma_api::ruma_api; 4 | use ruma_identifiers::{EventId, RoomId}; 5 | 6 | ruma_api! { 7 | metadata { 8 | description: "Sets the position of the read marker for a given room, and optionally the read receipt's location.", 9 | method: POST, 10 | name: "set_read_marker", 11 | path: "/_matrix/client/r0/rooms/:room_id/read_markers", 12 | rate_limited: true, 13 | requires_authentication: true, 14 | } 15 | 16 | request { 17 | /// The room ID to set the read marker in for the user. 18 | #[ruma_api(path)] 19 | pub room_id: RoomId, 20 | 21 | /// The event ID the read marker should be located at. 22 | /// The event MUST belong to the room. 23 | #[serde(rename = "m.fully_read")] 24 | pub fully_read: EventId, 25 | 26 | /// The event ID to set the read receipt location at. 27 | /// This is equivalent to calling the create_read_receipt endpoint and is 28 | /// provided here to save that extra call. 29 | #[serde(rename = "m.read", skip_serializing_if = "Option::is_none")] 30 | pub read_receipt: Option, 31 | 32 | } 33 | 34 | response {} 35 | 36 | error: crate::Error 37 | } 38 | -------------------------------------------------------------------------------- /src/r0/keys/get_key_changes.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/client/r0/keys/changes](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-keys-changes) 2 | 3 | use ruma_api::ruma_api; 4 | use ruma_identifiers::UserId; 5 | 6 | ruma_api! { 7 | metadata { 8 | description: "Gets a list of users who have updated their device identity keys since a previous sync token.", 9 | method: GET, 10 | name: "get_key_changes", 11 | path: "/_matrix/client/r0/keys/changes", 12 | rate_limited: false, 13 | requires_authentication: true, 14 | } 15 | 16 | request { 17 | /// The desired start point of the list. 18 | /// Should be the next_batch field from a response to an earlier call to /sync. 19 | #[ruma_api(query)] 20 | pub from: String, 21 | 22 | /// The desired end point of the list. 23 | /// Should be the next_batch field from a recent call to /sync - typically the most recent such call. 24 | #[ruma_api(query)] 25 | pub to: String, 26 | } 27 | 28 | response { 29 | /// The Matrix User IDs of all users who updated their device identity keys. 30 | pub changed: Vec, 31 | 32 | /// The Matrix User IDs of all users who may have left all the end-to-end 33 | /// encrypted rooms they previously shared with the user. 34 | pub left: Vec 35 | } 36 | 37 | error: crate::Error 38 | } 39 | -------------------------------------------------------------------------------- /src/r0/config/set_room_account_data.rs: -------------------------------------------------------------------------------- 1 | //! [PUT /_matrix/client/r0/user/{userId}/rooms/{roomId}/account_data/{type}](https://matrix.org/docs/spec/client_server/r0.4.0.html#put-matrix-client-r0-user-userid-rooms-roomid-account-data-type) 2 | 3 | use ruma_api::ruma_api; 4 | use ruma_identifiers::{RoomId, UserId}; 5 | use serde_json::Value; 6 | 7 | ruma_api! { 8 | metadata { 9 | description: "Associate account data with a room.", 10 | method: PUT, 11 | name: "set_room_account_data", 12 | path: "/_matrix/client/r0/user/:user_id/rooms/:room_id/account_data/:event_type", 13 | rate_limited: false, 14 | requires_authentication: true, 15 | } 16 | 17 | request { 18 | /// Arbitrary JSON to store as config data. 19 | #[ruma_api(body)] 20 | pub data: Value, 21 | /// The event type of the account_data to set. 22 | /// 23 | /// Custom types should be namespaced to avoid clashes. 24 | #[ruma_api(path)] 25 | pub event_type: String, 26 | /// The ID of the room to set account_data on. 27 | #[ruma_api(path)] 28 | pub room_id: RoomId, 29 | /// The ID of the user to set account_data for. 30 | /// 31 | /// The access token must be authorized to make requests for this user ID. 32 | #[ruma_api(path)] 33 | pub user_id: UserId, 34 | } 35 | 36 | response {} 37 | 38 | error: crate::Error 39 | } 40 | -------------------------------------------------------------------------------- /src/r0/client_exchange/send_event_to_device.rs: -------------------------------------------------------------------------------- 1 | //! [PUT /_matrix/client/r0/sendToDevice/{eventType}/{txnId}](https://matrix.org/docs/spec/client_server/r0.6.0#put-matrix-client-r0-sendtodevice-eventtype-txnid) 2 | 3 | use std::collections::HashMap; 4 | 5 | use ruma_api::ruma_api; 6 | use ruma_events::{collections::all, EventResult}; 7 | use ruma_identifiers::UserId; 8 | 9 | use super::DeviceIdOrAllDevices; 10 | 11 | ruma_api! { 12 | metadata { 13 | description: "Send an event to a device or devices.", 14 | method: PUT, 15 | name: "send_event_to_device", 16 | path: "/_matrix/client/r0/sendToDevice/:event_type/:txn_id", 17 | rate_limited: false, 18 | requires_authentication: true, 19 | } 20 | 21 | request { 22 | /// Type of event being sent to each device. 23 | #[ruma_api(path)] 24 | pub event_type: String, 25 | /// A request identifier unique to the access token used to send the request. 26 | #[ruma_api(path)] 27 | pub txn_id: String, 28 | /// A map of users to devices to a message event to be sent to the user's 29 | /// device. Individual message events can be sent to devices, but all 30 | /// events must be of the same type. 31 | #[wrap_incoming(all::Event with EventResult)] 32 | pub messages: HashMap> 33 | } 34 | 35 | response {} 36 | 37 | error: crate::Error 38 | } 39 | -------------------------------------------------------------------------------- /src/r0/redact/redact_event.rs: -------------------------------------------------------------------------------- 1 | //! [PUT /_matrix/client/r0/rooms/{roomId}/redact/{eventId}/{txnId}](https://matrix.org/docs/spec/client_server/r0.4.0.html#put-matrix-client-r0-rooms-roomid-redact-eventid-txnid) 2 | 3 | use ruma_api::ruma_api; 4 | use ruma_identifiers::{EventId, RoomId}; 5 | 6 | ruma_api! { 7 | metadata { 8 | description: "Redact an event, stripping all information not critical to the event graph integrity.", 9 | method: PUT, 10 | name: "redact_event", 11 | path: "/_matrix/client/r0/rooms/:room_id/redact/:event_id/:txn_id", 12 | rate_limited: false, 13 | requires_authentication: true, 14 | } 15 | 16 | request { 17 | /// The ID of the event to redact. 18 | #[ruma_api(path)] 19 | pub event_id: EventId, 20 | /// The reason for the redaction. 21 | #[serde(skip_serializing_if = "Option::is_none")] 22 | pub reason: Option, 23 | /// The ID of the room of the event to redact. 24 | #[ruma_api(path)] 25 | pub room_id: RoomId, 26 | /// The transaction ID for this event. 27 | /// 28 | /// Clients should generate a unique ID; it will be used by the server to ensure idempotency of requests. 29 | #[ruma_api(path)] 30 | pub txn_id: String, 31 | } 32 | 33 | response { 34 | /// The ID of the redacted event. 35 | pub event_id: EventId, 36 | } 37 | 38 | error: crate::Error 39 | } 40 | -------------------------------------------------------------------------------- /src/r0/session/get_login_types.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/client/r0/login](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-login) 2 | 3 | use ruma_api::ruma_api; 4 | use serde::{Deserialize, Serialize}; 5 | 6 | ruma_api! { 7 | metadata { 8 | description: "Gets the homeserver's supported login types to authenticate users. Clients should pick one of these and supply it as the type when logging in.", 9 | method: GET, 10 | name: "get_login_types", 11 | path: "/_matrix/client/r0/login", 12 | rate_limited: true, 13 | requires_authentication: false, 14 | } 15 | 16 | request {} 17 | 18 | response { 19 | /// The homeserver's supported login types. 20 | pub flows: Vec 21 | } 22 | 23 | error: crate::Error 24 | } 25 | 26 | /// An authentication mechanism. 27 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Deserialize, Serialize)] 28 | #[serde(tag = "type")] 29 | pub enum LoginType { 30 | /// A password is supplied to authenticate. 31 | #[serde(rename = "m.login.password")] 32 | Password, 33 | /// Token-based login. 34 | #[serde(rename = "m.login.token")] 35 | Token, 36 | } 37 | 38 | #[cfg(test)] 39 | mod tests { 40 | use super::LoginType; 41 | 42 | #[test] 43 | fn deserialize_login_type() { 44 | assert_eq!( 45 | serde_json::from_str::(r#" {"type": "m.login.password"} "#).unwrap(), 46 | LoginType::Password, 47 | ); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/r0/membership/joined_members.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/client/r0/rooms/{roomId}/joined_members](https://matrix.org/docs/spec/client_server/r0.4.0.html#get-matrix-client-r0-rooms-roomid-joined-members) 2 | 3 | use std::collections::HashMap; 4 | 5 | use ruma_api::ruma_api; 6 | use ruma_identifiers::{RoomId, UserId}; 7 | use serde::{Deserialize, Serialize}; 8 | 9 | ruma_api! { 10 | metadata { 11 | description: "Get a map of user ids to member info objects for members of the room. Primarily for use in Application Services.", 12 | method: GET, 13 | name: "joined_members", 14 | path: "/_matrix/client/r0/rooms/:room_id/joined_members", 15 | rate_limited: false, 16 | requires_authentication: true, 17 | } 18 | 19 | request { 20 | /// The room to get the members of. 21 | #[ruma_api(path)] 22 | pub room_id: RoomId, 23 | } 24 | 25 | response { 26 | /// A list of the rooms the user is in, i.e. 27 | /// the ID of each room in which the user has joined membership. 28 | pub joined: HashMap, 29 | } 30 | 31 | error: crate::Error 32 | } 33 | 34 | // TODO: Find out whether display_name and avatar_url are optional 35 | /// Information about a room member. 36 | #[derive(Clone, Debug, Deserialize, Serialize)] 37 | pub struct RoomMember { 38 | /// The display name of the user. 39 | pub display_name: String, 40 | /// The mxc avatar url of the user. 41 | pub avatar_url: Option, 42 | } 43 | -------------------------------------------------------------------------------- /src/r0/account/request_openid_token.rs: -------------------------------------------------------------------------------- 1 | //! [POST /_matrix/client/r0/user/{userId}/openid/request_token](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-user-userid-openid-request-token) 2 | 3 | use std::time::Duration; 4 | 5 | use ruma_api::ruma_api; 6 | use ruma_identifiers::UserId; 7 | use serde::{Deserialize, Serialize}; 8 | 9 | ruma_api! { 10 | metadata { 11 | description: "Request an OpenID 1.0 token to verify identity with a third party.", 12 | name: "request_openid_token", 13 | method: POST, 14 | path: "/_matrix/client/r0/user/:user_id/openid/request_token", 15 | rate_limited: true, 16 | requires_authentication: true, 17 | } 18 | 19 | request { 20 | /// User ID of authenticated user. 21 | #[ruma_api(path)] 22 | pub user_id: UserId, 23 | } 24 | 25 | response { 26 | /// Access token for verifying user's identity. 27 | pub access_token: String, 28 | /// Access token type. 29 | pub token_type: TokenType, 30 | /// Homeserver domain for verification of user's identity. 31 | pub matrix_server_name: String, 32 | /// Seconds until token expiration. 33 | #[serde(with = "crate::serde::duration::secs")] 34 | pub expires_in: Duration, 35 | } 36 | 37 | error: crate::Error 38 | } 39 | 40 | /// Access token types. 41 | #[derive(Clone, Copy, Debug, Deserialize, Serialize)] 42 | pub enum TokenType { 43 | /// Bearer token type 44 | Bearer, 45 | } 46 | -------------------------------------------------------------------------------- /src/r0/receipt/create_receipt.rs: -------------------------------------------------------------------------------- 1 | //! [POST /_matrix/client/r0/rooms/{roomId}/receipt/{receiptType}/{eventId}](https://matrix.org/docs/spec/client_server/r0.4.0.html#post-matrix-client-r0-rooms-roomid-receipt-receipttype-eventid) 2 | 3 | use std::convert::TryFrom; 4 | 5 | use ruma_api::ruma_api; 6 | use ruma_identifiers::{EventId, RoomId}; 7 | use strum::{Display, EnumString}; 8 | 9 | ruma_api! { 10 | metadata { 11 | description: "Send a receipt event to a room.", 12 | method: POST, 13 | name: "create_receipt", 14 | path: "/_matrix/client/r0/rooms/:room_id/receipt/:receipt_type/:event_id", 15 | rate_limited: true, 16 | requires_authentication: true, 17 | } 18 | 19 | request { 20 | /// The event ID to acknowledge up to. 21 | #[ruma_api(path)] 22 | pub event_id: EventId, 23 | /// The type of receipt to send. 24 | #[ruma_api(path)] 25 | pub receipt_type: ReceiptType, 26 | /// The room in which to send the event. 27 | #[ruma_api(path)] 28 | pub room_id: RoomId, 29 | } 30 | 31 | response {} 32 | 33 | error: crate::Error 34 | } 35 | 36 | /// The type of receipt. 37 | #[derive(Clone, Copy, Debug, Display, EnumString)] 38 | pub enum ReceiptType { 39 | /// m.read 40 | #[strum(serialize = "m.read")] 41 | Read, 42 | } 43 | 44 | impl TryFrom<&'_ str> for ReceiptType { 45 | type Error = strum::ParseError; 46 | 47 | fn try_from(s: &str) -> Result { 48 | s.parse() 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/unversioned/discover_homeserver.rs: -------------------------------------------------------------------------------- 1 | //! [GET /.well-known/matrix/client](https://matrix.org/docs/spec/client_server/r0.4.0.html#get-well-known-matrix-client) 2 | 3 | use ruma_api::ruma_api; 4 | use serde::{Deserialize, Serialize}; 5 | use url::Url; 6 | 7 | /// Information about a discovered homeserver. 8 | #[derive(Clone, Debug, Deserialize, Hash, PartialEq, PartialOrd, Serialize)] 9 | pub struct HomeserverInfo { 10 | /// The base URL for the homeserver for client-server connections. 11 | pub base_url: Url, 12 | } 13 | 14 | /// Information about a discovered identity server. 15 | #[derive(Clone, Debug, Deserialize, Hash, PartialEq, PartialOrd, Serialize)] 16 | pub struct IdentityServerInfo { 17 | /// The base URL for the identity server for client-server connections. 18 | pub base_url: Url, 19 | } 20 | 21 | ruma_api! { 22 | metadata { 23 | description: "Get discovery information about the domain.", 24 | method: GET, 25 | name: "discover_homeserver", 26 | path: "/.well-known/matrix/client", 27 | rate_limited: false, 28 | requires_authentication: false, 29 | } 30 | 31 | request {} 32 | 33 | response { 34 | /// Information about the homeserver to connect to. 35 | #[serde(rename = "m.homeserver")] 36 | pub homeserver: HomeserverInfo, 37 | 38 | /// Information about the identity server to connect to. 39 | #[serde(rename = "m.identity_server")] 40 | pub identity_server: Option, 41 | } 42 | 43 | error: crate::Error 44 | } 45 | -------------------------------------------------------------------------------- /src/r0/media/get_content.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/media/r0/download/{serverName}/{mediaId}](https://matrix.org/docs/spec/client_server/r0.6.0.html#get-matrix-media-r0-download-servername-mediaid) 2 | 3 | use ruma_api::ruma_api; 4 | 5 | ruma_api! { 6 | metadata { 7 | description: "Retrieve content from the media store.", 8 | method: GET, 9 | name: "get_media_content", 10 | path: "/_matrix/media/r0/download/:server_name/:media_id", 11 | rate_limited: false, 12 | requires_authentication: false, 13 | } 14 | 15 | request { 16 | /// The media ID from the mxc:// URI (the path component). 17 | #[ruma_api(path)] 18 | pub media_id: String, 19 | /// The server name from the mxc:// URI (the authoritory component). 20 | #[ruma_api(path)] 21 | pub server_name: String, 22 | /// Whether to fetch media deemed remote. 23 | /// Used to prevent routing loops. Defaults to `true`. 24 | #[ruma_api(query)] 25 | pub allow_remote: Option, 26 | } 27 | 28 | response { 29 | /// The content that was previously uploaded. 30 | #[ruma_api(raw_body)] 31 | pub file: Vec, 32 | /// The content type of the file that was previously uploaded. 33 | #[ruma_api(header = CONTENT_TYPE)] 34 | pub content_type: String, 35 | /// The name of the file that was previously uploaded, if set. 36 | #[ruma_api(header = CONTENT_DISPOSITION)] 37 | pub content_disposition: String, 38 | } 39 | 40 | error: crate::Error 41 | } 42 | -------------------------------------------------------------------------------- /src/r0/directory.rs: -------------------------------------------------------------------------------- 1 | //! Endpoints for the public room directory. 2 | 3 | pub mod get_public_rooms; 4 | pub mod get_public_rooms_filtered; 5 | 6 | use js_int::UInt; 7 | use ruma_identifiers::{RoomAliasId, RoomId}; 8 | use serde::{Deserialize, Serialize}; 9 | 10 | /// A chunk of a room list response, describing one room 11 | #[derive(Clone, Debug, Deserialize, Serialize)] 12 | pub struct PublicRoomsChunk { 13 | /// Aliases of the room. 14 | #[serde(skip_serializing_if = "Option::is_none")] 15 | pub aliases: Option>, 16 | /// The canonical alias of the room, if any. 17 | #[serde(skip_serializing_if = "Option::is_none")] 18 | pub canonical_alias: Option, 19 | /// The name of the room, if any. 20 | #[serde(skip_serializing_if = "Option::is_none")] 21 | pub name: Option, 22 | /// The number of members joined to the room. 23 | pub num_joined_members: UInt, 24 | /// The ID of the room. 25 | pub room_id: RoomId, 26 | /// The topic of the room, if any. 27 | #[serde(skip_serializing_if = "Option::is_none")] 28 | pub topic: Option, 29 | /// Whether the room may be viewed by guest users without joining. 30 | pub world_readable: bool, 31 | /// Whether guest users may join the room and participate in it. 32 | /// 33 | /// If they can, they will be subject to ordinary power level rules like any other user. 34 | pub guest_can_join: bool, 35 | /// The URL for the room's avatar, if one is set. 36 | #[serde(skip_serializing_if = "Option::is_none")] 37 | pub avatar_url: Option, 38 | } 39 | -------------------------------------------------------------------------------- /src/r0/message/create_message_event.rs: -------------------------------------------------------------------------------- 1 | //! [PUT /_matrix/client/r0/rooms/{roomId}/send/{eventType}/{txnId}](https://matrix.org/docs/spec/client_server/r0.4.0.html#put-matrix-client-r0-rooms-roomid-send-eventtype-txnid) 2 | 3 | use ruma_api::ruma_api; 4 | use ruma_events::{room::message::MessageEventContent, EventResult, EventType}; 5 | use ruma_identifiers::{EventId, RoomId}; 6 | 7 | ruma_api! { 8 | metadata { 9 | description: "Send a message event to a room.", 10 | method: PUT, 11 | name: "create_message_event", 12 | path: "/_matrix/client/r0/rooms/:room_id/send/:event_type/:txn_id", 13 | rate_limited: false, 14 | requires_authentication: true, 15 | } 16 | 17 | request { 18 | /// The room to send the event to. 19 | #[ruma_api(path)] 20 | pub room_id: RoomId, 21 | /// The type of event to send. 22 | #[ruma_api(path)] 23 | pub event_type: EventType, 24 | /// The transaction ID for this event. 25 | /// 26 | /// Clients should generate an ID unique across requests with the 27 | /// same access token; it will be used by the server to ensure 28 | /// idempotency of requests. 29 | #[ruma_api(path)] 30 | pub txn_id: String, 31 | /// The event's content. 32 | #[ruma_api(body)] 33 | #[wrap_incoming(with EventResult)] 34 | pub data: MessageEventContent, 35 | } 36 | 37 | response { 38 | /// A unique identifier for the event. 39 | pub event_id: EventId, 40 | } 41 | 42 | error: crate::Error 43 | } 44 | -------------------------------------------------------------------------------- /src/r0/presence/get_presence.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/client/r0/presence/{userId}/status](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-presence-userid-status) 2 | 3 | use std::time::Duration; 4 | 5 | use ruma_api::ruma_api; 6 | use ruma_events::presence::PresenceState; 7 | use ruma_identifiers::UserId; 8 | 9 | ruma_api! { 10 | metadata { 11 | description: "Get presence status for this user.", 12 | method: GET, 13 | name: "get_presence", 14 | path: "/_matrix/client/r0/presence/:user_id/status", 15 | rate_limited: false, 16 | requires_authentication: true, 17 | } 18 | 19 | request { 20 | /// The user whose presence state will be retrieved. 21 | #[ruma_api(path)] 22 | pub user_id: UserId, 23 | } 24 | 25 | response { 26 | /// The state message for this user if one was set. 27 | #[serde(skip_serializing_if = "Option::is_none")] 28 | pub status_msg: Option, 29 | /// Whether or not the user is currently active. 30 | #[serde(skip_serializing_if = "Option::is_none")] 31 | pub currently_active: Option, 32 | /// The length of time in milliseconds since an action was performed by the user. 33 | #[serde( 34 | with = "crate::serde::duration::opt_ms", 35 | default, 36 | skip_serializing_if = "Option::is_none", 37 | )] 38 | pub last_active_ago: Option, 39 | /// The user's presence state. 40 | pub presence: PresenceState, 41 | } 42 | 43 | error: crate::Error 44 | } 45 | -------------------------------------------------------------------------------- /src/r0/membership.rs: -------------------------------------------------------------------------------- 1 | //! Endpoints for room membership. 2 | 3 | pub mod ban_user; 4 | pub mod forget_room; 5 | pub mod get_member_events; 6 | pub mod invite_user; 7 | pub mod join_room_by_id; 8 | pub mod join_room_by_id_or_alias; 9 | pub mod joined_members; 10 | pub mod joined_rooms; 11 | pub mod kick_user; 12 | pub mod leave_room; 13 | pub mod unban_user; 14 | 15 | use std::collections::HashMap; 16 | 17 | use serde::{Deserialize, Serialize}; 18 | 19 | use crate::r0::thirdparty::Medium; 20 | 21 | /// A signature of an `m.third_party_invite` token to prove that this user owns a third party 22 | /// identity which has been invited to the room. 23 | #[derive(Clone, Debug, Deserialize, Serialize)] 24 | pub struct ThirdPartySigned { 25 | /// The Matrix ID of the invitee. 26 | pub mxid: String, 27 | /// The Matrix ID of the user who issued the invite. 28 | pub sender: String, 29 | /// A signatures object containing a signature of the entire signed object. 30 | pub signatures: HashMap>, 31 | /// The state key of the m.third_party_invite event. 32 | pub token: String, 33 | } 34 | 35 | /// Represents third party IDs to invite to the room. 36 | #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] 37 | pub struct Invite3pid { 38 | /// Hostname and port of identity server to be used for account lookups. 39 | pub id_server: String, 40 | /// An access token registered with the identity server. 41 | pub id_access_token: String, 42 | /// Type of third party ID. 43 | pub medium: Medium, 44 | /// Third party identifier. 45 | pub address: String, 46 | } 47 | -------------------------------------------------------------------------------- /src/r0/account/request_password_change_token_via_msisdn.rs: -------------------------------------------------------------------------------- 1 | //! [POST /_matrix/client/r0/account/password/msisdn/requestToken](https://matrix.org/docs/spec/client_server/r0.6.0.html#post-matrix-client-r0-account-password-msisdn-requesttoken) 2 | 3 | use js_int::UInt; 4 | use ruma_api::ruma_api; 5 | 6 | ruma_api! { 7 | metadata { 8 | description: "Request that a password change token is sent to the given phone number.", 9 | method: POST, 10 | name: "request_password_change_token_via_msisdn", 11 | path: "/_matrix/client/r0/account/password/msisdn/requestToken", 12 | rate_limited: false, 13 | requires_authentication: false, 14 | } 15 | 16 | request { 17 | /// Client-generated secret string used to protect this session. 18 | pub client_secret: String, 19 | /// Two-letter ISO 3166 country code for the phone number. 20 | pub country: String, 21 | /// Phone number to validate. 22 | pub phone_number: String, 23 | /// Used to distinguish protocol level retries from requests to re-send the SMS. 24 | pub send_attempt: UInt, 25 | /// Return URL for identity server to redirect the client back to. 26 | #[serde(skip_serializing_if = "Option::is_none")] 27 | pub next_link: Option, 28 | } 29 | 30 | response { 31 | /// The session identifier given by the identity server. 32 | pub sid: String, 33 | /// URL to submit validation token to. If omitted, verification happens without client. 34 | #[serde(skip_serializing_if = "Option::is_none")] 35 | pub submit_url: Option 36 | } 37 | 38 | error: crate::Error 39 | } 40 | -------------------------------------------------------------------------------- /src/r0/keys/claim_keys.rs: -------------------------------------------------------------------------------- 1 | //! [POST /_matrix/client/r0/keys/claim](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-keys-claim) 2 | 3 | use std::collections::HashMap; 4 | 5 | use std::time::Duration; 6 | 7 | use ruma_api::ruma_api; 8 | use ruma_identifiers::{DeviceId, UserId}; 9 | use serde_json::Value; 10 | 11 | use super::{AlgorithmAndDeviceId, KeyAlgorithm, OneTimeKey}; 12 | 13 | ruma_api! { 14 | metadata { 15 | description: "Claims one-time keys for use in pre-key messages.", 16 | method: POST, 17 | name: "claim_keys", 18 | path: "/_matrix/client/r0/keys/claim", 19 | rate_limited: false, 20 | requires_authentication: true, 21 | } 22 | 23 | request { 24 | /// The time (in milliseconds) to wait when downloading keys from remote servers. 25 | /// 10 seconds is the recommended default. 26 | #[serde( 27 | with = "crate::serde::duration::opt_ms", 28 | default, 29 | skip_serializing_if = "Option::is_none", 30 | )] 31 | pub timeout: Option, 32 | 33 | /// The keys to be claimed. 34 | pub one_time_keys: HashMap>, 35 | } 36 | 37 | response { 38 | /// If any remote homeservers could not be reached, they are recorded here. 39 | /// The names of the properties are the names of the unreachable servers. 40 | pub failures: HashMap, 41 | 42 | /// One-time keys for the queried devices. 43 | pub one_time_keys: HashMap>>, 44 | } 45 | 46 | error: crate::Error 47 | } 48 | -------------------------------------------------------------------------------- /src/r0/user_directory/search_users.rs: -------------------------------------------------------------------------------- 1 | //! [POST /_matrix/client/r0/user_directory/search](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-user-directory-search) 2 | 3 | use js_int::UInt; 4 | use ruma_api::ruma_api; 5 | use ruma_identifiers::UserId; 6 | use serde::{Deserialize, Serialize}; 7 | 8 | ruma_api! { 9 | metadata { 10 | description: "Performs a search for users on the homeserver.", 11 | method: POST, 12 | name: "search_users", 13 | path: "/_matrix/client/r0/user_directory/search", 14 | rate_limited: true, 15 | requires_authentication: true, 16 | } 17 | 18 | request { 19 | /// The term to search for. 20 | pub search_term: String, 21 | /// The maximum number of results to return. 22 | /// 23 | /// Defaults to 10. 24 | #[serde(skip_serializing_if = "Option::is_none")] 25 | pub limit: Option, 26 | } 27 | 28 | response { 29 | /// Ordered by rank and then whether or not profile info is available. 30 | pub results: Vec, 31 | /// Indicates if the result list has been truncated by the limit. 32 | pub limited: bool, 33 | } 34 | 35 | error: crate::Error 36 | } 37 | 38 | /// User data as result of a search. 39 | #[derive(Clone, Debug, Deserialize, Serialize)] 40 | pub struct User { 41 | /// The user's matrix user ID. 42 | pub user_id: UserId, 43 | /// The display name of the user, if one exists. 44 | #[serde(skip_serializing_if = "Option::is_none")] 45 | pub display_name: Option, 46 | /// The avatar url, as an MXC, if one exists. 47 | #[serde(skip_serializing_if = "Option::is_none")] 48 | pub avatar_url: Option, 49 | } 50 | -------------------------------------------------------------------------------- /src/r0/directory/get_public_rooms.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/client/r0/publicRooms](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-publicrooms) 2 | 3 | use js_int::UInt; 4 | use ruma_api::ruma_api; 5 | 6 | use super::PublicRoomsChunk; 7 | 8 | ruma_api! { 9 | metadata { 10 | description: "Get the list of rooms in this homeserver's public directory.", 11 | method: GET, 12 | name: "get_public_rooms", 13 | path: "/_matrix/client/r0/publicRooms", 14 | rate_limited: false, 15 | requires_authentication: false, 16 | } 17 | 18 | request { 19 | /// Limit for the number of results to return. 20 | #[serde(skip_serializing_if = "Option::is_none")] 21 | #[ruma_api(query)] 22 | pub limit: Option, 23 | /// Pagination token from a previous request. 24 | #[serde(skip_serializing_if = "Option::is_none")] 25 | #[ruma_api(query)] 26 | pub since: Option, 27 | /// The server to fetch the public room lists from. 28 | /// 29 | /// `None` means the server this request is sent to. 30 | #[serde(skip_serializing_if = "Option::is_none")] 31 | #[ruma_api(query)] 32 | pub server: Option, 33 | } 34 | 35 | response { 36 | /// A paginated chunk of public rooms. 37 | pub chunk: Vec, 38 | /// A pagination token for the response. 39 | pub next_batch: Option, 40 | /// A pagination token that allows fetching previous results. 41 | pub prev_batch: Option, 42 | /// An estimate on the total number of public rooms, if the server has an estimate. 43 | pub total_room_count_estimate: Option, 44 | } 45 | 46 | error: crate::Error 47 | } 48 | -------------------------------------------------------------------------------- /src/r0/media/get_content_as_filename.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/media/r0/download/{serverName}/{mediaId}/{fileName}](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-media-r0-download-servername-mediaid-filename) 2 | 3 | use ruma_api::ruma_api; 4 | 5 | ruma_api! { 6 | metadata { 7 | description: "Retrieve content from the media store, specifying a filename to return.", 8 | method: GET, 9 | name: "get_media_content_as_filename", 10 | path: "/_matrix/media/r0/download/:server_name/:media_id/:filename", 11 | rate_limited: false, 12 | requires_authentication: false, 13 | } 14 | 15 | request { 16 | /// The media ID from the mxc:// URI (the path component). 17 | #[ruma_api(path)] 18 | pub media_id: String, 19 | /// The server name from the mxc:// URI (the authoritory component). 20 | #[ruma_api(path)] 21 | pub server_name: String, 22 | /// The filename to return in the `Content-Disposition` header. 23 | #[ruma_api(path)] 24 | pub filename: String, 25 | /// Whether to fetch media deemed remote. 26 | /// Used to prevent routing loops. Defaults to `true`. 27 | #[ruma_api(query)] 28 | pub allow_remote: Option, 29 | } 30 | 31 | response { 32 | /// The content that was previously uploaded. 33 | #[ruma_api(raw_body)] 34 | pub file: Vec, 35 | /// The content type of the file that was previously uploaded. 36 | #[ruma_api(header = CONTENT_TYPE)] 37 | pub content_type: String, 38 | /// The name of the file that was previously uploaded, if set. 39 | #[ruma_api(header = CONTENT_DISPOSITION)] 40 | pub content_disposition: String, 41 | } 42 | 43 | error: crate::Error 44 | } 45 | -------------------------------------------------------------------------------- /src/r0/account/request_registration_token_via_email.rs: -------------------------------------------------------------------------------- 1 | //! [POST /_matrix/client/r0/register/email/requestToken](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-register-email-requesttoken) 2 | 3 | use js_int::UInt; 4 | use ruma_api::ruma_api; 5 | 6 | use super::IdentityServerInfo; 7 | 8 | ruma_api! { 9 | metadata { 10 | description: "Request a registration token with a 3rd party email.", 11 | method: POST, 12 | name: "request_registration_token_via_email", 13 | path: "/_matrix/client/r0/register/email/requestToken", 14 | rate_limited: false, 15 | requires_authentication: false, 16 | } 17 | 18 | request { 19 | /// Client-generated secret string used to protect this session. 20 | pub client_secret: String, 21 | /// The email address. 22 | pub email: String, 23 | /// Used to distinguish protocol level retries from requests to re-send the email. 24 | pub send_attempt: UInt, 25 | /// Return URL for identity server to redirect the client back to. 26 | #[serde(skip_serializing_if = "Option::is_none")] 27 | pub next_link: Option, 28 | /// Optional identity server hostname and access token. Deprecated since r0.6.0. 29 | #[serde(flatten)] 30 | #[serde(skip_serializing_if = "Option::is_none")] 31 | pub identity_server_info: Option, 32 | } 33 | 34 | response { 35 | /// The session identifier given by the identity server. 36 | pub sid: String, 37 | /// URL to submit validation token to. If omitted, verification happens without client. 38 | #[serde(skip_serializing_if = "Option::is_none")] 39 | pub submit_url: Option 40 | } 41 | 42 | error: crate::Error 43 | } 44 | -------------------------------------------------------------------------------- /src/r0/account/request_3pid_management_token_via_email.rs: -------------------------------------------------------------------------------- 1 | //! [POST /_matrix/client/r0/account/3pid/email/requestToken](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-account-3pid-email-requesttoken) 2 | 3 | use js_int::UInt; 4 | use ruma_api::ruma_api; 5 | 6 | use super::IdentityServerInfo; 7 | 8 | ruma_api! { 9 | metadata { 10 | description: "Request a 3PID management token with a 3rd party email.", 11 | method: POST, 12 | name: "request_3pid_association_token_via_email", 13 | path: "/_matrix/client/r0/account/3pid/email/requestToken", 14 | rate_limited: false, 15 | requires_authentication: false, 16 | } 17 | 18 | request { 19 | /// Client-generated secret string used to protect this session. 20 | pub client_secret: String, 21 | /// The email address. 22 | pub email: String, 23 | /// Used to distinguish protocol level retries from requests to re-send the email. 24 | pub send_attempt: UInt, 25 | /// Return URL for identity server to redirect the client back to. 26 | #[serde(skip_serializing_if = "Option::is_none")] 27 | pub next_link: Option, 28 | /// Optional identity server hostname and access token. Deprecated since r0.6.0. 29 | #[serde(flatten)] 30 | #[serde(skip_serializing_if = "Option::is_none")] 31 | pub identity_server_info: Option, 32 | } 33 | 34 | response { 35 | /// The session identifier given by the identity server. 36 | pub sid: String, 37 | /// URL to submit validation token to. If omitted, verification happens without client. 38 | #[serde(skip_serializing_if = "Option::is_none")] 39 | pub submit_url: Option 40 | } 41 | 42 | error: crate::Error 43 | } 44 | -------------------------------------------------------------------------------- /src/r0/account/request_password_change_token_via_email.rs: -------------------------------------------------------------------------------- 1 | //! [POST /_matrix/client/r0/account/password/email/requestToken](https://matrix.org/docs/spec/client_server/r0.6.0.html#post-matrix-client-r0-account-password-email-requesttoken) 2 | 3 | use js_int::UInt; 4 | use ruma_api::ruma_api; 5 | 6 | use super::IdentityServerInfo; 7 | 8 | ruma_api! { 9 | metadata { 10 | description: "Request that a password change token is sent to the given email address.", 11 | method: POST, 12 | name: "request_password_change_token_via_email", 13 | path: "/_matrix/client/r0/account/password/email/requestToken", 14 | rate_limited: false, 15 | requires_authentication: false, 16 | } 17 | 18 | request { 19 | /// Client-generated secret string used to protect this session. 20 | pub client_secret: String, 21 | /// The email address. 22 | pub email: String, 23 | /// Used to distinguish protocol level retries from requests to re-send the email. 24 | pub send_attempt: UInt, 25 | /// Return URL for identity server to redirect the client back to. 26 | #[serde(skip_serializing_if = "Option::is_none")] 27 | pub next_link: Option, 28 | /// Optional identity server hostname and access token. Deprecated since r0.6.0. 29 | #[serde(flatten)] 30 | #[serde(skip_serializing_if = "Option::is_none")] 31 | pub identity_server_info: Option, 32 | } 33 | 34 | response { 35 | /// The session identifier given by the identity server. 36 | pub sid: String, 37 | /// URL to submit validation token to. If omitted, verification happens without client. 38 | #[serde(skip_serializing_if = "Option::is_none")] 39 | pub submit_url: Option 40 | } 41 | 42 | error: crate::Error 43 | } 44 | -------------------------------------------------------------------------------- /src/r0/account/request_registration_token_via_msisdn.rs: -------------------------------------------------------------------------------- 1 | //! [POST /_matrix/client/r0/register/msisdn/requestToken](https://matrix.org/docs/spec/client_server/r0.6.0.html#post-matrix-client-r0-register-msisdn-requesttoken) 2 | 3 | use js_int::UInt; 4 | use ruma_api::ruma_api; 5 | 6 | use super::IdentityServerInfo; 7 | 8 | ruma_api! { 9 | metadata { 10 | description: "Request a registration token with a phone number.", 11 | method: POST, 12 | name: "request_registration_token_via_msisdn", 13 | path: "/_matrix/client/r0/register/msisdn/requestToken", 14 | rate_limited: false, 15 | requires_authentication: false, 16 | } 17 | 18 | request { 19 | /// Client-generated secret string used to protect this session. 20 | pub client_secret: String, 21 | /// Two-letter ISO 3166 country code for the phone number. 22 | pub country: String, 23 | /// Phone number to validate. 24 | pub phone_number: String, 25 | /// Return URL for identity server to redirect the client back to. 26 | #[serde(skip_serializing_if = "Option::is_none")] 27 | pub next_link: Option, 28 | /// Used to distinguish protocol level retries from requests to re-send the SMS. 29 | pub send_attempt: UInt, 30 | /// Optional identity server hostname and access token. Deprecated since r0.6.0. 31 | #[serde(flatten)] 32 | #[serde(skip_serializing_if = "Option::is_none")] 33 | pub identity_server_info: Option, 34 | } 35 | 36 | response { 37 | /// The session identifier given by the identity server. 38 | pub sid: String, 39 | /// URL to submit validation token to. If omitted, verification happens without client. 40 | #[serde(skip_serializing_if = "Option::is_none")] 41 | pub submit_url: Option 42 | } 43 | 44 | error: crate::Error 45 | } 46 | -------------------------------------------------------------------------------- /src/r0/account/request_3pid_management_token_via_msisdn.rs: -------------------------------------------------------------------------------- 1 | //! [POST /_matrix/client/r0/account/3pid/msisdn/requestToken](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-account-3pid-msisdn-requesttoken) 2 | 3 | use js_int::UInt; 4 | use ruma_api::ruma_api; 5 | 6 | use super::IdentityServerInfo; 7 | 8 | ruma_api! { 9 | metadata { 10 | description: "Request a 3PID management token with a phone number.", 11 | method: POST, 12 | name: "request_3pid_association_token_via_msisdn", 13 | path: "/_matrix/client/r0/account/3pid/msisdn/requestToken", 14 | rate_limited: false, 15 | requires_authentication: false, 16 | } 17 | 18 | request { 19 | /// Client-generated secret string used to protect this session. 20 | pub client_secret: String, 21 | /// Two-letter ISO 3166 country code for the phone number. 22 | pub country: String, 23 | /// Phone number to validate. 24 | pub phone_number: String, 25 | /// Used to distinguish protocol level retries from requests to re-send the SMS. 26 | pub send_attempt: UInt, 27 | /// Return URL for identity server to redirect the client back to. 28 | #[serde(skip_serializing_if = "Option::is_none")] 29 | pub next_link: Option, 30 | /// Optional identity server hostname and access token. Deprecated since r0.6.0. 31 | #[serde(flatten)] 32 | #[serde(skip_serializing_if = "Option::is_none")] 33 | pub identity_server_info: Option, 34 | } 35 | 36 | response { 37 | /// The session identifier given by the identity server. 38 | pub sid: String, 39 | /// URL to submit validation token to. If omitted, verification happens without client. 40 | #[serde(skip_serializing_if = "Option::is_none")] 41 | pub submit_url: Option 42 | } 43 | 44 | error: crate::Error 45 | } 46 | -------------------------------------------------------------------------------- /src/r0/server/get_user_info.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/client/r0/admin/whois/{userId}](https://matrix.org/docs/spec/client_server/r0.4.0.html#get-matrix-client-r0-admin-whois-userid) 2 | 3 | use std::collections::HashMap; 4 | 5 | use js_int::UInt; 6 | use ruma_api::ruma_api; 7 | use ruma_identifiers::UserId; 8 | use serde::{Deserialize, Serialize}; 9 | 10 | ruma_api! { 11 | metadata { 12 | description: "Get information about a particular user.", 13 | method: GET, 14 | name: "get_user_info", 15 | path: "/_matrix/client/r0/admin/whois/:user_id", 16 | rate_limited: false, 17 | requires_authentication: true, 18 | } 19 | 20 | request { 21 | /// The user to look up. 22 | #[ruma_api(path)] 23 | pub user_id: UserId, 24 | } 25 | 26 | response { 27 | /// The Matrix user ID of the user. 28 | pub user_id: UserId, 29 | /// A map of the user's device identifiers to information about that device. 30 | pub devices: HashMap, 31 | } 32 | 33 | error: crate::Error 34 | } 35 | 36 | /// Information about a connection in a user session. 37 | #[derive(Clone, Debug, Deserialize, Serialize)] 38 | pub struct ConnectionInfo { 39 | /// Most recently seen IP address of the session. 40 | pub ip: String, 41 | /// Unix timestamp that the session was last active. 42 | pub last_seen: UInt, 43 | /// User agent string last seen in the session. 44 | pub user_agent: String, 45 | } 46 | 47 | /// Information about a user's device. 48 | #[derive(Clone, Debug, Deserialize, Serialize)] 49 | pub struct DeviceInfo { 50 | /// A list of user sessions on this device. 51 | pub sessions: Vec, 52 | } 53 | 54 | /// Information about a user session. 55 | #[derive(Clone, Debug, Deserialize, Serialize)] 56 | pub struct SessionInfo { 57 | /// A list of connections in this session. 58 | pub connections: Vec, 59 | } 60 | -------------------------------------------------------------------------------- /src/r0/account.rs: -------------------------------------------------------------------------------- 1 | //! Endpoints for account registration and management. 2 | 3 | pub mod bind_3pid; 4 | pub mod change_password; 5 | pub mod deactivate; 6 | pub mod delete_3pid; 7 | pub mod get_username_availability; 8 | pub mod register; 9 | pub mod request_3pid_management_token_via_email; 10 | pub mod request_3pid_management_token_via_msisdn; 11 | pub mod request_openid_token; 12 | pub mod request_password_change_token_via_email; 13 | pub mod request_password_change_token_via_msisdn; 14 | pub mod request_registration_token_via_email; 15 | pub mod request_registration_token_via_msisdn; 16 | pub mod unbind_3pid; 17 | 18 | pub mod whoami; 19 | 20 | use serde::{Deserialize, Serialize}; 21 | 22 | /// Additional authentication information for the user-interactive authentication API. 23 | #[derive(Clone, Debug, Deserialize, Serialize)] 24 | pub struct AuthenticationData { 25 | /// The login type that the client is attempting to complete. 26 | #[serde(rename = "type")] 27 | pub kind: String, 28 | /// The value of the session key given by the homeserver. 29 | pub session: Option, 30 | } 31 | 32 | /// Additional authentication information for requestToken endpoints. 33 | #[derive(Clone, Debug, Deserialize, Serialize)] 34 | pub struct IdentityServerInfo { 35 | /// The ID server to send the onward request to as a hostname with an 36 | /// appended colon and port number if the port is not the default. 37 | pub id_server: String, 38 | /// Access token previously registered with identity server. 39 | pub id_access_token: String, 40 | } 41 | 42 | /// Possible values for deleting or unbinding 3PIDs 43 | #[derive(Clone, Copy, Debug, Deserialize, Serialize)] 44 | #[serde(rename_all = "kebab-case")] 45 | pub enum ThirdPartyIdRemovalStatus { 46 | /// Either the homeserver couldn't determine the right identity server to contact, or the 47 | /// identity server refused the operation. 48 | NoSupport, 49 | /// Success. 50 | Success, 51 | } 52 | -------------------------------------------------------------------------------- /src/r0/keys/get_keys.rs: -------------------------------------------------------------------------------- 1 | //! [POST /_matrix/client/r0/keys/query](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-keys-query) 2 | 3 | use std::{collections::HashMap, time::Duration}; 4 | 5 | use ruma_api::ruma_api; 6 | use ruma_identifiers::{DeviceId, UserId}; 7 | use serde_json::Value; 8 | 9 | use super::DeviceKeys; 10 | 11 | ruma_api! { 12 | metadata { 13 | description: "Returns the current devices and identity keys for the given users.", 14 | method: POST, 15 | name: "get_keys", 16 | path: "/_matrix/client/r0/keys/query", 17 | rate_limited: false, 18 | requires_authentication: true, 19 | } 20 | 21 | request { 22 | /// The time (in milliseconds) to wait when downloading keys from remote servers. 23 | /// 10 seconds is the recommended default. 24 | #[serde( 25 | with = "crate::serde::duration::opt_ms", 26 | default, 27 | skip_serializing_if = "Option::is_none", 28 | )] 29 | pub timeout: Option, 30 | 31 | /// The keys to be downloaded. An empty list indicates all devices for the corresponding user. 32 | pub device_keys: HashMap>, 33 | 34 | /// If the client is fetching keys as a result of a device update received in a sync request, 35 | /// this should be the 'since' token of that sync request, or any later sync token. 36 | /// This allows the server to ensure its response contains the keys advertised by the notification in that sync. 37 | #[serde(skip_serializing_if = "Option::is_none")] 38 | pub token: Option, 39 | } 40 | 41 | response { 42 | /// If any remote homeservers could not be reached, they are recorded here. 43 | /// The names of the properties are the names of the unreachable servers. 44 | pub failures: HashMap, 45 | 46 | /// Information on the queried devices. 47 | pub device_keys: HashMap>, 48 | } 49 | 50 | error: crate::Error 51 | } 52 | -------------------------------------------------------------------------------- /src/r0/push/set_pushrule.rs: -------------------------------------------------------------------------------- 1 | //! [PUT /_matrix/client/r0/pushrules/{scope}/{kind}/{ruleId}](https://matrix.org/docs/spec/client_server/r0.6.0#put-matrix-client-r0-pushrules-scope-kind-ruleid) 2 | 3 | use ruma_api::ruma_api; 4 | 5 | use super::{Action, PushCondition, RuleKind}; 6 | 7 | ruma_api! { 8 | metadata { 9 | description: "This endpoint allows the creation, modification and deletion of pushers for this user ID.", 10 | method: PUT, 11 | name: "set_pushrule", 12 | path: "/_matrix/client/r0/pushrules/:scope/:kind/:rule_id", 13 | rate_limited: true, 14 | requires_authentication: true, 15 | } 16 | 17 | request { 18 | /// The scope to set the rule in. 'global' to specify global rules. 19 | #[ruma_api(path)] 20 | pub scope: String, 21 | 22 | /// The kind of rule 23 | #[ruma_api(path)] 24 | pub kind: RuleKind, 25 | 26 | /// The identifier for the rule. 27 | #[ruma_api(path)] 28 | pub rule_id: String, 29 | 30 | /// Use 'before' with a rule_id as its value to make the new rule the next-most important rule with respect to the given user defined rule. 31 | #[ruma_api(query)] 32 | pub before: Option, 33 | 34 | /// This makes the new rule the next-less important rule relative to the given user defined rule. 35 | #[ruma_api(query)] 36 | pub after: Option, 37 | 38 | /// The actions to perform when this rule is matched. 39 | pub actions: Vec, 40 | 41 | /// The conditions that must hold true for an event in order for a rule to be applied to an event. A rule with no conditions always matches. 42 | /// Only applicable to underride and override rules, empty Vec otherwise. 43 | #[serde(default)] 44 | pub conditions: Vec, 45 | 46 | /// The glob-style pattern to match against. Only applicable to content rules. 47 | #[serde(skip_serializing_if = "Option::is_none")] 48 | pub pattern: Option, 49 | } 50 | 51 | response {} 52 | 53 | error: crate::Error 54 | } 55 | -------------------------------------------------------------------------------- /src/serde/duration/secs.rs: -------------------------------------------------------------------------------- 1 | //! De-/serialization functions for `Option` objects represented as milliseconds. 2 | //! Delegates to `js_int::UInt` to ensure integer size is within bounds. 3 | 4 | use std::{convert::TryFrom, time::Duration}; 5 | 6 | use js_int::UInt; 7 | use serde::{ 8 | de::{Deserialize, Deserializer}, 9 | ser::{Error, Serialize, Serializer}, 10 | }; 11 | 12 | /// Serializes a Duration to an integer representing seconds. 13 | /// Will fail if integer is greater than the maximum integer that can be 14 | /// unambiguously represented by an f64. 15 | pub fn serialize(duration: &Duration, serializer: S) -> Result 16 | where 17 | S: Serializer, 18 | { 19 | match UInt::try_from(duration.as_secs()) { 20 | Ok(uint) => uint.serialize(serializer), 21 | Err(err) => Err(S::Error::custom(err)), 22 | } 23 | } 24 | 25 | /// Deserializes an integer representing seconds into a Duration. 26 | /// Will fail if integer is greater than the maximum integer that can be 27 | /// unambiguously represented by an f64. 28 | pub fn deserialize<'de, D>(deserializer: D) -> Result 29 | where 30 | D: Deserializer<'de>, 31 | { 32 | UInt::deserialize(deserializer).map(|secs| Duration::from_secs(secs.into())) 33 | } 34 | 35 | #[cfg(test)] 36 | mod tests { 37 | use serde::{Deserialize, Serialize}; 38 | use serde_json::json; 39 | use std::time::Duration; 40 | 41 | #[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] 42 | struct DurationTest { 43 | #[serde(with = "crate::serde::duration::secs")] 44 | timeout: Duration, 45 | } 46 | 47 | #[test] 48 | fn test_deserialize_duration_as_seconds() { 49 | let json = json!({ "timeout": 3 }); 50 | 51 | assert_eq!( 52 | serde_json::from_value::(json).unwrap(), 53 | DurationTest { 54 | timeout: Duration::from_secs(3) 55 | }, 56 | ); 57 | } 58 | 59 | #[test] 60 | fn test_serialize_duration_as_seconds() { 61 | let test = DurationTest { 62 | timeout: Duration::from_millis(7000), 63 | }; 64 | assert_eq!(serde_json::to_value(test).unwrap(), json!({ "timeout": 7 }),); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/r0/directory/get_public_rooms_filtered.rs: -------------------------------------------------------------------------------- 1 | //! [POST /_matrix/client/r0/publicRooms](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-publicrooms) 2 | 3 | use js_int::UInt; 4 | use ruma_api::ruma_api; 5 | use serde::{Deserialize, Serialize}; 6 | 7 | use super::PublicRoomsChunk; 8 | 9 | ruma_api! { 10 | metadata { 11 | description: "Get the list of rooms in this homeserver's public directory.", 12 | method: POST, 13 | name: "get_public_rooms_filtered", 14 | path: "/_matrix/client/r0/publicRooms", 15 | rate_limited: false, 16 | requires_authentication: true, 17 | } 18 | 19 | request { 20 | /// The server to fetch the public room lists from. 21 | /// 22 | /// `None` means the server this request is sent to. 23 | #[serde(skip_serializing_if = "Option::is_none")] 24 | #[ruma_api(query)] 25 | pub server: Option, 26 | /// Limit for the number of results to return. 27 | #[serde(skip_serializing_if = "Option::is_none")] 28 | pub limit: Option, 29 | /// Pagination token from a previous request. 30 | #[serde(skip_serializing_if = "Option::is_none")] 31 | pub since: Option, 32 | /// Filter to apply to the results. 33 | #[serde(skip_serializing_if = "Option::is_none")] 34 | pub filter: Option, 35 | } 36 | 37 | response { 38 | /// A paginated chunk of public rooms. 39 | pub chunk: Vec, 40 | /// A pagination token for the response. 41 | pub next_batch: Option, 42 | /// A pagination token that allows fetching previous results. 43 | pub prev_batch: Option, 44 | /// An estimate on the total number of public rooms, if the server has an estimate. 45 | pub total_room_count_estimate: Option, 46 | } 47 | 48 | error: crate::Error 49 | } 50 | 51 | /// A filter for public rooms lists 52 | #[derive(Clone, Debug, Deserialize, Serialize)] 53 | pub struct Filter { 54 | /// A string to search for in the room metadata, e.g. name, topic, canonical alias etc. 55 | #[serde(skip_serializing_if = "Option::is_none")] 56 | pub generic_search_term: Option, 57 | } 58 | -------------------------------------------------------------------------------- /src/r0/media/get_content_thumbnail.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/media/r0/thumbnail/{serverName}/{mediaId}](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-media-r0-thumbnail-servername-mediaid) 2 | 3 | use js_int::UInt; 4 | use ruma_api::ruma_api; 5 | use serde::{Deserialize, Serialize}; 6 | 7 | /// The desired resizing method. 8 | #[derive(Clone, Copy, Debug, Deserialize, Serialize)] 9 | #[serde(rename_all = "snake_case")] 10 | pub enum Method { 11 | /// Crop the original to produce the requested image dimensions. 12 | Crop, 13 | /// Maintain the original aspect ratio of the source image. 14 | Scale, 15 | } 16 | 17 | ruma_api! { 18 | metadata { 19 | description: "Get a thumbnail of content from the media store.", 20 | method: GET, 21 | name: "get_content_thumbnail", 22 | path: "/_matrix/media/r0/thumbnail/:server_name/:media_id", 23 | rate_limited: true, 24 | requires_authentication: false, 25 | } 26 | 27 | request { 28 | /// Whether to fetch media deemed remote. 29 | /// 30 | /// Used to prevent routing loops. Defaults to `true`. 31 | #[ruma_api(query)] 32 | pub allow_remote: Option, 33 | /// The media ID from the mxc:// URI (the path component). 34 | #[ruma_api(path)] 35 | pub media_id: String, 36 | /// The server name from the mxc:// URI (the authoritory component). 37 | #[ruma_api(path)] 38 | pub server_name: String, 39 | /// The *desired* height of the thumbnail. The actual thumbnail may not match the size 40 | /// specified. 41 | #[ruma_api(query)] 42 | pub height: UInt, 43 | /// The desired resizing method. 44 | #[ruma_api(query)] 45 | pub method: Option, 46 | /// The *desired* width of the thumbnail. The actual thumbnail may not match the size 47 | /// specified. 48 | #[ruma_api(query)] 49 | pub width: UInt, 50 | } 51 | 52 | response { 53 | /// The content type of the thumbnail. 54 | #[ruma_api(header = CONTENT_TYPE)] 55 | pub content_type: String, 56 | /// A thumbnail of the requested content. 57 | #[ruma_api(body)] 58 | pub file: Vec, 59 | } 60 | 61 | error: crate::Error 62 | } 63 | -------------------------------------------------------------------------------- /src/r0/session/login/user_serde.rs: -------------------------------------------------------------------------------- 1 | //! Helper module for the Serialize / Deserialize impl's for the User struct 2 | //! in the parent module. 3 | 4 | use serde::{Deserialize, Serialize}; 5 | 6 | use super::Medium; 7 | 8 | // The following three structs could just be used in place of the one in the parent module, but 9 | // that one is arguably much easier to deal with. 10 | #[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] 11 | pub(crate) struct UserInfo<'a> { 12 | #[serde(borrow)] 13 | pub identifier: UserIdentifier<'a>, 14 | } 15 | 16 | #[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] 17 | #[serde(tag = "type")] 18 | pub(crate) enum UserIdentifier<'a> { 19 | #[serde(rename = "m.id.user")] 20 | MatrixId { user: &'a str }, 21 | #[serde(rename = "m.id.thirdparty")] 22 | ThirdPartyId { medium: Medium, address: &'a str }, 23 | #[serde(rename = "m.id.phone")] 24 | PhoneNumber { country: &'a str, phone: &'a str }, 25 | } 26 | 27 | impl<'a> From<&'a super::UserInfo> for UserInfo<'a> { 28 | fn from(su: &'a super::UserInfo) -> Self { 29 | use super::UserInfo::*; 30 | 31 | match su { 32 | MatrixId(user) => UserInfo { 33 | identifier: UserIdentifier::MatrixId { user }, 34 | }, 35 | ThirdPartyId { address, medium } => UserInfo { 36 | identifier: UserIdentifier::ThirdPartyId { 37 | address, 38 | medium: *medium, 39 | }, 40 | }, 41 | PhoneNumber { country, phone } => UserInfo { 42 | identifier: UserIdentifier::PhoneNumber { country, phone }, 43 | }, 44 | } 45 | } 46 | } 47 | 48 | impl Into for UserInfo<'_> { 49 | fn into(self) -> super::UserInfo { 50 | use super::UserInfo::*; 51 | 52 | match self.identifier { 53 | UserIdentifier::MatrixId { user } => MatrixId(user.to_owned()), 54 | UserIdentifier::ThirdPartyId { address, medium } => ThirdPartyId { 55 | address: address.to_owned(), 56 | medium: medium.to_owned(), 57 | }, 58 | UserIdentifier::PhoneNumber { country, phone } => PhoneNumber { 59 | country: country.to_owned(), 60 | phone: phone.to_owned(), 61 | }, 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/r0/client_exchange.rs: -------------------------------------------------------------------------------- 1 | //! Endpoints for client devices to exchange information not persisted in room DAG. 2 | 3 | use std::{ 4 | convert::TryFrom, 5 | fmt::{Display, Formatter, Result as FmtResult}, 6 | }; 7 | 8 | use ruma_identifiers::DeviceId; 9 | use serde::{ 10 | de::{self, Unexpected}, 11 | Deserialize, Deserializer, Serialize, Serializer, 12 | }; 13 | 14 | pub mod send_event_to_device; 15 | /// Represents one or all of a user's devices. 16 | #[derive(Clone, Debug, Hash, PartialEq, Eq)] 17 | pub enum DeviceIdOrAllDevices { 18 | /// Represents a device Id for one of a user's devices. 19 | DeviceId(DeviceId), 20 | /// Represents all devices for a user. 21 | AllDevices, 22 | } 23 | 24 | impl Display for DeviceIdOrAllDevices { 25 | fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { 26 | match self { 27 | DeviceIdOrAllDevices::DeviceId(device_id) => write!(f, "{}", device_id.to_string()), 28 | DeviceIdOrAllDevices::AllDevices => write!(f, "*"), 29 | } 30 | } 31 | } 32 | 33 | impl TryFrom<&str> for DeviceIdOrAllDevices { 34 | type Error = &'static str; 35 | fn try_from(device_id_or_all_devices: &str) -> Result { 36 | if device_id_or_all_devices.is_empty() { 37 | Err("Device identifier cannot be empty") 38 | } else if "*" == device_id_or_all_devices { 39 | Ok(DeviceIdOrAllDevices::AllDevices) 40 | } else { 41 | Ok(DeviceIdOrAllDevices::DeviceId( 42 | device_id_or_all_devices.to_string(), 43 | )) 44 | } 45 | } 46 | } 47 | 48 | impl Serialize for DeviceIdOrAllDevices { 49 | fn serialize(&self, serializer: S) -> Result 50 | where 51 | S: Serializer, 52 | { 53 | match self { 54 | Self::DeviceId(ref device_id) => serializer.serialize_str(&device_id), 55 | Self::AllDevices => serializer.serialize_str("*"), 56 | } 57 | } 58 | } 59 | 60 | impl<'de> Deserialize<'de> for DeviceIdOrAllDevices { 61 | fn deserialize(deserializer: D) -> Result 62 | where 63 | D: Deserializer<'de>, 64 | { 65 | let value = &String::deserialize(deserializer)?; 66 | 67 | DeviceIdOrAllDevices::try_from(&value[..]).map_err(|_| { 68 | de::Error::invalid_value(Unexpected::Str(&value), &"a valid device identifier or '*'") 69 | }) 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/r0/membership/get_member_events.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/client/r0/rooms/{roomId}/members](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-rooms-roomid-members) 2 | 3 | use ruma_api::ruma_api; 4 | use ruma_events::{room::member::MemberEvent, EventResult}; 5 | use ruma_identifiers::RoomId; 6 | use serde::{Deserialize, Serialize}; 7 | 8 | ruma_api! { 9 | metadata { 10 | description: "Get membership events for a room.", 11 | method: GET, 12 | name: "get_member_events", 13 | path: "/_matrix/client/r0/rooms/:room_id/members", 14 | rate_limited: false, 15 | requires_authentication: true, 16 | } 17 | 18 | request { 19 | /// The room to get the member events for. 20 | #[ruma_api(path)] 21 | pub room_id: RoomId, 22 | 23 | /// The point in time (pagination token) to return members for in the room. This token can 24 | /// be obtained from a prev_batch token returned for each room by the sync API. 25 | #[serde(skip_serializing_if = "Option::is_none")] 26 | #[ruma_api(query)] 27 | pub at: Option, 28 | 29 | /// The kind of memberships to filter for. Defaults to no filtering if unspecified. When 30 | /// specified alongside not_membership, the two parameters create an 'or' condition: either 31 | /// the membership is the same as membership or is not the same as not_membership. 32 | #[serde(skip_serializing_if = "Option::is_none")] 33 | #[ruma_api(query)] 34 | pub membership: Option, 35 | 36 | /// The kind of memberships to *exclude* from the results. Defaults to no filtering if 37 | /// unspecified. 38 | #[serde(skip_serializing_if = "Option::is_none")] 39 | #[ruma_api(query)] 40 | pub not_membership: Option, 41 | } 42 | 43 | response { 44 | /// A list of member events. 45 | #[wrap_incoming(MemberEvent with EventResult)] 46 | pub chunk: Vec 47 | } 48 | 49 | error: crate::Error 50 | } 51 | 52 | /// The kind of membership events to filter for. 53 | #[derive(Clone, Copy, Debug, Deserialize, Serialize)] 54 | #[serde(rename_all = "lowercase")] 55 | pub enum MembershipEventFilter { 56 | /// The user has joined. 57 | Join, 58 | /// The user has been invited. 59 | Invite, 60 | /// The user has left. 61 | Leave, 62 | /// The user has been banned. 63 | Ban, 64 | } 65 | -------------------------------------------------------------------------------- /src/r0/context/get_context.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/client/r0/rooms/{roomId}/context/{eventId}](https://matrix.org/docs/spec/client_server/r0.4.0.html#get-matrix-client-r0-rooms-roomid-context-eventid) 2 | 3 | use js_int::UInt; 4 | use ruma_api::ruma_api; 5 | use ruma_events::{collections::only, EventResult}; 6 | use ruma_identifiers::{EventId, RoomId}; 7 | 8 | use crate::r0::filter::RoomEventFilter; 9 | 10 | ruma_api! { 11 | metadata { 12 | description: "Get the events immediately preceding and following a given event.", 13 | method: GET, 14 | path: "/_matrix/client/r0/rooms/:room_id/context/:event_id", 15 | name: "get_context", 16 | rate_limited: false, 17 | requires_authentication: true, 18 | } 19 | 20 | request { 21 | /// The event to get context around. 22 | #[ruma_api(path)] 23 | pub event_id: EventId, 24 | /// The maximum number of events to return. 25 | /// 26 | /// Defaults to 10 if not supplied. 27 | #[ruma_api(query)] 28 | #[serde(skip_serializing_if = "Option::is_none")] 29 | pub limit: Option, 30 | /// The room to get events from. 31 | #[ruma_api(path)] 32 | pub room_id: RoomId, 33 | /// A RoomEventFilter to filter returned events with. 34 | #[serde(skip_serializing_if = "Option::is_none")] 35 | #[ruma_api(query)] 36 | pub filter: Option, 37 | } 38 | 39 | response { 40 | /// A token that can be used to paginate forwards with. 41 | pub end: String, 42 | /// Details of the requested event. 43 | #[wrap_incoming(with EventResult)] 44 | pub event: only::RoomEvent, 45 | /// A list of room events that happened just after the requested event, in chronological 46 | /// order. 47 | #[wrap_incoming(only::RoomEvent with EventResult)] 48 | pub events_after: Vec, 49 | /// A list of room events that happened just before the requested event, in 50 | /// reverse-chronological order. 51 | #[wrap_incoming(only::RoomEvent with EventResult)] 52 | pub events_before: Vec, 53 | /// A token that can be used to paginate backwards with. 54 | pub start: String, 55 | /// The state of the room at the last event returned. 56 | #[wrap_incoming(only::StateEvent with EventResult)] 57 | pub state: Vec, 58 | } 59 | 60 | error: crate::Error 61 | } 62 | -------------------------------------------------------------------------------- /src/r0/capabilities/get_capabilities.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/client/r0/capabilities](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-capabilities) 2 | 3 | use ruma_api::ruma_api; 4 | use serde::{Deserialize, Serialize}; 5 | use serde_json::Value; 6 | use std::collections::HashMap; 7 | 8 | ruma_api! { 9 | metadata { 10 | description: "Gets information about the server's supported feature set and other relevant capabilities.", 11 | method: GET, 12 | name: "get_capabilities", 13 | path: "/_matrix/client/r0/capabilities", 14 | rate_limited: true, 15 | requires_authentication: true 16 | } 17 | 18 | request {} 19 | 20 | response { 21 | /// The capabilities the server supports 22 | pub capabilities: Capabilities, 23 | } 24 | 25 | error: crate::Error 26 | } 27 | 28 | /// Contains information about all the capabilities that the server supports. 29 | #[derive(Clone, Debug, Serialize, Deserialize)] 30 | pub struct Capabilities { 31 | /// Capability to indicate if the user can change their password. 32 | #[serde(rename = "m.change_password", skip_serializing_if = "Option::is_none")] 33 | pub change_password: Option, 34 | 35 | /// The room versions the server supports. 36 | #[serde(rename = "m.room_versions", skip_serializing_if = "Option::is_none")] 37 | pub room_versions: Option, 38 | 39 | /// Any other custom capabilities that the server supports outside of the specification, 40 | /// labeled using the Java package naming convention and stored as arbitrary JSON values. 41 | #[serde(flatten)] 42 | pub custom_capabilities: HashMap, 43 | } 44 | 45 | /// Information about the m.change_password capability 46 | #[derive(Clone, Copy, Debug, Serialize, Deserialize)] 47 | pub struct ChangePasswordCapability { 48 | /// True if the user can change their password, false otherwise. 49 | pub enabled: bool, 50 | } 51 | 52 | /// Information about the m.room_versions capability 53 | #[derive(Clone, Debug, Serialize, Deserialize)] 54 | pub struct RoomVersionsCapability { 55 | /// The default room version the server is using for new rooms. 56 | pub default: String, 57 | 58 | /// A detailed description of the room versions the server supports. 59 | pub available: HashMap, 60 | } 61 | 62 | /// The stability of a room version 63 | #[derive(Clone, Copy, Debug, Serialize, Deserialize)] 64 | pub enum RoomVersionStability { 65 | /// An unstable room version 66 | #[serde(rename = "stable")] 67 | Stable, 68 | 69 | /// A stable room version 70 | #[serde(rename = "unstable")] 71 | Unstable, 72 | } 73 | -------------------------------------------------------------------------------- /src/r0/push/get_notifications.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/client/r0/notifications](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-notifications) 2 | 3 | use js_int::UInt; 4 | use ruma_api::{ruma_api, Outgoing}; 5 | use ruma_events::{collections::all, EventResult}; 6 | use ruma_identifiers::RoomId; 7 | use serde::Serialize; 8 | 9 | use super::Action; 10 | 11 | ruma_api! { 12 | metadata { 13 | description: "Paginate through the list of events that the user has been, or would have been notified about.", 14 | method: GET, 15 | name: "get_notifications", 16 | path: "/_matrix/client/r0/notifications", 17 | rate_limited: false, 18 | requires_authentication: true, 19 | } 20 | 21 | request { 22 | /// Pagination token given to retrieve the next set of events. 23 | #[ruma_api(query)] 24 | #[serde(skip_serializing_if = "Option::is_none")] 25 | pub from: Option, 26 | 27 | /// Limit on the number of events to return in this request. 28 | #[ruma_api(query)] 29 | #[serde(skip_serializing_if = "Option::is_none")] 30 | pub limit: Option, 31 | 32 | /// Allows basic filtering of events returned. Supply "highlight" to return only events where 33 | /// the notification had the 'highlight' tweak set. 34 | #[ruma_api(query)] 35 | #[serde(skip_serializing_if = "Option::is_none")] 36 | pub only: Option 37 | } 38 | 39 | response { 40 | /// The token to supply in the from param of the next /notifications request in order 41 | /// to request more events. If this is absent, there are no more results. 42 | #[serde(skip_serializing_if = "Option::is_none")] 43 | pub next_token: Option, 44 | 45 | 46 | /// The list of events that triggered notifications. 47 | #[wrap_incoming(Notification)] 48 | pub notifications: Vec, 49 | } 50 | 51 | error: crate::Error 52 | } 53 | 54 | /// Represents a notification 55 | #[derive(Clone, Debug, Serialize, Outgoing)] 56 | pub struct Notification { 57 | /// The actions to perform when the conditions for this rule are met. 58 | pub actions: Vec, 59 | 60 | /// The event that triggered the notification. 61 | #[wrap_incoming(with EventResult)] 62 | pub event: all::Event, 63 | 64 | /// The profile tag of the rule that matched this event. 65 | #[serde(skip_serializing_if = "Option::is_none")] 66 | pub profile_tag: Option, 67 | 68 | /// Indicates whether the user has sent a read receipt indicating that they have read this message. 69 | pub read: bool, 70 | 71 | /// The ID of the room in which the event was posted. 72 | pub room_id: RoomId, 73 | 74 | /// The unix timestamp at which the event notification was sent, in milliseconds. 75 | pub ts: UInt, 76 | } 77 | -------------------------------------------------------------------------------- /src/r0/message/get_message_events.rs: -------------------------------------------------------------------------------- 1 | //! [GET /_matrix/client/r0/rooms/{roomId}/messages](https://matrix.org/docs/spec/client_server/r0.4.0.html#get-matrix-client-r0-rooms-roomid-messages) 2 | 3 | use js_int::UInt; 4 | use ruma_api::ruma_api; 5 | use ruma_events::{collections::all::RoomEvent, EventResult}; 6 | use ruma_identifiers::RoomId; 7 | use serde::{Deserialize, Serialize}; 8 | 9 | use crate::r0::filter::RoomEventFilter; 10 | 11 | ruma_api! { 12 | metadata { 13 | description: "Get message events for a room.", 14 | method: GET, 15 | name: "get_message_events", 16 | path: "/_matrix/client/r0/rooms/:room_id/messages", 17 | rate_limited: false, 18 | requires_authentication: true, 19 | } 20 | 21 | request { 22 | /// The room to get events from. 23 | #[ruma_api(path)] 24 | pub room_id: RoomId, 25 | /// The token to start returning events from. 26 | /// 27 | /// This token can be obtained from a 28 | /// prev_batch token returned for each room by the sync API, or from a start or end token 29 | /// returned by a previous request to this endpoint. 30 | #[ruma_api(query)] 31 | pub from: String, 32 | /// The token to stop returning events at. 33 | /// 34 | /// This token can be obtained from a prev_batch 35 | /// token returned for each room by the sync endpoint, or from a start or end token returned 36 | /// by a previous request to this endpoint. 37 | #[serde(skip_serializing_if = "Option::is_none")] 38 | #[ruma_api(query)] 39 | pub to: Option, 40 | /// The direction to return events from. 41 | #[ruma_api(query)] 42 | pub dir: Direction, 43 | /// The maximum number of events to return. 44 | /// 45 | /// Default: 10. 46 | #[serde(skip_serializing_if = "Option::is_none")] 47 | #[ruma_api(query)] 48 | pub limit: Option, 49 | /// A RoomEventFilter to filter returned events with. 50 | #[serde(skip_serializing_if = "Option::is_none")] 51 | #[ruma_api(query)] 52 | pub filter: Option, 53 | } 54 | 55 | response { 56 | /// The token the pagination starts from. 57 | pub start: String, 58 | /// A list of room events. 59 | #[wrap_incoming(RoomEvent with EventResult)] 60 | pub chunk: Vec, 61 | /// The token the pagination ends at. 62 | pub end: String, 63 | } 64 | 65 | error: crate::Error 66 | } 67 | 68 | /// The direction to return events from. 69 | #[derive(Clone, Copy, Debug, Deserialize, Serialize)] 70 | pub enum Direction { 71 | /// Return events backwards in time from the requested `from` token. 72 | #[serde(rename = "b")] 73 | Backward, 74 | /// Return events forwards in time from the requested `from` token. 75 | #[serde(rename = "f")] 76 | Forward, 77 | } 78 | -------------------------------------------------------------------------------- /src/serde/duration/opt_ms.rs: -------------------------------------------------------------------------------- 1 | //! De-/serialization functions for `Option` objects represented as milliseconds. 2 | //! Delegates to `js_int::UInt` to ensure integer size is within bounds. 3 | 4 | use std::{convert::TryFrom, time::Duration}; 5 | 6 | use js_int::UInt; 7 | use serde::{ 8 | de::{Deserialize, Deserializer}, 9 | ser::{Error, Serialize, Serializer}, 10 | }; 11 | 12 | /// Serialize an Option. 13 | /// Will fail if integer is greater than the maximum integer that can be 14 | /// unambiguously represented by an f64. 15 | pub fn serialize(opt_duration: &Option, serializer: S) -> Result 16 | where 17 | S: Serializer, 18 | { 19 | match opt_duration { 20 | Some(duration) => match UInt::try_from(duration.as_millis()) { 21 | Ok(uint) => uint.serialize(serializer), 22 | Err(err) => Err(S::Error::custom(err)), 23 | }, 24 | None => serializer.serialize_none(), 25 | } 26 | } 27 | 28 | /// Deserializes an Option. 29 | /// Will fail if integer is greater than the maximum integer that can be 30 | /// unambiguously represented by an f64. 31 | pub fn deserialize<'de, D>(deserializer: D) -> Result, D::Error> 32 | where 33 | D: Deserializer<'de>, 34 | { 35 | Ok(Option::::deserialize(deserializer)? 36 | .map(|millis| Duration::from_millis(millis.into()))) 37 | } 38 | 39 | #[cfg(test)] 40 | mod tests { 41 | use serde::{Deserialize, Serialize}; 42 | use serde_json::json; 43 | use std::time::Duration; 44 | 45 | #[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] 46 | struct DurationTest { 47 | #[serde( 48 | with = "crate::serde::duration::opt_ms", 49 | default, 50 | skip_serializing_if = "Option::is_none" 51 | )] 52 | timeout: Option, 53 | } 54 | 55 | #[test] 56 | fn test_deserialize_some_duration_as_milliseconds() { 57 | let json = json!({ "timeout": 3000 }); 58 | 59 | assert_eq!( 60 | serde_json::from_value::(json).unwrap(), 61 | DurationTest { 62 | timeout: Some(Duration::from_millis(3000)) 63 | }, 64 | ); 65 | } 66 | 67 | #[test] 68 | fn test_deserialize_empty_duration_as_milliseconds() { 69 | let json = json!({}); 70 | 71 | assert_eq!( 72 | serde_json::from_value::(json).unwrap(), 73 | DurationTest { timeout: None }, 74 | ); 75 | } 76 | 77 | #[test] 78 | fn test_serialize_some_duration_as_milliseconds() { 79 | let request = DurationTest { 80 | timeout: Some(Duration::new(2, 0)), 81 | }; 82 | assert_eq!( 83 | serde_json::to_value(&request).unwrap(), 84 | json!({ "timeout": 2000 }) 85 | ); 86 | } 87 | 88 | #[test] 89 | fn test_serialize_empty_duration_as_milliseconds() { 90 | let request = DurationTest { timeout: None }; 91 | assert_eq!(serde_json::to_value(&request).unwrap(), json!({})); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/r0/membership/invite_user.rs: -------------------------------------------------------------------------------- 1 | //! [POST /_matrix/client/r0/rooms/{roomId}/invite][invite-by-user-id] 2 | //! 3 | //! This endpoint has two forms: one to invite a user 4 | //! [by their Matrix identifier][invite-by-user-id], and one to invite a user 5 | //! [by their third party identifier][invite-by-3pid]. 6 | //! 7 | //! [invite-by-user-id]: https://matrix.org/docs/spec/client_server/r0.6.0.html#post-matrix-client-r0-rooms-roomid-invite 8 | //! [invite-by-3pid]: https://matrix.org/docs/spec/client_server/r0.6.0#id101 9 | use ruma_api::ruma_api; 10 | use ruma_identifiers::{RoomId, UserId}; 11 | use serde::{Deserialize, Serialize}; 12 | 13 | use super::Invite3pid; 14 | 15 | ruma_api! { 16 | metadata { 17 | description: "Invite a user to a room.", 18 | method: POST, 19 | name: "invite_user", 20 | path: "/_matrix/client/r0/rooms/:room_id/invite", 21 | rate_limited: true, 22 | requires_authentication: true, 23 | } 24 | 25 | request { 26 | /// The room where the user should be invited. 27 | #[ruma_api(path)] 28 | pub room_id: RoomId, 29 | /// The user to invite. 30 | #[ruma_api(body)] 31 | pub recipient: InvitationRecipient, 32 | } 33 | 34 | response {} 35 | 36 | error: crate::Error 37 | } 38 | 39 | /// Distinguishes between invititations by Matrix or third party identifiers. 40 | #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] 41 | #[serde(untagged)] 42 | pub enum InvitationRecipient { 43 | /// Used to invite user by their Matrix identifer. 44 | UserId { 45 | /// Matrix identifier of user. 46 | user_id: UserId, 47 | }, 48 | /// Used to invite user by a third party identifer. 49 | ThirdPartyId(Invite3pid), 50 | } 51 | 52 | #[cfg(test)] 53 | mod tests { 54 | use super::InvitationRecipient; 55 | use crate::r0::{membership::Invite3pid, thirdparty::Medium}; 56 | use ruma_identifiers::UserId; 57 | use std::convert::TryFrom; 58 | #[test] 59 | fn deserialize_invite_by_user_id() { 60 | let incoming = 61 | serde_json::from_str::(r#" { "user_id": "@carl:example.org" } "#) 62 | .unwrap(); 63 | let user_id = UserId::try_from("@carl:example.org").unwrap(); 64 | let recipient = InvitationRecipient::UserId { user_id }; 65 | assert_eq!(incoming, recipient); 66 | } 67 | 68 | #[test] 69 | fn deserialize_invite_by_3pid() { 70 | let incoming = serde_json::from_str::( 71 | r#" 72 | { 73 | "id_server": "example.org", 74 | "id_access_token": "abcdefghijklmnop", 75 | "medium": "email", 76 | "address": "carl@example.org" 77 | } 78 | "#, 79 | ) 80 | .unwrap(); 81 | let recipient = InvitationRecipient::ThirdPartyId(Invite3pid { 82 | id_server: "example.org".to_string(), 83 | id_access_token: "abcdefghijklmnop".to_string(), 84 | medium: Medium::Email, 85 | address: "carl@example.org".to_string(), 86 | }); 87 | assert_eq!(incoming, recipient); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/r0/thirdparty.rs: -------------------------------------------------------------------------------- 1 | //! Endpoints for third party lookups 2 | 3 | pub mod get_location_for_protocol; 4 | pub mod get_location_for_room_alias; 5 | pub mod get_protocol; 6 | pub mod get_protocols; 7 | pub mod get_user_for_protocol; 8 | pub mod get_user_for_user_id; 9 | 10 | use std::collections::HashMap; 11 | 12 | use ruma_identifiers::{RoomAliasId, UserId}; 13 | 14 | use serde::{Deserialize, Serialize}; 15 | 16 | /// Metadata about a third party protocol. 17 | #[derive(Clone, Debug, Deserialize, Serialize)] 18 | pub struct Protocol { 19 | /// Fields which may be used to identify a third party user. 20 | pub user_fields: Vec, 21 | /// Fields which may be used to identify a third party location. 22 | pub location_fields: Vec, 23 | /// A content URI representing an icon for the third party protocol. 24 | pub icon: String, 25 | /// The type definitions for the fields defined in `user_fields` and `location_fields`. 26 | pub field_types: HashMap, 27 | /// A list of objects representing independent instances of configuration. 28 | pub instances: Vec, 29 | } 30 | 31 | /// Metadata about an instance of a third party protocol. 32 | #[derive(Clone, Debug, Deserialize, Serialize)] 33 | pub struct ProtocolInstance { 34 | /// A human-readable description for the protocol, such as the name. 35 | pub desc: String, 36 | /// An optional content URI representing the protocol. 37 | #[serde(skip_serializing_if = "Option::is_none")] 38 | pub icon: Option, 39 | /// Preset values for `fields` the client may use to search by. 40 | pub fields: HashMap, 41 | /// A unique identifier across all instances. 42 | pub network_id: String, 43 | } 44 | 45 | /// A type definition for a field used to identify third party users or locations. 46 | #[derive(Clone, Debug, Deserialize, Serialize)] 47 | pub struct FieldType { 48 | /// A regular expression for validation of a field's value. 49 | pub regexp: String, 50 | /// A placeholder serving as a valid example of the field value. 51 | pub placeholder: String, 52 | } 53 | 54 | /// A third party network location. 55 | #[derive(Clone, Debug, Deserialize, Serialize)] 56 | pub struct Location { 57 | /// An alias for a matrix room. 58 | pub alias: RoomAliasId, 59 | /// The protocol ID that the third party location is a part of. 60 | pub protocol: String, 61 | /// Information used to identify this third party location. 62 | pub fields: HashMap, 63 | } 64 | 65 | /// A third party network user. 66 | #[derive(Clone, Debug, Deserialize, Serialize)] 67 | pub struct User { 68 | /// A matrix user ID representing a third party user. 69 | pub userid: UserId, 70 | /// The protocol ID that the third party user is a part of. 71 | pub protocol: String, 72 | /// Information used to identify this third party user. 73 | pub fields: HashMap, 74 | } 75 | 76 | /// The medium of a third party identifier. 77 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Deserialize, Serialize)] 78 | #[serde(rename_all = "lowercase")] 79 | pub enum Medium { 80 | /// Email address identifier 81 | Email, 82 | /// Phone number identifier 83 | MSISDN, 84 | } 85 | -------------------------------------------------------------------------------- /src/r0/account/register.rs: -------------------------------------------------------------------------------- 1 | //! [POST /_matrix/client/r0/register](https://matrix.org/docs/spec/client_server/r0.4.0.html#post-matrix-client-r0-register) 2 | 3 | use ruma_api::ruma_api; 4 | use ruma_identifiers::{DeviceId, UserId}; 5 | use serde::{Deserialize, Serialize}; 6 | 7 | use super::AuthenticationData; 8 | 9 | ruma_api! { 10 | metadata { 11 | description: "Register an account on this homeserver.", 12 | method: POST, 13 | name: "register", 14 | path: "/_matrix/client/r0/register", 15 | rate_limited: true, 16 | requires_authentication: false, 17 | } 18 | 19 | request { 20 | /// If true, the server binds the email used for authentication 21 | /// to the Matrix ID with the ID Server. 22 | #[serde(skip_serializing_if = "Option::is_none")] 23 | pub bind_email: Option, 24 | /// The desired password for the account. 25 | /// 26 | /// Should only be empty for guest accounts. 27 | // TODO: the spec says nothing about when it is actually required. 28 | #[serde(skip_serializing_if = "Option::is_none")] 29 | pub password: Option, 30 | /// local part of the desired Matrix ID. 31 | /// 32 | /// If omitted, the homeserver MUST generate a Matrix ID local part. 33 | #[serde(skip_serializing_if = "Option::is_none")] 34 | pub username: Option, 35 | /// ID of the client device. 36 | /// 37 | /// If this does not correspond to a known client device, a new device will be created. 38 | /// The server will auto-generate a device_id if this is not specified. 39 | #[serde(skip_serializing_if = "Option::is_none")] 40 | pub device_id: Option, 41 | /// A display name to assign to the newly-created device. 42 | /// 43 | /// Ignored if `device_id` corresponds to a known device. 44 | #[serde(skip_serializing_if = "Option::is_none")] 45 | pub initial_device_display_name: Option, 46 | /// Additional authentication information for the user-interactive authentication API. 47 | /// 48 | /// Note that this information is not used to define how the registered user should be 49 | /// authenticated, but is instead used to authenticate the register call itself. 50 | /// It should be left empty, or omitted, unless an earlier call returned an response 51 | /// with status code 401. 52 | #[serde(skip_serializing_if = "Option::is_none")] 53 | pub auth: Option, 54 | /// Kind of account to register 55 | /// 56 | /// Defaults to `User` if ommited. 57 | #[ruma_api(query)] 58 | #[serde(skip_serializing_if = "Option::is_none")] 59 | pub kind: Option, 60 | } 61 | 62 | response { 63 | /// An access token for the account. 64 | /// 65 | /// This access token can then be used to authorize other requests. 66 | pub access_token: String, 67 | /// The hostname of the homeserver on which the account has been registered. 68 | pub home_server: String, 69 | /// The fully-qualified Matrix ID that has been registered. 70 | pub user_id: UserId, 71 | /// ID of the registered device. 72 | /// 73 | /// Will be the same as the corresponding parameter in the request, if one was specified. 74 | pub device_id: DeviceId, 75 | } 76 | 77 | error: crate::Error 78 | } 79 | 80 | /// The kind of account being registered. 81 | #[derive(Copy, Clone, Debug, Deserialize, Serialize)] 82 | #[serde(rename_all = "snake_case")] 83 | pub enum RegistrationKind { 84 | /// A guest account 85 | /// 86 | /// These accounts may have limited permissions and may not be supported by all servers. 87 | Guest, 88 | /// A regular user account 89 | User, 90 | } 91 | -------------------------------------------------------------------------------- /src/r0/room/create_room.rs: -------------------------------------------------------------------------------- 1 | //! [POST /_matrix/client/r0/createRoom](https://matrix.org/docs/spec/client_server/r0.6.0.html#post-matrix-client-r0-createroom) 2 | 3 | use ruma_api::ruma_api; 4 | use ruma_events::{room::power_levels::PowerLevelsEventContent, EventResult}; 5 | use ruma_identifiers::{RoomId, UserId}; 6 | use serde::{Deserialize, Serialize}; 7 | use serde_json::Value; 8 | 9 | use super::Visibility; 10 | use crate::r0::membership::Invite3pid; 11 | 12 | ruma_api! { 13 | metadata { 14 | description: "Create a new room.", 15 | method: POST, 16 | name: "create_room", 17 | path: "/_matrix/client/r0/createRoom", 18 | rate_limited: false, 19 | requires_authentication: true, 20 | } 21 | 22 | request { 23 | /// Extra keys to be added to the content of the `m.room.create`. 24 | #[serde(skip_serializing_if = "Option::is_none")] 25 | pub creation_content: Option, 26 | /// List of state events to send to the new room. 27 | /// 28 | /// Takes precedence over events set by preset, but gets overriden by 29 | /// name and topic keys. 30 | #[serde(default, skip_serializing_if = "Vec::is_empty")] 31 | pub initial_state: Vec, 32 | /// A list of user IDs to invite to the room. 33 | /// 34 | /// This will tell the server to invite everyone in the list to the newly created room. 35 | #[serde(default, skip_serializing_if = "Vec::is_empty")] 36 | pub invite: Vec, 37 | /// List of third party IDs of users to invite. 38 | #[serde(default, skip_serializing_if = "Vec::is_empty")] 39 | pub invite_3pid: Vec, 40 | /// If set, this sets the `is_direct` flag on room invites. 41 | #[serde(skip_serializing_if = "Option::is_none")] 42 | pub is_direct: Option, 43 | /// If this is included, an `m.room.name` event will be sent into the room to indicate 44 | /// the name of the room. 45 | #[serde(skip_serializing_if = "Option::is_none")] 46 | pub name: Option, 47 | /// Power level content to override in the default power level event. 48 | #[serde(skip_serializing_if = "Option::is_none")] 49 | #[wrap_incoming(PowerLevelsEventContent with EventResult)] 50 | pub power_level_content_override: Option, 51 | /// Convenience parameter for setting various default state events based on a preset. 52 | #[serde(skip_serializing_if = "Option::is_none")] 53 | pub preset: Option, 54 | /// The desired room alias local part. 55 | #[serde(skip_serializing_if = "Option::is_none")] 56 | pub room_alias_name: Option, 57 | /// Room version to set for the room. Defaults to homeserver's default if not specified. 58 | #[serde(skip_serializing_if = "Option::is_none")] 59 | pub room_version: Option, 60 | /// If this is included, an `m.room.topic` event will be sent into the room to indicate 61 | /// the topic for the room. 62 | #[serde(skip_serializing_if = "Option::is_none")] 63 | pub topic: Option, 64 | /// A public visibility indicates that the room will be shown in the published room 65 | /// list. A private visibility will hide the room from the published room list. Rooms 66 | /// default to private visibility if this key is not included. 67 | #[serde(skip_serializing_if = "Option::is_none")] 68 | pub visibility: Option, 69 | } 70 | 71 | response { 72 | /// The created room's ID. 73 | pub room_id: RoomId, 74 | } 75 | 76 | error: crate::Error 77 | } 78 | 79 | /// Extra options to be added to the `m.room.create` event. 80 | #[derive(Clone, Copy, Debug, Deserialize, Serialize)] 81 | pub struct CreationContent { 82 | /// Whether users on other servers can join this room. 83 | /// 84 | /// Defaults to `true` if key does not exist. 85 | #[serde(rename = "m.federate", skip_serializing_if = "Option::is_none")] 86 | pub federate: Option, 87 | } 88 | 89 | /// A convenience parameter for setting a few default state events. 90 | #[derive(Clone, Copy, Debug, Deserialize, Serialize)] 91 | #[serde(rename_all = "snake_case")] 92 | pub enum RoomPreset { 93 | /// `join_rules` is set to `invite` and `history_visibility` is set to `shared`. 94 | PrivateChat, 95 | /// `join_rules` is set to `public` and `history_visibility` is set to `shared`. 96 | PublicChat, 97 | /// Same as `PrivateChat`, but all initial invitees get the same power level as the creator. 98 | TrustedPrivateChat, 99 | } 100 | 101 | /// Represents content of a state event to be used to initalize new room state. 102 | #[derive(Clone, Debug, Deserialize, Serialize)] 103 | pub struct InitialStateEvent { 104 | /// State event type. 105 | #[serde(rename = "type")] 106 | pub event_type: String, 107 | /// `state_key` of the event to be sent. 108 | pub state_key: Option, 109 | /// JSON content of the state event. 110 | pub content: Value, 111 | } 112 | -------------------------------------------------------------------------------- /src/error.rs: -------------------------------------------------------------------------------- 1 | //! Errors that can be sent from the homeserver. 2 | 3 | use ruma_api::{error::ResponseDeserializationError, EndpointError}; 4 | use serde::{Deserialize, Serialize}; 5 | 6 | /// An enum for the error kind. Items may contain additional information. 7 | #[derive(Debug, Clone, Copy, Serialize, Deserialize)] 8 | #[serde(tag = "errcode")] 9 | pub enum ErrorKind { 10 | /// M_FORBIDDEN 11 | #[serde(rename = "M_FORBIDDEN")] 12 | Forbidden, 13 | /// M_UNKNOWN_TOKEN 14 | #[serde(rename = "M_UNKNOWN_TOKEN")] 15 | UnknownToken, 16 | /// M_MISSING_TOKEN 17 | #[serde(rename = "M_MISSING_TOKEN")] 18 | MissingToken, 19 | /// M_BAD_JSON 20 | #[serde(rename = "M_BAD_JSON")] 21 | BadJson, 22 | /// M_NOT_JSON 23 | #[serde(rename = "M_NOT_JSON")] 24 | NotJson, 25 | /// M_NOT_FOUND 26 | #[serde(rename = "M_NOT_FOUND")] 27 | NotFound, 28 | /// M_LIMIT_EXCEEDED 29 | #[serde(rename = "M_LIMIT_EXCEEDED")] 30 | LimitExceeded, 31 | /// M_UNKNOWN 32 | #[serde(rename = "M_UNKNOWN")] 33 | Unknown, 34 | /// M_UNRECOGNIZED 35 | #[serde(rename = "M_UNRECOGNIZED")] 36 | Unrecognized, 37 | /// M_UNAUTHORIZED 38 | #[serde(rename = "M_UNAUTHORIZED")] 39 | Unauthorized, 40 | /// M_USER_IN_USE 41 | #[serde(rename = "M_USER_IN_USE")] 42 | UserInUse, 43 | /// M_INVALID_USERNAME 44 | #[serde(rename = "M_INVALID_USERNAME")] 45 | InvalidUsername, 46 | /// M_ROOM_IN_USE 47 | #[serde(rename = "M_ROOM_IN_USE")] 48 | RoomInUse, 49 | /// M_INVALID_ROOM_STATE 50 | #[serde(rename = "M_INVALID_ROOM_STATE")] 51 | InvalidRoomState, 52 | /// M_THREEPID_IN_USE 53 | #[serde(rename = "M_THREEPID_IN_USE")] 54 | ThreepidInUse, 55 | /// M_THREEPID_NOT_FOUND 56 | #[serde(rename = "M_THREEPID_NOT_FOUND")] 57 | ThreepidNotFound, 58 | /// M_THREEPID_AUTH_FAILED 59 | #[serde(rename = "M_THREEPID_AUTH_FAILED")] 60 | ThreepidAuthFailed, 61 | /// M_THREEPID_DENIED 62 | #[serde(rename = "M_THREEPID_DENIED")] 63 | ThreepidDenied, 64 | /// M_SERVER_NOT_TRUSTED 65 | #[serde(rename = "M_SERVER_NOT_TRUSTED")] 66 | ServerNotTrusted, 67 | /// M_UNSUPPORTED_ROOM_VERSION 68 | #[serde(rename = "M_UNSUPPORTED_ROOM_VERSION")] 69 | UnsupportedRoomVersion, 70 | /// M_INCOMPATIBLE_ROOM_VERSION 71 | #[serde(rename = "M_INCOMPATIBLE_ROOM_VERSION")] 72 | IncompatibleRoomVersion, 73 | /// M_BAD_STATE 74 | #[serde(rename = "M_BAD_STATE")] 75 | BadState, 76 | /// M_GUEST_ACCESS_FORBIDDEN 77 | #[serde(rename = "M_GUEST_ACCESS_FORBIDDEN")] 78 | GuestAccessForbidden, 79 | /// M_CAPTCHA_NEEDED 80 | #[serde(rename = "M_CAPTCHA_NEEDED")] 81 | CaptchaNeeded, 82 | /// M_CAPTCHA_INVALID 83 | #[serde(rename = "M_CAPTCHA_INVALID")] 84 | CaptchaInvalid, 85 | /// M_MISSING_PARAM 86 | #[serde(rename = "M_MISSING_PARAM")] 87 | MissingParam, 88 | /// M_INVALID_PARAM 89 | #[serde(rename = "M_INVALID_PARAM")] 90 | InvalidParam, 91 | /// M_TOO_LARGE 92 | #[serde(rename = "M_TOO_LARGE")] 93 | TooLarge, 94 | /// M_EXCLUSIVE 95 | #[serde(rename = "M_EXCLUSIVE")] 96 | Exclusive, 97 | } 98 | 99 | /// A Matrix Error without a status code 100 | #[derive(Debug, Clone, Serialize, Deserialize)] 101 | pub struct ErrorBody { 102 | /// A value which can be used to handle an error message 103 | #[serde(flatten)] 104 | pub kind: ErrorKind, 105 | /// A human-readable error message, usually a sentence explaining what went wrong. 106 | #[serde(rename = "error")] 107 | pub message: String, 108 | } 109 | 110 | /// A Matrix Error 111 | #[derive(Debug, Clone)] 112 | pub struct Error { 113 | /// A value which can be used to handle an error message 114 | pub kind: ErrorKind, 115 | /// A human-readable error message, usually a sentence explaining what went wrong. 116 | pub message: String, 117 | /// The http status code 118 | pub status_code: http::StatusCode, 119 | } 120 | 121 | impl EndpointError for Error { 122 | fn try_from_response( 123 | response: http::Response>, 124 | ) -> Result { 125 | match serde_json::from_slice::(response.body()) { 126 | Ok(error_body) => Ok(error_body.into_error(response.status())), 127 | Err(de_error) => Err(ResponseDeserializationError::new(de_error, response)), 128 | } 129 | } 130 | } 131 | 132 | impl From for ErrorBody { 133 | fn from(error: Error) -> Self { 134 | Self { 135 | kind: error.kind, 136 | message: error.message, 137 | } 138 | } 139 | } 140 | 141 | impl ErrorBody { 142 | /// Convert the ErrorBody into an Error by adding the http status code. 143 | pub fn into_error(self, status_code: http::StatusCode) -> Error { 144 | Error { 145 | kind: self.kind, 146 | message: self.message, 147 | status_code, 148 | } 149 | } 150 | } 151 | 152 | impl From for http::Response> { 153 | fn from(error: Error) -> http::Response> { 154 | http::Response::builder() 155 | .header(http::header::CONTENT_TYPE, "application/json") 156 | .status(error.status_code) 157 | .body(serde_json::to_vec(&ErrorBody::from(error)).unwrap()) 158 | .unwrap() 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /src/r0/keys.rs: -------------------------------------------------------------------------------- 1 | //! Endpoints for key management 2 | 3 | use std::{ 4 | collections::HashMap, 5 | convert::TryFrom, 6 | fmt::{Debug, Display, Error as FmtError, Formatter}, 7 | }; 8 | 9 | use ruma_events::Algorithm; 10 | use ruma_identifiers::{DeviceId, UserId}; 11 | use serde::{ 12 | de::{self, Unexpected}, 13 | Deserialize, Deserializer, Serialize, Serializer, 14 | }; 15 | 16 | pub mod claim_keys; 17 | pub mod get_key_changes; 18 | pub mod get_keys; 19 | pub mod upload_keys; 20 | 21 | /// The basic key algorithms in the specification 22 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] 23 | pub enum KeyAlgorithm { 24 | /// The Ed25519 signature algorithm. 25 | #[serde(rename = "ed25519")] 26 | Ed25519, 27 | 28 | /// The Curve25519 ECDH algorithm. 29 | #[serde(rename = "curve25519")] 30 | Curve25519, 31 | 32 | /// The Curve25519 ECDH algorithm, but the key also contains signatures 33 | #[serde(rename = "signed_curve25519")] 34 | SignedCurve25519, 35 | } 36 | 37 | impl Display for KeyAlgorithm { 38 | fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> { 39 | let algorithm_str = match *self { 40 | KeyAlgorithm::Ed25519 => "ed25519", 41 | KeyAlgorithm::Curve25519 => "curve25519", 42 | KeyAlgorithm::SignedCurve25519 => "signed_curve25519", 43 | }; 44 | write!(f, "{}", algorithm_str)?; 45 | Ok(()) 46 | } 47 | } 48 | 49 | impl TryFrom<&'_ str> for KeyAlgorithm { 50 | type Error = &'static str; 51 | fn try_from(s: &str) -> Result { 52 | match s { 53 | "ed25519" => Ok(KeyAlgorithm::Ed25519), 54 | "curve25519" => Ok(KeyAlgorithm::Curve25519), 55 | "signed_curve25519" => Ok(KeyAlgorithm::SignedCurve25519), 56 | _ => Err("Unknown algorithm"), 57 | } 58 | } 59 | } 60 | 61 | /// A key algorithm and a device id, combined with a ':' 62 | #[derive(Debug, Clone, Hash, PartialEq, Eq)] 63 | pub struct AlgorithmAndDeviceId(pub KeyAlgorithm, pub DeviceId); 64 | 65 | impl Serialize for AlgorithmAndDeviceId { 66 | fn serialize(&self, serializer: S) -> Result 67 | where 68 | S: Serializer, 69 | { 70 | let s = format!("{}:{}", self.0, self.1); 71 | serializer.serialize_str(&s) 72 | } 73 | } 74 | 75 | impl<'de> Deserialize<'de> for AlgorithmAndDeviceId { 76 | #[allow(clippy::comparison_chain)] 77 | fn deserialize(deserializer: D) -> Result 78 | where 79 | D: Deserializer<'de>, 80 | { 81 | let value = String::deserialize(deserializer)?; 82 | let parts = value.split(':').collect::>(); 83 | 84 | const EXPECTED: &str = "a string composed of an algorithm and a device id separated by ':'"; 85 | 86 | if parts.len() < 2 { 87 | return Err(de::Error::invalid_type( 88 | Unexpected::Other("string without a ':' separator"), 89 | &EXPECTED, 90 | )); 91 | } else if parts.len() > 2 { 92 | return Err(de::Error::invalid_type( 93 | Unexpected::Other("string with more than one ':' separator"), 94 | &EXPECTED, 95 | )); 96 | } 97 | 98 | let algorithm_result = KeyAlgorithm::try_from(parts[0]); 99 | match algorithm_result { 100 | Ok(algorithm) => Ok(AlgorithmAndDeviceId(algorithm, parts[1].to_string())), 101 | Err(_) => Err(de::Error::invalid_value( 102 | Unexpected::Str(parts[0]), 103 | &"valid key algorithm", 104 | )), 105 | } 106 | } 107 | } 108 | 109 | /// Identity keys for a device. 110 | #[derive(Debug, Clone, Serialize, Deserialize)] 111 | pub struct DeviceKeys { 112 | /// The ID of the user the device belongs to. Must match the user ID used when logging in. 113 | pub user_id: UserId, 114 | /// The ID of the device these keys belong to. Must match the device ID used when logging in. 115 | pub device_id: DeviceId, 116 | /// The encryption algorithms supported by this device. 117 | pub algorithms: Vec, 118 | /// Public identity keys. 119 | pub keys: HashMap, 120 | /// Signatures for the device key object. 121 | pub signatures: HashMap>, 122 | /// Additional data added to the device key information by intermediate servers, and 123 | /// not covered by the signatures. 124 | #[serde(skip_serializing_if = "Option::is_none")] 125 | pub unsigned: Option, 126 | } 127 | 128 | /// Additional data added to device key information by intermediate servers. 129 | #[derive(Debug, Clone, Serialize, Deserialize)] 130 | pub struct UnsignedDeviceInfo { 131 | /// The display name which the user set on the device. 132 | pub device_display_name: String, 133 | } 134 | 135 | /// A key for the SignedCurve25519 algorithm 136 | #[derive(Debug, Clone, Serialize, Deserialize)] 137 | pub struct SignedKey { 138 | /// Base64-encoded 32-byte Curve25519 public key. 139 | pub key: String, 140 | /// Signatures for the key object. 141 | pub signatures: HashMap>, 142 | } 143 | 144 | /// A one-time public key for "pre-key" messages. 145 | #[derive(Debug, Clone, Serialize, Deserialize)] 146 | #[serde(untagged)] 147 | pub enum OneTimeKey { 148 | /// A key containing signatures, for the SignedCurve25519 algorithm. 149 | SignedKey(SignedKey), 150 | /// A string-valued key, for the Ed25519 and Curve25519 algorithms. 151 | Key(String), 152 | } 153 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # [unreleased] 2 | 3 | # 0.7.1 4 | 5 | Bug fixes: 6 | 7 | * Fix deserialization of `sync_events::Request` 8 | * Fix (de)serialization of `sync_events::RoomSummary` 9 | 10 | # 0.7.0 11 | 12 | Breaking changes: 13 | 14 | * Update ruma-api to 0.15.0 15 | * Update ruma-events to 0.18.0 16 | * Fix `r0::session::get_login_types` 17 | * Add `allow_remote` parameter to `r0::media::get_content` 18 | * Add missing parameters for `r0::room::create_room` 19 | * Moved `r0::room::create_room::Invite3pid` to `r0::membership::Invite3pid` 20 | * Replaced `user_id` parameter of `r0::membership::invite_user` with `recipient` 21 | to allow invitation of users by either Matrix or third party identifiers. 22 | * Remove deprecated endpoint `r0::contact::create_contact` (deprecated in r0.6.0) 23 | * Add lazy-loading options to `r0::filter::RoomEventFilter` (introduced in r0.5.0) 24 | * Change type for `limit` request parameter of `r0::context::get_context` from `u8` to `Option` 25 | * Use `std::time::Duration` for appropriate fields on several endpoints: 26 | ``` 27 | r0::{ 28 | account::request_openid_token, 29 | keys::{claim_keys, get_keys}, 30 | presence::get_presence, 31 | sync::sync_events, 32 | typing::create_typing_event, 33 | voip::get_turn_server_info 34 | } 35 | ``` 36 | 37 | Improvements: 38 | 39 | * Add an `Error` type that represents the well-known errors in the client-server API 40 | * the response deserialization code will try to create an instance of this type from http responses that indicate an error 41 | * Add OpenID token request endpoint. 42 | * Add `r0::client_exchange::send_event_to_device` (introduced in r0.3.0) 43 | * Add endpoints to retrieve account_data (introduced in r0.5.0) 44 | * Add media endpoints: `r0::media::{get_media_config, get_media_preview, get_content_as_filename}` 45 | * Add `unstable_features` to `unversioned::get_supported_versions` (introduced in r0.5.0) 46 | * Add request and response parameters for `r0::account::deactivate` 47 | * Add `r0::session::sso_login` (introduced in r0.5.0) 48 | * Add `filter` type for `r0::context::get_context` 49 | 50 | # 0.6.0 51 | 52 | Breaking changes: 53 | 54 | * Update ruma-api to 0.13.0 55 | * Our Minimum Supported Rust Version is now 1.40.0 56 | * Remove presence list endpoints `r0::presence::{get_subscribed_presences, update_presence_subscriptions}` (removed in r0.5.0) 57 | * Refactor `r0::send` endpoints and remove module: 58 | * Move `r0::send::send_message_event` to `r0::message::create_message_event` 59 | * Move `r0::send::send_state_event_for_empty_key` to `r0::state:create_state_event_for_empty_key` 60 | * Move `r0::send::send_state_event_for_key` to `r0::state:create_state_event_for_key` 61 | * Refactor `r0::sync` endpoints: 62 | * Move `r0::sync::get_member_events` to `r0::membership::get_member_events` 63 | * Move `r0::sync::get_message_events` to `r0::message::get_message_events` 64 | * Move `r0::sync::get_state_events` to `r0::state::get_state_events` 65 | * Move `r0::sync::get_state_events_for_empty_key` to `r0::state::get_state_events_for_empty_key` 66 | * Move `r0::sync::get_state_events_for_key` to `r0::state::get_state_events_for_key` 67 | * Update endpoints for requesting account management tokens via email: 68 | * Move `r0::account::request_password_change_token` to `r0::account::request_password_change_token_via_email` 69 | * Move `r0::account::request_register_token` to `r0::account::request_registration_token_via_email` 70 | * Modify `r0::account::request_registration_token_via_email` not to be rate-limited and require authentication 71 | * Merge duplicate enums `r0::contact::get_contact::Medium` and `r0::session::login::Medium` and move them to `r0::thirdparty` 72 | 73 | Improvements: 74 | 75 | * Add `r0::device` endpoints 76 | * Add `r0::room::get_room_event` (introduced in r0.4.0) 77 | * Add `r0::read_marker::set_read_marker` (introduced in r0.4.0) 78 | * Add `r0::capabilities::get_capabilities` (introduced in r0.5.0) 79 | * Add `r0::keys` endpoints (introduced in r0.3.0) 80 | * Add `r0::session::get_login_types` (introduced in r0.4.0) 81 | * Add `r0::account::get_username_availability` (introduced in r0.4.0) 82 | * Add endpoints to request management tokens (introduced upstream in r0.4.0): 83 | * `r0::account::request_3pid_management_token_via_msisdn` 84 | * `r0::account::request_password_change_token_via_msisdn` 85 | * `r0::account::request_registration_token_via_msisdn` 86 | * `r0::acount::request_3pid_management_token_via_email` 87 | * Update `r0::presence_get_presence` from r0.4.0 to r0.6.0 88 | * Add `r0::account::bind_3pid` 89 | * Add `r0::account::delete_3pid` 90 | * Add `r0::account::unbind_3pid` 91 | * Add `r0::push` endpoints 92 | * Add `r0::room::upgrade_room` (introduced upstream in r0.5.0) 93 | 94 | # 0.5.0 95 | 96 | Breaking changes: 97 | 98 | * Our Minimum Supported Rust Version is now 1.39.0 99 | * Update ruma-api from 0.11.0 to 0.12.0 100 | * Move `r0::directory::get_public_rooms::PublicRoomsChunk` to `r0::directory::PublicRoomsChunk` 101 | * Move `r0::room::create_room::Visibility` to `r0::room::Visibility` 102 | * Move `r0::account::register::AuthenticationData` to `r0::account::AuthenticationData` 103 | 104 | Improvements: 105 | 106 | * Update `r0::directory::get_public_rooms` from r0.3.0 to r0.6.0 107 | * Add `r0::directory::get_public_rooms_filtered` (introduced upstream in r0.3.0) 108 | * Add `filter` optional parameter to `r0::sync::get_message_events` (introduced upstream in r0.3.0) 109 | * Add `r0::appservice::set_room_visibility` (part of application service extensions for the client-server API) 110 | * Add `contains_url` to `r0::filter::RoomEventFilter` (introduced upstream in r0.3.0) 111 | * Update `r0::account::change_password` from r0.3.0 to r0.6.0 112 | * Add optional `auth` field 113 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Welcome! Thanks for looking into contributing to our project! 2 | 3 | # Table of Contents 4 | 5 | - [Looking for Help?](#looking-for-help) 6 | - [Documentation](#documentation) 7 | - [Chat Rooms](#chat-rooms) 8 | - [Reporting Issues](#reporting-issues) 9 | - [Submitting Code](#submitting-code) 10 | - [Coding Style](#coding-style) 11 | - [Modifying Endpoints](#modifying-endpoints) 12 | - [Submitting PRs](#submitting-prs) 13 | - [Where do I start?](#where-do-i-start) 14 | - [Testing](#testing) 15 | - [Contact](#contact) 16 | 17 | # Looking for Help? 18 | 19 | Here is a list of helpful resources you can consult: 20 | 21 | ## Documentation 22 | 23 | - [Matrix spec Documentation](https://matrix.org/docs/spec/client_server/latest) 24 | - Documentation to other Ruma modules: 25 | - [ruma-events](https://docs.rs/ruma-events/) 26 | - [ruma-api](https://docs.rs/ruma-api/) 27 | - [ruma-client](https://docs.rs/ruma-client/) 28 | 29 | ## Chat Rooms 30 | 31 | - Ruma Matrix room: [#ruma:matrix.org](https://matrix.to/#/#ruma:matrix.org) 32 | - Matrix Developer room: [#matrix-dev:matrix.org](https://matrix.to/#/#matrix-dev:matrix.org) 33 | 34 | # Reporting Issues 35 | 36 | If you find any bugs, inconsistencies or other problems, feel free to submit 37 | a GitHub [issue](issues). 38 | 39 | If you have a quick question, it may be easier to leave a message on 40 | [#ruma:matrix.org](https://matrix.to/#/#ruma:matrix.org). 41 | 42 | Also, if you have trouble getting on board, let us know so we can help future 43 | contributors to the project overcome that hurdle too. 44 | 45 | # Submitting Code 46 | 47 | Ready to write some code? Great! Here are some guidelines to follow to 48 | help you on your way: 49 | 50 | ## Coding Style 51 | 52 | ### Import Formatting 53 | 54 | Organize your imports into three groups separated by blank lines: 55 | 56 | 1. `std` imports 57 | 1. External imports (from other crates) 58 | 1. Local imports (`self::`, `super::`, `crate::` and things like `LocalType::*`) 59 | 60 | For example, 61 | 62 | ```rust 63 | use std::collections::HashMap; 64 | 65 | use ruma_api::ruma_api; 66 | 67 | use super::MyType; 68 | ``` 69 | 70 | Also, group imports by module. For example, do this: 71 | 72 | ```rust 73 | use std::{ 74 | collections::HashMap, 75 | convert::TryFrom, 76 | fmt::{Debug, Display, Error as FmtError, Formatter}, 77 | }; 78 | ``` 79 | 80 | as opposed to: 81 | 82 | ```rust 83 | use std::collections::HashMap; 84 | use std::convert::TryFrom; 85 | use std::fmt::{Debug, Display, Error as FmtError, Formatter}; 86 | ``` 87 | 88 | ### Code Formatting and Linting 89 | 90 | Use `rustfmt` to format your code and `clippy` to lint your code. Before 91 | committing your changes, go ahead and run `cargo fmt` and `cargo clippy 92 | --all-targets --all-features` on the repository to make sure that the 93 | formatting and linting checks pass in CI. Note that `clippy` warnings are 94 | reported as errors in CI builds, so make sure to handle those before 95 | comitting as well. (To install the tools, run `rustup component add rustfmt 96 | clippy`.) 97 | 98 | ### Commit Messages 99 | 100 | Write commit messages using the imperative mood, as if completing the sentence: 101 | "If applied, this commit will \_\_\_." For example, use "Fix some bug" instead 102 | of "Fixed some bug" or "Add a feature" instead of "Added a feature". 103 | 104 | (Take a look at this 105 | [blog post](https://www.freecodecamp.org/news/writing-good-commit-messages-a-practical-guide/) 106 | for more information on writing good commit messages.) 107 | 108 | ## Modifying Endpoints 109 | 110 | ### Matrix Spec Version 111 | 112 | Use the latest r0.x.x documentation when adding or modifying code. We target 113 | the latest minor version of the Matrix specification. (Note: We might 114 | reconsider this when the Client-Server API hits r1.0.0.) 115 | 116 | ### Endpoint Documentation Header 117 | 118 | Add a comment to the top of each endpoint file that includes the path 119 | and a link to the documentation of the spec. You can use the latest 120 | version at the time of the commit. For example: 121 | 122 | ```rust 123 | //! [GET /.well-known/matrix/client](https://matrix.org/docs/spec/client_server/r0.4.0#get-well-known-matrix-client) 124 | ``` 125 | 126 | ### Naming Endpoints 127 | 128 | When adding new endpoints, select the module that fits the purpose of the 129 | endpoint. When naming the endpoint itself, you can use the following 130 | guidelines: 131 | - The name should be a verb describing what the client is requesting, e.g. 132 | `get_some_resource`. 133 | - Endpoints which are basic CRUD operations should use the prefixes 134 | `create`, `get`, `update`, and `delete`. 135 | - The prefix `set` is preferred to create if the resource is a singleton. 136 | In other words, when there's no distinction between `create` and `update`. 137 | - Try to use names that are as descriptive as possible and distinct from 138 | other endpoints in all other modules. (For example, instead of 139 | `r0::room::get_event`, use `r0::room::get_room_event`). 140 | - If you're not sure what to name it, pick any name and we can help you 141 | with it. 142 | 143 | ### Tracking Changes 144 | 145 | Add your changes to the [change log](CHANGELOG.md). If possible, try to 146 | find and denote the version of the spec that included the change you are 147 | making. 148 | 149 | ## Submitting PRs 150 | 151 | Once you're ready to submit your code, create a pull request, and one of our 152 | maintainers will review it. Once your PR has passed review, a maintainer will 153 | merge the request and you're done! 🎉 154 | 155 | ## Where do I start? 156 | 157 | If this is your first contribution to the project, we recommend taking a look 158 | at one of the [open issues][] we've marked for new contributors. 159 | 160 | It may be helpful to peruse some of the documentation for `ruma-events` and 161 | `ruma-api` listed above for some context. 162 | 163 | [open issues]: https://github.com/ruma/ruma-client-api/issues?q=is%3Aopen+is%3Aissue+label%3Aeffort%2Feasy 164 | 165 | # Testing 166 | 167 | Before committing, run `cargo check` to make sure that your changes can build, as well as running the formatting and linting tools [mentioned above](#code-formatting-and-linting). 168 | 169 | # Contact 170 | 171 | Thanks again for being a contributor! If you have any questions, join us at 172 | [#ruma:matrix.org](https://matrix.to/#/#ruma:matrix.org). 173 | -------------------------------------------------------------------------------- /src/r0/session/login.rs: -------------------------------------------------------------------------------- 1 | //! [POST /_matrix/client/r0/login](https://matrix.org/docs/spec/client_server/r0.6.0#post-matrix-client-r0-login) 2 | 3 | use ruma_api::ruma_api; 4 | use ruma_identifiers::{DeviceId, UserId}; 5 | use serde::{Deserialize, Deserializer, Serialize, Serializer}; 6 | 7 | use crate::r0::thirdparty::Medium; 8 | 9 | ruma_api! { 10 | metadata { 11 | description: "Login to the homeserver.", 12 | method: POST, 13 | name: "login", 14 | path: "/_matrix/client/r0/login", 15 | rate_limited: true, 16 | requires_authentication: false, 17 | } 18 | 19 | request { 20 | /// Identification information for the user. 21 | #[serde(flatten)] 22 | pub user: UserInfo, 23 | /// The authentication mechanism. 24 | #[serde(flatten)] 25 | pub login_info: LoginInfo, 26 | /// ID of the client device 27 | #[serde(skip_serializing_if = "Option::is_none")] 28 | pub device_id: Option, 29 | /// A display name to assign to the newly-created device. Ignored if device_id corresponds 30 | /// to a known device. 31 | #[serde(skip_serializing_if = "Option::is_none")] 32 | pub initial_device_display_name: Option, 33 | } 34 | 35 | response { 36 | /// The fully-qualified Matrix ID that has been registered. 37 | pub user_id: UserId, 38 | /// An access token for the account. 39 | pub access_token: String, 40 | /// The hostname of the homeserver on which the account has been registered. 41 | /// 42 | /// Deprecated: Clients should extract the server_name from user_id (by splitting at the 43 | /// first colon) if they require it. 44 | #[serde(skip_serializing_if = "Option::is_none")] 45 | pub home_server: Option, 46 | /// ID of the logged-in device. 47 | /// 48 | /// Will be the same as the corresponging parameter in the request, if one was 49 | /// specified. 50 | pub device_id: String, 51 | /// Client configuration provided by the server. 52 | /// 53 | /// If present, clients SHOULD use the provided object to reconfigure themselves. 54 | pub well_known: Option, 55 | } 56 | 57 | error: crate::Error 58 | } 59 | 60 | /// Identification information for the user. 61 | #[derive(Clone, Debug, PartialEq, Eq)] 62 | pub enum UserInfo { 63 | /// Either a fully qualified Matrix user ID, or just the localpart (as part of the 'identifier' 64 | /// field). 65 | MatrixId(String), 66 | /// Third party identifier (as part of the 'identifier' field). 67 | ThirdPartyId { 68 | /// Third party identifier for the user. 69 | address: String, 70 | /// The medium of the identifier. 71 | medium: Medium, 72 | }, 73 | /// Same as third-party identification with medium == msisdn, but with a non-canonicalised 74 | /// phone number. 75 | PhoneNumber { 76 | /// The country that the phone number is from. 77 | country: String, 78 | /// The phone number. 79 | phone: String, 80 | }, 81 | } 82 | 83 | /// The authentication mechanism. 84 | #[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)] 85 | #[serde(tag = "type")] 86 | pub enum LoginInfo { 87 | /// A password is supplied to authenticate. 88 | #[serde(rename = "m.login.password")] 89 | Password { 90 | /// The password. 91 | password: String, 92 | }, 93 | /// Token-based login. 94 | #[serde(rename = "m.login.token")] 95 | Token { 96 | /// The token. 97 | token: String, 98 | }, 99 | } 100 | 101 | /// Client configuration provided by the server. 102 | #[derive(Clone, Debug, Deserialize, Serialize)] 103 | pub struct DiscoveryInfo { 104 | /// Information about the homeserver to connect to. 105 | #[serde(rename = "m.homeserver")] 106 | pub homeserver: HomeserverInfo, 107 | /// Information about the identity server to connect to. 108 | #[serde(rename = "m.identity_server")] 109 | pub identity_server: Option, 110 | } 111 | 112 | /// Information about the homeserver to connect to. 113 | #[derive(Clone, Debug, Deserialize, Serialize)] 114 | pub struct HomeserverInfo { 115 | /// The base URL for the homeserver for client-server connections. 116 | pub base_url: String, 117 | } 118 | 119 | /// Information about the identity server to connect to. 120 | #[derive(Clone, Debug, Deserialize, Serialize)] 121 | pub struct IdentityServerInfo { 122 | /// The base URL for the identity server for client-server connections. 123 | pub base_url: String, 124 | } 125 | 126 | mod user_serde; 127 | 128 | impl Serialize for UserInfo { 129 | fn serialize(&self, serializer: S) -> Result 130 | where 131 | S: Serializer, 132 | { 133 | user_serde::UserInfo::from(self).serialize(serializer) 134 | } 135 | } 136 | 137 | impl<'de> Deserialize<'de> for UserInfo { 138 | fn deserialize(deserializer: D) -> Result 139 | where 140 | D: Deserializer<'de>, 141 | { 142 | user_serde::UserInfo::deserialize(deserializer).map(Into::into) 143 | } 144 | } 145 | 146 | #[cfg(test)] 147 | mod tests { 148 | use std::convert::TryInto; 149 | 150 | use serde_json::json; 151 | 152 | use super::{LoginInfo, Medium, Request, UserInfo}; 153 | 154 | #[test] 155 | fn deserialize_login_type() { 156 | assert_eq!( 157 | serde_json::from_str::( 158 | r#" 159 | { 160 | "type": "m.login.password", 161 | "password": "ilovebananas" 162 | } 163 | "#, 164 | ) 165 | .unwrap(), 166 | LoginInfo::Password { 167 | password: "ilovebananas".into() 168 | } 169 | ); 170 | 171 | assert_eq!( 172 | serde_json::from_str::( 173 | r#" 174 | { 175 | "type": "m.login.token", 176 | "token": "1234567890abcdef" 177 | } 178 | "#, 179 | ) 180 | .unwrap(), 181 | LoginInfo::Token { 182 | token: "1234567890abcdef".into() 183 | } 184 | ); 185 | } 186 | 187 | #[test] 188 | fn deserialize_user() { 189 | assert_eq!( 190 | serde_json::from_str::( 191 | r#" 192 | { 193 | "identifier": { 194 | "type": "m.id.user", 195 | "user": "cheeky_monkey" 196 | } 197 | } 198 | "#, 199 | ) 200 | .unwrap(), 201 | UserInfo::MatrixId("cheeky_monkey".into()) 202 | ); 203 | } 204 | 205 | #[test] 206 | fn serialize_login_request_body() { 207 | let req: http::Request> = Request { 208 | user: UserInfo::ThirdPartyId { 209 | address: "hello@example.com".to_owned(), 210 | medium: Medium::Email, 211 | }, 212 | login_info: LoginInfo::Token { 213 | token: "0xdeadbeef".to_owned(), 214 | }, 215 | device_id: None, 216 | initial_device_display_name: Some("test".to_string()), 217 | } 218 | .try_into() 219 | .unwrap(); 220 | 221 | let req_body_value: serde_json::Value = serde_json::from_slice(req.body()).unwrap(); 222 | assert_eq!( 223 | req_body_value, 224 | json!({ 225 | "identifier": { 226 | "type": "m.id.thirdparty", 227 | "medium": "email", 228 | "address": "hello@example.com" 229 | }, 230 | "type": "m.login.token", 231 | "token": "0xdeadbeef", 232 | "initial_device_display_name": "test", 233 | }) 234 | ) 235 | } 236 | } 237 | --------------------------------------------------------------------------------