about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFire Demon <firedemon@creature.cafe>2020-09-21 02:22:56 -0500
committerFire Demon <firedemon@creature.cafe>2020-09-21 14:52:42 -0500
commit39b07aad85c0abd897f37860f5c9da854dcf523d (patch)
tree42e31cdcf95baa357ca1d5e91476421a9803f4ab
parent97d578eebdcbbc4705a303e8923e0332651890c1 (diff)
Drop Monsterfork v2 thread permissions; simplify feed filters
-rw-r--r--app/controllers/accounts_controller.rb1
-rw-r--r--app/controllers/activitypub/outboxes_controller.rb1
-rw-r--r--app/controllers/activitypub/replies_controller.rb1
-rw-r--r--app/controllers/api/v1/accounts/statuses_controller.rb1
-rw-r--r--app/controllers/api/v1/statuses/pins_controller.rb2
-rw-r--r--app/controllers/settings/preferences_controller.rb1
-rw-r--r--app/lib/activitypub/activity/create.rb11
-rw-r--r--app/lib/feed_manager.rb77
-rw-r--r--app/lib/status_filter.rb4
-rw-r--r--app/lib/user_settings_decorator.rb5
-rw-r--r--app/models/concerns/account_associations.rb3
-rw-r--r--app/models/conversation.rb2
-rw-r--r--app/models/status.rb33
-rw-r--r--app/models/user.rb2
-rw-r--r--app/policies/status_policy.rb31
-rw-r--r--app/services/mute_conversation_service.rb2
-rw-r--r--app/views/settings/preferences/filters/show.html.haml1
-rw-r--r--config/locales/simple_form.en-MP.yml2
-rw-r--r--db/migrate/20200721212401_backfill_account_id_on_conversations.rb15
-rw-r--r--db/migrate/20200726095058_backfill_semiprivate_on_statuses.rb14
-rw-r--r--db/migrate/20200923000001_remove_conversation_account.rb7
-rw-r--r--db/migrate/20200923000002_remove_semiprivate_flag.rb7
-rw-r--r--db/schema.rb6
23 files changed, 54 insertions, 175 deletions
diff --git a/app/controllers/accounts_controller.rb b/app/controllers/accounts_controller.rb
index d648e1a08..b7215cb36 100644
--- a/app/controllers/accounts_controller.rb
+++ b/app/controllers/accounts_controller.rb
@@ -83,7 +83,6 @@ class AccountsController < ApplicationController
     @account.statuses.permitted_for(
       @account,
       current_account,
-      include_semiprivate: true,
       include_reblogs: !(threads_requested? || replies_requested?),
       only_reblogs: reblogs_requested?,
       include_replies: replies_requested?,
diff --git a/app/controllers/activitypub/outboxes_controller.rb b/app/controllers/activitypub/outboxes_controller.rb
index 51945656f..4f2ed4db4 100644
--- a/app/controllers/activitypub/outboxes_controller.rb
+++ b/app/controllers/activitypub/outboxes_controller.rb
@@ -63,7 +63,6 @@ class ActivityPub::OutboxesController < ActivityPub::BaseController
       include_replies: true,
       include_reblogs: true,
       public: !(owner? || follower?),
-      include_semiprivate: owner? || mutual_follower?,
       exclude_local_only: true
     )
   end
diff --git a/app/controllers/activitypub/replies_controller.rb b/app/controllers/activitypub/replies_controller.rb
index 4d553fc07..fd12f0745 100644
--- a/app/controllers/activitypub/replies_controller.rb
+++ b/app/controllers/activitypub/replies_controller.rb
@@ -33,7 +33,6 @@ class ActivityPub::RepliesController < ActivityPub::BaseController
   def set_replies
     @replies = only_other_accounts? ? Status.where.not(account_id: @account.id) : @account.statuses
     @replies = @replies.where(in_reply_to_id: @status.id, visibility: [:public, :unlisted])
-    @replies = @replies.without_semiprivate unless authenticated_or_following?(@account)
     @replies = @replies.paginate_by_min_id(DESCENDANTS_LIMIT, params[:min_id])
   end
 
diff --git a/app/controllers/api/v1/accounts/statuses_controller.rb b/app/controllers/api/v1/accounts/statuses_controller.rb
index d7e973e31..099334cfe 100644
--- a/app/controllers/api/v1/accounts/statuses_controller.rb
+++ b/app/controllers/api/v1/accounts/statuses_controller.rb
@@ -44,7 +44,6 @@ class Api::V1::Accounts::StatusesController < Api::BaseController
     @account.statuses.permitted_for(
       @account,
       current_account,
-      include_semiprivate: true,
       include_reblogs: include_reblogs?,
       include_replies: include_replies?,
       only_reblogs: only_reblogs?,
diff --git a/app/controllers/api/v1/statuses/pins_controller.rb b/app/controllers/api/v1/statuses/pins_controller.rb
index 187b6145c..51b1621b6 100644
--- a/app/controllers/api/v1/statuses/pins_controller.rb
+++ b/app/controllers/api/v1/statuses/pins_controller.rb
@@ -9,7 +9,7 @@ class Api::V1::Statuses::PinsController < Api::BaseController
 
   def create
     StatusPin.create!(account: current_account, status: @status)
-    distribute_add_activity! unless @status.semiprivate?
+    distribute_add_activity!
     render json: @status, serializer: REST::StatusSerializer
   end
 
diff --git a/app/controllers/settings/preferences_controller.rb b/app/controllers/settings/preferences_controller.rb
index bbfd82869..f380c8310 100644
--- a/app/controllers/settings/preferences_controller.rb
+++ b/app/controllers/settings/preferences_controller.rb
@@ -74,7 +74,6 @@ class Settings::PreferencesController < Settings::BaseController
       :setting_boost_every,
       :setting_boost_jitter,
       :setting_boost_random,
-      :setting_filter_to_unknown,
       :setting_filter_from_unknown,
       :setting_unpublish_on_delete,
       :setting_rss_disabled,
diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb
index 9d03e5247..6dbd8769c 100644
--- a/app/lib/activitypub/activity/create.rb
+++ b/app/lib/activitypub/activity/create.rb
@@ -437,18 +437,13 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
       conversation = Conversation.find_by(uri: uri) if conversation.blank?
 
       if @object['inReplyTo'].blank? && replied_to_status.blank?
-        params = {
-          uri: uri,
-          root: object_uri,
-          account: @account,
-        }.freeze
         if conversation.blank?
-          conversation = Conversation.create!(params)
+          conversation = Conversation.create!(uri: uri, root: object_uri)
         elsif conversation.root.blank?
-          conversation.update!(params)
+          conversation.update!(uri: uri, root: object_uri)
         end
       elsif conversation.blank?
-        conversation = Conversation.create!(uri: uri, account_id: nil)
+        conversation = Conversation.create!(uri: uri)
       end
 
       conversation
diff --git a/app/lib/feed_manager.rb b/app/lib/feed_manager.rb
index 69009ffde..de61f12ca 100644
--- a/app/lib/feed_manager.rb
+++ b/app/lib/feed_manager.rb
@@ -1,8 +1,6 @@
 # frozen_string_literal: true
 
 require 'singleton'
-
-# rubocop:disable Metrics/ClassLength
 class FeedManager
   include Singleton
   include Redisable
@@ -359,60 +357,36 @@ class FeedManager
   # @param [Hash] filter_options
   # @return [Boolean]
   def filter_from_home?(status, receiver_id, crutches, filter_options)
-    conversation = status.conversation
-    reblog_conversation = status.reblog&.conversation
-
     return false if receiver_id == status.account_id
-    return true  unless status.published?
-    return true  if crutches[:hiding_thread][status.conversation_id] if conversation.present?
+    return true  if !status.published? || crutches[:hiding_thread][status.conversation_id]
     return true  if status.reply? && (status.in_reply_to_id.nil? || status.in_reply_to_account_id.nil?)
     return true  if phrase_filtered?(status, receiver_id, :home)
 
     check_for_blocks = crutches[:active_mentions][status.id] || []
-    check_for_blocks.concat([status.account_id, conversation&.account_id])
+    check_for_blocks.concat([status.account_id])
     check_for_blocks.concat([status.in_reply_to_account_id]) if status.reply?
 
     if status.reblog?
-      check_for_blocks.concat([status.reblog.account_id, reblog_conversation&.account_id])
+      check_for_blocks.concat([status.reblog.account_id])
       check_for_blocks.concat(crutches[:active_mentions][status.reblog_of_id] || [])
       check_for_blocks.concat([status.reblog.in_reply_to_account_id]) if status.reblog.reply?
     end
 
-    check_for_blocks.uniq!
-    check_for_blocks.compact!
     return true if check_for_blocks.any? { |target_account_id| crutches[:blocking][target_account_id] || crutches[:muting][target_account_id] }
 
     # Filter if...
     if status.reply? # ...it's a reply and...
-      # ...you're not following the author...
-      should_filter   = !crutches[:following][status.in_reply_to_account_id]
-      # (optional) ...or the owner(s) of the thread...
-      should_filter ||= !crutches[:following][conversation.account_id] if filter_options[:to_unknown] && conversation&.account_id.present?
-      # ...and the author isn't replying to a post you wrote...
+      # ...you're not following the participants...
+      should_filter   = (status.mention_ids - crutches[:following].keys).present?
+      # ...and the author isn't replying to you...
       should_filter &&= receiver_id != status.in_reply_to_account_id
-      # ...and the author isn't mentioning you.
-      should_filter &&= !crutches[:active_mentions][receiver_id]
 
       return !!should_filter
     elsif status.reblog? # ...it's a boost and...
-      should_filter = false
-
-      # ...it's a reply...
-      if status.reblog.reply? && !status.reblog.in_reply_to_account_id.nil?
-        # ...and you don't follow the author if:
-        # - you're filtering replies to parent authors you don't follow
-        # - they're silenced on this server
-        should_filter ||= !crutches[:following][status.reblog.in_reply_to_account_id] if filter_options[:to_unknown] || status.reblog.in_reply_to_account.silenced?
-        # - you're filtering replies to threads whose owners you don't follow
-        should_filter ||= !crutches[:following][reblog_conversation.account_id] if filter_options[:to_unknown] && reblog_conversation&.account_id.present?
-        # ...or you're blocking their domain...
-        should_filter ||= crutches[:domain_blocking][status.reblog.thread.account.domain] if status.reblog.thread.present?
-      end
-
-      # ...or it's a post from a thread's trunk and you don't follow the author if:
-      # - you're filtering boosts of authors you don't follow
+      # ...you don't follow the author if:
+      # - you're filtering boosts of folks you don't follow
       # - they're silenced on this server
-      should_filter ||= !crutches[:following][status.reblog.account_id] if filter_options[:from_unknown] || status.reblog.account.silenced?
+      should_filter = (filter_options[:from_unknown] || status.reblog.account.silenced?) && !crutches[:following][status.reblog.account_id]
 
       # ..or you're hiding boosts from them...
       should_filter ||= crutches[:hiding_reblogs][status.account_id]
@@ -421,10 +395,18 @@ class FeedManager
       # ...or you're blocking their domain...
       should_filter ||= crutches[:domain_blocking][status.reblog.account.domain]
 
+      # ...or it's a reply...
+      if !(should_filter || status.reblog.in_reply_to_account_id.nil?) && status.reblog.reply?
+        # ...and you don't follow the participants...
+        should_filter ||= (status.reblog.mention_ids - crutches[:following].keys).present?
+        # ...and the author isn't replying to you...
+        should_filter &&= receiver_id != status.in_reply_to_account_id
+      end
+
       return !!should_filter
     end
 
-    crutches[:following][status.account_id]
+    !crutches[:following][status.account_id]
   end
 
   # Check if status should not be added to the mentions feed
@@ -612,7 +594,6 @@ class FeedManager
       return {} if (settings = User.find_by(account_id: receiver_id)&.settings).blank?
 
       {
-        to_unknown: settings.filter_to_unknown,
         from_unknown: settings.filter_from_unknown,
       }
     end
@@ -626,24 +607,15 @@ class FeedManager
   def build_crutches(receiver_id, statuses)
     crutches = {}
 
-    crutches[:active_mentions] = Mention.active.where(status_id: statuses.flat_map { |s| [s.id, s.reblog_of_id] }.compact).pluck(:status_id, :account_id).each_with_object({}) { |(id, account_id), mapping| (mapping[id] ||= []).push(account_id) }
-
-    check_for_blocks = statuses.flat_map do |s|
-      arr = crutches[:active_mentions][s.id] || []
-      arr.concat([s.account_id])
+    mentions = Mention.active.where(status_id: statuses.flat_map { |s| [s.id, s.reblog_of_id] }.compact).pluck(:status_id, :account_id)
+    participants = statuses.flat_map { |s| [s.account_id, s.in_reply_to_account_id, s.reblog&.account_id, s.reblog&.in_reply_to_account_id].compact } | mentions.map { |m| m[1] }
 
-      if s.reblog?
-        arr.concat([s.reblog.account_id])
-        arr.concat(crutches[:active_mentions][s.reblog_of_id] || [])
-      end
-
-      arr
-    end
+    crutches[:active_mentions] = mentions.each_with_object({}) { |(id, account_id), mapping| (mapping[id] ||= []).push(account_id) }
 
-    crutches[:following]       = Follow.where(account_id: receiver_id, target_account_id: statuses.map(&:in_reply_to_account_id).compact).pluck(:target_account_id).each_with_object({}) { |id, mapping| mapping[id] = true }
+    crutches[:following]       = Follow.where(account_id: receiver_id, target_account_id: participants).pluck(:target_account_id).each_with_object({}) { |id, mapping| mapping[id] = true }
     crutches[:hiding_reblogs]  = Follow.where(account_id: receiver_id, target_account_id: statuses.map { |s| s.account_id if s.reblog? }.compact, show_reblogs: false).pluck(:target_account_id).each_with_object({}) { |id, mapping| mapping[id] = true }
-    crutches[:blocking]        = Block.where(account_id: receiver_id, target_account_id: check_for_blocks).pluck(:target_account_id).each_with_object({}) { |id, mapping| mapping[id] = true }
-    crutches[:muting]          = Mute.where(account_id: receiver_id, target_account_id: check_for_blocks).pluck(:target_account_id).each_with_object({}) { |id, mapping| mapping[id] = true }
+    crutches[:blocking]        = Block.where(account_id: receiver_id, target_account_id: participants).pluck(:target_account_id).each_with_object({}) { |id, mapping| mapping[id] = true }
+    crutches[:muting]          = Mute.where(account_id: receiver_id, target_account_id: participants).pluck(:target_account_id).each_with_object({}) { |id, mapping| mapping[id] = true }
     crutches[:domain_blocking] = AccountDomainBlock.where(account_id: receiver_id, domain: statuses.map { |s| s.reblog&.account&.domain }.compact).pluck(:domain).each_with_object({}) { |domain, mapping| mapping[domain] = true }
     crutches[:blocked_by]      = Block.where(target_account_id: receiver_id, account_id: statuses.map { |s| s.reblog&.account_id }.compact).pluck(:account_id).each_with_object({}) { |id, mapping| mapping[id] = true }
     crutches[:hiding_thread]   = ConversationMute.where(account_id: receiver_id, conversation_id: statuses.map(&:conversation_id).compact).pluck(:conversation_id).each_with_object({}) { |id, mapping| mapping[id] = true }
@@ -651,4 +623,3 @@ class FeedManager
     crutches
   end
 end
-# rubocop:enable Metrics/ClassLength
diff --git a/app/lib/status_filter.rb b/app/lib/status_filter.rb
index eb31dcad6..bd3e5245e 100644
--- a/app/lib/status_filter.rb
+++ b/app/lib/status_filter.rb
@@ -55,8 +55,6 @@ class StatusFilter
   end
 
   def policy_allows_show?
-    return false unless StatusPolicy.new(account, status, @preloaded_relations).show?
-
-    status.reblog? ? StatusPolicy.new(account, status.reblog, @preloaded_relations).show? : true
+    StatusPolicy.new(account, status, @preloaded_relations).show?
   end
 end
diff --git a/app/lib/user_settings_decorator.rb b/app/lib/user_settings_decorator.rb
index a58a17166..41b420ad0 100644
--- a/app/lib/user_settings_decorator.rb
+++ b/app/lib/user_settings_decorator.rb
@@ -60,7 +60,6 @@ class UserSettingsDecorator
     user.settings['boost_every']         = boost_every_preference if change?('setting_boost_every')
     user.settings['boost_jitter']        = boost_jitter_preference if change?('setting_boost_jitter')
     user.settings['boost_random']        = boost_random_preference if change?('setting_boost_random')
-    user.settings['filter_to_unknown']   = filter_to_unknown_preference if change?('setting_filter_to_unknown')
     user.settings['filter_from_unknown'] = filter_from_unknown_preference if change?('setting_filter_from_unknown')
     user.settings['unpublish_on_delete'] = unpublish_on_delete_preference if change?('setting_unpublish_on_delete')
     user.settings['rss_disabled']        = rss_disabled_preference if change?('setting_rss_disabled')
@@ -230,10 +229,6 @@ class UserSettingsDecorator
     boolean_cast_setting 'setting_boost_random'
   end
 
-  def filter_to_unknown_preference
-    boolean_cast_setting 'setting_filter_to_unknown'
-  end
-
   def filter_from_unknown_preference
     boolean_cast_setting 'setting_filter_from_unknown'
   end
diff --git a/app/models/concerns/account_associations.rb b/app/models/concerns/account_associations.rb
index 71947fc22..3b5e106fb 100644
--- a/app/models/concerns/account_associations.rb
+++ b/app/models/concerns/account_associations.rb
@@ -61,9 +61,6 @@ module AccountAssociations
     has_and_belongs_to_many :tags
     has_many :featured_tags, -> { includes(:tag) }, dependent: :destroy, inverse_of: :account
 
-    # Threads
-    has_many :threads, class_name: 'Conversation', inverse_of: :account, dependent: :nullify
-
     # Domain permissions
     has_many :domain_permissions, class_name: 'AccountDomainPermission', inverse_of: :account, dependent: :destroy
 
diff --git a/app/models/conversation.rb b/app/models/conversation.rb
index e065c34c8..0b9792091 100644
--- a/app/models/conversation.rb
+++ b/app/models/conversation.rb
@@ -7,7 +7,6 @@
 #  uri        :string
 #  created_at :datetime         not null
 #  updated_at :datetime         not null
-#  account_id :bigint(8)
 #  public     :boolean          default(FALSE), not null
 #  root       :string
 #
@@ -17,7 +16,6 @@ class Conversation < ApplicationRecord
 
   has_many :statuses
   has_many :mutes, class_name: 'ConversationMute', inverse_of: :conversation, dependent: :destroy
-  belongs_to :account, inverse_of: :threads, optional: true
 
   def local?
     uri.nil?
diff --git a/app/models/status.rb b/app/models/status.rb
index ba8b4ff2b..8c9a74902 100644
--- a/app/models/status.rb
+++ b/app/models/status.rb
@@ -29,7 +29,6 @@
 #  nest_level             :integer          default(0), not null
 #  published              :boolean          default(TRUE), not null
 #  title                  :text
-#  semiprivate            :boolean          default(FALSE), not null
 #  original_text          :text
 #  footer                 :text
 #  expires_at             :datetime
@@ -135,10 +134,8 @@ class Status < ApplicationRecord
   scope :including_unpublished, -> { unscope(where: :published) }
   scope :unpublished, -> { rewhere(published: false) }
   scope :published, -> { where(published: true) }
-  scope :without_semiprivate, -> { where(semiprivate: false) }
   scope :reblogs, -> { where('statuses.reblog_of_id IS NOT NULL') }
   scope :locally_reblogged, -> { where(id: Status.unscoped.local.reblogs.select(:reblog_of_id)) }
-  scope :conversations_by, ->(account) { joins(:conversation).where(conversations: { account: account }) }
   scope :mentioning_account, ->(account) { joins(:mentions).where(mentions: { account: account }) }
   scope :replies, -> { where(reply: true) }
   scope :expired, -> { published.where('statuses.expires_at IS NOT NULL AND statuses.expires_at < ?', Time.now.utc) }
@@ -377,13 +374,6 @@ class Status < ApplicationRecord
     @private_permissions = domain_permissions.where(visibility: [:private, :direct, :limited]).exists?
   end
 
-  def should_be_semiprivate?
-    return @should_be_semiprivate if defined?(@should_be_semiprivate)
-    return @should_be_semiprivate = true if distributable? && (private_domain_permissions? || account.private_domain_permissions?)
-
-    @should_be_semiprivate = !distributable? && (public_domain_permissions? || account.public_domain_permissions?)
-  end
-
   def should_limit_visibility?
     less_private_than?(thread&.visibility)
   end
@@ -408,7 +398,6 @@ class Status < ApplicationRecord
   after_create :set_poll_id
 
   after_save :set_domain_permissions, if: :local?
-  after_save :set_semiprivate, if: :local?
   after_save :set_conversation_root
 
   class << self
@@ -552,7 +541,6 @@ class Status < ApplicationRecord
       return query if options[:without_category_filters]
 
       query = query.published unless options[:include_unpublished]
-      query = query.without_semiprivate unless options[:include_semiprivate]
 
       if options[:only_reblogs]
         query = query.joins(:reblog)
@@ -576,12 +564,11 @@ class Status < ApplicationRecord
           query = query.without_reblogs
         end
 
-        query = if options[:include_replies]
-                  query = query.replies if options[:only_replies]
-                  query.conversations_by(target_account)
-                else
-                  query.without_replies
-                end
+        if options[:include_replies]
+          query = query.replies if options[:only_replies]
+        else
+          query = query.without_replies
+        end
       end
 
       return query if options[:tag].blank?
@@ -666,15 +653,11 @@ class Status < ApplicationRecord
     if reply? && !thread.nil?
       self.in_reply_to_account_id = carried_over_reply_to_account_id
       self.conversation_id        = thread.conversation_id if conversation_id.nil?
-    elsif conversation_id.nil?
-      self.conversation = reply? ? Conversation.new(account_id: nil) : Conversation.new(account_id: account_id)
-    elsif !reply? && account_id != conversation.account_id
-      conversation.update!(account_id: account_id)
     end
   end
 
   def set_conversation_root
-    conversation.update!(root: uri, account_id: account_id) if !reply && conversation.root.blank?
+    conversation.update!(root: uri) if !reply && conversation.present? && conversation.root.blank?
   end
 
   def carried_over_reply_to_account_id
@@ -711,10 +694,6 @@ class Status < ApplicationRecord
     end
   end
 
-  def set_semiprivate
-    update_column(:semiprivate, should_be_semiprivate?) if semiprivate != should_be_semiprivate?
-  end
-
   def update_statistics
     return unless distributable?
 
diff --git a/app/models/user.rb b/app/models/user.rb
index bb7fd4da5..5f2edab57 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -123,7 +123,7 @@ class User < ApplicationRecord
            :style_css_profile_errors, :style_css_webapp, :style_css_webapp_errors,
            :style_wide_media,
            :publish_in, :unpublish_in, :unpublish_delete, :boost_every, :boost_jitter,
-           :boost_random, :filter_to_unknown, :filter_from_unknown, :unpublish_on_delete,
+           :boost_random, :filter_from_unknown, :unpublish_on_delete,
            :rss_disabled,
            to: :settings, prefix: :setting, allow_nil: false
 
diff --git a/app/policies/status_policy.rb b/app/policies/status_policy.rb
index 9f851feb3..db600fe40 100644
--- a/app/policies/status_policy.rb
+++ b/app/policies/status_policy.rb
@@ -72,12 +72,6 @@ class StatusPolicy < ApplicationPolicy
     author.domain_blocking?(current_account.domain)
   end
 
-  def conversation_author_blocking_domain?
-    return false if current_account.nil? || current_account.domain.nil? || conversation_owner.nil?
-
-    conversation_owner.domain_blocking?(current_account.domain)
-  end
-
   def blocking_author?
     return false if current_account.nil?
 
@@ -90,17 +84,8 @@ class StatusPolicy < ApplicationPolicy
     @preloaded_relations[:blocked_by] ? @preloaded_relations[:blocked_by][author.id] : author.blocking?(current_account)
   end
 
-  def conversation_author_blocking?
-    return false if conversation_owner.nil?
-
-    @preloaded_relations[:blocked_by] ? @preloaded_relations[:blocked_by][conversation_owner.id] : conversation_owner.blocking?(current_account)
-  end
-
   def blocked_by_owners?
-    return author_blocking? || author_blocking_domain? if conversation_owner&.id == author.id
-    return true if conversation_author_blocking? || author_blocking?
-
-    conversation_author_blocking_domain? || author_blocking_domain?
+    author_blocking? || author_blocking_domain?
   end
 
   def following_author?
@@ -109,26 +94,14 @@ class StatusPolicy < ApplicationPolicy
     @preloaded_relations[:following] ? @preloaded_relations[:following][author.id] : current_account.following?(author)
   end
 
-  def following_conversation_owner?
-    return false if current_account.nil? || conversation_owner.nil?
-
-    @preloaded_relations[:following] ? @preloaded_relations[:following][conversation_owner.id] : current_account.following?(conversation_owner)
-  end
-
   def following_owners?
-    return following_author? if conversation_owner&.id == author.id
-
-    following_conversation_owner? && following_author?
+    following_author?
   end
 
   def author
     @author ||= record.account
   end
 
-  def conversation_owner
-    @conversation_owner ||= record.conversation&.account
-  end
-
   def local_only?
     record.local_only?
   end
diff --git a/app/services/mute_conversation_service.rb b/app/services/mute_conversation_service.rb
index 56defae52..a12bf9533 100644
--- a/app/services/mute_conversation_service.rb
+++ b/app/services/mute_conversation_service.rb
@@ -5,6 +5,6 @@ class MuteConversationService < BaseService
     return if account.blank? || conversation.blank?
 
     account.mute_conversation!(conversation)
-    MuteConversationWorker.perform_async(account.id, conversation.id) unless account.id == conversation.account_id
+    MuteConversationWorker.perform_async(account.id, conversation.id)
   end
 end
diff --git a/app/views/settings/preferences/filters/show.html.haml b/app/views/settings/preferences/filters/show.html.haml
index f91010724..20787d164 100644
--- a/app/views/settings/preferences/filters/show.html.haml
+++ b/app/views/settings/preferences/filters/show.html.haml
@@ -10,7 +10,6 @@
   %h4= t 'preferences.filtering'
 
   .fields-group
-    = f.input :setting_filter_to_unknown, as: :boolean, wrapper: :with_label
     = f.input :setting_filter_from_unknown, as: :boolean, wrapper: :with_label
 
   %h4= t 'preferences.public_timelines'
diff --git a/config/locales/simple_form.en-MP.yml b/config/locales/simple_form.en-MP.yml
index 6e992f942..200e8e26d 100644
--- a/config/locales/simple_form.en-MP.yml
+++ b/config/locales/simple_form.en-MP.yml
@@ -26,7 +26,6 @@ en-MP:
         setting_default_content_type_console_html: <code>Plain-text console formatting.</code>
         setting_default_content_type_bbcode_html: "<strong>[b]Bold[/b]</strong>, <u>[u]Underline[/u]</u>, <em>[i]Italic[/i]</em>, <code>[code]Console[/code]</code>, ..."
         setting_default_language: The language of your roars can be detected automatically, but it's not always accurate
-        setting_filter_to_unknown: Do not show replies to unfollowed accounts on your home timeline.  Takes effect for newly-pushed items.
         setting_filter_from_unknown: Do not show boosts from unfollowed accounts on your home timeline.  Takes effect for newly-pushed items.
         setting_manual_publish: This allows you to draft, proofread, and edit your roars before publishing them.  You can publish a roar from its <strong>action menu</strong> (the three dots).
         setting_rss_disabled: Improves privacy by turning off your account's public RSS feed.
@@ -55,7 +54,6 @@ en-MP:
         setting_display_media_show_all: Reveal all
         setting_expand_spoilers: Always expand roars marked with content warnings
         setting_favourite_modal: Show confirmation dialog before admiring (applies to Glitch flavour only)
-        setting_filter_to_unknown: Filter replies to unfollowed accounts
         setting_filter_from_unknown: Filter boosts from unfollowed accounts
         setting_manual_publish: Manually publish roars
         setting_publish_in: Auto-publish
diff --git a/db/migrate/20200721212401_backfill_account_id_on_conversations.rb b/db/migrate/20200721212401_backfill_account_id_on_conversations.rb
deleted file mode 100644
index 595fd8e52..000000000
--- a/db/migrate/20200721212401_backfill_account_id_on_conversations.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-class BackfillAccountIdOnConversations < ActiveRecord::Migration[5.2]
-  disable_ddl_transaction!
-
-  def up
-    Rails.logger.info('Backfilling owners of conversation threads...')
-    safety_assured do
-      Conversation.left_outer_joins(:statuses).where(statuses: { id: nil }).in_batches.destroy_all
-      execute('UPDATE conversations SET account_id = s.account_id FROM (SELECT account_id, conversation_id FROM statuses WHERE NOT reply) AS s WHERE conversations.id = s.conversation_id')
-    end
-  end
-
-  def down
-    true
-  end
-end
diff --git a/db/migrate/20200726095058_backfill_semiprivate_on_statuses.rb b/db/migrate/20200726095058_backfill_semiprivate_on_statuses.rb
deleted file mode 100644
index 0f247146e..000000000
--- a/db/migrate/20200726095058_backfill_semiprivate_on_statuses.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-class BackfillSemiprivateOnStatuses < ActiveRecord::Migration[5.2]
-  disable_ddl_transaction!
-
-  def up
-    Rails.logger.info('Backfilling semiprivate statuses...')
-    safety_assured do
-      Status.where(id: StatusDomainPermission.select(:status_id)).in_batches.update_all(semiprivate: true)
-    end
-  end
-
-  def down
-    true
-  end
-end
diff --git a/db/migrate/20200923000001_remove_conversation_account.rb b/db/migrate/20200923000001_remove_conversation_account.rb
new file mode 100644
index 000000000..1b61d41bf
--- /dev/null
+++ b/db/migrate/20200923000001_remove_conversation_account.rb
@@ -0,0 +1,7 @@
+class RemoveConversationAccount < ActiveRecord::Migration[5.2]
+  def change
+    safety_assured do
+      remove_column :conversations, :account_id
+    end
+  end
+end
diff --git a/db/migrate/20200923000002_remove_semiprivate_flag.rb b/db/migrate/20200923000002_remove_semiprivate_flag.rb
new file mode 100644
index 000000000..cd732c616
--- /dev/null
+++ b/db/migrate/20200923000002_remove_semiprivate_flag.rb
@@ -0,0 +1,7 @@
+class RemoveSemiprivateFlag < ActiveRecord::Migration[5.2]
+  def change
+    safety_assured do
+      remove_column :statuses, :semiprivate
+    end
+  end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 97e4b3142..4e3114068 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
 #
 # It's strongly recommended that you check this file into your version control system.
 
-ActiveRecord::Schema.define(version: 2020_09_23_000000) do
+ActiveRecord::Schema.define(version: 2020_09_23_000002) do
 
   # These are extensions that must be enabled in order to support this database
   enable_extension "plpgsql"
@@ -328,10 +328,8 @@ ActiveRecord::Schema.define(version: 2020_09_23_000000) do
     t.string "uri"
     t.datetime "created_at", null: false
     t.datetime "updated_at", null: false
-    t.bigint "account_id"
     t.boolean "public", default: false, null: false
     t.string "root"
-    t.index ["account_id"], name: "index_conversations_on_account_id"
     t.index ["uri"], name: "index_conversations_on_uri", unique: true
   end
 
@@ -877,7 +875,6 @@ ActiveRecord::Schema.define(version: 2020_09_23_000000) do
     t.integer "nest_level", limit: 2, default: 0, null: false
     t.boolean "published", default: true, null: false
     t.text "title"
-    t.boolean "semiprivate", default: false, null: false
     t.text "original_text"
     t.text "footer"
     t.datetime "expires_at"
@@ -1071,7 +1068,6 @@ ActiveRecord::Schema.define(version: 2020_09_23_000000) do
   add_foreign_key "collection_pages", "accounts", on_delete: :cascade
   add_foreign_key "conversation_mutes", "accounts", name: "fk_225b4212bb", on_delete: :cascade
   add_foreign_key "conversation_mutes", "conversations", on_delete: :cascade
-  add_foreign_key "conversations", "accounts"
   add_foreign_key "custom_emojis", "accounts", on_delete: :nullify
   add_foreign_key "custom_filters", "accounts", on_delete: :cascade
   add_foreign_key "devices", "accounts", on_delete: :cascade