discourse/lib/problem_check/group_email_credentials.rb
Ted Johansson a72dc2f420
DEV: Introduce a problem checks API (#25783)
Previously, problem checks were all added as either class methods or blocks in AdminDashboardData. Another set of class methods were used to add and run problem checks.

As of this PR, problem checks are promoted to first-class citizens. Each problem check receives their own class. This class of course contains the implementation for running the check, but also configuration items like retry strategies (for scheduled checks.)

In addition, the parent class ProblemCheck also serves as a registry for checks. For example we can get a list of all existing check classes through ProblemCheck.checks, or just the ones running on a schedule through ProblemCheck.scheduled.

After this refactor, the task of adding a new check is significantly simplified. You add a class that inherits ProblemCheck, you implement it, add a test, and you're good to go.
2024-02-23 11:20:32 +08:00

75 lines
2.0 KiB
Ruby

# frozen_string_literal: true
##
# If group SMTP or IMAP has been configured, we want to make sure the
# credentials are always valid otherwise emails will not be sending out
# from group inboxes. This check is run as part of scheduled admin
# problem checks, and if any credentials have issues they will show up on
# the admin dashboard as a high priority issue.
class ProblemCheck::GroupEmailCredentials < ProblemCheck
self.perform_every = 30.minutes
def call
[*smtp_errors, *imap_errors]
end
private
def smtp_errors
return [] if !SiteSetting.enable_smtp
Group.with_smtp_configured.find_each.filter_map do |group|
try_validate(group) do
EmailSettingsValidator.validate_smtp(
host: group.smtp_server,
port: group.smtp_port,
username: group.email_username,
password: group.email_password,
)
end
end
end
def imap_errors
return [] if !SiteSetting.enable_imap
Group.with_imap_configured.find_each.filter_map do |group|
try_validate(group) do
EmailSettingsValidator.validate_imap(
host: group.imap_server,
port: group.imap_port,
username: group.email_username,
password: group.email_password,
)
end
end
end
def try_validate(group, &blk)
begin
blk.call
nil
rescue *EmailSettingsExceptionHandler::EXPECTED_EXCEPTIONS => err
message =
I18n.t(
"dashboard.group_email_credentials_warning",
{
base_path: Discourse.base_path,
group_name: group.name,
group_full_name: group.full_name,
error: EmailSettingsExceptionHandler.friendly_exception_message(err, group.smtp_server),
},
)
Problem.new(message, priority: "high", identifier: "group_#{group.id}_email_credentials")
rescue => err
Discourse.warn_exception(
err,
message:
"Unexpected error when checking SMTP credentials for group #{group.id} (#{group.name}).",
)
nil
end
end
end