Skip to content

Commit

Permalink
feat: add wildcard pattern support to provider database
Browse files Browse the repository at this point in the history
  • Loading branch information
link2xt committed Feb 6, 2024
1 parent f1688d2 commit f8907e3
Show file tree
Hide file tree
Showing 4 changed files with 366 additions and 396 deletions.
4 changes: 2 additions & 2 deletions scripts/create-provider-data-rs.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,9 +220,9 @@ def process_dir(dir):

process_dir(Path(sys.argv[1]))

out_all += "pub(crate) static PROVIDER_DATA: Lazy<HashMap<&'static str, &'static Provider>> = Lazy::new(|| HashMap::from([\n"
out_all += "pub(crate) static PROVIDER_DATA: [(&str, &Provider); " + str(len(domains_set)) + "] = [\n";
out_all += out_domains
out_all += "]));\n\n"
out_all += "];\n\n"

out_all += "pub(crate) static PROVIDER_IDS: Lazy<HashMap<&'static str, &'static Provider>> = Lazy::new(|| HashMap::from([\n"
out_all += out_ids
Expand Down
2 changes: 1 addition & 1 deletion scripts/update-provider-database.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ set -euo pipefail
export TZ=UTC

# Provider database revision.
REV=18f714cf73d0bdfb8b013fa344494ab80c92b477
REV=2f3db24107e4802c2df0aa0a40f0e144006c0a9b

CORE_ROOT="$PWD"
TMP="$(mktemp -d)"
Expand Down
63 changes: 41 additions & 22 deletions src/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,18 @@ pub async fn get_provider_info(

/// Finds a provider in offline database based on domain.
pub fn get_provider_by_domain(domain: &str) -> Option<&'static Provider> {
if let Some(provider) = PROVIDER_DATA.get(domain.to_lowercase().as_str()) {
return Some(*provider);
let domain = domain.to_lowercase();
for (pattern, provider) in PROVIDER_DATA {
if let Some(suffix) = pattern.strip_prefix('*') {
// Wildcard domain pattern.
//
// For example, `suffix` is ".hermes.radio" for "*.hermes.radio" pattern.
if domain.ends_with(suffix) {
return Some(provider);
}
} else if pattern == domain {
return Some(provider);
}
}

None
Expand All @@ -226,33 +236,42 @@ pub fn get_provider_by_domain(domain: &str) -> Option<&'static Provider> {
///
/// For security reasons, only Gmail can be configured this way.
pub async fn get_provider_by_mx(context: &Context, domain: &str) -> Option<&'static Provider> {
if let Ok(resolver) = get_resolver() {
let mut fqdn: String = domain.to_string();
if !fqdn.ends_with('.') {
fqdn.push('.');
let Ok(resolver) = get_resolver() else {
warn!(context, "Cannot get a resolver to check MX records.");
return None;
};

let mut fqdn: String = domain.to_string();
if !fqdn.ends_with('.') {
fqdn.push('.');
}

let Ok(mx_domains) = resolver.mx_lookup(fqdn).await else {
warn!(context, "Cannot resolve MX records for {domain:?}.");
return None;
};

for (provider_domain_pattern, provider) in PROVIDER_DATA {
if provider.id != "gmail" {
// MX lookup is limited to Gmail for security reasons
continue;
}

if let Ok(mx_domains) = resolver.mx_lookup(fqdn).await {
for (provider_domain, provider) in &*PROVIDER_DATA {
if provider.id != "gmail" {
// MX lookup is limited to Gmail for security reasons
continue;
}
if provider_domain_pattern.starts_with('*') {
// Skip wildcard patterns.
continue;
}

let provider_fqdn = provider_domain.to_string() + ".";
let provider_fqdn_dot = ".".to_string() + &provider_fqdn;
let provider_fqdn = provider_domain_pattern.to_string() + ".";
let provider_fqdn_dot = ".".to_string() + &provider_fqdn;

for mx_domain in mx_domains.iter() {
let mx_domain = mx_domain.exchange().to_lowercase().to_utf8();
for mx_domain in mx_domains.iter() {
let mx_domain = mx_domain.exchange().to_lowercase().to_utf8();

if mx_domain == provider_fqdn || mx_domain.ends_with(&provider_fqdn_dot) {
return Some(provider);
}
}
if mx_domain == provider_fqdn || mx_domain.ends_with(&provider_fqdn_dot) {
return Some(provider);
}
}
} else {
warn!(context, "cannot get a resolver to check MX records.");
}

None
Expand Down
Loading

0 comments on commit f8907e3

Please sign in to comment.