From 062c5521f026ac98d899ded4137297476dad8988 Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 9 Apr 2020 18:49:27 +0200 Subject: [PATCH 1/5] Add displayname and avatar_url endpoints Add PUT and GET /_matrix/client/r0/profile/{userId}/displayname Endpoint Add PUT and GET /_matrix/client/r0/profile/{userId}/avatar_url Endpoint Add GET /_matrix/client/r0/profile/{userId} Endpoint Took 2 hours 16 minutes --- src/data.rs | 34 ++++++++++++ src/database.rs | 20 +++++++ src/main.rs | 136 +++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 189 insertions(+), 1 deletion(-) diff --git a/src/data.rs b/src/data.rs index dffb1e04..3ec3b44a 100644 --- a/src/data.rs +++ b/src/data.rs @@ -60,6 +60,40 @@ impl Data { .map(|bytes| utils::string_from_bytes(&bytes)) } + /// Set a new displayname. + pub fn displayname_set(&self, user_id: &UserId, displayname: Option) { + self.db + .profile_displayname + .insert(user_id.to_string(), &*displayname.unwrap_or_default()) + .unwrap(); + } + + /// Get a the displayname of a user. + pub fn displayname_get(&self, user_id: &UserId) -> Option { + self.db + .profile_displayname + .get(user_id.to_string()) + .unwrap() + .map(|bytes| utils::string_from_bytes(&bytes)) + } + + /// Set a new avatar_url. + pub fn avatar_url_set(&self, user_id: &UserId, avatar_url: String) { + self.db + .profile_avatar_url + .insert(user_id.to_string(), &*avatar_url) + .unwrap(); + } + + /// Get a the avatar_url of a user. + pub fn avatar_url_get(&self, user_id: &UserId) -> Option { + self.db + .profile_avatar_url + .get(user_id.to_string()) + .unwrap() + .map(|bytes| utils::string_from_bytes(&bytes)) + } + /// Add a new device to a user. pub fn device_add(&self, user_id: &UserId, device_id: &str) { if self diff --git a/src/database.rs b/src/database.rs index dee2e944..a6ddd552 100644 --- a/src/database.rs +++ b/src/database.rs @@ -52,6 +52,8 @@ impl MultiValue { pub struct Database { pub userid_password: sled::Tree, pub userid_deviceids: MultiValue, + pub profile_displayname: sled::Tree, + pub profile_avatar_url: sled::Tree, pub deviceid_token: sled::Tree, pub token_userid: sled::Tree, pub pduid_pdus: sled::Tree, @@ -75,6 +77,8 @@ impl Database { Self { userid_password: db.open_tree("userid_password").unwrap(), userid_deviceids: MultiValue(db.open_tree("userid_deviceids").unwrap()), + profile_displayname: db.open_tree("profile_displayname").unwrap(), + profile_avatar_url: db.open_tree("profile_avatar_url").unwrap(), deviceid_token: db.open_tree("deviceid_token").unwrap(), token_userid: db.open_tree("token_userid").unwrap(), pduid_pdus: db.open_tree("pduid_pdus").unwrap(), @@ -103,6 +107,22 @@ impl Database { String::from_utf8_lossy(&v), ); } + println!("# AccountData -> Displayname:"); + for (k, v) in self.profile_displayname.iter().map(|r| r.unwrap()) { + println!( + "{:?} -> {:?}", + String::from_utf8_lossy(&k), + String::from_utf8_lossy(&v), + ); + } + println!("# AccountData -> AvatarURL:"); + for (k, v) in self.profile_avatar_url.iter().map(|r| r.unwrap()) { + println!( + "{:?} -> {:?}", + String::from_utf8_lossy(&k), + String::from_utf8_lossy(&v), + ); + } println!("\n# DeviceId -> Token:"); for (k, v) in self.deviceid_token.iter().map(|r| r.unwrap()) { println!( diff --git a/src/main.rs b/src/main.rs index 92cb6d1f..41c7e6c4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -26,6 +26,9 @@ use ruma_client_api::{ membership::{join_room_by_id, join_room_by_id_or_alias}, message::create_message_event, presence::set_presence, + profile::{ + get_avatar_url, get_display_name, get_profile, set_avatar_url, set_display_name, + }, push::get_pushrules_all, room::create_room, session::{get_login_types, login}, @@ -39,7 +42,12 @@ use ruma_events::{collections::only::Event, EventType}; use ruma_identifiers::{RoomId, RoomIdOrAliasId, UserId}; use ruma_wrapper::{MatrixResult, Ruma}; use serde_json::json; -use std::{collections::HashMap, convert::TryInto, path::PathBuf, time::Duration}; +use std::{ + collections::HashMap, + convert::{TryFrom, TryInto}, + path::PathBuf, + time::Duration, +}; const GUEST_NAME_LENGTH: usize = 10; const DEVICE_ID_LENGTH: usize = 10; @@ -282,6 +290,127 @@ fn get_global_account_data_route( })) } +#[put("/_matrix/client/r0/profile/<_user_id>/displayname", data = "")] +fn set_displayname_route( + data: State, + body: Ruma, + _user_id: String, +) -> MatrixResult { + let user_id = body.user_id.clone().expect("user is authenticated"); + if body.displayname.is_none() { + debug!("Request was missing the displayname payload."); + return MatrixResult(Err(Error { + kind: ErrorKind::MissingParam, + message: "Missing displayname".to_owned(), + status_code: http::StatusCode::BAD_REQUEST, + })); + } + + data.displayname_set(&user_id, body.displayname.clone()); + // TODO send a new m.room.member join event with the updated displayname + // TODO send a new m.presence event with the updated displayname + + MatrixResult(Ok(set_display_name::Response)) +} + +#[get( + "/_matrix/client/r0/profile//displayname", + data = "" +)] +fn get_displayname_route( + data: State, + body: Ruma, + user_id_raw: String, +) -> MatrixResult { + let user_id = (*body).user_id.clone(); + if let Some(displayname) = data.displayname_get(&user_id) { + return MatrixResult(Ok(get_display_name::Response { + displayname: Some(displayname), + })); + } + + // Return 404 if we don't have any + debug!("Profile was not found."); + MatrixResult(Err(Error { + kind: ErrorKind::NotFound, + message: "Profile was not found".to_owned(), + status_code: http::StatusCode::NOT_FOUND, + })) +} +#[put("/_matrix/client/r0/profile/<_user_id>/avatar_url", data = "")] +fn set_avatar_url_route( + data: State, + body: Ruma, + _user_id: String, +) -> MatrixResult { + let user_id = body.user_id.clone().expect("user is authenticated"); + if body.avatar_url == "" { + debug!("Request was missing the avatar_url payload."); + return MatrixResult(Err(Error { + kind: ErrorKind::MissingParam, + message: "Missing avatar_url".to_owned(), + status_code: http::StatusCode::BAD_REQUEST, + })); + } + + // TODO in the future when we can handle media uploads make sure that this url is our own server + // TODO also make sure this is mxc:// format + + data.avatar_url_set(&user_id, body.avatar_url.clone()); + // TODO send a new m.room.member join event with the updated avatar_url + // TODO send a new m.presence event with the updated avatar_url + + MatrixResult(Ok(set_avatar_url::Response)) +} + +#[get("/_matrix/client/r0/profile//avatar_url", data = "")] +fn get_avatar_url_route( + data: State, + body: Ruma, + user_id_raw: String, +) -> MatrixResult { + let user_id = (*body).user_id.clone(); + if let Some(avatar_url) = data.avatar_url_get(&user_id) { + return MatrixResult(Ok(get_avatar_url::Response { + avatar_url: Some(avatar_url), + })); + } + + // Return 404 if we don't have a profile for this id + debug!("Profile was not found."); + MatrixResult(Err(Error { + kind: ErrorKind::NotFound, + message: "Profile was not found".to_owned(), + status_code: http::StatusCode::NOT_FOUND, + })) +} + +#[get("/_matrix/client/r0/profile/", data = "")] +fn get_profile_route( + data: State, + body: Ruma, + user_id_raw: String, +) -> MatrixResult { + let user_id = (*body).user_id.clone(); + let avatar_url = data.avatar_url_get(&user_id); + let displayname = data.displayname_get(&user_id); + + if avatar_url.is_some() && displayname.is_some() { + return MatrixResult(Ok(get_profile::Response { + avatar_url, + displayname, + })); + } + + // Return 404 if we don't have a profile for this id + debug!("Profile was not found."); + MatrixResult(Err(Error { + kind: ErrorKind::NotFound, + message: "Profile was not found".to_owned(), + status_code: http::StatusCode::NOT_FOUND, + })) +} + #[put("/_matrix/client/r0/presence/<_user_id>/status", data = "")] fn set_presence_route( body: Ruma, @@ -634,6 +763,11 @@ fn main() { create_filter_route, set_global_account_data_route, get_global_account_data_route, + set_displayname_route, + get_displayname_route, + set_avatar_url_route, + get_avatar_url_route, + get_profile_route, set_presence_route, get_keys_route, upload_keys_route, From b1284fd50966058f388fa672be79ba0412491eee Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 9 Apr 2020 20:47:03 +0200 Subject: [PATCH 2/5] Replace profile_* with userid_* Add a missing dot in the errormessage Require mxc:// to be present at the start of an avatar_url Update mxc check TODO Show displayname or avatar_url if either is available when getting the profile Endpoint Return the correct data in case of a empty displayname or an empty avatar_url Took 50 minutes Took 34 seconds --- src/data.rs | 18 ++++++-- src/database.rs | 12 ++--- src/main.rs | 113 ++++++++++++++++++++++++++++++------------------ 3 files changed, 91 insertions(+), 52 deletions(-) diff --git a/src/data.rs b/src/data.rs index 3ec3b44a..ef30e273 100644 --- a/src/data.rs +++ b/src/data.rs @@ -60,10 +60,15 @@ impl Data { .map(|bytes| utils::string_from_bytes(&bytes)) } + /// Removes a displayname. + pub fn displayname_remove(&self, user_id: &UserId) { + self.db.userid_displayname.remove(user_id).unwrap(); + } + /// Set a new displayname. pub fn displayname_set(&self, user_id: &UserId, displayname: Option) { self.db - .profile_displayname + .userid_displayname .insert(user_id.to_string(), &*displayname.unwrap_or_default()) .unwrap(); } @@ -71,16 +76,21 @@ impl Data { /// Get a the displayname of a user. pub fn displayname_get(&self, user_id: &UserId) -> Option { self.db - .profile_displayname + .userid_displayname .get(user_id.to_string()) .unwrap() .map(|bytes| utils::string_from_bytes(&bytes)) } + /// Removes a avatar_url. + pub fn avatar_url_remove(&self, user_id: &UserId) { + self.db.userid_avatar_url.remove(user_id).unwrap(); + } + /// Set a new avatar_url. pub fn avatar_url_set(&self, user_id: &UserId, avatar_url: String) { self.db - .profile_avatar_url + .userid_avatar_url .insert(user_id.to_string(), &*avatar_url) .unwrap(); } @@ -88,7 +98,7 @@ impl Data { /// Get a the avatar_url of a user. pub fn avatar_url_get(&self, user_id: &UserId) -> Option { self.db - .profile_avatar_url + .userid_avatar_url .get(user_id.to_string()) .unwrap() .map(|bytes| utils::string_from_bytes(&bytes)) diff --git a/src/database.rs b/src/database.rs index a6ddd552..bdfab5b1 100644 --- a/src/database.rs +++ b/src/database.rs @@ -52,8 +52,8 @@ impl MultiValue { pub struct Database { pub userid_password: sled::Tree, pub userid_deviceids: MultiValue, - pub profile_displayname: sled::Tree, - pub profile_avatar_url: sled::Tree, + pub userid_displayname: sled::Tree, + pub userid_avatar_url: sled::Tree, pub deviceid_token: sled::Tree, pub token_userid: sled::Tree, pub pduid_pdus: sled::Tree, @@ -77,8 +77,8 @@ impl Database { Self { userid_password: db.open_tree("userid_password").unwrap(), userid_deviceids: MultiValue(db.open_tree("userid_deviceids").unwrap()), - profile_displayname: db.open_tree("profile_displayname").unwrap(), - profile_avatar_url: db.open_tree("profile_avatar_url").unwrap(), + userid_displayname: db.open_tree("userid_displayname").unwrap(), + userid_avatar_url: db.open_tree("userid_avatar_url").unwrap(), deviceid_token: db.open_tree("deviceid_token").unwrap(), token_userid: db.open_tree("token_userid").unwrap(), pduid_pdus: db.open_tree("pduid_pdus").unwrap(), @@ -108,7 +108,7 @@ impl Database { ); } println!("# AccountData -> Displayname:"); - for (k, v) in self.profile_displayname.iter().map(|r| r.unwrap()) { + for (k, v) in self.userid_displayname.iter().map(|r| r.unwrap()) { println!( "{:?} -> {:?}", String::from_utf8_lossy(&k), @@ -116,7 +116,7 @@ impl Database { ); } println!("# AccountData -> AvatarURL:"); - for (k, v) in self.profile_avatar_url.iter().map(|r| r.unwrap()) { + for (k, v) in self.userid_avatar_url.iter().map(|r| r.unwrap()) { println!( "{:?} -> {:?}", String::from_utf8_lossy(&k), diff --git a/src/main.rs b/src/main.rs index 41c7e6c4..3bc1e4bf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@ #![feature(proc_macro_hygiene, decl_macro)] + mod data; mod database; mod pdu; @@ -88,7 +89,7 @@ fn register_route( .unwrap_or_else(|| utils::random_string(GUEST_NAME_LENGTH)), data.hostname() )) - .try_into() + .try_into() { Err(_) => { debug!("Username invalid"); @@ -152,7 +153,7 @@ fn login_route(data: State, body: Ruma) -> MatrixResult MatrixResult { } #[get( - "/_matrix/client/r0/user/<_user_id>/filter/<_filter_id>", - data = "" +"/_matrix/client/r0/user/<_user_id>/filter/<_filter_id>", +data = "" )] fn get_filter_route( body: Ruma, @@ -261,8 +262,8 @@ fn create_filter_route( } #[put( - "/_matrix/client/r0/user/<_user_id>/account_data/<_type>", - data = "" +"/_matrix/client/r0/user/<_user_id>/account_data/<_type>", +data = "" )] fn set_global_account_data_route( body: Ruma, @@ -274,8 +275,8 @@ fn set_global_account_data_route( } #[get( - "/_matrix/client/r0/user/<_user_id>/account_data/<_type>", - data = "" +"/_matrix/client/r0/user/<_user_id>/account_data/<_type>", +data = "" )] fn get_global_account_data_route( body: Ruma, @@ -297,25 +298,35 @@ fn set_displayname_route( _user_id: String, ) -> MatrixResult { let user_id = body.user_id.clone().expect("user is authenticated"); + + // Send error on None and accept Some("") as valid username + // Synapse returns a parsing error but the spec doesn't require this if body.displayname.is_none() { debug!("Request was missing the displayname payload."); return MatrixResult(Err(Error { kind: ErrorKind::MissingParam, - message: "Missing displayname".to_owned(), + message: "Missing displayname.".to_owned(), status_code: http::StatusCode::BAD_REQUEST, })); } - data.displayname_set(&user_id, body.displayname.clone()); - // TODO send a new m.room.member join event with the updated displayname - // TODO send a new m.presence event with the updated displayname + if let Some(displayname) = body.displayname { + if displayname == "" { + data.displayname_remove(&user_id); + } else { + data.displayname_set(&user_id, body.displayname.clone()); + // TODO send a new m.room.member join event with the updated displayname + // TODO send a new m.presence event with the updated displayname + + } + } MatrixResult(Ok(set_display_name::Response)) } #[get( - "/_matrix/client/r0/profile//displayname", - data = "" +"/_matrix/client/r0/profile//displayname", +data = "" )] fn get_displayname_route( data: State, @@ -323,20 +334,26 @@ fn get_displayname_route( user_id_raw: String, ) -> MatrixResult { let user_id = (*body).user_id.clone(); + if !data.user_exists(&user_id) { + // Return 404 if we don't have a profile for this id + debug!("Profile was not found."); + MatrixResult(Err(Error { + kind: ErrorKind::NotFound, + message: "Profile was not found".to_owned(), + status_code: http::StatusCode::NOT_FOUND, + })) + } if let Some(displayname) = data.displayname_get(&user_id) { return MatrixResult(Ok(get_display_name::Response { displayname: Some(displayname), })); } - // Return 404 if we don't have any - debug!("Profile was not found."); - MatrixResult(Err(Error { - kind: ErrorKind::NotFound, - message: "Profile was not found".to_owned(), - status_code: http::StatusCode::NOT_FOUND, + MatrixResult(Ok(get_display_name::Response { + displayname: None, })) } + #[put("/_matrix/client/r0/profile/<_user_id>/avatar_url", data = "")] fn set_avatar_url_route( data: State, @@ -344,21 +361,28 @@ fn set_avatar_url_route( _user_id: String, ) -> MatrixResult { let user_id = body.user_id.clone().expect("user is authenticated"); - if body.avatar_url == "" { - debug!("Request was missing the avatar_url payload."); + + if !body.avatar_url.starts_with("mxc://") { + debug!("Request contains an invalid avatar_url."); return MatrixResult(Err(Error { - kind: ErrorKind::MissingParam, + kind: ErrorKind::InvalidParam, message: "Missing avatar_url".to_owned(), status_code: http::StatusCode::BAD_REQUEST, })); } // TODO in the future when we can handle media uploads make sure that this url is our own server - // TODO also make sure this is mxc:// format + // TODO also make sure this is valid mxc:// format (not only starting with it) - data.avatar_url_set(&user_id, body.avatar_url.clone()); - // TODO send a new m.room.member join event with the updated avatar_url - // TODO send a new m.presence event with the updated avatar_url + + if body.avatar_url == "" { + data.avatar_url_remove(&user_id); + } else { + data.avatar_url_set(&user_id, body.displayname.clone()); + // TODO send a new m.room.member join event with the updated avatar_url + // TODO send a new m.presence event with the updated avatar_url + + } MatrixResult(Ok(set_avatar_url::Response)) } @@ -370,18 +394,23 @@ fn get_avatar_url_route( user_id_raw: String, ) -> MatrixResult { let user_id = (*body).user_id.clone(); + if !data.user_exists(&user_id) { + // Return 404 if we don't have a profile for this id + debug!("Profile was not found."); + MatrixResult(Err(Error { + kind: ErrorKind::NotFound, + message: "Profile was not found".to_owned(), + status_code: http::StatusCode::NOT_FOUND, + })) + } if let Some(avatar_url) = data.avatar_url_get(&user_id) { return MatrixResult(Ok(get_avatar_url::Response { avatar_url: Some(avatar_url), })); } - // Return 404 if we don't have a profile for this id - debug!("Profile was not found."); - MatrixResult(Err(Error { - kind: ErrorKind::NotFound, - message: "Profile was not found".to_owned(), - status_code: http::StatusCode::NOT_FOUND, + MatrixResult(Ok(get_avatar_url::Response { + avatar_url: None, })) } @@ -395,7 +424,7 @@ fn get_profile_route( let avatar_url = data.avatar_url_get(&user_id); let displayname = data.displayname_get(&user_id); - if avatar_url.is_some() && displayname.is_some() { + if avatar_url.is_some() || displayname.is_some() { return MatrixResult(Ok(get_profile::Response { avatar_url, displayname, @@ -498,8 +527,8 @@ fn get_alias_route(room_alias: String) -> MatrixResult { })); } } - .try_into() - .unwrap(); + .try_into() + .unwrap(); MatrixResult(Ok(get_alias::Response { room_id, @@ -606,8 +635,8 @@ fn get_protocols_route( } #[put( - "/_matrix/client/r0/rooms/<_room_id>/send/<_event_type>/<_txn_id>", - data = "" +"/_matrix/client/r0/rooms/<_room_id>/send/<_event_type>/<_txn_id>", +data = "" )] fn create_message_event_route( data: State, @@ -631,8 +660,8 @@ fn create_message_event_route( } #[put( - "/_matrix/client/r0/rooms/<_room_id>/state/<_event_type>/<_state_key>", - data = "" +"/_matrix/client/r0/rooms/<_room_id>/state/<_event_type>/<_state_key>", +data = "" )] fn create_state_event_for_key_route( data: State, @@ -654,8 +683,8 @@ fn create_state_event_for_key_route( } #[put( - "/_matrix/client/r0/rooms/<_room_id>/state/<_event_type>", - data = "" +"/_matrix/client/r0/rooms/<_room_id>/state/<_event_type>", +data = "" )] fn create_state_event_for_empty_key_route( data: State, From 49fe5e32710ee502bd10da843571c6e7cba2390a Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 9 Apr 2020 21:01:39 +0200 Subject: [PATCH 3/5] Rename userid_avatar_url to userid_avatarurl and fix debug print Run cargo fmt Took 5 minutes --- src/data.rs | 6 +++--- src/database.rs | 10 +++++----- src/main.rs | 47 ++++++++++++++++++++--------------------------- 3 files changed, 28 insertions(+), 35 deletions(-) diff --git a/src/data.rs b/src/data.rs index ef30e273..70cd2f88 100644 --- a/src/data.rs +++ b/src/data.rs @@ -84,13 +84,13 @@ impl Data { /// Removes a avatar_url. pub fn avatar_url_remove(&self, user_id: &UserId) { - self.db.userid_avatar_url.remove(user_id).unwrap(); + self.db.userid_avatarurl.remove(user_id).unwrap(); } /// Set a new avatar_url. pub fn avatar_url_set(&self, user_id: &UserId, avatar_url: String) { self.db - .userid_avatar_url + .userid_avatarurl .insert(user_id.to_string(), &*avatar_url) .unwrap(); } @@ -98,7 +98,7 @@ impl Data { /// Get a the avatar_url of a user. pub fn avatar_url_get(&self, user_id: &UserId) -> Option { self.db - .userid_avatar_url + .userid_avatarurl .get(user_id.to_string()) .unwrap() .map(|bytes| utils::string_from_bytes(&bytes)) diff --git a/src/database.rs b/src/database.rs index bdfab5b1..b8a41519 100644 --- a/src/database.rs +++ b/src/database.rs @@ -53,7 +53,7 @@ pub struct Database { pub userid_password: sled::Tree, pub userid_deviceids: MultiValue, pub userid_displayname: sled::Tree, - pub userid_avatar_url: sled::Tree, + pub userid_avatarurl: sled::Tree, pub deviceid_token: sled::Tree, pub token_userid: sled::Tree, pub pduid_pdus: sled::Tree, @@ -78,7 +78,7 @@ impl Database { userid_password: db.open_tree("userid_password").unwrap(), userid_deviceids: MultiValue(db.open_tree("userid_deviceids").unwrap()), userid_displayname: db.open_tree("userid_displayname").unwrap(), - userid_avatar_url: db.open_tree("userid_avatar_url").unwrap(), + userid_avatarurl: db.open_tree("userid_avatarurl").unwrap(), deviceid_token: db.open_tree("deviceid_token").unwrap(), token_userid: db.open_tree("token_userid").unwrap(), pduid_pdus: db.open_tree("pduid_pdus").unwrap(), @@ -107,7 +107,7 @@ impl Database { String::from_utf8_lossy(&v), ); } - println!("# AccountData -> Displayname:"); + println!("# UserId -> Displayname:"); for (k, v) in self.userid_displayname.iter().map(|r| r.unwrap()) { println!( "{:?} -> {:?}", @@ -115,8 +115,8 @@ impl Database { String::from_utf8_lossy(&v), ); } - println!("# AccountData -> AvatarURL:"); - for (k, v) in self.userid_avatar_url.iter().map(|r| r.unwrap()) { + println!("# UserId -> AvatarURL:"); + for (k, v) in self.userid_avatarurl.iter().map(|r| r.unwrap()) { println!( "{:?} -> {:?}", String::from_utf8_lossy(&k), diff --git a/src/main.rs b/src/main.rs index 3bc1e4bf..aee2d47c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -89,7 +89,7 @@ fn register_route( .unwrap_or_else(|| utils::random_string(GUEST_NAME_LENGTH)), data.hostname() )) - .try_into() + .try_into() { Err(_) => { debug!("Username invalid"); @@ -153,7 +153,7 @@ fn login_route(data: State, body: Ruma) -> MatrixResult MatrixResult { } #[get( -"/_matrix/client/r0/user/<_user_id>/filter/<_filter_id>", -data = "" + "/_matrix/client/r0/user/<_user_id>/filter/<_filter_id>", + data = "" )] fn get_filter_route( body: Ruma, @@ -262,8 +262,8 @@ fn create_filter_route( } #[put( -"/_matrix/client/r0/user/<_user_id>/account_data/<_type>", -data = "" + "/_matrix/client/r0/user/<_user_id>/account_data/<_type>", + data = "" )] fn set_global_account_data_route( body: Ruma, @@ -275,8 +275,8 @@ fn set_global_account_data_route( } #[get( -"/_matrix/client/r0/user/<_user_id>/account_data/<_type>", -data = "" + "/_matrix/client/r0/user/<_user_id>/account_data/<_type>", + data = "" )] fn get_global_account_data_route( body: Ruma, @@ -317,7 +317,6 @@ fn set_displayname_route( data.displayname_set(&user_id, body.displayname.clone()); // TODO send a new m.room.member join event with the updated displayname // TODO send a new m.presence event with the updated displayname - } } @@ -325,8 +324,8 @@ fn set_displayname_route( } #[get( -"/_matrix/client/r0/profile//displayname", -data = "" + "/_matrix/client/r0/profile//displayname", + data = "" )] fn get_displayname_route( data: State, @@ -349,9 +348,7 @@ fn get_displayname_route( })); } - MatrixResult(Ok(get_display_name::Response { - displayname: None, - })) + MatrixResult(Ok(get_display_name::Response { displayname: None })) } #[put("/_matrix/client/r0/profile/<_user_id>/avatar_url", data = "")] @@ -374,14 +371,12 @@ fn set_avatar_url_route( // TODO in the future when we can handle media uploads make sure that this url is our own server // TODO also make sure this is valid mxc:// format (not only starting with it) - if body.avatar_url == "" { data.avatar_url_remove(&user_id); } else { data.avatar_url_set(&user_id, body.displayname.clone()); // TODO send a new m.room.member join event with the updated avatar_url // TODO send a new m.presence event with the updated avatar_url - } MatrixResult(Ok(set_avatar_url::Response)) @@ -409,9 +404,7 @@ fn get_avatar_url_route( })); } - MatrixResult(Ok(get_avatar_url::Response { - avatar_url: None, - })) + MatrixResult(Ok(get_avatar_url::Response { avatar_url: None })) } #[get("/_matrix/client/r0/profile/", data = "")] @@ -527,8 +520,8 @@ fn get_alias_route(room_alias: String) -> MatrixResult { })); } } - .try_into() - .unwrap(); + .try_into() + .unwrap(); MatrixResult(Ok(get_alias::Response { room_id, @@ -635,8 +628,8 @@ fn get_protocols_route( } #[put( -"/_matrix/client/r0/rooms/<_room_id>/send/<_event_type>/<_txn_id>", -data = "" + "/_matrix/client/r0/rooms/<_room_id>/send/<_event_type>/<_txn_id>", + data = "" )] fn create_message_event_route( data: State, @@ -660,8 +653,8 @@ fn create_message_event_route( } #[put( -"/_matrix/client/r0/rooms/<_room_id>/state/<_event_type>/<_state_key>", -data = "" + "/_matrix/client/r0/rooms/<_room_id>/state/<_event_type>/<_state_key>", + data = "" )] fn create_state_event_for_key_route( data: State, @@ -683,8 +676,8 @@ fn create_state_event_for_key_route( } #[put( -"/_matrix/client/r0/rooms/<_room_id>/state/<_event_type>", -data = "" + "/_matrix/client/r0/rooms/<_room_id>/state/<_event_type>", + data = "" )] fn create_state_event_for_empty_key_route( data: State, From 8bcbc983c381d8318aeb85fabfacd29563332f14 Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 9 Apr 2020 21:11:21 +0200 Subject: [PATCH 4/5] Change and add Comments to the profile endpoints Add missing docs Took 9 minutes --- src/main.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/main.rs b/src/main.rs index aee2d47c..e85d90b3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -299,7 +299,7 @@ fn set_displayname_route( ) -> MatrixResult { let user_id = body.user_id.clone().expect("user is authenticated"); - // Send error on None and accept Some("") as valid username + // Send error on None // Synapse returns a parsing error but the spec doesn't require this if body.displayname.is_none() { debug!("Request was missing the displayname payload."); @@ -311,6 +311,7 @@ fn set_displayname_route( } if let Some(displayname) = body.displayname { + // Some("") will clear the displayname if displayname == "" { data.displayname_remove(&user_id); } else { @@ -338,7 +339,7 @@ fn get_displayname_route( debug!("Profile was not found."); MatrixResult(Err(Error { kind: ErrorKind::NotFound, - message: "Profile was not found".to_owned(), + message: "Profile was not found.".to_owned(), status_code: http::StatusCode::NOT_FOUND, })) } @@ -348,6 +349,7 @@ fn get_displayname_route( })); } + // The user has no displayname MatrixResult(Ok(get_display_name::Response { displayname: None })) } @@ -394,7 +396,7 @@ fn get_avatar_url_route( debug!("Profile was not found."); MatrixResult(Err(Error { kind: ErrorKind::NotFound, - message: "Profile was not found".to_owned(), + message: "Profile was not found.".to_owned(), status_code: http::StatusCode::NOT_FOUND, })) } @@ -404,6 +406,7 @@ fn get_avatar_url_route( })); } + // The user has no avatar MatrixResult(Ok(get_avatar_url::Response { avatar_url: None })) } @@ -428,7 +431,7 @@ fn get_profile_route( debug!("Profile was not found."); MatrixResult(Err(Error { kind: ErrorKind::NotFound, - message: "Profile was not found".to_owned(), + message: "Profile was not found.".to_owned(), status_code: http::StatusCode::NOT_FOUND, })) } From 57264f72e91f2fef41345e6166e9b1adebd5fc8a Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 9 Apr 2020 21:19:27 +0200 Subject: [PATCH 5/5] Fix avatar_url error message if not starting with mxc:// Took 8 minutes --- src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.rs b/src/main.rs index e85d90b3..17d01f51 100644 --- a/src/main.rs +++ b/src/main.rs @@ -365,7 +365,7 @@ fn set_avatar_url_route( debug!("Request contains an invalid avatar_url."); return MatrixResult(Err(Error { kind: ErrorKind::InvalidParam, - message: "Missing avatar_url".to_owned(), + message: "avatar_url has to start with mxc://.".to_owned(), status_code: http::StatusCode::BAD_REQUEST, })); }