* Wip: マイグレーション、設定など一式 * Fix test * Fix test * Fix: マスター用の設定を他サーバーに送信しないよう修正 * DTL、外部サーバーの情報受け入れのテストを追加 * スペルミスを修正 * Web画面に設定項目追加 * 既存の`master_settings`を上書きしないよう修正
This commit is contained in:
parent
a7dec3c59b
commit
76f2f2ed0c
26 changed files with 284 additions and 52 deletions
|
@ -4,8 +4,8 @@ class Settings::Preferences::OtherController < Settings::Preferences::BaseContro
|
|||
include DtlHelper
|
||||
|
||||
def show
|
||||
@dtl_enabled = DTL_ENABLED
|
||||
@dtl_tag = DTL_TAG
|
||||
@dtl_enabled = dtl_enabled?
|
||||
@dtl_tag = dtl_tag_name
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -18,7 +18,7 @@ class Settings::PrivacyExtraController < Settings::BaseController
|
|||
private
|
||||
|
||||
def account_params
|
||||
params.require(:account).permit(:dissubscribable, settings: UserSettings.keys)
|
||||
params.require(:account).permit(:subscription_policy, settings: UserSettings.keys)
|
||||
end
|
||||
|
||||
def set_account
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module DtlHelper
|
||||
DTL_ENABLED = ENV.fetch('DTL_ENABLED', 'false') == 'true'
|
||||
DTL_TAG = ENV.fetch('DTL_TAG', 'kmyblue')
|
||||
def dtl_enabled?
|
||||
ENV.fetch('DTL_ENABLED', 'false') == 'true'
|
||||
end
|
||||
|
||||
def dtl_tag_name
|
||||
ENV.fetch('DTL_TAG', 'kmyblue')
|
||||
end
|
||||
end
|
||||
|
|
|
@ -44,7 +44,7 @@ class AccountStatusesFilter
|
|||
private
|
||||
|
||||
def initial_scope
|
||||
if (suspended? || (domain_block&.reject_send_dissubscribable && @account.dissubscribable)) || domain_block&.reject_send_media || blocked?
|
||||
if (suspended? || (domain_block&.reject_send_dissubscribable && !@account.all_subscribable?)) || domain_block&.reject_send_media || blocked?
|
||||
Status.none
|
||||
elsif anonymous?
|
||||
account.statuses.where(visibility: %i(public unlisted public_unlisted))
|
||||
|
|
|
@ -236,7 +236,14 @@ class ActivityPub::TagManager
|
|||
end
|
||||
|
||||
def subscribable_by(account)
|
||||
account.dissubscribable ? [] : [COLLECTIONS[:public]]
|
||||
case account.subscription_policy
|
||||
when :allow
|
||||
[COLLECTIONS[:public]]
|
||||
when :followers_only
|
||||
[account_followers_url(account)]
|
||||
else
|
||||
[]
|
||||
end
|
||||
end
|
||||
|
||||
def searchable_by(status)
|
||||
|
|
|
@ -195,7 +195,7 @@ class StatusReachFinder
|
|||
blocks = DomainBlock.where(domain: nil)
|
||||
blocks = blocks.or(DomainBlock.where(reject_send_not_public_searchability: true)) if status.compute_searchability != 'public'
|
||||
blocks = blocks.or(DomainBlock.where(reject_send_public_unlisted: true)) if status.public_unlisted_visibility?
|
||||
blocks = blocks.or(DomainBlock.where(reject_send_dissubscribable: true)) if status.account.dissubscribable
|
||||
blocks = blocks.or(DomainBlock.where(reject_send_dissubscribable: true)) unless status.account.all_subscribable?
|
||||
blocks = blocks.or(DomainBlock.where(reject_send_media: true)) if status.with_media?
|
||||
blocks = blocks.or(DomainBlock.where(reject_send_sensitive: true)) if (status.with_media? && status.sensitive) || status.spoiler_text?
|
||||
blocks.pluck(:domain).uniq
|
||||
|
|
|
@ -52,9 +52,9 @@
|
|||
# requested_review_at :datetime
|
||||
# group_allow_private_message :boolean
|
||||
# searchability :integer default("direct"), not null
|
||||
# dissubscribable :boolean default(FALSE), not null
|
||||
# settings :jsonb
|
||||
# indexable :boolean default(FALSE), not null
|
||||
# master_settings :jsonb
|
||||
#
|
||||
|
||||
class Account < ApplicationRecord
|
||||
|
@ -88,6 +88,7 @@ class Account < ApplicationRecord
|
|||
include AccountSearch
|
||||
include AccountStatusesSearch
|
||||
include AccountOtherSettings
|
||||
include AccountMasterSettings
|
||||
|
||||
enum protocol: { ostatus: 0, activitypub: 1 }
|
||||
enum suspension_origin: { local: 0, remote: 1 }, _prefix: true
|
||||
|
|
28
app/models/concerns/account_master_settings.rb
Normal file
28
app/models/concerns/account_master_settings.rb
Normal file
|
@ -0,0 +1,28 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module AccountMasterSettings
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
def subscription_policy
|
||||
return master_settings['subscription_policy']&.to_sym || :allow if master_settings.present?
|
||||
|
||||
# allow, followers_only, block
|
||||
:allow
|
||||
end
|
||||
|
||||
def subscription_policy=(val)
|
||||
self.master_settings = (master_settings.nil? ? {} : master_settings).merge({ 'subscription_policy' => val })
|
||||
end
|
||||
|
||||
def all_subscribable?
|
||||
subscription_policy == :allow
|
||||
end
|
||||
|
||||
def public_master_settings
|
||||
{
|
||||
'subscription_policy' => subscription_policy,
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
|
@ -104,7 +104,7 @@ module AccountOtherSettings
|
|||
end
|
||||
|
||||
def public_settings_for_local
|
||||
public_settings
|
||||
public_settings.merge(public_master_settings)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -320,7 +320,7 @@ class Status < ApplicationRecord
|
|||
end
|
||||
|
||||
def dtl?
|
||||
tags.where(name: DTL_TAG).exists?
|
||||
(%w(public public_unlisted login).include?(visibility) || (unlisted_visibility? && public_searchability?)) && tags.where(name: dtl_tag_name).exists?
|
||||
end
|
||||
|
||||
def emojis
|
||||
|
|
|
@ -131,7 +131,7 @@ class StatusPolicy < ApplicationPolicy
|
|||
else
|
||||
(@domain_block.reject_send_not_public_searchability && status.compute_searchability != 'public') ||
|
||||
(@domain_block.reject_send_public_unlisted && status.public_unlisted_visibility?) ||
|
||||
(@domain_block.reject_send_dissubscribable && status.account.dissubscribable) ||
|
||||
(@domain_block.reject_send_dissubscribable && !status.account.all_subscribable?) ||
|
||||
(@domain_block.detect_invalid_subscription && status.public_unlisted_visibility? && status.account.user&.setting_reject_public_unlisted_subscription) ||
|
||||
(@domain_block.detect_invalid_subscription && status.public_visibility? && status.account.user&.setting_reject_unlisted_subscription) ||
|
||||
(@domain_block.reject_send_media && status.with_media?) ||
|
||||
|
|
|
@ -36,7 +36,7 @@ class InitialStateSerializer < ActiveModel::Serializer
|
|||
trends_as_landing_page: Setting.trends_as_landing_page,
|
||||
status_page_url: Setting.status_page_url,
|
||||
sso_redirect: sso_redirect,
|
||||
dtl_tag: DTL_ENABLED ? DTL_TAG : nil,
|
||||
dtl_tag: dtl_enabled? ? dtl_tag_name : nil,
|
||||
enable_local_privacy: Setting.enable_public_unlisted_visibility,
|
||||
enable_local_timeline: Setting.enable_local_timeline,
|
||||
}
|
||||
|
|
|
@ -112,7 +112,7 @@ class REST::AccountSerializer < ActiveModel::Serializer
|
|||
end
|
||||
|
||||
def subscribable
|
||||
!object.dissubscribable
|
||||
object.all_subscribable?
|
||||
end
|
||||
|
||||
def moved_to_account
|
||||
|
|
|
@ -83,7 +83,6 @@ class ActivityPub::ProcessAccountService < BaseService
|
|||
@account.suspension_origin = :local if auto_suspend?
|
||||
@account.silenced_at = domain_block.created_at if auto_silence?
|
||||
@account.searchability = :direct # not null
|
||||
@account.dissubscribable = false # not null
|
||||
|
||||
set_immediate_protocol_attributes!
|
||||
|
||||
|
@ -125,8 +124,8 @@ class ActivityPub::ProcessAccountService < BaseService
|
|||
@account.discoverable = @json['discoverable'] || false
|
||||
@account.indexable = @json['indexable'] || false
|
||||
@account.searchability = searchability_from_audience
|
||||
@account.dissubscribable = !subscribable(@account.note)
|
||||
@account.settings = other_settings
|
||||
@account.master_settings = (@account.master_settings || {}).merge(master_settings(@account.note))
|
||||
@account.memorial = @json['memorial'] || false
|
||||
end
|
||||
|
||||
|
@ -320,14 +319,24 @@ class ActivityPub::ProcessAccountService < BaseService
|
|||
@subscribable_by = as_array(@json['subscribableBy']).map { |x| value_or_id(x) }
|
||||
end
|
||||
|
||||
def subscribable(note)
|
||||
def subscription_policy(note)
|
||||
if subscribable_by.nil?
|
||||
note.exclude?('[subscribable:no]')
|
||||
note.include?('[subscribable:no]') ? :block : :allow
|
||||
elsif subscribable_by.any? { |uri| ActivityPub::TagManager.instance.public_collection?(uri) }
|
||||
:allow
|
||||
elsif subscribable_by.include?(@account.followers_url)
|
||||
:followers_only
|
||||
else
|
||||
subscribable_by.any? { |uri| ActivityPub::TagManager.instance.public_collection?(uri) }
|
||||
:block
|
||||
end
|
||||
end
|
||||
|
||||
def master_settings(note)
|
||||
{
|
||||
'subscription_policy' => subscription_policy(note),
|
||||
}
|
||||
end
|
||||
|
||||
def other_settings
|
||||
return {} unless @json['otherSetting'].is_a?(Array)
|
||||
|
||||
|
|
|
@ -23,8 +23,10 @@ class DeliveryAntennaService
|
|||
private
|
||||
|
||||
def delivery!
|
||||
must_dtl_tag = @account.dissubscribable
|
||||
return if must_dtl_tag && !DTL_ENABLED
|
||||
subscription_policy = @account.subscription_policy
|
||||
|
||||
dtl_post = @status.dtl? && dtl_enabled?
|
||||
return if subscription_policy == :block && (!dtl_post || !@account.user&.setting_dtl_force_subscribable)
|
||||
|
||||
tag_ids = @status.tags.pluck(:id)
|
||||
domain = @account.domain
|
||||
|
@ -38,8 +40,8 @@ class DeliveryAntennaService
|
|||
antennas = antennas.left_joins(:antenna_accounts).where(any_accounts: true).or(Antenna.left_joins(:antenna_accounts).where(antenna_accounts: { account: @account }))
|
||||
|
||||
antennas = Antenna.where(id: antennas.select(:id))
|
||||
if must_dtl_tag
|
||||
dtl_tag = Tag.find_or_create_by_names(DTL_TAG).first
|
||||
if subscription_policy == :block
|
||||
dtl_tag = Tag.find_or_create_by_names(dtl_tag_name).first
|
||||
return if !dtl_tag || tag_ids.exclude?(dtl_tag.id)
|
||||
|
||||
antennas = antennas.left_joins(:antenna_tags).where(antenna_tags: { tag_id: dtl_tag.id })
|
||||
|
@ -125,9 +127,9 @@ class DeliveryAntennaService
|
|||
def followers_only?
|
||||
case @status.visibility.to_sym
|
||||
when :public, :public_unlisted, :login, :limited
|
||||
false
|
||||
@status.account.subscription_policy == :followers_only
|
||||
when :unlisted
|
||||
@status.compute_searchability != 'public'
|
||||
@status.compute_searchability != 'public' || @status.account.subscription_policy == :followers_only
|
||||
else
|
||||
true
|
||||
end
|
||||
|
|
|
@ -53,12 +53,12 @@ class FanOutOnWriteService < BaseService
|
|||
when :public, :unlisted, :public_unlisted, :login, :private
|
||||
deliver_to_all_followers!
|
||||
deliver_to_lists!
|
||||
deliver_to_antennas! if !@account.dissubscribable || (@status.dtl? && DTL_ENABLED && @account.user&.setting_dtl_force_subscribable && @status.tags.exists?(name: DTL_TAG))
|
||||
deliver_to_antennas!
|
||||
deliver_to_stl_antennas! if Setting.enable_local_timeline
|
||||
deliver_to_ltl_antennas! if Setting.enable_local_timeline
|
||||
when :limited
|
||||
deliver_to_lists_mentioned_accounts_only!
|
||||
deliver_to_antennas! unless @account.dissubscribable
|
||||
deliver_to_antennas!
|
||||
deliver_to_stl_antennas! if Setting.enable_local_timeline
|
||||
deliver_to_mentioned_followers!
|
||||
else
|
||||
|
|
|
@ -105,10 +105,10 @@ class PostStatusService < BaseService
|
|||
end
|
||||
|
||||
def overwrite_dtl_post
|
||||
return unless DTL_ENABLED
|
||||
return unless dtl_enabled?
|
||||
|
||||
raw_tags = Extractor.extract_hashtags(@text)
|
||||
return if raw_tags.exclude?(DTL_TAG)
|
||||
return if raw_tags.exclude?(dtl_tag_name)
|
||||
return unless %i(public public_unlisted unlisted).include?(@visibility)
|
||||
|
||||
@visibility = @account.user&.setting_dtl_force_visibility if %i(public public_unlisted unlisted).include?(@account.user&.setting_dtl_force_visibility)
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
= ff.input :link_preview, wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.setting_link_preview'), hint: I18n.t('simple_form.hints.defaults.setting_link_preview')
|
||||
|
||||
.fields-group
|
||||
= f.input :dissubscribable, as: :boolean, wrapper: :with_label, kmyblue: true, hint: t('simple_form.hints.defaults.dissubscribable')
|
||||
= f.input :subscription_policy, kmyblue: true, collection: %w(allow followers_only block), label_method: ->(item) { safe_join([t("simple_form.labels.subscription_policy.#{item}")]) }, as: :radio_buttons, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li', wrapper: :with_floating_label, label: t('simple_form.labels.defaults.subscription_policy'), hint: t('simple_form.hints.defaults.subscription_policy')
|
||||
|
||||
.fields-group
|
||||
= ff.input :allow_quote, wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.setting_allow_quote'), hint: false
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue