use std::error::Error;
use matrix_sdk::Client;
use ruma::{api::client::discovery::get_authentication_issuer, OwnedDeviceId};
use serde::Deserialize;
use tracing::{debug, warn};
use url::Url;
pub(crate) async fn fetch_auth_issuer(client: &Client) -> Option<Url> {
let res = client
.send(get_authentication_issuer::msc2965::Request::new())
.await;
if let Err(error) = &res {
debug!("Could not fetch authentication issuer: {error:?}");
}
let issuer = res.ok()?.issuer;
match issuer.parse() {
Ok(url) => Some(url),
Err(error) => {
warn!("Could not parse authentication issuer `{issuer}` as a URL: {error}");
None
}
}
}
#[derive(Debug, Clone, Deserialize)]
struct ProviderMetadata {
account_management_uri: Url,
}
pub(crate) async fn discover_account_management_url(
client: &Client,
issuer: Url,
) -> Result<Url, Box<dyn Error + Send + Sync>> {
let mut config_url = issuer;
if !config_url.path().ends_with('/') {
let mut path = config_url.path().to_owned();
path.push('/');
config_url.set_path(&path);
}
let config_url = config_url.join(".well-known/openid-configuration")?;
let http_client = client.http_client();
let body = http_client
.get(config_url)
.send()
.await?
.error_for_status()?
.bytes()
.await?;
let metadata = serde_json::from_slice::<ProviderMetadata>(&body)?;
Ok(metadata.account_management_uri)
}
#[derive(Debug, Clone)]
pub(crate) enum AccountManagementAction {
Profile,
SessionEnd { device_id: OwnedDeviceId },
AccountDeactivate,
}
impl AccountManagementAction {
fn action_name(&self) -> &str {
match self {
Self::Profile => "org.matrix.profile",
Self::SessionEnd { .. } => "org.matrix.session_end",
Self::AccountDeactivate => "org.matrix.account_deactivate",
}
}
fn extra_data(&self) -> Option<(&str, &str)> {
match self {
Self::SessionEnd { device_id } => Some(("device_id", device_id.as_str())),
_ => None,
}
}
pub(crate) fn add_to_account_management_url(&self, url: &mut Url) {
let mut query_pairs = url.query_pairs_mut();
query_pairs.append_pair("action", self.action_name());
if let Some((name, value)) = self.extra_data() {
query_pairs.append_pair(name, value);
}
}
}