diff --git a/docs/todo.md b/docs/todo.md index 634bf8e..d8ba798 100644 --- a/docs/todo.md +++ b/docs/todo.md @@ -27,12 +27,12 @@ - [x] ~~5.3.6.1 Matrix User ID~~ - [x] ~~5.3.6.2 Third-party ID~~ - [x] ~~5.3.6.3 Phone number~~ - - [ ] 5.4 Login + - ~~[x] 5.4 Login~~ - [x] 5.4.1 ~~GET /_matrix/client/r0/login~~ - [x] 5.4.2 ~~POST /_matrix/client/r0/login~~ - - [ ] 5.4.3 POST /_matrix/client/r0/logout - - [ ] 5.4.4 POST /_matrix/client/r0/logout/all - - [ ] 5.4.5 Login Fallback + - [x] 5.4.3 ~~POST /_matrix/client/r0/logout~~ + - [x] 5.4.4 ~~POST /_matrix/client/r0/logout/all~~ + - [x] 5.4.5 ~~Login Fallback~~ *Higher level clients should implement this* - [ ] 5.5 Account registration and management - [ ] 5.5.1 POST /_matrix/client/r0/register - [ ] 5.5.2 POST /_matrix/client/r0/register/email/requestToken diff --git a/src/api/client.rs b/src/api/client.rs index c64ace5..1219c49 100644 --- a/src/api/client.rs +++ b/src/api/client.rs @@ -302,7 +302,7 @@ impl Client { // Holds implementation for Section 5.4, Login impl Client { - /// Implementation of [Section 5.4.1 **GET** `/_matrix/client/r0/login`](https://matrix.org/docs/spec/client_server/r0.5.0#get-matrix-client-r0-login). + /// Implementation of [5.4.1 **GET** `/_matrix/client/r0/login`](https://matrix.org/docs/spec/client_server/r0.5.0#get-matrix-client-r0-login). /// /// This request is rate-limited but does not require authentication. pub fn login_flows(&self) -> Result> { @@ -409,6 +409,40 @@ impl Client { )? .json()?) } + + /// Implementation of [5.4.3 **POST** `/_matrix/client/r0/logout`](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-logout) + /// + /// Invalidates an existing access token as well as the associated device. + /// The associated device keys are also deleted. + /// + /// This request is rate-limited but does not require authentication. + pub fn logout(&self) -> Result<(), Box> { + self.send( + MatrixHTTPMethod::Post, + "/_matrix/client/r0/logout", + None, + None, + None, + ) + .map(|_| ()) + } + + /// Implementation of [5.4.4 **POST** `/_matrix/client/r0/logout/all`](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-logout) + /// + /// Invalidates all access tokens as well as all associated devices. + /// The associated device keys are also deleted. + /// + /// This request is rate-limited but does not require authentication. + pub fn logout_all(&self) -> Result<(), Box> { + self.send( + MatrixHTTPMethod::Post, + "/_matrix/client/r0/logout/all", + None, + None, + None, + ) + .map(|_| ()) + } } #[cfg(test)] @@ -488,7 +522,7 @@ mod tests { .json() .unwrap(); - assert_eq!(dbg!(resp)["hello"], "world"); + assert_eq!(resp["hello"], "world"); }); // Override 429 response with valid response after initial request @@ -499,7 +533,43 @@ mod tests { .with_body(r#"{"hello": "world"}"#) .create(); } + + #[test] + fn login_resp_can_be_parsed() { + let _mock_version_check = mock("GET", "/_matrix/client/versions") + .with_body(r#"{"versions": ["r0.5.0"]}"#) + .create(); + + let _m = mock("POST", "/_matrix/client/r0/login") + .with_body( + r#"{ + "access_token": "angery", + "device_id": "HENLOWORLD", + "home_server": "eddie.sh", + "user_id": "@eddie:eddie.sh", + "well_known": { + "m.homeserver": { + "base_url": "https://eddie.sh/" + } + } + }"#, + ) + .create(); + + Client::new("http://dummy.website", None, None, None) + .unwrap() + .login_password( + IdentifierType::User { + user: "hello".to_string(), + }, + "foo", + Some("ABC"), + Some("DEF"), + ) + .unwrap(); + } } + #[derive(Default)] pub struct ApiError {} diff --git a/src/api/methods/login.rs b/src/api/methods/login.rs index ac0961e..cc239d1 100644 --- a/src/api/methods/login.rs +++ b/src/api/methods/login.rs @@ -38,4 +38,19 @@ pub struct LoginResponse { } #[derive(Deserialize)] -pub struct DiscoveryInformation {} +pub struct DiscoveryInformation { + #[serde(rename = "m.homeserver")] + pub homeserver: HomeserverInformation, + #[serde(rename = "m.identity_server")] + pub identity_server: Option, +} + +#[derive(Deserialize)] +pub struct HomeserverInformation { + pub base_url: String, +} + +#[derive(Deserialize)] +pub struct IdentityServerInformation { + pub base_url: String, +}