From 3640f72d7324c6f81b80658e8124d0cf7217b6a2 Mon Sep 17 00:00:00 2001 From: Pierre HUBERT Date: Thu, 27 Feb 2025 20:08:13 +0100 Subject: [PATCH] Can get user information --- src/main.rs | 5 ++++- src/server/api/mod.rs | 1 + src/server/api/profile.rs | 29 +++++++++++++++++++++++++++++ src/server/api/room.rs | 26 ++++++++++---------------- src/utils/matrix_utils.rs | 22 +++++++++++++++------- 5 files changed, 59 insertions(+), 24 deletions(-) create mode 100644 src/server/api/profile.rs diff --git a/src/main.rs b/src/main.rs index 042ab74..3463bdf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -68,7 +68,10 @@ async fn main() -> std::io::Result<()> { ) // TODO : handle media thumbnail // TODO : handle space - // TODO : handle user information + .route( + "/api/profile/{user_id}", + web::get().to(api::profile::get_profile), + ) .service(web::resource("/api/ws").route(web::get().to(api::ws::ws))) }) .workers(4) diff --git a/src/server/api/mod.rs b/src/server/api/mod.rs index 4023782..73a26c8 100644 --- a/src/server/api/mod.rs +++ b/src/server/api/mod.rs @@ -4,6 +4,7 @@ use actix_web::HttpResponse; pub mod account; pub mod media; +pub mod profile; pub mod room; pub mod ws; diff --git a/src/server/api/profile.rs b/src/server/api/profile.rs new file mode 100644 index 0000000..d37e612 --- /dev/null +++ b/src/server/api/profile.rs @@ -0,0 +1,29 @@ +use crate::extractors::client_auth::APIClientAuth; +use crate::server::HttpResult; +use crate::utils::matrix_utils::ApiMxcURI; +use actix_web::{web, HttpResponse}; +use ruma::api::client::profile; +use ruma::OwnedUserId; + +#[derive(serde::Deserialize)] +pub struct UserIDInPath { + user_id: OwnedUserId, +} + +#[derive(serde::Serialize)] +struct ProfileResponse { + display_name: Option, + avatar: Option, +} + +/// Get user profile +pub async fn get_profile(auth: APIClientAuth, path: web::Path) -> HttpResult { + let res = auth + .send_request(profile::get_profile::v3::Request::new(path.user_id.clone())) + .await?; + + Ok(HttpResponse::Ok().json(ProfileResponse { + display_name: res.displayname, + avatar: res.avatar_url.map(ApiMxcURI), + })) +} diff --git a/src/server/api/room.rs b/src/server/api/room.rs index 587f6c0..47430cc 100644 --- a/src/server/api/room.rs +++ b/src/server/api/room.rs @@ -1,10 +1,10 @@ use crate::extractors::client_auth::APIClientAuth; use crate::server::HttpResult; -use crate::utils::matrix_utils::parse_mxc_url; +use crate::utils::matrix_utils::ApiMxcURI; use actix_web::{web, HttpResponse}; use ruma::api::client::state; use ruma::events::StateEventType; -use ruma::{OwnedRoomId, OwnedServerName}; +use ruma::{OwnedMxcUri, OwnedRoomId}; #[derive(serde::Deserialize)] pub struct RoomIDInPath { @@ -32,11 +32,7 @@ pub async fn name(auth: APIClientAuth, path: web::Path) -> HttpRes } #[derive(serde::Serialize)] -struct GetRoomAvatarResponse { - url: String, - server_name: OwnedServerName, - media_id: String, -} +struct GetRoomAvatarResponse(ApiMxcURI); /// Get room avatar pub async fn avatar(auth: APIClientAuth, path: web::Path) -> HttpResult { @@ -48,14 +44,12 @@ pub async fn avatar(auth: APIClientAuth, path: web::Path) -> HttpR )) .await?; - let avatar_url = res.content.get_field("url")?.unwrap_or("").to_string(); - let Some((media_id, server_name)) = parse_mxc_url(&avatar_url) else { - return Ok(HttpResponse::InternalServerError().body("Invalid Matrix resource URL")); - }; + let avatar_url: Option = res.content.get_field("url")?; - Ok(HttpResponse::Ok().json(GetRoomAvatarResponse { - url: avatar_url.to_string(), - server_name, - media_id: media_id.to_string(), - })) + match avatar_url { + None => Ok(HttpResponse::NotFound().body("No avatar found for this room.")), + Some(avatar_url) => { + Ok(HttpResponse::Ok().json(GetRoomAvatarResponse(ApiMxcURI(avatar_url)))) + } + } } diff --git a/src/utils/matrix_utils.rs b/src/utils/matrix_utils.rs index 74da455..f780db9 100644 --- a/src/utils/matrix_utils.rs +++ b/src/utils/matrix_utils.rs @@ -1,10 +1,18 @@ -use ruma::OwnedServerName; -use std::str::FromStr; +use ruma::OwnedMxcUri; +use serde::ser::SerializeMap; +use serde::{Serialize, Serializer}; -/// Parse Matrix media URL returning media id and server name -pub fn parse_mxc_url(url: &str) -> Option<(&str, OwnedServerName)> { - let strip = url.strip_prefix("mxc://")?; - let parts = strip.split_once('/')?; +pub struct ApiMxcURI(pub OwnedMxcUri); - Some((parts.0, OwnedServerName::from_str(parts.1).ok()?)) +impl Serialize for ApiMxcURI { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let mut map = serializer.serialize_map(Some(3))?; + map.serialize_entry("uri", &self.0)?; + map.serialize_entry("server_name", &self.0.server_name().ok())?; + map.serialize_entry("media_id", &self.0.media_id().ok())?; + map.end() + } }