[fractal] API: Implement and use user request and response types
- From: Julian Sparber <jsparber src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [fractal] API: Implement and use user request and response types
- Date: Fri, 15 Feb 2019 13:46:43 +0000 (UTC)
commit dc924b1be08cdbd9bb8589a71892e77a738e89b0
Author: Alejandro DomÃnguez <adomu net-c com>
Date: Mon Jan 28 18:38:26 2019 +0100
API: Implement and use user request and response types
fractal-gtk/src/appop/account.rs | 64 +++----
fractal-gtk/src/widgets/address.rs | 28 +--
fractal-matrix-api/src/backend/mod.rs | 16 +-
fractal-matrix-api/src/backend/types.rs | 7 +-
fractal-matrix-api/src/backend/user.rs | 286 ++++++++++++++++---------------
fractal-matrix-api/src/model/member.rs | 11 ++
fractal-matrix-api/src/model/mod.rs | 2 +-
fractal-matrix-api/src/model/user.rs | 126 ++++++++++++++
fractal-matrix-api/src/model/userinfo.rs | 9 -
fractal-matrix-api/src/types.rs | 3 +-
10 files changed, 351 insertions(+), 201 deletions(-)
---
diff --git a/fractal-gtk/src/appop/account.rs b/fractal-gtk/src/appop/account.rs
index d0a84f8d..5cf316cc 100644
--- a/fractal-gtk/src/appop/account.rs
+++ b/fractal-gtk/src/appop/account.rs
@@ -12,10 +12,11 @@ use crate::widgets;
use crate::widgets::AvatarExt;
use crate::cache::download_to_cache;
-use fractal_api::types::UserInfo;
+use fractal_api::types::Medium;
+use fractal_api::types::ThirdPartyIdentifier;
impl AppOp {
- pub fn set_three_pid(&self, data: Option<Vec<UserInfo>>) {
+ pub fn set_three_pid(&self, data: Option<Vec<ThirdPartyIdentifier>>) {
self.update_address(data);
}
@@ -312,7 +313,7 @@ impl AppOp {
self.set_state(AppState::AccountSettings);
}
- pub fn update_address(&self, data: Option<Vec<UserInfo>>) {
+ pub fn update_address(&self, data: Option<Vec<ThirdPartyIdentifier>>) {
let grid = self
.ui
.builder
@@ -368,34 +369,37 @@ impl AppOp {
phone.pack_start(&empty_phone.create(None), true, true, 0);
if let Some(data) = data {
for item in data {
- if item.medium == "email" {
- if first_email {
- empty_email.update(Some(item.address));
- let entry =
- widgets::Address::new(widgets::AddressType::Email, &self).create(None);
- grid.insert_next_to(&email, gtk::PositionType::Bottom);
- grid.attach_next_to(&entry, &email, gtk::PositionType::Bottom, 1, 1);
- first_email = false;
- } else {
- let entry = widgets::Address::new(widgets::AddressType::Email, &self)
- .create(Some(item.address));
- grid.insert_next_to(&email, gtk::PositionType::Bottom);
- grid.attach_next_to(&entry, &email, gtk::PositionType::Bottom, 1, 1);
+ match item.medium {
+ Medium::Email => {
+ if first_email {
+ empty_email.update(Some(item.address));
+ let entry = widgets::Address::new(widgets::AddressType::Email, &self)
+ .create(None);
+ grid.insert_next_to(&email, gtk::PositionType::Bottom);
+ grid.attach_next_to(&entry, &email, gtk::PositionType::Bottom, 1, 1);
+ first_email = false;
+ } else {
+ let entry = widgets::Address::new(widgets::AddressType::Email, &self)
+ .create(Some(item.address));
+ grid.insert_next_to(&email, gtk::PositionType::Bottom);
+ grid.attach_next_to(&entry, &email, gtk::PositionType::Bottom, 1, 1);
+ }
}
- } else if item.medium == "msisdn" {
- if first_phone {
- empty_phone.update(Some(item.address));
- let entry =
- widgets::Address::new(widgets::AddressType::Phone, &self).create(None);
- grid.insert_next_to(&phone, gtk::PositionType::Bottom);
- grid.attach_next_to(&entry, &phone, gtk::PositionType::Bottom, 1, 1);
- first_phone = false;
- } else {
- let s = String::from("+") + &String::from(item.address);
- let entry = widgets::Address::new(widgets::AddressType::Phone, &self)
- .create(Some(s));
- grid.insert_next_to(&phone, gtk::PositionType::Bottom);
- grid.attach_next_to(&entry, &phone, gtk::PositionType::Bottom, 1, 1);
+ Medium::MsIsdn => {
+ if first_phone {
+ empty_phone.update(Some(item.address));
+ let entry = widgets::Address::new(widgets::AddressType::Phone, &self)
+ .create(None);
+ grid.insert_next_to(&phone, gtk::PositionType::Bottom);
+ grid.attach_next_to(&entry, &phone, gtk::PositionType::Bottom, 1, 1);
+ first_phone = false;
+ } else {
+ let s = String::from("+") + &item.address;
+ let entry = widgets::Address::new(widgets::AddressType::Phone, &self)
+ .create(Some(s));
+ grid.insert_next_to(&phone, gtk::PositionType::Bottom);
+ grid.attach_next_to(&entry, &phone, gtk::PositionType::Bottom, 1, 1);
+ }
}
}
}
diff --git a/fractal-gtk/src/widgets/address.rs b/fractal-gtk/src/widgets/address.rs
index 3a9d9228..dea21bfe 100644
--- a/fractal-gtk/src/widgets/address.rs
+++ b/fractal-gtk/src/widgets/address.rs
@@ -1,3 +1,4 @@
+use fractal_api::types::Medium;
use glib::signal;
use gtk;
use gtk::prelude::*;
@@ -170,8 +171,8 @@ impl<'a> Address<'a> {
entry.set_editable(false);
let medium = match medium {
- AddressType::Email => String::from("email"),
- AddressType::Phone => String::from("msisdn"),
+ AddressType::Email => Medium::Email,
+ AddressType::Phone => Medium::MsIsdn,
};
match action {
@@ -189,7 +190,7 @@ impl<'a> Address<'a> {
fn delete_address(
backend: &Sender<BKCommand>,
- medium: String,
+ medium: Medium,
address: Option<String>,
) -> Option<String> {
backend
@@ -200,19 +201,22 @@ fn delete_address(
fn add_address(
backend: &Sender<BKCommand>,
- medium: String,
+ medium: Medium,
id_server: String,
address: Option<String>,
) -> Option<String> {
let secret: String = thread_rng().sample_iter(&Alphanumeric).take(36).collect();
- if medium == "msisdn" {
- backend
- .send(BKCommand::GetTokenPhone(id_server, address?, secret))
- .unwrap();
- } else {
- backend
- .send(BKCommand::GetTokenEmail(id_server, address?, secret))
- .unwrap();
+ match medium {
+ Medium::MsIsdn => {
+ backend
+ .send(BKCommand::GetTokenPhone(id_server, address?, secret))
+ .unwrap();
+ }
+ Medium::Email => {
+ backend
+ .send(BKCommand::GetTokenEmail(id_server, address?, secret))
+ .unwrap();
+ }
}
None
}
diff --git a/fractal-matrix-api/src/backend/mod.rs b/fractal-matrix-api/src/backend/mod.rs
index 8dfca561..7487c7d4 100644
--- a/fractal-matrix-api/src/backend/mod.rs
+++ b/fractal-matrix-api/src/backend/mod.rs
@@ -121,11 +121,11 @@ impl Backend {
bkerror!(r, tx, BKResponse::GetThreePIDError);
}
Ok(BKCommand::GetTokenEmail(identity, email, client_secret)) => {
- let r = user::get_email_token(self, &identity, &email, client_secret);
+ let r = user::get_email_token(self, identity, email, client_secret);
bkerror!(r, tx, BKResponse::GetTokenEmailError);
}
Ok(BKCommand::GetTokenPhone(identity, phone, client_secret)) => {
- let r = user::get_phone_token(self, &identity, &phone, client_secret);
+ let r = user::get_phone_token(self, identity, phone, client_secret);
bkerror!(r, tx, BKResponse::GetTokenEmailError);
}
Ok(BKCommand::SubmitPhoneToken(identity, client_secret, sid, token)) => {
@@ -133,18 +133,18 @@ impl Backend {
bkerror!(r, tx, BKResponse::SubmitPhoneTokenError);
}
Ok(BKCommand::AddThreePID(identity, client_secret, sid)) => {
- let r = user::add_threepid(self, &identity, &client_secret, sid);
+ let r = user::add_threepid(self, identity, client_secret, sid);
bkerror!(r, tx, BKResponse::AddThreePIDError);
}
Ok(BKCommand::DeleteThreePID(medium, address)) => {
- user::delete_three_pid(self, &medium, &address);
+ user::delete_three_pid(self, medium, address);
}
Ok(BKCommand::ChangePassword(username, old_password, new_password)) => {
- let r = user::change_password(self, &username, &old_password, &new_password);
+ let r = user::change_password(self, username, old_password, new_password);
bkerror!(r, tx, BKResponse::ChangePasswordError);
}
- Ok(BKCommand::AccountDestruction(username, password, flag)) => {
- let r = user::account_destruction(self, &username, &password, flag);
+ Ok(BKCommand::AccountDestruction(username, password, _)) => {
+ let r = user::account_destruction(self, username, password);
bkerror!(r, tx, BKResponse::AccountDestructionError);
}
Ok(BKCommand::GetAvatar) => {
@@ -168,7 +168,7 @@ impl Backend {
bkerror!(r, tx, BKResponse::CommandError);
}
Ok(BKCommand::UserSearch(term)) => {
- let r = user::search(self, &term);
+ let r = user::search(self, term);
bkerror!(r, tx, BKResponse::CommandError);
}
diff --git a/fractal-matrix-api/src/backend/types.rs b/fractal-matrix-api/src/backend/types.rs
index a18f1c4e..9f72a41d 100644
--- a/fractal-matrix-api/src/backend/types.rs
+++ b/fractal-matrix-api/src/backend/types.rs
@@ -5,13 +5,14 @@ use std::sync::{Arc, Condvar, Mutex};
use crate::error::Error;
use crate::types::Event;
+use crate::types::Medium;
use crate::types::Member;
use crate::types::Message;
use crate::types::ProtocolInstance;
use crate::types::Room;
use crate::types::Sticker;
use crate::types::StickerGroup;
-use crate::types::UserInfo;
+use crate::types::ThirdPartyIdentifier;
use crate::cache::CacheMap;
use url::Url;
@@ -32,7 +33,7 @@ pub enum BKCommand {
GetTokenPhone(String, String, String),
SubmitPhoneToken(String, String, String, String),
AddThreePID(String, String, String),
- DeleteThreePID(String, String),
+ DeleteThreePID(Medium, String),
ChangePassword(String, String, String),
AccountDestruction(String, String, bool),
GetAvatar,
@@ -90,7 +91,7 @@ pub enum BKResponse {
Logout,
Name(String),
SetUserName(String),
- GetThreePID(Vec<UserInfo>),
+ GetThreePID(Vec<ThirdPartyIdentifier>),
GetTokenEmail(String, String),
GetTokenPhone(String, String),
SubmitPhoneToken(Option<String>, String),
diff --git a/fractal-matrix-api/src/backend/user.rs b/fractal-matrix-api/src/backend/user.rs
index fe02fe01..4d95ad57 100644
--- a/fractal-matrix-api/src/backend/user.rs
+++ b/fractal-matrix-api/src/backend/user.rs
@@ -19,8 +19,26 @@ use std::sync::{Arc, Mutex};
use std::thread;
use url::Url;
+use crate::types::AddThreePIDRequest;
+use crate::types::AuthenticationData;
+use crate::types::ChangePasswordRequest;
+use crate::types::DeactivateAccountRequest;
+use crate::types::DeleteThreePIDRequest;
+use crate::types::EmailTokenRequest;
+use crate::types::GetDisplayNameResponse;
+use crate::types::Identifier;
+use crate::types::Medium;
use crate::types::Member;
-use crate::types::UserInfo;
+use crate::types::PhoneTokenRequest;
+use crate::types::PutDisplayNameRequest;
+use crate::types::SearchUserRequest;
+use crate::types::SearchUserResponse;
+use crate::types::SubmitPhoneTokenRequest;
+use crate::types::SubmitPhoneTokenResponse;
+use crate::types::ThirdPartyIDResponse;
+use crate::types::ThirdPartyTokenResponse;
+use crate::types::ThreePIDCredentials;
+use crate::types::UserIdentifier;
use serde_json;
use serde_json::Value as JsonValue;
@@ -31,9 +49,12 @@ pub fn get_username(bk: &Backend) -> Result<(), Error> {
let tx = bk.tx.clone();
get!(
&url,
- |r: JsonValue| {
- let name = String::from(r["displayname"].as_str().unwrap_or(&id));
+ |r: JsonValue| if let Ok(response) = serde_json::from_value::<GetDisplayNameResponse>(r) {
+ let name = response.displayname.unwrap_or(id);
tx.send(BKResponse::Name(name)).unwrap();
+ } else {
+ tx.send(BKResponse::UserNameError(Error::BackendError))
+ .unwrap();
},
|err| tx.send(BKResponse::UserNameError(err)).unwrap()
);
@@ -45,15 +66,17 @@ pub fn set_username(bk: &Backend, name: String) -> Result<(), Error> {
let id = bk.data.lock().unwrap().user_id.clone();
let url = bk.url(&format!("profile/{}/displayname", encode_uid(&id)), vec![])?;
- let attrs = json!({
- "displayname": name,
- });
+ let attrs = PutDisplayNameRequest {
+ displayname: Some(name.clone()),
+ };
+ let attrs_json =
+ serde_json::to_value(attrs).expect("Failed to serialize display name setting request");
let tx = bk.tx.clone();
query!(
"put",
&url,
- &attrs,
+ &attrs_json,
|_| {
tx.send(BKResponse::SetUserName(name)).unwrap();
},
@@ -70,36 +93,12 @@ pub fn get_threepid(bk: &Backend) -> Result<(), Error> {
let tx = bk.tx.clone();
get!(
&url,
- |r: JsonValue| {
- let mut result: Vec<UserInfo> = vec![];
- if let Some(arr) = r["threepids"].as_array() {
- for pid in arr.iter() {
- let address = match pid["address"].as_str() {
- None => String::new(),
- Some(a) => a.to_string(),
- };
- let add = match pid["added_at"].as_u64() {
- None => 0,
- Some(a) => a,
- };
- let medium = match pid["medium"].as_str() {
- None => String::new(),
- Some(a) => a.to_string(),
- };
- let val = match pid["validated_at"].as_u64() {
- None => 0,
- Some(a) => a,
- };
-
- result.push(UserInfo {
- address: address,
- added_at: add,
- validated_at: val,
- medium: medium,
- });
- }
- }
- tx.send(BKResponse::GetThreePID(result)).unwrap();
+ |r: JsonValue| if let Ok(response) = serde_json::from_value::<ThirdPartyIDResponse>(r) {
+ tx.send(BKResponse::GetThreePID(response.threepids))
+ .unwrap();
+ } else {
+ tx.send(BKResponse::GetThreePIDError(Error::BackendError))
+ .unwrap();
},
|err| tx.send(BKResponse::GetThreePIDError(err)).unwrap()
);
@@ -109,26 +108,31 @@ pub fn get_threepid(bk: &Backend) -> Result<(), Error> {
pub fn get_email_token(
bk: &Backend,
- identity: &str,
- email: &str,
+ identity: String,
+ email: String,
client_secret: String,
) -> Result<(), Error> {
let url = bk.url("account/3pid/email/requestToken", vec![])?;
- let attrs = json!({
- "id_server": identity[8..],
- "client_secret": client_secret.clone(),
- "email": email,
- "send_attempt": "1",
- });
+ let attrs = EmailTokenRequest {
+ id_server: identity[8..].into(),
+ client_secret: client_secret.clone(),
+ email: email,
+ send_attempt: 1,
+ next_link: None,
+ };
+
+ let attrs_json = serde_json::to_value(attrs).expect("Failed to serialize email token request");
let tx = bk.tx.clone();
post!(
&url,
- &attrs,
- |r: JsonValue| {
- let sid = String::from(r["sid"].as_str().unwrap_or_default());
- tx.send(BKResponse::GetTokenEmail(sid, client_secret))
+ &attrs_json,
+ |r: JsonValue| if let Ok(response) = serde_json::from_value::<ThirdPartyTokenResponse>(r) {
+ tx.send(BKResponse::GetTokenEmail(response.sid, client_secret))
+ .unwrap();
+ } else {
+ tx.send(BKResponse::GetTokenEmailError(Error::BackendError))
.unwrap();
},
|err| match err {
@@ -148,27 +152,32 @@ pub fn get_email_token(
pub fn get_phone_token(
bk: &Backend,
- identity: &str,
- phone: &str,
+ identity: String,
+ phone: String,
client_secret: String,
) -> Result<(), Error> {
let url = bk.url(&format!("account/3pid/msisdn/requestToken"), vec![])?;
- let attrs = json!({
- "id_server": identity[8..],
- "client_secret": client_secret,
- "phone_number": phone,
- "country": "",
- "send_attempt": "1",
- });
+ let attrs = PhoneTokenRequest {
+ id_server: identity[8..].into(),
+ client_secret: client_secret.clone(),
+ phone_number: phone,
+ country: String::new(),
+ send_attempt: 1,
+ next_link: None,
+ };
+
+ let attrs_json = serde_json::to_value(attrs).expect("Failed to serialize phone token request");
let tx = bk.tx.clone();
post!(
&url,
- &attrs,
- |r: JsonValue| {
- let sid = String::from(r["sid"].as_str().unwrap_or_default());
- tx.send(BKResponse::GetTokenPhone(sid, client_secret))
+ &attrs_json,
+ |r: JsonValue| if let Ok(response) = serde_json::from_value::<ThirdPartyTokenResponse>(r) {
+ tx.send(BKResponse::GetTokenPhone(response.sid, client_secret))
+ .unwrap();
+ } else {
+ tx.send(BKResponse::GetTokenPhoneError(Error::BackendError))
.unwrap();
},
|err| match err {
@@ -188,25 +197,28 @@ pub fn get_phone_token(
pub fn add_threepid(
bk: &Backend,
- identity: &str,
- client_secret: &str,
+ identity: String,
+ client_secret: String,
sid: String,
) -> Result<(), Error> {
let url = bk.url(&format!("account/3pid"), vec![])?;
- let attrs = json!({
- "three_pid_creds": {
- "id_server": identity[8..],
- "sid": sid,
- "client_secret": client_secret.clone()
+ let attrs = AddThreePIDRequest {
+ three_pid_creds: ThreePIDCredentials {
+ id_server: identity[8..].into(),
+ sid: sid.clone(),
+ client_secret,
},
- "bind": true
- });
+ bind: true,
+ };
+
+ let attrs_json = serde_json::to_value(attrs)
+ .expect("Failed to serialize add third party information request");
let tx = bk.tx.clone();
post!(
&url,
- &attrs,
- |_r: JsonValue| {
+ &attrs_json,
+ |_| {
tx.send(BKResponse::AddThreePID(sid)).unwrap();
},
|err| {
@@ -224,25 +236,28 @@ pub fn submit_phone_token(
sid: String,
token: String,
) -> Result<(), Error> {
- let params = &[
- ("sid", sid.clone()),
- ("client_secret", client_secret.clone()),
- ("token", token),
- ];
let path = "/_matrix/identity/api/v1/validate/msisdn/submitToken";
- let url = build_url(&Url::parse(&url)?, path, params)?;
+ let url = build_url(&Url::parse(url)?, path, &[])?;
+
+ let attrs = SubmitPhoneTokenRequest {
+ sid: sid.clone(),
+ client_secret: client_secret.clone(),
+ token,
+ };
+ let attrs_json =
+ serde_json::to_value(attrs).expect("Failed to serialize phone token submit request");
let tx = bk.tx.clone();
post!(
&url,
- |r: JsonValue| {
- let result = if r["success"] == true {
- Some(sid)
- } else {
- None
- };
+ &attrs_json,
+ |r: JsonValue| if let Ok(response) = serde_json::from_value::<SubmitPhoneTokenResponse>(r) {
+ let result = Some(sid).filter(|_| response.success);
tx.send(BKResponse::SubmitPhoneToken(result, client_secret))
.unwrap();
+ } else {
+ tx.send(BKResponse::SubmitPhoneTokenError(Error::BackendError))
+ .unwrap();
},
|err| {
tx.send(BKResponse::SubmitPhoneTokenError(err)).unwrap();
@@ -252,7 +267,7 @@ pub fn submit_phone_token(
Ok(())
}
-pub fn delete_three_pid(bk: &Backend, medium: &str, address: &str) {
+pub fn delete_three_pid(bk: &Backend, medium: Medium, address: String) {
let baseu = bk.get_base_url();
let tk = bk.data.lock().unwrap().access_token.clone();
let mut url = baseu
@@ -261,15 +276,14 @@ pub fn delete_three_pid(bk: &Backend, medium: &str, address: &str) {
url.query_pairs_mut()
.clear()
.append_pair("access_token", &tk);
- let attrs = json!({
- "medium": medium,
- "address": address,
- });
+ let attrs = DeleteThreePIDRequest { medium, address };
+ let attrs_json =
+ serde_json::to_value(attrs).expect("Failed to serialize third party ID delete request");
let tx = bk.tx.clone();
post!(
&url,
- &attrs,
+ &attrs_json,
|_r: JsonValue| {
tx.send(BKResponse::DeleteThreePID).unwrap();
},
@@ -281,25 +295,27 @@ pub fn delete_three_pid(bk: &Backend, medium: &str, address: &str) {
pub fn change_password(
bk: &Backend,
- username: &str,
- old_password: &str,
- new_password: &str,
+ user: String,
+ old_password: String,
+ new_password: String,
) -> Result<(), Error> {
let url = bk.url(&format!("account/password"), vec![])?;
- let attrs = json!({
- "new_password": new_password,
- "auth": {
- "type": "m.login.password",
- "user": username,
- "password": old_password,
- }
- });
-
+ let attrs = ChangePasswordRequest {
+ new_password,
+ auth: Some(AuthenticationData::Password {
+ identifier: Identifier::new(UserIdentifier::User { user }),
+ password: old_password,
+ session: None,
+ }),
+ };
+
+ let attrs_json =
+ serde_json::to_value(attrs).expect("Failed to serialize password change request");
let tx = bk.tx.clone();
post!(
&url,
- &attrs,
+ &attrs_json,
|r: JsonValue| {
info!("{}", r);
tx.send(BKResponse::ChangePassword).unwrap();
@@ -312,27 +328,23 @@ pub fn change_password(
Ok(())
}
-pub fn account_destruction(
- bk: &Backend,
- username: &str,
- password: &str,
- flag: bool,
-) -> Result<(), Error> {
+pub fn account_destruction(bk: &Backend, user: String, password: String) -> Result<(), Error> {
let url = bk.url(&format!("account/deactivate"), vec![])?;
- let attrs = json!({
- "erase": flag,
- "auth": {
- "type": "m.login.password",
- "user": username,
- "password": password,
- }
- });
+ let attrs = DeactivateAccountRequest {
+ auth: Some(AuthenticationData::Password {
+ identifier: Identifier::new(UserIdentifier::User { user }),
+ password,
+ session: None,
+ }),
+ };
+ let attrs_json =
+ serde_json::to_value(attrs).expect("Failed to serialize account deactivation request");
let tx = bk.tx.clone();
post!(
&url,
- &attrs,
+ &attrs_json,
|r: JsonValue| {
info!("{}", r);
tx.send(BKResponse::AccountDestruction).unwrap();
@@ -414,11 +426,13 @@ pub fn get_username_async(bk: &Backend, uid: String, tx: Sender<String>) -> Resu
let url = bk.url(&format!("profile/{}/displayname", encode_uid(&uid)), vec![])?;
get!(
&url,
- |r: JsonValue| {
- let name = String::from(r["displayname"].as_str().unwrap_or(&uid));
+ |r: JsonValue| if let Ok(response) = serde_json::from_value::<GetDisplayNameResponse>(r) {
+ let name = response.displayname.unwrap_or(uid);
tx.send(name).unwrap();
+ } else {
+ tx.send(uid.to_string()).unwrap();
},
- |_err| tx.send(uid.to_string()).unwrap()
+ |_| tx.send(uid.to_string()).unwrap()
);
Ok(())
@@ -492,28 +506,26 @@ pub fn set_user_avatar(bk: &Backend, avatar: String) -> Result<(), Error> {
Ok(())
}
-pub fn search(bk: &Backend, term: &str) -> Result<(), Error> {
+pub fn search(bk: &Backend, search_term: String) -> Result<(), Error> {
let url = bk.url(&format!("user_directory/search"), vec![])?;
- let attrs = json!({
- "search_term": term,
- });
+ let attrs = SearchUserRequest {
+ search_term,
+ ..Default::default()
+ };
+ let attrs_json =
+ serde_json::to_value(attrs).expect("Failed to serialize user directory search request");
let tx = bk.tx.clone();
post!(
&url,
- &attrs,
- |js: JsonValue| {
- let mut users: Vec<Member> = vec![];
- if let Some(arr) = js["results"].as_array() {
- for member in arr.iter() {
- let mut member_s: Member = serde_json::from_value(member.clone()).unwrap();
- member_s.uid = member["user_id"].as_str().unwrap_or_default().to_string();
-
- users.push(member_s);
- }
- }
+ &attrs_json,
+ |r: JsonValue| if let Ok(response) = serde_json::from_value::<SearchUserResponse>(r) {
+ let users = response.results.into_iter().map(Into::into).collect();
tx.send(BKResponse::UserSearch(users)).unwrap();
+ } else {
+ tx.send(BKResponse::CommandError(Error::BackendError))
+ .unwrap();
},
|err| {
tx.send(BKResponse::CommandError(err)).unwrap();
diff --git a/fractal-matrix-api/src/model/member.rs b/fractal-matrix-api/src/model/member.rs
index 0e8dfcdb..a2ff4b1b 100644
--- a/fractal-matrix-api/src/model/member.rs
+++ b/fractal-matrix-api/src/model/member.rs
@@ -1,3 +1,4 @@
+use crate::types::User;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
@@ -30,5 +31,15 @@ impl PartialEq for Member {
}
}
+impl From<User> for Member {
+ fn from(user: User) -> Self {
+ Self {
+ uid: user.user_id,
+ alias: user.display_name,
+ avatar: user.avatar_url,
+ }
+ }
+}
+
// hashmap userid -> Member
pub type MemberList = HashMap<String, Member>;
diff --git a/fractal-matrix-api/src/model/mod.rs b/fractal-matrix-api/src/model/mod.rs
index 1e05f375..93ed1579 100644
--- a/fractal-matrix-api/src/model/mod.rs
+++ b/fractal-matrix-api/src/model/mod.rs
@@ -7,7 +7,7 @@ pub mod register;
pub mod room;
pub mod stickers;
pub mod sync;
-pub mod userinfo;
+pub mod user;
use serde::{Deserialize, Serialize};
diff --git a/fractal-matrix-api/src/model/user.rs b/fractal-matrix-api/src/model/user.rs
new file mode 100644
index 00000000..a6a5e6da
--- /dev/null
+++ b/fractal-matrix-api/src/model/user.rs
@@ -0,0 +1,126 @@
+use super::{AuthenticationData, Medium, ThreePIDCredentials};
+use serde::{Deserialize, Serialize};
+use std::ops::Not;
+
+#[derive(Clone, Debug, Deserialize)]
+pub struct GetDisplayNameResponse {
+ pub displayname: Option<String>,
+}
+
+#[derive(Clone, Debug, Serialize)]
+pub struct PutDisplayNameRequest {
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub displayname: Option<String>,
+}
+
+#[derive(Debug, Clone, Deserialize)]
+pub struct ThirdPartyIDResponse {
+ pub threepids: Vec<ThirdPartyIdentifier>,
+}
+
+#[derive(Debug, Clone, Deserialize)]
+pub struct ThirdPartyIdentifier {
+ pub added_at: u64,
+ pub medium: Medium,
+ pub validated_at: u64,
+ pub address: String,
+}
+
+#[derive(Clone, Debug, Serialize)]
+pub struct EmailTokenRequest {
+ pub client_secret: String,
+ pub email: String,
+ pub id_server: String,
+ pub send_attempt: u64,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub next_link: Option<String>,
+}
+
+#[derive(Clone, Debug, Serialize)]
+pub struct PhoneTokenRequest {
+ pub client_secret: String,
+ pub phone_number: String,
+ pub country: String,
+ pub id_server: String,
+ pub send_attempt: u64,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub next_link: Option<String>,
+}
+
+#[derive(Clone, Debug, Deserialize)]
+pub struct ThirdPartyTokenResponse {
+ pub sid: String,
+}
+
+#[derive(Clone, Debug, Serialize)]
+pub struct AddThreePIDRequest {
+ pub three_pid_creds: ThreePIDCredentials,
+ #[serde(skip_serializing_if = "Not::not")]
+ pub bind: bool,
+}
+
+#[derive(Clone, Debug, Serialize)]
+pub struct SubmitPhoneTokenRequest {
+ pub sid: String,
+ pub client_secret: String,
+ pub token: String,
+}
+
+#[derive(Clone, Debug, Deserialize)]
+pub struct SubmitPhoneTokenResponse {
+ pub success: bool,
+}
+
+#[derive(Clone, Debug, Serialize)]
+pub struct DeleteThreePIDRequest {
+ pub medium: Medium,
+ pub address: String,
+}
+
+#[derive(Clone, Debug, Serialize)]
+pub struct ChangePasswordRequest {
+ pub new_password: String,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub auth: Option<AuthenticationData>,
+}
+
+#[derive(Clone, Debug, Serialize)]
+pub struct DeactivateAccountRequest {
+ #[serde(skip_serializing_if = "Option::is_none")]
+ pub auth: Option<AuthenticationData>,
+}
+
+#[derive(Clone, Debug, Serialize)]
+pub struct SearchUserRequest {
+ pub search_term: String,
+ #[serde(skip_serializing_if = "u64_is_10")]
+ pub limit: u64,
+}
+
+impl Default for SearchUserRequest {
+ fn default() -> Self {
+ Self {
+ search_term: Default::default(),
+ limit: 10,
+ }
+ }
+}
+
+#[derive(Clone, Debug, Deserialize)]
+pub struct SearchUserResponse {
+ pub results: Vec<User>,
+ pub limited: bool,
+}
+
+#[derive(Clone, Debug, Deserialize)]
+pub struct User {
+ pub user_id: String,
+ #[serde(default)]
+ pub display_name: Option<String>,
+ #[serde(default)]
+ pub avatar_url: Option<String>,
+}
+
+fn u64_is_10(number: &u64) -> bool {
+ number == &10
+}
diff --git a/fractal-matrix-api/src/types.rs b/fractal-matrix-api/src/types.rs
index 96aa9d1f..fce0a4a4 100644
--- a/fractal-matrix-api/src/types.rs
+++ b/fractal-matrix-api/src/types.rs
@@ -21,4 +21,5 @@ pub use crate::model::stickers::StickerGroup;
pub use crate::model::sync::JoinedRoom;
pub use crate::model::sync::SyncResponse;
pub use crate::model::sync::UnreadNotificationsCount;
-pub use crate::model::userinfo::UserInfo;
+pub use crate::model::user::*;
+pub use crate::model::*;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]