let dc_check_qr() accept DCACCOUNT-schemes

This commit is contained in:
B. Petersen
2020-02-09 01:44:17 +01:00
committed by holger krekel
parent 875e89e71a
commit 1882176489
3 changed files with 55 additions and 1 deletions

View File

@@ -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.

View File

@@ -86,6 +86,9 @@ pub enum LotState {
/// test1=formatted fingerprint
QrFprWithoutAddr = 230,
/// text1=domain
QrAccount = 250,
/// id=contact
QrAddr = 320,

View File

@@ -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<str>) -> 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());
}
}