From 1882176489a31f42f0a6d15be88e821521e43157 Mon Sep 17 00:00:00 2001 From: "B. Petersen" Date: Sun, 9 Feb 2020 01:44:17 +0100 Subject: [PATCH] let dc_check_qr() accept DCACCOUNT-schemes --- deltachat-ffi/deltachat.h | 3 ++- src/lot.rs | 3 +++ src/qr.rs | 50 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/deltachat-ffi/deltachat.h b/deltachat-ffi/deltachat.h index bb883edaf..d7b1c426d 100644 --- a/deltachat-ffi/deltachat.h +++ b/deltachat-ffi/deltachat.h @@ -2111,6 +2111,7 @@ void dc_stop_ongoing_process (dc_context_t* context); #define DC_QR_FPR_OK 210 // id=contact #define DC_QR_FPR_MISMATCH 220 // id=contact #define DC_QR_FPR_WITHOUT_ADDR 230 // test1=formatted fingerprint +#define DC_QR_ACCOUNT 250 // text1=domain #define DC_QR_ADDR 320 // id=contact #define DC_QR_TEXT 330 // text1=text #define DC_QR_URL 332 // text1=URL @@ -2128,12 +2129,12 @@ void dc_stop_ongoing_process (dc_context_t* context); * - DC_QR_FPR_OK with dc_lot_t::id=Contact ID * - DC_QR_FPR_MISMATCH with dc_lot_t::id=Contact ID * - DC_QR_FPR_WITHOUT_ADDR with dc_lot_t::test1=Formatted fingerprint + * - DC_QR_ACCOUNT allows creation of an account, dc_lot_t::text1=domain * - DC_QR_ADDR with dc_lot_t::id=Contact ID * - DC_QR_TEXT with dc_lot_t::text1=Text * - DC_QR_URL with dc_lot_t::text1=URL * - DC_QR_ERROR with dc_lot_t::text1=Error string * - * * @memberof dc_context_t * @param context The context object. * @param qr The text of the scanned QR code. diff --git a/src/lot.rs b/src/lot.rs index e1c14e6e3..c1f27eae0 100644 --- a/src/lot.rs +++ b/src/lot.rs @@ -86,6 +86,9 @@ pub enum LotState { /// test1=formatted fingerprint QrFprWithoutAddr = 230, + /// text1=domain + QrAccount = 250, + /// id=contact QrAddr = 320, diff --git a/src/qr.rs b/src/qr.rs index 76bd9c6f1..1f93dcded 100644 --- a/src/qr.rs +++ b/src/qr.rs @@ -13,8 +13,10 @@ use crate::key::dc_normalize_fingerprint; use crate::lot::{Lot, LotState}; use crate::param::*; use crate::peerstate::*; +use reqwest::Url; const OPENPGP4FPR_SCHEME: &str = "OPENPGP4FPR:"; // yes: uppercase +const DCACCOUNT_SCHEME: &str = "DCACCOUNT:"; const MAILTO_SCHEME: &str = "mailto:"; const MATMSG_SCHEME: &str = "MATMSG:"; const VCARD_SCHEME: &str = "BEGIN:VCARD"; @@ -43,6 +45,8 @@ pub fn check_qr(context: &Context, qr: impl AsRef) -> Lot { if qr.starts_with(OPENPGP4FPR_SCHEME) { decode_openpgp(context, qr) + } else if qr.starts_with(DCACCOUNT_SCHEME) { + decode_account(context, qr) } else if qr.starts_with(MAILTO_SCHEME) { decode_mailto(context, qr) } else if qr.starts_with(SMTP_SCHEME) { @@ -179,6 +183,28 @@ fn decode_openpgp(context: &Context, qr: &str) -> Lot { lot } +/// scheme: `DCACCOUNT:https://example.org/new_email?t=1w_7wDjgjelxeX884x96v3` +fn decode_account(_context: &Context, qr: &str) -> Lot { + let payload = &qr[DCACCOUNT_SCHEME.len()..]; + + let mut lot = Lot::new(); + + if let Ok(url) = Url::parse(payload) { + if url.scheme() == "https" { + lot.state = LotState::QrAccount; + lot.text1 = url.host_str().map(|x| x.to_string()); + } else { + lot.state = LotState::QrError; + lot.text1 = Some(format!("Bad scheme for account url: {}", payload)); + } + } else { + lot.state = LotState::QrError; + lot.text1 = Some(format!("Invalid account url: {}", payload)); + } + + lot +} + /// Extract address for the mailto scheme. /// /// Scheme: `mailto:addr...?subject=...&body=..` @@ -493,4 +519,28 @@ mod tests { assert_eq!(res.get_state(), LotState::QrError); assert_eq!(res.get_id(), 0); } + + #[test] + fn test_decode_account() { + let ctx = dummy_context(); + + let res = check_qr( + &ctx.ctx, + "DCACCOUNT:https://example.org/new_email?t=1w_7wDjgjelxeX884x96v3", + ); + assert_eq!(res.get_state(), LotState::QrAccount); + assert_eq!(res.get_text1().unwrap(), "example.org"); + } + + #[test] + fn test_decode_account_bad_scheme() { + let ctx = dummy_context(); + + let res = check_qr( + &ctx.ctx, + "DCACCOUNT:http://example.org/new_email?t=1w_7wDjgjelxeX884x96v3", + ); + assert_eq!(res.get_state(), LotState::QrError); + assert!(res.get_text1().is_some()); + } }