FEATURE: Add scheduled Twitter login problem check - Part 1 (#25830)
This PR adds a new scheduled problem check that simply tries to connect to Twitter OAuth endpoint to check that it's working. It is using the default retry strategy of 2 retries 30 seconds apart.
This commit is contained in:
parent
a1d7548869
commit
ed2496c59d
|
@ -1506,6 +1506,7 @@ en:
|
|||
description: "Top 10 users who have had likes from a wide range of people."
|
||||
|
||||
dashboard:
|
||||
twitter_login_warning: 'Twitter login appears to not be working at the moment. Check the credentials in <a href="%{base_path}/admin/site_settings/category/login?filter=twitter">the Site Settings</a>.'
|
||||
group_email_credentials_warning: 'There was an issue with the email credentials for the group <a href="%{base_path}/g/%{group_name}/manage/email">%{group_full_name}</a>. No emails will be sent from the group inbox until this problem is addressed. %{error}'
|
||||
rails_env_warning: "Your server is running in %{env} mode."
|
||||
host_names_warning: "Your config/database.yml file is using the default localhost hostname. Update it to use your site's hostname."
|
||||
|
|
|
@ -9,6 +9,16 @@ class Auth::TwitterAuthenticator < Auth::ManagedAuthenticator
|
|||
SiteSetting.enable_twitter_logins
|
||||
end
|
||||
|
||||
def healthy?
|
||||
connection =
|
||||
Faraday.new(url: "https://api.twitter.com") do |config|
|
||||
config.basic_auth(SiteSetting.twitter_consumer_key, SiteSetting.twitter_consumer_secret)
|
||||
end
|
||||
connection.post("/oauth2/token").status == 200
|
||||
rescue Faraday::Error
|
||||
false
|
||||
end
|
||||
|
||||
def after_authenticate(auth_token, existing_account: nil)
|
||||
# Twitter sends a huge amount of data which we don't need, so ignore it
|
||||
auth_token[:extra] = {}
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
class ProblemCheck
|
||||
include ActiveSupport::Configurable
|
||||
|
||||
config_accessor :priority, default: "low", instance_writer: false
|
||||
|
||||
# Determines if the check should be performed at a regular interval, and if
|
||||
# so how often. If left blank, the check will be performed every time the
|
||||
# admin dashboard is loaded, or the data is otherwise requested.
|
||||
|
@ -50,4 +52,25 @@ class ProblemCheck
|
|||
def call
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def problem
|
||||
[
|
||||
Problem.new(
|
||||
I18n.t(translation_key, base_path: Discourse.base_path),
|
||||
priority: self.config.priority,
|
||||
identifier:,
|
||||
),
|
||||
]
|
||||
end
|
||||
|
||||
def no_problem
|
||||
[]
|
||||
end
|
||||
|
||||
def translation_key
|
||||
# TODO: Infer a default based on class name, then move translations in locale file.
|
||||
raise NotImplementedError
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ProblemCheck::TwitterLogin < ProblemCheck
|
||||
self.priority = "high"
|
||||
|
||||
# TODO: Implement.
|
||||
self.perform_every = 24.hours
|
||||
|
||||
def call
|
||||
return no_problem if !authenticator.enabled?
|
||||
return no_problem if authenticator.healthy?
|
||||
|
||||
problem
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def authenticator
|
||||
@authenticator ||= Auth::TwitterAuthenticator.new
|
||||
end
|
||||
|
||||
def translation_key
|
||||
"dashboard.twitter_login_warning"
|
||||
end
|
||||
end
|
|
@ -34,4 +34,13 @@ RSpec.describe Jobs::ProblemChecks do
|
|||
},
|
||||
) { described_class.new.execute([]) }
|
||||
end
|
||||
|
||||
it "does not schedule non-scheduled checks" do
|
||||
expect_not_enqueued_with(
|
||||
job: :problem_check,
|
||||
args: {
|
||||
check_identifier: "non_scheduled_check",
|
||||
},
|
||||
) { described_class.new.execute([]) }
|
||||
end
|
||||
end
|
||||
|
|
|
@ -65,4 +65,37 @@ RSpec.describe Auth::TwitterAuthenticator do
|
|||
expect(authenticator.description_for_user(user)).to eq("")
|
||||
end
|
||||
end
|
||||
|
||||
describe "#healthy?" do
|
||||
let(:authenticator) { described_class.new }
|
||||
|
||||
let(:connection) { mock("Faraday::Connection") }
|
||||
let(:response) { mock("Faraday::Response") }
|
||||
|
||||
before do
|
||||
Faraday.stubs(:new).returns(connection)
|
||||
connection.stubs(:post).returns(response)
|
||||
response.stubs(:status).returns(status)
|
||||
end
|
||||
|
||||
context "when endpoint is reachable" do
|
||||
let(:status) { 200 }
|
||||
|
||||
it { expect(authenticator).to be_healthy }
|
||||
end
|
||||
|
||||
context "when credentials aren't recognized" do
|
||||
let(:status) { 403 }
|
||||
|
||||
it { expect(authenticator).not_to be_healthy }
|
||||
end
|
||||
|
||||
context "when an unexpected error happens" do
|
||||
let(:status) { anything }
|
||||
|
||||
before { connection.stubs(:post).raises(Faraday::ServerError) }
|
||||
|
||||
it { expect(authenticator).not_to be_healthy }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe ProblemCheck::TwitterLogin do
|
||||
let(:problem_check) { described_class.new }
|
||||
|
||||
let(:authenticator) { mock("Auth::TwitterAuthenticator") }
|
||||
|
||||
before { Auth::TwitterAuthenticator.stubs(:new).returns(authenticator) }
|
||||
|
||||
describe "#call" do
|
||||
context "when Twitter authentication isn't enabled" do
|
||||
before { authenticator.stubs(:enabled?).returns(false) }
|
||||
|
||||
it { expect(problem_check.call).to be_empty }
|
||||
end
|
||||
|
||||
context "when Twitter authentication appears to work" do
|
||||
before do
|
||||
authenticator.stubs(:enabled?).returns(true)
|
||||
authenticator.stubs(:healthy?).returns(true)
|
||||
end
|
||||
|
||||
it { expect(problem_check.call).to be_empty }
|
||||
end
|
||||
|
||||
context "when Twitter authentication appears not to work" do
|
||||
before do
|
||||
authenticator.stubs(:enabled?).returns(true)
|
||||
authenticator.stubs(:healthy?).returns(false)
|
||||
Discourse.stubs(:base_path).returns("foo.bar")
|
||||
end
|
||||
|
||||
it do
|
||||
expect(problem_check.call).to contain_exactly(
|
||||
have_attributes(
|
||||
identifier: :twitter_login,
|
||||
priority: "high",
|
||||
message:
|
||||
'Twitter login appears to not be working at the moment. Check the credentials in <a href="foo.bar/admin/site_settings/category/login?filter=twitter">the Site Settings</a>.',
|
||||
),
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -26,11 +26,12 @@ RSpec.describe ProblemCheck do
|
|||
end
|
||||
|
||||
describe ".checks" do
|
||||
it { expect(described_class.checks).to contain_exactly(scheduled_check, unscheduled_check) }
|
||||
it { expect(described_class.checks).to include(scheduled_check, unscheduled_check) }
|
||||
end
|
||||
|
||||
describe ".scheduled" do
|
||||
it { expect(described_class.scheduled).to contain_exactly(scheduled_check) }
|
||||
it { expect(described_class.scheduled).to include(scheduled_check) }
|
||||
it { expect(described_class.scheduled).not_to include(unscheduled_check) }
|
||||
end
|
||||
|
||||
describe ".scheduled?" do
|
||||
|
|
Loading…
Reference in New Issue