mirror of
https://github.com/codeninjasllc/discourse.git
synced 2024-11-27 17:46:05 -05:00
FEATURE: "Suspect" users list in admin.
This commit is contained in:
parent
10b5032188
commit
257bde8e2b
6 changed files with 107 additions and 91 deletions
|
@ -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">
|
||||
|
|
|
@ -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
|
||||
|
|
78
app/serializers/admin_user_list_serializer.rb
Normal file
78
app/serializers/admin_user_list_serializer.rb
Normal 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
|
|
@ -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
|
||||
|
|
|
@ -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."
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in a new issue