about summary refs log tree commit diff
path: root/app/policies/status_policy.rb
diff options
context:
space:
mode:
authorFire Demon <firedemon@creature.cafe>2020-07-21 23:40:01 -0500
committerFire Demon <firedemon@creature.cafe>2020-08-30 05:44:01 -0500
commitc752a46c457759149c14ae0e4d501d5ef2ce478a (patch)
tree5066a3b5cf73ba06d16a8b494bc3e91a094f807b /app/policies/status_policy.rb
parent03338243d28df8ecca77785c77214260ca0c32c9 (diff)
[Privacy] Implement thread ownership and visibility
Diffstat (limited to 'app/policies/status_policy.rb')
-rw-r--r--app/policies/status_policy.rb52
1 files changed, 46 insertions, 6 deletions
diff --git a/app/policies/status_policy.rb b/app/policies/status_policy.rb
index 22e985b03..bec58c39f 100644
--- a/app/policies/status_policy.rb
+++ b/app/policies/status_policy.rb
@@ -18,9 +18,9 @@ class StatusPolicy < ApplicationPolicy
     if requires_mention?
       owned? || mention_exists?
     elsif private?
-      owned? || (following_author? && following_parent_author?) || mention_exists?
+      owned? || following_owners? || mention_exists?
     else
-      current_account.nil? || !(author_blocking? || parent_author_blocking? || author_blocking_domain? || parent_author_blocking_domain?)
+      current_account.nil? || !blocked_by_owners?
     end
   end
 
@@ -53,7 +53,7 @@ class StatusPolicy < ApplicationPolicy
   end
 
   def private?
-    record.private_visibility?
+    record.private_visibility? || !public_conversation?
   end
 
   def mention_exists?
@@ -78,6 +78,12 @@ class StatusPolicy < ApplicationPolicy
     parent_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?
 
@@ -96,6 +102,19 @@ class StatusPolicy < ApplicationPolicy
     @preloaded_relations[:blocked_by] ? @preloaded_relations[:blocked_by][parent_author.id] : parent_author.blocking?(current_account)
   end
 
+  def conversation_author_blocking?
+    return public_conversation? 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 && parent_author&.id == author.id
+    return true if conversation_author_blocking? || parent_author_blocking? || author_blocking?
+
+    conversation_author_blocking_domain? || parent_author_blocking_domain? || author_blocking_domain?
+  end
+
   def following_author?
     return false if current_account.nil?
 
@@ -109,14 +128,31 @@ class StatusPolicy < ApplicationPolicy
     @preloaded_relations[:following] ? @preloaded_relations[:following][parent_author.id] : current_account.following?(parent_author)
   end
 
+  def following_conversation_owner?
+    return false if current_account.nil?
+    return public_conversation? if 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 && parent_author&.id == author.id
+
+    following_conversation_owner? && following_parent_author? && following_author?
+  end
+
   def author
-    record.account
+    @author ||= record.account
   end
 
   def parent_author
-    record.in_reply_to_account
+    @parent_author ||= record.in_reply_to_account
   end
-  
+
+  def conversation_owner
+    @conversation_owner ||= record.conversation&.account
+  end
+
   def local_only?
     record.local_only?
   end
@@ -124,4 +160,8 @@ class StatusPolicy < ApplicationPolicy
   def published?
     record.published?
   end
+
+  def public_conversation?
+    @public_conversation ||= (record.conversation&.public? || false)
+  end
 end