From 8b4edc46a7ac31e276beb0922e87f0a7f17bc9f7 Mon Sep 17 00:00:00 2001 From: "B. Petersen" Date: Tue, 11 Feb 2020 02:12:44 +0100 Subject: [PATCH] implement dc_set_config_from_qr() --- deltachat-ffi/src/lib.rs | 8 ++++++- examples/repl/cmdline.rs | 4 ++++ src/qr.rs | 51 +++++++++++++++++++++++++++++++++++----- 3 files changed, 56 insertions(+), 7 deletions(-) diff --git a/deltachat-ffi/src/lib.rs b/deltachat-ffi/src/lib.rs index 3f13361e1..a37d84db4 100644 --- a/deltachat-ffi/src/lib.rs +++ b/deltachat-ffi/src/lib.rs @@ -435,7 +435,13 @@ pub unsafe extern "C" fn dc_set_config_from_qr( let qr = to_string_lossy(qr); let ffi_context = &*context; ffi_context - .with_inner(|ctx| qr::set_config_from_qr(ctx, &qr) as libc::c_int) + .with_inner(|ctx| match qr::set_config_from_qr(ctx, &qr) { + Ok(()) => 1, + Err(err) => { + error!(ctx, "Failed to create account from QR code: {}", err); + 0 + } + }) .unwrap_or(0) } diff --git a/examples/repl/cmdline.rs b/examples/repl/cmdline.rs index b944a9577..79bb8ebe7 100644 --- a/examples/repl/cmdline.rs +++ b/examples/repl/cmdline.rs @@ -967,6 +967,10 @@ pub fn dc_cmdline(context: &Context, line: &str) -> Result<(), failure::Error> { res.get_text2() ); } + "setqr" => { + ensure!(!arg1.is_empty(), "Argument missing."); + set_config_from_qr(context, arg1); + } "providerinfo" => { ensure!(!arg1.is_empty(), "Argument missing."); match provider::get_provider_info(arg1) { diff --git a/src/qr.rs b/src/qr.rs index a8955c78e..15e4cbc69 100644 --- a/src/qr.rs +++ b/src/qr.rs @@ -4,6 +4,7 @@ use lazy_static::lazy_static; use percent_encoding::percent_decode_str; use crate::chat; +use crate::config::*; use crate::constants::Blocked; use crate::contact::*; use crate::context::Context; @@ -14,6 +15,7 @@ use crate::lot::{Lot, LotState}; use crate::param::*; use crate::peerstate::*; use reqwest::Url; +use serde::Deserialize; const OPENPGP4FPR_SCHEME: &str = "OPENPGP4FPR:"; // yes: uppercase const DCACCOUNT_SCHEME: &str = "DCACCOUNT:"; @@ -205,12 +207,49 @@ fn decode_account(_context: &Context, qr: &str) -> Lot { lot } -pub fn set_config_from_qr(context: &Context, qr: &str) -> bool { - error!( - context, - "Setting config from QR is not yet implemented :/ QR code: {}", qr - ); - false +#[derive(Debug, Deserialize)] +struct CreateAccountResponse { + email: String, + password: String, +} + +/// take a qr of the type DC_QR_ACCOUNT, parse it's parameters, +/// download additional information from the contained url and set the parameters. +/// on success, a configure::configure() should be able to log in to the account +pub fn set_config_from_qr(context: &Context, qr: &str) -> Result<(), Error> { + let url_str = &qr[DCACCOUNT_SCHEME.len()..]; + + let response = reqwest::blocking::Client::new().post(url_str).send(); + if response.is_err() { + return Err(format_err!( + "Cannot create account, request to {} failed", + url_str + )); + } + let response = response.unwrap(); + if !response.status().is_success() { + return Err(format_err!( + "Request to {} unsuccessful: {:?}", + url_str, + response + )); + } + + let parsed: reqwest::Result = response.json(); + if parsed.is_err() { + return Err(format_err!( + "Failed to parse JSON response from {}: error: {:?}", + url_str, + parsed + )); + } + println!("response: {:?}", &parsed); + let parsed = parsed.unwrap(); + + context.set_config(Config::Addr, Some(&parsed.email))?; + context.set_config(Config::MailPw, Some(&parsed.password))?; + + Ok(()) } /// Extract address for the mailto scheme.