diff --git a/Cargo.lock b/Cargo.lock index 9c44c295..70d09219 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3478,7 +3478,7 @@ dependencies = [ [[package]] name = "ruma" version = "0.12.6" -source = "git+https://github.com/matrix-construct/ruma?rev=93f28d777073e60687e8013e59d8d16b5adbdf9a#93f28d777073e60687e8013e59d8d16b5adbdf9a" +source = "git+https://github.com/matrix-construct/ruma?rev=5682b88cf1bcaf0f47805d614b476b242ef075d4#5682b88cf1bcaf0f47805d614b476b242ef075d4" dependencies = [ "assign", "js_int", @@ -3497,7 +3497,7 @@ dependencies = [ [[package]] name = "ruma-appservice-api" version = "0.12.2" -source = "git+https://github.com/matrix-construct/ruma?rev=93f28d777073e60687e8013e59d8d16b5adbdf9a#93f28d777073e60687e8013e59d8d16b5adbdf9a" +source = "git+https://github.com/matrix-construct/ruma?rev=5682b88cf1bcaf0f47805d614b476b242ef075d4#5682b88cf1bcaf0f47805d614b476b242ef075d4" dependencies = [ "js_int", "ruma-common", @@ -3509,7 +3509,7 @@ dependencies = [ [[package]] name = "ruma-client-api" version = "0.20.4" -source = "git+https://github.com/matrix-construct/ruma?rev=93f28d777073e60687e8013e59d8d16b5adbdf9a#93f28d777073e60687e8013e59d8d16b5adbdf9a" +source = "git+https://github.com/matrix-construct/ruma?rev=5682b88cf1bcaf0f47805d614b476b242ef075d4#5682b88cf1bcaf0f47805d614b476b242ef075d4" dependencies = [ "as_variant", "assign", @@ -3532,7 +3532,7 @@ dependencies = [ [[package]] name = "ruma-common" version = "0.15.4" -source = "git+https://github.com/matrix-construct/ruma?rev=93f28d777073e60687e8013e59d8d16b5adbdf9a#93f28d777073e60687e8013e59d8d16b5adbdf9a" +source = "git+https://github.com/matrix-construct/ruma?rev=5682b88cf1bcaf0f47805d614b476b242ef075d4#5682b88cf1bcaf0f47805d614b476b242ef075d4" dependencies = [ "as_variant", "base64", @@ -3565,7 +3565,7 @@ dependencies = [ [[package]] name = "ruma-events" version = "0.30.5" -source = "git+https://github.com/matrix-construct/ruma?rev=93f28d777073e60687e8013e59d8d16b5adbdf9a#93f28d777073e60687e8013e59d8d16b5adbdf9a" +source = "git+https://github.com/matrix-construct/ruma?rev=5682b88cf1bcaf0f47805d614b476b242ef075d4#5682b88cf1bcaf0f47805d614b476b242ef075d4" dependencies = [ "as_variant", "indexmap", @@ -3591,7 +3591,7 @@ dependencies = [ [[package]] name = "ruma-federation-api" version = "0.11.2" -source = "git+https://github.com/matrix-construct/ruma?rev=93f28d777073e60687e8013e59d8d16b5adbdf9a#93f28d777073e60687e8013e59d8d16b5adbdf9a" +source = "git+https://github.com/matrix-construct/ruma?rev=5682b88cf1bcaf0f47805d614b476b242ef075d4#5682b88cf1bcaf0f47805d614b476b242ef075d4" dependencies = [ "bytes", "headers", @@ -3613,7 +3613,7 @@ dependencies = [ [[package]] name = "ruma-identifiers-validation" version = "0.10.1" -source = "git+https://github.com/matrix-construct/ruma?rev=93f28d777073e60687e8013e59d8d16b5adbdf9a#93f28d777073e60687e8013e59d8d16b5adbdf9a" +source = "git+https://github.com/matrix-construct/ruma?rev=5682b88cf1bcaf0f47805d614b476b242ef075d4#5682b88cf1bcaf0f47805d614b476b242ef075d4" dependencies = [ "js_int", "thiserror 2.0.16", @@ -3622,7 +3622,7 @@ dependencies = [ [[package]] name = "ruma-macros" version = "0.15.2" -source = "git+https://github.com/matrix-construct/ruma?rev=93f28d777073e60687e8013e59d8d16b5adbdf9a#93f28d777073e60687e8013e59d8d16b5adbdf9a" +source = "git+https://github.com/matrix-construct/ruma?rev=5682b88cf1bcaf0f47805d614b476b242ef075d4#5682b88cf1bcaf0f47805d614b476b242ef075d4" dependencies = [ "cfg-if", "proc-macro-crate", @@ -3637,7 +3637,7 @@ dependencies = [ [[package]] name = "ruma-push-gateway-api" version = "0.11.0" -source = "git+https://github.com/matrix-construct/ruma?rev=93f28d777073e60687e8013e59d8d16b5adbdf9a#93f28d777073e60687e8013e59d8d16b5adbdf9a" +source = "git+https://github.com/matrix-construct/ruma?rev=5682b88cf1bcaf0f47805d614b476b242ef075d4#5682b88cf1bcaf0f47805d614b476b242ef075d4" dependencies = [ "js_int", "ruma-common", @@ -3649,7 +3649,7 @@ dependencies = [ [[package]] name = "ruma-signatures" version = "0.17.1" -source = "git+https://github.com/matrix-construct/ruma?rev=93f28d777073e60687e8013e59d8d16b5adbdf9a#93f28d777073e60687e8013e59d8d16b5adbdf9a" +source = "git+https://github.com/matrix-construct/ruma?rev=5682b88cf1bcaf0f47805d614b476b242ef075d4#5682b88cf1bcaf0f47805d614b476b242ef075d4" dependencies = [ "base64", "ed25519-dalek", diff --git a/Cargo.toml b/Cargo.toml index 5c01381b..99522fa6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -317,7 +317,7 @@ default-features = false [workspace.dependencies.ruma] git = "https://github.com/matrix-construct/ruma" -rev = "93f28d777073e60687e8013e59d8d16b5adbdf9a" +rev = "5682b88cf1bcaf0f47805d614b476b242ef075d4" features = [ "__compat", "appservice-api-c", diff --git a/src/api/client/account.rs b/src/api/client/account.rs index 3dfbd9d5..05e096ca 100644 --- a/src/api/client/account.rs +++ b/src/api/client/account.rs @@ -7,11 +7,11 @@ use ruma::api::client::{ request_3pid_management_token_via_email, request_3pid_management_token_via_msisdn, whoami, }, - uiaa::{AuthFlow, AuthType, UiaaInfo}, + uiaa::{AuthData, AuthFlow, AuthType, Jwt, UiaaInfo}, }; use tuwunel_core::{Err, Error, Result, err, info, utils, utils::ReadyExt}; -use super::SESSION_ID_LENGTH; +use super::{SESSION_ID_LENGTH, session::jwt::validate_user}; use crate::Ruma; /// # `POST /_matrix/client/r0/account/password` @@ -140,20 +140,29 @@ pub(crate) async fn deactivate_route( InsecureClientIp(client): InsecureClientIp, body: Ruma, ) -> Result { - // Authentication for this endpoint was made optional, but we need - // authentication currently - let sender_user = body - .sender_user - .as_ref() - .ok_or_else(|| err!(Request(MissingToken("Missing access token."))))?; - + let pass_flow = AuthFlow { stages: vec![AuthType::Password] }; + let jwt_flow = AuthFlow { stages: vec![AuthType::Jwt] }; let mut uiaainfo = UiaaInfo { - flows: vec![AuthFlow { stages: vec![AuthType::Password] }], + flows: [pass_flow, jwt_flow].into(), ..Default::default() }; - match &body.auth { + let sender_user = match &body.auth { + | Some(AuthData::Jwt(Jwt { token, .. })) => { + let sender_user = validate_user(&services, token)?; + if !services.users.exists(&sender_user).await { + return Err!(Request(NotFound("User {sender_user} is not registered."))); + } + + // Success! + sender_user + }, | Some(auth) => { + let sender_user = body + .sender_user + .as_deref() + .ok_or_else(|| err!(Request(MissingToken("Missing access token."))))?; + let (worked, uiaainfo) = services .uiaa .try_auth(sender_user, body.sender_device(), auth, &uiaainfo) @@ -162,10 +171,17 @@ pub(crate) async fn deactivate_route( if !worked { return Err(Error::Uiaa(uiaainfo)); } + // Success! + sender_user.to_owned() }, | _ => match body.json_body { | Some(ref json) => { + let sender_user = body + .sender_user + .as_ref() + .ok_or_else(|| err!(Request(MissingToken("Missing access token."))))?; + uiaainfo.session = Some(utils::random_string(SESSION_ID_LENGTH)); services .uiaa @@ -177,11 +193,11 @@ pub(crate) async fn deactivate_route( return Err!(Request(NotJson("JSON body is not valid"))); }, }, - } + }; services .deactivate - .full_deactivate(sender_user) + .full_deactivate(&sender_user) .boxed() .await?; diff --git a/src/api/client/session/jwt.rs b/src/api/client/session/jwt.rs index 8016f90d..60839aa4 100644 --- a/src/api/client/session/jwt.rs +++ b/src/api/client/session/jwt.rs @@ -22,20 +22,9 @@ pub(super) async fn handle_login( _body: &Ruma, info: &Token, ) -> Result { - let config = &services.config.jwt; - - if !config.enable { - return Err!(Request(Unknown("JWT login is not enabled."))); - } - - let claim = validate(config, &info.token)?; - let local = claim.sub.to_lowercase(); - let server = &services.server.name; - let user_id = UserId::parse_with_server_name(local, server).map_err(|e| { - err!(Request(InvalidUsername("JWT subject is not a valid user MXID: {e}"))) - })?; - + let user_id = validate_user(services, &info.token)?; if !services.users.exists(&user_id).await { + let config = &services.config.jwt; if !config.register_user { return Err!(Request(NotFound("User {user_id} is not registered on this server."))); } @@ -49,6 +38,22 @@ pub(super) async fn handle_login( Ok(user_id) } +pub(crate) fn validate_user(services: &Services, token: &str) -> Result { + let config = &services.config.jwt; + if !config.enable { + return Err!(Request(Unauthorized("JWT login is not enabled."))); + } + + let claim = validate(config, token)?; + let local = claim.sub.to_lowercase(); + let server = &services.server.name; + let user_id = UserId::parse_with_server_name(local, server).map_err(|e| { + err!(Request(InvalidUsername("JWT subject is not a valid user MXID: {e}"))) + })?; + + Ok(user_id) +} + fn validate(config: &JwtConfig, token: &str) -> Result { let verifier = init_verifier(config)?; let validator = init_validator(config)?; diff --git a/src/api/client/session/mod.rs b/src/api/client/session/mod.rs index 18a2fffb..a158684a 100644 --- a/src/api/client/session/mod.rs +++ b/src/api/client/session/mod.rs @@ -1,5 +1,5 @@ mod appservice; -mod jwt; +pub(crate) mod jwt; mod ldap; mod logout; mod password;