From bb81024ac7177a7e9875f9d1d3cc77e5f3b0bda9 Mon Sep 17 00:00:00 2001 From: Benjamin Walker Date: Thu, 17 Oct 2024 13:17:17 +1000 Subject: [PATCH] Relax postmaster checks #51 --- classes/check/dnsmx.php | 4 +--- classes/check/dnspostmastertools.php | 36 ++++++++++++++++++++++------ classes/dns_util.php | 31 ++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 10 deletions(-) diff --git a/classes/check/dnsmx.php b/classes/check/dnsmx.php index 9f2c0b8..7d13dca 100644 --- a/classes/check/dnsmx.php +++ b/classes/check/dnsmx.php @@ -78,9 +78,7 @@ public function get_result(): result { $status = result::WARNING; $summary = "MX DNS record missing"; } else { - $allmxdomains = join('
', array_map(function ($x) { - return $x['target'] . ' (' . $x['pri'] . ')'; - }, $mxdomains)); + $allmxdomains = $dns->format_mx_records($mxdomains); $details .= "

MX record found on domain $noreplydomain pointing to
$allmxdomains

"; $status = result::OK; $summary = "MX record points to " . $mxdomains[0]['target']; diff --git a/classes/check/dnspostmastertools.php b/classes/check/dnspostmastertools.php index 784d166..4c04e7a 100644 --- a/classes/check/dnspostmastertools.php +++ b/classes/check/dnspostmastertools.php @@ -56,9 +56,6 @@ public function get_action_link(): ?\action_link { public function get_result(): result { global $DB, $CFG; - $url = new \moodle_url($CFG->wwwroot); - $domain = $url->get_host(); - $details = ''; $details .= ''; $status = result::INFO; @@ -76,28 +73,53 @@ public function get_result(): result { $vendornames = join(', ', $vendors); $summary = "Post master tools setup for $vendornames "; + // Check the most common user domains. + $userdomains = $dns->get_user_domains(5); + $domaintable = ''; + $targets = []; + if (!empty($userdomains)) { + $domaintable .= '
VendorTokenConfirmedUrl
'; + $domaintable .= ''; + + foreach ($userdomains as $domain) { + $targets = array_merge($targets, array_column($mxrecords, 'target')); + $mxrecords = $dns->get_mx_record($domain->domain); + $allmxdomains = $dns->format_mx_records($mxrecords); + $domaintable .= ""; + } + $domaintable .= "
Top user domainsUsersMX records
$domain->domain$domain->count$allmxdomains
"; + } + $status = result::INFO; foreach ($vendors as $vendor) { $token = get_config('tool_emailutils', 'postmaster' . $vendor . 'token'); $record = $dns->get_matching_dns_record($noreplydomain, $token); + $usevendor = !empty(array_filter($targets, function($target) use ($vendor) { + return strpos($target, $vendor) !== false; + })); - if (empty($token)) { + if (empty($token) && !$usevendor) { + $summary = "Post master tools not required for $vendor"; + $status = result::NA; + $confirmed = 'N/A'; + } else if (empty($token)) { $summary = "Post master tools not setup with $vendor"; - $status = result::WARNING; + $status = result::INFO; $confirmed = 'N/A'; } else if (empty($record)) { $confirmed = 'No'; $details .= "

$token was not found in TXT records

"; - $status = result::ERROR; + $status = result::WARNING; $summary = "Post master tools not verified with $vendor"; } else { $confirmed = 'Yes'; $status = result::OK; } - $details .= "$vendor$token$confirmed"; + $details .= "$vendor$token$confirmed"; } $details .= ''; + $details .= $domaintable; return new result($status, $summary, $details); } diff --git a/classes/dns_util.php b/classes/dns_util.php index 09596c0..004e932 100644 --- a/classes/dns_util.php +++ b/classes/dns_util.php @@ -96,6 +96,26 @@ public function get_subdomains($domain) { return rtrim(strstr($domain, $primarydomain, true), '.'); } + /** + * Gets the most common user email domains from the database. + * @param int $number limits the number of domains + * @return array + */ + public function get_user_domains(int $number = 0): array { + global $DB; + + $domainsql = $DB->sql_substr('LOWER(email)', $DB->sql_position("'@'", 'email') . ' + 1'); + $sql = "SELECT $domainsql AS domain, count(*) AS count + FROM {user} + WHERE email LIKE '%@%.%' AND suspended = 0 AND deleted = 0 + GROUP BY $domainsql + ORDER BY count DESC"; + if (!empty($number)) { + $sql .= " LIMIT $number"; + } + return $DB->get_records_sql($sql); + } + /** * Get spf txt record contents * @param string $domain specify a different domain @@ -235,6 +255,17 @@ public function get_mx_record($domain) { return $records; } + /** + * Formats MX records to display in checks + * @param array $mxrecords + * @return string + */ + public function format_mx_records(array $mxrecords): string { + return join('
', array_map(function ($x) { + return $x['target'] . ' (' . $x['pri'] . ')'; + }, $mxrecords)); + } + /** * Get matching record contents * @param string $domain domain to check