From 24552b5160a5090e7d6056fb69a209aa48fe4fce Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 30 Jul 2019 11:10:46 +0200 Subject: Add whitelist mode (#11291) --- app/controllers/remote_interaction_controller.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'app/controllers/remote_interaction_controller.rb') diff --git a/app/controllers/remote_interaction_controller.rb b/app/controllers/remote_interaction_controller.rb index cc6993c52..fa742fb0a 100644 --- a/app/controllers/remote_interaction_controller.rb +++ b/app/controllers/remote_interaction_controller.rb @@ -5,6 +5,7 @@ class RemoteInteractionController < ApplicationController layout 'modal' + before_action :authenticate_user!, if: :whitelist_mode? before_action :set_interaction_type before_action :set_status before_action :set_body_classes -- cgit From f51c7c105f1d04520656c1235f8a5f58d256fd0e Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 7 Aug 2019 21:14:08 +0200 Subject: Fix acct URIs with IDN domains not being resolved (#11520) Fix #11494 --- app/controllers/remote_interaction_controller.rb | 1 - app/models/remote_follow.rb | 36 ++++++++++++++++++++---- app/services/resolve_account_service.rb | 14 ++++++--- 3 files changed, 40 insertions(+), 11 deletions(-) (limited to 'app/controllers/remote_interaction_controller.rb') diff --git a/app/controllers/remote_interaction_controller.rb b/app/controllers/remote_interaction_controller.rb index fa742fb0a..de5616e25 100644 --- a/app/controllers/remote_interaction_controller.rb +++ b/app/controllers/remote_interaction_controller.rb @@ -39,7 +39,6 @@ class RemoteInteractionController < ApplicationController @status = Status.find(params[:id]) authorize @status, :show? rescue Mastodon::NotPermittedError - # Reraise in order to get a 404 raise ActiveRecord::RecordNotFound end diff --git a/app/models/remote_follow.rb b/app/models/remote_follow.rb index 2537de36c..93df11724 100644 --- a/app/models/remote_follow.rb +++ b/app/models/remote_follow.rb @@ -2,19 +2,21 @@ class RemoteFollow include ActiveModel::Validations + include RoutingHelper attr_accessor :acct, :addressable_template validates :acct, presence: true - def initialize(attrs = nil) - @acct = attrs[:acct].gsub(/\A@/, '').strip if !attrs.nil? && !attrs[:acct].nil? + def initialize(attrs = {}) + @acct = normalize_acct(attrs[:acct]) end def valid? return false unless super - populate_template + fetch_template! + errors.empty? end @@ -28,8 +30,30 @@ class RemoteFollow private - def populate_template - if acct.blank? || redirect_url_link.nil? || redirect_url_link.template.nil? + def normalize_acct(value) + return if value.blank? + + username, domain = value.strip.gsub(/\A@/, '').split('@') + + domain = begin + if TagManager.instance.local_domain?(domain) + nil + else + TagManager.instance.normalize_domain(domain) + end + end + + [username, domain].compact.join('@') + end + + def fetch_template! + return missing_resource if acct.blank? + + _, domain = acct.split('@') + + if domain.nil? + @addressable_template = Addressable::Template.new("#{authorize_interaction_url}?uri={uri}") + elsif redirect_url_link.nil? || redirect_url_link.template.nil? missing_resource_error else @addressable_template = Addressable::Template.new(redirect_uri_template) @@ -45,7 +69,7 @@ class RemoteFollow end def acct_resource - @_acct_resource ||= Goldfinger.finger("acct:#{acct}") + @acct_resource ||= Goldfinger.finger("acct:#{acct}") rescue Goldfinger::Error, HTTP::ConnectionError nil end diff --git a/app/services/resolve_account_service.rb b/app/services/resolve_account_service.rb index 7864c4bcd..12e6544a0 100644 --- a/app/services/resolve_account_service.rb +++ b/app/services/resolve_account_service.rb @@ -60,17 +60,23 @@ class ResolveAccountService < BaseService @account = uri @username = @account.username @domain = @account.domain - @uri = [@username, @domain].compact.join('@') else - @uri = uri @username, @domain = uri.split('@') end - @domain = nil if TagManager.instance.local_domain?(@domain) + @domain = begin + if TagManager.instance.local_domain?(@domain) + nil + else + TagManager.instance.normalize_domain(@domain) + end + end + + @uri = [@username, @domain].compact.join('@') end def process_webfinger!(uri, redirected = false) - @webfinger = Goldfinger.finger("acct:#{@uri}") + @webfinger = Goldfinger.finger("acct:#{uri}") confirmed_username, confirmed_domain = @webfinger.subject.gsub(/\Aacct:/, '').split('@') if confirmed_username.casecmp(@username).zero? && confirmed_domain.casecmp(@domain).zero? -- cgit From b54b725d6bc8dd0a4ab0fe0bf408193c1bae8106 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 30 Aug 2019 02:19:17 +0200 Subject: Fix uncaught domain normalization error in remote follow (#11703) --- app/controllers/remote_follow_controller.rb | 2 +- app/controllers/remote_interaction_controller.rb | 2 +- app/models/remote_follow.rb | 6 ++++-- app/validators/domain_validator.rb | 12 ++++++++++-- spec/controllers/remote_follow_controller_spec.rb | 4 +--- spec/models/remote_follow_spec.rb | 2 +- 6 files changed, 18 insertions(+), 10 deletions(-) (limited to 'app/controllers/remote_interaction_controller.rb') diff --git a/app/controllers/remote_follow_controller.rb b/app/controllers/remote_follow_controller.rb index 0fb71d335..ba963a7a0 100644 --- a/app/controllers/remote_follow_controller.rb +++ b/app/controllers/remote_follow_controller.rb @@ -29,7 +29,7 @@ class RemoteFollowController < ApplicationController end def session_params - { acct: session[:remote_follow] } + { acct: session[:remote_follow] || current_account&.username } end def set_body_classes diff --git a/app/controllers/remote_interaction_controller.rb b/app/controllers/remote_interaction_controller.rb index de5616e25..15224e853 100644 --- a/app/controllers/remote_interaction_controller.rb +++ b/app/controllers/remote_interaction_controller.rb @@ -32,7 +32,7 @@ class RemoteInteractionController < ApplicationController end def session_params - { acct: session[:remote_follow] } + { acct: session[:remote_follow] || current_account&.username } end def set_status diff --git a/app/models/remote_follow.rb b/app/models/remote_follow.rb index 93df11724..52dd3f67b 100644 --- a/app/models/remote_follow.rb +++ b/app/models/remote_follow.rb @@ -6,7 +6,7 @@ class RemoteFollow attr_accessor :acct, :addressable_template - validates :acct, presence: true + validates :acct, presence: true, domain: { acct: true } def initialize(attrs = {}) @acct = normalize_acct(attrs[:acct]) @@ -21,7 +21,7 @@ class RemoteFollow end def subscribe_address_for(account) - addressable_template.expand(uri: account.local_username_and_domain).to_s + addressable_template.expand(uri: ActivityPub::TagManager.instance.uri_for(account)).to_s end def interact_address_for(status) @@ -44,6 +44,8 @@ class RemoteFollow end [username, domain].compact.join('@') + rescue Addressable::URI::InvalidURIError + value end def fetch_template! diff --git a/app/validators/domain_validator.rb b/app/validators/domain_validator.rb index ae07f1798..6e4a854ff 100644 --- a/app/validators/domain_validator.rb +++ b/app/validators/domain_validator.rb @@ -4,14 +4,22 @@ class DomainValidator < ActiveModel::EachValidator def validate_each(record, attribute, value) return if value.blank? - record.errors.add(attribute, I18n.t('domain_validator.invalid_domain')) unless compliant?(value) + domain = begin + if options[:acct] + value.split('@').last + else + value + end + end + + record.errors.add(attribute, I18n.t('domain_validator.invalid_domain')) unless compliant?(domain) end private def compliant?(value) Addressable::URI.new.tap { |uri| uri.host = value } - rescue Addressable::URI::InvalidURIError + rescue Addressable::URI::InvalidURIError, IDN::Idna::IdnaError false end end diff --git a/spec/controllers/remote_follow_controller_spec.rb b/spec/controllers/remote_follow_controller_spec.rb index 5088c2e65..d79dd2949 100644 --- a/spec/controllers/remote_follow_controller_spec.rb +++ b/spec/controllers/remote_follow_controller_spec.rb @@ -66,9 +66,7 @@ describe RemoteFollowController do end it 'redirects to the remote location' do - address = "http://example.com/follow_me?acct=test_user%40#{Rails.configuration.x.local_domain}" - - expect(response).to redirect_to(address) + expect(response).to redirect_to("http://example.com/follow_me?acct=https%3A%2F%2F#{Rails.configuration.x.local_domain}%2Fusers%2Ftest_user") end end end diff --git a/spec/models/remote_follow_spec.rb b/spec/models/remote_follow_spec.rb index ed2667b28..5b4c19b5b 100644 --- a/spec/models/remote_follow_spec.rb +++ b/spec/models/remote_follow_spec.rb @@ -61,7 +61,7 @@ RSpec.describe RemoteFollow do subject { remote_follow.subscribe_address_for(account) } it 'returns subscribe address' do - is_expected.to eq 'https://quitter.no/main/ostatussub?profile=alice%40cb6e6126.ngrok.io' + is_expected.to eq 'https://quitter.no/main/ostatussub?profile=https%3A%2F%2Fcb6e6126.ngrok.io%2Fusers%2Falice' end end end -- cgit From de5305a3a5b2c2c3e92f6e92ad8c72742c501e73 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 28 Sep 2019 01:33:27 +0200 Subject: Fix redirecting non-functional accounts on public pages (#11978) Fix #11969 --- app/controllers/accounts_controller.rb | 1 + app/controllers/custom_css_controller.rb | 1 + app/controllers/directories_controller.rb | 2 ++ app/controllers/follower_accounts_controller.rb | 1 + app/controllers/following_accounts_controller.rb | 1 + app/controllers/manifests_controller.rb | 1 + app/controllers/media_controller.rb | 1 + app/controllers/media_proxy_controller.rb | 1 + app/controllers/remote_follow_controller.rb | 2 ++ app/controllers/remote_interaction_controller.rb | 2 ++ app/controllers/statuses_controller.rb | 1 + app/controllers/tags_controller.rb | 2 ++ 12 files changed, 16 insertions(+) (limited to 'app/controllers/remote_interaction_controller.rb') diff --git a/app/controllers/accounts_controller.rb b/app/controllers/accounts_controller.rb index 0f6f5e3a6..1dab5d5f2 100644 --- a/app/controllers/accounts_controller.rb +++ b/app/controllers/accounts_controller.rb @@ -10,6 +10,7 @@ class AccountsController < ApplicationController before_action :set_body_classes skip_around_action :set_locale, if: -> { request.format == :json } + skip_before_action :require_functional! def show respond_to do |format| diff --git a/app/controllers/custom_css_controller.rb b/app/controllers/custom_css_controller.rb index e3f67bd14..0a667a6a6 100644 --- a/app/controllers/custom_css_controller.rb +++ b/app/controllers/custom_css_controller.rb @@ -2,6 +2,7 @@ class CustomCssController < ApplicationController skip_before_action :store_current_location + skip_before_action :require_functional! before_action :set_cache_headers diff --git a/app/controllers/directories_controller.rb b/app/controllers/directories_controller.rb index 7da975a23..750c835dd 100644 --- a/app/controllers/directories_controller.rb +++ b/app/controllers/directories_controller.rb @@ -9,6 +9,8 @@ class DirectoriesController < ApplicationController before_action :set_tag, only: :show before_action :set_accounts + skip_before_action :require_functional! + def index render :index end diff --git a/app/controllers/follower_accounts_controller.rb b/app/controllers/follower_accounts_controller.rb index 892c51cf4..705ff4122 100644 --- a/app/controllers/follower_accounts_controller.rb +++ b/app/controllers/follower_accounts_controller.rb @@ -8,6 +8,7 @@ class FollowerAccountsController < ApplicationController before_action :set_cache_headers skip_around_action :set_locale, if: -> { request.format == :json } + skip_before_action :require_functional! def index respond_to do |format| diff --git a/app/controllers/following_accounts_controller.rb b/app/controllers/following_accounts_controller.rb index 653d9a486..968de980d 100644 --- a/app/controllers/following_accounts_controller.rb +++ b/app/controllers/following_accounts_controller.rb @@ -8,6 +8,7 @@ class FollowingAccountsController < ApplicationController before_action :set_cache_headers skip_around_action :set_locale, if: -> { request.format == :json } + skip_before_action :require_functional! def index respond_to do |format| diff --git a/app/controllers/manifests_controller.rb b/app/controllers/manifests_controller.rb index 491cde745..960510f60 100644 --- a/app/controllers/manifests_controller.rb +++ b/app/controllers/manifests_controller.rb @@ -2,6 +2,7 @@ class ManifestsController < ApplicationController skip_before_action :store_current_location + skip_before_action :require_functional! def show expires_in 3.minutes, public: true diff --git a/app/controllers/media_controller.rb b/app/controllers/media_controller.rb index 1f693de32..05cf09c28 100644 --- a/app/controllers/media_controller.rb +++ b/app/controllers/media_controller.rb @@ -4,6 +4,7 @@ class MediaController < ApplicationController include Authorization skip_before_action :store_current_location + skip_before_action :require_functional! before_action :authenticate_user!, if: :whitelist_mode? before_action :set_media_attachment diff --git a/app/controllers/media_proxy_controller.rb b/app/controllers/media_proxy_controller.rb index 47544f21c..014b89de1 100644 --- a/app/controllers/media_proxy_controller.rb +++ b/app/controllers/media_proxy_controller.rb @@ -4,6 +4,7 @@ class MediaProxyController < ApplicationController include RoutingHelper skip_before_action :store_current_location + skip_before_action :require_functional! before_action :authenticate_user!, if: :whitelist_mode? diff --git a/app/controllers/remote_follow_controller.rb b/app/controllers/remote_follow_controller.rb index ba963a7a0..db1604644 100644 --- a/app/controllers/remote_follow_controller.rb +++ b/app/controllers/remote_follow_controller.rb @@ -7,6 +7,8 @@ class RemoteFollowController < ApplicationController before_action :set_body_classes + skip_before_action :require_functional! + def new @remote_follow = RemoteFollow.new(session_params) end diff --git a/app/controllers/remote_interaction_controller.rb b/app/controllers/remote_interaction_controller.rb index 15224e853..4073e7ac3 100644 --- a/app/controllers/remote_interaction_controller.rb +++ b/app/controllers/remote_interaction_controller.rb @@ -10,6 +10,8 @@ class RemoteInteractionController < ApplicationController before_action :set_status before_action :set_body_classes + skip_before_action :require_functional! + def new @remote_follow = RemoteFollow.new(session_params) end diff --git a/app/controllers/statuses_controller.rb b/app/controllers/statuses_controller.rb index 83131f484..57bbeca64 100644 --- a/app/controllers/statuses_controller.rb +++ b/app/controllers/statuses_controller.rb @@ -19,6 +19,7 @@ class StatusesController < ApplicationController before_action :set_autoplay, only: :embed skip_around_action :set_locale, if: -> { request.format == :json } + skip_before_action :require_functional!, only: [:show, :embed] content_security_policy only: :embed do |p| p.frame_ancestors(false) diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb index 4dfa05264..77d5661b8 100644 --- a/app/controllers/tags_controller.rb +++ b/app/controllers/tags_controller.rb @@ -13,6 +13,8 @@ class TagsController < ApplicationController before_action :set_body_classes before_action :set_instance_presenter + skip_before_action :require_functional! + def show respond_to do |format| format.html do -- cgit