diff --git a/crates/ruma-identity-service-api/CHANGELOG.md b/crates/ruma-identity-service-api/CHANGELOG.md index cf0136db..256fe117 100644 --- a/crates/ruma-identity-service-api/CHANGELOG.md +++ b/crates/ruma-identity-service-api/CHANGELOG.md @@ -11,6 +11,7 @@ Improvements: * Add more endpoints: ```rust + association::unbind_3pid::v2, invitation::store_invitation::v2 ``` diff --git a/crates/ruma-identity-service-api/src/association.rs b/crates/ruma-identity-service-api/src/association.rs index 477aaf60..c237b41e 100644 --- a/crates/ruma-identity-service-api/src/association.rs +++ b/crates/ruma-identity-service-api/src/association.rs @@ -4,3 +4,4 @@ pub mod bind_3pid; pub mod check_3pid_validity; pub mod email; pub mod msisdn; +pub mod unbind_3pid; diff --git a/crates/ruma-identity-service-api/src/association/unbind_3pid.rs b/crates/ruma-identity-service-api/src/association/unbind_3pid.rs new file mode 100644 index 00000000..7e744e15 --- /dev/null +++ b/crates/ruma-identity-service-api/src/association/unbind_3pid.rs @@ -0,0 +1,3 @@ +//! Endpoint to remove an association between a session and a Matrix user ID. + +pub mod v2; diff --git a/crates/ruma-identity-service-api/src/association/unbind_3pid/v2.rs b/crates/ruma-identity-service-api/src/association/unbind_3pid/v2.rs new file mode 100644 index 00000000..e34acf90 --- /dev/null +++ b/crates/ruma-identity-service-api/src/association/unbind_3pid/v2.rs @@ -0,0 +1,94 @@ +//! [POST /_matrix/identity/v2/3pid/unbind](https://matrix.org/docs/spec/identity_service/r0.3.0#post-matrix-identity-v2-3pid-unbind) + +use ruma_api::ruma_api; +use ruma_common::thirdparty::Medium; +use ruma_identifiers::{user_id::UserId, ClientSecretBox, SessionIdBox}; +use serde::{Deserialize, Serialize}; + +ruma_api! { + metadata: { + description: "Remove an association between a session and a Matrix user ID.", + method: POST, + name: "unbind_3pid", + path: "/_matrix/identity/v2/3pid/unbind", + rate_limited: false, + authentication: AccessToken, + } + + request: { + /// The proof that the client owns the 3PID. + /// + /// If this is not provided, the request must be signed by the homeserver which controls + /// the `mxid`. + #[serde(flatten)] + #[serde(skip_serializing_if = "Option::is_none")] + pub threepid_ownership_proof: Option<&'a ThreePidOwnershipProof>, + + /// The Matrix user ID to remove from the 3PIDs. + pub mxid: &'a UserId, + + /// The 3PID to remove. Must match the 3PID used to generate the session if using `sid` and + /// `client_secret` to authenticate this request. + pub threepid: &'a ThirdPartyId, + } + + #[derive(Default)] + response: {} +} + +impl<'a> Request<'a> { + /// Creates a `Request` with the given Session ID, client secret, Matrix user ID and 3PID. + pub fn new( + threepid_ownership_proof: Option<&'a ThreePidOwnershipProof>, + mxid: &'a UserId, + threepid: &'a ThirdPartyId, + ) -> Self { + Self { threepid_ownership_proof, mxid, threepid } + } +} + +impl Response { + /// Creates an empty `Response`. + pub fn new() -> Self { + Self {} + } +} + +/// A 3PID to unbind. +#[derive(Clone, Debug, Serialize, Deserialize)] +#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] +pub struct ThirdPartyId { + /// A medium matching the medium of identifier to unbind. + pub medium: Medium, + + /// The 3PID address to remove. + pub address: String, +} + +impl ThirdPartyId { + /// Creates a new `ThirdPartyId` with the given medium and address. + pub fn new(medium: Medium, address: String) -> Self { + Self { medium, address } + } +} + +/// A proof that the client owns the 3PID. +/// +/// Must be constructed using the same session ID and client secret generated and passed by the +/// `requestToken` call for the given 3PID. +#[derive(Clone, Debug, Serialize, Deserialize)] +#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] +pub struct ThreePidOwnershipProof { + /// The Session ID generated by the `requestToken` call. + pub sid: SessionIdBox, + + /// The client secret passed to the `requestToken` call. + pub client_secret: ClientSecretBox, +} + +impl ThreePidOwnershipProof { + /// Creates a new `ThreePidOwnershipProof` with the given session ID and client secret. + pub fn new(sid: SessionIdBox, client_secret: ClientSecretBox) -> Self { + Self { sid, client_secret } + } +}