mirror of
https://github.com/chatmail/core.git
synced 2026-04-17 21:46:35 +03:00
add dns_prefill attribute to entered login params and implement parsing
for it
This commit is contained in:
@@ -54,6 +54,9 @@ pub struct EnteredLoginParam {
|
||||
/// If true, login via OAUTH2 (not recommended anymore).
|
||||
/// Default: false
|
||||
pub oauth2: Option<bool>,
|
||||
|
||||
/// IP addresses for prefilling DNS
|
||||
pub dns_prefill: Vec<String>,
|
||||
}
|
||||
|
||||
impl From<dc::EnteredLoginParam> for EnteredLoginParam {
|
||||
@@ -75,6 +78,7 @@ impl From<dc::EnteredLoginParam> for EnteredLoginParam {
|
||||
smtp_password: param.smtp.password.into_option(),
|
||||
certificate_checks: certificate_checks.into_option(),
|
||||
oauth2: param.oauth2.into_option(),
|
||||
dns_prefill: param.dns_prefill,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -101,6 +105,7 @@ impl TryFrom<EnteredLoginParam> for dc::EnteredLoginParam {
|
||||
},
|
||||
certificate_checks: param.certificate_checks.unwrap_or_default().into(),
|
||||
oauth2: param.oauth2.unwrap_or_default(),
|
||||
dns_prefill: param.dns_prefill,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,6 +97,9 @@ pub struct EnteredLoginParam {
|
||||
|
||||
/// If true, login via OAUTH2 (not recommended anymore)
|
||||
pub oauth2: bool,
|
||||
|
||||
/// IP addresses for prefilling DNS
|
||||
pub dns_prefill: Vec<String>,
|
||||
}
|
||||
|
||||
impl EnteredLoginParam {
|
||||
@@ -191,6 +194,7 @@ impl EnteredLoginParam {
|
||||
},
|
||||
certificate_checks,
|
||||
oauth2,
|
||||
dns_prefill: Default::default(),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -360,6 +364,7 @@ mod tests {
|
||||
},
|
||||
certificate_checks: Default::default(),
|
||||
oauth2: false,
|
||||
dns_prefill: Default::default(),
|
||||
};
|
||||
param.save(&t).await?;
|
||||
assert_eq!(
|
||||
|
||||
30
src/qr.rs
30
src/qr.rs
@@ -12,6 +12,7 @@ use percent_encoding::{NON_ALPHANUMERIC, percent_decode_str, percent_encode};
|
||||
use rand::TryRngCore as _;
|
||||
use rand::distr::{Alphanumeric, SampleString};
|
||||
use serde::Deserialize;
|
||||
use url::Url;
|
||||
|
||||
use crate::config::Config;
|
||||
use crate::contact::{Contact, ContactId, Origin};
|
||||
@@ -656,6 +657,7 @@ async fn decode_ideltachat(context: &Context, prefix: &str, qr: &str) -> Result<
|
||||
/// scheme: `DCACCOUNT:example.org`
|
||||
/// or `DCACCOUNT:https://example.org/new`
|
||||
/// or `DCACCOUNT:https://example.org/new_email?t=1w_7wDjgjelxeX884x96v3`
|
||||
/// or `dcaccount:example.org?a=127.0.0.1,[::1]`
|
||||
fn decode_account(qr: &str) -> Result<Qr> {
|
||||
let payload = qr
|
||||
.get(DCACCOUNT_SCHEME.len()..)
|
||||
@@ -784,9 +786,33 @@ pub(crate) async fn login_param_from_account_qr(
|
||||
if !payload.starts_with(HTTPS_SCHEME) {
|
||||
let rng = &mut rand::rngs::OsRng.unwrap_err();
|
||||
let username = Alphanumeric.sample_string(rng, 9);
|
||||
let addr = username + "@" + payload;
|
||||
let host = if let Some(start_of_query) = payload.find("?") {
|
||||
payload
|
||||
.get(..start_of_query)
|
||||
.context("failed to ignore query part")?
|
||||
} else {
|
||||
payload
|
||||
};
|
||||
let addr = username + "@" + host;
|
||||
let password = Alphanumeric.sample_string(rng, 50);
|
||||
|
||||
let dns_prefill: Vec<String> = match Url::parse(qr) {
|
||||
Ok(url) => {
|
||||
let options = url.query_pairs();
|
||||
let parameter_map: BTreeMap<String, String> = options
|
||||
.map(|(key, value)| (key.into_owned(), value.into_owned()))
|
||||
.collect();
|
||||
parameter_map
|
||||
.get("a")
|
||||
.map(|ips| ips.split(",").map(|s| s.to_owned()).collect())
|
||||
.unwrap_or_default()
|
||||
}
|
||||
Err(err) => {
|
||||
error!(context, "error parsing parameter of account url: {err}");
|
||||
Default::default()
|
||||
}
|
||||
};
|
||||
|
||||
let param = EnteredLoginParam {
|
||||
addr,
|
||||
imap: EnteredServerLoginParam {
|
||||
@@ -796,6 +822,7 @@ pub(crate) async fn login_param_from_account_qr(
|
||||
smtp: Default::default(),
|
||||
certificate_checks: EnteredCertificateChecks::Strict,
|
||||
oauth2: false,
|
||||
dns_prefill,
|
||||
};
|
||||
return Ok(param);
|
||||
}
|
||||
@@ -816,6 +843,7 @@ pub(crate) async fn login_param_from_account_qr(
|
||||
smtp: Default::default(),
|
||||
certificate_checks: EnteredCertificateChecks::Strict,
|
||||
oauth2: false,
|
||||
dns_prefill: Default::default(),
|
||||
};
|
||||
|
||||
Ok(param)
|
||||
|
||||
@@ -191,6 +191,7 @@ pub(crate) fn login_param_from_login_qr(
|
||||
},
|
||||
certificate_checks: certificate_checks.unwrap_or_default(),
|
||||
oauth2: false,
|
||||
dns_prefill: Default::default(),
|
||||
};
|
||||
Ok(param)
|
||||
}
|
||||
|
||||
@@ -711,6 +711,31 @@ async fn test_decode_account() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_decode_account_with_dns_prefill() -> Result<()> {
|
||||
let ctx = &TestContext::new().await;
|
||||
|
||||
for (qr, prefill_ips) in [
|
||||
(
|
||||
"dcaccount:example.org?a=127.0.0.1,[::1]",
|
||||
vec!["127.0.0.1", "[::1]"],
|
||||
),
|
||||
(
|
||||
"DCACCOUNT:example.org?a=127.0.0.1,[::1]",
|
||||
vec!["127.0.0.1", "[::1]"],
|
||||
),
|
||||
("dcaccount:example.org?a=[::1]", vec!["[::1]"]),
|
||||
("DCACCOUNT:example.org?a=127.0.0.1", vec!["127.0.0.1"]),
|
||||
] {
|
||||
let param = login_param_from_account_qr(ctx, qr).await?;
|
||||
println!("addr {}", param.addr);
|
||||
assert!(param.addr.ends_with("example.org"));
|
||||
assert_eq!(param.dns_prefill, prefill_ips);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_decode_tg_socks_proxy() -> Result<()> {
|
||||
let t = TestContext::new().await;
|
||||
|
||||
Reference in New Issue
Block a user