diff --git a/ruma-identity-service-api/src/lib.rs b/ruma-identity-service-api/src/lib.rs index 3b9decb1..558fc995 100644 --- a/ruma-identity-service-api/src/lib.rs +++ b/ruma-identity-service-api/src/lib.rs @@ -9,5 +9,6 @@ pub mod authentication; pub mod keys; +pub mod lookup; pub mod status; pub mod tos; diff --git a/ruma-identity-service-api/src/lookup.rs b/ruma-identity-service-api/src/lookup.rs new file mode 100644 index 00000000..af14b468 --- /dev/null +++ b/ruma-identity-service-api/src/lookup.rs @@ -0,0 +1,36 @@ +//! Endpoints to look up Matrix IDs bound to 3PIDs. + +use ruma_serde::StringEnum; + +pub mod get_hash_parameters; +pub mod lookup_3pid; + +/// The algorithms that can be used to hash the identifiers used for lookup, as defined in the +/// Matrix Spec. +/// +/// This type can hold an arbitrary string. To check for algorithms that are not available as a +/// documented variant here, use its string representation, obtained through `.as_str()`. +#[derive(Debug, PartialEq, Eq, Clone, StringEnum)] +#[non_exhaustive] +#[ruma_enum(rename_all = "snake_case")] +pub enum IdentifierHashingAlgorithm { + /// The SHA-256 hashing algorithm. + Sha256, + + /// No algorithm is used, and identifier strings are directly used for lookup. + None, + + #[doc(hidden)] + _Custom(String), +} + +#[cfg(test)] +mod test { + use super::IdentifierHashingAlgorithm; + + #[test] + fn parse_identifier_hashing_algorithm() { + assert_eq!(IdentifierHashingAlgorithm::from("sha256"), IdentifierHashingAlgorithm::Sha256); + assert_eq!(IdentifierHashingAlgorithm::from("none"), IdentifierHashingAlgorithm::None); + } +} diff --git a/ruma-identity-service-api/src/lookup/get_hash_parameters.rs b/ruma-identity-service-api/src/lookup/get_hash_parameters.rs new file mode 100644 index 00000000..7d701e53 --- /dev/null +++ b/ruma-identity-service-api/src/lookup/get_hash_parameters.rs @@ -0,0 +1,3 @@ +//! Endpoint to get details about Hashing identifiers. + +pub mod v2; diff --git a/ruma-identity-service-api/src/lookup/get_hash_parameters/v2.rs b/ruma-identity-service-api/src/lookup/get_hash_parameters/v2.rs new file mode 100644 index 00000000..599d7ae2 --- /dev/null +++ b/ruma-identity-service-api/src/lookup/get_hash_parameters/v2.rs @@ -0,0 +1,43 @@ +//! [GET /_matrix/identity/v2/hash_details](https://matrix.org/docs/spec/identity_service/r0.3.0#get-matrix-identity-v2-hash-details) + +use ruma_api::ruma_api; + +use crate::lookup::IdentifierHashingAlgorithm; + +ruma_api! { + metadata: { + description: "Gets parameters for hashing identifiers from the server. This can include any of the algorithms defined in the spec.", + method: GET, + name: "get_hash_parameters", + path: "/_matrix/identity/v2/hash_details", + authentication: AccessToken, + rate_limited: false, + } + + #[derive(Default)] + request: {} + + response: { + /// The pepper the client MUST use in hashing identifiers, and MUST supply to the /lookup endpoint when performing lookups. + /// + /// Servers SHOULD rotate this string often. + pub lookup_pepper: String, + + /// The algorithms the server supports. Must contain at least `sha256`. + pub algorithms: Vec, + } +} + +impl Request { + /// Creates an empty `Request`. + pub fn new() -> Self { + Self {} + } +} + +impl Response { + /// Create a new `Response` using the given pepper and `Vec` of algorithms. + pub fn new(lookup_pepper: String, algorithms: Vec) -> Self { + Self { lookup_pepper, algorithms } + } +} diff --git a/ruma-identity-service-api/src/lookup/lookup_3pid.rs b/ruma-identity-service-api/src/lookup/lookup_3pid.rs new file mode 100644 index 00000000..619c3fd7 --- /dev/null +++ b/ruma-identity-service-api/src/lookup/lookup_3pid.rs @@ -0,0 +1,3 @@ +//! Endpoint to look up set of Matrix IDs which are bound to 3PIDs. + +pub mod v2; diff --git a/ruma-identity-service-api/src/lookup/lookup_3pid/v2.rs b/ruma-identity-service-api/src/lookup/lookup_3pid/v2.rs new file mode 100644 index 00000000..40aae9f6 --- /dev/null +++ b/ruma-identity-service-api/src/lookup/lookup_3pid/v2.rs @@ -0,0 +1,59 @@ +//! [POST /_matrix/identity/v2/lookup](https://matrix.org/docs/spec/identity_service/0.3.0#post-matrix-identity-v2-lookup) + +use std::collections::BTreeMap; + +use ruma_api::ruma_api; +use ruma_identifiers::UserId; + +use crate::lookup::IdentifierHashingAlgorithm; + +ruma_api! { + metadata: { + description: "Looks up the set of Matrix User IDs which have bound the 3PIDs given, if bindings are available.", + method: POST, + name: "lookup_3pid", + path: "/_matrix/identity/v2/lookup", + authentication: AccessToken, + rate_limited: false, + } + + request: { + /// The algorithm the client is using to encode the `addresses`. This should be one of the + /// available options from `/hash_details`. + pub algorithm: &'a IdentifierHashingAlgorithm, + + /// The pepper from `/hash_details`. This is required even when the `algorithm` does not + /// make use of it. + pub pepper: &'a str, + + /// The addresses to look up. The format of the entries here depend on the `algorithm` + /// used. Note that queries which have been incorrectly hashed or formatted will lead to no + /// matches. + pub addresses: &'a [String], + } + + response: { + /// Any applicable mappings of `addresses` to Matrix User IDs. Addresses which do not have + /// associations will not be included, which can make this property be an empty object. + pub mappings: BTreeMap, + } +} + +impl<'a> Request<'a> { + /// Create a `Request` with algorithm, pepper and addresses to loop up. + pub fn new( + algorithm: &'a IdentifierHashingAlgorithm, + pepper: &'a str, + addresses: &'a [String], + ) -> Self { + Self { algorithm, pepper, addresses } + } +} + +impl Response { + /// Create a `Response` with the BTreeMap which map addresses from the request which were + /// found to their corresponding User IDs. + pub fn new(mappings: BTreeMap) -> Self { + Self { mappings } + } +}