FEATURE: "Suspect" users list in admin.

This commit is contained in:
Robin Ward 2014-11-26 13:56:12 -05:00
parent 10b5032188
commit 257bde8e2b
6 changed files with 107 additions and 91 deletions

View file

@ -9,6 +9,7 @@
<li>{{#link-to 'adminUsersList.show' 'staff'}}{{i18n admin.users.nav.staff}}{{/link-to}}</li>
<li>{{#link-to 'adminUsersList.show' 'suspended'}}{{i18n admin.users.nav.suspended}}{{/link-to}}</li>
<li>{{#link-to 'adminUsersList.show' 'blocked'}}{{i18n admin.users.nav.blocked}}{{/link-to}}</li>
<li>{{#link-to 'adminUsersList.show' 'suspect'}}{{i18n admin.users.nav.suspect}}{{/link-to}}</li>
</ul>
</div>
<div class="pull-right">

View file

@ -32,7 +32,7 @@ class Admin::UsersController < Admin::AdminController
StaffActionLogger.new(current_user).log_show_emails(users)
end
render_serialized(users, AdminUserSerializer)
render_serialized(users, AdminUserListSerializer)
end
def show

View file

@ -0,0 +1,78 @@
class AdminUserListSerializer < BasicUserSerializer
attributes :email,
:active,
:admin,
:moderator,
:last_seen_age,
:last_emailed_age,
:created_at_age,
:username_lower,
:trust_level,
:trust_level_locked,
:flag_level,
:username,
:title,
:avatar_template,
:can_approve,
:approved,
:suspended_at,
:suspended_till,
:suspended,
:blocked,
:time_read
[:days_visited, :posts_read_count, :topics_entered, :post_count].each do |sym|
attributes sym
define_method sym do
object.user_stat.send(sym)
end
end
def include_email?
# staff members can always see their email
(scope.is_staff? && object.id == scope.user.id) || scope.can_see_emails?
end
alias_method :include_associated_accounts?, :include_email?
def suspended
object.suspended?
end
def can_impersonate
scope.can_impersonate?(object)
end
def last_emailed_age
return nil if object.last_emailed_at.blank?
AgeWords.age_words(Time.now - object.last_emailed_at)
end
def last_seen_age
return nil if object.last_seen_at.blank?
AgeWords.age_words(Time.now - object.last_seen_at)
end
def time_read
return nil if object.user_stat.time_read.blank?
AgeWords.age_words(object.user_stat.time_read)
end
def created_at_age
AgeWords.age_words(Time.now - object.created_at)
end
def can_approve
scope.can_approve?(object)
end
def include_can_approve?
SiteSetting.must_approve_users
end
def include_approved?
SiteSetting.must_approve_users
end
end

View file

@ -1,88 +1,16 @@
class AdminUserSerializer < BasicUserSerializer
require_dependency 'admin_user_list_serializer'
attributes :email,
:active,
:admin,
:moderator,
:last_seen_age,
:last_emailed_age,
:created_at_age,
:username_lower,
:trust_level,
:trust_level_locked,
:flag_level,
:username,
:title,
:avatar_template,
:can_approve,
:approved,
:suspended_at,
:suspended_till,
:suspended,
:ip_address,
:registration_ip_address,
class AdminUserSerializer < AdminUserListSerializer
attributes :associated_accounts,
:can_send_activation_email,
:can_activate,
:can_deactivate,
:blocked,
:time_read,
:associated_accounts
:ip_address,
:registration_ip_address,
:can_send_activation_email
has_one :single_sign_on_record, serializer: SingleSignOnRecordSerializer, embed: :objects
[:days_visited, :posts_read_count, :topics_entered, :post_count].each do |sym|
attributes sym
define_method sym do
object.user_stat.send(sym)
end
end
def include_email?
# staff members can always see their email
(scope.is_staff? && object.id == scope.user.id) || scope.can_see_emails?
end
alias_method :include_associated_accounts?, :include_email?
def suspended
object.suspended?
end
def can_impersonate
scope.can_impersonate?(object)
end
def last_emailed_age
return nil if object.last_emailed_at.blank?
AgeWords.age_words(Time.now - object.last_emailed_at)
end
def last_seen_age
return nil if object.last_seen_at.blank?
AgeWords.age_words(Time.now - object.last_seen_at)
end
def time_read
return nil if object.user_stat.time_read.blank?
AgeWords.age_words(object.user_stat.time_read)
end
def created_at_age
AgeWords.age_words(Time.now - object.created_at)
end
def can_approve
scope.can_approve?(object)
end
def include_can_approve?
SiteSetting.must_approve_users
end
def include_approved?
SiteSetting.must_approve_users
end
def can_send_activation_email
scope.can_send_activation_email?(object)
end

View file

@ -1895,6 +1895,7 @@ en:
staff: 'Staff'
suspended: 'Suspended'
blocked: 'Blocked'
suspect: 'Suspect'
approved: "Approved?"
approved_selected:
one: "approve user"
@ -1916,6 +1917,7 @@ en:
moderators: 'Moderators'
blocked: 'Blocked Users'
suspended: 'Suspended Users'
suspect: 'Suspect Users'
reject_successful:
one: "Successfully rejected 1 user."
other: "Successfully rejected %{count} users."

View file

@ -11,15 +11,7 @@ class AdminUserIndexQuery
attr_reader :params, :trust_levels
def find_users(limit=100)
find_users_query.includes(:user_stat)
.includes(:single_sign_on_record)
.includes(:facebook_user_info)
.includes(:twitter_user_info)
.includes(:github_user_info)
.includes(:google_user_info)
.includes(:oauth2_user_info)
.includes(:user_open_ids)
.limit(limit)
find_users_query.includes(:user_stat).limit(limit)
end
def count_users
@ -32,10 +24,10 @@ class AdminUserIndexQuery
if params[:query] == "active"
order << "COALESCE(last_seen_at, to_date('1970-01-01', 'YYYY-MM-DD')) DESC"
else
order << "created_at DESC"
order << "users.created_at DESC"
end
order << "username"
order << "users.username"
klass.order(order.reject(&:blank?).join(","))
end
@ -47,6 +39,20 @@ class AdminUserIndexQuery
end
end
def suspect_users
where_conds = []
# One signal: no reading yet the user has bio text
where_conds << "user_stats.posts_read_count = 0 AND user_stats.topics_entered = 0 AND COALESCE(user_profiles.bio_raw, '') = ''"
# Another surprising signal: Username ends with a number
where_conds << "users.username ~ '[0-9]+$'"
@query.activated
.references(:user_stats)
.includes(:user_profile)
.where(where_conds.map {|c| "(#{c})"}.join(" AND "))
end
def filter_by_query_classification
case params[:query]
when 'staff' then @query.where("admin or moderator")
@ -55,6 +61,7 @@ class AdminUserIndexQuery
when 'blocked' then @query.blocked
when 'suspended' then @query.suspended
when 'pending' then @query.not_suspended.where(approved: false)
when 'suspect' then suspect_users
end
end