1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
|
# frozen_string_literal: true
class AccountFilter
KEYS = %i(
origin
status
role_ids
username
by_domain
display_name
email
ip
invited_by
order
).freeze
attr_reader :params
def initialize(params)
@params = params.to_h.symbolize_keys
end
def results
scope = Account.includes(:account_stat, user: [:ips, :invite_request]).without_instance_actor.reorder(nil)
relevant_params.each do |key, value|
next if key.to_s == 'page'
scope.merge!(scope_for(key, value)) if value.present?
end
scope
end
private
def relevant_params
params.tap do |args|
args.delete(:origin) if origin_is_remote_and_domain_present?
end
end
def origin_is_remote_and_domain_present?
params[:origin] == 'remote' && params[:by_domain].present?
end
def scope_for(key, value)
case key.to_s
when 'origin'
origin_scope(value)
when 'role_ids'
role_scope(value)
when 'status'
status_scope(value)
when 'by_domain'
Account.where(domain: value.to_s.strip)
when 'username'
Account.matches_username(value.to_s.strip)
when 'display_name'
Account.matches_display_name(value.to_s.strip)
when 'email'
accounts_with_users.merge(User.matches_email(value.to_s.strip))
when 'ip'
valid_ip?(value) ? accounts_with_users.merge(User.matches_ip(value).group('users.id, accounts.id')) : Account.none
when 'invited_by'
invited_by_scope(value)
when 'order'
order_scope(value)
else
raise Mastodon::InvalidParameterError, "Unknown filter: #{key}"
end
end
def origin_scope(value)
case value.to_s
when 'local'
Account.local
when 'remote'
Account.remote
else
raise Mastodon::InvalidParameterError, "Unknown origin: #{value}"
end
end
def status_scope(value)
case value.to_s
when 'active'
Account.without_suspended
when 'pending'
accounts_with_users.merge(User.pending)
when 'suspended'
Account.suspended
when 'disabled'
accounts_with_users.merge(User.disabled).without_suspended
when 'silenced'
Account.silenced
when 'sensitized'
Account.sensitized
else
raise Mastodon::InvalidParameterError, "Unknown status: #{value}"
end
end
def order_scope(value)
case value.to_s
when 'active'
accounts_with_users
.left_joins(:account_stat)
.order(
Arel.sql(
<<~SQL.squish
COALESCE(users.current_sign_in_at, account_stats.last_status_at, to_timestamp(0)) DESC, accounts.id DESC
SQL
)
)
when 'recent'
Account.recent
else
raise Mastodon::InvalidParameterError, "Unknown order: #{value}"
end
end
def invited_by_scope(value)
Account.left_joins(user: :invite).merge(Invite.where(user_id: value.to_s))
end
def role_scope(value)
accounts_with_users.merge(User.where(role_id: Array(value).map(&:to_s)))
end
def accounts_with_users
Account.left_joins(:user)
end
def valid_ip?(value)
IPAddr.new(value.to_s) && true
rescue IPAddr::InvalidAddressError
false
end
end
|