diff --git a/app/services/problem_check/maxmind_db_configuration.rb b/app/services/problem_check/maxmind_db_configuration.rb
new file mode 100644
index 00000000000..579b68c8c61
--- /dev/null
+++ b/app/services/problem_check/maxmind_db_configuration.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class ProblemCheck::MaxmindDbConfiguration < ProblemCheck
+ self.priority = "low"
+
+ def call
+ if GlobalSetting.maxmind_license_key.present? && GlobalSetting.maxmind_account_id.blank?
+ problem
+ else
+ no_problem
+ end
+ end
+
+ private
+
+ def translation_key
+ "dashboard.maxmind_db_configuration_warning"
+ end
+end
diff --git a/config/discourse_defaults.conf b/config/discourse_defaults.conf
index 82bac40765a..51e7d5aed07 100644
--- a/config/discourse_defaults.conf
+++ b/config/discourse_defaults.conf
@@ -294,7 +294,8 @@ refresh_maxmind_db_during_precompile_days = 2
maxmind_backup_path =
# register an account at: https://www.maxmind.com/en/geolite2/signup
-# then head to profile and get your license key
+# then head to profile and get your account ID and license key
+maxmind_account_id =
maxmind_license_key =
# Configures a URL mirror to download the MaxMind databases from.
diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml
index a996b457664..b421d058280 100644
--- a/config/locales/server.en.yml
+++ b/config/locales/server.en.yml
@@ -1622,6 +1622,7 @@ en:
sidekiq_warning: 'Sidekiq is not running. Many tasks, like sending emails, are executed asynchronously by Sidekiq. Please ensure at least one Sidekiq process is running. Learn about Sidekiq here.'
queue_size_warning: "The number of queued jobs is %{queue_size}, which is high. This could indicate a problem with the Sidekiq process(es), or you may need to add more Sidekiq workers."
memory_warning: "Your server is running with less than 1 GB of total memory. At least 1 GB of memory is recommended."
+ maxmind_db_configuration_warning: 'The server has been configured to use MaxMind databases for reverse IP lookups but a valid MaxMind account ID has not been configured which may result in MaxMind databases failing to download in the future. See this guide to learn more.'
google_oauth2_config_warning: 'The server is configured to allow signup and login with Google OAuth2 (enable_google_oauth2_logins), but the client id and client secret values are not set. Go to the Site Settings and update the settings. See this guide to learn more.'
facebook_config_warning: 'The server is configured to allow signup and login with Facebook (enable_facebook_logins), but the app id and app secret values are not set. Go to the Site Settings and update the settings. See this guide to learn more.'
twitter_config_warning: 'The server is configured to allow signup and login with Twitter (enable_twitter_logins), but the key and secret values are not set. Go to the Site Settings and update the settings. See this guide to learn more.'
diff --git a/lib/discourse_ip_info.rb b/lib/discourse_ip_info.rb
index e96aa2fdd71..23dc4569640 100644
--- a/lib/discourse_ip_info.rb
+++ b/lib/discourse_ip_info.rb
@@ -25,17 +25,34 @@ class DiscourseIpInfo
end
def self.mmdb_download(name)
+ extra_headers = {}
+
url =
if GlobalSetting.maxmind_mirror_url.present?
File.join(GlobalSetting.maxmind_mirror_url, "#{name}.tar.gz").to_s
else
- if GlobalSetting.maxmind_license_key.blank?
- STDERR.puts "MaxMind IP database updates require a license"
- STDERR.puts "Please set DISCOURSE_MAXMIND_LICENSE_KEY to one you generated at https://www.maxmind.com"
+ license_key = GlobalSetting.maxmind_license_key
+
+ if license_key.blank?
+ STDERR.puts "MaxMind IP database download requires an account ID and a license key"
+ STDERR.puts "Please set DISCOURSE_MAXMIND_ACCOUNT_ID and DISCOURSE_MAXMIND_LICENSE_KEY. See https://meta.discourse.org/t/configure-maxmind-for-reverse-ip-lookups/173941 for more details."
return
end
- "https://download.maxmind.com/app/geoip_download?license_key=#{GlobalSetting.maxmind_license_key}&edition_id=#{name}&suffix=tar.gz"
+ account_id = GlobalSetting.maxmind_account_id
+
+ if account_id.present?
+ extra_headers[
+ "Authorization"
+ ] = "Basic #{Base64.strict_encode64("#{account_id}:#{license_key}")}"
+
+ "https://download.maxmind.com/geoip/databases/#{name}/download?suffix=tar.gz"
+ else
+ # This URL is not documented by MaxMind, but it works but we don't know when it will stop working. Therefore,
+ # we are deprecating this in 3.3 and will remove it in 3.4. An admin dashboard warning has been added to inform
+ # site admins about this deprecation. See `ProblemCheck::MaxmindDbConfiguration` for more information.
+ "https://download.maxmind.com/app/geoip_download?license_key=#{license_key}&edition_id=#{name}&suffix=tar.gz"
+ end
end
gz_file =
@@ -45,6 +62,7 @@ class DiscourseIpInfo
tmp_file_name: "#{name}.gz",
validate_uri: false,
follow_redirect: true,
+ extra_headers:,
)
filename = File.basename(gz_file.path)
diff --git a/lib/discourse_ip_info_spec.rb b/lib/discourse_ip_info_spec.rb
index c0fc8ac4f35..9152de09e31 100644
--- a/lib/discourse_ip_info_spec.rb
+++ b/lib/discourse_ip_info_spec.rb
@@ -2,6 +2,29 @@
RSpec.describe DiscourseIpInfo do
describe ".mmdb_download" do
+ it "should download the MaxMind databases from MaxMind's download permalinks when `maxmind_license_key` and `maxmind_account_id` global setting has been set" do
+ global_setting :maxmind_license_key, "license_key"
+ global_setting :maxmind_account_id, "account_id"
+
+ stub_request(
+ :get,
+ "https://download.maxmind.com/geoip/databases/GeoLite2-City/download?suffix=tar.gz",
+ ).with(basic_auth: %w[account_id license_key]).to_return(status: 200, body: "", headers: {})
+
+ described_class.mmdb_download("GeoLite2-City")
+ end
+
+ it "should download the MaxMind databases from MaxMind's undocumented download URL when `maxmind_license_key` global setting has been set but not `maxmind_account_id` for backwards compatibility reasons" do
+ global_setting :maxmind_license_key, "license_key"
+
+ stub_request(
+ :get,
+ "https://download.maxmind.com/app/geoip_download?license_key=license_key&edition_id=GeoLite2-City&suffix=tar.gz",
+ ).to_return(status: 200, body: "", headers: {})
+
+ described_class.mmdb_download("GeoLite2-City")
+ end
+
it "should download the MaxMind databases from the right URL when `maxmind_mirror_url` global setting has been configured" do
global_setting :maxmind_mirror_url, "https://b.www.example.com/mirror"
diff --git a/lib/file_helper.rb b/lib/file_helper.rb
index cfb0e60bc66..7bbd09ed27a 100644
--- a/lib/file_helper.rb
+++ b/lib/file_helper.rb
@@ -50,7 +50,8 @@ class FileHelper
verbose: false,
validate_uri: true,
retain_on_max_file_size_exceeded: false,
- include_port_in_host_header: false
+ include_port_in_host_header: false,
+ extra_headers: {}
)
url = "https:" + url if url.start_with?("//")
raise Discourse::InvalidParameters.new(:url) unless url =~ %r{\Ahttps?://}
@@ -66,6 +67,7 @@ class FileHelper
validate_uri: validate_uri,
timeout: read_timeout,
include_port_in_host_header: include_port_in_host_header,
+ headers: extra_headers,
)
fd.get do |response, chunk, uri|
diff --git a/spec/services/problem_check/maxmind_db_configuration_spec.rb b/spec/services/problem_check/maxmind_db_configuration_spec.rb
new file mode 100644
index 00000000000..ca642e5b961
--- /dev/null
+++ b/spec/services/problem_check/maxmind_db_configuration_spec.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+RSpec.describe ProblemCheck::MaxmindDbConfiguration do
+ subject(:check) { described_class.new }
+
+ context "when `maxmind_license_key` and `maxmind_account_id` global settings are not set" do
+ it "should not raise any warning message" do
+ expect(check).to be_chill_about_it
+ end
+ end
+
+ context "when `maxmind_license_key` and `maxmind_account_id` global settings are set" do
+ it "should not raise any warning message" do
+ expect(check).to be_chill_about_it
+ end
+ end
+
+ context "when `maxmind_license_key` global setting is set but not `maxmind_account_id`" do
+ it "should raise the right warning" do
+ global_setting :maxmind_license_key, "license_key"
+
+ expect(check).to have_a_problem.with_priority("low").with_message(
+ I18n.t("dashboard.maxmind_db_configuration_warning"),
+ )
+ end
+ end
+end