about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.env.production.sample5
-rw-r--r--app/controllers/well_known/webfinger_controller.rb9
-rw-r--r--config/initializers/ostatus.rb4
-rw-r--r--spec/controllers/well_known/webfinger_controller_spec.rb24
4 files changed, 41 insertions, 1 deletions
diff --git a/.env.production.sample b/.env.production.sample
index e37a38c38..23cf18c8e 100644
--- a/.env.production.sample
+++ b/.env.production.sample
@@ -20,6 +20,11 @@ LOCAL_HTTPS=true
 # DO *NOT* USE THIS UNLESS YOU KNOW *EXACTLY* WHAT YOU ARE DOING.
 # WEB_DOMAIN=mastodon.example.com
 
+# Use this if you want to have several aliases handler@example1.com
+# handler@example2.com etc. for the same user. LOCAL_DOMAIN should not
+# be added. Comma separated values
+# ALTERNATE_DOMAINS=example1.com,example2.com
+
 # Application secrets
 # Generate each with the `rake secret` task (`docker-compose run --rm web rake secret` if you use docker compose)
 PAPERCLIP_SECRET=
diff --git a/app/controllers/well_known/webfinger_controller.rb b/app/controllers/well_known/webfinger_controller.rb
index 4a521d102..84f3015e8 100644
--- a/app/controllers/well_known/webfinger_controller.rb
+++ b/app/controllers/well_known/webfinger_controller.rb
@@ -23,7 +23,14 @@ module WellKnown
     private
 
     def username_from_resource
-      WebfingerResource.new(resource_param).username
+      resource_user = resource_param
+
+      username, domain = resource_user.split('@')
+      if Rails.configuration.x.alternate_domains.include?(domain)
+        resource_user = "#{username}@#{Rails.configuration.x.local_domain}"
+      end
+
+      WebfingerResource.new(resource_user).username
     end
 
     def pem_to_magic_key(public_key)
diff --git a/config/initializers/ostatus.rb b/config/initializers/ostatus.rb
index 0c6e88f31..342996dcd 100644
--- a/config/initializers/ostatus.rb
+++ b/config/initializers/ostatus.rb
@@ -5,12 +5,16 @@ host     = ENV.fetch('LOCAL_DOMAIN') { "localhost:#{port}" }
 web_host = ENV.fetch('WEB_DOMAIN') { host }
 https    = ENV['LOCAL_HTTPS'] == 'true'
 
+alternate_domains = ENV.fetch('ALTERNATE_DOMAINS') { "" }
+
 Rails.application.configure do
   config.x.local_domain = host
   config.x.web_domain   = web_host
   config.x.use_https    = https
   config.x.use_s3       = ENV['S3_ENABLED'] == 'true'
 
+  config.x.alternate_domains = alternate_domains.split(/\s*,\s*/)
+
   config.action_mailer.default_url_options = { host: web_host, protocol: https ? 'https://' : 'http://', trailing_slash: false }
   config.x.streaming_api_base_url          = 'ws://localhost:4000'
 
diff --git a/spec/controllers/well_known/webfinger_controller_spec.rb b/spec/controllers/well_known/webfinger_controller_spec.rb
index 6e493b037..4d588bf4e 100644
--- a/spec/controllers/well_known/webfinger_controller_spec.rb
+++ b/spec/controllers/well_known/webfinger_controller_spec.rb
@@ -6,6 +6,12 @@ describe WellKnown::WebfingerController, type: :controller do
   describe 'GET #show' do
     let(:alice) { Fabricate(:account, username: 'alice') }
 
+    around(:each) do |example|
+      before = Rails.configuration.x.alternate_domains
+      example.run
+      Rails.configuration.x.alternate_domains = before
+    end
+
     it 'returns http success when account can be found' do
       get :show, params: { resource: alice.to_webfinger_s }, format: :json
 
@@ -17,5 +23,23 @@ describe WellKnown::WebfingerController, type: :controller do
 
       expect(response).to have_http_status(:not_found)
     end
+
+    it 'returns http success when account can be found with alternate domains' do
+      Rails.configuration.x.alternate_domains = ["foo.org"]
+      username, domain = alice.to_webfinger_s.split("@")
+
+      get :show, params: { resource: "#{username}@foo.org" }, format: :json
+
+      expect(response).to have_http_status(:success)
+    end
+
+    it 'returns http not found when account can not be found with alternate domains' do
+      Rails.configuration.x.alternate_domains = ["foo.org"]
+      username, domain = alice.to_webfinger_s.split("@")
+
+      get :show, params: { resource: "#{username}@bar.org" }, format: :json
+
+      expect(response).to have_http_status(:not_found)
+    end
   end
 end