[fractal] Request 3PID (email) verification through matrix-sdk



commit 318d4e7450b3af01eccf4568e976b800dd37eb60
Author: Alejandro Domínguez <adomu net-c com>
Date:   Fri Sep 25 07:32:18 2020 +0200

    Request 3PID (email) verification through matrix-sdk

 fractal-gtk/src/backend/room.rs                    | 16 +---
 fractal-gtk/src/backend/user.rs                    | 95 +++++++---------------
 fractal-gtk/src/widgets/address.rs                 | 61 ++++++++------
 fractal-matrix-api/src/meson.build                 |  1 -
 fractal-matrix-api/src/r0/contact.rs               |  1 -
 .../r0/contact/request_verification_token_email.rs | 48 -----------
 6 files changed, 69 insertions(+), 153 deletions(-)
---
diff --git a/fractal-gtk/src/backend/room.rs b/fractal-gtk/src/backend/room.rs
index 4a86739e..a9423054 100644
--- a/fractal-gtk/src/backend/room.rs
+++ b/fractal-gtk/src/backend/room.rs
@@ -2,7 +2,7 @@ use log::error;
 use serde_json::json;
 
 use fractal_api::{
-    api::{error::ErrorKind as RumaErrorKind, Error as RumaClientError},
+    api::error::ErrorKind as RumaErrorKind,
     identifiers::{Error as IdError, EventId, RoomId, RoomIdOrAliasId, UserId},
     url::{ParseError as UrlError, Url},
     Client as MatrixClient, Error as MatrixError, FromHttpResponseError as RumaResponseError,
@@ -112,12 +112,7 @@ pub async fn get_room_detail(
 
     let response = match session_client.send(request).await {
         Ok(response) => Some(response),
-        Err(MatrixError::RumaResponse(RumaResponseError::Http(ServerError::Known(
-            RumaClientError {
-                kind: RumaErrorKind::NotFound,
-                ..
-            },
-        )))) => None,
+        Err(err) if get_ruma_error_kind(&err) == Some(&RumaErrorKind::NotFound) => None,
         Err(err) => return Err(err.into()),
     };
 
@@ -166,12 +161,7 @@ pub async fn get_room_avatar(
 
     let response = match session_client.send(request).await {
         Ok(response) => Some(response),
-        Err(MatrixError::RumaResponse(RumaResponseError::Http(ServerError::Known(
-            RumaClientError {
-                kind: RumaErrorKind::NotFound,
-                ..
-            },
-        )))) => None,
+        Err(err) if get_ruma_error_kind(&err) == Some(&RumaErrorKind::NotFound) => None,
         Err(err) => return Err(err.into()),
     };
 
diff --git a/fractal-gtk/src/backend/user.rs b/fractal-gtk/src/backend/user.rs
index 88bdfe28..42433d73 100644
--- a/fractal-gtk/src/backend/user.rs
+++ b/fractal-gtk/src/backend/user.rs
@@ -1,3 +1,4 @@
+use fractal_api::api::error::ErrorKind as RumaErrorKind;
 use fractal_api::identifiers::UserId;
 use fractal_api::reqwest::Error as ReqwestError;
 use fractal_api::url::{ParseError as UrlError, Url};
@@ -17,6 +18,7 @@ use std::path::PathBuf;
 use super::room::AttachedFileError;
 use crate::model::member::Member;
 use fractal_api::api::r0::account::change_password::Request as ChangePasswordRequest;
+use fractal_api::api::r0::account::request_3pid_management_token_via_email::Request as EmailTokenRequest;
 use fractal_api::api::r0::contact::get_contacts::Request as GetContactsRequest;
 use fractal_api::api::r0::contact::get_contacts::ThirdPartyIdentifier;
 use fractal_api::api::r0::profile::get_display_name::Request as GetDisplayNameRequest;
@@ -41,10 +43,6 @@ use fractal_api::r0::contact::create::Parameters as AddThreePIDParameters;
 use fractal_api::r0::contact::delete::request as delete_contact;
 use fractal_api::r0::contact::delete::Body as DeleteThreePIDBody;
 use fractal_api::r0::contact::delete::Parameters as DeleteThreePIDParameters;
-use fractal_api::r0::contact::request_verification_token_email::request as 
request_contact_verification_token_email;
-use fractal_api::r0::contact::request_verification_token_email::Body as EmailTokenBody;
-use fractal_api::r0::contact::request_verification_token_email::Parameters as EmailTokenParameters;
-use fractal_api::r0::contact::request_verification_token_email::Response as EmailTokenResponse;
 use fractal_api::r0::contact::request_verification_token_msisdn::request as 
request_contact_verification_token_msisdn;
 use fractal_api::r0::contact::request_verification_token_msisdn::Body as PhoneTokenBody;
 use fractal_api::r0::contact::request_verification_token_msisdn::Parameters as PhoneTokenParameters;
@@ -55,7 +53,7 @@ use fractal_api::r0::ThreePIDCredentials;
 
 use super::{dw_media, ContentType};
 
-use super::{remove_matrix_access_token_if_present, HandleError};
+use super::{get_ruma_error_kind, remove_matrix_access_token_if_present, HandleError};
 use crate::app::App;
 use crate::util::i18n::i18n;
 use crate::APPOP;
@@ -135,79 +133,46 @@ pub async fn get_threepid(
 }
 
 #[derive(Debug)]
-pub enum GetTokenEmailError {
-    IdentityServerUrl(UrlError),
-    Reqwest(ReqwestError),
-    TokenUsed,
-    Denied,
-}
+pub struct GetTokenEmailError(MatrixError);
 
-impl From<ReqwestError> for GetTokenEmailError {
-    fn from(err: ReqwestError) -> Self {
-        Self::Reqwest(err)
+impl From<MatrixError> for GetTokenEmailError {
+    fn from(err: MatrixError) -> Self {
+        Self(err)
     }
 }
 
 impl HandleError for GetTokenEmailError {
     fn handle_error(&self) {
-        match self {
-            Self::TokenUsed => {
-                let error = i18n("Email is already in use");
-                APPOP!(show_error_dialog_in_settings, (error));
-            }
-            Self::Denied => {
-                let error = i18n("Please enter a valid email address.");
-                APPOP!(show_error_dialog_in_settings, (error));
-            }
-            Self::Reqwest(err) => {
-                let error = i18n("Couldn’t add the email address.");
-                let err_str = format!("{:?}", err);
-                error!(
-                    "{}",
-                    remove_matrix_access_token_if_present(&err_str).unwrap_or(err_str)
-                );
-                APPOP!(show_error_dialog_in_settings, (error));
-            }
-            Self::IdentityServerUrl(err) => {
-                let error = i18n("The identity server is invalid.");
-                error!("The identity server is invalid: {:?}", err);
-                APPOP!(show_error_dialog_in_settings, (error));
-            }
+        let err = &self.0;
+        let ruma_error_kind = get_ruma_error_kind(err);
+
+        if ruma_error_kind == Some(&RumaErrorKind::ThreepidInUse) {
+            let error = i18n("Email is already in use");
+            APPOP!(show_error_dialog_in_settings, (error));
+        } else if ruma_error_kind == Some(&RumaErrorKind::ThreepidDenied) {
+            let error = i18n("Please enter a valid email address.");
+            APPOP!(show_error_dialog_in_settings, (error));
+        } else {
+            let error = i18n("Couldn’t add the email address.");
+            let err_str = format!("{:?}", err);
+            error!(
+                "{}",
+                remove_matrix_access_token_if_present(&err_str).unwrap_or(err_str)
+            );
+            APPOP!(show_error_dialog_in_settings, (error));
         }
     }
 }
 
-pub fn get_email_token(
-    base: Url,
-    access_token: AccessToken,
-    identity: Url,
-    email: String,
+pub async fn get_email_token(
+    session_client: MatrixClient,
+    email: &str,
     client_secret: String,
 ) -> Result<(String, String), GetTokenEmailError> {
-    use EmailTokenResponse::*;
-
-    let params = EmailTokenParameters { access_token };
-    let body = EmailTokenBody {
-        id_server: identity
-            .try_into()
-            .map_err(GetTokenEmailError::IdentityServerUrl)?,
-        client_secret: client_secret.clone(),
-        email,
-        send_attempt: 1,
-        next_link: None,
-    };
-
-    let request = request_contact_verification_token_email(base, &params, &body)?;
+    let request = EmailTokenRequest::new(&client_secret, email, 1_u32.into());
+    let response = session_client.send(request).await?;
 
-    match HTTP_CLIENT
-        .get_client()
-        .execute(request)?
-        .json::<EmailTokenResponse>()?
-    {
-        Passed(info) => Ok((info.sid, client_secret)),
-        Failed(info) if info.errcode == "M_THREEPID_IN_USE" => Err(GetTokenEmailError::TokenUsed),
-        Failed(_) => Err(GetTokenEmailError::Denied),
-    }
+    Ok((response.sid, client_secret))
 }
 
 #[derive(Debug)]
diff --git a/fractal-gtk/src/widgets/address.rs b/fractal-gtk/src/widgets/address.rs
index 89735333..87c1c0b4 100644
--- a/fractal-gtk/src/widgets/address.rs
+++ b/fractal-gtk/src/widgets/address.rs
@@ -2,13 +2,14 @@ use crate::backend::user;
 use fractal_api::r0::AccessToken;
 use fractal_api::r0::Medium;
 use fractal_api::url::Url;
+use fractal_api::Client as MatrixClient;
 use glib::signal;
 use gtk::prelude::*;
 use rand::distributions::Alphanumeric;
 use rand::{thread_rng, Rng};
 use std::thread;
 
-use crate::app::App;
+use crate::app::{App, RUNTIME};
 use crate::appop::AppOp;
 use crate::backend::HandleError;
 
@@ -161,7 +162,7 @@ impl<'a> Address<'a> {
         let entry = self.entry.clone();
         let address = self.address.clone();
         let access_token = login_data.access_token;
-        let server_url = login_data.session_client.homeserver().clone();
+        let session_client = login_data.session_client;
         let id_server = login_data.identity_url;
         self.signal_id = Some(self.button.clone().connect_clicked(move |w| {
             if !w.get_sensitive() || !w.is_visible() {
@@ -182,16 +183,21 @@ impl<'a> Address<'a> {
             match action {
                 Some(AddressAction::Delete) => {
                     if let Some(address) = address.clone() {
-                        delete_address(medium, address, server_url.clone(), access_token.clone());
+                        delete_address(
+                            medium,
+                            address,
+                            session_client.homeserver().clone(),
+                            access_token.clone(),
+                        );
                     }
                 }
                 Some(AddressAction::Add) => {
                     let address = entry.get_text().to_string();
                     add_address(
+                        session_client.clone(),
                         medium,
                         id_server.clone(),
                         address,
-                        server_url.clone(),
                         access_token.clone(),
                     );
                 }
@@ -215,37 +221,42 @@ fn delete_address(medium: Medium, address: String, server_url: Url, access_token
 }
 
 fn add_address(
+    session_client: MatrixClient,
     medium: Medium,
     id_server: Url,
     address: String,
-    server_url: Url,
     access_token: AccessToken,
 ) {
+    let server_url = session_client.homeserver().clone();
     let secret: String = thread_rng().sample_iter(&Alphanumeric).take(36).collect();
-    thread::spawn(move || match medium {
+    match medium {
         Medium::MsIsdn => {
-            match user::get_phone_token(server_url, access_token, id_server, address, secret) {
-                Ok((sid, secret)) => {
-                    let sid = Some(sid);
-                    let secret = Some(secret);
-                    APPOP!(get_token_phone, (sid, secret))
-                }
-                Err(err) => {
-                    err.handle_error();
+            thread::spawn(move || {
+                match user::get_phone_token(server_url, access_token, id_server, address, secret) {
+                    Ok((sid, secret)) => {
+                        let sid = Some(sid);
+                        let secret = Some(secret);
+                        APPOP!(get_token_phone, (sid, secret))
+                    }
+                    Err(err) => {
+                        err.handle_error();
+                    }
                 }
-            }
+            });
         }
         Medium::Email => {
-            match user::get_email_token(server_url, access_token, id_server, address, secret) {
-                Ok((sid, secret)) => {
-                    let sid = Some(sid);
-                    let secret = Some(secret);
-                    APPOP!(get_token_email, (sid, secret));
-                }
-                Err(err) => {
-                    err.handle_error();
+            RUNTIME.spawn(async move {
+                match user::get_email_token(session_client, &address, secret).await {
+                    Ok((sid, secret)) => {
+                        let sid = Some(sid);
+                        let secret = Some(secret);
+                        APPOP!(get_token_email, (sid, secret));
+                    }
+                    Err(err) => {
+                        err.handle_error();
+                    }
                 }
-            }
+            });
         }
-    });
+    };
 }
diff --git a/fractal-matrix-api/src/meson.build b/fractal-matrix-api/src/meson.build
index f998b126..b97cc735 100644
--- a/fractal-matrix-api/src/meson.build
+++ b/fractal-matrix-api/src/meson.build
@@ -8,7 +8,6 @@ api_sources = files(
   'r0/account/logout.rs',
   'r0/contact/create.rs',
   'r0/contact/delete.rs',
-  'r0/contact/request_verification_token_email.rs',
   'r0/contact/request_verification_token_msisdn.rs',
   'r0/server/domain_info.rs',
   'r0/sync/sync_events.rs',
diff --git a/fractal-matrix-api/src/r0/contact.rs b/fractal-matrix-api/src/r0/contact.rs
index 839045d1..14804e9d 100644
--- a/fractal-matrix-api/src/r0/contact.rs
+++ b/fractal-matrix-api/src/r0/contact.rs
@@ -1,4 +1,3 @@
 pub mod create;
 pub mod delete;
-pub mod request_verification_token_email;
 pub mod request_verification_token_msisdn;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]