mirror of
https://github.com/codeninjasllc/discourse.git
synced 2024-11-23 23:58:31 -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' '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' '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' 'blocked'}}{{i18n admin.users.nav.blocked}}{{/link-to}}</li>
|
||||||
|
<li>{{#link-to 'adminUsersList.show' 'suspect'}}{{i18n admin.users.nav.suspect}}{{/link-to}}</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="pull-right">
|
<div class="pull-right">
|
||||||
|
|
|
@ -32,7 +32,7 @@ class Admin::UsersController < Admin::AdminController
|
||||||
StaffActionLogger.new(current_user).log_show_emails(users)
|
StaffActionLogger.new(current_user).log_show_emails(users)
|
||||||
end
|
end
|
||||||
|
|
||||||
render_serialized(users, AdminUserSerializer)
|
render_serialized(users, AdminUserListSerializer)
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
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,
|
class AdminUserSerializer < AdminUserListSerializer
|
||||||
:active,
|
|
||||||
:admin,
|
attributes :associated_accounts,
|
||||||
: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,
|
|
||||||
:can_send_activation_email,
|
:can_send_activation_email,
|
||||||
:can_activate,
|
:can_activate,
|
||||||
:can_deactivate,
|
:ip_address,
|
||||||
:blocked,
|
:registration_ip_address,
|
||||||
:time_read,
|
:can_send_activation_email
|
||||||
:associated_accounts
|
|
||||||
|
|
||||||
has_one :single_sign_on_record, serializer: SingleSignOnRecordSerializer, embed: :objects
|
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
|
def can_send_activation_email
|
||||||
scope.can_send_activation_email?(object)
|
scope.can_send_activation_email?(object)
|
||||||
end
|
end
|
||||||
|
|
|
@ -1895,6 +1895,7 @@ en:
|
||||||
staff: 'Staff'
|
staff: 'Staff'
|
||||||
suspended: 'Suspended'
|
suspended: 'Suspended'
|
||||||
blocked: 'Blocked'
|
blocked: 'Blocked'
|
||||||
|
suspect: 'Suspect'
|
||||||
approved: "Approved?"
|
approved: "Approved?"
|
||||||
approved_selected:
|
approved_selected:
|
||||||
one: "approve user"
|
one: "approve user"
|
||||||
|
@ -1916,6 +1917,7 @@ en:
|
||||||
moderators: 'Moderators'
|
moderators: 'Moderators'
|
||||||
blocked: 'Blocked Users'
|
blocked: 'Blocked Users'
|
||||||
suspended: 'Suspended Users'
|
suspended: 'Suspended Users'
|
||||||
|
suspect: 'Suspect Users'
|
||||||
reject_successful:
|
reject_successful:
|
||||||
one: "Successfully rejected 1 user."
|
one: "Successfully rejected 1 user."
|
||||||
other: "Successfully rejected %{count} users."
|
other: "Successfully rejected %{count} users."
|
||||||
|
|
|
@ -11,15 +11,7 @@ class AdminUserIndexQuery
|
||||||
attr_reader :params, :trust_levels
|
attr_reader :params, :trust_levels
|
||||||
|
|
||||||
def find_users(limit=100)
|
def find_users(limit=100)
|
||||||
find_users_query.includes(:user_stat)
|
find_users_query.includes(:user_stat).limit(limit)
|
||||||
.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)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def count_users
|
def count_users
|
||||||
|
@ -32,10 +24,10 @@ class AdminUserIndexQuery
|
||||||
if params[:query] == "active"
|
if params[:query] == "active"
|
||||||
order << "COALESCE(last_seen_at, to_date('1970-01-01', 'YYYY-MM-DD')) DESC"
|
order << "COALESCE(last_seen_at, to_date('1970-01-01', 'YYYY-MM-DD')) DESC"
|
||||||
else
|
else
|
||||||
order << "created_at DESC"
|
order << "users.created_at DESC"
|
||||||
end
|
end
|
||||||
|
|
||||||
order << "username"
|
order << "users.username"
|
||||||
|
|
||||||
klass.order(order.reject(&:blank?).join(","))
|
klass.order(order.reject(&:blank?).join(","))
|
||||||
end
|
end
|
||||||
|
@ -47,6 +39,20 @@ class AdminUserIndexQuery
|
||||||
end
|
end
|
||||||
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
|
def filter_by_query_classification
|
||||||
case params[:query]
|
case params[:query]
|
||||||
when 'staff' then @query.where("admin or moderator")
|
when 'staff' then @query.where("admin or moderator")
|
||||||
|
@ -55,6 +61,7 @@ class AdminUserIndexQuery
|
||||||
when 'blocked' then @query.blocked
|
when 'blocked' then @query.blocked
|
||||||
when 'suspended' then @query.suspended
|
when 'suspended' then @query.suspended
|
||||||
when 'pending' then @query.not_suspended.where(approved: false)
|
when 'pending' then @query.not_suspended.where(approved: false)
|
||||||
|
when 'suspect' then suspect_users
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue