about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--app/lib/feed_manager.rb1
-rw-r--r--app/models/status.rb10
-rw-r--r--app/services/process_feed_service.rb18
-rw-r--r--app/services/process_mentions_service.rb2
4 files changed, 16 insertions, 15 deletions
diff --git a/app/lib/feed_manager.rb b/app/lib/feed_manager.rb
index f0928a945..623a1af03 100644
--- a/app/lib/feed_manager.rb
+++ b/app/lib/feed_manager.rb
@@ -107,7 +107,6 @@ class FeedManager
     should_filter ||= receiver.blocking?(status.account)                                    # or it's from someone I blocked
     should_filter ||= receiver.blocking?(status.mentions.includes(:account).map(&:account)) # or if it mentions someone I blocked
     should_filter ||= (status.account.silenced? && !receiver.following?(status.account))    # of if the account is silenced and I'm not following them
-    should_filter ||= (status.private_visibility? && !receiver.following?(status.account))  # or if the mentioned account is not permitted to see the private status
 
     if status.reply? && !status.in_reply_to_account_id.nil?                                 # or it's a reply
       should_filter ||= receiver.blocking?(status.in_reply_to_account)                      # to a user I blocked
diff --git a/app/models/status.rb b/app/models/status.rb
index d2be72308..93594ec8f 100644
--- a/app/models/status.rb
+++ b/app/models/status.rb
@@ -76,7 +76,11 @@ class Status < ApplicationRecord
   end
 
   def permitted?(other_account = nil)
-    private_visibility? ? (account.id == other_account&.id || other_account&.following?(account)) : other_account.nil? || !account.blocking?(other_account)
+    if private_visibility?
+      (account.id == other_account&.id || other_account&.following?(account) || mentions.include?(other_account))
+    else
+      other_account.nil? || !account.blocking?(other_account)
+    end
   end
 
   def ancestors(account = nil)
@@ -153,6 +157,10 @@ class Status < ApplicationRecord
         where('1 = 1')
       elsif !account.nil? && target_account.blocking?(account)
         where('1 = 0')
+      elsif !account.nil?
+        joins('LEFT OUTER JOIN mentions ON statuses.id = mentions.status_id')
+          .where('mentions.account_id = ?', account.id)
+          .where('statuses.visibility != ? OR mentions.id IS NOT NULL', Status.visibilities[:private])
       else
         where.not(visibility: :private)
       end
diff --git a/app/services/process_feed_service.rb b/app/services/process_feed_service.rb
index c411e3e82..f0a62aa14 100644
--- a/app/services/process_feed_service.rb
+++ b/app/services/process_feed_service.rb
@@ -106,7 +106,8 @@ class ProcessFeedService < BaseService
         text: content(entry),
         spoiler_text: content_warning(entry),
         created_at: published(entry),
-        reply: thread?(entry)
+        reply: thread?(entry),
+        visibility: visibility_scope(entry)
       )
 
       if thread?(entry)
@@ -144,15 +145,9 @@ class ProcessFeedService < BaseService
 
     def mentions_from_xml(parent, xml)
       processed_account_ids = []
-      public_visibility     = false
 
       xml.xpath('./xmlns:link[@rel="mentioned"]', xmlns: TagManager::XMLNS).each do |link|
-        if link['ostatus:object-type'] == TagManager::TYPES[:collection] && link['href'] == TagManager::COLLECTIONS[:public]
-          public_visibility = true
-          next
-        elsif link['ostatus:object-type'] == TagManager::TYPES[:group]
-          next
-        end
+        next if [TagManager::TYPES[:group], TagManager::TYPES[:collection]].include? link['ostatus:object-type']
 
         url = Addressable::URI.parse(link['href'])
 
@@ -172,9 +167,6 @@ class ProcessFeedService < BaseService
         # So we can skip duplicate mentions
         processed_account_ids << mentioned_account.id
       end
-
-      parent.visibility = public_visibility ? :public : :unlisted
-      parent.save!
     end
 
     def hashtags_from_xml(parent, xml)
@@ -230,6 +222,10 @@ class ProcessFeedService < BaseService
       xml.at_xpath('./xmlns:summary', xmlns: TagManager::XMLNS)&.content || ''
     end
 
+    def visibility_scope(xml = @xml)
+      xml.at_xpath('./mastodon:scope', mastodon: TagManager::MTDN_XMLNS)&.content&.to_sym || :public
+    end
+
     def published(xml = @xml)
       xml.at_xpath('./xmlns:published', xmlns: TagManager::XMLNS).content
     end
diff --git a/app/services/process_mentions_service.rb b/app/services/process_mentions_service.rb
index 67fd3dcf7..d3d3af8af 100644
--- a/app/services/process_mentions_service.rb
+++ b/app/services/process_mentions_service.rb
@@ -30,8 +30,6 @@ class ProcessMentionsService < BaseService
     status.mentions.each do |mention|
       mentioned_account = mention.account
 
-      next if status.private_visibility? && (!mentioned_account.following?(status.account) || !mentioned_account.local?)
-
       if mentioned_account.local?
         NotifyService.new.call(mentioned_account, mention)
       else