parent
ff2860d0df
commit
d89e1114bb
11 changed files with 123 additions and 2 deletions
34
app/controllers/admin/special_domains_controller.rb
Normal file
34
app/controllers/admin/special_domains_controller.rb
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Admin
|
||||||
|
class SpecialDomainsController < BaseController
|
||||||
|
def show
|
||||||
|
authorize :instance, :show?
|
||||||
|
|
||||||
|
@admin_settings = Form::AdminSettings.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
authorize :instance, :destroy?
|
||||||
|
|
||||||
|
@admin_settings = Form::AdminSettings.new(settings_params)
|
||||||
|
|
||||||
|
if @admin_settings.save
|
||||||
|
flash[:notice] = I18n.t('generic.changes_saved_msg')
|
||||||
|
redirect_to after_update_redirect_path
|
||||||
|
else
|
||||||
|
render :show
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def after_update_redirect_path
|
||||||
|
admin_special_domains_path
|
||||||
|
end
|
||||||
|
|
||||||
|
def settings_params
|
||||||
|
params.require(:form_admin_settings).permit(*Form::AdminSettings::KEYS)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -63,6 +63,8 @@ class Form::AdminSettings
|
||||||
emoji_reaction_disallow_domains
|
emoji_reaction_disallow_domains
|
||||||
block_unfollow_account_mention
|
block_unfollow_account_mention
|
||||||
hold_remote_new_accounts
|
hold_remote_new_accounts
|
||||||
|
stop_fetch_activity_domains
|
||||||
|
stop_link_preview_domains
|
||||||
).freeze
|
).freeze
|
||||||
|
|
||||||
INTEGER_KEYS = %i(
|
INTEGER_KEYS = %i(
|
||||||
|
@ -120,6 +122,8 @@ class Form::AdminSettings
|
||||||
|
|
||||||
STRING_ARRAY_KEYS = %i(
|
STRING_ARRAY_KEYS = %i(
|
||||||
emoji_reaction_disallow_domains
|
emoji_reaction_disallow_domains
|
||||||
|
stop_fetch_activity_domains
|
||||||
|
stop_link_preview_domains
|
||||||
).freeze
|
).freeze
|
||||||
|
|
||||||
attr_accessor(*KEYS)
|
attr_accessor(*KEYS)
|
||||||
|
|
|
@ -106,7 +106,8 @@ class FetchLinkCardService < BaseService
|
||||||
|
|
||||||
def bad_url?(uri)
|
def bad_url?(uri)
|
||||||
# Avoid local instance URLs and invalid URLs
|
# Avoid local instance URLs and invalid URLs
|
||||||
uri.host.blank? || TagManager.instance.local_url?(uri.to_s) || !%w(http https).include?(uri.scheme)
|
uri.host.blank? || TagManager.instance.local_url?(uri.to_s) || !%w(http https).include?(uri.scheme) ||
|
||||||
|
referenced_urls.include?(uri.to_s) || Setting.stop_link_preview_domains&.include?(uri.host)
|
||||||
end
|
end
|
||||||
|
|
||||||
def mention_link?(anchor)
|
def mention_link?(anchor)
|
||||||
|
|
|
@ -153,10 +153,16 @@ class ProcessReferencesService < BaseService
|
||||||
|
|
||||||
def url_to_status(url)
|
def url_to_status(url)
|
||||||
status = ActivityPub::TagManager.instance.uri_to_resource(url, Status, url: true)
|
status = ActivityPub::TagManager.instance.uri_to_resource(url, Status, url: true)
|
||||||
status ||= ResolveURLService.new.call(url, on_behalf_of: @status.account) if @fetch_remote && @no_fetch_urls.exclude?(url)
|
status ||= ResolveURLService.new.call(url, on_behalf_of: @status.account) unless bad_url_to_fetch?(url)
|
||||||
referrable?(status) ? status : nil
|
referrable?(status) ? status : nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def bad_url_to_fetch?(url)
|
||||||
|
uri = Addressable::URI.parse(url).normalize
|
||||||
|
|
||||||
|
!@fetch_remote || @no_fetch_urls.include?(url) || uri.host.blank? || Setting.stop_fetch_activity_domains&.include?(uri.host)
|
||||||
|
end
|
||||||
|
|
||||||
def referrable?(target_status)
|
def referrable?(target_status)
|
||||||
return false if target_status.nil?
|
return false if target_status.nil?
|
||||||
return @referrable if defined?(@referrable)
|
return @referrable if defined?(@referrable)
|
||||||
|
|
17
app/views/admin/special_domains/show.html.haml
Normal file
17
app/views/admin/special_domains/show.html.haml
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
- content_for :page_title do
|
||||||
|
= t('admin.special_domains.title')
|
||||||
|
|
||||||
|
- content_for :header_tags do
|
||||||
|
= javascript_pack_tag 'admin', async: true, crossorigin: 'anonymous'
|
||||||
|
|
||||||
|
= simple_form_for @admin_settings, url: admin_special_domains_path, html: { method: :post } do |f|
|
||||||
|
= render 'shared/error_messages', object: @admin_settings
|
||||||
|
|
||||||
|
.fields-group
|
||||||
|
= f.input :stop_fetch_activity_domains, wrapper: :with_label, as: :text, input_html: { rows: 6 }, label: t('admin.special_domains.stop_fetch_activity_domains.title'), hint: t('admin.special_domains.stop_fetch_activity_domains.preamble')
|
||||||
|
|
||||||
|
.fields-group
|
||||||
|
= f.input :stop_link_preview_domains, wrapper: :with_label, as: :text, input_html: { rows: 6 }, label: t('admin.special_domains.stop_link_preview_domains.title'), hint: t('admin.special_domains.stop_link_preview_domains.preamble')
|
||||||
|
|
||||||
|
.actions
|
||||||
|
= f.button :button, t('generic.save_changes'), type: :submit
|
|
@ -1046,6 +1046,14 @@ en:
|
||||||
minor: Minor release
|
minor: Minor release
|
||||||
patch: Patch release — bugfixes and easy to apply changes
|
patch: Patch release — bugfixes and easy to apply changes
|
||||||
version: Version
|
version: Version
|
||||||
|
special_domains:
|
||||||
|
stop_fetch_activity_domains:
|
||||||
|
preamble: WebとActivityでドメインの異なるサーバーでは、WebにアクセスしてもActivityが取得できない場合があります。参照において、投稿本文内でそのようなURLが指定された場合のフェッチを抑止します。多くの場合、この設定を利用する機会はほとんどありません。
|
||||||
|
title: Domains do not fetch for references
|
||||||
|
stop_link_preview_domains:
|
||||||
|
preamble: 多くのアクセスがあったIPアドレスからの接続を一時的に制限するサイトがある場合、自分のサーバーが不利に扱われる場合があります。そのようなサイトにアクセスしてリンクプレビューを生成する処理を抑制します。多くの場合、この設定を利用する機会はほとんどありません。
|
||||||
|
title: Domains do not fetch for link previews
|
||||||
|
title: Special domains
|
||||||
special_instances:
|
special_instances:
|
||||||
emoji_reaction_disallow_domains: Domains we are not permitted emoji reaction
|
emoji_reaction_disallow_domains: Domains we are not permitted emoji reaction
|
||||||
emoji_reaction_disallow_domains_hint: If you need to be considerate to your coalition partners, set the domain with a new line separator. It is not possible to put an emoji reaction on a post from a set domain.
|
emoji_reaction_disallow_domains_hint: If you need to be considerate to your coalition partners, set the domain with a new line separator. It is not possible to put an emoji reaction on a post from a set domain.
|
||||||
|
|
|
@ -1042,6 +1042,14 @@ ja:
|
||||||
minor: マイナーリリース
|
minor: マイナーリリース
|
||||||
patch: パッチ (バグ修正のみ)
|
patch: パッチ (バグ修正のみ)
|
||||||
version: バージョン
|
version: バージョン
|
||||||
|
special_domains:
|
||||||
|
stop_fetch_activity_domains:
|
||||||
|
preamble: WebとActivityでドメインの異なるサーバーでは、WebにアクセスしてもActivityが取得できない場合があります。参照において、投稿本文内でそのようなURLが指定された場合のフェッチを抑止します。ドメインは改行区切りで複数指定できます。多くの場合、この設定を利用する機会はほとんどありません。
|
||||||
|
title: 参照でフェッチを行わないドメイン
|
||||||
|
stop_link_preview_domains:
|
||||||
|
preamble: 多くのアクセスがあったIPアドレスからの接続を一時的に制限するサイトがある場合、自分のサーバーが不利に扱われる場合があります。そのようなサイトにアクセスしてリンクプレビューを生成する処理を抑制します。ドメインは改行区切りで複数指定できます。多くの場合、この設定を利用する機会はほとんどありません。
|
||||||
|
title: リンクのプレビューを行わないドメイン
|
||||||
|
title: 特殊なドメイン
|
||||||
special_instances:
|
special_instances:
|
||||||
emoji_reaction_disallow_domains: 自分のサーバーが絵文字リアクションをすることを許可しないドメイン
|
emoji_reaction_disallow_domains: 自分のサーバーが絵文字リアクションをすることを許可しないドメイン
|
||||||
emoji_reaction_disallow_domains_hint: 連合先に配慮する必要がある場合、ドメインを改行区切りで設定します。設定されたドメインの投稿に絵文字リアクションを付けることはできません。
|
emoji_reaction_disallow_domains_hint: 連合先に配慮する必要がある場合、ドメインを改行区切りで設定します。設定されたドメインの投稿に絵文字リアクションを付けることはできません。
|
||||||
|
|
|
@ -60,6 +60,7 @@ SimpleNavigation::Configuration.run do |navigation|
|
||||||
s.item :follow_recommendations, safe_join([fa_icon('user-plus fw'), t('admin.follow_recommendations.title')]), admin_follow_recommendations_path, highlights_on: %r{/admin/follow_recommendations}, if: -> { current_user.can?(:manage_taxonomies) }
|
s.item :follow_recommendations, safe_join([fa_icon('user-plus fw'), t('admin.follow_recommendations.title')]), admin_follow_recommendations_path, highlights_on: %r{/admin/follow_recommendations}, if: -> { current_user.can?(:manage_taxonomies) }
|
||||||
s.item :instances, safe_join([fa_icon('cloud fw'), t('admin.instances.title')]), admin_instances_path(limited: limited_federation_mode? ? nil : '1'), highlights_on: %r{/admin/instances|/admin/domain_blocks|/admin/domain_allows}, if: -> { current_user.can?(:manage_federation) }
|
s.item :instances, safe_join([fa_icon('cloud fw'), t('admin.instances.title')]), admin_instances_path(limited: limited_federation_mode? ? nil : '1'), highlights_on: %r{/admin/instances|/admin/domain_blocks|/admin/domain_allows}, if: -> { current_user.can?(:manage_federation) }
|
||||||
s.item :special_instances, safe_join([fa_icon('list fw'), t('admin.special_instances.title')]), admin_special_instances_path, highlights_on: %r{/admin/special_instances}, if: -> { current_user.can?(:manage_federation) }
|
s.item :special_instances, safe_join([fa_icon('list fw'), t('admin.special_instances.title')]), admin_special_instances_path, highlights_on: %r{/admin/special_instances}, if: -> { current_user.can?(:manage_federation) }
|
||||||
|
s.item :special_domains, safe_join([fa_icon('list fw'), t('admin.special_domains.title')]), admin_special_domains_path, highlights_on: %r{/admin/special_domains}, if: -> { current_user.can?(:manage_federation) }
|
||||||
s.item :email_domain_blocks, safe_join([fa_icon('envelope fw'), t('admin.email_domain_blocks.title')]), admin_email_domain_blocks_path, highlights_on: %r{/admin/email_domain_blocks}, if: -> { current_user.can?(:manage_blocks) }
|
s.item :email_domain_blocks, safe_join([fa_icon('envelope fw'), t('admin.email_domain_blocks.title')]), admin_email_domain_blocks_path, highlights_on: %r{/admin/email_domain_blocks}, if: -> { current_user.can?(:manage_blocks) }
|
||||||
s.item :ip_blocks, safe_join([fa_icon('ban fw'), t('admin.ip_blocks.title')]), admin_ip_blocks_path, highlights_on: %r{/admin/ip_blocks}, if: -> { current_user.can?(:manage_blocks) }
|
s.item :ip_blocks, safe_join([fa_icon('ban fw'), t('admin.ip_blocks.title')]), admin_ip_blocks_path, highlights_on: %r{/admin/ip_blocks}, if: -> { current_user.can?(:manage_blocks) }
|
||||||
s.item :action_logs, safe_join([fa_icon('bars fw'), t('admin.action_logs.title')]), admin_action_logs_path, if: -> { current_user.can?(:view_audit_log) }
|
s.item :action_logs, safe_join([fa_icon('bars fw'), t('admin.action_logs.title')]), admin_action_logs_path, if: -> { current_user.can?(:view_audit_log) }
|
||||||
|
|
|
@ -46,6 +46,7 @@ namespace :admin do
|
||||||
resources :ng_rule_histories, only: [:show]
|
resources :ng_rule_histories, only: [:show]
|
||||||
resource :sensitive_words, only: [:show, :create]
|
resource :sensitive_words, only: [:show, :create]
|
||||||
resource :special_instances, only: [:show, :create]
|
resource :special_instances, only: [:show, :create]
|
||||||
|
resource :special_domains, only: [:show, :create]
|
||||||
|
|
||||||
resources :announcements, except: [:show] do
|
resources :announcements, except: [:show] do
|
||||||
member do
|
member do
|
||||||
|
|
|
@ -284,6 +284,20 @@ RSpec.describe FetchLinkCardService do
|
||||||
expect(status.preview_card.title).to eq 'Hello world'
|
expect(status.preview_card.title).to eq 'Hello world'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when URL domain is blocked by admin' do
|
||||||
|
let(:status) { Fabricate(:status, text: 'http://example.com/html') }
|
||||||
|
let(:custom_before) { true }
|
||||||
|
|
||||||
|
before do
|
||||||
|
Setting.stop_link_preview_domains = ['example.com']
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'creates preview card' do
|
||||||
|
subject.call(status)
|
||||||
|
expect(status.preview_card).to be_nil
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with a remote status' do
|
context 'with a remote status' do
|
||||||
|
|
|
@ -175,6 +175,33 @@ RSpec.describe ProcessReferencesService, type: :service do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'with fetch is blocked by admin' do
|
||||||
|
let(:text) { 'Hello RT https://web.example.com/note' }
|
||||||
|
|
||||||
|
before do
|
||||||
|
Setting.stop_fetch_activity_domains = ['web.example.com']
|
||||||
|
stub_request(:get, 'https://web.example.com/note').to_return(status: 404)
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the post is known' do
|
||||||
|
let(:target_status) { Fabricate(:status, uri: 'https://example.com/note', url: 'https://web.example.com/note') }
|
||||||
|
|
||||||
|
it 'post status', :sidekiq_inline do
|
||||||
|
expect(subject.size).to eq 1
|
||||||
|
expect(subject.pluck(0)).to include target_status.id
|
||||||
|
expect(subject.pluck(1)).to include 'RT'
|
||||||
|
expect(notify?).to be true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the post is unknown' do
|
||||||
|
it 'post status', :sidekiq_inline do
|
||||||
|
expect(subject.size).to eq 0
|
||||||
|
expect(a_request(:get, 'https://web.example.com/note')).to_not have_been_made
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context 'when unfetched remote post' do
|
context 'when unfetched remote post' do
|
||||||
let(:account) { Fabricate(:account, followers_url: 'http://example.com/followers', domain: 'example.com', uri: 'https://example.com/actor') }
|
let(:account) { Fabricate(:account, followers_url: 'http://example.com/followers', domain: 'example.com', uri: 'https://example.com/actor') }
|
||||||
let(:object_json) do
|
let(:object_json) do
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue