* Add: #363 特定サーバーの投稿にスタンプを付けることを禁止する管理者設定 * Fix test
This commit is contained in:
parent
08f2fcb72b
commit
7b8fedb3cd
10 changed files with 157 additions and 26 deletions
34
app/controllers/admin/special_instances_controller.rb
Normal file
34
app/controllers/admin/special_instances_controller.rb
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Admin
|
||||||
|
class SpecialInstancesController < 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_instances_path
|
||||||
|
end
|
||||||
|
|
||||||
|
def settings_params
|
||||||
|
params.require(:form_admin_settings).permit(*Form::AdminSettings::KEYS)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -9,11 +9,17 @@ module Account::OtherSettings
|
||||||
end
|
end
|
||||||
|
|
||||||
def noai?
|
def noai?
|
||||||
user&.setting_noai || (settings.present? && settings['noai']) || false
|
return user.setting_noai if local? && user.present?
|
||||||
|
return settings['noai'] if settings.present? && settings.key?('noai')
|
||||||
|
|
||||||
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
def translatable_private?
|
def translatable_private?
|
||||||
user&.setting_translatable_private || (settings.present? && settings['translatable_private']) || false
|
return user.setting_translatable_private if local? && user.present?
|
||||||
|
return settings['translatable_private'] if settings.present? && settings.key?('translatable_private')
|
||||||
|
|
||||||
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
def link_preview?
|
def link_preview?
|
||||||
|
@ -31,30 +37,31 @@ module Account::OtherSettings
|
||||||
end
|
end
|
||||||
|
|
||||||
def hide_statuses_count?
|
def hide_statuses_count?
|
||||||
return user&.setting_hide_statuses_count unless user&.setting_hide_statuses_count.nil?
|
return user&.setting_hide_statuses_count if local? && user.present?
|
||||||
return settings['hide_statuses_count'] if settings.present?
|
return settings['hide_statuses_count'] if settings.present? && settings.key?('hide_statuses_count')
|
||||||
|
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
def hide_following_count?
|
def hide_following_count?
|
||||||
return user&.setting_hide_following_count unless user&.setting_hide_following_count.nil?
|
return user&.setting_hide_following_count if local? && user.present?
|
||||||
return settings['hide_following_count'] if settings.present?
|
return settings['hide_following_count'] if settings.present? && settings.key?('hide_following_count')
|
||||||
|
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
def hide_followers_count?
|
def hide_followers_count?
|
||||||
return user&.setting_hide_followers_count unless user&.setting_hide_followers_count.nil?
|
return user&.setting_hide_followers_count if local? && user.present?
|
||||||
return settings['hide_followers_count'] if settings.present?
|
return settings['hide_followers_count'] if settings.present? && settings.key?('hide_followers_count')
|
||||||
|
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
def emoji_reaction_policy
|
def emoji_reaction_policy
|
||||||
return settings['emoji_reaction_policy']&.to_sym || :allow if settings.present? && user.nil?
|
return :block if !local? && Setting.emoji_reaction_disallow_domains&.include?(domain)
|
||||||
|
return settings['emoji_reaction_policy']&.to_sym || :allow if settings.present? && !local?
|
||||||
return :allow if user.nil?
|
return :allow if user.nil?
|
||||||
return :block if local? && !Setting.enable_emoji_reaction
|
return :block if local? && !Setting.enable_emoji_reaction # for federation
|
||||||
|
|
||||||
user.setting_emoji_reaction_policy&.to_sym
|
user.setting_emoji_reaction_policy&.to_sym
|
||||||
end
|
end
|
||||||
|
@ -88,7 +95,7 @@ module Account::OtherSettings
|
||||||
|
|
||||||
def public_settings
|
def public_settings
|
||||||
# Please update `app/javascript/mastodon/api_types/accounts.ts` when making changes to the attributes
|
# Please update `app/javascript/mastodon/api_types/accounts.ts` when making changes to the attributes
|
||||||
config = {
|
{
|
||||||
'noindex' => noindex?,
|
'noindex' => noindex?,
|
||||||
'noai' => noai?,
|
'noai' => noai?,
|
||||||
'hide_network' => hide_collections,
|
'hide_network' => hide_collections,
|
||||||
|
@ -98,10 +105,8 @@ module Account::OtherSettings
|
||||||
'translatable_private' => translatable_private?,
|
'translatable_private' => translatable_private?,
|
||||||
'link_preview' => link_preview?,
|
'link_preview' => link_preview?,
|
||||||
'allow_quote' => allow_quote?,
|
'allow_quote' => allow_quote?,
|
||||||
'emoji_reaction_policy' => Setting.enable_emoji_reaction ? emoji_reaction_policy : :block,
|
'emoji_reaction_policy' => Setting.enable_emoji_reaction ? emoji_reaction_policy.to_s : 'block',
|
||||||
}
|
}
|
||||||
config = config.merge(settings) if settings.present?
|
|
||||||
config
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def public_settings_for_local
|
def public_settings_for_local
|
||||||
|
|
|
@ -52,6 +52,7 @@ class Form::AdminSettings
|
||||||
enable_public_unlisted_visibility
|
enable_public_unlisted_visibility
|
||||||
unlocked_friend
|
unlocked_friend
|
||||||
enable_local_timeline
|
enable_local_timeline
|
||||||
|
emoji_reaction_disallow_domains
|
||||||
).freeze
|
).freeze
|
||||||
|
|
||||||
INTEGER_KEYS = %i(
|
INTEGER_KEYS = %i(
|
||||||
|
@ -99,6 +100,7 @@ class Form::AdminSettings
|
||||||
ng_words_for_stranger_mention
|
ng_words_for_stranger_mention
|
||||||
sensitive_words
|
sensitive_words
|
||||||
sensitive_words_for_full
|
sensitive_words_for_full
|
||||||
|
emoji_reaction_disallow_domains
|
||||||
).freeze
|
).freeze
|
||||||
|
|
||||||
attr_accessor(*KEYS)
|
attr_accessor(*KEYS)
|
||||||
|
|
14
app/views/admin/special_instances/show.html.haml
Normal file
14
app/views/admin/special_instances/show.html.haml
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
- content_for :page_title do
|
||||||
|
= t('admin.special_instances.title')
|
||||||
|
|
||||||
|
- content_for :header_tags do
|
||||||
|
= javascript_pack_tag 'admin', async: true, crossorigin: 'anonymous'
|
||||||
|
|
||||||
|
= simple_form_for @admin_settings, url: admin_special_instances_path, html: { method: :post } do |f|
|
||||||
|
= render 'shared/error_messages', object: @admin_settings
|
||||||
|
|
||||||
|
.fields-group
|
||||||
|
= f.input :emoji_reaction_disallow_domains, wrapper: :with_label, as: :text, input_html: { rows: 6 }, label: t('admin.special_instances.emoji_reaction_disallow_domains'), hint: t('admin.special_instances.emoji_reaction_disallow_domains_hint')
|
||||||
|
|
||||||
|
.actions
|
||||||
|
= f.button :button, t('generic.save_changes'), type: :submit
|
|
@ -911,6 +911,10 @@ 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_instances:
|
||||||
|
emoji_reaction_disallow_domains: Domains we are not permitted stamp
|
||||||
|
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 a stamp on a post from a set domain.
|
||||||
|
title: Special servers
|
||||||
statuses:
|
statuses:
|
||||||
account: Author
|
account: Author
|
||||||
application: Application
|
application: Application
|
||||||
|
|
|
@ -909,6 +909,10 @@ ja:
|
||||||
minor: マイナーリリース
|
minor: マイナーリリース
|
||||||
patch: パッチ (バグ修正のみ)
|
patch: パッチ (バグ修正のみ)
|
||||||
version: バージョン
|
version: バージョン
|
||||||
|
special_instances:
|
||||||
|
emoji_reaction_disallow_domains: 自分がスタンプをつけることを許可しないドメイン
|
||||||
|
emoji_reaction_disallow_domains_hint: 連合先に配慮する必要がある場合、ドメインを改行区切りで設定します。設定されたドメインの投稿にスタンプを付けることはできません。
|
||||||
|
title: 特殊なサーバー
|
||||||
statuses:
|
statuses:
|
||||||
account: 作成者
|
account: 作成者
|
||||||
application: アプリ
|
application: アプリ
|
||||||
|
|
|
@ -54,6 +54,7 @@ SimpleNavigation::Configuration.run do |navigation|
|
||||||
s.item :invites, safe_join([fa_icon('user-plus fw'), t('admin.invites.title')]), admin_invites_path, if: -> { current_user.can?(:manage_invites) }
|
s.item :invites, safe_join([fa_icon('user-plus fw'), t('admin.invites.title')]), admin_invites_path, if: -> { current_user.can?(:manage_invites) }
|
||||||
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 :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) }
|
||||||
|
|
|
@ -34,6 +34,7 @@ namespace :admin do
|
||||||
resources :warning_presets, except: [:new, :show]
|
resources :warning_presets, except: [:new, :show]
|
||||||
resource :ng_words, only: [:show, :create]
|
resource :ng_words, only: [:show, :create]
|
||||||
resource :sensitive_words, only: [:show, :create]
|
resource :sensitive_words, only: [:show, :create]
|
||||||
|
resource :special_instances, only: [:show, :create]
|
||||||
|
|
||||||
resources :announcements, except: [:show] do
|
resources :announcements, except: [:show] do
|
||||||
member do
|
member do
|
||||||
|
|
|
@ -46,6 +46,7 @@ defaults: &defaults
|
||||||
unlocked_friend: false
|
unlocked_friend: false
|
||||||
stranger_mention_from_local_ng: true
|
stranger_mention_from_local_ng: true
|
||||||
enable_local_timeline: true
|
enable_local_timeline: true
|
||||||
|
emoji_reaction_disallow_domains: []
|
||||||
|
|
||||||
development:
|
development:
|
||||||
<<: *defaults
|
<<: *defaults
|
||||||
|
|
|
@ -270,38 +270,38 @@ RSpec.describe Account do
|
||||||
reactioned.follow!(mutual)
|
reactioned.follow!(mutual)
|
||||||
end
|
end
|
||||||
|
|
||||||
shared_examples 'with policy' do |override_policy, anyone_r, followee_r, follower_r, mutual_r, self_r| # rubocop:disable Metrics/ParameterLists
|
shared_examples 'with policy' do |override_policy, permitted|
|
||||||
context "when policy is #{override_policy}" do
|
context "when policy is #{override_policy}" do
|
||||||
let(:policy) { override_policy }
|
let(:policy) { override_policy }
|
||||||
|
|
||||||
it 'allows anyone' do
|
it 'allows anyone' do
|
||||||
expect(reactioned.allow_emoji_reaction?(anyone)).to be anyone_r
|
expect(reactioned.allow_emoji_reaction?(anyone)).to be permitted.include?(:anyone)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'allows followee' do
|
it 'allows followee' do
|
||||||
expect(reactioned.allow_emoji_reaction?(followee)).to be followee_r
|
expect(reactioned.allow_emoji_reaction?(followee)).to be permitted.include?(:following)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'allows follower' do
|
it 'allows follower' do
|
||||||
expect(reactioned.allow_emoji_reaction?(follower)).to be follower_r
|
expect(reactioned.allow_emoji_reaction?(follower)).to be permitted.include?(:followers)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'allows mutual' do
|
it 'allows mutual' do
|
||||||
expect(reactioned.allow_emoji_reaction?(mutual)).to be mutual_r
|
expect(reactioned.allow_emoji_reaction?(mutual)).to be permitted.include?(:mutuals)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'allows self' do
|
it 'allows self' do
|
||||||
expect(reactioned.allow_emoji_reaction?(reactioned)).to be self_r
|
expect(reactioned.allow_emoji_reaction?(reactioned)).to be permitted.include?(:self)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it_behaves_like 'with policy', :allow, true, true, true, true, true
|
it_behaves_like 'with policy', :allow, %i(anyone following followers mutuals self)
|
||||||
it_behaves_like 'with policy', :outside_only, false, true, true, true, true
|
it_behaves_like 'with policy', :outside_only, %i(following followers mutuals self)
|
||||||
it_behaves_like 'with policy', :following_only, false, true, false, true, true
|
it_behaves_like 'with policy', :following_only, %i(following mutuals self)
|
||||||
it_behaves_like 'with policy', :followers_only, false, false, true, true, true
|
it_behaves_like 'with policy', :followers_only, %i(followers mutuals self)
|
||||||
it_behaves_like 'with policy', :mutuals_only, false, false, false, true, true
|
it_behaves_like 'with policy', :mutuals_only, %i(mutuals self)
|
||||||
it_behaves_like 'with policy', :block, false, false, false, false, false
|
it_behaves_like 'with policy', :block, %i()
|
||||||
|
|
||||||
shared_examples 'allow local only' do |override_policy|
|
shared_examples 'allow local only' do |override_policy|
|
||||||
context "when policy is #{override_policy} but allow local only" do
|
context "when policy is #{override_policy} but allow local only" do
|
||||||
|
@ -371,6 +371,71 @@ RSpec.describe Account do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '#emoji_reaction_policy' do
|
||||||
|
subject { account.emoji_reaction_policy }
|
||||||
|
|
||||||
|
let(:domains) { 'example.com' }
|
||||||
|
let(:account) { Fabricate(:account, domain: 'example.com', uri: 'https://example.com/actor') }
|
||||||
|
|
||||||
|
before do
|
||||||
|
Form::AdminSettings.new(emoji_reaction_disallow_domains: domains).save
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'blocked if target domain' do
|
||||||
|
expect(subject).to eq :block
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when other domain' do
|
||||||
|
let(:account) { Fabricate(:account, domain: 'allow.example.com', uri: 'https://allow.example.com/actor') }
|
||||||
|
|
||||||
|
it 'allowed if target domain' do
|
||||||
|
expect(subject).to_not eq :block
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#public_settings_for_local' do
|
||||||
|
subject { account.public_settings_for_local }
|
||||||
|
|
||||||
|
let(:account) { Fabricate(:user, settings: { link_preview: false, allow_quote: true, hide_statuses_count: true, emoji_reaction_policy: :followers_only }).account }
|
||||||
|
|
||||||
|
shared_examples 'some settings' do |permitted, emoji_reaction_policy|
|
||||||
|
it 'link_preview is disallowed' do
|
||||||
|
expect(subject['link_preview']).to be permitted.include?(:link_preview)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'allow_quote is allowed' do
|
||||||
|
expect(subject['allow_quote']).to be permitted.include?(:allow_quote)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'hide_statuses_count is allowed' do
|
||||||
|
expect(subject['hide_statuses_count']).to be permitted.include?(:hide_statuses_count)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'hide_following_count is disallowed' do
|
||||||
|
expect(subject['hide_following_count']).to be permitted.include?(:hide_following_count)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'emoji_reaction is allowed followers' do
|
||||||
|
expect(subject['emoji_reaction_policy']).to eq emoji_reaction_policy
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it_behaves_like 'some settings', %i(allow_quote hide_statuses_count), 'followers_only'
|
||||||
|
|
||||||
|
context 'when remote user' do
|
||||||
|
let(:account) { Fabricate(:account, domain: 'example.com', uri: 'https://example.com/actor', settings: { 'link_preview' => false, 'allow_quote' => true, 'hide_statuses_count' => true, 'emoji_reaction_policy' => 'followers_only' }) }
|
||||||
|
|
||||||
|
it_behaves_like 'some settings', %i(allow_quote hide_statuses_count), 'followers_only'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when remote user by server other_settings is not supported' do
|
||||||
|
let(:account) { Fabricate(:account, domain: 'example.com', uri: 'https://example.com/actor') }
|
||||||
|
|
||||||
|
it_behaves_like 'some settings', %i(link_preview allow_quote), 'allow'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe '#favourited?' do
|
describe '#favourited?' do
|
||||||
subject { Fabricate(:account) }
|
subject { Fabricate(:account) }
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue