about summary refs log tree commit diff
path: root/app/models
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2017-05-19 21:05:32 +0200
committerGitHub <noreply@github.com>2017-05-19 21:05:32 +0200
commitf1ab70649b00e717a00ac295d42ff99160aa713b (patch)
tree283147302494a44af53409ca71736ffc1bd6eda1 /app/models
parent1548695c8300618d44efa8785f5c6eb7b3a86917 (diff)
Add buttons to block and unblock domain (#3127)
* Add buttons to block and unblock domain

* Relationship API now returns "domain_blocking" status for accounts,
rename "block entire domain" to "hide entire domain", fix unblocking domain,
do not block notifications from domain-blocked-but-followed people, do
not send Salmons to domain blocked users

* Add test

* Personal domain blocks shouldn't affect Salmon after all, since in this
direction of communication the control is very thin when it comes to
public stuff. Best stay consistent and not affect federation in this way

* Ignore followers and follow request from domain blocked folks,
ensure account domain blocks are not created for empty domain,
and avoid duplicates in validation

* Purge followers when blocking domain (without soft-blocks, since they
are useless here)

* Add tests, fix local timeline being empty when having any domain blocks
Diffstat (limited to 'app/models')
-rw-r--r--app/models/account_domain_block.rb1
-rw-r--r--app/models/concerns/account_interactions.rb6
-rw-r--r--app/models/status.rb14
3 files changed, 15 insertions, 6 deletions
diff --git a/app/models/account_domain_block.rb b/app/models/account_domain_block.rb
index 9241d9720..bdd64c01a 100644
--- a/app/models/account_domain_block.rb
+++ b/app/models/account_domain_block.rb
@@ -14,6 +14,7 @@ class AccountDomainBlock < ApplicationRecord
   include Paginable
 
   belongs_to :account, required: true
+  validates :domain, presence: true, uniqueness: { scope: :account_id }
 
   after_create  :remove_blocking_cache
   after_destroy :remove_blocking_cache
diff --git a/app/models/concerns/account_interactions.rb b/app/models/concerns/account_interactions.rb
index c8006bd0b..0ef7512e2 100644
--- a/app/models/concerns/account_interactions.rb
+++ b/app/models/concerns/account_interactions.rb
@@ -23,6 +23,12 @@ module AccountInteractions
     def requested_map(target_account_ids, account_id)
       follow_mapping(FollowRequest.where(target_account_id: target_account_ids, account_id: account_id), :target_account_id)
     end
+
+    def domain_blocking_map(target_account_ids, account_id)
+      accounts_map    = Account.where(id: target_account_ids).select('id, domain').map { |a| [a.id, a.domain] }.to_h
+      blocked_domains = AccountDomainBlock.where(account_id: account_id, domain: accounts_map.values).pluck(:domain)
+      accounts_map.map { |id, domain| [id, blocked_domains.include?(domain)] }.to_h
+    end
   end
 
   included do
diff --git a/app/models/status.rb b/app/models/status.rb
index 70021eb65..80f33a7c7 100644
--- a/app/models/status.rb
+++ b/app/models/status.rb
@@ -67,7 +67,8 @@ class Status < ApplicationRecord
   scope :local_only, -> { left_outer_joins(:account).where(accounts: { domain: nil }) }
   scope :excluding_silenced_accounts, -> { left_outer_joins(:account).where(accounts: { silenced: false }) }
   scope :including_silenced_accounts, -> { left_outer_joins(:account).where(accounts: { silenced: true }) }
-  scope :not_excluded_by_account, ->(account) { where.not(account_id: account.excluded_from_timeline_account_ids, accounts: { domain: account.excluded_from_timeline_domains }) }
+  scope :not_excluded_by_account, ->(account) { where.not(account_id: account.excluded_from_timeline_account_ids) }
+  scope :not_domain_blocked_by_account, ->(account) { left_outer_joins(:account).where.not(accounts: { domain: account.excluded_from_timeline_domains }) }
 
   cache_associated :account, :application, :media_attachments, :tags, :stream_entry, mentions: :account, reblog: [:account, :application, :stream_entry, :tags, :media_attachments, mentions: :account], thread: :account
 
@@ -152,13 +153,13 @@ class Status < ApplicationRecord
     def as_public_timeline(account = nil, local_only = false)
       query = timeline_scope(local_only).without_replies
 
-      apply_timeline_filters(query, account)
+      apply_timeline_filters(query, account, local_only)
     end
 
     def as_tag_timeline(tag, account = nil, local_only = false)
       query = timeline_scope(local_only).tagged_with(tag)
 
-      apply_timeline_filters(query, account)
+      apply_timeline_filters(query, account, local_only)
     end
 
     def as_outbox_timeline(account)
@@ -222,16 +223,17 @@ class Status < ApplicationRecord
         .without_reblogs
     end
 
-    def apply_timeline_filters(query, account)
+    def apply_timeline_filters(query, account, local_only)
       if account.nil?
         filter_timeline_default(query)
       else
-        filter_timeline_for_account(query, account)
+        filter_timeline_for_account(query, account, local_only)
       end
     end
 
-    def filter_timeline_for_account(query, account)
+    def filter_timeline_for_account(query, account, local_only)
       query = query.not_excluded_by_account(account)
+      query = query.not_domain_blocked_by_account(account) unless local_only
       query = query.in_allowed_languages(account) if account.allowed_languages.present?
       query.merge(account_silencing_filter(account))
     end