discourse/app/services/problem_check/group_email_credentials.rb
Ted Johansson d446cc7318
FIX: Fix scheduled targeted problem checks (#35696)
Scheduled problem checks with multiple targets are not honouring the
`run_every` configuration.

For checks with multiple targets, all targets are checked in a single
instance of the problem check. However, we have one problem check
tracker per target.

This mismatch results in the `#ready_to_run?` method always creating a
tracker with no target when being checked.

This commit fixes that by:

**Expect checks to operate on a single target.**

This change makes it so that instances of a `ProblemCheck` class are
initialized with a target. So instead of 1-N we now have an N-N
relationship between checks and trackers.

Each instance can access their `target` through an attribute of the same
name.

This also means problem checks are back to returning a singular
`Problem` or `nil`, instead of `[Problem]` or `[]`.

For scheduled checks, this means that `ScheduleProblemChecks` now
enqueues `N` jobs (where `N` is the number of targets) per check instead
of `1` job per check.

**Update existing targeted checks to operate on a single target.**

This is essentially just removing the loop inside the check.
2025-11-10 10:09:14 +08:00

74 lines
2.1 KiB
Ruby
Vendored

# 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.priority = "high"
self.perform_every = 30.minutes
self.targets = -> do
[*Group.with_smtp_configured.pluck(:name), *Group.with_imap_configured.pluck(:name)]
end
def call
if group = Group.with_smtp_configured.find_by(name: target)
return no_problem if !SiteSetting.enable_smtp
return(
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
if group = Group.with_imap_configured.find_by(name: target)
return no_problem if !SiteSetting.enable_imap
return(
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
no_problem
end
private
def translation_data(group)
{ group_name: group.name, group_full_name: group.full_name }
end
def try_validate(group, &blk)
begin
blk.call
no_problem
rescue *EmailSettingsExceptionHandler::EXPECTED_EXCEPTIONS => err
error_message =
EmailSettingsExceptionHandler.friendly_exception_message(err, group.smtp_server)
problem(group, override_data: { error: error_message })
rescue => err
Discourse.warn_exception(
err,
message:
"Unexpected error when checking SMTP credentials for group #{group.id} (#{group.name}).",
)
no_problem
end
end
end