forked from discourse/discourse
-
Notifications
You must be signed in to change notification settings - Fork 0
/
admin_user_index_query.rb
158 lines (132 loc) · 4.36 KB
/
admin_user_index_query.rb
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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
require_dependency 'trust_level'
class AdminUserIndexQuery
def initialize(params = {}, klass = User, trust_levels = TrustLevel.levels)
@params = params
@query = initialize_query_with_order(klass.joins(:primary_email))
@trust_levels = trust_levels
end
attr_reader :params, :trust_levels
SORTABLE_MAPPING = {
'created' => 'created_at',
'last_emailed' => "COALESCE(last_emailed_at, to_date('1970-01-01', 'YYYY-MM-DD'))",
'seen' => "COALESCE(last_seen_at, to_date('1970-01-01', 'YYYY-MM-DD'))",
'username' => 'username',
'email' => 'email',
'trust_level' => 'trust_level',
'days_visited' => 'user_stats.days_visited',
'posts_read' => 'user_stats.posts_read_count',
'topics_viewed' => 'user_stats.topics_entered',
'posts' => 'user_stats.post_count',
'read_time' => 'user_stats.time_read'
}
def find_users(limit = 100)
page = params[:page].to_i - 1
if page < 0
page = 0
end
find_users_query.limit(limit).offset(page * limit)
end
def count_users
find_users_query.count
end
def custom_direction
asc = params[:ascending]
asc.present? && asc ? "ASC" : "DESC"
end
def initialize_query_with_order(klass)
order = []
custom_order = params[:order]
if custom_order.present? &&
without_dir = SORTABLE_MAPPING[custom_order.downcase.sub(/ (asc|desc)$/, '')]
order << "#{without_dir} #{custom_direction}"
end
if !custom_order.present?
if params[:query] == "active"
order << "COALESCE(users.last_seen_at, to_date('1970-01-01', 'YYYY-MM-DD')) DESC"
else
order << "users.created_at DESC"
end
order << "users.username"
end
if params[:stats].present? && params[:stats] == false
klass.order(order.reject(&:blank?).join(","))
else
klass.includes(:user_stat).order(order.reject(&:blank?).join(","))
end
end
def filter_by_trust
levels = trust_levels.map { |key, _| key.to_s }
if levels.include?(params[:query])
@query.where('trust_level = ?', trust_levels[params[:query].to_sym])
end
end
def suspect_users
where_conds = []
# One signal: no reading yet the user has bio text
where_conds << "user_stats.posts_read_count <= 1 AND user_stats.topics_entered <= 1"
@query.activated
.human_users
.references(:user_stats)
.includes(:user_profile)
.where("COALESCE(user_profiles.bio_raw, '') != ''")
.where('users.created_at <= ?', 1.day.ago)
.where(where_conds.map { |c| "(#{c})" }.join(" OR "))
end
def filter_by_query_classification
case params[:query]
when 'staff' then @query.where("admin or moderator")
when 'admins' then @query.where(admin: true)
when 'moderators' then @query.where(moderator: true)
when 'silenced' then @query.silenced
when 'suspended' then @query.suspended
when 'pending' then @query.not_suspended.where(approved: false, active: true)
when 'suspect' then suspect_users
end
end
def filter_by_user_with_bypass(filter)
if filter =~ /.+@.+/
# probably an email so try the bypass
user_id = UserEmail.where(email: filter.downcase).pluck(:user_id).first
if user_id
return @query.where('users.id = ?', user_id)
end
end
@query.where('username_lower ILIKE :filter OR user_emails.email ILIKE :filter', filter: "%#{params[:filter]}%")
end
def filter_by_search
if params[:email].present?
return @query.where('user_emails.email = ?', params[:email].downcase)
end
filter = params[:filter]
if filter.present?
filter.strip!
if ip = IPAddr.new(filter) rescue nil
@query.where('ip_address <<= :ip OR registration_ip_address <<= :ip', ip: ip.to_cidr_s)
else
filter_by_user_with_bypass(filter)
end
end
end
def filter_by_ip
if params[:ip].present?
@query.where('ip_address = :ip OR registration_ip_address = :ip', ip: params[:ip].strip)
end
end
def filter_exclude
if params[:exclude].present?
@query.where('users.id != ?', params[:exclude])
end
end
# this might not be needed in rails 4 ?
def append(active_relation)
@query = active_relation if active_relation
end
def find_users_query
append filter_by_trust
append filter_by_query_classification
append filter_by_ip
append filter_exclude
append filter_by_search
@query
end
end