2013-09-10 21:21:16 -04:00
|
|
|
# UserHistory stores information about actions that users have taken,
|
|
|
|
# like deleting users, changing site settings, dimissing notifications, etc.
|
|
|
|
# Use other classes, like StaffActionLogger, to log records to this table.
|
|
|
|
class UserHistory < ActiveRecord::Base
|
|
|
|
belongs_to :acting_user, class_name: 'User'
|
|
|
|
belongs_to :target_user, class_name: 'User'
|
2013-04-11 16:04:20 -04:00
|
|
|
|
|
|
|
validates_presence_of :action
|
|
|
|
|
2013-09-10 21:21:16 -04:00
|
|
|
scope :only_staff_actions, ->{ where("action IN (?)", UserHistory.staff_action_ids) }
|
|
|
|
|
2014-02-28 16:30:45 -05:00
|
|
|
before_save :set_admin_only
|
|
|
|
|
2013-04-11 16:04:20 -04:00
|
|
|
def self.actions
|
2013-08-21 12:03:21 -04:00
|
|
|
@actions ||= Enum.new( :delete_user,
|
|
|
|
:change_trust_level,
|
|
|
|
:change_site_setting,
|
|
|
|
:change_site_customization,
|
2013-09-12 14:58:20 -04:00
|
|
|
:delete_site_customization,
|
|
|
|
:checked_for_custom_avatar,
|
2013-09-13 13:49:34 -04:00
|
|
|
:notified_about_avatar,
|
2013-09-17 14:38:39 -04:00
|
|
|
:notified_about_sequential_replies,
|
2014-02-06 19:19:45 -05:00
|
|
|
:notified_about_dominating_topic,
|
2013-11-07 13:53:32 -05:00
|
|
|
:suspend_user,
|
2014-03-19 13:31:17 -04:00
|
|
|
:unsuspend_user,
|
2014-03-19 15:30:12 -04:00
|
|
|
:facebook_no_email,
|
|
|
|
:grant_badge,
|
|
|
|
:revoke_badge)
|
2013-04-11 16:04:20 -04:00
|
|
|
end
|
2013-08-09 10:06:02 -04:00
|
|
|
|
2013-09-10 21:21:16 -04:00
|
|
|
# Staff actions is a subset of all actions, used to audit actions taken by staff users.
|
|
|
|
def self.staff_actions
|
|
|
|
@staff_actions ||= [:delete_user,
|
|
|
|
:change_trust_level,
|
|
|
|
:change_site_setting,
|
|
|
|
:change_site_customization,
|
2013-11-01 10:47:03 -04:00
|
|
|
:delete_site_customization,
|
2013-11-07 13:53:32 -05:00
|
|
|
:suspend_user,
|
2014-03-19 15:30:12 -04:00
|
|
|
:unsuspend_user,
|
|
|
|
:grant_badge,
|
|
|
|
:revoke_badge]
|
2013-09-10 21:21:16 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def self.staff_action_ids
|
|
|
|
@staff_action_ids ||= staff_actions.map { |a| actions[a] }
|
|
|
|
end
|
|
|
|
|
2014-02-28 16:30:45 -05:00
|
|
|
def self.admin_only_action_ids
|
|
|
|
@admin_only_action_ids ||= [actions[:change_site_setting]]
|
|
|
|
end
|
|
|
|
|
2013-08-09 10:06:02 -04:00
|
|
|
def self.with_filters(filters)
|
|
|
|
query = self
|
2013-09-10 21:21:16 -04:00
|
|
|
if filters[:action_name] and action_id = UserHistory.actions[filters[:action_name].to_sym]
|
2013-08-09 10:06:02 -04:00
|
|
|
query = query.where('action = ?', action_id)
|
|
|
|
end
|
2013-09-10 21:21:16 -04:00
|
|
|
[:acting_user, :target_user].each do |key|
|
2013-08-09 16:58:57 -04:00
|
|
|
if filters[key] and obj_id = User.where(username_lower: filters[key].downcase).pluck(:id)
|
|
|
|
query = query.where("#{key.to_s}_id = ?", obj_id)
|
|
|
|
end
|
|
|
|
end
|
2013-08-20 13:50:51 -04:00
|
|
|
query = query.where("subject = ?", filters[:subject]) if filters[:subject]
|
2013-08-09 10:06:02 -04:00
|
|
|
query
|
|
|
|
end
|
2013-08-21 10:49:35 -04:00
|
|
|
|
2013-11-01 10:47:03 -04:00
|
|
|
def self.for(user, action_type)
|
|
|
|
self.where(target_user_id: user.id, action: UserHistory.actions[action_type])
|
|
|
|
end
|
|
|
|
|
2013-09-17 14:38:39 -04:00
|
|
|
def self.exists_for_user?(user, action_type, opts=nil)
|
|
|
|
opts = opts || {}
|
|
|
|
result = self.where(target_user_id: user.id, action: UserHistory.actions[action_type])
|
|
|
|
result = result.where(topic_id: opts[:topic_id]) if opts[:topic_id]
|
|
|
|
result.exists?
|
2013-09-12 17:46:43 -04:00
|
|
|
end
|
|
|
|
|
2014-02-28 16:30:45 -05:00
|
|
|
def self.staff_action_records(viewer, opts={})
|
|
|
|
query = self.with_filters(opts.slice(:action_name, :acting_user, :target_user, :subject)).only_staff_actions.limit(200).order('id DESC').includes(:acting_user, :target_user)
|
|
|
|
query = query.where(admin_only: false) unless viewer && viewer.admin?
|
|
|
|
query
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
def set_admin_only
|
|
|
|
self.admin_only = UserHistory.admin_only_action_ids.include?(self.action)
|
|
|
|
self
|
|
|
|
end
|
|
|
|
|
2013-08-21 10:49:35 -04:00
|
|
|
def new_value_is_json?
|
2013-09-10 21:21:16 -04:00
|
|
|
[UserHistory.actions[:change_site_customization], UserHistory.actions[:delete_site_customization]].include?(action)
|
2013-08-21 10:49:35 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def previous_value_is_json?
|
|
|
|
new_value_is_json?
|
|
|
|
end
|
2013-04-11 16:04:20 -04:00
|
|
|
end
|
2013-05-23 22:48:32 -04:00
|
|
|
|
|
|
|
# == Schema Information
|
|
|
|
#
|
2013-10-03 23:28:49 -04:00
|
|
|
# Table name: user_histories
|
2013-05-23 22:48:32 -04:00
|
|
|
#
|
|
|
|
# id :integer not null, primary key
|
|
|
|
# action :integer not null
|
2013-10-03 23:28:49 -04:00
|
|
|
# acting_user_id :integer
|
2013-05-23 22:48:32 -04:00
|
|
|
# target_user_id :integer
|
|
|
|
# details :text
|
2014-04-08 11:35:44 -04:00
|
|
|
# created_at :datetime
|
|
|
|
# updated_at :datetime
|
2013-08-13 16:09:27 -04:00
|
|
|
# context :string(255)
|
|
|
|
# ip_address :string(255)
|
|
|
|
# email :string(255)
|
2013-08-27 20:42:58 -04:00
|
|
|
# subject :text
|
|
|
|
# previous_value :text
|
|
|
|
# new_value :text
|
2013-10-03 23:28:49 -04:00
|
|
|
# topic_id :integer
|
2014-03-20 00:35:51 -04:00
|
|
|
# admin_only :boolean default(FALSE)
|
2013-08-13 16:09:27 -04:00
|
|
|
#
|
|
|
|
# Indexes
|
|
|
|
#
|
2013-10-03 23:28:49 -04:00
|
|
|
# index_user_histories_on_acting_user_id_and_action_and_id (acting_user_id,action,id)
|
2014-04-08 11:35:44 -04:00
|
|
|
# index_user_histories_on_action_and_id (action,id)
|
|
|
|
# index_user_histories_on_subject_and_id (subject,id)
|
|
|
|
# index_user_histories_on_target_user_id_and_id (target_user_id,id)
|
2013-05-23 22:48:32 -04:00
|
|
|
#
|